1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
63 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_SET_GOT_OFFSET 17)
74 (UNSPEC_TLS_LD_BASE 20)
77 ; Other random patterns
86 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
87 (UNSPEC_TRUNC_NOOP 39)
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 40)
108 ; Generic math support
110 (UNSPEC_IEEE_MIN 51) ; not commutative
111 (UNSPEC_IEEE_MAX 52) ; not commutative
126 (UNSPEC_FRNDINT_FLOOR 70)
127 (UNSPEC_FRNDINT_CEIL 71)
128 (UNSPEC_FRNDINT_TRUNC 72)
129 (UNSPEC_FRNDINT_MASK_PM 73)
130 (UNSPEC_FIST_FLOOR 74)
131 (UNSPEC_FIST_CEIL 75)
133 ; x87 Double output FP
134 (UNSPEC_SINCOS_COS 80)
135 (UNSPEC_SINCOS_SIN 81)
136 (UNSPEC_XTRACT_FRACT 84)
137 (UNSPEC_XTRACT_EXP 85)
138 (UNSPEC_FSCALE_FRACT 86)
139 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
161 (UNSPEC_INSERTQI 132)
166 (UNSPEC_INSERTPS 135)
168 (UNSPEC_MOVNTDQA 137)
170 (UNSPEC_PHMINPOSUW 139)
176 (UNSPEC_PCMPESTR 144)
177 (UNSPEC_PCMPISTR 145)
180 (UNSPEC_SSE5_INTRINSIC 150)
181 (UNSPEC_SSE5_UNSIGNED_CMP 151)
182 (UNSPEC_SSE5_TRUEFALSE 152)
183 (UNSPEC_SSE5_PERMUTE 153)
185 (UNSPEC_CVTPH2PS 155)
186 (UNSPEC_CVTPS2PH 156)
190 (UNSPEC_AESENCLAST 160)
192 (UNSPEC_AESDECLAST 162)
194 (UNSPEC_AESKEYGENASSIST 164)
201 [(UNSPECV_BLOCKAGE 0)
202 (UNSPECV_STACK_PROBE 1)
211 (UNSPECV_CMPXCHG_1 10)
212 (UNSPECV_CMPXCHG_2 11)
215 (UNSPECV_PROLOGUE_USE 14)
219 ;; Constants to represent pcomtrue/pcomfalse variants
229 ;; Constants used in the SSE5 pperm instruction
231 [(PPERM_SRC 0x00) /* copy source */
232 (PPERM_INVERT 0x20) /* invert source */
233 (PPERM_REVERSE 0x40) /* bit reverse source */
234 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
235 (PPERM_ZERO 0x80) /* all 0's */
236 (PPERM_ONES 0xa0) /* all 1's */
237 (PPERM_SIGN 0xc0) /* propagate sign bit */
238 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
239 (PPERM_SRC1 0x00) /* use first source byte */
240 (PPERM_SRC2 0x10) /* use second source byte */
243 ;; Registers by name.
259 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
262 ;; In C guard expressions, put expressions which may be compile-time
263 ;; constants first. This allows for better optimization. For
264 ;; example, write "TARGET_64BIT && reload_completed", not
265 ;; "reload_completed && TARGET_64BIT".
268 ;; Processor type. This attribute must exactly match the processor_type
269 ;; enumeration in i386.h.
270 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
271 nocona,core2,generic32,generic64,amdfam10"
272 (const (symbol_ref "ix86_tune")))
274 ;; A basic instruction type. Refinements due to arguments to be
275 ;; provided in other attributes.
278 alu,alu1,negnot,imov,imovx,lea,
279 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
280 icmp,test,ibr,setcc,icmov,
281 push,pop,call,callv,leave,
283 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
284 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
285 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
287 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
288 (const_string "other"))
290 ;; Main data type used by the insn
292 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
293 (const_string "unknown"))
295 ;; The CPU unit operations uses.
296 (define_attr "unit" "integer,i387,sse,mmx,unknown"
297 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
298 (const_string "i387")
299 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
300 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
301 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
303 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
305 (eq_attr "type" "other")
306 (const_string "unknown")]
307 (const_string "integer")))
309 ;; The (bounding maximum) length of an instruction immediate.
310 (define_attr "length_immediate" ""
311 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
314 (eq_attr "unit" "i387,sse,mmx")
316 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
318 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
319 (eq_attr "type" "imov,test")
320 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
321 (eq_attr "type" "call")
322 (if_then_else (match_operand 0 "constant_call_address_operand" "")
325 (eq_attr "type" "callv")
326 (if_then_else (match_operand 1 "constant_call_address_operand" "")
329 ;; We don't know the size before shorten_branches. Expect
330 ;; the instruction to fit for better scheduling.
331 (eq_attr "type" "ibr")
334 (symbol_ref "/* Update immediate_length and other attributes! */
335 gcc_unreachable (),1")))
337 ;; The (bounding maximum) length of an instruction address.
338 (define_attr "length_address" ""
339 (cond [(eq_attr "type" "str,other,multi,fxch")
341 (and (eq_attr "type" "call")
342 (match_operand 0 "constant_call_address_operand" ""))
344 (and (eq_attr "type" "callv")
345 (match_operand 1 "constant_call_address_operand" ""))
348 (symbol_ref "ix86_attr_length_address_default (insn)")))
350 ;; Set when length prefix is used.
351 (define_attr "prefix_data16" ""
352 (if_then_else (ior (eq_attr "mode" "HI")
353 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
357 ;; Set when string REP prefix is used.
358 (define_attr "prefix_rep" ""
359 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
363 ;; Set when 0f opcode prefix is used.
364 (define_attr "prefix_0f" ""
366 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
367 (eq_attr "unit" "sse,mmx"))
371 ;; Set when REX opcode prefix is used.
372 (define_attr "prefix_rex" ""
373 (cond [(and (eq_attr "mode" "DI")
374 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
376 (and (eq_attr "mode" "QI")
377 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
380 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
386 ;; There are also additional prefixes in SSSE3.
387 (define_attr "prefix_extra" "" (const_int 0))
389 ;; Set when modrm byte is used.
390 (define_attr "modrm" ""
391 (cond [(eq_attr "type" "str,leave")
393 (eq_attr "unit" "i387")
395 (and (eq_attr "type" "incdec")
396 (ior (match_operand:SI 1 "register_operand" "")
397 (match_operand:HI 1 "register_operand" "")))
399 (and (eq_attr "type" "push")
400 (not (match_operand 1 "memory_operand" "")))
402 (and (eq_attr "type" "pop")
403 (not (match_operand 0 "memory_operand" "")))
405 (and (eq_attr "type" "imov")
406 (ior (and (match_operand 0 "register_operand" "")
407 (match_operand 1 "immediate_operand" ""))
408 (ior (and (match_operand 0 "ax_reg_operand" "")
409 (match_operand 1 "memory_displacement_only_operand" ""))
410 (and (match_operand 0 "memory_displacement_only_operand" "")
411 (match_operand 1 "ax_reg_operand" "")))))
413 (and (eq_attr "type" "call")
414 (match_operand 0 "constant_call_address_operand" ""))
416 (and (eq_attr "type" "callv")
417 (match_operand 1 "constant_call_address_operand" ""))
422 ;; The (bounding maximum) length of an instruction in bytes.
423 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
424 ;; Later we may want to split them and compute proper length as for
426 (define_attr "length" ""
427 (cond [(eq_attr "type" "other,multi,fistp,frndint")
429 (eq_attr "type" "fcmp")
431 (eq_attr "unit" "i387")
433 (plus (attr "prefix_data16")
434 (attr "length_address")))]
435 (plus (plus (attr "modrm")
436 (plus (attr "prefix_0f")
437 (plus (attr "prefix_rex")
438 (plus (attr "prefix_extra")
440 (plus (attr "prefix_rep")
441 (plus (attr "prefix_data16")
442 (plus (attr "length_immediate")
443 (attr "length_address")))))))
445 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
446 ;; `store' if there is a simple memory reference therein, or `unknown'
447 ;; if the instruction is complex.
449 (define_attr "memory" "none,load,store,both,unknown"
450 (cond [(eq_attr "type" "other,multi,str")
451 (const_string "unknown")
452 (eq_attr "type" "lea,fcmov,fpspc")
453 (const_string "none")
454 (eq_attr "type" "fistp,leave")
455 (const_string "both")
456 (eq_attr "type" "frndint")
457 (const_string "load")
458 (eq_attr "type" "push")
459 (if_then_else (match_operand 1 "memory_operand" "")
460 (const_string "both")
461 (const_string "store"))
462 (eq_attr "type" "pop")
463 (if_then_else (match_operand 0 "memory_operand" "")
464 (const_string "both")
465 (const_string "load"))
466 (eq_attr "type" "setcc")
467 (if_then_else (match_operand 0 "memory_operand" "")
468 (const_string "store")
469 (const_string "none"))
470 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
471 (if_then_else (ior (match_operand 0 "memory_operand" "")
472 (match_operand 1 "memory_operand" ""))
473 (const_string "load")
474 (const_string "none"))
475 (eq_attr "type" "ibr")
476 (if_then_else (match_operand 0 "memory_operand" "")
477 (const_string "load")
478 (const_string "none"))
479 (eq_attr "type" "call")
480 (if_then_else (match_operand 0 "constant_call_address_operand" "")
481 (const_string "none")
482 (const_string "load"))
483 (eq_attr "type" "callv")
484 (if_then_else (match_operand 1 "constant_call_address_operand" "")
485 (const_string "none")
486 (const_string "load"))
487 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
488 (match_operand 1 "memory_operand" ""))
489 (const_string "both")
490 (and (match_operand 0 "memory_operand" "")
491 (match_operand 1 "memory_operand" ""))
492 (const_string "both")
493 (match_operand 0 "memory_operand" "")
494 (const_string "store")
495 (match_operand 1 "memory_operand" "")
496 (const_string "load")
498 "!alu1,negnot,ishift1,
499 imov,imovx,icmp,test,bitmanip,
501 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
502 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
503 (match_operand 2 "memory_operand" ""))
504 (const_string "load")
505 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
506 (match_operand 3 "memory_operand" ""))
507 (const_string "load")
509 (const_string "none")))
511 ;; Indicates if an instruction has both an immediate and a displacement.
513 (define_attr "imm_disp" "false,true,unknown"
514 (cond [(eq_attr "type" "other,multi")
515 (const_string "unknown")
516 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
517 (and (match_operand 0 "memory_displacement_operand" "")
518 (match_operand 1 "immediate_operand" "")))
519 (const_string "true")
520 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
521 (and (match_operand 0 "memory_displacement_operand" "")
522 (match_operand 2 "immediate_operand" "")))
523 (const_string "true")
525 (const_string "false")))
527 ;; Indicates if an FP operation has an integer source.
529 (define_attr "fp_int_src" "false,true"
530 (const_string "false"))
532 ;; Defines rounding mode of an FP operation.
534 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
535 (const_string "any"))
537 ;; Describe a user's asm statement.
538 (define_asm_attributes
539 [(set_attr "length" "128")
540 (set_attr "type" "multi")])
542 ;; All integer comparison codes.
543 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
545 ;; All floating-point comparison codes.
546 (define_code_iterator fp_cond [unordered ordered
547 uneq unge ungt unle unlt ltgt ])
549 (define_code_iterator plusminus [plus minus])
551 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
553 ;; Base name for define_insn
554 (define_code_attr plusminus_insn
555 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
556 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
558 ;; Base name for insn mnemonic.
559 (define_code_attr plusminus_mnemonic
560 [(plus "add") (ss_plus "adds") (us_plus "addus")
561 (minus "sub") (ss_minus "subs") (us_minus "subus")])
563 ;; Mark commutative operators as such in constraints.
564 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
565 (minus "") (ss_minus "") (us_minus "")])
567 ;; Mapping of signed max and min
568 (define_code_iterator smaxmin [smax smin])
570 ;; Mapping of unsigned max and min
571 (define_code_iterator umaxmin [umax umin])
573 ;; Base name for integer and FP insn mnemonic
574 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
575 (umax "maxu") (umin "minu")])
576 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
578 ;; Mapping of parallel logic operators
579 (define_code_iterator plogic [and ior xor])
581 ;; Base name for insn mnemonic.
582 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
584 ;; Mapping of abs neg operators
585 (define_code_iterator absneg [abs neg])
587 ;; Base name for x87 insn mnemonic.
588 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
590 ;; All single word integer modes.
591 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
593 ;; Instruction suffix for integer modes.
594 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
596 ;; Register class for integer modes.
597 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
599 ;; Immediate operand constraint for integer modes.
600 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
602 ;; General operand predicate for integer modes.
603 (define_mode_attr general_operand
604 [(QI "general_operand")
605 (HI "general_operand")
606 (SI "general_operand")
607 (DI "x86_64_general_operand")])
609 ;; SSE and x87 SFmode and DFmode floating point modes
610 (define_mode_iterator MODEF [SF DF])
612 ;; All x87 floating point modes
613 (define_mode_iterator X87MODEF [SF DF XF])
615 ;; All integer modes handled by x87 fisttp operator.
616 (define_mode_iterator X87MODEI [HI SI DI])
618 ;; All integer modes handled by integer x87 operators.
619 (define_mode_iterator X87MODEI12 [HI SI])
621 ;; All integer modes handled by SSE cvtts?2si* operators.
622 (define_mode_iterator SSEMODEI24 [SI DI])
624 ;; SSE asm suffix for floating point modes
625 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
627 ;; SSE vector mode corresponding to a scalar mode
628 (define_mode_attr ssevecmode
629 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
631 ;; Instruction suffix for REX 64bit operators.
632 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
634 ;; This mode iterator allows :P to be used for patterns that operate on
635 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
636 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
639 ;; Scheduling descriptions
641 (include "pentium.md")
644 (include "athlon.md")
648 ;; Operand and operator predicates and constraints
650 (include "predicates.md")
651 (include "constraints.md")
654 ;; Compare instructions.
656 ;; All compare insns have expanders that save the operands away without
657 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
658 ;; after the cmp) will actually emit the cmpM.
660 (define_expand "cmpti"
661 [(set (reg:CC FLAGS_REG)
662 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
663 (match_operand:TI 1 "x86_64_general_operand" "")))]
666 if (MEM_P (operands[0]) && MEM_P (operands[1]))
667 operands[0] = force_reg (TImode, operands[0]);
668 ix86_compare_op0 = operands[0];
669 ix86_compare_op1 = operands[1];
673 (define_expand "cmpdi"
674 [(set (reg:CC FLAGS_REG)
675 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
676 (match_operand:DI 1 "x86_64_general_operand" "")))]
679 if (MEM_P (operands[0]) && MEM_P (operands[1]))
680 operands[0] = force_reg (DImode, operands[0]);
681 ix86_compare_op0 = operands[0];
682 ix86_compare_op1 = operands[1];
686 (define_expand "cmpsi"
687 [(set (reg:CC FLAGS_REG)
688 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
689 (match_operand:SI 1 "general_operand" "")))]
692 if (MEM_P (operands[0]) && MEM_P (operands[1]))
693 operands[0] = force_reg (SImode, operands[0]);
694 ix86_compare_op0 = operands[0];
695 ix86_compare_op1 = operands[1];
699 (define_expand "cmphi"
700 [(set (reg:CC FLAGS_REG)
701 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
702 (match_operand:HI 1 "general_operand" "")))]
705 if (MEM_P (operands[0]) && MEM_P (operands[1]))
706 operands[0] = force_reg (HImode, operands[0]);
707 ix86_compare_op0 = operands[0];
708 ix86_compare_op1 = operands[1];
712 (define_expand "cmpqi"
713 [(set (reg:CC FLAGS_REG)
714 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
715 (match_operand:QI 1 "general_operand" "")))]
718 if (MEM_P (operands[0]) && MEM_P (operands[1]))
719 operands[0] = force_reg (QImode, operands[0]);
720 ix86_compare_op0 = operands[0];
721 ix86_compare_op1 = operands[1];
725 (define_insn "cmpdi_ccno_1_rex64"
726 [(set (reg FLAGS_REG)
727 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
728 (match_operand:DI 1 "const0_operand" "")))]
729 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
732 cmp{q}\t{%1, %0|%0, %1}"
733 [(set_attr "type" "test,icmp")
734 (set_attr "length_immediate" "0,1")
735 (set_attr "mode" "DI")])
737 (define_insn "*cmpdi_minus_1_rex64"
738 [(set (reg FLAGS_REG)
739 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
740 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
742 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
743 "cmp{q}\t{%1, %0|%0, %1}"
744 [(set_attr "type" "icmp")
745 (set_attr "mode" "DI")])
747 (define_expand "cmpdi_1_rex64"
748 [(set (reg:CC FLAGS_REG)
749 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
750 (match_operand:DI 1 "general_operand" "")))]
754 (define_insn "cmpdi_1_insn_rex64"
755 [(set (reg FLAGS_REG)
756 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
757 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
758 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
759 "cmp{q}\t{%1, %0|%0, %1}"
760 [(set_attr "type" "icmp")
761 (set_attr "mode" "DI")])
764 (define_insn "*cmpsi_ccno_1"
765 [(set (reg FLAGS_REG)
766 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
767 (match_operand:SI 1 "const0_operand" "")))]
768 "ix86_match_ccmode (insn, CCNOmode)"
771 cmp{l}\t{%1, %0|%0, %1}"
772 [(set_attr "type" "test,icmp")
773 (set_attr "length_immediate" "0,1")
774 (set_attr "mode" "SI")])
776 (define_insn "*cmpsi_minus_1"
777 [(set (reg FLAGS_REG)
778 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
779 (match_operand:SI 1 "general_operand" "ri,mr"))
781 "ix86_match_ccmode (insn, CCGOCmode)"
782 "cmp{l}\t{%1, %0|%0, %1}"
783 [(set_attr "type" "icmp")
784 (set_attr "mode" "SI")])
786 (define_expand "cmpsi_1"
787 [(set (reg:CC FLAGS_REG)
788 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
789 (match_operand:SI 1 "general_operand" "")))]
793 (define_insn "*cmpsi_1_insn"
794 [(set (reg FLAGS_REG)
795 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
796 (match_operand:SI 1 "general_operand" "ri,mr")))]
797 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
798 && ix86_match_ccmode (insn, CCmode)"
799 "cmp{l}\t{%1, %0|%0, %1}"
800 [(set_attr "type" "icmp")
801 (set_attr "mode" "SI")])
803 (define_insn "*cmphi_ccno_1"
804 [(set (reg FLAGS_REG)
805 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
806 (match_operand:HI 1 "const0_operand" "")))]
807 "ix86_match_ccmode (insn, CCNOmode)"
810 cmp{w}\t{%1, %0|%0, %1}"
811 [(set_attr "type" "test,icmp")
812 (set_attr "length_immediate" "0,1")
813 (set_attr "mode" "HI")])
815 (define_insn "*cmphi_minus_1"
816 [(set (reg FLAGS_REG)
817 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
818 (match_operand:HI 1 "general_operand" "rn,mr"))
820 "ix86_match_ccmode (insn, CCGOCmode)"
821 "cmp{w}\t{%1, %0|%0, %1}"
822 [(set_attr "type" "icmp")
823 (set_attr "mode" "HI")])
825 (define_insn "*cmphi_1"
826 [(set (reg FLAGS_REG)
827 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
828 (match_operand:HI 1 "general_operand" "rn,mr")))]
829 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
830 && ix86_match_ccmode (insn, CCmode)"
831 "cmp{w}\t{%1, %0|%0, %1}"
832 [(set_attr "type" "icmp")
833 (set_attr "mode" "HI")])
835 (define_insn "*cmpqi_ccno_1"
836 [(set (reg FLAGS_REG)
837 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
838 (match_operand:QI 1 "const0_operand" "")))]
839 "ix86_match_ccmode (insn, CCNOmode)"
842 cmp{b}\t{$0, %0|%0, 0}"
843 [(set_attr "type" "test,icmp")
844 (set_attr "length_immediate" "0,1")
845 (set_attr "mode" "QI")])
847 (define_insn "*cmpqi_1"
848 [(set (reg FLAGS_REG)
849 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
850 (match_operand:QI 1 "general_operand" "qn,mq")))]
851 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
852 && ix86_match_ccmode (insn, CCmode)"
853 "cmp{b}\t{%1, %0|%0, %1}"
854 [(set_attr "type" "icmp")
855 (set_attr "mode" "QI")])
857 (define_insn "*cmpqi_minus_1"
858 [(set (reg FLAGS_REG)
859 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
860 (match_operand:QI 1 "general_operand" "qn,mq"))
862 "ix86_match_ccmode (insn, CCGOCmode)"
863 "cmp{b}\t{%1, %0|%0, %1}"
864 [(set_attr "type" "icmp")
865 (set_attr "mode" "QI")])
867 (define_insn "*cmpqi_ext_1"
868 [(set (reg FLAGS_REG)
870 (match_operand:QI 0 "general_operand" "Qm")
873 (match_operand 1 "ext_register_operand" "Q")
876 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
877 "cmp{b}\t{%h1, %0|%0, %h1}"
878 [(set_attr "type" "icmp")
879 (set_attr "mode" "QI")])
881 (define_insn "*cmpqi_ext_1_rex64"
882 [(set (reg FLAGS_REG)
884 (match_operand:QI 0 "register_operand" "Q")
887 (match_operand 1 "ext_register_operand" "Q")
890 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
891 "cmp{b}\t{%h1, %0|%0, %h1}"
892 [(set_attr "type" "icmp")
893 (set_attr "mode" "QI")])
895 (define_insn "*cmpqi_ext_2"
896 [(set (reg FLAGS_REG)
900 (match_operand 0 "ext_register_operand" "Q")
903 (match_operand:QI 1 "const0_operand" "")))]
904 "ix86_match_ccmode (insn, CCNOmode)"
906 [(set_attr "type" "test")
907 (set_attr "length_immediate" "0")
908 (set_attr "mode" "QI")])
910 (define_expand "cmpqi_ext_3"
911 [(set (reg:CC FLAGS_REG)
915 (match_operand 0 "ext_register_operand" "")
918 (match_operand:QI 1 "general_operand" "")))]
922 (define_insn "cmpqi_ext_3_insn"
923 [(set (reg FLAGS_REG)
927 (match_operand 0 "ext_register_operand" "Q")
930 (match_operand:QI 1 "general_operand" "Qmn")))]
931 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
932 "cmp{b}\t{%1, %h0|%h0, %1}"
933 [(set_attr "type" "icmp")
934 (set_attr "mode" "QI")])
936 (define_insn "cmpqi_ext_3_insn_rex64"
937 [(set (reg FLAGS_REG)
941 (match_operand 0 "ext_register_operand" "Q")
944 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
945 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
946 "cmp{b}\t{%1, %h0|%h0, %1}"
947 [(set_attr "type" "icmp")
948 (set_attr "mode" "QI")])
950 (define_insn "*cmpqi_ext_4"
951 [(set (reg FLAGS_REG)
955 (match_operand 0 "ext_register_operand" "Q")
960 (match_operand 1 "ext_register_operand" "Q")
963 "ix86_match_ccmode (insn, CCmode)"
964 "cmp{b}\t{%h1, %h0|%h0, %h1}"
965 [(set_attr "type" "icmp")
966 (set_attr "mode" "QI")])
968 ;; These implement float point compares.
969 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
970 ;; which would allow mix and match FP modes on the compares. Which is what
971 ;; the old patterns did, but with many more of them.
973 (define_expand "cmpxf"
974 [(set (reg:CC FLAGS_REG)
975 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
976 (match_operand:XF 1 "nonmemory_operand" "")))]
979 ix86_compare_op0 = operands[0];
980 ix86_compare_op1 = operands[1];
984 (define_expand "cmp<mode>"
985 [(set (reg:CC FLAGS_REG)
986 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
987 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
988 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
990 ix86_compare_op0 = operands[0];
991 ix86_compare_op1 = operands[1];
995 ;; FP compares, step 1:
996 ;; Set the FP condition codes.
998 ;; CCFPmode compare with exceptions
999 ;; CCFPUmode compare with no exceptions
1001 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1002 ;; used to manage the reg stack popping would not be preserved.
1004 (define_insn "*cmpfp_0"
1005 [(set (match_operand:HI 0 "register_operand" "=a")
1008 (match_operand 1 "register_operand" "f")
1009 (match_operand 2 "const0_operand" ""))]
1011 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1012 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1013 "* return output_fp_compare (insn, operands, 0, 0);"
1014 [(set_attr "type" "multi")
1015 (set_attr "unit" "i387")
1017 (cond [(match_operand:SF 1 "" "")
1019 (match_operand:DF 1 "" "")
1022 (const_string "XF")))])
1024 (define_insn_and_split "*cmpfp_0_cc"
1025 [(set (reg:CCFP FLAGS_REG)
1027 (match_operand 1 "register_operand" "f")
1028 (match_operand 2 "const0_operand" "")))
1029 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1030 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1031 && TARGET_SAHF && !TARGET_CMOVE
1032 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1034 "&& reload_completed"
1037 [(compare:CCFP (match_dup 1)(match_dup 2))]
1039 (set (reg:CC FLAGS_REG)
1040 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1042 [(set_attr "type" "multi")
1043 (set_attr "unit" "i387")
1045 (cond [(match_operand:SF 1 "" "")
1047 (match_operand:DF 1 "" "")
1050 (const_string "XF")))])
1052 (define_insn "*cmpfp_xf"
1053 [(set (match_operand:HI 0 "register_operand" "=a")
1056 (match_operand:XF 1 "register_operand" "f")
1057 (match_operand:XF 2 "register_operand" "f"))]
1060 "* return output_fp_compare (insn, operands, 0, 0);"
1061 [(set_attr "type" "multi")
1062 (set_attr "unit" "i387")
1063 (set_attr "mode" "XF")])
1065 (define_insn_and_split "*cmpfp_xf_cc"
1066 [(set (reg:CCFP FLAGS_REG)
1068 (match_operand:XF 1 "register_operand" "f")
1069 (match_operand:XF 2 "register_operand" "f")))
1070 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1072 && TARGET_SAHF && !TARGET_CMOVE"
1074 "&& reload_completed"
1077 [(compare:CCFP (match_dup 1)(match_dup 2))]
1079 (set (reg:CC FLAGS_REG)
1080 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1082 [(set_attr "type" "multi")
1083 (set_attr "unit" "i387")
1084 (set_attr "mode" "XF")])
1086 (define_insn "*cmpfp_<mode>"
1087 [(set (match_operand:HI 0 "register_operand" "=a")
1090 (match_operand:MODEF 1 "register_operand" "f")
1091 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1094 "* return output_fp_compare (insn, operands, 0, 0);"
1095 [(set_attr "type" "multi")
1096 (set_attr "unit" "i387")
1097 (set_attr "mode" "<MODE>")])
1099 (define_insn_and_split "*cmpfp_<mode>_cc"
1100 [(set (reg:CCFP FLAGS_REG)
1102 (match_operand:MODEF 1 "register_operand" "f")
1103 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1104 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1106 && TARGET_SAHF && !TARGET_CMOVE"
1108 "&& reload_completed"
1111 [(compare:CCFP (match_dup 1)(match_dup 2))]
1113 (set (reg:CC FLAGS_REG)
1114 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1116 [(set_attr "type" "multi")
1117 (set_attr "unit" "i387")
1118 (set_attr "mode" "<MODE>")])
1120 (define_insn "*cmpfp_u"
1121 [(set (match_operand:HI 0 "register_operand" "=a")
1124 (match_operand 1 "register_operand" "f")
1125 (match_operand 2 "register_operand" "f"))]
1127 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1128 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1129 "* return output_fp_compare (insn, operands, 0, 1);"
1130 [(set_attr "type" "multi")
1131 (set_attr "unit" "i387")
1133 (cond [(match_operand:SF 1 "" "")
1135 (match_operand:DF 1 "" "")
1138 (const_string "XF")))])
1140 (define_insn_and_split "*cmpfp_u_cc"
1141 [(set (reg:CCFPU FLAGS_REG)
1143 (match_operand 1 "register_operand" "f")
1144 (match_operand 2 "register_operand" "f")))
1145 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1146 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1147 && TARGET_SAHF && !TARGET_CMOVE
1148 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1150 "&& reload_completed"
1153 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1155 (set (reg:CC FLAGS_REG)
1156 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1158 [(set_attr "type" "multi")
1159 (set_attr "unit" "i387")
1161 (cond [(match_operand:SF 1 "" "")
1163 (match_operand:DF 1 "" "")
1166 (const_string "XF")))])
1168 (define_insn "*cmpfp_<mode>"
1169 [(set (match_operand:HI 0 "register_operand" "=a")
1172 (match_operand 1 "register_operand" "f")
1173 (match_operator 3 "float_operator"
1174 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1176 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1177 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
1178 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1179 "* return output_fp_compare (insn, operands, 0, 0);"
1180 [(set_attr "type" "multi")
1181 (set_attr "unit" "i387")
1182 (set_attr "fp_int_src" "true")
1183 (set_attr "mode" "<MODE>")])
1185 (define_insn_and_split "*cmpfp_<mode>_cc"
1186 [(set (reg:CCFP FLAGS_REG)
1188 (match_operand 1 "register_operand" "f")
1189 (match_operator 3 "float_operator"
1190 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1191 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1192 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1193 && TARGET_SAHF && !TARGET_CMOVE
1194 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
1195 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1197 "&& reload_completed"
1202 (match_op_dup 3 [(match_dup 2)]))]
1204 (set (reg:CC FLAGS_REG)
1205 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1207 [(set_attr "type" "multi")
1208 (set_attr "unit" "i387")
1209 (set_attr "fp_int_src" "true")
1210 (set_attr "mode" "<MODE>")])
1212 ;; FP compares, step 2
1213 ;; Move the fpsw to ax.
1215 (define_insn "x86_fnstsw_1"
1216 [(set (match_operand:HI 0 "register_operand" "=a")
1217 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1220 [(set_attr "length" "2")
1221 (set_attr "mode" "SI")
1222 (set_attr "unit" "i387")])
1224 ;; FP compares, step 3
1225 ;; Get ax into flags, general case.
1227 (define_insn "x86_sahf_1"
1228 [(set (reg:CC FLAGS_REG)
1229 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1233 #ifdef HAVE_AS_IX86_SAHF
1236 return ".byte\t0x9e";
1239 [(set_attr "length" "1")
1240 (set_attr "athlon_decode" "vector")
1241 (set_attr "amdfam10_decode" "direct")
1242 (set_attr "mode" "SI")])
1244 ;; Pentium Pro can do steps 1 through 3 in one go.
1245 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1246 (define_insn "*cmpfp_i_mixed"
1247 [(set (reg:CCFP FLAGS_REG)
1248 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1249 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1250 "TARGET_MIX_SSE_I387
1251 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1252 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1253 "* return output_fp_compare (insn, operands, 1, 0);"
1254 [(set_attr "type" "fcmp,ssecomi")
1256 (if_then_else (match_operand:SF 1 "" "")
1258 (const_string "DF")))
1259 (set_attr "athlon_decode" "vector")
1260 (set_attr "amdfam10_decode" "direct")])
1262 (define_insn "*cmpfp_i_sse"
1263 [(set (reg:CCFP FLAGS_REG)
1264 (compare:CCFP (match_operand 0 "register_operand" "x")
1265 (match_operand 1 "nonimmediate_operand" "xm")))]
1267 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1268 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1269 "* return output_fp_compare (insn, operands, 1, 0);"
1270 [(set_attr "type" "ssecomi")
1272 (if_then_else (match_operand:SF 1 "" "")
1274 (const_string "DF")))
1275 (set_attr "athlon_decode" "vector")
1276 (set_attr "amdfam10_decode" "direct")])
1278 (define_insn "*cmpfp_i_i387"
1279 [(set (reg:CCFP FLAGS_REG)
1280 (compare:CCFP (match_operand 0 "register_operand" "f")
1281 (match_operand 1 "register_operand" "f")))]
1282 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1284 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1285 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1286 "* return output_fp_compare (insn, operands, 1, 0);"
1287 [(set_attr "type" "fcmp")
1289 (cond [(match_operand:SF 1 "" "")
1291 (match_operand:DF 1 "" "")
1294 (const_string "XF")))
1295 (set_attr "athlon_decode" "vector")
1296 (set_attr "amdfam10_decode" "direct")])
1298 (define_insn "*cmpfp_iu_mixed"
1299 [(set (reg:CCFPU FLAGS_REG)
1300 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1301 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1302 "TARGET_MIX_SSE_I387
1303 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1304 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1305 "* return output_fp_compare (insn, operands, 1, 1);"
1306 [(set_attr "type" "fcmp,ssecomi")
1308 (if_then_else (match_operand:SF 1 "" "")
1310 (const_string "DF")))
1311 (set_attr "athlon_decode" "vector")
1312 (set_attr "amdfam10_decode" "direct")])
1314 (define_insn "*cmpfp_iu_sse"
1315 [(set (reg:CCFPU FLAGS_REG)
1316 (compare:CCFPU (match_operand 0 "register_operand" "x")
1317 (match_operand 1 "nonimmediate_operand" "xm")))]
1319 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1320 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1321 "* return output_fp_compare (insn, operands, 1, 1);"
1322 [(set_attr "type" "ssecomi")
1324 (if_then_else (match_operand:SF 1 "" "")
1326 (const_string "DF")))
1327 (set_attr "athlon_decode" "vector")
1328 (set_attr "amdfam10_decode" "direct")])
1330 (define_insn "*cmpfp_iu_387"
1331 [(set (reg:CCFPU FLAGS_REG)
1332 (compare:CCFPU (match_operand 0 "register_operand" "f")
1333 (match_operand 1 "register_operand" "f")))]
1334 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1336 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1337 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1338 "* return output_fp_compare (insn, operands, 1, 1);"
1339 [(set_attr "type" "fcmp")
1341 (cond [(match_operand:SF 1 "" "")
1343 (match_operand:DF 1 "" "")
1346 (const_string "XF")))
1347 (set_attr "athlon_decode" "vector")
1348 (set_attr "amdfam10_decode" "direct")])
1350 ;; Move instructions.
1352 ;; General case of fullword move.
1354 (define_expand "movsi"
1355 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1356 (match_operand:SI 1 "general_operand" ""))]
1358 "ix86_expand_move (SImode, operands); DONE;")
1360 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1363 ;; %%% We don't use a post-inc memory reference because x86 is not a
1364 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1365 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1366 ;; targets without our curiosities, and it is just as easy to represent
1367 ;; this differently.
1369 (define_insn "*pushsi2"
1370 [(set (match_operand:SI 0 "push_operand" "=<")
1371 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1374 [(set_attr "type" "push")
1375 (set_attr "mode" "SI")])
1377 ;; For 64BIT abi we always round up to 8 bytes.
1378 (define_insn "*pushsi2_rex64"
1379 [(set (match_operand:SI 0 "push_operand" "=X")
1380 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1383 [(set_attr "type" "push")
1384 (set_attr "mode" "SI")])
1386 (define_insn "*pushsi2_prologue"
1387 [(set (match_operand:SI 0 "push_operand" "=<")
1388 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1389 (clobber (mem:BLK (scratch)))]
1392 [(set_attr "type" "push")
1393 (set_attr "mode" "SI")])
1395 (define_insn "*popsi1_epilogue"
1396 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1397 (mem:SI (reg:SI SP_REG)))
1398 (set (reg:SI SP_REG)
1399 (plus:SI (reg:SI SP_REG) (const_int 4)))
1400 (clobber (mem:BLK (scratch)))]
1403 [(set_attr "type" "pop")
1404 (set_attr "mode" "SI")])
1406 (define_insn "popsi1"
1407 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1408 (mem:SI (reg:SI SP_REG)))
1409 (set (reg:SI SP_REG)
1410 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1413 [(set_attr "type" "pop")
1414 (set_attr "mode" "SI")])
1416 (define_insn "*movsi_xor"
1417 [(set (match_operand:SI 0 "register_operand" "=r")
1418 (match_operand:SI 1 "const0_operand" ""))
1419 (clobber (reg:CC FLAGS_REG))]
1420 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1422 [(set_attr "type" "alu1")
1423 (set_attr "mode" "SI")
1424 (set_attr "length_immediate" "0")])
1426 (define_insn "*movsi_or"
1427 [(set (match_operand:SI 0 "register_operand" "=r")
1428 (match_operand:SI 1 "immediate_operand" "i"))
1429 (clobber (reg:CC FLAGS_REG))]
1431 && operands[1] == constm1_rtx
1432 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1434 operands[1] = constm1_rtx;
1435 return "or{l}\t{%1, %0|%0, %1}";
1437 [(set_attr "type" "alu1")
1438 (set_attr "mode" "SI")
1439 (set_attr "length_immediate" "1")])
1441 (define_insn "*movsi_1"
1442 [(set (match_operand:SI 0 "nonimmediate_operand"
1443 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1444 (match_operand:SI 1 "general_operand"
1445 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1446 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1448 switch (get_attr_type (insn))
1451 if (get_attr_mode (insn) == MODE_TI)
1452 return "pxor\t%0, %0";
1453 return "xorps\t%0, %0";
1456 switch (get_attr_mode (insn))
1459 return "movdqa\t{%1, %0|%0, %1}";
1461 return "movaps\t{%1, %0|%0, %1}";
1463 return "movd\t{%1, %0|%0, %1}";
1465 return "movss\t{%1, %0|%0, %1}";
1471 return "pxor\t%0, %0";
1474 if (get_attr_mode (insn) == MODE_DI)
1475 return "movq\t{%1, %0|%0, %1}";
1476 return "movd\t{%1, %0|%0, %1}";
1479 return "lea{l}\t{%1, %0|%0, %1}";
1482 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1483 return "mov{l}\t{%1, %0|%0, %1}";
1487 (cond [(eq_attr "alternative" "2")
1488 (const_string "mmxadd")
1489 (eq_attr "alternative" "3,4,5")
1490 (const_string "mmxmov")
1491 (eq_attr "alternative" "6")
1492 (const_string "sselog1")
1493 (eq_attr "alternative" "7,8,9,10,11")
1494 (const_string "ssemov")
1495 (match_operand:DI 1 "pic_32bit_operand" "")
1496 (const_string "lea")
1498 (const_string "imov")))
1500 (cond [(eq_attr "alternative" "2,3")
1502 (eq_attr "alternative" "6,7")
1504 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1505 (const_string "V4SF")
1506 (const_string "TI"))
1507 (and (eq_attr "alternative" "8,9,10,11")
1508 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1511 (const_string "SI")))])
1513 ;; Stores and loads of ax to arbitrary constant address.
1514 ;; We fake an second form of instruction to force reload to load address
1515 ;; into register when rax is not available
1516 (define_insn "*movabssi_1_rex64"
1517 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1518 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1519 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1521 movabs{l}\t{%1, %P0|%P0, %1}
1522 mov{l}\t{%1, %a0|%a0, %1}"
1523 [(set_attr "type" "imov")
1524 (set_attr "modrm" "0,*")
1525 (set_attr "length_address" "8,0")
1526 (set_attr "length_immediate" "0,*")
1527 (set_attr "memory" "store")
1528 (set_attr "mode" "SI")])
1530 (define_insn "*movabssi_2_rex64"
1531 [(set (match_operand:SI 0 "register_operand" "=a,r")
1532 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1533 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1535 movabs{l}\t{%P1, %0|%0, %P1}
1536 mov{l}\t{%a1, %0|%0, %a1}"
1537 [(set_attr "type" "imov")
1538 (set_attr "modrm" "0,*")
1539 (set_attr "length_address" "8,0")
1540 (set_attr "length_immediate" "0")
1541 (set_attr "memory" "load")
1542 (set_attr "mode" "SI")])
1544 (define_insn "*swapsi"
1545 [(set (match_operand:SI 0 "register_operand" "+r")
1546 (match_operand:SI 1 "register_operand" "+r"))
1551 [(set_attr "type" "imov")
1552 (set_attr "mode" "SI")
1553 (set_attr "pent_pair" "np")
1554 (set_attr "athlon_decode" "vector")
1555 (set_attr "amdfam10_decode" "double")])
1557 (define_expand "movhi"
1558 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1559 (match_operand:HI 1 "general_operand" ""))]
1561 "ix86_expand_move (HImode, operands); DONE;")
1563 (define_insn "*pushhi2"
1564 [(set (match_operand:HI 0 "push_operand" "=X")
1565 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1568 [(set_attr "type" "push")
1569 (set_attr "mode" "SI")])
1571 ;; For 64BIT abi we always round up to 8 bytes.
1572 (define_insn "*pushhi2_rex64"
1573 [(set (match_operand:HI 0 "push_operand" "=X")
1574 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1577 [(set_attr "type" "push")
1578 (set_attr "mode" "DI")])
1580 (define_insn "*movhi_1"
1581 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1582 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1583 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1585 switch (get_attr_type (insn))
1588 /* movzwl is faster than movw on p2 due to partial word stalls,
1589 though not as fast as an aligned movl. */
1590 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1592 if (get_attr_mode (insn) == MODE_SI)
1593 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1595 return "mov{w}\t{%1, %0|%0, %1}";
1599 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1600 (const_string "imov")
1601 (and (eq_attr "alternative" "0")
1602 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1604 (eq (symbol_ref "TARGET_HIMODE_MATH")
1606 (const_string "imov")
1607 (and (eq_attr "alternative" "1,2")
1608 (match_operand:HI 1 "aligned_operand" ""))
1609 (const_string "imov")
1610 (and (ne (symbol_ref "TARGET_MOVX")
1612 (eq_attr "alternative" "0,2"))
1613 (const_string "imovx")
1615 (const_string "imov")))
1617 (cond [(eq_attr "type" "imovx")
1619 (and (eq_attr "alternative" "1,2")
1620 (match_operand:HI 1 "aligned_operand" ""))
1622 (and (eq_attr "alternative" "0")
1623 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1625 (eq (symbol_ref "TARGET_HIMODE_MATH")
1629 (const_string "HI")))])
1631 ;; Stores and loads of ax to arbitrary constant address.
1632 ;; We fake an second form of instruction to force reload to load address
1633 ;; into register when rax is not available
1634 (define_insn "*movabshi_1_rex64"
1635 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1636 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1637 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1639 movabs{w}\t{%1, %P0|%P0, %1}
1640 mov{w}\t{%1, %a0|%a0, %1}"
1641 [(set_attr "type" "imov")
1642 (set_attr "modrm" "0,*")
1643 (set_attr "length_address" "8,0")
1644 (set_attr "length_immediate" "0,*")
1645 (set_attr "memory" "store")
1646 (set_attr "mode" "HI")])
1648 (define_insn "*movabshi_2_rex64"
1649 [(set (match_operand:HI 0 "register_operand" "=a,r")
1650 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1651 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1653 movabs{w}\t{%P1, %0|%0, %P1}
1654 mov{w}\t{%a1, %0|%0, %a1}"
1655 [(set_attr "type" "imov")
1656 (set_attr "modrm" "0,*")
1657 (set_attr "length_address" "8,0")
1658 (set_attr "length_immediate" "0")
1659 (set_attr "memory" "load")
1660 (set_attr "mode" "HI")])
1662 (define_insn "*swaphi_1"
1663 [(set (match_operand:HI 0 "register_operand" "+r")
1664 (match_operand:HI 1 "register_operand" "+r"))
1667 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1669 [(set_attr "type" "imov")
1670 (set_attr "mode" "SI")
1671 (set_attr "pent_pair" "np")
1672 (set_attr "athlon_decode" "vector")
1673 (set_attr "amdfam10_decode" "double")])
1675 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1676 (define_insn "*swaphi_2"
1677 [(set (match_operand:HI 0 "register_operand" "+r")
1678 (match_operand:HI 1 "register_operand" "+r"))
1681 "TARGET_PARTIAL_REG_STALL"
1683 [(set_attr "type" "imov")
1684 (set_attr "mode" "HI")
1685 (set_attr "pent_pair" "np")
1686 (set_attr "athlon_decode" "vector")])
1688 (define_expand "movstricthi"
1689 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1690 (match_operand:HI 1 "general_operand" ""))]
1691 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1693 /* Don't generate memory->memory moves, go through a register */
1694 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1695 operands[1] = force_reg (HImode, operands[1]);
1698 (define_insn "*movstricthi_1"
1699 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1700 (match_operand:HI 1 "general_operand" "rn,m"))]
1701 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1702 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1703 "mov{w}\t{%1, %0|%0, %1}"
1704 [(set_attr "type" "imov")
1705 (set_attr "mode" "HI")])
1707 (define_insn "*movstricthi_xor"
1708 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1709 (match_operand:HI 1 "const0_operand" ""))
1710 (clobber (reg:CC FLAGS_REG))]
1712 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1714 [(set_attr "type" "alu1")
1715 (set_attr "mode" "HI")
1716 (set_attr "length_immediate" "0")])
1718 (define_expand "movqi"
1719 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1720 (match_operand:QI 1 "general_operand" ""))]
1722 "ix86_expand_move (QImode, operands); DONE;")
1724 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1725 ;; "push a byte". But actually we use pushl, which has the effect
1726 ;; of rounding the amount pushed up to a word.
1728 (define_insn "*pushqi2"
1729 [(set (match_operand:QI 0 "push_operand" "=X")
1730 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1733 [(set_attr "type" "push")
1734 (set_attr "mode" "SI")])
1736 ;; For 64BIT abi we always round up to 8 bytes.
1737 (define_insn "*pushqi2_rex64"
1738 [(set (match_operand:QI 0 "push_operand" "=X")
1739 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "DI")])
1745 ;; Situation is quite tricky about when to choose full sized (SImode) move
1746 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1747 ;; partial register dependency machines (such as AMD Athlon), where QImode
1748 ;; moves issue extra dependency and for partial register stalls machines
1749 ;; that don't use QImode patterns (and QImode move cause stall on the next
1752 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1753 ;; register stall machines with, where we use QImode instructions, since
1754 ;; partial register stall can be caused there. Then we use movzx.
1755 (define_insn "*movqi_1"
1756 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1757 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1758 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1760 switch (get_attr_type (insn))
1763 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1764 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1766 if (get_attr_mode (insn) == MODE_SI)
1767 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1769 return "mov{b}\t{%1, %0|%0, %1}";
1773 (cond [(and (eq_attr "alternative" "5")
1774 (not (match_operand:QI 1 "aligned_operand" "")))
1775 (const_string "imovx")
1776 (ne (symbol_ref "optimize_size") (const_int 0))
1777 (const_string "imov")
1778 (and (eq_attr "alternative" "3")
1779 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1781 (eq (symbol_ref "TARGET_QIMODE_MATH")
1783 (const_string "imov")
1784 (eq_attr "alternative" "3,5")
1785 (const_string "imovx")
1786 (and (ne (symbol_ref "TARGET_MOVX")
1788 (eq_attr "alternative" "2"))
1789 (const_string "imovx")
1791 (const_string "imov")))
1793 (cond [(eq_attr "alternative" "3,4,5")
1795 (eq_attr "alternative" "6")
1797 (eq_attr "type" "imovx")
1799 (and (eq_attr "type" "imov")
1800 (and (eq_attr "alternative" "0,1")
1801 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1803 (and (eq (symbol_ref "optimize_size")
1805 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1808 ;; Avoid partial register stalls when not using QImode arithmetic
1809 (and (eq_attr "type" "imov")
1810 (and (eq_attr "alternative" "0,1")
1811 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1813 (eq (symbol_ref "TARGET_QIMODE_MATH")
1817 (const_string "QI")))])
1819 (define_insn "*swapqi_1"
1820 [(set (match_operand:QI 0 "register_operand" "+r")
1821 (match_operand:QI 1 "register_operand" "+r"))
1824 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1826 [(set_attr "type" "imov")
1827 (set_attr "mode" "SI")
1828 (set_attr "pent_pair" "np")
1829 (set_attr "athlon_decode" "vector")
1830 (set_attr "amdfam10_decode" "vector")])
1832 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1833 (define_insn "*swapqi_2"
1834 [(set (match_operand:QI 0 "register_operand" "+q")
1835 (match_operand:QI 1 "register_operand" "+q"))
1838 "TARGET_PARTIAL_REG_STALL"
1840 [(set_attr "type" "imov")
1841 (set_attr "mode" "QI")
1842 (set_attr "pent_pair" "np")
1843 (set_attr "athlon_decode" "vector")])
1845 (define_expand "movstrictqi"
1846 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1847 (match_operand:QI 1 "general_operand" ""))]
1848 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1850 /* Don't generate memory->memory moves, go through a register. */
1851 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1852 operands[1] = force_reg (QImode, operands[1]);
1855 (define_insn "*movstrictqi_1"
1856 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1857 (match_operand:QI 1 "general_operand" "*qn,m"))]
1858 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1859 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1860 "mov{b}\t{%1, %0|%0, %1}"
1861 [(set_attr "type" "imov")
1862 (set_attr "mode" "QI")])
1864 (define_insn "*movstrictqi_xor"
1865 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1866 (match_operand:QI 1 "const0_operand" ""))
1867 (clobber (reg:CC FLAGS_REG))]
1868 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1870 [(set_attr "type" "alu1")
1871 (set_attr "mode" "QI")
1872 (set_attr "length_immediate" "0")])
1874 (define_insn "*movsi_extv_1"
1875 [(set (match_operand:SI 0 "register_operand" "=R")
1876 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1880 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1881 [(set_attr "type" "imovx")
1882 (set_attr "mode" "SI")])
1884 (define_insn "*movhi_extv_1"
1885 [(set (match_operand:HI 0 "register_operand" "=R")
1886 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1890 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1891 [(set_attr "type" "imovx")
1892 (set_attr "mode" "SI")])
1894 (define_insn "*movqi_extv_1"
1895 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1896 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1901 switch (get_attr_type (insn))
1904 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1906 return "mov{b}\t{%h1, %0|%0, %h1}";
1910 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1911 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1912 (ne (symbol_ref "TARGET_MOVX")
1914 (const_string "imovx")
1915 (const_string "imov")))
1917 (if_then_else (eq_attr "type" "imovx")
1919 (const_string "QI")))])
1921 (define_insn "*movqi_extv_1_rex64"
1922 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1923 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1928 switch (get_attr_type (insn))
1931 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1933 return "mov{b}\t{%h1, %0|%0, %h1}";
1937 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1938 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1939 (ne (symbol_ref "TARGET_MOVX")
1941 (const_string "imovx")
1942 (const_string "imov")))
1944 (if_then_else (eq_attr "type" "imovx")
1946 (const_string "QI")))])
1948 ;; Stores and loads of ax to arbitrary constant address.
1949 ;; We fake an second form of instruction to force reload to load address
1950 ;; into register when rax is not available
1951 (define_insn "*movabsqi_1_rex64"
1952 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1953 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1954 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1956 movabs{b}\t{%1, %P0|%P0, %1}
1957 mov{b}\t{%1, %a0|%a0, %1}"
1958 [(set_attr "type" "imov")
1959 (set_attr "modrm" "0,*")
1960 (set_attr "length_address" "8,0")
1961 (set_attr "length_immediate" "0,*")
1962 (set_attr "memory" "store")
1963 (set_attr "mode" "QI")])
1965 (define_insn "*movabsqi_2_rex64"
1966 [(set (match_operand:QI 0 "register_operand" "=a,r")
1967 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1968 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1970 movabs{b}\t{%P1, %0|%0, %P1}
1971 mov{b}\t{%a1, %0|%0, %a1}"
1972 [(set_attr "type" "imov")
1973 (set_attr "modrm" "0,*")
1974 (set_attr "length_address" "8,0")
1975 (set_attr "length_immediate" "0")
1976 (set_attr "memory" "load")
1977 (set_attr "mode" "QI")])
1979 (define_insn "*movdi_extzv_1"
1980 [(set (match_operand:DI 0 "register_operand" "=R")
1981 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1985 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1986 [(set_attr "type" "imovx")
1987 (set_attr "mode" "DI")])
1989 (define_insn "*movsi_extzv_1"
1990 [(set (match_operand:SI 0 "register_operand" "=R")
1991 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1995 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1996 [(set_attr "type" "imovx")
1997 (set_attr "mode" "SI")])
1999 (define_insn "*movqi_extzv_2"
2000 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2001 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2006 switch (get_attr_type (insn))
2009 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2011 return "mov{b}\t{%h1, %0|%0, %h1}";
2015 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2016 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2017 (ne (symbol_ref "TARGET_MOVX")
2019 (const_string "imovx")
2020 (const_string "imov")))
2022 (if_then_else (eq_attr "type" "imovx")
2024 (const_string "QI")))])
2026 (define_insn "*movqi_extzv_2_rex64"
2027 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2028 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2033 switch (get_attr_type (insn))
2036 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2038 return "mov{b}\t{%h1, %0|%0, %h1}";
2042 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2043 (ne (symbol_ref "TARGET_MOVX")
2045 (const_string "imovx")
2046 (const_string "imov")))
2048 (if_then_else (eq_attr "type" "imovx")
2050 (const_string "QI")))])
2052 (define_insn "movsi_insv_1"
2053 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2056 (match_operand:SI 1 "general_operand" "Qmn"))]
2058 "mov{b}\t{%b1, %h0|%h0, %b1}"
2059 [(set_attr "type" "imov")
2060 (set_attr "mode" "QI")])
2062 (define_insn "*movsi_insv_1_rex64"
2063 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2066 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2068 "mov{b}\t{%b1, %h0|%h0, %b1}"
2069 [(set_attr "type" "imov")
2070 (set_attr "mode" "QI")])
2072 (define_insn "movdi_insv_1_rex64"
2073 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2076 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2078 "mov{b}\t{%b1, %h0|%h0, %b1}"
2079 [(set_attr "type" "imov")
2080 (set_attr "mode" "QI")])
2082 (define_insn "*movqi_insv_2"
2083 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2086 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2089 "mov{b}\t{%h1, %h0|%h0, %h1}"
2090 [(set_attr "type" "imov")
2091 (set_attr "mode" "QI")])
2093 (define_expand "movdi"
2094 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2095 (match_operand:DI 1 "general_operand" ""))]
2097 "ix86_expand_move (DImode, operands); DONE;")
2099 (define_insn "*pushdi"
2100 [(set (match_operand:DI 0 "push_operand" "=<")
2101 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2105 (define_insn "*pushdi2_rex64"
2106 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2107 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2112 [(set_attr "type" "push,multi")
2113 (set_attr "mode" "DI")])
2115 ;; Convert impossible pushes of immediate to existing instructions.
2116 ;; First try to get scratch register and go through it. In case this
2117 ;; fails, push sign extended lower part first and then overwrite
2118 ;; upper part by 32bit move.
2120 [(match_scratch:DI 2 "r")
2121 (set (match_operand:DI 0 "push_operand" "")
2122 (match_operand:DI 1 "immediate_operand" ""))]
2123 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2124 && !x86_64_immediate_operand (operands[1], DImode)"
2125 [(set (match_dup 2) (match_dup 1))
2126 (set (match_dup 0) (match_dup 2))]
2129 ;; We need to define this as both peepholer and splitter for case
2130 ;; peephole2 pass is not run.
2131 ;; "&& 1" is needed to keep it from matching the previous pattern.
2133 [(set (match_operand:DI 0 "push_operand" "")
2134 (match_operand:DI 1 "immediate_operand" ""))]
2135 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2136 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2137 [(set (match_dup 0) (match_dup 1))
2138 (set (match_dup 2) (match_dup 3))]
2139 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2140 operands[1] = gen_lowpart (DImode, operands[2]);
2141 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2146 [(set (match_operand:DI 0 "push_operand" "")
2147 (match_operand:DI 1 "immediate_operand" ""))]
2148 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2149 ? epilogue_completed : reload_completed)
2150 && !symbolic_operand (operands[1], DImode)
2151 && !x86_64_immediate_operand (operands[1], DImode)"
2152 [(set (match_dup 0) (match_dup 1))
2153 (set (match_dup 2) (match_dup 3))]
2154 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2155 operands[1] = gen_lowpart (DImode, operands[2]);
2156 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2160 (define_insn "*pushdi2_prologue_rex64"
2161 [(set (match_operand:DI 0 "push_operand" "=<")
2162 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2163 (clobber (mem:BLK (scratch)))]
2166 [(set_attr "type" "push")
2167 (set_attr "mode" "DI")])
2169 (define_insn "*popdi1_epilogue_rex64"
2170 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2171 (mem:DI (reg:DI SP_REG)))
2172 (set (reg:DI SP_REG)
2173 (plus:DI (reg:DI SP_REG) (const_int 8)))
2174 (clobber (mem:BLK (scratch)))]
2177 [(set_attr "type" "pop")
2178 (set_attr "mode" "DI")])
2180 (define_insn "popdi1"
2181 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2182 (mem:DI (reg:DI SP_REG)))
2183 (set (reg:DI SP_REG)
2184 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2187 [(set_attr "type" "pop")
2188 (set_attr "mode" "DI")])
2190 (define_insn "*movdi_xor_rex64"
2191 [(set (match_operand:DI 0 "register_operand" "=r")
2192 (match_operand:DI 1 "const0_operand" ""))
2193 (clobber (reg:CC FLAGS_REG))]
2194 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2195 && reload_completed"
2197 [(set_attr "type" "alu1")
2198 (set_attr "mode" "SI")
2199 (set_attr "length_immediate" "0")])
2201 (define_insn "*movdi_or_rex64"
2202 [(set (match_operand:DI 0 "register_operand" "=r")
2203 (match_operand:DI 1 "const_int_operand" "i"))
2204 (clobber (reg:CC FLAGS_REG))]
2205 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2207 && operands[1] == constm1_rtx"
2209 operands[1] = constm1_rtx;
2210 return "or{q}\t{%1, %0|%0, %1}";
2212 [(set_attr "type" "alu1")
2213 (set_attr "mode" "DI")
2214 (set_attr "length_immediate" "1")])
2216 (define_insn "*movdi_2"
2217 [(set (match_operand:DI 0 "nonimmediate_operand"
2218 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2219 (match_operand:DI 1 "general_operand"
2220 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2221 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2226 movq\t{%1, %0|%0, %1}
2227 movq\t{%1, %0|%0, %1}
2229 movq\t{%1, %0|%0, %1}
2230 movdqa\t{%1, %0|%0, %1}
2231 movq\t{%1, %0|%0, %1}
2233 movlps\t{%1, %0|%0, %1}
2234 movaps\t{%1, %0|%0, %1}
2235 movlps\t{%1, %0|%0, %1}"
2236 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2237 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2240 [(set (match_operand:DI 0 "push_operand" "")
2241 (match_operand:DI 1 "general_operand" ""))]
2242 "!TARGET_64BIT && reload_completed
2243 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2245 "ix86_split_long_move (operands); DONE;")
2247 ;; %%% This multiword shite has got to go.
2249 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2250 (match_operand:DI 1 "general_operand" ""))]
2251 "!TARGET_64BIT && reload_completed
2252 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2253 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2255 "ix86_split_long_move (operands); DONE;")
2257 (define_insn "*movdi_1_rex64"
2258 [(set (match_operand:DI 0 "nonimmediate_operand"
2259 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2260 (match_operand:DI 1 "general_operand"
2261 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2262 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2264 switch (get_attr_type (insn))
2267 if (SSE_REG_P (operands[0]))
2268 return "movq2dq\t{%1, %0|%0, %1}";
2270 return "movdq2q\t{%1, %0|%0, %1}";
2273 if (get_attr_mode (insn) == MODE_TI)
2274 return "movdqa\t{%1, %0|%0, %1}";
2278 /* Moves from and into integer register is done using movd
2279 opcode with REX prefix. */
2280 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2281 return "movd\t{%1, %0|%0, %1}";
2282 return "movq\t{%1, %0|%0, %1}";
2286 return "pxor\t%0, %0";
2292 return "lea{q}\t{%a1, %0|%0, %a1}";
2295 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2296 if (get_attr_mode (insn) == MODE_SI)
2297 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2298 else if (which_alternative == 2)
2299 return "movabs{q}\t{%1, %0|%0, %1}";
2301 return "mov{q}\t{%1, %0|%0, %1}";
2305 (cond [(eq_attr "alternative" "5")
2306 (const_string "mmxadd")
2307 (eq_attr "alternative" "6,7,8,9,10")
2308 (const_string "mmxmov")
2309 (eq_attr "alternative" "11")
2310 (const_string "sselog1")
2311 (eq_attr "alternative" "12,13,14,15,16")
2312 (const_string "ssemov")
2313 (eq_attr "alternative" "17,18")
2314 (const_string "ssecvt")
2315 (eq_attr "alternative" "4")
2316 (const_string "multi")
2317 (match_operand:DI 1 "pic_32bit_operand" "")
2318 (const_string "lea")
2320 (const_string "imov")))
2321 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2322 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2323 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2325 ;; Stores and loads of ax to arbitrary constant address.
2326 ;; We fake an second form of instruction to force reload to load address
2327 ;; into register when rax is not available
2328 (define_insn "*movabsdi_1_rex64"
2329 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2330 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2331 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2333 movabs{q}\t{%1, %P0|%P0, %1}
2334 mov{q}\t{%1, %a0|%a0, %1}"
2335 [(set_attr "type" "imov")
2336 (set_attr "modrm" "0,*")
2337 (set_attr "length_address" "8,0")
2338 (set_attr "length_immediate" "0,*")
2339 (set_attr "memory" "store")
2340 (set_attr "mode" "DI")])
2342 (define_insn "*movabsdi_2_rex64"
2343 [(set (match_operand:DI 0 "register_operand" "=a,r")
2344 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2345 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2347 movabs{q}\t{%P1, %0|%0, %P1}
2348 mov{q}\t{%a1, %0|%0, %a1}"
2349 [(set_attr "type" "imov")
2350 (set_attr "modrm" "0,*")
2351 (set_attr "length_address" "8,0")
2352 (set_attr "length_immediate" "0")
2353 (set_attr "memory" "load")
2354 (set_attr "mode" "DI")])
2356 ;; Convert impossible stores of immediate to existing instructions.
2357 ;; First try to get scratch register and go through it. In case this
2358 ;; fails, move by 32bit parts.
2360 [(match_scratch:DI 2 "r")
2361 (set (match_operand:DI 0 "memory_operand" "")
2362 (match_operand:DI 1 "immediate_operand" ""))]
2363 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2364 && !x86_64_immediate_operand (operands[1], DImode)"
2365 [(set (match_dup 2) (match_dup 1))
2366 (set (match_dup 0) (match_dup 2))]
2369 ;; We need to define this as both peepholer and splitter for case
2370 ;; peephole2 pass is not run.
2371 ;; "&& 1" is needed to keep it from matching the previous pattern.
2373 [(set (match_operand:DI 0 "memory_operand" "")
2374 (match_operand:DI 1 "immediate_operand" ""))]
2375 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2376 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2377 [(set (match_dup 2) (match_dup 3))
2378 (set (match_dup 4) (match_dup 5))]
2379 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2382 [(set (match_operand:DI 0 "memory_operand" "")
2383 (match_operand:DI 1 "immediate_operand" ""))]
2384 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2385 ? epilogue_completed : reload_completed)
2386 && !symbolic_operand (operands[1], DImode)
2387 && !x86_64_immediate_operand (operands[1], DImode)"
2388 [(set (match_dup 2) (match_dup 3))
2389 (set (match_dup 4) (match_dup 5))]
2390 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2392 (define_insn "*swapdi_rex64"
2393 [(set (match_operand:DI 0 "register_operand" "+r")
2394 (match_operand:DI 1 "register_operand" "+r"))
2399 [(set_attr "type" "imov")
2400 (set_attr "mode" "DI")
2401 (set_attr "pent_pair" "np")
2402 (set_attr "athlon_decode" "vector")
2403 (set_attr "amdfam10_decode" "double")])
2405 (define_expand "movti"
2406 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2407 (match_operand:TI 1 "nonimmediate_operand" ""))]
2408 "TARGET_SSE || TARGET_64BIT"
2411 ix86_expand_move (TImode, operands);
2412 else if (push_operand (operands[0], TImode))
2413 ix86_expand_push (TImode, operands[1]);
2415 ix86_expand_vector_move (TImode, operands);
2419 (define_insn "*movti_internal"
2420 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2421 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2422 "TARGET_SSE && !TARGET_64BIT
2423 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2425 switch (which_alternative)
2428 if (get_attr_mode (insn) == MODE_V4SF)
2429 return "xorps\t%0, %0";
2431 return "pxor\t%0, %0";
2434 /* TDmode values are passed as TImode on the stack. Moving them
2435 to stack may result in unaligned memory access. */
2436 if (misaligned_operand (operands[0], TImode)
2437 || misaligned_operand (operands[1], TImode))
2439 if (get_attr_mode (insn) == MODE_V4SF)
2440 return "movups\t{%1, %0|%0, %1}";
2442 return "movdqu\t{%1, %0|%0, %1}";
2446 if (get_attr_mode (insn) == MODE_V4SF)
2447 return "movaps\t{%1, %0|%0, %1}";
2449 return "movdqa\t{%1, %0|%0, %1}";
2455 [(set_attr "type" "sselog1,ssemov,ssemov")
2457 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2458 (ne (symbol_ref "optimize_size") (const_int 0)))
2459 (const_string "V4SF")
2460 (and (eq_attr "alternative" "2")
2461 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2463 (const_string "V4SF")]
2464 (const_string "TI")))])
2466 (define_insn "*movti_rex64"
2467 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2468 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2470 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2472 switch (which_alternative)
2478 if (get_attr_mode (insn) == MODE_V4SF)
2479 return "xorps\t%0, %0";
2481 return "pxor\t%0, %0";
2484 /* TDmode values are passed as TImode on the stack. Moving them
2485 to stack may result in unaligned memory access. */
2486 if (misaligned_operand (operands[0], TImode)
2487 || misaligned_operand (operands[1], TImode))
2489 if (get_attr_mode (insn) == MODE_V4SF)
2490 return "movups\t{%1, %0|%0, %1}";
2492 return "movdqu\t{%1, %0|%0, %1}";
2496 if (get_attr_mode (insn) == MODE_V4SF)
2497 return "movaps\t{%1, %0|%0, %1}";
2499 return "movdqa\t{%1, %0|%0, %1}";
2505 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2507 (cond [(eq_attr "alternative" "2,3")
2509 (ne (symbol_ref "optimize_size")
2511 (const_string "V4SF")
2512 (const_string "TI"))
2513 (eq_attr "alternative" "4")
2515 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2517 (ne (symbol_ref "optimize_size")
2519 (const_string "V4SF")
2520 (const_string "TI"))]
2521 (const_string "DI")))])
2524 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2525 (match_operand:TI 1 "general_operand" ""))]
2526 "reload_completed && !SSE_REG_P (operands[0])
2527 && !SSE_REG_P (operands[1])"
2529 "ix86_split_long_move (operands); DONE;")
2531 ;; This expands to what emit_move_complex would generate if we didn't
2532 ;; have a movti pattern. Having this avoids problems with reload on
2533 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2534 ;; to have around all the time.
2535 (define_expand "movcdi"
2536 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2537 (match_operand:CDI 1 "general_operand" ""))]
2540 if (push_operand (operands[0], CDImode))
2541 emit_move_complex_push (CDImode, operands[0], operands[1]);
2543 emit_move_complex_parts (operands[0], operands[1]);
2547 (define_expand "movsf"
2548 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2549 (match_operand:SF 1 "general_operand" ""))]
2551 "ix86_expand_move (SFmode, operands); DONE;")
2553 (define_insn "*pushsf"
2554 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2555 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2558 /* Anything else should be already split before reg-stack. */
2559 gcc_assert (which_alternative == 1);
2560 return "push{l}\t%1";
2562 [(set_attr "type" "multi,push,multi")
2563 (set_attr "unit" "i387,*,*")
2564 (set_attr "mode" "SF,SI,SF")])
2566 (define_insn "*pushsf_rex64"
2567 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2568 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2571 /* Anything else should be already split before reg-stack. */
2572 gcc_assert (which_alternative == 1);
2573 return "push{q}\t%q1";
2575 [(set_attr "type" "multi,push,multi")
2576 (set_attr "unit" "i387,*,*")
2577 (set_attr "mode" "SF,DI,SF")])
2580 [(set (match_operand:SF 0 "push_operand" "")
2581 (match_operand:SF 1 "memory_operand" ""))]
2583 && MEM_P (operands[1])
2584 && (operands[2] = find_constant_src (insn))"
2589 ;; %%% Kill this when call knows how to work this out.
2591 [(set (match_operand:SF 0 "push_operand" "")
2592 (match_operand:SF 1 "any_fp_register_operand" ""))]
2594 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2595 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2598 [(set (match_operand:SF 0 "push_operand" "")
2599 (match_operand:SF 1 "any_fp_register_operand" ""))]
2601 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2602 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2604 (define_insn "*movsf_1"
2605 [(set (match_operand:SF 0 "nonimmediate_operand"
2606 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2607 (match_operand:SF 1 "general_operand"
2608 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2609 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2610 && (reload_in_progress || reload_completed
2611 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2612 || (!TARGET_SSE_MATH && optimize_size
2613 && standard_80387_constant_p (operands[1]))
2614 || GET_CODE (operands[1]) != CONST_DOUBLE
2615 || memory_operand (operands[0], SFmode))"
2617 switch (which_alternative)
2621 return output_387_reg_move (insn, operands);
2624 return standard_80387_constant_opcode (operands[1]);
2628 return "mov{l}\t{%1, %0|%0, %1}";
2630 if (get_attr_mode (insn) == MODE_TI)
2631 return "pxor\t%0, %0";
2633 return "xorps\t%0, %0";
2635 if (get_attr_mode (insn) == MODE_V4SF)
2636 return "movaps\t{%1, %0|%0, %1}";
2638 return "movss\t{%1, %0|%0, %1}";
2640 return "movss\t{%1, %0|%0, %1}";
2643 case 12: case 13: case 14: case 15:
2644 return "movd\t{%1, %0|%0, %1}";
2647 return "movq\t{%1, %0|%0, %1}";
2653 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2655 (cond [(eq_attr "alternative" "3,4,9,10")
2657 (eq_attr "alternative" "5")
2659 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2661 (ne (symbol_ref "TARGET_SSE2")
2663 (eq (symbol_ref "optimize_size")
2666 (const_string "V4SF"))
2667 /* For architectures resolving dependencies on
2668 whole SSE registers use APS move to break dependency
2669 chains, otherwise use short move to avoid extra work.
2671 Do the same for architectures resolving dependencies on
2672 the parts. While in DF mode it is better to always handle
2673 just register parts, the SF mode is different due to lack
2674 of instructions to load just part of the register. It is
2675 better to maintain the whole registers in single format
2676 to avoid problems on using packed logical operations. */
2677 (eq_attr "alternative" "6")
2679 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2681 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2683 (const_string "V4SF")
2684 (const_string "SF"))
2685 (eq_attr "alternative" "11")
2686 (const_string "DI")]
2687 (const_string "SF")))])
2689 (define_insn "*swapsf"
2690 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2691 (match_operand:SF 1 "fp_register_operand" "+f"))
2694 "reload_completed || TARGET_80387"
2696 if (STACK_TOP_P (operands[0]))
2701 [(set_attr "type" "fxch")
2702 (set_attr "mode" "SF")])
2704 (define_expand "movdf"
2705 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2706 (match_operand:DF 1 "general_operand" ""))]
2708 "ix86_expand_move (DFmode, operands); DONE;")
2710 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2711 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2712 ;; On the average, pushdf using integers can be still shorter. Allow this
2713 ;; pattern for optimize_size too.
2715 (define_insn "*pushdf_nointeger"
2716 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2717 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2718 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2720 /* This insn should be already split before reg-stack. */
2723 [(set_attr "type" "multi")
2724 (set_attr "unit" "i387,*,*,*")
2725 (set_attr "mode" "DF,SI,SI,DF")])
2727 (define_insn "*pushdf_integer"
2728 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2729 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2730 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2732 /* This insn should be already split before reg-stack. */
2735 [(set_attr "type" "multi")
2736 (set_attr "unit" "i387,*,*")
2737 (set_attr "mode" "DF,SI,DF")])
2739 ;; %%% Kill this when call knows how to work this out.
2741 [(set (match_operand:DF 0 "push_operand" "")
2742 (match_operand:DF 1 "any_fp_register_operand" ""))]
2744 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2745 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2749 [(set (match_operand:DF 0 "push_operand" "")
2750 (match_operand:DF 1 "general_operand" ""))]
2753 "ix86_split_long_move (operands); DONE;")
2755 ;; Moving is usually shorter when only FP registers are used. This separate
2756 ;; movdf pattern avoids the use of integer registers for FP operations
2757 ;; when optimizing for size.
2759 (define_insn "*movdf_nointeger"
2760 [(set (match_operand:DF 0 "nonimmediate_operand"
2761 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2762 (match_operand:DF 1 "general_operand"
2763 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2764 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2765 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2766 && (reload_in_progress || reload_completed
2767 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2768 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2769 && !memory_operand (operands[0], DFmode)
2770 && standard_80387_constant_p (operands[1]))
2771 || GET_CODE (operands[1]) != CONST_DOUBLE
2773 || !TARGET_MEMORY_MISMATCH_STALL
2774 || reload_in_progress || reload_completed)
2775 && memory_operand (operands[0], DFmode)))"
2777 switch (which_alternative)
2781 return output_387_reg_move (insn, operands);
2784 return standard_80387_constant_opcode (operands[1]);
2790 switch (get_attr_mode (insn))
2793 return "xorps\t%0, %0";
2795 return "xorpd\t%0, %0";
2797 return "pxor\t%0, %0";
2804 switch (get_attr_mode (insn))
2807 return "movaps\t{%1, %0|%0, %1}";
2809 return "movapd\t{%1, %0|%0, %1}";
2811 return "movdqa\t{%1, %0|%0, %1}";
2813 return "movq\t{%1, %0|%0, %1}";
2815 return "movsd\t{%1, %0|%0, %1}";
2817 return "movlpd\t{%1, %0|%0, %1}";
2819 return "movlps\t{%1, %0|%0, %1}";
2828 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2830 (cond [(eq_attr "alternative" "0,1,2")
2832 (eq_attr "alternative" "3,4")
2835 /* For SSE1, we have many fewer alternatives. */
2836 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2837 (cond [(eq_attr "alternative" "5,6")
2838 (const_string "V4SF")
2840 (const_string "V2SF"))
2842 /* xorps is one byte shorter. */
2843 (eq_attr "alternative" "5")
2844 (cond [(ne (symbol_ref "optimize_size")
2846 (const_string "V4SF")
2847 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2851 (const_string "V2DF"))
2853 /* For architectures resolving dependencies on
2854 whole SSE registers use APD move to break dependency
2855 chains, otherwise use short move to avoid extra work.
2857 movaps encodes one byte shorter. */
2858 (eq_attr "alternative" "6")
2860 [(ne (symbol_ref "optimize_size")
2862 (const_string "V4SF")
2863 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2865 (const_string "V2DF")
2867 (const_string "DF"))
2868 /* For architectures resolving dependencies on register
2869 parts we may avoid extra work to zero out upper part
2871 (eq_attr "alternative" "7")
2873 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2875 (const_string "V1DF")
2876 (const_string "DF"))
2878 (const_string "DF")))])
2880 (define_insn "*movdf_integer_rex64"
2881 [(set (match_operand:DF 0 "nonimmediate_operand"
2882 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2883 (match_operand:DF 1 "general_operand"
2884 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2885 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2886 && (reload_in_progress || reload_completed
2887 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2888 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2889 && standard_80387_constant_p (operands[1]))
2890 || GET_CODE (operands[1]) != CONST_DOUBLE
2891 || memory_operand (operands[0], DFmode))"
2893 switch (which_alternative)
2897 return output_387_reg_move (insn, operands);
2900 return standard_80387_constant_opcode (operands[1]);
2907 switch (get_attr_mode (insn))
2910 return "xorps\t%0, %0";
2912 return "xorpd\t%0, %0";
2914 return "pxor\t%0, %0";
2921 switch (get_attr_mode (insn))
2924 return "movaps\t{%1, %0|%0, %1}";
2926 return "movapd\t{%1, %0|%0, %1}";
2928 return "movdqa\t{%1, %0|%0, %1}";
2930 return "movq\t{%1, %0|%0, %1}";
2932 return "movsd\t{%1, %0|%0, %1}";
2934 return "movlpd\t{%1, %0|%0, %1}";
2936 return "movlps\t{%1, %0|%0, %1}";
2943 return "movd\t{%1, %0|%0, %1}";
2949 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2951 (cond [(eq_attr "alternative" "0,1,2")
2953 (eq_attr "alternative" "3,4,9,10")
2956 /* For SSE1, we have many fewer alternatives. */
2957 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2958 (cond [(eq_attr "alternative" "5,6")
2959 (const_string "V4SF")
2961 (const_string "V2SF"))
2963 /* xorps is one byte shorter. */
2964 (eq_attr "alternative" "5")
2965 (cond [(ne (symbol_ref "optimize_size")
2967 (const_string "V4SF")
2968 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2972 (const_string "V2DF"))
2974 /* For architectures resolving dependencies on
2975 whole SSE registers use APD move to break dependency
2976 chains, otherwise use short move to avoid extra work.
2978 movaps encodes one byte shorter. */
2979 (eq_attr "alternative" "6")
2981 [(ne (symbol_ref "optimize_size")
2983 (const_string "V4SF")
2984 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2986 (const_string "V2DF")
2988 (const_string "DF"))
2989 /* For architectures resolving dependencies on register
2990 parts we may avoid extra work to zero out upper part
2992 (eq_attr "alternative" "7")
2994 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2996 (const_string "V1DF")
2997 (const_string "DF"))
2999 (const_string "DF")))])
3001 (define_insn "*movdf_integer"
3002 [(set (match_operand:DF 0 "nonimmediate_operand"
3003 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3004 (match_operand:DF 1 "general_operand"
3005 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3006 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3007 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3008 && (reload_in_progress || reload_completed
3009 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3010 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3011 && standard_80387_constant_p (operands[1]))
3012 || GET_CODE (operands[1]) != CONST_DOUBLE
3013 || memory_operand (operands[0], DFmode))"
3015 switch (which_alternative)
3019 return output_387_reg_move (insn, operands);
3022 return standard_80387_constant_opcode (operands[1]);
3029 switch (get_attr_mode (insn))
3032 return "xorps\t%0, %0";
3034 return "xorpd\t%0, %0";
3036 return "pxor\t%0, %0";
3043 switch (get_attr_mode (insn))
3046 return "movaps\t{%1, %0|%0, %1}";
3048 return "movapd\t{%1, %0|%0, %1}";
3050 return "movdqa\t{%1, %0|%0, %1}";
3052 return "movq\t{%1, %0|%0, %1}";
3054 return "movsd\t{%1, %0|%0, %1}";
3056 return "movlpd\t{%1, %0|%0, %1}";
3058 return "movlps\t{%1, %0|%0, %1}";
3067 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3069 (cond [(eq_attr "alternative" "0,1,2")
3071 (eq_attr "alternative" "3,4")
3074 /* For SSE1, we have many fewer alternatives. */
3075 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3076 (cond [(eq_attr "alternative" "5,6")
3077 (const_string "V4SF")
3079 (const_string "V2SF"))
3081 /* xorps is one byte shorter. */
3082 (eq_attr "alternative" "5")
3083 (cond [(ne (symbol_ref "optimize_size")
3085 (const_string "V4SF")
3086 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3090 (const_string "V2DF"))
3092 /* For architectures resolving dependencies on
3093 whole SSE registers use APD move to break dependency
3094 chains, otherwise use short move to avoid extra work.
3096 movaps encodes one byte shorter. */
3097 (eq_attr "alternative" "6")
3099 [(ne (symbol_ref "optimize_size")
3101 (const_string "V4SF")
3102 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3104 (const_string "V2DF")
3106 (const_string "DF"))
3107 /* For architectures resolving dependencies on register
3108 parts we may avoid extra work to zero out upper part
3110 (eq_attr "alternative" "7")
3112 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3114 (const_string "V1DF")
3115 (const_string "DF"))
3117 (const_string "DF")))])
3120 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3121 (match_operand:DF 1 "general_operand" ""))]
3123 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3124 && ! (ANY_FP_REG_P (operands[0]) ||
3125 (GET_CODE (operands[0]) == SUBREG
3126 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3127 && ! (ANY_FP_REG_P (operands[1]) ||
3128 (GET_CODE (operands[1]) == SUBREG
3129 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3131 "ix86_split_long_move (operands); DONE;")
3133 (define_insn "*swapdf"
3134 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3135 (match_operand:DF 1 "fp_register_operand" "+f"))
3138 "reload_completed || TARGET_80387"
3140 if (STACK_TOP_P (operands[0]))
3145 [(set_attr "type" "fxch")
3146 (set_attr "mode" "DF")])
3148 (define_expand "movxf"
3149 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3150 (match_operand:XF 1 "general_operand" ""))]
3152 "ix86_expand_move (XFmode, operands); DONE;")
3154 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3155 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3156 ;; Pushing using integer instructions is longer except for constants
3157 ;; and direct memory references.
3158 ;; (assuming that any given constant is pushed only once, but this ought to be
3159 ;; handled elsewhere).
3161 (define_insn "*pushxf_nointeger"
3162 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3163 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3166 /* This insn should be already split before reg-stack. */
3169 [(set_attr "type" "multi")
3170 (set_attr "unit" "i387,*,*")
3171 (set_attr "mode" "XF,SI,SI")])
3173 (define_insn "*pushxf_integer"
3174 [(set (match_operand:XF 0 "push_operand" "=<,<")
3175 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3178 /* This insn should be already split before reg-stack. */
3181 [(set_attr "type" "multi")
3182 (set_attr "unit" "i387,*")
3183 (set_attr "mode" "XF,SI")])
3186 [(set (match_operand 0 "push_operand" "")
3187 (match_operand 1 "general_operand" ""))]
3189 && (GET_MODE (operands[0]) == XFmode
3190 || GET_MODE (operands[0]) == DFmode)
3191 && !ANY_FP_REG_P (operands[1])"
3193 "ix86_split_long_move (operands); DONE;")
3196 [(set (match_operand:XF 0 "push_operand" "")
3197 (match_operand:XF 1 "any_fp_register_operand" ""))]
3199 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3200 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3201 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3203 ;; Do not use integer registers when optimizing for size
3204 (define_insn "*movxf_nointeger"
3205 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3206 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3208 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3209 && (reload_in_progress || reload_completed
3210 || (optimize_size && standard_80387_constant_p (operands[1]))
3211 || GET_CODE (operands[1]) != CONST_DOUBLE
3212 || memory_operand (operands[0], XFmode))"
3214 switch (which_alternative)
3218 return output_387_reg_move (insn, operands);
3221 return standard_80387_constant_opcode (operands[1]);
3229 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3230 (set_attr "mode" "XF,XF,XF,SI,SI")])
3232 (define_insn "*movxf_integer"
3233 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3234 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3236 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3237 && (reload_in_progress || reload_completed
3238 || (optimize_size && standard_80387_constant_p (operands[1]))
3239 || GET_CODE (operands[1]) != CONST_DOUBLE
3240 || memory_operand (operands[0], XFmode))"
3242 switch (which_alternative)
3246 return output_387_reg_move (insn, operands);
3249 return standard_80387_constant_opcode (operands[1]);
3258 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3259 (set_attr "mode" "XF,XF,XF,SI,SI")])
3261 (define_expand "movtf"
3262 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3263 (match_operand:TF 1 "nonimmediate_operand" ""))]
3266 ix86_expand_move (TFmode, operands);
3270 (define_insn "*movtf_internal"
3271 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3272 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3274 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3276 switch (which_alternative)
3280 if (get_attr_mode (insn) == MODE_V4SF)
3281 return "movaps\t{%1, %0|%0, %1}";
3283 return "movdqa\t{%1, %0|%0, %1}";
3285 if (get_attr_mode (insn) == MODE_V4SF)
3286 return "xorps\t%0, %0";
3288 return "pxor\t%0, %0";
3296 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3298 (cond [(eq_attr "alternative" "0,2")
3300 (ne (symbol_ref "optimize_size")
3302 (const_string "V4SF")
3303 (const_string "TI"))
3304 (eq_attr "alternative" "1")
3306 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3308 (ne (symbol_ref "optimize_size")
3310 (const_string "V4SF")
3311 (const_string "TI"))]
3312 (const_string "DI")))])
3315 [(set (match_operand 0 "nonimmediate_operand" "")
3316 (match_operand 1 "general_operand" ""))]
3318 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3319 && GET_MODE (operands[0]) == XFmode
3320 && ! (ANY_FP_REG_P (operands[0]) ||
3321 (GET_CODE (operands[0]) == SUBREG
3322 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3323 && ! (ANY_FP_REG_P (operands[1]) ||
3324 (GET_CODE (operands[1]) == SUBREG
3325 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3327 "ix86_split_long_move (operands); DONE;")
3330 [(set (match_operand 0 "register_operand" "")
3331 (match_operand 1 "memory_operand" ""))]
3333 && MEM_P (operands[1])
3334 && (GET_MODE (operands[0]) == TFmode
3335 || GET_MODE (operands[0]) == XFmode
3336 || GET_MODE (operands[0]) == SFmode
3337 || GET_MODE (operands[0]) == DFmode)
3338 && (operands[2] = find_constant_src (insn))"
3339 [(set (match_dup 0) (match_dup 2))]
3341 rtx c = operands[2];
3342 rtx r = operands[0];
3344 if (GET_CODE (r) == SUBREG)
3349 if (!standard_sse_constant_p (c))
3352 else if (FP_REG_P (r))
3354 if (!standard_80387_constant_p (c))
3357 else if (MMX_REG_P (r))
3362 [(set (match_operand 0 "register_operand" "")
3363 (float_extend (match_operand 1 "memory_operand" "")))]
3365 && MEM_P (operands[1])
3366 && (GET_MODE (operands[0]) == TFmode
3367 || GET_MODE (operands[0]) == XFmode
3368 || GET_MODE (operands[0]) == SFmode
3369 || GET_MODE (operands[0]) == DFmode)
3370 && (operands[2] = find_constant_src (insn))"
3371 [(set (match_dup 0) (match_dup 2))]
3373 rtx c = operands[2];
3374 rtx r = operands[0];
3376 if (GET_CODE (r) == SUBREG)
3381 if (!standard_sse_constant_p (c))
3384 else if (FP_REG_P (r))
3386 if (!standard_80387_constant_p (c))
3389 else if (MMX_REG_P (r))
3393 (define_insn "swapxf"
3394 [(set (match_operand:XF 0 "register_operand" "+f")
3395 (match_operand:XF 1 "register_operand" "+f"))
3400 if (STACK_TOP_P (operands[0]))
3405 [(set_attr "type" "fxch")
3406 (set_attr "mode" "XF")])
3408 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3410 [(set (match_operand:X87MODEF 0 "register_operand" "")
3411 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3412 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3413 && (standard_80387_constant_p (operands[1]) == 8
3414 || standard_80387_constant_p (operands[1]) == 9)"
3415 [(set (match_dup 0)(match_dup 1))
3417 (neg:X87MODEF (match_dup 0)))]
3421 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3422 if (real_isnegzero (&r))
3423 operands[1] = CONST0_RTX (<MODE>mode);
3425 operands[1] = CONST1_RTX (<MODE>mode);
3429 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3430 (match_operand:TF 1 "general_operand" ""))]
3432 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3434 "ix86_split_long_move (operands); DONE;")
3436 ;; Zero extension instructions
3438 (define_expand "zero_extendhisi2"
3439 [(set (match_operand:SI 0 "register_operand" "")
3440 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3443 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3445 operands[1] = force_reg (HImode, operands[1]);
3446 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3451 (define_insn "zero_extendhisi2_and"
3452 [(set (match_operand:SI 0 "register_operand" "=r")
3453 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3454 (clobber (reg:CC FLAGS_REG))]
3455 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3457 [(set_attr "type" "alu1")
3458 (set_attr "mode" "SI")])
3461 [(set (match_operand:SI 0 "register_operand" "")
3462 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3463 (clobber (reg:CC FLAGS_REG))]
3464 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3465 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3466 (clobber (reg:CC FLAGS_REG))])]
3469 (define_insn "*zero_extendhisi2_movzwl"
3470 [(set (match_operand:SI 0 "register_operand" "=r")
3471 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3472 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3473 "movz{wl|x}\t{%1, %0|%0, %1}"
3474 [(set_attr "type" "imovx")
3475 (set_attr "mode" "SI")])
3477 (define_expand "zero_extendqihi2"
3479 [(set (match_operand:HI 0 "register_operand" "")
3480 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3481 (clobber (reg:CC FLAGS_REG))])]
3485 (define_insn "*zero_extendqihi2_and"
3486 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3487 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3488 (clobber (reg:CC FLAGS_REG))]
3489 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3491 [(set_attr "type" "alu1")
3492 (set_attr "mode" "HI")])
3494 (define_insn "*zero_extendqihi2_movzbw_and"
3495 [(set (match_operand:HI 0 "register_operand" "=r,r")
3496 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3497 (clobber (reg:CC FLAGS_REG))]
3498 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3500 [(set_attr "type" "imovx,alu1")
3501 (set_attr "mode" "HI")])
3503 ; zero extend to SImode here to avoid partial register stalls
3504 (define_insn "*zero_extendqihi2_movzbl"
3505 [(set (match_operand:HI 0 "register_operand" "=r")
3506 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3507 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3508 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3509 [(set_attr "type" "imovx")
3510 (set_attr "mode" "SI")])
3512 ;; For the movzbw case strip only the clobber
3514 [(set (match_operand:HI 0 "register_operand" "")
3515 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3516 (clobber (reg:CC FLAGS_REG))]
3518 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3519 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3520 [(set (match_operand:HI 0 "register_operand" "")
3521 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3523 ;; When source and destination does not overlap, clear destination
3524 ;; first and then do the movb
3526 [(set (match_operand:HI 0 "register_operand" "")
3527 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3528 (clobber (reg:CC FLAGS_REG))]
3530 && ANY_QI_REG_P (operands[0])
3531 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3532 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3533 [(set (match_dup 0) (const_int 0))
3534 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3535 "operands[2] = gen_lowpart (QImode, operands[0]);")
3537 ;; Rest is handled by single and.
3539 [(set (match_operand:HI 0 "register_operand" "")
3540 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3541 (clobber (reg:CC FLAGS_REG))]
3543 && true_regnum (operands[0]) == true_regnum (operands[1])"
3544 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3545 (clobber (reg:CC FLAGS_REG))])]
3548 (define_expand "zero_extendqisi2"
3550 [(set (match_operand:SI 0 "register_operand" "")
3551 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3552 (clobber (reg:CC FLAGS_REG))])]
3556 (define_insn "*zero_extendqisi2_and"
3557 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3558 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3559 (clobber (reg:CC FLAGS_REG))]
3560 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3562 [(set_attr "type" "alu1")
3563 (set_attr "mode" "SI")])
3565 (define_insn "*zero_extendqisi2_movzbw_and"
3566 [(set (match_operand:SI 0 "register_operand" "=r,r")
3567 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3568 (clobber (reg:CC FLAGS_REG))]
3569 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3571 [(set_attr "type" "imovx,alu1")
3572 (set_attr "mode" "SI")])
3574 (define_insn "*zero_extendqisi2_movzbw"
3575 [(set (match_operand:SI 0 "register_operand" "=r")
3576 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3577 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3578 "movz{bl|x}\t{%1, %0|%0, %1}"
3579 [(set_attr "type" "imovx")
3580 (set_attr "mode" "SI")])
3582 ;; For the movzbl case strip only the clobber
3584 [(set (match_operand:SI 0 "register_operand" "")
3585 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3586 (clobber (reg:CC FLAGS_REG))]
3588 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3589 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3591 (zero_extend:SI (match_dup 1)))])
3593 ;; When source and destination does not overlap, clear destination
3594 ;; first and then do the movb
3596 [(set (match_operand:SI 0 "register_operand" "")
3597 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3598 (clobber (reg:CC FLAGS_REG))]
3600 && ANY_QI_REG_P (operands[0])
3601 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3602 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3603 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3604 [(set (match_dup 0) (const_int 0))
3605 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3606 "operands[2] = gen_lowpart (QImode, operands[0]);")
3608 ;; Rest is handled by single and.
3610 [(set (match_operand:SI 0 "register_operand" "")
3611 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3612 (clobber (reg:CC FLAGS_REG))]
3614 && true_regnum (operands[0]) == true_regnum (operands[1])"
3615 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3616 (clobber (reg:CC FLAGS_REG))])]
3619 ;; %%% Kill me once multi-word ops are sane.
3620 (define_expand "zero_extendsidi2"
3621 [(set (match_operand:DI 0 "register_operand" "")
3622 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3627 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3632 (define_insn "zero_extendsidi2_32"
3633 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3635 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3636 (clobber (reg:CC FLAGS_REG))]
3642 movd\t{%1, %0|%0, %1}
3643 movd\t{%1, %0|%0, %1}
3644 movd\t{%1, %0|%0, %1}
3645 movd\t{%1, %0|%0, %1}"
3646 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3647 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3649 (define_insn "zero_extendsidi2_rex64"
3650 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3652 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3655 mov\t{%k1, %k0|%k0, %k1}
3657 movd\t{%1, %0|%0, %1}
3658 movd\t{%1, %0|%0, %1}
3659 movd\t{%1, %0|%0, %1}
3660 movd\t{%1, %0|%0, %1}"
3661 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3662 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3665 [(set (match_operand:DI 0 "memory_operand" "")
3666 (zero_extend:DI (match_dup 0)))]
3668 [(set (match_dup 4) (const_int 0))]
3669 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3672 [(set (match_operand:DI 0 "register_operand" "")
3673 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3674 (clobber (reg:CC FLAGS_REG))]
3675 "!TARGET_64BIT && reload_completed
3676 && true_regnum (operands[0]) == true_regnum (operands[1])"
3677 [(set (match_dup 4) (const_int 0))]
3678 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3681 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3682 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3683 (clobber (reg:CC FLAGS_REG))]
3684 "!TARGET_64BIT && reload_completed
3685 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3686 [(set (match_dup 3) (match_dup 1))
3687 (set (match_dup 4) (const_int 0))]
3688 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3690 (define_insn "zero_extendhidi2"
3691 [(set (match_operand:DI 0 "register_operand" "=r")
3692 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3694 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "DI")])
3698 (define_insn "zero_extendqidi2"
3699 [(set (match_operand:DI 0 "register_operand" "=r")
3700 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3702 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3703 [(set_attr "type" "imovx")
3704 (set_attr "mode" "DI")])
3706 ;; Sign extension instructions
3708 (define_expand "extendsidi2"
3709 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3710 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3711 (clobber (reg:CC FLAGS_REG))
3712 (clobber (match_scratch:SI 2 ""))])]
3717 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3722 (define_insn "*extendsidi2_1"
3723 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3724 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3725 (clobber (reg:CC FLAGS_REG))
3726 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3730 (define_insn "extendsidi2_rex64"
3731 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3732 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3736 movs{lq|x}\t{%1,%0|%0, %1}"
3737 [(set_attr "type" "imovx")
3738 (set_attr "mode" "DI")
3739 (set_attr "prefix_0f" "0")
3740 (set_attr "modrm" "0,1")])
3742 (define_insn "extendhidi2"
3743 [(set (match_operand:DI 0 "register_operand" "=r")
3744 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3746 "movs{wq|x}\t{%1,%0|%0, %1}"
3747 [(set_attr "type" "imovx")
3748 (set_attr "mode" "DI")])
3750 (define_insn "extendqidi2"
3751 [(set (match_operand:DI 0 "register_operand" "=r")
3752 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3754 "movs{bq|x}\t{%1,%0|%0, %1}"
3755 [(set_attr "type" "imovx")
3756 (set_attr "mode" "DI")])
3758 ;; Extend to memory case when source register does die.
3760 [(set (match_operand:DI 0 "memory_operand" "")
3761 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3762 (clobber (reg:CC FLAGS_REG))
3763 (clobber (match_operand:SI 2 "register_operand" ""))]
3765 && dead_or_set_p (insn, operands[1])
3766 && !reg_mentioned_p (operands[1], operands[0]))"
3767 [(set (match_dup 3) (match_dup 1))
3768 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3769 (clobber (reg:CC FLAGS_REG))])
3770 (set (match_dup 4) (match_dup 1))]
3771 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3773 ;; Extend to memory case when source register does not die.
3775 [(set (match_operand:DI 0 "memory_operand" "")
3776 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3777 (clobber (reg:CC FLAGS_REG))
3778 (clobber (match_operand:SI 2 "register_operand" ""))]
3782 split_di (&operands[0], 1, &operands[3], &operands[4]);
3784 emit_move_insn (operands[3], operands[1]);
3786 /* Generate a cltd if possible and doing so it profitable. */
3787 if ((optimize_size || TARGET_USE_CLTD)
3788 && true_regnum (operands[1]) == AX_REG
3789 && true_regnum (operands[2]) == DX_REG)
3791 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3795 emit_move_insn (operands[2], operands[1]);
3796 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3798 emit_move_insn (operands[4], operands[2]);
3802 ;; Extend to register case. Optimize case where source and destination
3803 ;; registers match and cases where we can use cltd.
3805 [(set (match_operand:DI 0 "register_operand" "")
3806 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3807 (clobber (reg:CC FLAGS_REG))
3808 (clobber (match_scratch:SI 2 ""))]
3812 split_di (&operands[0], 1, &operands[3], &operands[4]);
3814 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3815 emit_move_insn (operands[3], operands[1]);
3817 /* Generate a cltd if possible and doing so it profitable. */
3818 if ((optimize_size || TARGET_USE_CLTD)
3819 && true_regnum (operands[3]) == AX_REG)
3821 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3825 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3826 emit_move_insn (operands[4], operands[1]);
3828 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3832 (define_insn "extendhisi2"
3833 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3834 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3837 switch (get_attr_prefix_0f (insn))
3840 return "{cwtl|cwde}";
3842 return "movs{wl|x}\t{%1,%0|%0, %1}";
3845 [(set_attr "type" "imovx")
3846 (set_attr "mode" "SI")
3847 (set (attr "prefix_0f")
3848 ;; movsx is short decodable while cwtl is vector decoded.
3849 (if_then_else (and (eq_attr "cpu" "!k6")
3850 (eq_attr "alternative" "0"))
3852 (const_string "1")))
3854 (if_then_else (eq_attr "prefix_0f" "0")
3856 (const_string "1")))])
3858 (define_insn "*extendhisi2_zext"
3859 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3861 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3864 switch (get_attr_prefix_0f (insn))
3867 return "{cwtl|cwde}";
3869 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3872 [(set_attr "type" "imovx")
3873 (set_attr "mode" "SI")
3874 (set (attr "prefix_0f")
3875 ;; movsx is short decodable while cwtl is vector decoded.
3876 (if_then_else (and (eq_attr "cpu" "!k6")
3877 (eq_attr "alternative" "0"))
3879 (const_string "1")))
3881 (if_then_else (eq_attr "prefix_0f" "0")
3883 (const_string "1")))])
3885 (define_insn "extendqihi2"
3886 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3887 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3890 switch (get_attr_prefix_0f (insn))
3893 return "{cbtw|cbw}";
3895 return "movs{bw|x}\t{%1,%0|%0, %1}";
3898 [(set_attr "type" "imovx")
3899 (set_attr "mode" "HI")
3900 (set (attr "prefix_0f")
3901 ;; movsx is short decodable while cwtl is vector decoded.
3902 (if_then_else (and (eq_attr "cpu" "!k6")
3903 (eq_attr "alternative" "0"))
3905 (const_string "1")))
3907 (if_then_else (eq_attr "prefix_0f" "0")
3909 (const_string "1")))])
3911 (define_insn "extendqisi2"
3912 [(set (match_operand:SI 0 "register_operand" "=r")
3913 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3915 "movs{bl|x}\t{%1,%0|%0, %1}"
3916 [(set_attr "type" "imovx")
3917 (set_attr "mode" "SI")])
3919 (define_insn "*extendqisi2_zext"
3920 [(set (match_operand:DI 0 "register_operand" "=r")
3922 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3924 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3925 [(set_attr "type" "imovx")
3926 (set_attr "mode" "SI")])
3928 ;; Conversions between float and double.
3930 ;; These are all no-ops in the model used for the 80387. So just
3933 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3934 (define_insn "*dummy_extendsfdf2"
3935 [(set (match_operand:DF 0 "push_operand" "=<")
3936 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3941 [(set (match_operand:DF 0 "push_operand" "")
3942 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3944 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3945 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3947 (define_insn "*dummy_extendsfxf2"
3948 [(set (match_operand:XF 0 "push_operand" "=<")
3949 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3954 [(set (match_operand:XF 0 "push_operand" "")
3955 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3957 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3958 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3959 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3962 [(set (match_operand:XF 0 "push_operand" "")
3963 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3965 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3966 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3967 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3969 (define_expand "extendsfdf2"
3970 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3971 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3972 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3974 /* ??? Needed for compress_float_constant since all fp constants
3975 are LEGITIMATE_CONSTANT_P. */
3976 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3978 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3979 && standard_80387_constant_p (operands[1]) > 0)
3981 operands[1] = simplify_const_unary_operation
3982 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3983 emit_move_insn_1 (operands[0], operands[1]);
3986 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3990 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3992 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3994 We do the conversion post reload to avoid producing of 128bit spills
3995 that might lead to ICE on 32bit target. The sequence unlikely combine
3998 [(set (match_operand:DF 0 "register_operand" "")
4000 (match_operand:SF 1 "nonimmediate_operand" "")))]
4001 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4002 && reload_completed && SSE_REG_P (operands[0])"
4007 (parallel [(const_int 0) (const_int 1)]))))]
4009 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4010 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4011 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4012 Try to avoid move when unpacking can be done in source. */
4013 if (REG_P (operands[1]))
4015 /* If it is unsafe to overwrite upper half of source, we need
4016 to move to destination and unpack there. */
4017 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4018 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4019 && true_regnum (operands[0]) != true_regnum (operands[1]))
4021 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4022 emit_move_insn (tmp, operands[1]);
4025 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4026 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4029 emit_insn (gen_vec_setv4sf_0 (operands[3],
4030 CONST0_RTX (V4SFmode), operands[1]));
4033 (define_insn "*extendsfdf2_mixed"
4034 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4036 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4037 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4039 switch (which_alternative)
4043 return output_387_reg_move (insn, operands);
4046 return "cvtss2sd\t{%1, %0|%0, %1}";
4052 [(set_attr "type" "fmov,fmov,ssecvt")
4053 (set_attr "mode" "SF,XF,DF")])
4055 (define_insn "*extendsfdf2_sse"
4056 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4057 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4058 "TARGET_SSE2 && TARGET_SSE_MATH"
4059 "cvtss2sd\t{%1, %0|%0, %1}"
4060 [(set_attr "type" "ssecvt")
4061 (set_attr "mode" "DF")])
4063 (define_insn "*extendsfdf2_i387"
4064 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4065 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4067 "* return output_387_reg_move (insn, operands);"
4068 [(set_attr "type" "fmov")
4069 (set_attr "mode" "SF,XF")])
4071 (define_expand "extend<mode>xf2"
4072 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4073 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4076 /* ??? Needed for compress_float_constant since all fp constants
4077 are LEGITIMATE_CONSTANT_P. */
4078 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4080 if (standard_80387_constant_p (operands[1]) > 0)
4082 operands[1] = simplify_const_unary_operation
4083 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4084 emit_move_insn_1 (operands[0], operands[1]);
4087 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4091 (define_insn "*extend<mode>xf2_i387"
4092 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4094 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4096 "* return output_387_reg_move (insn, operands);"
4097 [(set_attr "type" "fmov")
4098 (set_attr "mode" "<MODE>,XF")])
4100 ;; %%% This seems bad bad news.
4101 ;; This cannot output into an f-reg because there is no way to be sure
4102 ;; of truncating in that case. Otherwise this is just like a simple move
4103 ;; insn. So we pretend we can output to a reg in order to get better
4104 ;; register preferencing, but we really use a stack slot.
4106 ;; Conversion from DFmode to SFmode.
4108 (define_expand "truncdfsf2"
4109 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4111 (match_operand:DF 1 "nonimmediate_operand" "")))]
4112 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4114 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4116 else if (flag_unsafe_math_optimizations)
4120 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4121 rtx temp = assign_386_stack_local (SFmode, slot);
4122 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4127 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4129 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4131 We do the conversion post reload to avoid producing of 128bit spills
4132 that might lead to ICE on 32bit target. The sequence unlikely combine
4135 [(set (match_operand:SF 0 "register_operand" "")
4137 (match_operand:DF 1 "nonimmediate_operand" "")))]
4138 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4139 && reload_completed && SSE_REG_P (operands[0])"
4142 (float_truncate:V2SF
4146 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4147 operands[3] = CONST0_RTX (V2SFmode);
4148 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4149 /* Use movsd for loading from memory, unpcklpd for registers.
4150 Try to avoid move when unpacking can be done in source, or SSE3
4151 movddup is available. */
4152 if (REG_P (operands[1]))
4155 && true_regnum (operands[0]) != true_regnum (operands[1])
4156 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4157 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4159 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4160 emit_move_insn (tmp, operands[1]);
4163 else if (!TARGET_SSE3)
4164 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4165 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4168 emit_insn (gen_sse2_loadlpd (operands[4],
4169 CONST0_RTX (V2DFmode), operands[1]));
4172 (define_expand "truncdfsf2_with_temp"
4173 [(parallel [(set (match_operand:SF 0 "" "")
4174 (float_truncate:SF (match_operand:DF 1 "" "")))
4175 (clobber (match_operand:SF 2 "" ""))])]
4178 (define_insn "*truncdfsf_fast_mixed"
4179 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4181 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4182 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4184 switch (which_alternative)
4187 return output_387_reg_move (insn, operands);
4189 return "cvtsd2ss\t{%1, %0|%0, %1}";
4194 [(set_attr "type" "fmov,ssecvt")
4195 (set_attr "mode" "SF")])
4197 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4198 ;; because nothing we do here is unsafe.
4199 (define_insn "*truncdfsf_fast_sse"
4200 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4202 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4203 "TARGET_SSE2 && TARGET_SSE_MATH"
4204 "cvtsd2ss\t{%1, %0|%0, %1}"
4205 [(set_attr "type" "ssecvt")
4206 (set_attr "mode" "SF")])
4208 (define_insn "*truncdfsf_fast_i387"
4209 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4211 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4212 "TARGET_80387 && flag_unsafe_math_optimizations"
4213 "* return output_387_reg_move (insn, operands);"
4214 [(set_attr "type" "fmov")
4215 (set_attr "mode" "SF")])
4217 (define_insn "*truncdfsf_mixed"
4218 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4220 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4221 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4222 "TARGET_MIX_SSE_I387"
4224 switch (which_alternative)
4227 return output_387_reg_move (insn, operands);
4232 return "cvtsd2ss\t{%1, %0|%0, %1}";
4237 [(set_attr "type" "fmov,multi,ssecvt")
4238 (set_attr "unit" "*,i387,*")
4239 (set_attr "mode" "SF")])
4241 (define_insn "*truncdfsf_i387"
4242 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4244 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4245 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4248 switch (which_alternative)
4251 return output_387_reg_move (insn, operands);
4259 [(set_attr "type" "fmov,multi")
4260 (set_attr "unit" "*,i387")
4261 (set_attr "mode" "SF")])
4263 (define_insn "*truncdfsf2_i387_1"
4264 [(set (match_operand:SF 0 "memory_operand" "=m")
4266 (match_operand:DF 1 "register_operand" "f")))]
4268 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4269 && !TARGET_MIX_SSE_I387"
4270 "* return output_387_reg_move (insn, operands);"
4271 [(set_attr "type" "fmov")
4272 (set_attr "mode" "SF")])
4275 [(set (match_operand:SF 0 "register_operand" "")
4277 (match_operand:DF 1 "fp_register_operand" "")))
4278 (clobber (match_operand 2 "" ""))]
4280 [(set (match_dup 2) (match_dup 1))
4281 (set (match_dup 0) (match_dup 2))]
4283 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4286 ;; Conversion from XFmode to {SF,DF}mode
4288 (define_expand "truncxf<mode>2"
4289 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4290 (float_truncate:MODEF
4291 (match_operand:XF 1 "register_operand" "")))
4292 (clobber (match_dup 2))])]
4295 if (flag_unsafe_math_optimizations)
4297 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4298 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4299 if (reg != operands[0])
4300 emit_move_insn (operands[0], reg);
4305 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4306 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4310 (define_insn "*truncxfsf2_mixed"
4311 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4313 (match_operand:XF 1 "register_operand" "f,f")))
4314 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4317 gcc_assert (!which_alternative);
4318 return output_387_reg_move (insn, operands);
4320 [(set_attr "type" "fmov,multi")
4321 (set_attr "unit" "*,i387")
4322 (set_attr "mode" "SF")])
4324 (define_insn "*truncxfdf2_mixed"
4325 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4327 (match_operand:XF 1 "register_operand" "f,f")))
4328 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4331 gcc_assert (!which_alternative);
4332 return output_387_reg_move (insn, operands);
4334 [(set_attr "type" "fmov,multi")
4335 (set_attr "unit" "*,i387")
4336 (set_attr "mode" "DF")])
4338 (define_insn "truncxf<mode>2_i387_noop"
4339 [(set (match_operand:MODEF 0 "register_operand" "=f")
4340 (float_truncate:MODEF
4341 (match_operand:XF 1 "register_operand" "f")))]
4342 "TARGET_80387 && flag_unsafe_math_optimizations"
4343 "* return output_387_reg_move (insn, operands);"
4344 [(set_attr "type" "fmov")
4345 (set_attr "mode" "<MODE>")])
4347 (define_insn "*truncxf<mode>2_i387"
4348 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4349 (float_truncate:MODEF
4350 (match_operand:XF 1 "register_operand" "f")))]
4352 "* return output_387_reg_move (insn, operands);"
4353 [(set_attr "type" "fmov")
4354 (set_attr "mode" "<MODE>")])
4357 [(set (match_operand:MODEF 0 "register_operand" "")
4358 (float_truncate:MODEF
4359 (match_operand:XF 1 "register_operand" "")))
4360 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4361 "TARGET_80387 && reload_completed"
4362 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4363 (set (match_dup 0) (match_dup 2))]
4367 [(set (match_operand:MODEF 0 "memory_operand" "")
4368 (float_truncate:MODEF
4369 (match_operand:XF 1 "register_operand" "")))
4370 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4372 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4375 ;; Signed conversion to DImode.
4377 (define_expand "fix_truncxfdi2"
4378 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4379 (fix:DI (match_operand:XF 1 "register_operand" "")))
4380 (clobber (reg:CC FLAGS_REG))])]
4385 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4390 (define_expand "fix_trunc<mode>di2"
4391 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4392 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4393 (clobber (reg:CC FLAGS_REG))])]
4394 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4397 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4399 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4402 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4404 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4405 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4406 if (out != operands[0])
4407 emit_move_insn (operands[0], out);
4412 ;; Signed conversion to SImode.
4414 (define_expand "fix_truncxfsi2"
4415 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4416 (fix:SI (match_operand:XF 1 "register_operand" "")))
4417 (clobber (reg:CC FLAGS_REG))])]
4422 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4427 (define_expand "fix_trunc<mode>si2"
4428 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4429 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4430 (clobber (reg:CC FLAGS_REG))])]
4431 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4434 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4436 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4439 if (SSE_FLOAT_MODE_P (<MODE>mode))
4441 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4442 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4443 if (out != operands[0])
4444 emit_move_insn (operands[0], out);
4449 ;; Signed conversion to HImode.
4451 (define_expand "fix_trunc<mode>hi2"
4452 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4453 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4454 (clobber (reg:CC FLAGS_REG))])]
4456 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4460 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4465 ;; Unsigned conversion to SImode.
4467 (define_expand "fixuns_trunc<mode>si2"
4469 [(set (match_operand:SI 0 "register_operand" "")
4471 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4473 (clobber (match_scratch:<ssevecmode> 3 ""))
4474 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4475 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4477 enum machine_mode mode = <MODE>mode;
4478 enum machine_mode vecmode = <ssevecmode>mode;
4479 REAL_VALUE_TYPE TWO31r;
4482 real_ldexp (&TWO31r, &dconst1, 31);
4483 two31 = const_double_from_real_value (TWO31r, mode);
4484 two31 = ix86_build_const_vector (mode, true, two31);
4485 operands[2] = force_reg (vecmode, two31);
4488 (define_insn_and_split "*fixuns_trunc<mode>_1"
4489 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4491 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4492 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4493 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4494 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4495 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4497 "&& reload_completed"
4500 ix86_split_convert_uns_si_sse (operands);
4504 ;; Unsigned conversion to HImode.
4505 ;; Without these patterns, we'll try the unsigned SI conversion which
4506 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4508 (define_expand "fixuns_trunc<mode>hi2"
4510 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4511 (set (match_operand:HI 0 "nonimmediate_operand" "")
4512 (subreg:HI (match_dup 2) 0))]
4513 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4514 "operands[2] = gen_reg_rtx (SImode);")
4516 ;; When SSE is available, it is always faster to use it!
4517 (define_insn "fix_trunc<mode>di_sse"
4518 [(set (match_operand:DI 0 "register_operand" "=r,r")
4519 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4520 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4521 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4522 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4523 [(set_attr "type" "sseicvt")
4524 (set_attr "mode" "<MODE>")
4525 (set_attr "athlon_decode" "double,vector")
4526 (set_attr "amdfam10_decode" "double,double")])
4528 (define_insn "fix_trunc<mode>si_sse"
4529 [(set (match_operand:SI 0 "register_operand" "=r,r")
4530 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4531 "SSE_FLOAT_MODE_P (<MODE>mode)
4532 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4533 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4534 [(set_attr "type" "sseicvt")
4535 (set_attr "mode" "<MODE>")
4536 (set_attr "athlon_decode" "double,vector")
4537 (set_attr "amdfam10_decode" "double,double")])
4539 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4541 [(set (match_operand:MODEF 0 "register_operand" "")
4542 (match_operand:MODEF 1 "memory_operand" ""))
4543 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4544 (fix:SSEMODEI24 (match_dup 0)))]
4545 "TARGET_SHORTEN_X87_SSE
4546 && peep2_reg_dead_p (2, operands[0])"
4547 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4550 ;; Avoid vector decoded forms of the instruction.
4552 [(match_scratch:DF 2 "Y2")
4553 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4554 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4555 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4556 [(set (match_dup 2) (match_dup 1))
4557 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4561 [(match_scratch:SF 2 "x")
4562 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4563 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4564 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4565 [(set (match_dup 2) (match_dup 1))
4566 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4569 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4570 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4571 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4572 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4574 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4575 && (TARGET_64BIT || <MODE>mode != DImode))
4577 && !(reload_completed || reload_in_progress)"
4582 if (memory_operand (operands[0], VOIDmode))
4583 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4586 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4587 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4593 [(set_attr "type" "fisttp")
4594 (set_attr "mode" "<MODE>")])
4596 (define_insn "fix_trunc<mode>_i387_fisttp"
4597 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4598 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4599 (clobber (match_scratch:XF 2 "=&1f"))]
4600 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4602 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4603 && (TARGET_64BIT || <MODE>mode != DImode))
4604 && TARGET_SSE_MATH)"
4605 "* return output_fix_trunc (insn, operands, 1);"
4606 [(set_attr "type" "fisttp")
4607 (set_attr "mode" "<MODE>")])
4609 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4610 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4611 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4612 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4613 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4614 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4617 && (TARGET_64BIT || <MODE>mode != DImode))
4618 && TARGET_SSE_MATH)"
4620 [(set_attr "type" "fisttp")
4621 (set_attr "mode" "<MODE>")])
4624 [(set (match_operand:X87MODEI 0 "register_operand" "")
4625 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4626 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4627 (clobber (match_scratch 3 ""))]
4629 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4630 (clobber (match_dup 3))])
4631 (set (match_dup 0) (match_dup 2))]
4635 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4636 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4637 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4638 (clobber (match_scratch 3 ""))]
4640 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4641 (clobber (match_dup 3))])]
4644 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4645 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4646 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4647 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4648 ;; function in i386.c.
4649 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4650 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4651 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4652 (clobber (reg:CC FLAGS_REG))]
4653 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4655 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4656 && (TARGET_64BIT || <MODE>mode != DImode))
4657 && !(reload_completed || reload_in_progress)"
4662 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4664 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4665 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4666 if (memory_operand (operands[0], VOIDmode))
4667 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4668 operands[2], operands[3]));
4671 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4672 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4673 operands[2], operands[3],
4678 [(set_attr "type" "fistp")
4679 (set_attr "i387_cw" "trunc")
4680 (set_attr "mode" "<MODE>")])
4682 (define_insn "fix_truncdi_i387"
4683 [(set (match_operand:DI 0 "memory_operand" "=m")
4684 (fix:DI (match_operand 1 "register_operand" "f")))
4685 (use (match_operand:HI 2 "memory_operand" "m"))
4686 (use (match_operand:HI 3 "memory_operand" "m"))
4687 (clobber (match_scratch:XF 4 "=&1f"))]
4688 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4690 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4691 "* return output_fix_trunc (insn, operands, 0);"
4692 [(set_attr "type" "fistp")
4693 (set_attr "i387_cw" "trunc")
4694 (set_attr "mode" "DI")])
4696 (define_insn "fix_truncdi_i387_with_temp"
4697 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4698 (fix:DI (match_operand 1 "register_operand" "f,f")))
4699 (use (match_operand:HI 2 "memory_operand" "m,m"))
4700 (use (match_operand:HI 3 "memory_operand" "m,m"))
4701 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4702 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4703 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4705 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4707 [(set_attr "type" "fistp")
4708 (set_attr "i387_cw" "trunc")
4709 (set_attr "mode" "DI")])
4712 [(set (match_operand:DI 0 "register_operand" "")
4713 (fix:DI (match_operand 1 "register_operand" "")))
4714 (use (match_operand:HI 2 "memory_operand" ""))
4715 (use (match_operand:HI 3 "memory_operand" ""))
4716 (clobber (match_operand:DI 4 "memory_operand" ""))
4717 (clobber (match_scratch 5 ""))]
4719 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4722 (clobber (match_dup 5))])
4723 (set (match_dup 0) (match_dup 4))]
4727 [(set (match_operand:DI 0 "memory_operand" "")
4728 (fix:DI (match_operand 1 "register_operand" "")))
4729 (use (match_operand:HI 2 "memory_operand" ""))
4730 (use (match_operand:HI 3 "memory_operand" ""))
4731 (clobber (match_operand:DI 4 "memory_operand" ""))
4732 (clobber (match_scratch 5 ""))]
4734 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4737 (clobber (match_dup 5))])]
4740 (define_insn "fix_trunc<mode>_i387"
4741 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4742 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4743 (use (match_operand:HI 2 "memory_operand" "m"))
4744 (use (match_operand:HI 3 "memory_operand" "m"))]
4745 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4747 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4748 "* return output_fix_trunc (insn, operands, 0);"
4749 [(set_attr "type" "fistp")
4750 (set_attr "i387_cw" "trunc")
4751 (set_attr "mode" "<MODE>")])
4753 (define_insn "fix_trunc<mode>_i387_with_temp"
4754 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4755 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4756 (use (match_operand:HI 2 "memory_operand" "m,m"))
4757 (use (match_operand:HI 3 "memory_operand" "m,m"))
4758 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4759 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4761 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4763 [(set_attr "type" "fistp")
4764 (set_attr "i387_cw" "trunc")
4765 (set_attr "mode" "<MODE>")])
4768 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4769 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4770 (use (match_operand:HI 2 "memory_operand" ""))
4771 (use (match_operand:HI 3 "memory_operand" ""))
4772 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4774 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4776 (use (match_dup 3))])
4777 (set (match_dup 0) (match_dup 4))]
4781 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4782 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4783 (use (match_operand:HI 2 "memory_operand" ""))
4784 (use (match_operand:HI 3 "memory_operand" ""))
4785 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4787 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4789 (use (match_dup 3))])]
4792 (define_insn "x86_fnstcw_1"
4793 [(set (match_operand:HI 0 "memory_operand" "=m")
4794 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4797 [(set_attr "length" "2")
4798 (set_attr "mode" "HI")
4799 (set_attr "unit" "i387")])
4801 (define_insn "x86_fldcw_1"
4802 [(set (reg:HI FPCR_REG)
4803 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4806 [(set_attr "length" "2")
4807 (set_attr "mode" "HI")
4808 (set_attr "unit" "i387")
4809 (set_attr "athlon_decode" "vector")
4810 (set_attr "amdfam10_decode" "vector")])
4812 ;; Conversion between fixed point and floating point.
4814 ;; Even though we only accept memory inputs, the backend _really_
4815 ;; wants to be able to do this between registers.
4817 (define_expand "floathi<mode>2"
4818 [(set (match_operand:X87MODEF 0 "register_operand" "")
4819 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4821 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4822 || TARGET_MIX_SSE_I387)"
4825 ;; Pre-reload splitter to add memory clobber to the pattern.
4826 (define_insn_and_split "*floathi<mode>2_1"
4827 [(set (match_operand:X87MODEF 0 "register_operand" "")
4828 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4831 || TARGET_MIX_SSE_I387)
4832 && !(reload_completed || reload_in_progress)"
4835 [(parallel [(set (match_dup 0)
4836 (float:X87MODEF (match_dup 1)))
4837 (clobber (match_dup 2))])]
4838 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4840 (define_insn "*floathi<mode>2_i387_with_temp"
4841 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4842 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4843 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4845 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4846 || TARGET_MIX_SSE_I387)"
4848 [(set_attr "type" "fmov,multi")
4849 (set_attr "mode" "<MODE>")
4850 (set_attr "unit" "*,i387")
4851 (set_attr "fp_int_src" "true")])
4853 (define_insn "*floathi<mode>2_i387"
4854 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4855 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4858 || TARGET_MIX_SSE_I387)"
4860 [(set_attr "type" "fmov")
4861 (set_attr "mode" "<MODE>")
4862 (set_attr "fp_int_src" "true")])
4865 [(set (match_operand:X87MODEF 0 "register_operand" "")
4866 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4867 (clobber (match_operand:HI 2 "memory_operand" ""))]
4869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4870 || TARGET_MIX_SSE_I387)
4871 && reload_completed"
4872 [(set (match_dup 2) (match_dup 1))
4873 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4877 [(set (match_operand:X87MODEF 0 "register_operand" "")
4878 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4879 (clobber (match_operand:HI 2 "memory_operand" ""))]
4881 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4882 || TARGET_MIX_SSE_I387)
4883 && reload_completed"
4884 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4887 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4888 [(set (match_operand:X87MODEF 0 "register_operand" "")
4890 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4892 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4893 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4896 ;; Pre-reload splitter to add memory clobber to the pattern.
4897 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4898 [(set (match_operand:X87MODEF 0 "register_operand" "")
4899 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4901 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4902 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4903 || TARGET_MIX_SSE_I387))
4904 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4905 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4906 && ((<SSEMODEI24:MODE>mode == SImode
4907 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4908 && flag_trapping_math)
4909 || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4910 && !(reload_completed || reload_in_progress)"
4913 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4914 (clobber (match_dup 2))])]
4916 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4918 /* Avoid store forwarding (partial memory) stall penalty
4919 by passing DImode value through XMM registers. */
4920 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4921 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4924 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4931 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4932 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4934 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4935 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4936 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4937 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4939 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4940 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4941 (set_attr "unit" "*,i387,*,*,*")
4942 (set_attr "athlon_decode" "*,*,double,direct,double")
4943 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4944 (set_attr "fp_int_src" "true")])
4946 (define_insn "*floatsi<mode>2_vector_mixed"
4947 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4948 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4949 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4950 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4954 [(set_attr "type" "fmov,sseicvt")
4955 (set_attr "mode" "<MODE>,<ssevecmode>")
4956 (set_attr "unit" "i387,*")
4957 (set_attr "athlon_decode" "*,direct")
4958 (set_attr "amdfam10_decode" "*,double")
4959 (set_attr "fp_int_src" "true")])
4961 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4962 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4964 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4965 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4966 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4967 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4969 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4970 (set_attr "mode" "<MODEF:MODE>")
4971 (set_attr "unit" "*,i387,*,*")
4972 (set_attr "athlon_decode" "*,*,double,direct")
4973 (set_attr "amdfam10_decode" "*,*,vector,double")
4974 (set_attr "fp_int_src" "true")])
4977 [(set (match_operand:MODEF 0 "register_operand" "")
4978 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4979 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4980 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4981 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4982 && TARGET_INTER_UNIT_CONVERSIONS
4984 && (SSE_REG_P (operands[0])
4985 || (GET_CODE (operands[0]) == SUBREG
4986 && SSE_REG_P (operands[0])))"
4987 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
4991 [(set (match_operand:MODEF 0 "register_operand" "")
4992 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4993 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4994 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4995 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4996 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
4998 && (SSE_REG_P (operands[0])
4999 || (GET_CODE (operands[0]) == SUBREG
5000 && SSE_REG_P (operands[0])))"
5001 [(set (match_dup 2) (match_dup 1))
5002 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5005 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5006 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5008 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5009 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5010 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5011 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5014 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5015 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5016 [(set_attr "type" "fmov,sseicvt,sseicvt")
5017 (set_attr "mode" "<MODEF:MODE>")
5018 (set_attr "unit" "i387,*,*")
5019 (set_attr "athlon_decode" "*,double,direct")
5020 (set_attr "amdfam10_decode" "*,vector,double")
5021 (set_attr "fp_int_src" "true")])
5023 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5024 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5026 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5027 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5028 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5029 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5032 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5033 [(set_attr "type" "fmov,sseicvt")
5034 (set_attr "mode" "<MODEF:MODE>")
5035 (set_attr "athlon_decode" "*,direct")
5036 (set_attr "amdfam10_decode" "*,double")
5037 (set_attr "fp_int_src" "true")])
5039 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5040 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5042 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5043 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5044 "TARGET_SSE2 && TARGET_SSE_MATH
5045 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5047 [(set_attr "type" "sseicvt")
5048 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5049 (set_attr "athlon_decode" "double,direct,double")
5050 (set_attr "amdfam10_decode" "vector,double,double")
5051 (set_attr "fp_int_src" "true")])
5053 (define_insn "*floatsi<mode>2_vector_sse"
5054 [(set (match_operand:MODEF 0 "register_operand" "=x")
5055 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5056 "TARGET_SSE2 && TARGET_SSE_MATH
5057 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5059 [(set_attr "type" "sseicvt")
5060 (set_attr "mode" "<MODE>")
5061 (set_attr "athlon_decode" "direct")
5062 (set_attr "amdfam10_decode" "double")
5063 (set_attr "fp_int_src" "true")])
5066 [(set (match_operand:MODEF 0 "register_operand" "")
5067 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5068 (clobber (match_operand:SI 2 "memory_operand" ""))]
5069 "TARGET_SSE2 && TARGET_SSE_MATH
5070 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5072 && (SSE_REG_P (operands[0])
5073 || (GET_CODE (operands[0]) == SUBREG
5074 && SSE_REG_P (operands[0])))"
5077 rtx op1 = operands[1];
5079 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5081 if (GET_CODE (op1) == SUBREG)
5082 op1 = SUBREG_REG (op1);
5084 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5086 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5087 emit_insn (gen_sse2_loadld (operands[4],
5088 CONST0_RTX (V4SImode), operands[1]));
5090 /* We can ignore possible trapping value in the
5091 high part of SSE register for non-trapping math. */
5092 else if (SSE_REG_P (op1) && !flag_trapping_math)
5093 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5096 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5097 emit_move_insn (operands[2], operands[1]);
5098 emit_insn (gen_sse2_loadld (operands[4],
5099 CONST0_RTX (V4SImode), operands[2]));
5102 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5107 [(set (match_operand:MODEF 0 "register_operand" "")
5108 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5109 (clobber (match_operand:SI 2 "memory_operand" ""))]
5110 "TARGET_SSE2 && TARGET_SSE_MATH
5111 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5113 && (SSE_REG_P (operands[0])
5114 || (GET_CODE (operands[0]) == SUBREG
5115 && SSE_REG_P (operands[0])))"
5118 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5120 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5122 emit_insn (gen_sse2_loadld (operands[4],
5123 CONST0_RTX (V4SImode), operands[1]));
5125 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5130 [(set (match_operand:MODEF 0 "register_operand" "")
5131 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5132 "TARGET_SSE2 && TARGET_SSE_MATH
5133 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5135 && (SSE_REG_P (operands[0])
5136 || (GET_CODE (operands[0]) == SUBREG
5137 && SSE_REG_P (operands[0])))"
5140 rtx op1 = operands[1];
5142 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5144 if (GET_CODE (op1) == SUBREG)
5145 op1 = SUBREG_REG (op1);
5147 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5149 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5150 emit_insn (gen_sse2_loadld (operands[4],
5151 CONST0_RTX (V4SImode), operands[1]));
5153 /* We can ignore possible trapping value in the
5154 high part of SSE register for non-trapping math. */
5155 else if (SSE_REG_P (op1) && !flag_trapping_math)
5156 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5162 [(set (match_operand:MODEF 0 "register_operand" "")
5163 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5164 "TARGET_SSE2 && TARGET_SSE_MATH
5165 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5167 && (SSE_REG_P (operands[0])
5168 || (GET_CODE (operands[0]) == SUBREG
5169 && SSE_REG_P (operands[0])))"
5172 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5174 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5176 emit_insn (gen_sse2_loadld (operands[4],
5177 CONST0_RTX (V4SImode), operands[1]));
5179 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5183 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5184 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5186 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5187 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5188 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5189 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5191 [(set_attr "type" "sseicvt")
5192 (set_attr "mode" "<MODEF:MODE>")
5193 (set_attr "athlon_decode" "double,direct")
5194 (set_attr "amdfam10_decode" "vector,double")
5195 (set_attr "fp_int_src" "true")])
5197 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5198 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5200 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5201 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5202 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5203 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5204 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5205 [(set_attr "type" "sseicvt")
5206 (set_attr "mode" "<MODEF:MODE>")
5207 (set_attr "athlon_decode" "double,direct")
5208 (set_attr "amdfam10_decode" "vector,double")
5209 (set_attr "fp_int_src" "true")])
5212 [(set (match_operand:MODEF 0 "register_operand" "")
5213 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5214 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5215 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5216 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5217 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5219 && (SSE_REG_P (operands[0])
5220 || (GET_CODE (operands[0]) == SUBREG
5221 && SSE_REG_P (operands[0])))"
5222 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5225 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5226 [(set (match_operand:MODEF 0 "register_operand" "=x")
5228 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5229 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5230 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5231 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5232 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5233 [(set_attr "type" "sseicvt")
5234 (set_attr "mode" "<MODEF:MODE>")
5235 (set_attr "athlon_decode" "direct")
5236 (set_attr "amdfam10_decode" "double")
5237 (set_attr "fp_int_src" "true")])
5240 [(set (match_operand:MODEF 0 "register_operand" "")
5241 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5242 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5243 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5244 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5245 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5247 && (SSE_REG_P (operands[0])
5248 || (GET_CODE (operands[0]) == SUBREG
5249 && SSE_REG_P (operands[0])))"
5250 [(set (match_dup 2) (match_dup 1))
5251 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5255 [(set (match_operand:MODEF 0 "register_operand" "")
5256 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5257 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5258 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5259 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5261 && (SSE_REG_P (operands[0])
5262 || (GET_CODE (operands[0]) == SUBREG
5263 && SSE_REG_P (operands[0])))"
5264 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5267 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5268 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5270 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5271 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5276 [(set_attr "type" "fmov,multi")
5277 (set_attr "mode" "<X87MODEF:MODE>")
5278 (set_attr "unit" "*,i387")
5279 (set_attr "fp_int_src" "true")])
5281 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5282 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5284 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5287 [(set_attr "type" "fmov")
5288 (set_attr "mode" "<X87MODEF:MODE>")
5289 (set_attr "fp_int_src" "true")])
5292 [(set (match_operand:X87MODEF 0 "register_operand" "")
5293 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5294 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5297 && FP_REG_P (operands[0])"
5298 [(set (match_dup 2) (match_dup 1))
5299 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5303 [(set (match_operand:X87MODEF 0 "register_operand" "")
5304 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5305 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5308 && FP_REG_P (operands[0])"
5309 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5312 ;; Avoid store forwarding (partial memory) stall penalty
5313 ;; by passing DImode value through XMM registers. */
5315 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5316 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5318 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5319 (clobber (match_scratch:V4SI 3 "=X,x"))
5320 (clobber (match_scratch:V4SI 4 "=X,x"))
5321 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5322 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5323 && !TARGET_64BIT && !optimize_size"
5325 [(set_attr "type" "multi")
5326 (set_attr "mode" "<X87MODEF:MODE>")
5327 (set_attr "unit" "i387")
5328 (set_attr "fp_int_src" "true")])
5331 [(set (match_operand:X87MODEF 0 "register_operand" "")
5332 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5333 (clobber (match_scratch:V4SI 3 ""))
5334 (clobber (match_scratch:V4SI 4 ""))
5335 (clobber (match_operand:DI 2 "memory_operand" ""))]
5336 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5337 && !TARGET_64BIT && !optimize_size
5339 && FP_REG_P (operands[0])"
5340 [(set (match_dup 2) (match_dup 3))
5341 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5343 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5344 Assemble the 64-bit DImode value in an xmm register. */
5345 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5346 gen_rtx_SUBREG (SImode, operands[1], 0)));
5347 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5348 gen_rtx_SUBREG (SImode, operands[1], 4)));
5349 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5351 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5355 [(set (match_operand:X87MODEF 0 "register_operand" "")
5356 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5357 (clobber (match_scratch:V4SI 3 ""))
5358 (clobber (match_scratch:V4SI 4 ""))
5359 (clobber (match_operand:DI 2 "memory_operand" ""))]
5360 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5361 && !TARGET_64BIT && !optimize_size
5363 && FP_REG_P (operands[0])"
5364 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5367 ;; Avoid store forwarding (partial memory) stall penalty by extending
5368 ;; SImode value to DImode through XMM register instead of pushing two
5369 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5370 ;; targets benefit from this optimization. Also note that fild
5371 ;; loads from memory only.
5373 (define_insn "*floatunssi<mode>2_1"
5374 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5375 (unsigned_float:X87MODEF
5376 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5377 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5378 (clobber (match_scratch:SI 3 "=X,x"))]
5380 && TARGET_80387 && TARGET_SSE"
5382 [(set_attr "type" "multi")
5383 (set_attr "mode" "<MODE>")])
5386 [(set (match_operand:X87MODEF 0 "register_operand" "")
5387 (unsigned_float:X87MODEF
5388 (match_operand:SI 1 "register_operand" "")))
5389 (clobber (match_operand:DI 2 "memory_operand" ""))
5390 (clobber (match_scratch:SI 3 ""))]
5392 && TARGET_80387 && TARGET_SSE
5393 && reload_completed"
5394 [(set (match_dup 2) (match_dup 1))
5396 (float:X87MODEF (match_dup 2)))]
5397 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5400 [(set (match_operand:X87MODEF 0 "register_operand" "")
5401 (unsigned_float:X87MODEF
5402 (match_operand:SI 1 "memory_operand" "")))
5403 (clobber (match_operand:DI 2 "memory_operand" ""))
5404 (clobber (match_scratch:SI 3 ""))]
5406 && TARGET_80387 && TARGET_SSE
5407 && reload_completed"
5408 [(set (match_dup 2) (match_dup 3))
5410 (float:X87MODEF (match_dup 2)))]
5412 emit_move_insn (operands[3], operands[1]);
5413 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5416 (define_expand "floatunssi<mode>2"
5418 [(set (match_operand:X87MODEF 0 "register_operand" "")
5419 (unsigned_float:X87MODEF
5420 (match_operand:SI 1 "nonimmediate_operand" "")))
5421 (clobber (match_dup 2))
5422 (clobber (match_scratch:SI 3 ""))])]
5424 && ((TARGET_80387 && TARGET_SSE)
5425 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5427 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5429 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5434 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5435 operands[2] = assign_386_stack_local (DImode, slot);
5439 (define_expand "floatunsdisf2"
5440 [(use (match_operand:SF 0 "register_operand" ""))
5441 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5442 "TARGET_64BIT && TARGET_SSE_MATH"
5443 "x86_emit_floatuns (operands); DONE;")
5445 (define_expand "floatunsdidf2"
5446 [(use (match_operand:DF 0 "register_operand" ""))
5447 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5448 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5449 && TARGET_SSE2 && TARGET_SSE_MATH"
5452 x86_emit_floatuns (operands);
5454 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5460 ;; %%% splits for addditi3
5462 (define_expand "addti3"
5463 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5464 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5465 (match_operand:TI 2 "x86_64_general_operand" "")))
5466 (clobber (reg:CC FLAGS_REG))]
5468 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5470 (define_insn "*addti3_1"
5471 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5472 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5473 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5474 (clobber (reg:CC FLAGS_REG))]
5475 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5479 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5480 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5481 (match_operand:TI 2 "x86_64_general_operand" "")))
5482 (clobber (reg:CC FLAGS_REG))]
5483 "TARGET_64BIT && reload_completed"
5484 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5486 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5487 (parallel [(set (match_dup 3)
5488 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5491 (clobber (reg:CC FLAGS_REG))])]
5492 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5494 ;; %%% splits for addsidi3
5495 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5496 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5497 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5499 (define_expand "adddi3"
5500 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5501 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5502 (match_operand:DI 2 "x86_64_general_operand" "")))
5503 (clobber (reg:CC FLAGS_REG))]
5505 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5507 (define_insn "*adddi3_1"
5508 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5509 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5510 (match_operand:DI 2 "general_operand" "roiF,riF")))
5511 (clobber (reg:CC FLAGS_REG))]
5512 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5516 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5517 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5518 (match_operand:DI 2 "general_operand" "")))
5519 (clobber (reg:CC FLAGS_REG))]
5520 "!TARGET_64BIT && reload_completed"
5521 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5523 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5524 (parallel [(set (match_dup 3)
5525 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5528 (clobber (reg:CC FLAGS_REG))])]
5529 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5531 (define_insn "adddi3_carry_rex64"
5532 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5533 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5534 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5535 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5536 (clobber (reg:CC FLAGS_REG))]
5537 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5538 "adc{q}\t{%2, %0|%0, %2}"
5539 [(set_attr "type" "alu")
5540 (set_attr "pent_pair" "pu")
5541 (set_attr "mode" "DI")])
5543 (define_insn "*adddi3_cc_rex64"
5544 [(set (reg:CC FLAGS_REG)
5545 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5546 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5548 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5549 (plus:DI (match_dup 1) (match_dup 2)))]
5550 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5551 "add{q}\t{%2, %0|%0, %2}"
5552 [(set_attr "type" "alu")
5553 (set_attr "mode" "DI")])
5555 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5556 [(set (reg:CCC FLAGS_REG)
5559 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5560 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5562 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5563 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5564 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5565 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5566 [(set_attr "type" "alu")
5567 (set_attr "mode" "<MODE>")])
5569 (define_insn "*add<mode>3_cconly_overflow"
5570 [(set (reg:CCC FLAGS_REG)
5572 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5573 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5575 (clobber (match_scratch:SWI 0 "=<r>"))]
5576 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5577 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5578 [(set_attr "type" "alu")
5579 (set_attr "mode" "<MODE>")])
5581 (define_insn "*sub<mode>3_cconly_overflow"
5582 [(set (reg:CCC FLAGS_REG)
5584 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5585 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5588 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5589 [(set_attr "type" "icmp")
5590 (set_attr "mode" "<MODE>")])
5592 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5593 [(set (reg:CCC FLAGS_REG)
5595 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5596 (match_operand:SI 2 "general_operand" "g"))
5598 (set (match_operand:DI 0 "register_operand" "=r")
5599 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5600 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5601 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5602 [(set_attr "type" "alu")
5603 (set_attr "mode" "SI")])
5605 (define_insn "addqi3_carry"
5606 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5607 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5608 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5609 (match_operand:QI 2 "general_operand" "qn,qm")))
5610 (clobber (reg:CC FLAGS_REG))]
5611 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5612 "adc{b}\t{%2, %0|%0, %2}"
5613 [(set_attr "type" "alu")
5614 (set_attr "pent_pair" "pu")
5615 (set_attr "mode" "QI")])
5617 (define_insn "addhi3_carry"
5618 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5619 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5620 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5621 (match_operand:HI 2 "general_operand" "rn,rm")))
5622 (clobber (reg:CC FLAGS_REG))]
5623 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5624 "adc{w}\t{%2, %0|%0, %2}"
5625 [(set_attr "type" "alu")
5626 (set_attr "pent_pair" "pu")
5627 (set_attr "mode" "HI")])
5629 (define_insn "addsi3_carry"
5630 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5631 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5632 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5633 (match_operand:SI 2 "general_operand" "ri,rm")))
5634 (clobber (reg:CC FLAGS_REG))]
5635 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5636 "adc{l}\t{%2, %0|%0, %2}"
5637 [(set_attr "type" "alu")
5638 (set_attr "pent_pair" "pu")
5639 (set_attr "mode" "SI")])
5641 (define_insn "*addsi3_carry_zext"
5642 [(set (match_operand:DI 0 "register_operand" "=r")
5644 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5645 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5646 (match_operand:SI 2 "general_operand" "g"))))
5647 (clobber (reg:CC FLAGS_REG))]
5648 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5649 "adc{l}\t{%2, %k0|%k0, %2}"
5650 [(set_attr "type" "alu")
5651 (set_attr "pent_pair" "pu")
5652 (set_attr "mode" "SI")])
5654 (define_insn "*addsi3_cc"
5655 [(set (reg:CC FLAGS_REG)
5656 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5657 (match_operand:SI 2 "general_operand" "ri,rm")]
5659 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5660 (plus:SI (match_dup 1) (match_dup 2)))]
5661 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5662 "add{l}\t{%2, %0|%0, %2}"
5663 [(set_attr "type" "alu")
5664 (set_attr "mode" "SI")])
5666 (define_insn "addqi3_cc"
5667 [(set (reg:CC FLAGS_REG)
5668 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5669 (match_operand:QI 2 "general_operand" "qn,qm")]
5671 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5672 (plus:QI (match_dup 1) (match_dup 2)))]
5673 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5674 "add{b}\t{%2, %0|%0, %2}"
5675 [(set_attr "type" "alu")
5676 (set_attr "mode" "QI")])
5678 (define_expand "addsi3"
5679 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5680 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5681 (match_operand:SI 2 "general_operand" "")))
5682 (clobber (reg:CC FLAGS_REG))])]
5684 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5686 (define_insn "*lea_1"
5687 [(set (match_operand:SI 0 "register_operand" "=r")
5688 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5690 "lea{l}\t{%a1, %0|%0, %a1}"
5691 [(set_attr "type" "lea")
5692 (set_attr "mode" "SI")])
5694 (define_insn "*lea_1_rex64"
5695 [(set (match_operand:SI 0 "register_operand" "=r")
5696 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5698 "lea{l}\t{%a1, %0|%0, %a1}"
5699 [(set_attr "type" "lea")
5700 (set_attr "mode" "SI")])
5702 (define_insn "*lea_1_zext"
5703 [(set (match_operand:DI 0 "register_operand" "=r")
5705 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5707 "lea{l}\t{%a1, %k0|%k0, %a1}"
5708 [(set_attr "type" "lea")
5709 (set_attr "mode" "SI")])
5711 (define_insn "*lea_2_rex64"
5712 [(set (match_operand:DI 0 "register_operand" "=r")
5713 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5715 "lea{q}\t{%a1, %0|%0, %a1}"
5716 [(set_attr "type" "lea")
5717 (set_attr "mode" "DI")])
5719 ;; The lea patterns for non-Pmodes needs to be matched by several
5720 ;; insns converted to real lea by splitters.
5722 (define_insn_and_split "*lea_general_1"
5723 [(set (match_operand 0 "register_operand" "=r")
5724 (plus (plus (match_operand 1 "index_register_operand" "l")
5725 (match_operand 2 "register_operand" "r"))
5726 (match_operand 3 "immediate_operand" "i")))]
5727 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5728 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5729 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5730 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5731 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5732 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5733 || GET_MODE (operands[3]) == VOIDmode)"
5735 "&& reload_completed"
5739 operands[0] = gen_lowpart (SImode, operands[0]);
5740 operands[1] = gen_lowpart (Pmode, operands[1]);
5741 operands[2] = gen_lowpart (Pmode, operands[2]);
5742 operands[3] = gen_lowpart (Pmode, operands[3]);
5743 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5745 if (Pmode != SImode)
5746 pat = gen_rtx_SUBREG (SImode, pat, 0);
5747 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5750 [(set_attr "type" "lea")
5751 (set_attr "mode" "SI")])
5753 (define_insn_and_split "*lea_general_1_zext"
5754 [(set (match_operand:DI 0 "register_operand" "=r")
5756 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5757 (match_operand:SI 2 "register_operand" "r"))
5758 (match_operand:SI 3 "immediate_operand" "i"))))]
5761 "&& reload_completed"
5763 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5765 (match_dup 3)) 0)))]
5767 operands[1] = gen_lowpart (Pmode, operands[1]);
5768 operands[2] = gen_lowpart (Pmode, operands[2]);
5769 operands[3] = gen_lowpart (Pmode, operands[3]);
5771 [(set_attr "type" "lea")
5772 (set_attr "mode" "SI")])
5774 (define_insn_and_split "*lea_general_2"
5775 [(set (match_operand 0 "register_operand" "=r")
5776 (plus (mult (match_operand 1 "index_register_operand" "l")
5777 (match_operand 2 "const248_operand" "i"))
5778 (match_operand 3 "nonmemory_operand" "ri")))]
5779 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5780 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5781 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5782 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5783 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5784 || GET_MODE (operands[3]) == VOIDmode)"
5786 "&& reload_completed"
5790 operands[0] = gen_lowpart (SImode, operands[0]);
5791 operands[1] = gen_lowpart (Pmode, operands[1]);
5792 operands[3] = gen_lowpart (Pmode, operands[3]);
5793 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5795 if (Pmode != SImode)
5796 pat = gen_rtx_SUBREG (SImode, pat, 0);
5797 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5800 [(set_attr "type" "lea")
5801 (set_attr "mode" "SI")])
5803 (define_insn_and_split "*lea_general_2_zext"
5804 [(set (match_operand:DI 0 "register_operand" "=r")
5806 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5807 (match_operand:SI 2 "const248_operand" "n"))
5808 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5811 "&& reload_completed"
5813 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5815 (match_dup 3)) 0)))]
5817 operands[1] = gen_lowpart (Pmode, operands[1]);
5818 operands[3] = gen_lowpart (Pmode, operands[3]);
5820 [(set_attr "type" "lea")
5821 (set_attr "mode" "SI")])
5823 (define_insn_and_split "*lea_general_3"
5824 [(set (match_operand 0 "register_operand" "=r")
5825 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5826 (match_operand 2 "const248_operand" "i"))
5827 (match_operand 3 "register_operand" "r"))
5828 (match_operand 4 "immediate_operand" "i")))]
5829 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5830 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5831 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5832 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5833 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5835 "&& reload_completed"
5839 operands[0] = gen_lowpart (SImode, operands[0]);
5840 operands[1] = gen_lowpart (Pmode, operands[1]);
5841 operands[3] = gen_lowpart (Pmode, operands[3]);
5842 operands[4] = gen_lowpart (Pmode, operands[4]);
5843 pat = gen_rtx_PLUS (Pmode,
5844 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5848 if (Pmode != SImode)
5849 pat = gen_rtx_SUBREG (SImode, pat, 0);
5850 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5853 [(set_attr "type" "lea")
5854 (set_attr "mode" "SI")])
5856 (define_insn_and_split "*lea_general_3_zext"
5857 [(set (match_operand:DI 0 "register_operand" "=r")
5859 (plus:SI (plus:SI (mult:SI
5860 (match_operand:SI 1 "index_register_operand" "l")
5861 (match_operand:SI 2 "const248_operand" "n"))
5862 (match_operand:SI 3 "register_operand" "r"))
5863 (match_operand:SI 4 "immediate_operand" "i"))))]
5866 "&& reload_completed"
5868 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5871 (match_dup 4)) 0)))]
5873 operands[1] = gen_lowpart (Pmode, operands[1]);
5874 operands[3] = gen_lowpart (Pmode, operands[3]);
5875 operands[4] = gen_lowpart (Pmode, operands[4]);
5877 [(set_attr "type" "lea")
5878 (set_attr "mode" "SI")])
5880 (define_insn "*adddi_1_rex64"
5881 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5882 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5883 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5884 (clobber (reg:CC FLAGS_REG))]
5885 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5887 switch (get_attr_type (insn))
5890 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5891 return "lea{q}\t{%a2, %0|%0, %a2}";
5894 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5895 if (operands[2] == const1_rtx)
5896 return "inc{q}\t%0";
5899 gcc_assert (operands[2] == constm1_rtx);
5900 return "dec{q}\t%0";
5904 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5906 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5907 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5908 if (CONST_INT_P (operands[2])
5909 /* Avoid overflows. */
5910 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5911 && (INTVAL (operands[2]) == 128
5912 || (INTVAL (operands[2]) < 0
5913 && INTVAL (operands[2]) != -128)))
5915 operands[2] = GEN_INT (-INTVAL (operands[2]));
5916 return "sub{q}\t{%2, %0|%0, %2}";
5918 return "add{q}\t{%2, %0|%0, %2}";
5922 (cond [(eq_attr "alternative" "2")
5923 (const_string "lea")
5924 ; Current assemblers are broken and do not allow @GOTOFF in
5925 ; ought but a memory context.
5926 (match_operand:DI 2 "pic_symbolic_operand" "")
5927 (const_string "lea")
5928 (match_operand:DI 2 "incdec_operand" "")
5929 (const_string "incdec")
5931 (const_string "alu")))
5932 (set_attr "mode" "DI")])
5934 ;; Convert lea to the lea pattern to avoid flags dependency.
5936 [(set (match_operand:DI 0 "register_operand" "")
5937 (plus:DI (match_operand:DI 1 "register_operand" "")
5938 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5939 (clobber (reg:CC FLAGS_REG))]
5940 "TARGET_64BIT && reload_completed
5941 && true_regnum (operands[0]) != true_regnum (operands[1])"
5943 (plus:DI (match_dup 1)
5947 (define_insn "*adddi_2_rex64"
5948 [(set (reg FLAGS_REG)
5950 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5951 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5953 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5954 (plus:DI (match_dup 1) (match_dup 2)))]
5955 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5956 && ix86_binary_operator_ok (PLUS, DImode, operands)
5957 /* Current assemblers are broken and do not allow @GOTOFF in
5958 ought but a memory context. */
5959 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5961 switch (get_attr_type (insn))
5964 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5965 if (operands[2] == const1_rtx)
5966 return "inc{q}\t%0";
5969 gcc_assert (operands[2] == constm1_rtx);
5970 return "dec{q}\t%0";
5974 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5975 /* ???? We ought to handle there the 32bit case too
5976 - do we need new constraint? */
5977 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5978 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5979 if (CONST_INT_P (operands[2])
5980 /* Avoid overflows. */
5981 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5982 && (INTVAL (operands[2]) == 128
5983 || (INTVAL (operands[2]) < 0
5984 && INTVAL (operands[2]) != -128)))
5986 operands[2] = GEN_INT (-INTVAL (operands[2]));
5987 return "sub{q}\t{%2, %0|%0, %2}";
5989 return "add{q}\t{%2, %0|%0, %2}";
5993 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5994 (const_string "incdec")
5995 (const_string "alu")))
5996 (set_attr "mode" "DI")])
5998 (define_insn "*adddi_3_rex64"
5999 [(set (reg FLAGS_REG)
6000 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6001 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6002 (clobber (match_scratch:DI 0 "=r"))]
6004 && ix86_match_ccmode (insn, CCZmode)
6005 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6006 /* Current assemblers are broken and do not allow @GOTOFF in
6007 ought but a memory context. */
6008 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6010 switch (get_attr_type (insn))
6013 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6014 if (operands[2] == const1_rtx)
6015 return "inc{q}\t%0";
6018 gcc_assert (operands[2] == constm1_rtx);
6019 return "dec{q}\t%0";
6023 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6024 /* ???? We ought to handle there the 32bit case too
6025 - do we need new constraint? */
6026 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6027 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6028 if (CONST_INT_P (operands[2])
6029 /* Avoid overflows. */
6030 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6031 && (INTVAL (operands[2]) == 128
6032 || (INTVAL (operands[2]) < 0
6033 && INTVAL (operands[2]) != -128)))
6035 operands[2] = GEN_INT (-INTVAL (operands[2]));
6036 return "sub{q}\t{%2, %0|%0, %2}";
6038 return "add{q}\t{%2, %0|%0, %2}";
6042 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6043 (const_string "incdec")
6044 (const_string "alu")))
6045 (set_attr "mode" "DI")])
6047 ; For comparisons against 1, -1 and 128, we may generate better code
6048 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6049 ; is matched then. We can't accept general immediate, because for
6050 ; case of overflows, the result is messed up.
6051 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6053 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6054 ; only for comparisons not depending on it.
6055 (define_insn "*adddi_4_rex64"
6056 [(set (reg FLAGS_REG)
6057 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6058 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6059 (clobber (match_scratch:DI 0 "=rm"))]
6061 && ix86_match_ccmode (insn, CCGCmode)"
6063 switch (get_attr_type (insn))
6066 if (operands[2] == constm1_rtx)
6067 return "inc{q}\t%0";
6070 gcc_assert (operands[2] == const1_rtx);
6071 return "dec{q}\t%0";
6075 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6076 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6077 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6078 if ((INTVAL (operands[2]) == -128
6079 || (INTVAL (operands[2]) > 0
6080 && INTVAL (operands[2]) != 128))
6081 /* Avoid overflows. */
6082 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6083 return "sub{q}\t{%2, %0|%0, %2}";
6084 operands[2] = GEN_INT (-INTVAL (operands[2]));
6085 return "add{q}\t{%2, %0|%0, %2}";
6089 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6090 (const_string "incdec")
6091 (const_string "alu")))
6092 (set_attr "mode" "DI")])
6094 (define_insn "*adddi_5_rex64"
6095 [(set (reg FLAGS_REG)
6097 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6098 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6100 (clobber (match_scratch:DI 0 "=r"))]
6102 && ix86_match_ccmode (insn, CCGOCmode)
6103 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6104 /* Current assemblers are broken and do not allow @GOTOFF in
6105 ought but a memory context. */
6106 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6108 switch (get_attr_type (insn))
6111 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6112 if (operands[2] == const1_rtx)
6113 return "inc{q}\t%0";
6116 gcc_assert (operands[2] == constm1_rtx);
6117 return "dec{q}\t%0";
6121 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6122 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6123 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6124 if (CONST_INT_P (operands[2])
6125 /* Avoid overflows. */
6126 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6127 && (INTVAL (operands[2]) == 128
6128 || (INTVAL (operands[2]) < 0
6129 && INTVAL (operands[2]) != -128)))
6131 operands[2] = GEN_INT (-INTVAL (operands[2]));
6132 return "sub{q}\t{%2, %0|%0, %2}";
6134 return "add{q}\t{%2, %0|%0, %2}";
6138 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6139 (const_string "incdec")
6140 (const_string "alu")))
6141 (set_attr "mode" "DI")])
6144 (define_insn "*addsi_1"
6145 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6146 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6147 (match_operand:SI 2 "general_operand" "g,ri,li")))
6148 (clobber (reg:CC FLAGS_REG))]
6149 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6151 switch (get_attr_type (insn))
6154 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6155 return "lea{l}\t{%a2, %0|%0, %a2}";
6158 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6159 if (operands[2] == const1_rtx)
6160 return "inc{l}\t%0";
6163 gcc_assert (operands[2] == constm1_rtx);
6164 return "dec{l}\t%0";
6168 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6170 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6171 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6172 if (CONST_INT_P (operands[2])
6173 && (INTVAL (operands[2]) == 128
6174 || (INTVAL (operands[2]) < 0
6175 && INTVAL (operands[2]) != -128)))
6177 operands[2] = GEN_INT (-INTVAL (operands[2]));
6178 return "sub{l}\t{%2, %0|%0, %2}";
6180 return "add{l}\t{%2, %0|%0, %2}";
6184 (cond [(eq_attr "alternative" "2")
6185 (const_string "lea")
6186 ; Current assemblers are broken and do not allow @GOTOFF in
6187 ; ought but a memory context.
6188 (match_operand:SI 2 "pic_symbolic_operand" "")
6189 (const_string "lea")
6190 (match_operand:SI 2 "incdec_operand" "")
6191 (const_string "incdec")
6193 (const_string "alu")))
6194 (set_attr "mode" "SI")])
6196 ;; Convert lea to the lea pattern to avoid flags dependency.
6198 [(set (match_operand 0 "register_operand" "")
6199 (plus (match_operand 1 "register_operand" "")
6200 (match_operand 2 "nonmemory_operand" "")))
6201 (clobber (reg:CC FLAGS_REG))]
6203 && true_regnum (operands[0]) != true_regnum (operands[1])"
6207 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6208 may confuse gen_lowpart. */
6209 if (GET_MODE (operands[0]) != Pmode)
6211 operands[1] = gen_lowpart (Pmode, operands[1]);
6212 operands[2] = gen_lowpart (Pmode, operands[2]);
6214 operands[0] = gen_lowpart (SImode, operands[0]);
6215 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6216 if (Pmode != SImode)
6217 pat = gen_rtx_SUBREG (SImode, pat, 0);
6218 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6222 ;; It may seem that nonimmediate operand is proper one for operand 1.
6223 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6224 ;; we take care in ix86_binary_operator_ok to not allow two memory
6225 ;; operands so proper swapping will be done in reload. This allow
6226 ;; patterns constructed from addsi_1 to match.
6227 (define_insn "addsi_1_zext"
6228 [(set (match_operand:DI 0 "register_operand" "=r,r")
6230 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6231 (match_operand:SI 2 "general_operand" "g,li"))))
6232 (clobber (reg:CC FLAGS_REG))]
6233 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6235 switch (get_attr_type (insn))
6238 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6239 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6242 if (operands[2] == const1_rtx)
6243 return "inc{l}\t%k0";
6246 gcc_assert (operands[2] == constm1_rtx);
6247 return "dec{l}\t%k0";
6251 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6252 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6253 if (CONST_INT_P (operands[2])
6254 && (INTVAL (operands[2]) == 128
6255 || (INTVAL (operands[2]) < 0
6256 && INTVAL (operands[2]) != -128)))
6258 operands[2] = GEN_INT (-INTVAL (operands[2]));
6259 return "sub{l}\t{%2, %k0|%k0, %2}";
6261 return "add{l}\t{%2, %k0|%k0, %2}";
6265 (cond [(eq_attr "alternative" "1")
6266 (const_string "lea")
6267 ; Current assemblers are broken and do not allow @GOTOFF in
6268 ; ought but a memory context.
6269 (match_operand:SI 2 "pic_symbolic_operand" "")
6270 (const_string "lea")
6271 (match_operand:SI 2 "incdec_operand" "")
6272 (const_string "incdec")
6274 (const_string "alu")))
6275 (set_attr "mode" "SI")])
6277 ;; Convert lea to the lea pattern to avoid flags dependency.
6279 [(set (match_operand:DI 0 "register_operand" "")
6281 (plus:SI (match_operand:SI 1 "register_operand" "")
6282 (match_operand:SI 2 "nonmemory_operand" ""))))
6283 (clobber (reg:CC FLAGS_REG))]
6284 "TARGET_64BIT && reload_completed
6285 && true_regnum (operands[0]) != true_regnum (operands[1])"
6287 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6289 operands[1] = gen_lowpart (Pmode, operands[1]);
6290 operands[2] = gen_lowpart (Pmode, operands[2]);
6293 (define_insn "*addsi_2"
6294 [(set (reg FLAGS_REG)
6296 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6297 (match_operand:SI 2 "general_operand" "g,ri"))
6299 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6300 (plus:SI (match_dup 1) (match_dup 2)))]
6301 "ix86_match_ccmode (insn, CCGOCmode)
6302 && ix86_binary_operator_ok (PLUS, SImode, operands)
6303 /* Current assemblers are broken and do not allow @GOTOFF in
6304 ought but a memory context. */
6305 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6307 switch (get_attr_type (insn))
6310 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6311 if (operands[2] == const1_rtx)
6312 return "inc{l}\t%0";
6315 gcc_assert (operands[2] == constm1_rtx);
6316 return "dec{l}\t%0";
6320 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6321 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6322 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6323 if (CONST_INT_P (operands[2])
6324 && (INTVAL (operands[2]) == 128
6325 || (INTVAL (operands[2]) < 0
6326 && INTVAL (operands[2]) != -128)))
6328 operands[2] = GEN_INT (-INTVAL (operands[2]));
6329 return "sub{l}\t{%2, %0|%0, %2}";
6331 return "add{l}\t{%2, %0|%0, %2}";
6335 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6336 (const_string "incdec")
6337 (const_string "alu")))
6338 (set_attr "mode" "SI")])
6340 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6341 (define_insn "*addsi_2_zext"
6342 [(set (reg FLAGS_REG)
6344 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6345 (match_operand:SI 2 "general_operand" "g"))
6347 (set (match_operand:DI 0 "register_operand" "=r")
6348 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6349 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6350 && ix86_binary_operator_ok (PLUS, SImode, operands)
6351 /* Current assemblers are broken and do not allow @GOTOFF in
6352 ought but a memory context. */
6353 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6355 switch (get_attr_type (insn))
6358 if (operands[2] == const1_rtx)
6359 return "inc{l}\t%k0";
6362 gcc_assert (operands[2] == constm1_rtx);
6363 return "dec{l}\t%k0";
6367 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6368 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6369 if (CONST_INT_P (operands[2])
6370 && (INTVAL (operands[2]) == 128
6371 || (INTVAL (operands[2]) < 0
6372 && INTVAL (operands[2]) != -128)))
6374 operands[2] = GEN_INT (-INTVAL (operands[2]));
6375 return "sub{l}\t{%2, %k0|%k0, %2}";
6377 return "add{l}\t{%2, %k0|%k0, %2}";
6381 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6382 (const_string "incdec")
6383 (const_string "alu")))
6384 (set_attr "mode" "SI")])
6386 (define_insn "*addsi_3"
6387 [(set (reg FLAGS_REG)
6388 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6389 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6390 (clobber (match_scratch:SI 0 "=r"))]
6391 "ix86_match_ccmode (insn, CCZmode)
6392 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6393 /* Current assemblers are broken and do not allow @GOTOFF in
6394 ought but a memory context. */
6395 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6397 switch (get_attr_type (insn))
6400 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6401 if (operands[2] == const1_rtx)
6402 return "inc{l}\t%0";
6405 gcc_assert (operands[2] == constm1_rtx);
6406 return "dec{l}\t%0";
6410 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6411 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6412 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6413 if (CONST_INT_P (operands[2])
6414 && (INTVAL (operands[2]) == 128
6415 || (INTVAL (operands[2]) < 0
6416 && INTVAL (operands[2]) != -128)))
6418 operands[2] = GEN_INT (-INTVAL (operands[2]));
6419 return "sub{l}\t{%2, %0|%0, %2}";
6421 return "add{l}\t{%2, %0|%0, %2}";
6425 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6426 (const_string "incdec")
6427 (const_string "alu")))
6428 (set_attr "mode" "SI")])
6430 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6431 (define_insn "*addsi_3_zext"
6432 [(set (reg FLAGS_REG)
6433 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6434 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6435 (set (match_operand:DI 0 "register_operand" "=r")
6436 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6437 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6438 && ix86_binary_operator_ok (PLUS, SImode, operands)
6439 /* Current assemblers are broken and do not allow @GOTOFF in
6440 ought but a memory context. */
6441 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6443 switch (get_attr_type (insn))
6446 if (operands[2] == const1_rtx)
6447 return "inc{l}\t%k0";
6450 gcc_assert (operands[2] == constm1_rtx);
6451 return "dec{l}\t%k0";
6455 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6456 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6457 if (CONST_INT_P (operands[2])
6458 && (INTVAL (operands[2]) == 128
6459 || (INTVAL (operands[2]) < 0
6460 && INTVAL (operands[2]) != -128)))
6462 operands[2] = GEN_INT (-INTVAL (operands[2]));
6463 return "sub{l}\t{%2, %k0|%k0, %2}";
6465 return "add{l}\t{%2, %k0|%k0, %2}";
6469 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6470 (const_string "incdec")
6471 (const_string "alu")))
6472 (set_attr "mode" "SI")])
6474 ; For comparisons against 1, -1 and 128, we may generate better code
6475 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6476 ; is matched then. We can't accept general immediate, because for
6477 ; case of overflows, the result is messed up.
6478 ; This pattern also don't hold of 0x80000000, since the value overflows
6480 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6481 ; only for comparisons not depending on it.
6482 (define_insn "*addsi_4"
6483 [(set (reg FLAGS_REG)
6484 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6485 (match_operand:SI 2 "const_int_operand" "n")))
6486 (clobber (match_scratch:SI 0 "=rm"))]
6487 "ix86_match_ccmode (insn, CCGCmode)
6488 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6490 switch (get_attr_type (insn))
6493 if (operands[2] == constm1_rtx)
6494 return "inc{l}\t%0";
6497 gcc_assert (operands[2] == const1_rtx);
6498 return "dec{l}\t%0";
6502 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6503 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6504 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6505 if ((INTVAL (operands[2]) == -128
6506 || (INTVAL (operands[2]) > 0
6507 && INTVAL (operands[2]) != 128)))
6508 return "sub{l}\t{%2, %0|%0, %2}";
6509 operands[2] = GEN_INT (-INTVAL (operands[2]));
6510 return "add{l}\t{%2, %0|%0, %2}";
6514 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6515 (const_string "incdec")
6516 (const_string "alu")))
6517 (set_attr "mode" "SI")])
6519 (define_insn "*addsi_5"
6520 [(set (reg FLAGS_REG)
6522 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6523 (match_operand:SI 2 "general_operand" "g"))
6525 (clobber (match_scratch:SI 0 "=r"))]
6526 "ix86_match_ccmode (insn, CCGOCmode)
6527 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6528 /* Current assemblers are broken and do not allow @GOTOFF in
6529 ought but a memory context. */
6530 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6532 switch (get_attr_type (insn))
6535 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6536 if (operands[2] == const1_rtx)
6537 return "inc{l}\t%0";
6540 gcc_assert (operands[2] == constm1_rtx);
6541 return "dec{l}\t%0";
6545 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6546 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6547 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6548 if (CONST_INT_P (operands[2])
6549 && (INTVAL (operands[2]) == 128
6550 || (INTVAL (operands[2]) < 0
6551 && INTVAL (operands[2]) != -128)))
6553 operands[2] = GEN_INT (-INTVAL (operands[2]));
6554 return "sub{l}\t{%2, %0|%0, %2}";
6556 return "add{l}\t{%2, %0|%0, %2}";
6560 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6561 (const_string "incdec")
6562 (const_string "alu")))
6563 (set_attr "mode" "SI")])
6565 (define_expand "addhi3"
6566 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6567 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6568 (match_operand:HI 2 "general_operand" "")))
6569 (clobber (reg:CC FLAGS_REG))])]
6570 "TARGET_HIMODE_MATH"
6571 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6573 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6574 ;; type optimizations enabled by define-splits. This is not important
6575 ;; for PII, and in fact harmful because of partial register stalls.
6577 (define_insn "*addhi_1_lea"
6578 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6579 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6580 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6581 (clobber (reg:CC FLAGS_REG))]
6582 "!TARGET_PARTIAL_REG_STALL
6583 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6585 switch (get_attr_type (insn))
6590 if (operands[2] == const1_rtx)
6591 return "inc{w}\t%0";
6594 gcc_assert (operands[2] == constm1_rtx);
6595 return "dec{w}\t%0";
6599 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6600 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6601 if (CONST_INT_P (operands[2])
6602 && (INTVAL (operands[2]) == 128
6603 || (INTVAL (operands[2]) < 0
6604 && INTVAL (operands[2]) != -128)))
6606 operands[2] = GEN_INT (-INTVAL (operands[2]));
6607 return "sub{w}\t{%2, %0|%0, %2}";
6609 return "add{w}\t{%2, %0|%0, %2}";
6613 (if_then_else (eq_attr "alternative" "2")
6614 (const_string "lea")
6615 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6616 (const_string "incdec")
6617 (const_string "alu"))))
6618 (set_attr "mode" "HI,HI,SI")])
6620 (define_insn "*addhi_1"
6621 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6622 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6623 (match_operand:HI 2 "general_operand" "rn,rm")))
6624 (clobber (reg:CC FLAGS_REG))]
6625 "TARGET_PARTIAL_REG_STALL
6626 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6628 switch (get_attr_type (insn))
6631 if (operands[2] == const1_rtx)
6632 return "inc{w}\t%0";
6635 gcc_assert (operands[2] == constm1_rtx);
6636 return "dec{w}\t%0";
6640 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6641 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6642 if (CONST_INT_P (operands[2])
6643 && (INTVAL (operands[2]) == 128
6644 || (INTVAL (operands[2]) < 0
6645 && INTVAL (operands[2]) != -128)))
6647 operands[2] = GEN_INT (-INTVAL (operands[2]));
6648 return "sub{w}\t{%2, %0|%0, %2}";
6650 return "add{w}\t{%2, %0|%0, %2}";
6654 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6655 (const_string "incdec")
6656 (const_string "alu")))
6657 (set_attr "mode" "HI")])
6659 (define_insn "*addhi_2"
6660 [(set (reg FLAGS_REG)
6662 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6663 (match_operand:HI 2 "general_operand" "rmn,rn"))
6665 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6666 (plus:HI (match_dup 1) (match_dup 2)))]
6667 "ix86_match_ccmode (insn, CCGOCmode)
6668 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6670 switch (get_attr_type (insn))
6673 if (operands[2] == const1_rtx)
6674 return "inc{w}\t%0";
6677 gcc_assert (operands[2] == constm1_rtx);
6678 return "dec{w}\t%0";
6682 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6683 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6684 if (CONST_INT_P (operands[2])
6685 && (INTVAL (operands[2]) == 128
6686 || (INTVAL (operands[2]) < 0
6687 && INTVAL (operands[2]) != -128)))
6689 operands[2] = GEN_INT (-INTVAL (operands[2]));
6690 return "sub{w}\t{%2, %0|%0, %2}";
6692 return "add{w}\t{%2, %0|%0, %2}";
6696 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6697 (const_string "incdec")
6698 (const_string "alu")))
6699 (set_attr "mode" "HI")])
6701 (define_insn "*addhi_3"
6702 [(set (reg FLAGS_REG)
6703 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6704 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6705 (clobber (match_scratch:HI 0 "=r"))]
6706 "ix86_match_ccmode (insn, CCZmode)
6707 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6709 switch (get_attr_type (insn))
6712 if (operands[2] == const1_rtx)
6713 return "inc{w}\t%0";
6716 gcc_assert (operands[2] == constm1_rtx);
6717 return "dec{w}\t%0";
6721 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6722 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6723 if (CONST_INT_P (operands[2])
6724 && (INTVAL (operands[2]) == 128
6725 || (INTVAL (operands[2]) < 0
6726 && INTVAL (operands[2]) != -128)))
6728 operands[2] = GEN_INT (-INTVAL (operands[2]));
6729 return "sub{w}\t{%2, %0|%0, %2}";
6731 return "add{w}\t{%2, %0|%0, %2}";
6735 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6736 (const_string "incdec")
6737 (const_string "alu")))
6738 (set_attr "mode" "HI")])
6740 ; See comments above addsi_4 for details.
6741 (define_insn "*addhi_4"
6742 [(set (reg FLAGS_REG)
6743 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6744 (match_operand:HI 2 "const_int_operand" "n")))
6745 (clobber (match_scratch:HI 0 "=rm"))]
6746 "ix86_match_ccmode (insn, CCGCmode)
6747 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6749 switch (get_attr_type (insn))
6752 if (operands[2] == constm1_rtx)
6753 return "inc{w}\t%0";
6756 gcc_assert (operands[2] == const1_rtx);
6757 return "dec{w}\t%0";
6761 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6762 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6763 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6764 if ((INTVAL (operands[2]) == -128
6765 || (INTVAL (operands[2]) > 0
6766 && INTVAL (operands[2]) != 128)))
6767 return "sub{w}\t{%2, %0|%0, %2}";
6768 operands[2] = GEN_INT (-INTVAL (operands[2]));
6769 return "add{w}\t{%2, %0|%0, %2}";
6773 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6774 (const_string "incdec")
6775 (const_string "alu")))
6776 (set_attr "mode" "SI")])
6779 (define_insn "*addhi_5"
6780 [(set (reg FLAGS_REG)
6782 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6783 (match_operand:HI 2 "general_operand" "rmn"))
6785 (clobber (match_scratch:HI 0 "=r"))]
6786 "ix86_match_ccmode (insn, CCGOCmode)
6787 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6789 switch (get_attr_type (insn))
6792 if (operands[2] == const1_rtx)
6793 return "inc{w}\t%0";
6796 gcc_assert (operands[2] == constm1_rtx);
6797 return "dec{w}\t%0";
6801 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6802 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6803 if (CONST_INT_P (operands[2])
6804 && (INTVAL (operands[2]) == 128
6805 || (INTVAL (operands[2]) < 0
6806 && INTVAL (operands[2]) != -128)))
6808 operands[2] = GEN_INT (-INTVAL (operands[2]));
6809 return "sub{w}\t{%2, %0|%0, %2}";
6811 return "add{w}\t{%2, %0|%0, %2}";
6815 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6816 (const_string "incdec")
6817 (const_string "alu")))
6818 (set_attr "mode" "HI")])
6820 (define_expand "addqi3"
6821 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6822 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6823 (match_operand:QI 2 "general_operand" "")))
6824 (clobber (reg:CC FLAGS_REG))])]
6825 "TARGET_QIMODE_MATH"
6826 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6828 ;; %%% Potential partial reg stall on alternative 2. What to do?
6829 (define_insn "*addqi_1_lea"
6830 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6831 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6832 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6833 (clobber (reg:CC FLAGS_REG))]
6834 "!TARGET_PARTIAL_REG_STALL
6835 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6837 int widen = (which_alternative == 2);
6838 switch (get_attr_type (insn))
6843 if (operands[2] == const1_rtx)
6844 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6847 gcc_assert (operands[2] == constm1_rtx);
6848 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6852 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6853 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6854 if (CONST_INT_P (operands[2])
6855 && (INTVAL (operands[2]) == 128
6856 || (INTVAL (operands[2]) < 0
6857 && INTVAL (operands[2]) != -128)))
6859 operands[2] = GEN_INT (-INTVAL (operands[2]));
6861 return "sub{l}\t{%2, %k0|%k0, %2}";
6863 return "sub{b}\t{%2, %0|%0, %2}";
6866 return "add{l}\t{%k2, %k0|%k0, %k2}";
6868 return "add{b}\t{%2, %0|%0, %2}";
6872 (if_then_else (eq_attr "alternative" "3")
6873 (const_string "lea")
6874 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6875 (const_string "incdec")
6876 (const_string "alu"))))
6877 (set_attr "mode" "QI,QI,SI,SI")])
6879 (define_insn "*addqi_1"
6880 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6881 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6882 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6883 (clobber (reg:CC FLAGS_REG))]
6884 "TARGET_PARTIAL_REG_STALL
6885 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6887 int widen = (which_alternative == 2);
6888 switch (get_attr_type (insn))
6891 if (operands[2] == const1_rtx)
6892 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6895 gcc_assert (operands[2] == constm1_rtx);
6896 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6900 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6901 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6902 if (CONST_INT_P (operands[2])
6903 && (INTVAL (operands[2]) == 128
6904 || (INTVAL (operands[2]) < 0
6905 && INTVAL (operands[2]) != -128)))
6907 operands[2] = GEN_INT (-INTVAL (operands[2]));
6909 return "sub{l}\t{%2, %k0|%k0, %2}";
6911 return "sub{b}\t{%2, %0|%0, %2}";
6914 return "add{l}\t{%k2, %k0|%k0, %k2}";
6916 return "add{b}\t{%2, %0|%0, %2}";
6920 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6921 (const_string "incdec")
6922 (const_string "alu")))
6923 (set_attr "mode" "QI,QI,SI")])
6925 (define_insn "*addqi_1_slp"
6926 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6927 (plus:QI (match_dup 0)
6928 (match_operand:QI 1 "general_operand" "qn,qnm")))
6929 (clobber (reg:CC FLAGS_REG))]
6930 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6931 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6933 switch (get_attr_type (insn))
6936 if (operands[1] == const1_rtx)
6937 return "inc{b}\t%0";
6940 gcc_assert (operands[1] == constm1_rtx);
6941 return "dec{b}\t%0";
6945 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6946 if (CONST_INT_P (operands[1])
6947 && INTVAL (operands[1]) < 0)
6949 operands[1] = GEN_INT (-INTVAL (operands[1]));
6950 return "sub{b}\t{%1, %0|%0, %1}";
6952 return "add{b}\t{%1, %0|%0, %1}";
6956 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6957 (const_string "incdec")
6958 (const_string "alu1")))
6959 (set (attr "memory")
6960 (if_then_else (match_operand 1 "memory_operand" "")
6961 (const_string "load")
6962 (const_string "none")))
6963 (set_attr "mode" "QI")])
6965 (define_insn "*addqi_2"
6966 [(set (reg FLAGS_REG)
6968 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6969 (match_operand:QI 2 "general_operand" "qmn,qn"))
6971 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6972 (plus:QI (match_dup 1) (match_dup 2)))]
6973 "ix86_match_ccmode (insn, CCGOCmode)
6974 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6976 switch (get_attr_type (insn))
6979 if (operands[2] == const1_rtx)
6980 return "inc{b}\t%0";
6983 gcc_assert (operands[2] == constm1_rtx
6984 || (CONST_INT_P (operands[2])
6985 && INTVAL (operands[2]) == 255));
6986 return "dec{b}\t%0";
6990 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6991 if (CONST_INT_P (operands[2])
6992 && INTVAL (operands[2]) < 0)
6994 operands[2] = GEN_INT (-INTVAL (operands[2]));
6995 return "sub{b}\t{%2, %0|%0, %2}";
6997 return "add{b}\t{%2, %0|%0, %2}";
7001 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7002 (const_string "incdec")
7003 (const_string "alu")))
7004 (set_attr "mode" "QI")])
7006 (define_insn "*addqi_3"
7007 [(set (reg FLAGS_REG)
7008 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7009 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7010 (clobber (match_scratch:QI 0 "=q"))]
7011 "ix86_match_ccmode (insn, CCZmode)
7012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7014 switch (get_attr_type (insn))
7017 if (operands[2] == const1_rtx)
7018 return "inc{b}\t%0";
7021 gcc_assert (operands[2] == constm1_rtx
7022 || (CONST_INT_P (operands[2])
7023 && INTVAL (operands[2]) == 255));
7024 return "dec{b}\t%0";
7028 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7029 if (CONST_INT_P (operands[2])
7030 && INTVAL (operands[2]) < 0)
7032 operands[2] = GEN_INT (-INTVAL (operands[2]));
7033 return "sub{b}\t{%2, %0|%0, %2}";
7035 return "add{b}\t{%2, %0|%0, %2}";
7039 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7040 (const_string "incdec")
7041 (const_string "alu")))
7042 (set_attr "mode" "QI")])
7044 ; See comments above addsi_4 for details.
7045 (define_insn "*addqi_4"
7046 [(set (reg FLAGS_REG)
7047 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7048 (match_operand:QI 2 "const_int_operand" "n")))
7049 (clobber (match_scratch:QI 0 "=qm"))]
7050 "ix86_match_ccmode (insn, CCGCmode)
7051 && (INTVAL (operands[2]) & 0xff) != 0x80"
7053 switch (get_attr_type (insn))
7056 if (operands[2] == constm1_rtx
7057 || (CONST_INT_P (operands[2])
7058 && INTVAL (operands[2]) == 255))
7059 return "inc{b}\t%0";
7062 gcc_assert (operands[2] == const1_rtx);
7063 return "dec{b}\t%0";
7067 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7068 if (INTVAL (operands[2]) < 0)
7070 operands[2] = GEN_INT (-INTVAL (operands[2]));
7071 return "add{b}\t{%2, %0|%0, %2}";
7073 return "sub{b}\t{%2, %0|%0, %2}";
7077 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7078 (const_string "incdec")
7079 (const_string "alu")))
7080 (set_attr "mode" "QI")])
7083 (define_insn "*addqi_5"
7084 [(set (reg FLAGS_REG)
7086 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7087 (match_operand:QI 2 "general_operand" "qmn"))
7089 (clobber (match_scratch:QI 0 "=q"))]
7090 "ix86_match_ccmode (insn, CCGOCmode)
7091 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7093 switch (get_attr_type (insn))
7096 if (operands[2] == const1_rtx)
7097 return "inc{b}\t%0";
7100 gcc_assert (operands[2] == constm1_rtx
7101 || (CONST_INT_P (operands[2])
7102 && INTVAL (operands[2]) == 255));
7103 return "dec{b}\t%0";
7107 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7108 if (CONST_INT_P (operands[2])
7109 && INTVAL (operands[2]) < 0)
7111 operands[2] = GEN_INT (-INTVAL (operands[2]));
7112 return "sub{b}\t{%2, %0|%0, %2}";
7114 return "add{b}\t{%2, %0|%0, %2}";
7118 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7119 (const_string "incdec")
7120 (const_string "alu")))
7121 (set_attr "mode" "QI")])
7124 (define_insn "addqi_ext_1"
7125 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7130 (match_operand 1 "ext_register_operand" "0")
7133 (match_operand:QI 2 "general_operand" "Qmn")))
7134 (clobber (reg:CC FLAGS_REG))]
7137 switch (get_attr_type (insn))
7140 if (operands[2] == const1_rtx)
7141 return "inc{b}\t%h0";
7144 gcc_assert (operands[2] == constm1_rtx
7145 || (CONST_INT_P (operands[2])
7146 && INTVAL (operands[2]) == 255));
7147 return "dec{b}\t%h0";
7151 return "add{b}\t{%2, %h0|%h0, %2}";
7155 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7156 (const_string "incdec")
7157 (const_string "alu")))
7158 (set_attr "mode" "QI")])
7160 (define_insn "*addqi_ext_1_rex64"
7161 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7166 (match_operand 1 "ext_register_operand" "0")
7169 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7170 (clobber (reg:CC FLAGS_REG))]
7173 switch (get_attr_type (insn))
7176 if (operands[2] == const1_rtx)
7177 return "inc{b}\t%h0";
7180 gcc_assert (operands[2] == constm1_rtx
7181 || (CONST_INT_P (operands[2])
7182 && INTVAL (operands[2]) == 255));
7183 return "dec{b}\t%h0";
7187 return "add{b}\t{%2, %h0|%h0, %2}";
7191 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7192 (const_string "incdec")
7193 (const_string "alu")))
7194 (set_attr "mode" "QI")])
7196 (define_insn "*addqi_ext_2"
7197 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7202 (match_operand 1 "ext_register_operand" "%0")
7206 (match_operand 2 "ext_register_operand" "Q")
7209 (clobber (reg:CC FLAGS_REG))]
7211 "add{b}\t{%h2, %h0|%h0, %h2}"
7212 [(set_attr "type" "alu")
7213 (set_attr "mode" "QI")])
7215 ;; The patterns that match these are at the end of this file.
7217 (define_expand "addxf3"
7218 [(set (match_operand:XF 0 "register_operand" "")
7219 (plus:XF (match_operand:XF 1 "register_operand" "")
7220 (match_operand:XF 2 "register_operand" "")))]
7224 (define_expand "add<mode>3"
7225 [(set (match_operand:MODEF 0 "register_operand" "")
7226 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7227 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7228 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7231 ;; Subtract instructions
7233 ;; %%% splits for subditi3
7235 (define_expand "subti3"
7236 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7237 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7238 (match_operand:TI 2 "x86_64_general_operand" "")))
7239 (clobber (reg:CC FLAGS_REG))])]
7241 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7243 (define_insn "*subti3_1"
7244 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7245 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7246 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7247 (clobber (reg:CC FLAGS_REG))]
7248 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7252 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7253 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7254 (match_operand:TI 2 "x86_64_general_operand" "")))
7255 (clobber (reg:CC FLAGS_REG))]
7256 "TARGET_64BIT && reload_completed"
7257 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7258 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7259 (parallel [(set (match_dup 3)
7260 (minus:DI (match_dup 4)
7261 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7263 (clobber (reg:CC FLAGS_REG))])]
7264 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7266 ;; %%% splits for subsidi3
7268 (define_expand "subdi3"
7269 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7270 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7271 (match_operand:DI 2 "x86_64_general_operand" "")))
7272 (clobber (reg:CC FLAGS_REG))])]
7274 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7276 (define_insn "*subdi3_1"
7277 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7278 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7279 (match_operand:DI 2 "general_operand" "roiF,riF")))
7280 (clobber (reg:CC FLAGS_REG))]
7281 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7285 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7286 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7287 (match_operand:DI 2 "general_operand" "")))
7288 (clobber (reg:CC FLAGS_REG))]
7289 "!TARGET_64BIT && reload_completed"
7290 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7291 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7292 (parallel [(set (match_dup 3)
7293 (minus:SI (match_dup 4)
7294 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7296 (clobber (reg:CC FLAGS_REG))])]
7297 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7299 (define_insn "subdi3_carry_rex64"
7300 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7301 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7302 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7303 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7304 (clobber (reg:CC FLAGS_REG))]
7305 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7306 "sbb{q}\t{%2, %0|%0, %2}"
7307 [(set_attr "type" "alu")
7308 (set_attr "pent_pair" "pu")
7309 (set_attr "mode" "DI")])
7311 (define_insn "*subdi_1_rex64"
7312 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7313 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7314 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7315 (clobber (reg:CC FLAGS_REG))]
7316 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7317 "sub{q}\t{%2, %0|%0, %2}"
7318 [(set_attr "type" "alu")
7319 (set_attr "mode" "DI")])
7321 (define_insn "*subdi_2_rex64"
7322 [(set (reg FLAGS_REG)
7324 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7325 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7327 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7328 (minus:DI (match_dup 1) (match_dup 2)))]
7329 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7330 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7331 "sub{q}\t{%2, %0|%0, %2}"
7332 [(set_attr "type" "alu")
7333 (set_attr "mode" "DI")])
7335 (define_insn "*subdi_3_rex63"
7336 [(set (reg FLAGS_REG)
7337 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7338 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7339 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7340 (minus:DI (match_dup 1) (match_dup 2)))]
7341 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7342 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7343 "sub{q}\t{%2, %0|%0, %2}"
7344 [(set_attr "type" "alu")
7345 (set_attr "mode" "DI")])
7347 (define_insn "subqi3_carry"
7348 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7349 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7350 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7351 (match_operand:QI 2 "general_operand" "qn,qm"))))
7352 (clobber (reg:CC FLAGS_REG))]
7353 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7354 "sbb{b}\t{%2, %0|%0, %2}"
7355 [(set_attr "type" "alu")
7356 (set_attr "pent_pair" "pu")
7357 (set_attr "mode" "QI")])
7359 (define_insn "subhi3_carry"
7360 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7361 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7362 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7363 (match_operand:HI 2 "general_operand" "rn,rm"))))
7364 (clobber (reg:CC FLAGS_REG))]
7365 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7366 "sbb{w}\t{%2, %0|%0, %2}"
7367 [(set_attr "type" "alu")
7368 (set_attr "pent_pair" "pu")
7369 (set_attr "mode" "HI")])
7371 (define_insn "subsi3_carry"
7372 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7373 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7374 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7375 (match_operand:SI 2 "general_operand" "ri,rm"))))
7376 (clobber (reg:CC FLAGS_REG))]
7377 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7378 "sbb{l}\t{%2, %0|%0, %2}"
7379 [(set_attr "type" "alu")
7380 (set_attr "pent_pair" "pu")
7381 (set_attr "mode" "SI")])
7383 (define_insn "subsi3_carry_zext"
7384 [(set (match_operand:DI 0 "register_operand" "=r")
7386 (minus:SI (match_operand:SI 1 "register_operand" "0")
7387 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7388 (match_operand:SI 2 "general_operand" "g")))))
7389 (clobber (reg:CC FLAGS_REG))]
7390 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7391 "sbb{l}\t{%2, %k0|%k0, %2}"
7392 [(set_attr "type" "alu")
7393 (set_attr "pent_pair" "pu")
7394 (set_attr "mode" "SI")])
7396 (define_expand "subsi3"
7397 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7398 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7399 (match_operand:SI 2 "general_operand" "")))
7400 (clobber (reg:CC FLAGS_REG))])]
7402 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7404 (define_insn "*subsi_1"
7405 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7406 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7407 (match_operand:SI 2 "general_operand" "ri,rm")))
7408 (clobber (reg:CC FLAGS_REG))]
7409 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7410 "sub{l}\t{%2, %0|%0, %2}"
7411 [(set_attr "type" "alu")
7412 (set_attr "mode" "SI")])
7414 (define_insn "*subsi_1_zext"
7415 [(set (match_operand:DI 0 "register_operand" "=r")
7417 (minus:SI (match_operand:SI 1 "register_operand" "0")
7418 (match_operand:SI 2 "general_operand" "g"))))
7419 (clobber (reg:CC FLAGS_REG))]
7420 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7421 "sub{l}\t{%2, %k0|%k0, %2}"
7422 [(set_attr "type" "alu")
7423 (set_attr "mode" "SI")])
7425 (define_insn "*subsi_2"
7426 [(set (reg FLAGS_REG)
7428 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7429 (match_operand:SI 2 "general_operand" "ri,rm"))
7431 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7432 (minus:SI (match_dup 1) (match_dup 2)))]
7433 "ix86_match_ccmode (insn, CCGOCmode)
7434 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7435 "sub{l}\t{%2, %0|%0, %2}"
7436 [(set_attr "type" "alu")
7437 (set_attr "mode" "SI")])
7439 (define_insn "*subsi_2_zext"
7440 [(set (reg FLAGS_REG)
7442 (minus:SI (match_operand:SI 1 "register_operand" "0")
7443 (match_operand:SI 2 "general_operand" "g"))
7445 (set (match_operand:DI 0 "register_operand" "=r")
7447 (minus:SI (match_dup 1)
7449 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7450 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7451 "sub{l}\t{%2, %k0|%k0, %2}"
7452 [(set_attr "type" "alu")
7453 (set_attr "mode" "SI")])
7455 (define_insn "*subsi_3"
7456 [(set (reg FLAGS_REG)
7457 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7458 (match_operand:SI 2 "general_operand" "ri,rm")))
7459 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7460 (minus:SI (match_dup 1) (match_dup 2)))]
7461 "ix86_match_ccmode (insn, CCmode)
7462 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7463 "sub{l}\t{%2, %0|%0, %2}"
7464 [(set_attr "type" "alu")
7465 (set_attr "mode" "SI")])
7467 (define_insn "*subsi_3_zext"
7468 [(set (reg FLAGS_REG)
7469 (compare (match_operand:SI 1 "register_operand" "0")
7470 (match_operand:SI 2 "general_operand" "g")))
7471 (set (match_operand:DI 0 "register_operand" "=r")
7473 (minus:SI (match_dup 1)
7475 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7476 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7477 "sub{l}\t{%2, %1|%1, %2}"
7478 [(set_attr "type" "alu")
7479 (set_attr "mode" "DI")])
7481 (define_expand "subhi3"
7482 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7483 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7484 (match_operand:HI 2 "general_operand" "")))
7485 (clobber (reg:CC FLAGS_REG))])]
7486 "TARGET_HIMODE_MATH"
7487 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7489 (define_insn "*subhi_1"
7490 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7491 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7492 (match_operand:HI 2 "general_operand" "rn,rm")))
7493 (clobber (reg:CC FLAGS_REG))]
7494 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7495 "sub{w}\t{%2, %0|%0, %2}"
7496 [(set_attr "type" "alu")
7497 (set_attr "mode" "HI")])
7499 (define_insn "*subhi_2"
7500 [(set (reg FLAGS_REG)
7502 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7503 (match_operand:HI 2 "general_operand" "rn,rm"))
7505 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7506 (minus:HI (match_dup 1) (match_dup 2)))]
7507 "ix86_match_ccmode (insn, CCGOCmode)
7508 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7509 "sub{w}\t{%2, %0|%0, %2}"
7510 [(set_attr "type" "alu")
7511 (set_attr "mode" "HI")])
7513 (define_insn "*subhi_3"
7514 [(set (reg FLAGS_REG)
7515 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7516 (match_operand:HI 2 "general_operand" "rn,rm")))
7517 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7518 (minus:HI (match_dup 1) (match_dup 2)))]
7519 "ix86_match_ccmode (insn, CCmode)
7520 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7521 "sub{w}\t{%2, %0|%0, %2}"
7522 [(set_attr "type" "alu")
7523 (set_attr "mode" "HI")])
7525 (define_expand "subqi3"
7526 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7527 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7528 (match_operand:QI 2 "general_operand" "")))
7529 (clobber (reg:CC FLAGS_REG))])]
7530 "TARGET_QIMODE_MATH"
7531 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7533 (define_insn "*subqi_1"
7534 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7535 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7536 (match_operand:QI 2 "general_operand" "qn,qm")))
7537 (clobber (reg:CC FLAGS_REG))]
7538 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7539 "sub{b}\t{%2, %0|%0, %2}"
7540 [(set_attr "type" "alu")
7541 (set_attr "mode" "QI")])
7543 (define_insn "*subqi_1_slp"
7544 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7545 (minus:QI (match_dup 0)
7546 (match_operand:QI 1 "general_operand" "qn,qm")))
7547 (clobber (reg:CC FLAGS_REG))]
7548 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7549 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7550 "sub{b}\t{%1, %0|%0, %1}"
7551 [(set_attr "type" "alu1")
7552 (set_attr "mode" "QI")])
7554 (define_insn "*subqi_2"
7555 [(set (reg FLAGS_REG)
7557 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7558 (match_operand:QI 2 "general_operand" "qn,qm"))
7560 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7561 (minus:QI (match_dup 1) (match_dup 2)))]
7562 "ix86_match_ccmode (insn, CCGOCmode)
7563 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7564 "sub{b}\t{%2, %0|%0, %2}"
7565 [(set_attr "type" "alu")
7566 (set_attr "mode" "QI")])
7568 (define_insn "*subqi_3"
7569 [(set (reg FLAGS_REG)
7570 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7571 (match_operand:QI 2 "general_operand" "qn,qm")))
7572 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7573 (minus:QI (match_dup 1) (match_dup 2)))]
7574 "ix86_match_ccmode (insn, CCmode)
7575 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7576 "sub{b}\t{%2, %0|%0, %2}"
7577 [(set_attr "type" "alu")
7578 (set_attr "mode" "QI")])
7580 ;; The patterns that match these are at the end of this file.
7582 (define_expand "subxf3"
7583 [(set (match_operand:XF 0 "register_operand" "")
7584 (minus:XF (match_operand:XF 1 "register_operand" "")
7585 (match_operand:XF 2 "register_operand" "")))]
7589 (define_expand "sub<mode>3"
7590 [(set (match_operand:MODEF 0 "register_operand" "")
7591 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7592 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7593 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7596 ;; Multiply instructions
7598 (define_expand "muldi3"
7599 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7600 (mult:DI (match_operand:DI 1 "register_operand" "")
7601 (match_operand:DI 2 "x86_64_general_operand" "")))
7602 (clobber (reg:CC FLAGS_REG))])]
7607 ;; IMUL reg64, reg64, imm8 Direct
7608 ;; IMUL reg64, mem64, imm8 VectorPath
7609 ;; IMUL reg64, reg64, imm32 Direct
7610 ;; IMUL reg64, mem64, imm32 VectorPath
7611 ;; IMUL reg64, reg64 Direct
7612 ;; IMUL reg64, mem64 Direct
7614 (define_insn "*muldi3_1_rex64"
7615 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7616 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7617 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7618 (clobber (reg:CC FLAGS_REG))]
7620 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7622 imul{q}\t{%2, %1, %0|%0, %1, %2}
7623 imul{q}\t{%2, %1, %0|%0, %1, %2}
7624 imul{q}\t{%2, %0|%0, %2}"
7625 [(set_attr "type" "imul")
7626 (set_attr "prefix_0f" "0,0,1")
7627 (set (attr "athlon_decode")
7628 (cond [(eq_attr "cpu" "athlon")
7629 (const_string "vector")
7630 (eq_attr "alternative" "1")
7631 (const_string "vector")
7632 (and (eq_attr "alternative" "2")
7633 (match_operand 1 "memory_operand" ""))
7634 (const_string "vector")]
7635 (const_string "direct")))
7636 (set (attr "amdfam10_decode")
7637 (cond [(and (eq_attr "alternative" "0,1")
7638 (match_operand 1 "memory_operand" ""))
7639 (const_string "vector")]
7640 (const_string "direct")))
7641 (set_attr "mode" "DI")])
7643 (define_expand "mulsi3"
7644 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7645 (mult:SI (match_operand:SI 1 "register_operand" "")
7646 (match_operand:SI 2 "general_operand" "")))
7647 (clobber (reg:CC FLAGS_REG))])]
7652 ;; IMUL reg32, reg32, imm8 Direct
7653 ;; IMUL reg32, mem32, imm8 VectorPath
7654 ;; IMUL reg32, reg32, imm32 Direct
7655 ;; IMUL reg32, mem32, imm32 VectorPath
7656 ;; IMUL reg32, reg32 Direct
7657 ;; IMUL reg32, mem32 Direct
7659 (define_insn "*mulsi3_1"
7660 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7661 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7662 (match_operand:SI 2 "general_operand" "K,i,mr")))
7663 (clobber (reg:CC FLAGS_REG))]
7664 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7666 imul{l}\t{%2, %1, %0|%0, %1, %2}
7667 imul{l}\t{%2, %1, %0|%0, %1, %2}
7668 imul{l}\t{%2, %0|%0, %2}"
7669 [(set_attr "type" "imul")
7670 (set_attr "prefix_0f" "0,0,1")
7671 (set (attr "athlon_decode")
7672 (cond [(eq_attr "cpu" "athlon")
7673 (const_string "vector")
7674 (eq_attr "alternative" "1")
7675 (const_string "vector")
7676 (and (eq_attr "alternative" "2")
7677 (match_operand 1 "memory_operand" ""))
7678 (const_string "vector")]
7679 (const_string "direct")))
7680 (set (attr "amdfam10_decode")
7681 (cond [(and (eq_attr "alternative" "0,1")
7682 (match_operand 1 "memory_operand" ""))
7683 (const_string "vector")]
7684 (const_string "direct")))
7685 (set_attr "mode" "SI")])
7687 (define_insn "*mulsi3_1_zext"
7688 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7690 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7691 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7692 (clobber (reg:CC FLAGS_REG))]
7694 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7696 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7697 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7698 imul{l}\t{%2, %k0|%k0, %2}"
7699 [(set_attr "type" "imul")
7700 (set_attr "prefix_0f" "0,0,1")
7701 (set (attr "athlon_decode")
7702 (cond [(eq_attr "cpu" "athlon")
7703 (const_string "vector")
7704 (eq_attr "alternative" "1")
7705 (const_string "vector")
7706 (and (eq_attr "alternative" "2")
7707 (match_operand 1 "memory_operand" ""))
7708 (const_string "vector")]
7709 (const_string "direct")))
7710 (set (attr "amdfam10_decode")
7711 (cond [(and (eq_attr "alternative" "0,1")
7712 (match_operand 1 "memory_operand" ""))
7713 (const_string "vector")]
7714 (const_string "direct")))
7715 (set_attr "mode" "SI")])
7717 (define_expand "mulhi3"
7718 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7719 (mult:HI (match_operand:HI 1 "register_operand" "")
7720 (match_operand:HI 2 "general_operand" "")))
7721 (clobber (reg:CC FLAGS_REG))])]
7722 "TARGET_HIMODE_MATH"
7726 ;; IMUL reg16, reg16, imm8 VectorPath
7727 ;; IMUL reg16, mem16, imm8 VectorPath
7728 ;; IMUL reg16, reg16, imm16 VectorPath
7729 ;; IMUL reg16, mem16, imm16 VectorPath
7730 ;; IMUL reg16, reg16 Direct
7731 ;; IMUL reg16, mem16 Direct
7732 (define_insn "*mulhi3_1"
7733 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7734 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7735 (match_operand:HI 2 "general_operand" "K,n,mr")))
7736 (clobber (reg:CC FLAGS_REG))]
7737 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7739 imul{w}\t{%2, %1, %0|%0, %1, %2}
7740 imul{w}\t{%2, %1, %0|%0, %1, %2}
7741 imul{w}\t{%2, %0|%0, %2}"
7742 [(set_attr "type" "imul")
7743 (set_attr "prefix_0f" "0,0,1")
7744 (set (attr "athlon_decode")
7745 (cond [(eq_attr "cpu" "athlon")
7746 (const_string "vector")
7747 (eq_attr "alternative" "1,2")
7748 (const_string "vector")]
7749 (const_string "direct")))
7750 (set (attr "amdfam10_decode")
7751 (cond [(eq_attr "alternative" "0,1")
7752 (const_string "vector")]
7753 (const_string "direct")))
7754 (set_attr "mode" "HI")])
7756 (define_expand "mulqi3"
7757 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7758 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7759 (match_operand:QI 2 "register_operand" "")))
7760 (clobber (reg:CC FLAGS_REG))])]
7761 "TARGET_QIMODE_MATH"
7768 (define_insn "*mulqi3_1"
7769 [(set (match_operand:QI 0 "register_operand" "=a")
7770 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7771 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7772 (clobber (reg:CC FLAGS_REG))]
7774 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7776 [(set_attr "type" "imul")
7777 (set_attr "length_immediate" "0")
7778 (set (attr "athlon_decode")
7779 (if_then_else (eq_attr "cpu" "athlon")
7780 (const_string "vector")
7781 (const_string "direct")))
7782 (set_attr "amdfam10_decode" "direct")
7783 (set_attr "mode" "QI")])
7785 (define_expand "umulqihi3"
7786 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7787 (mult:HI (zero_extend:HI
7788 (match_operand:QI 1 "nonimmediate_operand" ""))
7790 (match_operand:QI 2 "register_operand" ""))))
7791 (clobber (reg:CC FLAGS_REG))])]
7792 "TARGET_QIMODE_MATH"
7795 (define_insn "*umulqihi3_1"
7796 [(set (match_operand:HI 0 "register_operand" "=a")
7797 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7798 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7799 (clobber (reg:CC FLAGS_REG))]
7801 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7803 [(set_attr "type" "imul")
7804 (set_attr "length_immediate" "0")
7805 (set (attr "athlon_decode")
7806 (if_then_else (eq_attr "cpu" "athlon")
7807 (const_string "vector")
7808 (const_string "direct")))
7809 (set_attr "amdfam10_decode" "direct")
7810 (set_attr "mode" "QI")])
7812 (define_expand "mulqihi3"
7813 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7814 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7815 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7816 (clobber (reg:CC FLAGS_REG))])]
7817 "TARGET_QIMODE_MATH"
7820 (define_insn "*mulqihi3_insn"
7821 [(set (match_operand:HI 0 "register_operand" "=a")
7822 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7823 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7824 (clobber (reg:CC FLAGS_REG))]
7826 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7828 [(set_attr "type" "imul")
7829 (set_attr "length_immediate" "0")
7830 (set (attr "athlon_decode")
7831 (if_then_else (eq_attr "cpu" "athlon")
7832 (const_string "vector")
7833 (const_string "direct")))
7834 (set_attr "amdfam10_decode" "direct")
7835 (set_attr "mode" "QI")])
7837 (define_expand "umulditi3"
7838 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7839 (mult:TI (zero_extend:TI
7840 (match_operand:DI 1 "nonimmediate_operand" ""))
7842 (match_operand:DI 2 "register_operand" ""))))
7843 (clobber (reg:CC FLAGS_REG))])]
7847 (define_insn "*umulditi3_insn"
7848 [(set (match_operand:TI 0 "register_operand" "=A")
7849 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7850 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7851 (clobber (reg:CC FLAGS_REG))]
7853 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7855 [(set_attr "type" "imul")
7856 (set_attr "length_immediate" "0")
7857 (set (attr "athlon_decode")
7858 (if_then_else (eq_attr "cpu" "athlon")
7859 (const_string "vector")
7860 (const_string "double")))
7861 (set_attr "amdfam10_decode" "double")
7862 (set_attr "mode" "DI")])
7864 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7865 (define_expand "umulsidi3"
7866 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7867 (mult:DI (zero_extend:DI
7868 (match_operand:SI 1 "nonimmediate_operand" ""))
7870 (match_operand:SI 2 "register_operand" ""))))
7871 (clobber (reg:CC FLAGS_REG))])]
7875 (define_insn "*umulsidi3_insn"
7876 [(set (match_operand:DI 0 "register_operand" "=A")
7877 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7878 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7879 (clobber (reg:CC FLAGS_REG))]
7881 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7883 [(set_attr "type" "imul")
7884 (set_attr "length_immediate" "0")
7885 (set (attr "athlon_decode")
7886 (if_then_else (eq_attr "cpu" "athlon")
7887 (const_string "vector")
7888 (const_string "double")))
7889 (set_attr "amdfam10_decode" "double")
7890 (set_attr "mode" "SI")])
7892 (define_expand "mulditi3"
7893 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7894 (mult:TI (sign_extend:TI
7895 (match_operand:DI 1 "nonimmediate_operand" ""))
7897 (match_operand:DI 2 "register_operand" ""))))
7898 (clobber (reg:CC FLAGS_REG))])]
7902 (define_insn "*mulditi3_insn"
7903 [(set (match_operand:TI 0 "register_operand" "=A")
7904 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7905 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7906 (clobber (reg:CC FLAGS_REG))]
7908 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7910 [(set_attr "type" "imul")
7911 (set_attr "length_immediate" "0")
7912 (set (attr "athlon_decode")
7913 (if_then_else (eq_attr "cpu" "athlon")
7914 (const_string "vector")
7915 (const_string "double")))
7916 (set_attr "amdfam10_decode" "double")
7917 (set_attr "mode" "DI")])
7919 (define_expand "mulsidi3"
7920 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7921 (mult:DI (sign_extend:DI
7922 (match_operand:SI 1 "nonimmediate_operand" ""))
7924 (match_operand:SI 2 "register_operand" ""))))
7925 (clobber (reg:CC FLAGS_REG))])]
7929 (define_insn "*mulsidi3_insn"
7930 [(set (match_operand:DI 0 "register_operand" "=A")
7931 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7932 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7933 (clobber (reg:CC FLAGS_REG))]
7935 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7937 [(set_attr "type" "imul")
7938 (set_attr "length_immediate" "0")
7939 (set (attr "athlon_decode")
7940 (if_then_else (eq_attr "cpu" "athlon")
7941 (const_string "vector")
7942 (const_string "double")))
7943 (set_attr "amdfam10_decode" "double")
7944 (set_attr "mode" "SI")])
7946 (define_expand "umuldi3_highpart"
7947 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7950 (mult:TI (zero_extend:TI
7951 (match_operand:DI 1 "nonimmediate_operand" ""))
7953 (match_operand:DI 2 "register_operand" "")))
7955 (clobber (match_scratch:DI 3 ""))
7956 (clobber (reg:CC FLAGS_REG))])]
7960 (define_insn "*umuldi3_highpart_rex64"
7961 [(set (match_operand:DI 0 "register_operand" "=d")
7964 (mult:TI (zero_extend:TI
7965 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7967 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7969 (clobber (match_scratch:DI 3 "=1"))
7970 (clobber (reg:CC FLAGS_REG))]
7972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7974 [(set_attr "type" "imul")
7975 (set_attr "length_immediate" "0")
7976 (set (attr "athlon_decode")
7977 (if_then_else (eq_attr "cpu" "athlon")
7978 (const_string "vector")
7979 (const_string "double")))
7980 (set_attr "amdfam10_decode" "double")
7981 (set_attr "mode" "DI")])
7983 (define_expand "umulsi3_highpart"
7984 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7987 (mult:DI (zero_extend:DI
7988 (match_operand:SI 1 "nonimmediate_operand" ""))
7990 (match_operand:SI 2 "register_operand" "")))
7992 (clobber (match_scratch:SI 3 ""))
7993 (clobber (reg:CC FLAGS_REG))])]
7997 (define_insn "*umulsi3_highpart_insn"
7998 [(set (match_operand:SI 0 "register_operand" "=d")
8001 (mult:DI (zero_extend:DI
8002 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8004 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8006 (clobber (match_scratch:SI 3 "=1"))
8007 (clobber (reg:CC FLAGS_REG))]
8008 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8010 [(set_attr "type" "imul")
8011 (set_attr "length_immediate" "0")
8012 (set (attr "athlon_decode")
8013 (if_then_else (eq_attr "cpu" "athlon")
8014 (const_string "vector")
8015 (const_string "double")))
8016 (set_attr "amdfam10_decode" "double")
8017 (set_attr "mode" "SI")])
8019 (define_insn "*umulsi3_highpart_zext"
8020 [(set (match_operand:DI 0 "register_operand" "=d")
8021 (zero_extend:DI (truncate:SI
8023 (mult:DI (zero_extend:DI
8024 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8026 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8028 (clobber (match_scratch:SI 3 "=1"))
8029 (clobber (reg:CC FLAGS_REG))]
8031 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8033 [(set_attr "type" "imul")
8034 (set_attr "length_immediate" "0")
8035 (set (attr "athlon_decode")
8036 (if_then_else (eq_attr "cpu" "athlon")
8037 (const_string "vector")
8038 (const_string "double")))
8039 (set_attr "amdfam10_decode" "double")
8040 (set_attr "mode" "SI")])
8042 (define_expand "smuldi3_highpart"
8043 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8046 (mult:TI (sign_extend:TI
8047 (match_operand:DI 1 "nonimmediate_operand" ""))
8049 (match_operand:DI 2 "register_operand" "")))
8051 (clobber (match_scratch:DI 3 ""))
8052 (clobber (reg:CC FLAGS_REG))])]
8056 (define_insn "*smuldi3_highpart_rex64"
8057 [(set (match_operand:DI 0 "register_operand" "=d")
8060 (mult:TI (sign_extend:TI
8061 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8063 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8065 (clobber (match_scratch:DI 3 "=1"))
8066 (clobber (reg:CC FLAGS_REG))]
8068 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8070 [(set_attr "type" "imul")
8071 (set (attr "athlon_decode")
8072 (if_then_else (eq_attr "cpu" "athlon")
8073 (const_string "vector")
8074 (const_string "double")))
8075 (set_attr "amdfam10_decode" "double")
8076 (set_attr "mode" "DI")])
8078 (define_expand "smulsi3_highpart"
8079 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8082 (mult:DI (sign_extend:DI
8083 (match_operand:SI 1 "nonimmediate_operand" ""))
8085 (match_operand:SI 2 "register_operand" "")))
8087 (clobber (match_scratch:SI 3 ""))
8088 (clobber (reg:CC FLAGS_REG))])]
8092 (define_insn "*smulsi3_highpart_insn"
8093 [(set (match_operand:SI 0 "register_operand" "=d")
8096 (mult:DI (sign_extend:DI
8097 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8099 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8101 (clobber (match_scratch:SI 3 "=1"))
8102 (clobber (reg:CC FLAGS_REG))]
8103 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8105 [(set_attr "type" "imul")
8106 (set (attr "athlon_decode")
8107 (if_then_else (eq_attr "cpu" "athlon")
8108 (const_string "vector")
8109 (const_string "double")))
8110 (set_attr "amdfam10_decode" "double")
8111 (set_attr "mode" "SI")])
8113 (define_insn "*smulsi3_highpart_zext"
8114 [(set (match_operand:DI 0 "register_operand" "=d")
8115 (zero_extend:DI (truncate:SI
8117 (mult:DI (sign_extend:DI
8118 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8120 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8122 (clobber (match_scratch:SI 3 "=1"))
8123 (clobber (reg:CC FLAGS_REG))]
8125 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8127 [(set_attr "type" "imul")
8128 (set (attr "athlon_decode")
8129 (if_then_else (eq_attr "cpu" "athlon")
8130 (const_string "vector")
8131 (const_string "double")))
8132 (set_attr "amdfam10_decode" "double")
8133 (set_attr "mode" "SI")])
8135 ;; The patterns that match these are at the end of this file.
8137 (define_expand "mulxf3"
8138 [(set (match_operand:XF 0 "register_operand" "")
8139 (mult:XF (match_operand:XF 1 "register_operand" "")
8140 (match_operand:XF 2 "register_operand" "")))]
8144 (define_expand "mul<mode>3"
8145 [(set (match_operand:MODEF 0 "register_operand" "")
8146 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8147 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8148 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8151 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8154 ;; Divide instructions
8156 (define_insn "divqi3"
8157 [(set (match_operand:QI 0 "register_operand" "=a")
8158 (div:QI (match_operand:HI 1 "register_operand" "0")
8159 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8160 (clobber (reg:CC FLAGS_REG))]
8161 "TARGET_QIMODE_MATH"
8163 [(set_attr "type" "idiv")
8164 (set_attr "mode" "QI")])
8166 (define_insn "udivqi3"
8167 [(set (match_operand:QI 0 "register_operand" "=a")
8168 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8169 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8170 (clobber (reg:CC FLAGS_REG))]
8171 "TARGET_QIMODE_MATH"
8173 [(set_attr "type" "idiv")
8174 (set_attr "mode" "QI")])
8176 ;; The patterns that match these are at the end of this file.
8178 (define_expand "divxf3"
8179 [(set (match_operand:XF 0 "register_operand" "")
8180 (div:XF (match_operand:XF 1 "register_operand" "")
8181 (match_operand:XF 2 "register_operand" "")))]
8185 (define_expand "divdf3"
8186 [(set (match_operand:DF 0 "register_operand" "")
8187 (div:DF (match_operand:DF 1 "register_operand" "")
8188 (match_operand:DF 2 "nonimmediate_operand" "")))]
8189 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8192 (define_expand "divsf3"
8193 [(set (match_operand:SF 0 "register_operand" "")
8194 (div:SF (match_operand:SF 1 "register_operand" "")
8195 (match_operand:SF 2 "nonimmediate_operand" "")))]
8196 "TARGET_80387 || TARGET_SSE_MATH"
8198 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8199 && flag_finite_math_only && !flag_trapping_math
8200 && flag_unsafe_math_optimizations)
8202 ix86_emit_swdivsf (operands[0], operands[1],
8203 operands[2], SFmode);
8208 ;; Remainder instructions.
8210 (define_expand "divmoddi4"
8211 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8212 (div:DI (match_operand:DI 1 "register_operand" "")
8213 (match_operand:DI 2 "nonimmediate_operand" "")))
8214 (set (match_operand:DI 3 "register_operand" "")
8215 (mod:DI (match_dup 1) (match_dup 2)))
8216 (clobber (reg:CC FLAGS_REG))])]
8220 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8221 ;; Penalize eax case slightly because it results in worse scheduling
8223 (define_insn "*divmoddi4_nocltd_rex64"
8224 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8225 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8226 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8227 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8228 (mod:DI (match_dup 2) (match_dup 3)))
8229 (clobber (reg:CC FLAGS_REG))]
8230 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8232 [(set_attr "type" "multi")])
8234 (define_insn "*divmoddi4_cltd_rex64"
8235 [(set (match_operand:DI 0 "register_operand" "=a")
8236 (div:DI (match_operand:DI 2 "register_operand" "a")
8237 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8238 (set (match_operand:DI 1 "register_operand" "=&d")
8239 (mod:DI (match_dup 2) (match_dup 3)))
8240 (clobber (reg:CC FLAGS_REG))]
8241 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8243 [(set_attr "type" "multi")])
8245 (define_insn "*divmoddi_noext_rex64"
8246 [(set (match_operand:DI 0 "register_operand" "=a")
8247 (div:DI (match_operand:DI 1 "register_operand" "0")
8248 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8249 (set (match_operand:DI 3 "register_operand" "=d")
8250 (mod:DI (match_dup 1) (match_dup 2)))
8251 (use (match_operand:DI 4 "register_operand" "3"))
8252 (clobber (reg:CC FLAGS_REG))]
8255 [(set_attr "type" "idiv")
8256 (set_attr "mode" "DI")])
8259 [(set (match_operand:DI 0 "register_operand" "")
8260 (div:DI (match_operand:DI 1 "register_operand" "")
8261 (match_operand:DI 2 "nonimmediate_operand" "")))
8262 (set (match_operand:DI 3 "register_operand" "")
8263 (mod:DI (match_dup 1) (match_dup 2)))
8264 (clobber (reg:CC FLAGS_REG))]
8265 "TARGET_64BIT && reload_completed"
8266 [(parallel [(set (match_dup 3)
8267 (ashiftrt:DI (match_dup 4) (const_int 63)))
8268 (clobber (reg:CC FLAGS_REG))])
8269 (parallel [(set (match_dup 0)
8270 (div:DI (reg:DI 0) (match_dup 2)))
8272 (mod:DI (reg:DI 0) (match_dup 2)))
8274 (clobber (reg:CC FLAGS_REG))])]
8276 /* Avoid use of cltd in favor of a mov+shift. */
8277 if (!TARGET_USE_CLTD && !optimize_size)
8279 if (true_regnum (operands[1]))
8280 emit_move_insn (operands[0], operands[1]);
8282 emit_move_insn (operands[3], operands[1]);
8283 operands[4] = operands[3];
8287 gcc_assert (!true_regnum (operands[1]));
8288 operands[4] = operands[1];
8293 (define_expand "divmodsi4"
8294 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8295 (div:SI (match_operand:SI 1 "register_operand" "")
8296 (match_operand:SI 2 "nonimmediate_operand" "")))
8297 (set (match_operand:SI 3 "register_operand" "")
8298 (mod:SI (match_dup 1) (match_dup 2)))
8299 (clobber (reg:CC FLAGS_REG))])]
8303 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8304 ;; Penalize eax case slightly because it results in worse scheduling
8306 (define_insn "*divmodsi4_nocltd"
8307 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8308 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8309 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8310 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8311 (mod:SI (match_dup 2) (match_dup 3)))
8312 (clobber (reg:CC FLAGS_REG))]
8313 "!optimize_size && !TARGET_USE_CLTD"
8315 [(set_attr "type" "multi")])
8317 (define_insn "*divmodsi4_cltd"
8318 [(set (match_operand:SI 0 "register_operand" "=a")
8319 (div:SI (match_operand:SI 2 "register_operand" "a")
8320 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8321 (set (match_operand:SI 1 "register_operand" "=&d")
8322 (mod:SI (match_dup 2) (match_dup 3)))
8323 (clobber (reg:CC FLAGS_REG))]
8324 "optimize_size || TARGET_USE_CLTD"
8326 [(set_attr "type" "multi")])
8328 (define_insn "*divmodsi_noext"
8329 [(set (match_operand:SI 0 "register_operand" "=a")
8330 (div:SI (match_operand:SI 1 "register_operand" "0")
8331 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8332 (set (match_operand:SI 3 "register_operand" "=d")
8333 (mod:SI (match_dup 1) (match_dup 2)))
8334 (use (match_operand:SI 4 "register_operand" "3"))
8335 (clobber (reg:CC FLAGS_REG))]
8338 [(set_attr "type" "idiv")
8339 (set_attr "mode" "SI")])
8342 [(set (match_operand:SI 0 "register_operand" "")
8343 (div:SI (match_operand:SI 1 "register_operand" "")
8344 (match_operand:SI 2 "nonimmediate_operand" "")))
8345 (set (match_operand:SI 3 "register_operand" "")
8346 (mod:SI (match_dup 1) (match_dup 2)))
8347 (clobber (reg:CC FLAGS_REG))]
8349 [(parallel [(set (match_dup 3)
8350 (ashiftrt:SI (match_dup 4) (const_int 31)))
8351 (clobber (reg:CC FLAGS_REG))])
8352 (parallel [(set (match_dup 0)
8353 (div:SI (reg:SI 0) (match_dup 2)))
8355 (mod:SI (reg:SI 0) (match_dup 2)))
8357 (clobber (reg:CC FLAGS_REG))])]
8359 /* Avoid use of cltd in favor of a mov+shift. */
8360 if (!TARGET_USE_CLTD && !optimize_size)
8362 if (true_regnum (operands[1]))
8363 emit_move_insn (operands[0], operands[1]);
8365 emit_move_insn (operands[3], operands[1]);
8366 operands[4] = operands[3];
8370 gcc_assert (!true_regnum (operands[1]));
8371 operands[4] = operands[1];
8375 (define_insn "divmodhi4"
8376 [(set (match_operand:HI 0 "register_operand" "=a")
8377 (div:HI (match_operand:HI 1 "register_operand" "0")
8378 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8379 (set (match_operand:HI 3 "register_operand" "=&d")
8380 (mod:HI (match_dup 1) (match_dup 2)))
8381 (clobber (reg:CC FLAGS_REG))]
8382 "TARGET_HIMODE_MATH"
8384 [(set_attr "type" "multi")
8385 (set_attr "length_immediate" "0")
8386 (set_attr "mode" "SI")])
8388 (define_insn "udivmoddi4"
8389 [(set (match_operand:DI 0 "register_operand" "=a")
8390 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8391 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8392 (set (match_operand:DI 3 "register_operand" "=&d")
8393 (umod:DI (match_dup 1) (match_dup 2)))
8394 (clobber (reg:CC FLAGS_REG))]
8396 "xor{q}\t%3, %3\;div{q}\t%2"
8397 [(set_attr "type" "multi")
8398 (set_attr "length_immediate" "0")
8399 (set_attr "mode" "DI")])
8401 (define_insn "*udivmoddi4_noext"
8402 [(set (match_operand:DI 0 "register_operand" "=a")
8403 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8404 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8405 (set (match_operand:DI 3 "register_operand" "=d")
8406 (umod:DI (match_dup 1) (match_dup 2)))
8408 (clobber (reg:CC FLAGS_REG))]
8411 [(set_attr "type" "idiv")
8412 (set_attr "mode" "DI")])
8415 [(set (match_operand:DI 0 "register_operand" "")
8416 (udiv:DI (match_operand:DI 1 "register_operand" "")
8417 (match_operand:DI 2 "nonimmediate_operand" "")))
8418 (set (match_operand:DI 3 "register_operand" "")
8419 (umod:DI (match_dup 1) (match_dup 2)))
8420 (clobber (reg:CC FLAGS_REG))]
8421 "TARGET_64BIT && reload_completed"
8422 [(set (match_dup 3) (const_int 0))
8423 (parallel [(set (match_dup 0)
8424 (udiv:DI (match_dup 1) (match_dup 2)))
8426 (umod:DI (match_dup 1) (match_dup 2)))
8428 (clobber (reg:CC FLAGS_REG))])]
8431 (define_insn "udivmodsi4"
8432 [(set (match_operand:SI 0 "register_operand" "=a")
8433 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8434 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8435 (set (match_operand:SI 3 "register_operand" "=&d")
8436 (umod:SI (match_dup 1) (match_dup 2)))
8437 (clobber (reg:CC FLAGS_REG))]
8439 "xor{l}\t%3, %3\;div{l}\t%2"
8440 [(set_attr "type" "multi")
8441 (set_attr "length_immediate" "0")
8442 (set_attr "mode" "SI")])
8444 (define_insn "*udivmodsi4_noext"
8445 [(set (match_operand:SI 0 "register_operand" "=a")
8446 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8447 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8448 (set (match_operand:SI 3 "register_operand" "=d")
8449 (umod:SI (match_dup 1) (match_dup 2)))
8451 (clobber (reg:CC FLAGS_REG))]
8454 [(set_attr "type" "idiv")
8455 (set_attr "mode" "SI")])
8458 [(set (match_operand:SI 0 "register_operand" "")
8459 (udiv:SI (match_operand:SI 1 "register_operand" "")
8460 (match_operand:SI 2 "nonimmediate_operand" "")))
8461 (set (match_operand:SI 3 "register_operand" "")
8462 (umod:SI (match_dup 1) (match_dup 2)))
8463 (clobber (reg:CC FLAGS_REG))]
8465 [(set (match_dup 3) (const_int 0))
8466 (parallel [(set (match_dup 0)
8467 (udiv:SI (match_dup 1) (match_dup 2)))
8469 (umod:SI (match_dup 1) (match_dup 2)))
8471 (clobber (reg:CC FLAGS_REG))])]
8474 (define_expand "udivmodhi4"
8475 [(set (match_dup 4) (const_int 0))
8476 (parallel [(set (match_operand:HI 0 "register_operand" "")
8477 (udiv:HI (match_operand:HI 1 "register_operand" "")
8478 (match_operand:HI 2 "nonimmediate_operand" "")))
8479 (set (match_operand:HI 3 "register_operand" "")
8480 (umod:HI (match_dup 1) (match_dup 2)))
8482 (clobber (reg:CC FLAGS_REG))])]
8483 "TARGET_HIMODE_MATH"
8484 "operands[4] = gen_reg_rtx (HImode);")
8486 (define_insn "*udivmodhi_noext"
8487 [(set (match_operand:HI 0 "register_operand" "=a")
8488 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8489 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8490 (set (match_operand:HI 3 "register_operand" "=d")
8491 (umod:HI (match_dup 1) (match_dup 2)))
8492 (use (match_operand:HI 4 "register_operand" "3"))
8493 (clobber (reg:CC FLAGS_REG))]
8496 [(set_attr "type" "idiv")
8497 (set_attr "mode" "HI")])
8499 ;; We cannot use div/idiv for double division, because it causes
8500 ;; "division by zero" on the overflow and that's not what we expect
8501 ;; from truncate. Because true (non truncating) double division is
8502 ;; never generated, we can't create this insn anyway.
8505 ; [(set (match_operand:SI 0 "register_operand" "=a")
8507 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8509 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8510 ; (set (match_operand:SI 3 "register_operand" "=d")
8512 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8513 ; (clobber (reg:CC FLAGS_REG))]
8515 ; "div{l}\t{%2, %0|%0, %2}"
8516 ; [(set_attr "type" "idiv")])
8518 ;;- Logical AND instructions
8520 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8521 ;; Note that this excludes ah.
8523 (define_insn "*testdi_1_rex64"
8524 [(set (reg FLAGS_REG)
8526 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8527 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8529 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8530 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8532 test{l}\t{%k1, %k0|%k0, %k1}
8533 test{l}\t{%k1, %k0|%k0, %k1}
8534 test{q}\t{%1, %0|%0, %1}
8535 test{q}\t{%1, %0|%0, %1}
8536 test{q}\t{%1, %0|%0, %1}"
8537 [(set_attr "type" "test")
8538 (set_attr "modrm" "0,1,0,1,1")
8539 (set_attr "mode" "SI,SI,DI,DI,DI")
8540 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8542 (define_insn "testsi_1"
8543 [(set (reg FLAGS_REG)
8545 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8546 (match_operand:SI 1 "general_operand" "i,i,ri"))
8548 "ix86_match_ccmode (insn, CCNOmode)
8549 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8550 "test{l}\t{%1, %0|%0, %1}"
8551 [(set_attr "type" "test")
8552 (set_attr "modrm" "0,1,1")
8553 (set_attr "mode" "SI")
8554 (set_attr "pent_pair" "uv,np,uv")])
8556 (define_expand "testsi_ccno_1"
8557 [(set (reg:CCNO FLAGS_REG)
8559 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8560 (match_operand:SI 1 "nonmemory_operand" ""))
8565 (define_insn "*testhi_1"
8566 [(set (reg FLAGS_REG)
8567 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8568 (match_operand:HI 1 "general_operand" "n,n,rn"))
8570 "ix86_match_ccmode (insn, CCNOmode)
8571 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8572 "test{w}\t{%1, %0|%0, %1}"
8573 [(set_attr "type" "test")
8574 (set_attr "modrm" "0,1,1")
8575 (set_attr "mode" "HI")
8576 (set_attr "pent_pair" "uv,np,uv")])
8578 (define_expand "testqi_ccz_1"
8579 [(set (reg:CCZ FLAGS_REG)
8580 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8581 (match_operand:QI 1 "nonmemory_operand" ""))
8586 (define_insn "*testqi_1_maybe_si"
8587 [(set (reg FLAGS_REG)
8590 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8591 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8593 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8594 && ix86_match_ccmode (insn,
8595 CONST_INT_P (operands[1])
8596 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8598 if (which_alternative == 3)
8600 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8601 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8602 return "test{l}\t{%1, %k0|%k0, %1}";
8604 return "test{b}\t{%1, %0|%0, %1}";
8606 [(set_attr "type" "test")
8607 (set_attr "modrm" "0,1,1,1")
8608 (set_attr "mode" "QI,QI,QI,SI")
8609 (set_attr "pent_pair" "uv,np,uv,np")])
8611 (define_insn "*testqi_1"
8612 [(set (reg FLAGS_REG)
8615 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8616 (match_operand:QI 1 "general_operand" "n,n,qn"))
8618 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8619 && ix86_match_ccmode (insn, CCNOmode)"
8620 "test{b}\t{%1, %0|%0, %1}"
8621 [(set_attr "type" "test")
8622 (set_attr "modrm" "0,1,1")
8623 (set_attr "mode" "QI")
8624 (set_attr "pent_pair" "uv,np,uv")])
8626 (define_expand "testqi_ext_ccno_0"
8627 [(set (reg:CCNO FLAGS_REG)
8631 (match_operand 0 "ext_register_operand" "")
8634 (match_operand 1 "const_int_operand" ""))
8639 (define_insn "*testqi_ext_0"
8640 [(set (reg FLAGS_REG)
8644 (match_operand 0 "ext_register_operand" "Q")
8647 (match_operand 1 "const_int_operand" "n"))
8649 "ix86_match_ccmode (insn, CCNOmode)"
8650 "test{b}\t{%1, %h0|%h0, %1}"
8651 [(set_attr "type" "test")
8652 (set_attr "mode" "QI")
8653 (set_attr "length_immediate" "1")
8654 (set_attr "pent_pair" "np")])
8656 (define_insn "*testqi_ext_1"
8657 [(set (reg FLAGS_REG)
8661 (match_operand 0 "ext_register_operand" "Q")
8665 (match_operand:QI 1 "general_operand" "Qm")))
8667 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8668 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8669 "test{b}\t{%1, %h0|%h0, %1}"
8670 [(set_attr "type" "test")
8671 (set_attr "mode" "QI")])
8673 (define_insn "*testqi_ext_1_rex64"
8674 [(set (reg FLAGS_REG)
8678 (match_operand 0 "ext_register_operand" "Q")
8682 (match_operand:QI 1 "register_operand" "Q")))
8684 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8685 "test{b}\t{%1, %h0|%h0, %1}"
8686 [(set_attr "type" "test")
8687 (set_attr "mode" "QI")])
8689 (define_insn "*testqi_ext_2"
8690 [(set (reg FLAGS_REG)
8694 (match_operand 0 "ext_register_operand" "Q")
8698 (match_operand 1 "ext_register_operand" "Q")
8702 "ix86_match_ccmode (insn, CCNOmode)"
8703 "test{b}\t{%h1, %h0|%h0, %h1}"
8704 [(set_attr "type" "test")
8705 (set_attr "mode" "QI")])
8707 ;; Combine likes to form bit extractions for some tests. Humor it.
8708 (define_insn "*testqi_ext_3"
8709 [(set (reg FLAGS_REG)
8710 (compare (zero_extract:SI
8711 (match_operand 0 "nonimmediate_operand" "rm")
8712 (match_operand:SI 1 "const_int_operand" "")
8713 (match_operand:SI 2 "const_int_operand" ""))
8715 "ix86_match_ccmode (insn, CCNOmode)
8716 && INTVAL (operands[1]) > 0
8717 && INTVAL (operands[2]) >= 0
8718 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8719 && (GET_MODE (operands[0]) == SImode
8720 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8721 || GET_MODE (operands[0]) == HImode
8722 || GET_MODE (operands[0]) == QImode)"
8725 (define_insn "*testqi_ext_3_rex64"
8726 [(set (reg FLAGS_REG)
8727 (compare (zero_extract:DI
8728 (match_operand 0 "nonimmediate_operand" "rm")
8729 (match_operand:DI 1 "const_int_operand" "")
8730 (match_operand:DI 2 "const_int_operand" ""))
8733 && ix86_match_ccmode (insn, CCNOmode)
8734 && INTVAL (operands[1]) > 0
8735 && INTVAL (operands[2]) >= 0
8736 /* Ensure that resulting mask is zero or sign extended operand. */
8737 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8738 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8739 && INTVAL (operands[1]) > 32))
8740 && (GET_MODE (operands[0]) == SImode
8741 || GET_MODE (operands[0]) == DImode
8742 || GET_MODE (operands[0]) == HImode
8743 || GET_MODE (operands[0]) == QImode)"
8747 [(set (match_operand 0 "flags_reg_operand" "")
8748 (match_operator 1 "compare_operator"
8750 (match_operand 2 "nonimmediate_operand" "")
8751 (match_operand 3 "const_int_operand" "")
8752 (match_operand 4 "const_int_operand" ""))
8754 "ix86_match_ccmode (insn, CCNOmode)"
8755 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8757 rtx val = operands[2];
8758 HOST_WIDE_INT len = INTVAL (operands[3]);
8759 HOST_WIDE_INT pos = INTVAL (operands[4]);
8761 enum machine_mode mode, submode;
8763 mode = GET_MODE (val);
8766 /* ??? Combine likes to put non-volatile mem extractions in QImode
8767 no matter the size of the test. So find a mode that works. */
8768 if (! MEM_VOLATILE_P (val))
8770 mode = smallest_mode_for_size (pos + len, MODE_INT);
8771 val = adjust_address (val, mode, 0);
8774 else if (GET_CODE (val) == SUBREG
8775 && (submode = GET_MODE (SUBREG_REG (val)),
8776 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8777 && pos + len <= GET_MODE_BITSIZE (submode))
8779 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8781 val = SUBREG_REG (val);
8783 else if (mode == HImode && pos + len <= 8)
8785 /* Small HImode tests can be converted to QImode. */
8787 val = gen_lowpart (QImode, val);
8790 if (len == HOST_BITS_PER_WIDE_INT)
8793 mask = ((HOST_WIDE_INT)1 << len) - 1;
8796 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8799 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8800 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8801 ;; this is relatively important trick.
8802 ;; Do the conversion only post-reload to avoid limiting of the register class
8805 [(set (match_operand 0 "flags_reg_operand" "")
8806 (match_operator 1 "compare_operator"
8807 [(and (match_operand 2 "register_operand" "")
8808 (match_operand 3 "const_int_operand" ""))
8811 && QI_REG_P (operands[2])
8812 && GET_MODE (operands[2]) != QImode
8813 && ((ix86_match_ccmode (insn, CCZmode)
8814 && !(INTVAL (operands[3]) & ~(255 << 8)))
8815 || (ix86_match_ccmode (insn, CCNOmode)
8816 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8819 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8822 "operands[2] = gen_lowpart (SImode, operands[2]);
8823 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8826 [(set (match_operand 0 "flags_reg_operand" "")
8827 (match_operator 1 "compare_operator"
8828 [(and (match_operand 2 "nonimmediate_operand" "")
8829 (match_operand 3 "const_int_operand" ""))
8832 && GET_MODE (operands[2]) != QImode
8833 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8834 && ((ix86_match_ccmode (insn, CCZmode)
8835 && !(INTVAL (operands[3]) & ~255))
8836 || (ix86_match_ccmode (insn, CCNOmode)
8837 && !(INTVAL (operands[3]) & ~127)))"
8839 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8841 "operands[2] = gen_lowpart (QImode, operands[2]);
8842 operands[3] = gen_lowpart (QImode, operands[3]);")
8845 ;; %%% This used to optimize known byte-wide and operations to memory,
8846 ;; and sometimes to QImode registers. If this is considered useful,
8847 ;; it should be done with splitters.
8849 (define_expand "anddi3"
8850 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8851 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8852 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8853 (clobber (reg:CC FLAGS_REG))]
8855 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8857 (define_insn "*anddi_1_rex64"
8858 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8859 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8860 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8861 (clobber (reg:CC FLAGS_REG))]
8862 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8864 switch (get_attr_type (insn))
8868 enum machine_mode mode;
8870 gcc_assert (CONST_INT_P (operands[2]));
8871 if (INTVAL (operands[2]) == 0xff)
8875 gcc_assert (INTVAL (operands[2]) == 0xffff);
8879 operands[1] = gen_lowpart (mode, operands[1]);
8881 return "movz{bq|x}\t{%1,%0|%0, %1}";
8883 return "movz{wq|x}\t{%1,%0|%0, %1}";
8887 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8888 if (get_attr_mode (insn) == MODE_SI)
8889 return "and{l}\t{%k2, %k0|%k0, %k2}";
8891 return "and{q}\t{%2, %0|%0, %2}";
8894 [(set_attr "type" "alu,alu,alu,imovx")
8895 (set_attr "length_immediate" "*,*,*,0")
8896 (set_attr "mode" "SI,DI,DI,DI")])
8898 (define_insn "*anddi_2"
8899 [(set (reg FLAGS_REG)
8900 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8901 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8903 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8904 (and:DI (match_dup 1) (match_dup 2)))]
8905 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8906 && ix86_binary_operator_ok (AND, DImode, operands)"
8908 and{l}\t{%k2, %k0|%k0, %k2}
8909 and{q}\t{%2, %0|%0, %2}
8910 and{q}\t{%2, %0|%0, %2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "mode" "SI,DI,DI")])
8914 (define_expand "andsi3"
8915 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8916 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8917 (match_operand:SI 2 "general_operand" "")))
8918 (clobber (reg:CC FLAGS_REG))]
8920 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8922 (define_insn "*andsi_1"
8923 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8924 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8925 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8926 (clobber (reg:CC FLAGS_REG))]
8927 "ix86_binary_operator_ok (AND, SImode, operands)"
8929 switch (get_attr_type (insn))
8933 enum machine_mode mode;
8935 gcc_assert (CONST_INT_P (operands[2]));
8936 if (INTVAL (operands[2]) == 0xff)
8940 gcc_assert (INTVAL (operands[2]) == 0xffff);
8944 operands[1] = gen_lowpart (mode, operands[1]);
8946 return "movz{bl|x}\t{%1,%0|%0, %1}";
8948 return "movz{wl|x}\t{%1,%0|%0, %1}";
8952 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8953 return "and{l}\t{%2, %0|%0, %2}";
8956 [(set_attr "type" "alu,alu,imovx")
8957 (set_attr "length_immediate" "*,*,0")
8958 (set_attr "mode" "SI")])
8961 [(set (match_operand 0 "register_operand" "")
8963 (const_int -65536)))
8964 (clobber (reg:CC FLAGS_REG))]
8965 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8966 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8967 "operands[1] = gen_lowpart (HImode, operands[0]);")
8970 [(set (match_operand 0 "ext_register_operand" "")
8973 (clobber (reg:CC FLAGS_REG))]
8974 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8975 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8976 "operands[1] = gen_lowpart (QImode, operands[0]);")
8979 [(set (match_operand 0 "ext_register_operand" "")
8981 (const_int -65281)))
8982 (clobber (reg:CC FLAGS_REG))]
8983 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8984 [(parallel [(set (zero_extract:SI (match_dup 0)
8988 (zero_extract:SI (match_dup 0)
8991 (zero_extract:SI (match_dup 0)
8994 (clobber (reg:CC FLAGS_REG))])]
8995 "operands[0] = gen_lowpart (SImode, operands[0]);")
8997 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8998 (define_insn "*andsi_1_zext"
8999 [(set (match_operand:DI 0 "register_operand" "=r")
9001 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9002 (match_operand:SI 2 "general_operand" "g"))))
9003 (clobber (reg:CC FLAGS_REG))]
9004 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9005 "and{l}\t{%2, %k0|%k0, %2}"
9006 [(set_attr "type" "alu")
9007 (set_attr "mode" "SI")])
9009 (define_insn "*andsi_2"
9010 [(set (reg FLAGS_REG)
9011 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9012 (match_operand:SI 2 "general_operand" "g,ri"))
9014 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9015 (and:SI (match_dup 1) (match_dup 2)))]
9016 "ix86_match_ccmode (insn, CCNOmode)
9017 && ix86_binary_operator_ok (AND, SImode, operands)"
9018 "and{l}\t{%2, %0|%0, %2}"
9019 [(set_attr "type" "alu")
9020 (set_attr "mode" "SI")])
9022 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9023 (define_insn "*andsi_2_zext"
9024 [(set (reg FLAGS_REG)
9025 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9026 (match_operand:SI 2 "general_operand" "g"))
9028 (set (match_operand:DI 0 "register_operand" "=r")
9029 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9030 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9031 && ix86_binary_operator_ok (AND, SImode, operands)"
9032 "and{l}\t{%2, %k0|%k0, %2}"
9033 [(set_attr "type" "alu")
9034 (set_attr "mode" "SI")])
9036 (define_expand "andhi3"
9037 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9038 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9039 (match_operand:HI 2 "general_operand" "")))
9040 (clobber (reg:CC FLAGS_REG))]
9041 "TARGET_HIMODE_MATH"
9042 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9044 (define_insn "*andhi_1"
9045 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9046 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9047 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9048 (clobber (reg:CC FLAGS_REG))]
9049 "ix86_binary_operator_ok (AND, HImode, operands)"
9051 switch (get_attr_type (insn))
9054 gcc_assert (CONST_INT_P (operands[2]));
9055 gcc_assert (INTVAL (operands[2]) == 0xff);
9056 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9059 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9061 return "and{w}\t{%2, %0|%0, %2}";
9064 [(set_attr "type" "alu,alu,imovx")
9065 (set_attr "length_immediate" "*,*,0")
9066 (set_attr "mode" "HI,HI,SI")])
9068 (define_insn "*andhi_2"
9069 [(set (reg FLAGS_REG)
9070 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9071 (match_operand:HI 2 "general_operand" "rmn,rn"))
9073 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9074 (and:HI (match_dup 1) (match_dup 2)))]
9075 "ix86_match_ccmode (insn, CCNOmode)
9076 && ix86_binary_operator_ok (AND, HImode, operands)"
9077 "and{w}\t{%2, %0|%0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "mode" "HI")])
9081 (define_expand "andqi3"
9082 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9083 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9084 (match_operand:QI 2 "general_operand" "")))
9085 (clobber (reg:CC FLAGS_REG))]
9086 "TARGET_QIMODE_MATH"
9087 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9089 ;; %%% Potential partial reg stall on alternative 2. What to do?
9090 (define_insn "*andqi_1"
9091 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9092 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9093 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9094 (clobber (reg:CC FLAGS_REG))]
9095 "ix86_binary_operator_ok (AND, QImode, operands)"
9097 and{b}\t{%2, %0|%0, %2}
9098 and{b}\t{%2, %0|%0, %2}
9099 and{l}\t{%k2, %k0|%k0, %k2}"
9100 [(set_attr "type" "alu")
9101 (set_attr "mode" "QI,QI,SI")])
9103 (define_insn "*andqi_1_slp"
9104 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9105 (and:QI (match_dup 0)
9106 (match_operand:QI 1 "general_operand" "qn,qmn")))
9107 (clobber (reg:CC FLAGS_REG))]
9108 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9109 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9110 "and{b}\t{%1, %0|%0, %1}"
9111 [(set_attr "type" "alu1")
9112 (set_attr "mode" "QI")])
9114 (define_insn "*andqi_2_maybe_si"
9115 [(set (reg FLAGS_REG)
9117 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9118 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9120 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9121 (and:QI (match_dup 1) (match_dup 2)))]
9122 "ix86_binary_operator_ok (AND, QImode, operands)
9123 && ix86_match_ccmode (insn,
9124 CONST_INT_P (operands[2])
9125 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9127 if (which_alternative == 2)
9129 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9130 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9131 return "and{l}\t{%2, %k0|%k0, %2}";
9133 return "and{b}\t{%2, %0|%0, %2}";
9135 [(set_attr "type" "alu")
9136 (set_attr "mode" "QI,QI,SI")])
9138 (define_insn "*andqi_2"
9139 [(set (reg FLAGS_REG)
9141 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9142 (match_operand:QI 2 "general_operand" "qmn,qn"))
9144 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9145 (and:QI (match_dup 1) (match_dup 2)))]
9146 "ix86_match_ccmode (insn, CCNOmode)
9147 && ix86_binary_operator_ok (AND, QImode, operands)"
9148 "and{b}\t{%2, %0|%0, %2}"
9149 [(set_attr "type" "alu")
9150 (set_attr "mode" "QI")])
9152 (define_insn "*andqi_2_slp"
9153 [(set (reg FLAGS_REG)
9155 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9156 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9158 (set (strict_low_part (match_dup 0))
9159 (and:QI (match_dup 0) (match_dup 1)))]
9160 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9161 && ix86_match_ccmode (insn, CCNOmode)
9162 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9163 "and{b}\t{%1, %0|%0, %1}"
9164 [(set_attr "type" "alu1")
9165 (set_attr "mode" "QI")])
9167 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9168 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9169 ;; for a QImode operand, which of course failed.
9171 (define_insn "andqi_ext_0"
9172 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9177 (match_operand 1 "ext_register_operand" "0")
9180 (match_operand 2 "const_int_operand" "n")))
9181 (clobber (reg:CC FLAGS_REG))]
9183 "and{b}\t{%2, %h0|%h0, %2}"
9184 [(set_attr "type" "alu")
9185 (set_attr "length_immediate" "1")
9186 (set_attr "mode" "QI")])
9188 ;; Generated by peephole translating test to and. This shows up
9189 ;; often in fp comparisons.
9191 (define_insn "*andqi_ext_0_cc"
9192 [(set (reg FLAGS_REG)
9196 (match_operand 1 "ext_register_operand" "0")
9199 (match_operand 2 "const_int_operand" "n"))
9201 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9210 "ix86_match_ccmode (insn, CCNOmode)"
9211 "and{b}\t{%2, %h0|%h0, %2}"
9212 [(set_attr "type" "alu")
9213 (set_attr "length_immediate" "1")
9214 (set_attr "mode" "QI")])
9216 (define_insn "*andqi_ext_1"
9217 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9222 (match_operand 1 "ext_register_operand" "0")
9226 (match_operand:QI 2 "general_operand" "Qm"))))
9227 (clobber (reg:CC FLAGS_REG))]
9229 "and{b}\t{%2, %h0|%h0, %2}"
9230 [(set_attr "type" "alu")
9231 (set_attr "length_immediate" "0")
9232 (set_attr "mode" "QI")])
9234 (define_insn "*andqi_ext_1_rex64"
9235 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9240 (match_operand 1 "ext_register_operand" "0")
9244 (match_operand 2 "ext_register_operand" "Q"))))
9245 (clobber (reg:CC FLAGS_REG))]
9247 "and{b}\t{%2, %h0|%h0, %2}"
9248 [(set_attr "type" "alu")
9249 (set_attr "length_immediate" "0")
9250 (set_attr "mode" "QI")])
9252 (define_insn "*andqi_ext_2"
9253 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9258 (match_operand 1 "ext_register_operand" "%0")
9262 (match_operand 2 "ext_register_operand" "Q")
9265 (clobber (reg:CC FLAGS_REG))]
9267 "and{b}\t{%h2, %h0|%h0, %h2}"
9268 [(set_attr "type" "alu")
9269 (set_attr "length_immediate" "0")
9270 (set_attr "mode" "QI")])
9272 ;; Convert wide AND instructions with immediate operand to shorter QImode
9273 ;; equivalents when possible.
9274 ;; Don't do the splitting with memory operands, since it introduces risk
9275 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9276 ;; for size, but that can (should?) be handled by generic code instead.
9278 [(set (match_operand 0 "register_operand" "")
9279 (and (match_operand 1 "register_operand" "")
9280 (match_operand 2 "const_int_operand" "")))
9281 (clobber (reg:CC FLAGS_REG))]
9283 && QI_REG_P (operands[0])
9284 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9285 && !(~INTVAL (operands[2]) & ~(255 << 8))
9286 && GET_MODE (operands[0]) != QImode"
9287 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9288 (and:SI (zero_extract:SI (match_dup 1)
9289 (const_int 8) (const_int 8))
9291 (clobber (reg:CC FLAGS_REG))])]
9292 "operands[0] = gen_lowpart (SImode, operands[0]);
9293 operands[1] = gen_lowpart (SImode, operands[1]);
9294 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9296 ;; Since AND can be encoded with sign extended immediate, this is only
9297 ;; profitable when 7th bit is not set.
9299 [(set (match_operand 0 "register_operand" "")
9300 (and (match_operand 1 "general_operand" "")
9301 (match_operand 2 "const_int_operand" "")))
9302 (clobber (reg:CC FLAGS_REG))]
9304 && ANY_QI_REG_P (operands[0])
9305 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9306 && !(~INTVAL (operands[2]) & ~255)
9307 && !(INTVAL (operands[2]) & 128)
9308 && GET_MODE (operands[0]) != QImode"
9309 [(parallel [(set (strict_low_part (match_dup 0))
9310 (and:QI (match_dup 1)
9312 (clobber (reg:CC FLAGS_REG))])]
9313 "operands[0] = gen_lowpart (QImode, operands[0]);
9314 operands[1] = gen_lowpart (QImode, operands[1]);
9315 operands[2] = gen_lowpart (QImode, operands[2]);")
9317 ;; Logical inclusive OR instructions
9319 ;; %%% This used to optimize known byte-wide and operations to memory.
9320 ;; If this is considered useful, it should be done with splitters.
9322 (define_expand "iordi3"
9323 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9324 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9325 (match_operand:DI 2 "x86_64_general_operand" "")))
9326 (clobber (reg:CC FLAGS_REG))]
9328 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9330 (define_insn "*iordi_1_rex64"
9331 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9332 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9333 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9334 (clobber (reg:CC FLAGS_REG))]
9336 && ix86_binary_operator_ok (IOR, DImode, operands)"
9337 "or{q}\t{%2, %0|%0, %2}"
9338 [(set_attr "type" "alu")
9339 (set_attr "mode" "DI")])
9341 (define_insn "*iordi_2_rex64"
9342 [(set (reg FLAGS_REG)
9343 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9344 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9346 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9347 (ior:DI (match_dup 1) (match_dup 2)))]
9349 && ix86_match_ccmode (insn, CCNOmode)
9350 && ix86_binary_operator_ok (IOR, DImode, operands)"
9351 "or{q}\t{%2, %0|%0, %2}"
9352 [(set_attr "type" "alu")
9353 (set_attr "mode" "DI")])
9355 (define_insn "*iordi_3_rex64"
9356 [(set (reg FLAGS_REG)
9357 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9358 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9360 (clobber (match_scratch:DI 0 "=r"))]
9362 && ix86_match_ccmode (insn, CCNOmode)
9363 && ix86_binary_operator_ok (IOR, DImode, operands)"
9364 "or{q}\t{%2, %0|%0, %2}"
9365 [(set_attr "type" "alu")
9366 (set_attr "mode" "DI")])
9369 (define_expand "iorsi3"
9370 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9371 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9372 (match_operand:SI 2 "general_operand" "")))
9373 (clobber (reg:CC FLAGS_REG))]
9375 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9377 (define_insn "*iorsi_1"
9378 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9379 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9380 (match_operand:SI 2 "general_operand" "ri,g")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "ix86_binary_operator_ok (IOR, SImode, operands)"
9383 "or{l}\t{%2, %0|%0, %2}"
9384 [(set_attr "type" "alu")
9385 (set_attr "mode" "SI")])
9387 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9388 (define_insn "*iorsi_1_zext"
9389 [(set (match_operand:DI 0 "register_operand" "=r")
9391 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9392 (match_operand:SI 2 "general_operand" "g"))))
9393 (clobber (reg:CC FLAGS_REG))]
9394 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9395 "or{l}\t{%2, %k0|%k0, %2}"
9396 [(set_attr "type" "alu")
9397 (set_attr "mode" "SI")])
9399 (define_insn "*iorsi_1_zext_imm"
9400 [(set (match_operand:DI 0 "register_operand" "=r")
9401 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9402 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9403 (clobber (reg:CC FLAGS_REG))]
9405 "or{l}\t{%2, %k0|%k0, %2}"
9406 [(set_attr "type" "alu")
9407 (set_attr "mode" "SI")])
9409 (define_insn "*iorsi_2"
9410 [(set (reg FLAGS_REG)
9411 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9412 (match_operand:SI 2 "general_operand" "g,ri"))
9414 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9415 (ior:SI (match_dup 1) (match_dup 2)))]
9416 "ix86_match_ccmode (insn, CCNOmode)
9417 && ix86_binary_operator_ok (IOR, SImode, operands)"
9418 "or{l}\t{%2, %0|%0, %2}"
9419 [(set_attr "type" "alu")
9420 (set_attr "mode" "SI")])
9422 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9423 ;; ??? Special case for immediate operand is missing - it is tricky.
9424 (define_insn "*iorsi_2_zext"
9425 [(set (reg FLAGS_REG)
9426 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9427 (match_operand:SI 2 "general_operand" "g"))
9429 (set (match_operand:DI 0 "register_operand" "=r")
9430 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9431 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9432 && ix86_binary_operator_ok (IOR, SImode, operands)"
9433 "or{l}\t{%2, %k0|%k0, %2}"
9434 [(set_attr "type" "alu")
9435 (set_attr "mode" "SI")])
9437 (define_insn "*iorsi_2_zext_imm"
9438 [(set (reg FLAGS_REG)
9439 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9440 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9442 (set (match_operand:DI 0 "register_operand" "=r")
9443 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9444 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9445 && ix86_binary_operator_ok (IOR, SImode, operands)"
9446 "or{l}\t{%2, %k0|%k0, %2}"
9447 [(set_attr "type" "alu")
9448 (set_attr "mode" "SI")])
9450 (define_insn "*iorsi_3"
9451 [(set (reg FLAGS_REG)
9452 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9453 (match_operand:SI 2 "general_operand" "g"))
9455 (clobber (match_scratch:SI 0 "=r"))]
9456 "ix86_match_ccmode (insn, CCNOmode)
9457 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9458 "or{l}\t{%2, %0|%0, %2}"
9459 [(set_attr "type" "alu")
9460 (set_attr "mode" "SI")])
9462 (define_expand "iorhi3"
9463 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9464 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9465 (match_operand:HI 2 "general_operand" "")))
9466 (clobber (reg:CC FLAGS_REG))]
9467 "TARGET_HIMODE_MATH"
9468 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9470 (define_insn "*iorhi_1"
9471 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9472 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9473 (match_operand:HI 2 "general_operand" "rmn,rn")))
9474 (clobber (reg:CC FLAGS_REG))]
9475 "ix86_binary_operator_ok (IOR, HImode, operands)"
9476 "or{w}\t{%2, %0|%0, %2}"
9477 [(set_attr "type" "alu")
9478 (set_attr "mode" "HI")])
9480 (define_insn "*iorhi_2"
9481 [(set (reg FLAGS_REG)
9482 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9483 (match_operand:HI 2 "general_operand" "rmn,rn"))
9485 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9486 (ior:HI (match_dup 1) (match_dup 2)))]
9487 "ix86_match_ccmode (insn, CCNOmode)
9488 && ix86_binary_operator_ok (IOR, HImode, operands)"
9489 "or{w}\t{%2, %0|%0, %2}"
9490 [(set_attr "type" "alu")
9491 (set_attr "mode" "HI")])
9493 (define_insn "*iorhi_3"
9494 [(set (reg FLAGS_REG)
9495 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9496 (match_operand:HI 2 "general_operand" "rmn"))
9498 (clobber (match_scratch:HI 0 "=r"))]
9499 "ix86_match_ccmode (insn, CCNOmode)
9500 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9501 "or{w}\t{%2, %0|%0, %2}"
9502 [(set_attr "type" "alu")
9503 (set_attr "mode" "HI")])
9505 (define_expand "iorqi3"
9506 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9507 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9508 (match_operand:QI 2 "general_operand" "")))
9509 (clobber (reg:CC FLAGS_REG))]
9510 "TARGET_QIMODE_MATH"
9511 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9513 ;; %%% Potential partial reg stall on alternative 2. What to do?
9514 (define_insn "*iorqi_1"
9515 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9516 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9517 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9518 (clobber (reg:CC FLAGS_REG))]
9519 "ix86_binary_operator_ok (IOR, QImode, operands)"
9521 or{b}\t{%2, %0|%0, %2}
9522 or{b}\t{%2, %0|%0, %2}
9523 or{l}\t{%k2, %k0|%k0, %k2}"
9524 [(set_attr "type" "alu")
9525 (set_attr "mode" "QI,QI,SI")])
9527 (define_insn "*iorqi_1_slp"
9528 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9529 (ior:QI (match_dup 0)
9530 (match_operand:QI 1 "general_operand" "qmn,qn")))
9531 (clobber (reg:CC FLAGS_REG))]
9532 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9533 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9534 "or{b}\t{%1, %0|%0, %1}"
9535 [(set_attr "type" "alu1")
9536 (set_attr "mode" "QI")])
9538 (define_insn "*iorqi_2"
9539 [(set (reg FLAGS_REG)
9540 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9541 (match_operand:QI 2 "general_operand" "qmn,qn"))
9543 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9544 (ior:QI (match_dup 1) (match_dup 2)))]
9545 "ix86_match_ccmode (insn, CCNOmode)
9546 && ix86_binary_operator_ok (IOR, QImode, operands)"
9547 "or{b}\t{%2, %0|%0, %2}"
9548 [(set_attr "type" "alu")
9549 (set_attr "mode" "QI")])
9551 (define_insn "*iorqi_2_slp"
9552 [(set (reg FLAGS_REG)
9553 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9554 (match_operand:QI 1 "general_operand" "qmn,qn"))
9556 (set (strict_low_part (match_dup 0))
9557 (ior:QI (match_dup 0) (match_dup 1)))]
9558 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9559 && ix86_match_ccmode (insn, CCNOmode)
9560 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9561 "or{b}\t{%1, %0|%0, %1}"
9562 [(set_attr "type" "alu1")
9563 (set_attr "mode" "QI")])
9565 (define_insn "*iorqi_3"
9566 [(set (reg FLAGS_REG)
9567 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9568 (match_operand:QI 2 "general_operand" "qmn"))
9570 (clobber (match_scratch:QI 0 "=q"))]
9571 "ix86_match_ccmode (insn, CCNOmode)
9572 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9573 "or{b}\t{%2, %0|%0, %2}"
9574 [(set_attr "type" "alu")
9575 (set_attr "mode" "QI")])
9577 (define_insn "iorqi_ext_0"
9578 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9583 (match_operand 1 "ext_register_operand" "0")
9586 (match_operand 2 "const_int_operand" "n")))
9587 (clobber (reg:CC FLAGS_REG))]
9588 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9589 "or{b}\t{%2, %h0|%h0, %2}"
9590 [(set_attr "type" "alu")
9591 (set_attr "length_immediate" "1")
9592 (set_attr "mode" "QI")])
9594 (define_insn "*iorqi_ext_1"
9595 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9600 (match_operand 1 "ext_register_operand" "0")
9604 (match_operand:QI 2 "general_operand" "Qm"))))
9605 (clobber (reg:CC FLAGS_REG))]
9607 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9608 "or{b}\t{%2, %h0|%h0, %2}"
9609 [(set_attr "type" "alu")
9610 (set_attr "length_immediate" "0")
9611 (set_attr "mode" "QI")])
9613 (define_insn "*iorqi_ext_1_rex64"
9614 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9619 (match_operand 1 "ext_register_operand" "0")
9623 (match_operand 2 "ext_register_operand" "Q"))))
9624 (clobber (reg:CC FLAGS_REG))]
9626 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9627 "or{b}\t{%2, %h0|%h0, %2}"
9628 [(set_attr "type" "alu")
9629 (set_attr "length_immediate" "0")
9630 (set_attr "mode" "QI")])
9632 (define_insn "*iorqi_ext_2"
9633 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9637 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9640 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9643 (clobber (reg:CC FLAGS_REG))]
9644 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9645 "ior{b}\t{%h2, %h0|%h0, %h2}"
9646 [(set_attr "type" "alu")
9647 (set_attr "length_immediate" "0")
9648 (set_attr "mode" "QI")])
9651 [(set (match_operand 0 "register_operand" "")
9652 (ior (match_operand 1 "register_operand" "")
9653 (match_operand 2 "const_int_operand" "")))
9654 (clobber (reg:CC FLAGS_REG))]
9656 && QI_REG_P (operands[0])
9657 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9658 && !(INTVAL (operands[2]) & ~(255 << 8))
9659 && GET_MODE (operands[0]) != QImode"
9660 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9661 (ior:SI (zero_extract:SI (match_dup 1)
9662 (const_int 8) (const_int 8))
9664 (clobber (reg:CC FLAGS_REG))])]
9665 "operands[0] = gen_lowpart (SImode, operands[0]);
9666 operands[1] = gen_lowpart (SImode, operands[1]);
9667 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9669 ;; Since OR can be encoded with sign extended immediate, this is only
9670 ;; profitable when 7th bit is set.
9672 [(set (match_operand 0 "register_operand" "")
9673 (ior (match_operand 1 "general_operand" "")
9674 (match_operand 2 "const_int_operand" "")))
9675 (clobber (reg:CC FLAGS_REG))]
9677 && ANY_QI_REG_P (operands[0])
9678 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9679 && !(INTVAL (operands[2]) & ~255)
9680 && (INTVAL (operands[2]) & 128)
9681 && GET_MODE (operands[0]) != QImode"
9682 [(parallel [(set (strict_low_part (match_dup 0))
9683 (ior:QI (match_dup 1)
9685 (clobber (reg:CC FLAGS_REG))])]
9686 "operands[0] = gen_lowpart (QImode, operands[0]);
9687 operands[1] = gen_lowpart (QImode, operands[1]);
9688 operands[2] = gen_lowpart (QImode, operands[2]);")
9690 ;; Logical XOR instructions
9692 ;; %%% This used to optimize known byte-wide and operations to memory.
9693 ;; If this is considered useful, it should be done with splitters.
9695 (define_expand "xordi3"
9696 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9697 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9698 (match_operand:DI 2 "x86_64_general_operand" "")))
9699 (clobber (reg:CC FLAGS_REG))]
9701 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9703 (define_insn "*xordi_1_rex64"
9704 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9705 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9706 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9707 (clobber (reg:CC FLAGS_REG))]
9709 && ix86_binary_operator_ok (XOR, DImode, operands)"
9710 "xor{q}\t{%2, %0|%0, %2}"
9711 [(set_attr "type" "alu")
9712 (set_attr "mode" "DI")])
9714 (define_insn "*xordi_2_rex64"
9715 [(set (reg FLAGS_REG)
9716 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9717 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9719 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9720 (xor:DI (match_dup 1) (match_dup 2)))]
9722 && ix86_match_ccmode (insn, CCNOmode)
9723 && ix86_binary_operator_ok (XOR, DImode, operands)"
9724 "xor{q}\t{%2, %0|%0, %2}"
9725 [(set_attr "type" "alu")
9726 (set_attr "mode" "DI")])
9728 (define_insn "*xordi_3_rex64"
9729 [(set (reg FLAGS_REG)
9730 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9731 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9733 (clobber (match_scratch:DI 0 "=r"))]
9735 && ix86_match_ccmode (insn, CCNOmode)
9736 && ix86_binary_operator_ok (XOR, DImode, operands)"
9737 "xor{q}\t{%2, %0|%0, %2}"
9738 [(set_attr "type" "alu")
9739 (set_attr "mode" "DI")])
9741 (define_expand "xorsi3"
9742 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9743 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9744 (match_operand:SI 2 "general_operand" "")))
9745 (clobber (reg:CC FLAGS_REG))]
9747 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9749 (define_insn "*xorsi_1"
9750 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9751 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9752 (match_operand:SI 2 "general_operand" "ri,rm")))
9753 (clobber (reg:CC FLAGS_REG))]
9754 "ix86_binary_operator_ok (XOR, SImode, operands)"
9755 "xor{l}\t{%2, %0|%0, %2}"
9756 [(set_attr "type" "alu")
9757 (set_attr "mode" "SI")])
9759 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9760 ;; Add speccase for immediates
9761 (define_insn "*xorsi_1_zext"
9762 [(set (match_operand:DI 0 "register_operand" "=r")
9764 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9765 (match_operand:SI 2 "general_operand" "g"))))
9766 (clobber (reg:CC FLAGS_REG))]
9767 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9768 "xor{l}\t{%2, %k0|%k0, %2}"
9769 [(set_attr "type" "alu")
9770 (set_attr "mode" "SI")])
9772 (define_insn "*xorsi_1_zext_imm"
9773 [(set (match_operand:DI 0 "register_operand" "=r")
9774 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9775 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9776 (clobber (reg:CC FLAGS_REG))]
9777 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9778 "xor{l}\t{%2, %k0|%k0, %2}"
9779 [(set_attr "type" "alu")
9780 (set_attr "mode" "SI")])
9782 (define_insn "*xorsi_2"
9783 [(set (reg FLAGS_REG)
9784 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9785 (match_operand:SI 2 "general_operand" "g,ri"))
9787 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9788 (xor:SI (match_dup 1) (match_dup 2)))]
9789 "ix86_match_ccmode (insn, CCNOmode)
9790 && ix86_binary_operator_ok (XOR, SImode, operands)"
9791 "xor{l}\t{%2, %0|%0, %2}"
9792 [(set_attr "type" "alu")
9793 (set_attr "mode" "SI")])
9795 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9796 ;; ??? Special case for immediate operand is missing - it is tricky.
9797 (define_insn "*xorsi_2_zext"
9798 [(set (reg FLAGS_REG)
9799 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9800 (match_operand:SI 2 "general_operand" "g"))
9802 (set (match_operand:DI 0 "register_operand" "=r")
9803 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9804 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9805 && ix86_binary_operator_ok (XOR, SImode, operands)"
9806 "xor{l}\t{%2, %k0|%k0, %2}"
9807 [(set_attr "type" "alu")
9808 (set_attr "mode" "SI")])
9810 (define_insn "*xorsi_2_zext_imm"
9811 [(set (reg FLAGS_REG)
9812 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9813 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9815 (set (match_operand:DI 0 "register_operand" "=r")
9816 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9817 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9818 && ix86_binary_operator_ok (XOR, SImode, operands)"
9819 "xor{l}\t{%2, %k0|%k0, %2}"
9820 [(set_attr "type" "alu")
9821 (set_attr "mode" "SI")])
9823 (define_insn "*xorsi_3"
9824 [(set (reg FLAGS_REG)
9825 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9826 (match_operand:SI 2 "general_operand" "g"))
9828 (clobber (match_scratch:SI 0 "=r"))]
9829 "ix86_match_ccmode (insn, CCNOmode)
9830 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9831 "xor{l}\t{%2, %0|%0, %2}"
9832 [(set_attr "type" "alu")
9833 (set_attr "mode" "SI")])
9835 (define_expand "xorhi3"
9836 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9837 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9838 (match_operand:HI 2 "general_operand" "")))
9839 (clobber (reg:CC FLAGS_REG))]
9840 "TARGET_HIMODE_MATH"
9841 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9843 (define_insn "*xorhi_1"
9844 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9845 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9846 (match_operand:HI 2 "general_operand" "rmn,rn")))
9847 (clobber (reg:CC FLAGS_REG))]
9848 "ix86_binary_operator_ok (XOR, HImode, operands)"
9849 "xor{w}\t{%2, %0|%0, %2}"
9850 [(set_attr "type" "alu")
9851 (set_attr "mode" "HI")])
9853 (define_insn "*xorhi_2"
9854 [(set (reg FLAGS_REG)
9855 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9856 (match_operand:HI 2 "general_operand" "rmn,rn"))
9858 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9859 (xor:HI (match_dup 1) (match_dup 2)))]
9860 "ix86_match_ccmode (insn, CCNOmode)
9861 && ix86_binary_operator_ok (XOR, HImode, operands)"
9862 "xor{w}\t{%2, %0|%0, %2}"
9863 [(set_attr "type" "alu")
9864 (set_attr "mode" "HI")])
9866 (define_insn "*xorhi_3"
9867 [(set (reg FLAGS_REG)
9868 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9869 (match_operand:HI 2 "general_operand" "rmn"))
9871 (clobber (match_scratch:HI 0 "=r"))]
9872 "ix86_match_ccmode (insn, CCNOmode)
9873 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9874 "xor{w}\t{%2, %0|%0, %2}"
9875 [(set_attr "type" "alu")
9876 (set_attr "mode" "HI")])
9878 (define_expand "xorqi3"
9879 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9880 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9881 (match_operand:QI 2 "general_operand" "")))
9882 (clobber (reg:CC FLAGS_REG))]
9883 "TARGET_QIMODE_MATH"
9884 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9886 ;; %%% Potential partial reg stall on alternative 2. What to do?
9887 (define_insn "*xorqi_1"
9888 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9889 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9890 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9891 (clobber (reg:CC FLAGS_REG))]
9892 "ix86_binary_operator_ok (XOR, QImode, operands)"
9894 xor{b}\t{%2, %0|%0, %2}
9895 xor{b}\t{%2, %0|%0, %2}
9896 xor{l}\t{%k2, %k0|%k0, %k2}"
9897 [(set_attr "type" "alu")
9898 (set_attr "mode" "QI,QI,SI")])
9900 (define_insn "*xorqi_1_slp"
9901 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9902 (xor:QI (match_dup 0)
9903 (match_operand:QI 1 "general_operand" "qn,qmn")))
9904 (clobber (reg:CC FLAGS_REG))]
9905 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9906 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9907 "xor{b}\t{%1, %0|%0, %1}"
9908 [(set_attr "type" "alu1")
9909 (set_attr "mode" "QI")])
9911 (define_insn "xorqi_ext_0"
9912 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9917 (match_operand 1 "ext_register_operand" "0")
9920 (match_operand 2 "const_int_operand" "n")))
9921 (clobber (reg:CC FLAGS_REG))]
9922 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9923 "xor{b}\t{%2, %h0|%h0, %2}"
9924 [(set_attr "type" "alu")
9925 (set_attr "length_immediate" "1")
9926 (set_attr "mode" "QI")])
9928 (define_insn "*xorqi_ext_1"
9929 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9934 (match_operand 1 "ext_register_operand" "0")
9938 (match_operand:QI 2 "general_operand" "Qm"))))
9939 (clobber (reg:CC FLAGS_REG))]
9941 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9942 "xor{b}\t{%2, %h0|%h0, %2}"
9943 [(set_attr "type" "alu")
9944 (set_attr "length_immediate" "0")
9945 (set_attr "mode" "QI")])
9947 (define_insn "*xorqi_ext_1_rex64"
9948 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9953 (match_operand 1 "ext_register_operand" "0")
9957 (match_operand 2 "ext_register_operand" "Q"))))
9958 (clobber (reg:CC FLAGS_REG))]
9960 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9961 "xor{b}\t{%2, %h0|%h0, %2}"
9962 [(set_attr "type" "alu")
9963 (set_attr "length_immediate" "0")
9964 (set_attr "mode" "QI")])
9966 (define_insn "*xorqi_ext_2"
9967 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9971 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9974 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9977 (clobber (reg:CC FLAGS_REG))]
9978 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9979 "xor{b}\t{%h2, %h0|%h0, %h2}"
9980 [(set_attr "type" "alu")
9981 (set_attr "length_immediate" "0")
9982 (set_attr "mode" "QI")])
9984 (define_insn "*xorqi_cc_1"
9985 [(set (reg FLAGS_REG)
9987 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9988 (match_operand:QI 2 "general_operand" "qmn,qn"))
9990 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9991 (xor:QI (match_dup 1) (match_dup 2)))]
9992 "ix86_match_ccmode (insn, CCNOmode)
9993 && ix86_binary_operator_ok (XOR, QImode, operands)"
9994 "xor{b}\t{%2, %0|%0, %2}"
9995 [(set_attr "type" "alu")
9996 (set_attr "mode" "QI")])
9998 (define_insn "*xorqi_2_slp"
9999 [(set (reg FLAGS_REG)
10000 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10001 (match_operand:QI 1 "general_operand" "qmn,qn"))
10003 (set (strict_low_part (match_dup 0))
10004 (xor:QI (match_dup 0) (match_dup 1)))]
10005 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10006 && ix86_match_ccmode (insn, CCNOmode)
10007 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10008 "xor{b}\t{%1, %0|%0, %1}"
10009 [(set_attr "type" "alu1")
10010 (set_attr "mode" "QI")])
10012 (define_insn "*xorqi_cc_2"
10013 [(set (reg FLAGS_REG)
10015 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10016 (match_operand:QI 2 "general_operand" "qmn"))
10018 (clobber (match_scratch:QI 0 "=q"))]
10019 "ix86_match_ccmode (insn, CCNOmode)
10020 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10021 "xor{b}\t{%2, %0|%0, %2}"
10022 [(set_attr "type" "alu")
10023 (set_attr "mode" "QI")])
10025 (define_insn "*xorqi_cc_ext_1"
10026 [(set (reg FLAGS_REG)
10030 (match_operand 1 "ext_register_operand" "0")
10033 (match_operand:QI 2 "general_operand" "qmn"))
10035 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10039 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10041 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10042 "xor{b}\t{%2, %h0|%h0, %2}"
10043 [(set_attr "type" "alu")
10044 (set_attr "mode" "QI")])
10046 (define_insn "*xorqi_cc_ext_1_rex64"
10047 [(set (reg FLAGS_REG)
10051 (match_operand 1 "ext_register_operand" "0")
10054 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10056 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10060 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10062 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10063 "xor{b}\t{%2, %h0|%h0, %2}"
10064 [(set_attr "type" "alu")
10065 (set_attr "mode" "QI")])
10067 (define_expand "xorqi_cc_ext_1"
10069 (set (reg:CCNO FLAGS_REG)
10073 (match_operand 1 "ext_register_operand" "")
10076 (match_operand:QI 2 "general_operand" ""))
10078 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10082 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10088 [(set (match_operand 0 "register_operand" "")
10089 (xor (match_operand 1 "register_operand" "")
10090 (match_operand 2 "const_int_operand" "")))
10091 (clobber (reg:CC FLAGS_REG))]
10093 && QI_REG_P (operands[0])
10094 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10095 && !(INTVAL (operands[2]) & ~(255 << 8))
10096 && GET_MODE (operands[0]) != QImode"
10097 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10098 (xor:SI (zero_extract:SI (match_dup 1)
10099 (const_int 8) (const_int 8))
10101 (clobber (reg:CC FLAGS_REG))])]
10102 "operands[0] = gen_lowpart (SImode, operands[0]);
10103 operands[1] = gen_lowpart (SImode, operands[1]);
10104 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10106 ;; Since XOR can be encoded with sign extended immediate, this is only
10107 ;; profitable when 7th bit is set.
10109 [(set (match_operand 0 "register_operand" "")
10110 (xor (match_operand 1 "general_operand" "")
10111 (match_operand 2 "const_int_operand" "")))
10112 (clobber (reg:CC FLAGS_REG))]
10114 && ANY_QI_REG_P (operands[0])
10115 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10116 && !(INTVAL (operands[2]) & ~255)
10117 && (INTVAL (operands[2]) & 128)
10118 && GET_MODE (operands[0]) != QImode"
10119 [(parallel [(set (strict_low_part (match_dup 0))
10120 (xor:QI (match_dup 1)
10122 (clobber (reg:CC FLAGS_REG))])]
10123 "operands[0] = gen_lowpart (QImode, operands[0]);
10124 operands[1] = gen_lowpart (QImode, operands[1]);
10125 operands[2] = gen_lowpart (QImode, operands[2]);")
10127 ;; Negation instructions
10129 (define_expand "negti2"
10130 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10131 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10132 (clobber (reg:CC FLAGS_REG))])]
10134 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10136 (define_insn "*negti2_1"
10137 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10138 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10139 (clobber (reg:CC FLAGS_REG))]
10141 && ix86_unary_operator_ok (NEG, TImode, operands)"
10145 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10146 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10147 (clobber (reg:CC FLAGS_REG))]
10148 "TARGET_64BIT && reload_completed"
10150 [(set (reg:CCZ FLAGS_REG)
10151 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10152 (set (match_dup 0) (neg:DI (match_dup 1)))])
10154 [(set (match_dup 2)
10155 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10158 (clobber (reg:CC FLAGS_REG))])
10160 [(set (match_dup 2)
10161 (neg:DI (match_dup 2)))
10162 (clobber (reg:CC FLAGS_REG))])]
10163 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10165 (define_expand "negdi2"
10166 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10167 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10168 (clobber (reg:CC FLAGS_REG))])]
10170 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10172 (define_insn "*negdi2_1"
10173 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10174 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10175 (clobber (reg:CC FLAGS_REG))]
10177 && ix86_unary_operator_ok (NEG, DImode, operands)"
10181 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10182 (neg:DI (match_operand:DI 1 "general_operand" "")))
10183 (clobber (reg:CC FLAGS_REG))]
10184 "!TARGET_64BIT && reload_completed"
10186 [(set (reg:CCZ FLAGS_REG)
10187 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10188 (set (match_dup 0) (neg:SI (match_dup 1)))])
10190 [(set (match_dup 2)
10191 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10194 (clobber (reg:CC FLAGS_REG))])
10196 [(set (match_dup 2)
10197 (neg:SI (match_dup 2)))
10198 (clobber (reg:CC FLAGS_REG))])]
10199 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10201 (define_insn "*negdi2_1_rex64"
10202 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10203 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10204 (clobber (reg:CC FLAGS_REG))]
10205 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10207 [(set_attr "type" "negnot")
10208 (set_attr "mode" "DI")])
10210 ;; The problem with neg is that it does not perform (compare x 0),
10211 ;; it really performs (compare 0 x), which leaves us with the zero
10212 ;; flag being the only useful item.
10214 (define_insn "*negdi2_cmpz_rex64"
10215 [(set (reg:CCZ FLAGS_REG)
10216 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10218 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10219 (neg:DI (match_dup 1)))]
10220 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10222 [(set_attr "type" "negnot")
10223 (set_attr "mode" "DI")])
10226 (define_expand "negsi2"
10227 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10228 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10229 (clobber (reg:CC FLAGS_REG))])]
10231 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10233 (define_insn "*negsi2_1"
10234 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10235 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10236 (clobber (reg:CC FLAGS_REG))]
10237 "ix86_unary_operator_ok (NEG, SImode, operands)"
10239 [(set_attr "type" "negnot")
10240 (set_attr "mode" "SI")])
10242 ;; Combine is quite creative about this pattern.
10243 (define_insn "*negsi2_1_zext"
10244 [(set (match_operand:DI 0 "register_operand" "=r")
10245 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10248 (clobber (reg:CC FLAGS_REG))]
10249 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10251 [(set_attr "type" "negnot")
10252 (set_attr "mode" "SI")])
10254 ;; The problem with neg is that it does not perform (compare x 0),
10255 ;; it really performs (compare 0 x), which leaves us with the zero
10256 ;; flag being the only useful item.
10258 (define_insn "*negsi2_cmpz"
10259 [(set (reg:CCZ FLAGS_REG)
10260 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10262 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10263 (neg:SI (match_dup 1)))]
10264 "ix86_unary_operator_ok (NEG, SImode, operands)"
10266 [(set_attr "type" "negnot")
10267 (set_attr "mode" "SI")])
10269 (define_insn "*negsi2_cmpz_zext"
10270 [(set (reg:CCZ FLAGS_REG)
10271 (compare:CCZ (lshiftrt:DI
10273 (match_operand:DI 1 "register_operand" "0")
10277 (set (match_operand:DI 0 "register_operand" "=r")
10278 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10281 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10283 [(set_attr "type" "negnot")
10284 (set_attr "mode" "SI")])
10286 (define_expand "neghi2"
10287 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10288 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10289 (clobber (reg:CC FLAGS_REG))])]
10290 "TARGET_HIMODE_MATH"
10291 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10293 (define_insn "*neghi2_1"
10294 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10295 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10296 (clobber (reg:CC FLAGS_REG))]
10297 "ix86_unary_operator_ok (NEG, HImode, operands)"
10299 [(set_attr "type" "negnot")
10300 (set_attr "mode" "HI")])
10302 (define_insn "*neghi2_cmpz"
10303 [(set (reg:CCZ FLAGS_REG)
10304 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10306 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10307 (neg:HI (match_dup 1)))]
10308 "ix86_unary_operator_ok (NEG, HImode, operands)"
10310 [(set_attr "type" "negnot")
10311 (set_attr "mode" "HI")])
10313 (define_expand "negqi2"
10314 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10315 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10316 (clobber (reg:CC FLAGS_REG))])]
10317 "TARGET_QIMODE_MATH"
10318 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10320 (define_insn "*negqi2_1"
10321 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10322 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10323 (clobber (reg:CC FLAGS_REG))]
10324 "ix86_unary_operator_ok (NEG, QImode, operands)"
10326 [(set_attr "type" "negnot")
10327 (set_attr "mode" "QI")])
10329 (define_insn "*negqi2_cmpz"
10330 [(set (reg:CCZ FLAGS_REG)
10331 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10333 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10334 (neg:QI (match_dup 1)))]
10335 "ix86_unary_operator_ok (NEG, QImode, operands)"
10337 [(set_attr "type" "negnot")
10338 (set_attr "mode" "QI")])
10340 ;; Changing of sign for FP values is doable using integer unit too.
10342 (define_expand "<code><mode>2"
10343 [(set (match_operand:X87MODEF 0 "register_operand" "")
10344 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10345 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10346 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10348 (define_insn "*absneg<mode>2_mixed"
10349 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10350 (match_operator:MODEF 3 "absneg_operator"
10351 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10352 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10353 (clobber (reg:CC FLAGS_REG))]
10354 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10357 (define_insn "*absneg<mode>2_sse"
10358 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10359 (match_operator:MODEF 3 "absneg_operator"
10360 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10361 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10362 (clobber (reg:CC FLAGS_REG))]
10363 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10366 (define_insn "*absneg<mode>2_i387"
10367 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10368 (match_operator:X87MODEF 3 "absneg_operator"
10369 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10370 (use (match_operand 2 "" ""))
10371 (clobber (reg:CC FLAGS_REG))]
10372 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10375 (define_expand "<code>tf2"
10376 [(set (match_operand:TF 0 "register_operand" "")
10377 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10379 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10381 (define_insn "*absnegtf2_sse"
10382 [(set (match_operand:TF 0 "register_operand" "=x,x")
10383 (match_operator:TF 3 "absneg_operator"
10384 [(match_operand:TF 1 "register_operand" "0,x")]))
10385 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10386 (clobber (reg:CC FLAGS_REG))]
10390 ;; Splitters for fp abs and neg.
10393 [(set (match_operand 0 "fp_register_operand" "")
10394 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10395 (use (match_operand 2 "" ""))
10396 (clobber (reg:CC FLAGS_REG))]
10398 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10401 [(set (match_operand 0 "register_operand" "")
10402 (match_operator 3 "absneg_operator"
10403 [(match_operand 1 "register_operand" "")]))
10404 (use (match_operand 2 "nonimmediate_operand" ""))
10405 (clobber (reg:CC FLAGS_REG))]
10406 "reload_completed && SSE_REG_P (operands[0])"
10407 [(set (match_dup 0) (match_dup 3))]
10409 enum machine_mode mode = GET_MODE (operands[0]);
10410 enum machine_mode vmode = GET_MODE (operands[2]);
10413 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10414 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10415 if (operands_match_p (operands[0], operands[2]))
10418 operands[1] = operands[2];
10421 if (GET_CODE (operands[3]) == ABS)
10422 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10424 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10429 [(set (match_operand:SF 0 "register_operand" "")
10430 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10431 (use (match_operand:V4SF 2 "" ""))
10432 (clobber (reg:CC FLAGS_REG))]
10434 [(parallel [(set (match_dup 0) (match_dup 1))
10435 (clobber (reg:CC FLAGS_REG))])]
10438 operands[0] = gen_lowpart (SImode, operands[0]);
10439 if (GET_CODE (operands[1]) == ABS)
10441 tmp = gen_int_mode (0x7fffffff, SImode);
10442 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10446 tmp = gen_int_mode (0x80000000, SImode);
10447 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10453 [(set (match_operand:DF 0 "register_operand" "")
10454 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10455 (use (match_operand 2 "" ""))
10456 (clobber (reg:CC FLAGS_REG))]
10458 [(parallel [(set (match_dup 0) (match_dup 1))
10459 (clobber (reg:CC FLAGS_REG))])]
10464 tmp = gen_lowpart (DImode, operands[0]);
10465 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10468 if (GET_CODE (operands[1]) == ABS)
10471 tmp = gen_rtx_NOT (DImode, tmp);
10475 operands[0] = gen_highpart (SImode, operands[0]);
10476 if (GET_CODE (operands[1]) == ABS)
10478 tmp = gen_int_mode (0x7fffffff, SImode);
10479 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10483 tmp = gen_int_mode (0x80000000, SImode);
10484 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10491 [(set (match_operand:XF 0 "register_operand" "")
10492 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10493 (use (match_operand 2 "" ""))
10494 (clobber (reg:CC FLAGS_REG))]
10496 [(parallel [(set (match_dup 0) (match_dup 1))
10497 (clobber (reg:CC FLAGS_REG))])]
10500 operands[0] = gen_rtx_REG (SImode,
10501 true_regnum (operands[0])
10502 + (TARGET_64BIT ? 1 : 2));
10503 if (GET_CODE (operands[1]) == ABS)
10505 tmp = GEN_INT (0x7fff);
10506 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10510 tmp = GEN_INT (0x8000);
10511 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10516 ;; Conditionalize these after reload. If they match before reload, we
10517 ;; lose the clobber and ability to use integer instructions.
10519 (define_insn "*<code><mode>2_1"
10520 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10521 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10523 && (reload_completed
10524 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10526 [(set_attr "type" "fsgn")
10527 (set_attr "mode" "<MODE>")])
10529 (define_insn "*<code>extendsfdf2"
10530 [(set (match_operand:DF 0 "register_operand" "=f")
10531 (absneg:DF (float_extend:DF
10532 (match_operand:SF 1 "register_operand" "0"))))]
10533 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10535 [(set_attr "type" "fsgn")
10536 (set_attr "mode" "DF")])
10538 (define_insn "*<code>extendsfxf2"
10539 [(set (match_operand:XF 0 "register_operand" "=f")
10540 (absneg:XF (float_extend:XF
10541 (match_operand:SF 1 "register_operand" "0"))))]
10544 [(set_attr "type" "fsgn")
10545 (set_attr "mode" "XF")])
10547 (define_insn "*<code>extenddfxf2"
10548 [(set (match_operand:XF 0 "register_operand" "=f")
10549 (absneg:XF (float_extend:XF
10550 (match_operand:DF 1 "register_operand" "0"))))]
10553 [(set_attr "type" "fsgn")
10554 (set_attr "mode" "XF")])
10556 ;; Copysign instructions
10558 (define_mode_iterator CSGNMODE [SF DF TF])
10559 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10561 (define_expand "copysign<mode>3"
10562 [(match_operand:CSGNMODE 0 "register_operand" "")
10563 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10564 (match_operand:CSGNMODE 2 "register_operand" "")]
10565 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10566 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10568 ix86_expand_copysign (operands);
10572 (define_insn_and_split "copysign<mode>3_const"
10573 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10575 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10576 (match_operand:CSGNMODE 2 "register_operand" "0")
10577 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10579 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10580 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10582 "&& reload_completed"
10585 ix86_split_copysign_const (operands);
10589 (define_insn "copysign<mode>3_var"
10590 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10592 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10593 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10594 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10595 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10597 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10598 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10599 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10603 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10605 [(match_operand:CSGNMODE 2 "register_operand" "")
10606 (match_operand:CSGNMODE 3 "register_operand" "")
10607 (match_operand:<CSGNVMODE> 4 "" "")
10608 (match_operand:<CSGNVMODE> 5 "" "")]
10610 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10611 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10612 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10613 && reload_completed"
10616 ix86_split_copysign_var (operands);
10620 ;; One complement instructions
10622 (define_expand "one_cmpldi2"
10623 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10624 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10626 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10628 (define_insn "*one_cmpldi2_1_rex64"
10629 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10630 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10631 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10633 [(set_attr "type" "negnot")
10634 (set_attr "mode" "DI")])
10636 (define_insn "*one_cmpldi2_2_rex64"
10637 [(set (reg FLAGS_REG)
10638 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10640 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10641 (not:DI (match_dup 1)))]
10642 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10643 && ix86_unary_operator_ok (NOT, DImode, operands)"
10645 [(set_attr "type" "alu1")
10646 (set_attr "mode" "DI")])
10649 [(set (match_operand 0 "flags_reg_operand" "")
10650 (match_operator 2 "compare_operator"
10651 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10653 (set (match_operand:DI 1 "nonimmediate_operand" "")
10654 (not:DI (match_dup 3)))]
10655 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10656 [(parallel [(set (match_dup 0)
10658 [(xor:DI (match_dup 3) (const_int -1))
10661 (xor:DI (match_dup 3) (const_int -1)))])]
10664 (define_expand "one_cmplsi2"
10665 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10666 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10668 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10670 (define_insn "*one_cmplsi2_1"
10671 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10672 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10673 "ix86_unary_operator_ok (NOT, SImode, operands)"
10675 [(set_attr "type" "negnot")
10676 (set_attr "mode" "SI")])
10678 ;; ??? Currently never generated - xor is used instead.
10679 (define_insn "*one_cmplsi2_1_zext"
10680 [(set (match_operand:DI 0 "register_operand" "=r")
10681 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10682 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10684 [(set_attr "type" "negnot")
10685 (set_attr "mode" "SI")])
10687 (define_insn "*one_cmplsi2_2"
10688 [(set (reg FLAGS_REG)
10689 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10691 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10692 (not:SI (match_dup 1)))]
10693 "ix86_match_ccmode (insn, CCNOmode)
10694 && ix86_unary_operator_ok (NOT, SImode, operands)"
10696 [(set_attr "type" "alu1")
10697 (set_attr "mode" "SI")])
10700 [(set (match_operand 0 "flags_reg_operand" "")
10701 (match_operator 2 "compare_operator"
10702 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10704 (set (match_operand:SI 1 "nonimmediate_operand" "")
10705 (not:SI (match_dup 3)))]
10706 "ix86_match_ccmode (insn, CCNOmode)"
10707 [(parallel [(set (match_dup 0)
10708 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10711 (xor:SI (match_dup 3) (const_int -1)))])]
10714 ;; ??? Currently never generated - xor is used instead.
10715 (define_insn "*one_cmplsi2_2_zext"
10716 [(set (reg FLAGS_REG)
10717 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10719 (set (match_operand:DI 0 "register_operand" "=r")
10720 (zero_extend:DI (not:SI (match_dup 1))))]
10721 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10722 && ix86_unary_operator_ok (NOT, SImode, operands)"
10724 [(set_attr "type" "alu1")
10725 (set_attr "mode" "SI")])
10728 [(set (match_operand 0 "flags_reg_operand" "")
10729 (match_operator 2 "compare_operator"
10730 [(not:SI (match_operand:SI 3 "register_operand" ""))
10732 (set (match_operand:DI 1 "register_operand" "")
10733 (zero_extend:DI (not:SI (match_dup 3))))]
10734 "ix86_match_ccmode (insn, CCNOmode)"
10735 [(parallel [(set (match_dup 0)
10736 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10739 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10742 (define_expand "one_cmplhi2"
10743 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10744 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10745 "TARGET_HIMODE_MATH"
10746 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10748 (define_insn "*one_cmplhi2_1"
10749 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10750 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10751 "ix86_unary_operator_ok (NOT, HImode, operands)"
10753 [(set_attr "type" "negnot")
10754 (set_attr "mode" "HI")])
10756 (define_insn "*one_cmplhi2_2"
10757 [(set (reg FLAGS_REG)
10758 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10760 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10761 (not:HI (match_dup 1)))]
10762 "ix86_match_ccmode (insn, CCNOmode)
10763 && ix86_unary_operator_ok (NEG, HImode, operands)"
10765 [(set_attr "type" "alu1")
10766 (set_attr "mode" "HI")])
10769 [(set (match_operand 0 "flags_reg_operand" "")
10770 (match_operator 2 "compare_operator"
10771 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10773 (set (match_operand:HI 1 "nonimmediate_operand" "")
10774 (not:HI (match_dup 3)))]
10775 "ix86_match_ccmode (insn, CCNOmode)"
10776 [(parallel [(set (match_dup 0)
10777 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10780 (xor:HI (match_dup 3) (const_int -1)))])]
10783 ;; %%% Potential partial reg stall on alternative 1. What to do?
10784 (define_expand "one_cmplqi2"
10785 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10786 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10787 "TARGET_QIMODE_MATH"
10788 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10790 (define_insn "*one_cmplqi2_1"
10791 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10792 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10793 "ix86_unary_operator_ok (NOT, QImode, operands)"
10797 [(set_attr "type" "negnot")
10798 (set_attr "mode" "QI,SI")])
10800 (define_insn "*one_cmplqi2_2"
10801 [(set (reg FLAGS_REG)
10802 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10804 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10805 (not:QI (match_dup 1)))]
10806 "ix86_match_ccmode (insn, CCNOmode)
10807 && ix86_unary_operator_ok (NOT, QImode, operands)"
10809 [(set_attr "type" "alu1")
10810 (set_attr "mode" "QI")])
10813 [(set (match_operand 0 "flags_reg_operand" "")
10814 (match_operator 2 "compare_operator"
10815 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10817 (set (match_operand:QI 1 "nonimmediate_operand" "")
10818 (not:QI (match_dup 3)))]
10819 "ix86_match_ccmode (insn, CCNOmode)"
10820 [(parallel [(set (match_dup 0)
10821 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10824 (xor:QI (match_dup 3) (const_int -1)))])]
10827 ;; Arithmetic shift instructions
10829 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10830 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10831 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10832 ;; from the assembler input.
10834 ;; This instruction shifts the target reg/mem as usual, but instead of
10835 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10836 ;; is a left shift double, bits are taken from the high order bits of
10837 ;; reg, else if the insn is a shift right double, bits are taken from the
10838 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10839 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10841 ;; Since sh[lr]d does not change the `reg' operand, that is done
10842 ;; separately, making all shifts emit pairs of shift double and normal
10843 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10844 ;; support a 63 bit shift, each shift where the count is in a reg expands
10845 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10847 ;; If the shift count is a constant, we need never emit more than one
10848 ;; shift pair, instead using moves and sign extension for counts greater
10851 (define_expand "ashlti3"
10852 [(set (match_operand:TI 0 "register_operand" "")
10853 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10854 (match_operand:QI 2 "nonmemory_operand" "")))]
10856 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10858 ;; This pattern must be defined before *ashlti3_1 to prevent
10859 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10861 (define_insn "sse2_ashlti3"
10862 [(set (match_operand:TI 0 "register_operand" "=x")
10863 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10864 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10867 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10868 return "pslldq\t{%2, %0|%0, %2}";
10870 [(set_attr "type" "sseishft")
10871 (set_attr "prefix_data16" "1")
10872 (set_attr "mode" "TI")])
10874 (define_insn "*ashlti3_1"
10875 [(set (match_operand:TI 0 "register_operand" "=&r,r")
10876 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10877 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10878 (clobber (reg:CC FLAGS_REG))]
10881 [(set_attr "type" "multi")])
10884 [(match_scratch:DI 3 "r")
10885 (parallel [(set (match_operand:TI 0 "register_operand" "")
10886 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10887 (match_operand:QI 2 "nonmemory_operand" "")))
10888 (clobber (reg:CC FLAGS_REG))])
10892 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10895 [(set (match_operand:TI 0 "register_operand" "")
10896 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10897 (match_operand:QI 2 "nonmemory_operand" "")))
10898 (clobber (reg:CC FLAGS_REG))]
10899 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10900 ? epilogue_completed : reload_completed)"
10902 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10904 (define_insn "x86_64_shld"
10905 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10906 (ior:DI (ashift:DI (match_dup 0)
10907 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10908 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10909 (minus:QI (const_int 64) (match_dup 2)))))
10910 (clobber (reg:CC FLAGS_REG))]
10912 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10913 [(set_attr "type" "ishift")
10914 (set_attr "prefix_0f" "1")
10915 (set_attr "mode" "DI")
10916 (set_attr "athlon_decode" "vector")
10917 (set_attr "amdfam10_decode" "vector")])
10919 (define_expand "x86_64_shift_adj"
10920 [(set (reg:CCZ FLAGS_REG)
10921 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10924 (set (match_operand:DI 0 "register_operand" "")
10925 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10926 (match_operand:DI 1 "register_operand" "")
10929 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10930 (match_operand:DI 3 "register_operand" "r")
10935 (define_expand "ashldi3"
10936 [(set (match_operand:DI 0 "shiftdi_operand" "")
10937 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10938 (match_operand:QI 2 "nonmemory_operand" "")))]
10940 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10942 (define_insn "*ashldi3_1_rex64"
10943 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10944 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10945 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10946 (clobber (reg:CC FLAGS_REG))]
10947 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10949 switch (get_attr_type (insn))
10952 gcc_assert (operands[2] == const1_rtx);
10953 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10954 return "add{q}\t%0, %0";
10957 gcc_assert (CONST_INT_P (operands[2]));
10958 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10959 operands[1] = gen_rtx_MULT (DImode, operands[1],
10960 GEN_INT (1 << INTVAL (operands[2])));
10961 return "lea{q}\t{%a1, %0|%0, %a1}";
10964 if (REG_P (operands[2]))
10965 return "sal{q}\t{%b2, %0|%0, %b2}";
10966 else if (operands[2] == const1_rtx
10967 && (TARGET_SHIFT1 || optimize_size))
10968 return "sal{q}\t%0";
10970 return "sal{q}\t{%2, %0|%0, %2}";
10973 [(set (attr "type")
10974 (cond [(eq_attr "alternative" "1")
10975 (const_string "lea")
10976 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10978 (match_operand 0 "register_operand" ""))
10979 (match_operand 2 "const1_operand" ""))
10980 (const_string "alu")
10982 (const_string "ishift")))
10983 (set_attr "mode" "DI")])
10985 ;; Convert lea to the lea pattern to avoid flags dependency.
10987 [(set (match_operand:DI 0 "register_operand" "")
10988 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10989 (match_operand:QI 2 "immediate_operand" "")))
10990 (clobber (reg:CC FLAGS_REG))]
10991 "TARGET_64BIT && reload_completed
10992 && true_regnum (operands[0]) != true_regnum (operands[1])"
10993 [(set (match_dup 0)
10994 (mult:DI (match_dup 1)
10996 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10998 ;; This pattern can't accept a variable shift count, since shifts by
10999 ;; zero don't affect the flags. We assume that shifts by constant
11000 ;; zero are optimized away.
11001 (define_insn "*ashldi3_cmp_rex64"
11002 [(set (reg FLAGS_REG)
11004 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11005 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11007 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11008 (ashift:DI (match_dup 1) (match_dup 2)))]
11011 || !TARGET_PARTIAL_FLAG_REG_STALL
11012 || (operands[2] == const1_rtx
11014 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11015 && ix86_match_ccmode (insn, CCGOCmode)
11016 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11018 switch (get_attr_type (insn))
11021 gcc_assert (operands[2] == const1_rtx);
11022 return "add{q}\t%0, %0";
11025 if (REG_P (operands[2]))
11026 return "sal{q}\t{%b2, %0|%0, %b2}";
11027 else if (operands[2] == const1_rtx
11028 && (TARGET_SHIFT1 || optimize_size))
11029 return "sal{q}\t%0";
11031 return "sal{q}\t{%2, %0|%0, %2}";
11034 [(set (attr "type")
11035 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11037 (match_operand 0 "register_operand" ""))
11038 (match_operand 2 "const1_operand" ""))
11039 (const_string "alu")
11041 (const_string "ishift")))
11042 (set_attr "mode" "DI")])
11044 (define_insn "*ashldi3_cconly_rex64"
11045 [(set (reg FLAGS_REG)
11047 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11048 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11050 (clobber (match_scratch:DI 0 "=r"))]
11053 || !TARGET_PARTIAL_FLAG_REG_STALL
11054 || (operands[2] == const1_rtx
11056 || TARGET_DOUBLE_WITH_ADD)))
11057 && ix86_match_ccmode (insn, CCGOCmode)
11058 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11060 switch (get_attr_type (insn))
11063 gcc_assert (operands[2] == const1_rtx);
11064 return "add{q}\t%0, %0";
11067 if (REG_P (operands[2]))
11068 return "sal{q}\t{%b2, %0|%0, %b2}";
11069 else if (operands[2] == const1_rtx
11070 && (TARGET_SHIFT1 || optimize_size))
11071 return "sal{q}\t%0";
11073 return "sal{q}\t{%2, %0|%0, %2}";
11076 [(set (attr "type")
11077 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11079 (match_operand 0 "register_operand" ""))
11080 (match_operand 2 "const1_operand" ""))
11081 (const_string "alu")
11083 (const_string "ishift")))
11084 (set_attr "mode" "DI")])
11086 (define_insn "*ashldi3_1"
11087 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11088 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11089 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11090 (clobber (reg:CC FLAGS_REG))]
11093 [(set_attr "type" "multi")])
11095 ;; By default we don't ask for a scratch register, because when DImode
11096 ;; values are manipulated, registers are already at a premium. But if
11097 ;; we have one handy, we won't turn it away.
11099 [(match_scratch:SI 3 "r")
11100 (parallel [(set (match_operand:DI 0 "register_operand" "")
11101 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11102 (match_operand:QI 2 "nonmemory_operand" "")))
11103 (clobber (reg:CC FLAGS_REG))])
11105 "!TARGET_64BIT && TARGET_CMOVE"
11107 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11110 [(set (match_operand:DI 0 "register_operand" "")
11111 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11112 (match_operand:QI 2 "nonmemory_operand" "")))
11113 (clobber (reg:CC FLAGS_REG))]
11114 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11115 ? epilogue_completed : reload_completed)"
11117 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11119 (define_insn "x86_shld"
11120 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11121 (ior:SI (ashift:SI (match_dup 0)
11122 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11123 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11124 (minus:QI (const_int 32) (match_dup 2)))))
11125 (clobber (reg:CC FLAGS_REG))]
11127 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11128 [(set_attr "type" "ishift")
11129 (set_attr "prefix_0f" "1")
11130 (set_attr "mode" "SI")
11131 (set_attr "pent_pair" "np")
11132 (set_attr "athlon_decode" "vector")
11133 (set_attr "amdfam10_decode" "vector")])
11135 (define_expand "x86_shift_adj_1"
11136 [(set (reg:CCZ FLAGS_REG)
11137 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11140 (set (match_operand:SI 0 "register_operand" "")
11141 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11142 (match_operand:SI 1 "register_operand" "")
11145 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11146 (match_operand:SI 3 "register_operand" "r")
11151 (define_expand "x86_shift_adj_2"
11152 [(use (match_operand:SI 0 "register_operand" ""))
11153 (use (match_operand:SI 1 "register_operand" ""))
11154 (use (match_operand:QI 2 "register_operand" ""))]
11157 rtx label = gen_label_rtx ();
11160 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11162 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11163 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11164 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11165 gen_rtx_LABEL_REF (VOIDmode, label),
11167 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11168 JUMP_LABEL (tmp) = label;
11170 emit_move_insn (operands[0], operands[1]);
11171 ix86_expand_clear (operands[1]);
11173 emit_label (label);
11174 LABEL_NUSES (label) = 1;
11179 (define_expand "ashlsi3"
11180 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11181 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11182 (match_operand:QI 2 "nonmemory_operand" "")))
11183 (clobber (reg:CC FLAGS_REG))]
11185 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11187 (define_insn "*ashlsi3_1"
11188 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11189 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11190 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11191 (clobber (reg:CC FLAGS_REG))]
11192 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11194 switch (get_attr_type (insn))
11197 gcc_assert (operands[2] == const1_rtx);
11198 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11199 return "add{l}\t%0, %0";
11205 if (REG_P (operands[2]))
11206 return "sal{l}\t{%b2, %0|%0, %b2}";
11207 else if (operands[2] == const1_rtx
11208 && (TARGET_SHIFT1 || optimize_size))
11209 return "sal{l}\t%0";
11211 return "sal{l}\t{%2, %0|%0, %2}";
11214 [(set (attr "type")
11215 (cond [(eq_attr "alternative" "1")
11216 (const_string "lea")
11217 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11219 (match_operand 0 "register_operand" ""))
11220 (match_operand 2 "const1_operand" ""))
11221 (const_string "alu")
11223 (const_string "ishift")))
11224 (set_attr "mode" "SI")])
11226 ;; Convert lea to the lea pattern to avoid flags dependency.
11228 [(set (match_operand 0 "register_operand" "")
11229 (ashift (match_operand 1 "index_register_operand" "")
11230 (match_operand:QI 2 "const_int_operand" "")))
11231 (clobber (reg:CC FLAGS_REG))]
11233 && true_regnum (operands[0]) != true_regnum (operands[1])
11234 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11238 enum machine_mode mode = GET_MODE (operands[0]);
11240 if (GET_MODE_SIZE (mode) < 4)
11241 operands[0] = gen_lowpart (SImode, operands[0]);
11243 operands[1] = gen_lowpart (Pmode, operands[1]);
11244 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11246 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11247 if (Pmode != SImode)
11248 pat = gen_rtx_SUBREG (SImode, pat, 0);
11249 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11253 ;; Rare case of shifting RSP is handled by generating move and shift
11255 [(set (match_operand 0 "register_operand" "")
11256 (ashift (match_operand 1 "register_operand" "")
11257 (match_operand:QI 2 "const_int_operand" "")))
11258 (clobber (reg:CC FLAGS_REG))]
11260 && true_regnum (operands[0]) != true_regnum (operands[1])"
11264 emit_move_insn (operands[0], operands[1]);
11265 pat = gen_rtx_SET (VOIDmode, operands[0],
11266 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11267 operands[0], operands[2]));
11268 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11269 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11273 (define_insn "*ashlsi3_1_zext"
11274 [(set (match_operand:DI 0 "register_operand" "=r,r")
11275 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11276 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11277 (clobber (reg:CC FLAGS_REG))]
11278 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11280 switch (get_attr_type (insn))
11283 gcc_assert (operands[2] == const1_rtx);
11284 return "add{l}\t%k0, %k0";
11290 if (REG_P (operands[2]))
11291 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11292 else if (operands[2] == const1_rtx
11293 && (TARGET_SHIFT1 || optimize_size))
11294 return "sal{l}\t%k0";
11296 return "sal{l}\t{%2, %k0|%k0, %2}";
11299 [(set (attr "type")
11300 (cond [(eq_attr "alternative" "1")
11301 (const_string "lea")
11302 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11304 (match_operand 2 "const1_operand" ""))
11305 (const_string "alu")
11307 (const_string "ishift")))
11308 (set_attr "mode" "SI")])
11310 ;; Convert lea to the lea pattern to avoid flags dependency.
11312 [(set (match_operand:DI 0 "register_operand" "")
11313 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11314 (match_operand:QI 2 "const_int_operand" ""))))
11315 (clobber (reg:CC FLAGS_REG))]
11316 "TARGET_64BIT && reload_completed
11317 && true_regnum (operands[0]) != true_regnum (operands[1])"
11318 [(set (match_dup 0) (zero_extend:DI
11319 (subreg:SI (mult:SI (match_dup 1)
11320 (match_dup 2)) 0)))]
11322 operands[1] = gen_lowpart (Pmode, operands[1]);
11323 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11326 ;; This pattern can't accept a variable shift count, since shifts by
11327 ;; zero don't affect the flags. We assume that shifts by constant
11328 ;; zero are optimized away.
11329 (define_insn "*ashlsi3_cmp"
11330 [(set (reg FLAGS_REG)
11332 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11333 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11335 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11336 (ashift:SI (match_dup 1) (match_dup 2)))]
11338 || !TARGET_PARTIAL_FLAG_REG_STALL
11339 || (operands[2] == const1_rtx
11341 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11342 && ix86_match_ccmode (insn, CCGOCmode)
11343 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11345 switch (get_attr_type (insn))
11348 gcc_assert (operands[2] == const1_rtx);
11349 return "add{l}\t%0, %0";
11352 if (REG_P (operands[2]))
11353 return "sal{l}\t{%b2, %0|%0, %b2}";
11354 else if (operands[2] == const1_rtx
11355 && (TARGET_SHIFT1 || optimize_size))
11356 return "sal{l}\t%0";
11358 return "sal{l}\t{%2, %0|%0, %2}";
11361 [(set (attr "type")
11362 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11364 (match_operand 0 "register_operand" ""))
11365 (match_operand 2 "const1_operand" ""))
11366 (const_string "alu")
11368 (const_string "ishift")))
11369 (set_attr "mode" "SI")])
11371 (define_insn "*ashlsi3_cconly"
11372 [(set (reg FLAGS_REG)
11374 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11375 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11377 (clobber (match_scratch:SI 0 "=r"))]
11379 || !TARGET_PARTIAL_FLAG_REG_STALL
11380 || (operands[2] == const1_rtx
11382 || TARGET_DOUBLE_WITH_ADD)))
11383 && ix86_match_ccmode (insn, CCGOCmode)
11384 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11386 switch (get_attr_type (insn))
11389 gcc_assert (operands[2] == const1_rtx);
11390 return "add{l}\t%0, %0";
11393 if (REG_P (operands[2]))
11394 return "sal{l}\t{%b2, %0|%0, %b2}";
11395 else if (operands[2] == const1_rtx
11396 && (TARGET_SHIFT1 || optimize_size))
11397 return "sal{l}\t%0";
11399 return "sal{l}\t{%2, %0|%0, %2}";
11402 [(set (attr "type")
11403 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11405 (match_operand 0 "register_operand" ""))
11406 (match_operand 2 "const1_operand" ""))
11407 (const_string "alu")
11409 (const_string "ishift")))
11410 (set_attr "mode" "SI")])
11412 (define_insn "*ashlsi3_cmp_zext"
11413 [(set (reg FLAGS_REG)
11415 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11416 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11418 (set (match_operand:DI 0 "register_operand" "=r")
11419 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11422 || !TARGET_PARTIAL_FLAG_REG_STALL
11423 || (operands[2] == const1_rtx
11425 || TARGET_DOUBLE_WITH_ADD)))
11426 && ix86_match_ccmode (insn, CCGOCmode)
11427 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11429 switch (get_attr_type (insn))
11432 gcc_assert (operands[2] == const1_rtx);
11433 return "add{l}\t%k0, %k0";
11436 if (REG_P (operands[2]))
11437 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11438 else if (operands[2] == const1_rtx
11439 && (TARGET_SHIFT1 || optimize_size))
11440 return "sal{l}\t%k0";
11442 return "sal{l}\t{%2, %k0|%k0, %2}";
11445 [(set (attr "type")
11446 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11448 (match_operand 2 "const1_operand" ""))
11449 (const_string "alu")
11451 (const_string "ishift")))
11452 (set_attr "mode" "SI")])
11454 (define_expand "ashlhi3"
11455 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11456 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11457 (match_operand:QI 2 "nonmemory_operand" "")))
11458 (clobber (reg:CC FLAGS_REG))]
11459 "TARGET_HIMODE_MATH"
11460 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11462 (define_insn "*ashlhi3_1_lea"
11463 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11464 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11465 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11466 (clobber (reg:CC FLAGS_REG))]
11467 "!TARGET_PARTIAL_REG_STALL
11468 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11470 switch (get_attr_type (insn))
11475 gcc_assert (operands[2] == const1_rtx);
11476 return "add{w}\t%0, %0";
11479 if (REG_P (operands[2]))
11480 return "sal{w}\t{%b2, %0|%0, %b2}";
11481 else if (operands[2] == const1_rtx
11482 && (TARGET_SHIFT1 || optimize_size))
11483 return "sal{w}\t%0";
11485 return "sal{w}\t{%2, %0|%0, %2}";
11488 [(set (attr "type")
11489 (cond [(eq_attr "alternative" "1")
11490 (const_string "lea")
11491 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11493 (match_operand 0 "register_operand" ""))
11494 (match_operand 2 "const1_operand" ""))
11495 (const_string "alu")
11497 (const_string "ishift")))
11498 (set_attr "mode" "HI,SI")])
11500 (define_insn "*ashlhi3_1"
11501 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11502 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11503 (match_operand:QI 2 "nonmemory_operand" "cI")))
11504 (clobber (reg:CC FLAGS_REG))]
11505 "TARGET_PARTIAL_REG_STALL
11506 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11508 switch (get_attr_type (insn))
11511 gcc_assert (operands[2] == const1_rtx);
11512 return "add{w}\t%0, %0";
11515 if (REG_P (operands[2]))
11516 return "sal{w}\t{%b2, %0|%0, %b2}";
11517 else if (operands[2] == const1_rtx
11518 && (TARGET_SHIFT1 || optimize_size))
11519 return "sal{w}\t%0";
11521 return "sal{w}\t{%2, %0|%0, %2}";
11524 [(set (attr "type")
11525 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11527 (match_operand 0 "register_operand" ""))
11528 (match_operand 2 "const1_operand" ""))
11529 (const_string "alu")
11531 (const_string "ishift")))
11532 (set_attr "mode" "HI")])
11534 ;; This pattern can't accept a variable shift count, since shifts by
11535 ;; zero don't affect the flags. We assume that shifts by constant
11536 ;; zero are optimized away.
11537 (define_insn "*ashlhi3_cmp"
11538 [(set (reg FLAGS_REG)
11540 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11541 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11543 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11544 (ashift:HI (match_dup 1) (match_dup 2)))]
11546 || !TARGET_PARTIAL_FLAG_REG_STALL
11547 || (operands[2] == const1_rtx
11549 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11550 && ix86_match_ccmode (insn, CCGOCmode)
11551 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11553 switch (get_attr_type (insn))
11556 gcc_assert (operands[2] == const1_rtx);
11557 return "add{w}\t%0, %0";
11560 if (REG_P (operands[2]))
11561 return "sal{w}\t{%b2, %0|%0, %b2}";
11562 else if (operands[2] == const1_rtx
11563 && (TARGET_SHIFT1 || optimize_size))
11564 return "sal{w}\t%0";
11566 return "sal{w}\t{%2, %0|%0, %2}";
11569 [(set (attr "type")
11570 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11572 (match_operand 0 "register_operand" ""))
11573 (match_operand 2 "const1_operand" ""))
11574 (const_string "alu")
11576 (const_string "ishift")))
11577 (set_attr "mode" "HI")])
11579 (define_insn "*ashlhi3_cconly"
11580 [(set (reg FLAGS_REG)
11582 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11583 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11585 (clobber (match_scratch:HI 0 "=r"))]
11587 || !TARGET_PARTIAL_FLAG_REG_STALL
11588 || (operands[2] == const1_rtx
11590 || TARGET_DOUBLE_WITH_ADD)))
11591 && ix86_match_ccmode (insn, CCGOCmode)
11592 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11594 switch (get_attr_type (insn))
11597 gcc_assert (operands[2] == const1_rtx);
11598 return "add{w}\t%0, %0";
11601 if (REG_P (operands[2]))
11602 return "sal{w}\t{%b2, %0|%0, %b2}";
11603 else if (operands[2] == const1_rtx
11604 && (TARGET_SHIFT1 || optimize_size))
11605 return "sal{w}\t%0";
11607 return "sal{w}\t{%2, %0|%0, %2}";
11610 [(set (attr "type")
11611 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11613 (match_operand 0 "register_operand" ""))
11614 (match_operand 2 "const1_operand" ""))
11615 (const_string "alu")
11617 (const_string "ishift")))
11618 (set_attr "mode" "HI")])
11620 (define_expand "ashlqi3"
11621 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11622 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11623 (match_operand:QI 2 "nonmemory_operand" "")))
11624 (clobber (reg:CC FLAGS_REG))]
11625 "TARGET_QIMODE_MATH"
11626 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11628 ;; %%% Potential partial reg stall on alternative 2. What to do?
11630 (define_insn "*ashlqi3_1_lea"
11631 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11632 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11633 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11634 (clobber (reg:CC FLAGS_REG))]
11635 "!TARGET_PARTIAL_REG_STALL
11636 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11638 switch (get_attr_type (insn))
11643 gcc_assert (operands[2] == const1_rtx);
11644 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11645 return "add{l}\t%k0, %k0";
11647 return "add{b}\t%0, %0";
11650 if (REG_P (operands[2]))
11652 if (get_attr_mode (insn) == MODE_SI)
11653 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11655 return "sal{b}\t{%b2, %0|%0, %b2}";
11657 else if (operands[2] == const1_rtx
11658 && (TARGET_SHIFT1 || optimize_size))
11660 if (get_attr_mode (insn) == MODE_SI)
11661 return "sal{l}\t%0";
11663 return "sal{b}\t%0";
11667 if (get_attr_mode (insn) == MODE_SI)
11668 return "sal{l}\t{%2, %k0|%k0, %2}";
11670 return "sal{b}\t{%2, %0|%0, %2}";
11674 [(set (attr "type")
11675 (cond [(eq_attr "alternative" "2")
11676 (const_string "lea")
11677 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11679 (match_operand 0 "register_operand" ""))
11680 (match_operand 2 "const1_operand" ""))
11681 (const_string "alu")
11683 (const_string "ishift")))
11684 (set_attr "mode" "QI,SI,SI")])
11686 (define_insn "*ashlqi3_1"
11687 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11688 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11689 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11690 (clobber (reg:CC FLAGS_REG))]
11691 "TARGET_PARTIAL_REG_STALL
11692 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11694 switch (get_attr_type (insn))
11697 gcc_assert (operands[2] == const1_rtx);
11698 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11699 return "add{l}\t%k0, %k0";
11701 return "add{b}\t%0, %0";
11704 if (REG_P (operands[2]))
11706 if (get_attr_mode (insn) == MODE_SI)
11707 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11709 return "sal{b}\t{%b2, %0|%0, %b2}";
11711 else if (operands[2] == const1_rtx
11712 && (TARGET_SHIFT1 || optimize_size))
11714 if (get_attr_mode (insn) == MODE_SI)
11715 return "sal{l}\t%0";
11717 return "sal{b}\t%0";
11721 if (get_attr_mode (insn) == MODE_SI)
11722 return "sal{l}\t{%2, %k0|%k0, %2}";
11724 return "sal{b}\t{%2, %0|%0, %2}";
11728 [(set (attr "type")
11729 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11731 (match_operand 0 "register_operand" ""))
11732 (match_operand 2 "const1_operand" ""))
11733 (const_string "alu")
11735 (const_string "ishift")))
11736 (set_attr "mode" "QI,SI")])
11738 ;; This pattern can't accept a variable shift count, since shifts by
11739 ;; zero don't affect the flags. We assume that shifts by constant
11740 ;; zero are optimized away.
11741 (define_insn "*ashlqi3_cmp"
11742 [(set (reg FLAGS_REG)
11744 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11745 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11747 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11748 (ashift:QI (match_dup 1) (match_dup 2)))]
11750 || !TARGET_PARTIAL_FLAG_REG_STALL
11751 || (operands[2] == const1_rtx
11753 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11754 && ix86_match_ccmode (insn, CCGOCmode)
11755 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11757 switch (get_attr_type (insn))
11760 gcc_assert (operands[2] == const1_rtx);
11761 return "add{b}\t%0, %0";
11764 if (REG_P (operands[2]))
11765 return "sal{b}\t{%b2, %0|%0, %b2}";
11766 else if (operands[2] == const1_rtx
11767 && (TARGET_SHIFT1 || optimize_size))
11768 return "sal{b}\t%0";
11770 return "sal{b}\t{%2, %0|%0, %2}";
11773 [(set (attr "type")
11774 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11776 (match_operand 0 "register_operand" ""))
11777 (match_operand 2 "const1_operand" ""))
11778 (const_string "alu")
11780 (const_string "ishift")))
11781 (set_attr "mode" "QI")])
11783 (define_insn "*ashlqi3_cconly"
11784 [(set (reg FLAGS_REG)
11786 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11787 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11789 (clobber (match_scratch:QI 0 "=q"))]
11791 || !TARGET_PARTIAL_FLAG_REG_STALL
11792 || (operands[2] == const1_rtx
11794 || TARGET_DOUBLE_WITH_ADD)))
11795 && ix86_match_ccmode (insn, CCGOCmode)
11796 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11798 switch (get_attr_type (insn))
11801 gcc_assert (operands[2] == const1_rtx);
11802 return "add{b}\t%0, %0";
11805 if (REG_P (operands[2]))
11806 return "sal{b}\t{%b2, %0|%0, %b2}";
11807 else if (operands[2] == const1_rtx
11808 && (TARGET_SHIFT1 || optimize_size))
11809 return "sal{b}\t%0";
11811 return "sal{b}\t{%2, %0|%0, %2}";
11814 [(set (attr "type")
11815 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11817 (match_operand 0 "register_operand" ""))
11818 (match_operand 2 "const1_operand" ""))
11819 (const_string "alu")
11821 (const_string "ishift")))
11822 (set_attr "mode" "QI")])
11824 ;; See comment above `ashldi3' about how this works.
11826 (define_expand "ashrti3"
11827 [(set (match_operand:TI 0 "register_operand" "")
11828 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11829 (match_operand:QI 2 "nonmemory_operand" "")))]
11831 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11833 (define_insn "*ashrti3_1"
11834 [(set (match_operand:TI 0 "register_operand" "=r")
11835 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11836 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11837 (clobber (reg:CC FLAGS_REG))]
11840 [(set_attr "type" "multi")])
11843 [(match_scratch:DI 3 "r")
11844 (parallel [(set (match_operand:TI 0 "register_operand" "")
11845 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11846 (match_operand:QI 2 "nonmemory_operand" "")))
11847 (clobber (reg:CC FLAGS_REG))])
11851 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11854 [(set (match_operand:TI 0 "register_operand" "")
11855 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11856 (match_operand:QI 2 "nonmemory_operand" "")))
11857 (clobber (reg:CC FLAGS_REG))]
11858 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11859 ? epilogue_completed : reload_completed)"
11861 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11863 (define_insn "x86_64_shrd"
11864 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11865 (ior:DI (ashiftrt:DI (match_dup 0)
11866 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11867 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11868 (minus:QI (const_int 64) (match_dup 2)))))
11869 (clobber (reg:CC FLAGS_REG))]
11871 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11872 [(set_attr "type" "ishift")
11873 (set_attr "prefix_0f" "1")
11874 (set_attr "mode" "DI")
11875 (set_attr "athlon_decode" "vector")
11876 (set_attr "amdfam10_decode" "vector")])
11878 (define_expand "ashrdi3"
11879 [(set (match_operand:DI 0 "shiftdi_operand" "")
11880 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11881 (match_operand:QI 2 "nonmemory_operand" "")))]
11883 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11885 (define_insn "*ashrdi3_63_rex64"
11886 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11887 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11888 (match_operand:DI 2 "const_int_operand" "i,i")))
11889 (clobber (reg:CC FLAGS_REG))]
11890 "TARGET_64BIT && INTVAL (operands[2]) == 63
11891 && (TARGET_USE_CLTD || optimize_size)
11892 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11895 sar{q}\t{%2, %0|%0, %2}"
11896 [(set_attr "type" "imovx,ishift")
11897 (set_attr "prefix_0f" "0,*")
11898 (set_attr "length_immediate" "0,*")
11899 (set_attr "modrm" "0,1")
11900 (set_attr "mode" "DI")])
11902 (define_insn "*ashrdi3_1_one_bit_rex64"
11903 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11904 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11905 (match_operand:QI 2 "const1_operand" "")))
11906 (clobber (reg:CC FLAGS_REG))]
11908 && (TARGET_SHIFT1 || optimize_size)
11909 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11911 [(set_attr "type" "ishift")
11912 (set (attr "length")
11913 (if_then_else (match_operand:DI 0 "register_operand" "")
11915 (const_string "*")))])
11917 (define_insn "*ashrdi3_1_rex64"
11918 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11919 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11920 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11921 (clobber (reg:CC FLAGS_REG))]
11922 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11924 sar{q}\t{%2, %0|%0, %2}
11925 sar{q}\t{%b2, %0|%0, %b2}"
11926 [(set_attr "type" "ishift")
11927 (set_attr "mode" "DI")])
11929 ;; This pattern can't accept a variable shift count, since shifts by
11930 ;; zero don't affect the flags. We assume that shifts by constant
11931 ;; zero are optimized away.
11932 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11933 [(set (reg FLAGS_REG)
11935 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11936 (match_operand:QI 2 "const1_operand" ""))
11938 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11939 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11941 && (TARGET_SHIFT1 || optimize_size)
11942 && ix86_match_ccmode (insn, CCGOCmode)
11943 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11945 [(set_attr "type" "ishift")
11946 (set (attr "length")
11947 (if_then_else (match_operand:DI 0 "register_operand" "")
11949 (const_string "*")))])
11951 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11952 [(set (reg FLAGS_REG)
11954 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11955 (match_operand:QI 2 "const1_operand" ""))
11957 (clobber (match_scratch:DI 0 "=r"))]
11959 && (TARGET_SHIFT1 || optimize_size)
11960 && ix86_match_ccmode (insn, CCGOCmode)
11961 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11963 [(set_attr "type" "ishift")
11964 (set_attr "length" "2")])
11966 ;; This pattern can't accept a variable shift count, since shifts by
11967 ;; zero don't affect the flags. We assume that shifts by constant
11968 ;; zero are optimized away.
11969 (define_insn "*ashrdi3_cmp_rex64"
11970 [(set (reg FLAGS_REG)
11972 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11973 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11975 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11976 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11978 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11979 && ix86_match_ccmode (insn, CCGOCmode)
11980 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11981 "sar{q}\t{%2, %0|%0, %2}"
11982 [(set_attr "type" "ishift")
11983 (set_attr "mode" "DI")])
11985 (define_insn "*ashrdi3_cconly_rex64"
11986 [(set (reg FLAGS_REG)
11988 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11989 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11991 (clobber (match_scratch:DI 0 "=r"))]
11993 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11994 && ix86_match_ccmode (insn, CCGOCmode)
11995 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11996 "sar{q}\t{%2, %0|%0, %2}"
11997 [(set_attr "type" "ishift")
11998 (set_attr "mode" "DI")])
12000 (define_insn "*ashrdi3_1"
12001 [(set (match_operand:DI 0 "register_operand" "=r")
12002 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12003 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12004 (clobber (reg:CC FLAGS_REG))]
12007 [(set_attr "type" "multi")])
12009 ;; By default we don't ask for a scratch register, because when DImode
12010 ;; values are manipulated, registers are already at a premium. But if
12011 ;; we have one handy, we won't turn it away.
12013 [(match_scratch:SI 3 "r")
12014 (parallel [(set (match_operand:DI 0 "register_operand" "")
12015 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12016 (match_operand:QI 2 "nonmemory_operand" "")))
12017 (clobber (reg:CC FLAGS_REG))])
12019 "!TARGET_64BIT && TARGET_CMOVE"
12021 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12024 [(set (match_operand:DI 0 "register_operand" "")
12025 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12026 (match_operand:QI 2 "nonmemory_operand" "")))
12027 (clobber (reg:CC FLAGS_REG))]
12028 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12029 ? epilogue_completed : reload_completed)"
12031 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12033 (define_insn "x86_shrd"
12034 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12035 (ior:SI (ashiftrt:SI (match_dup 0)
12036 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12037 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12038 (minus:QI (const_int 32) (match_dup 2)))))
12039 (clobber (reg:CC FLAGS_REG))]
12041 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12042 [(set_attr "type" "ishift")
12043 (set_attr "prefix_0f" "1")
12044 (set_attr "pent_pair" "np")
12045 (set_attr "mode" "SI")])
12047 (define_expand "x86_shift_adj_3"
12048 [(use (match_operand:SI 0 "register_operand" ""))
12049 (use (match_operand:SI 1 "register_operand" ""))
12050 (use (match_operand:QI 2 "register_operand" ""))]
12053 rtx label = gen_label_rtx ();
12056 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12058 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12059 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12060 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12061 gen_rtx_LABEL_REF (VOIDmode, label),
12063 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12064 JUMP_LABEL (tmp) = label;
12066 emit_move_insn (operands[0], operands[1]);
12067 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12069 emit_label (label);
12070 LABEL_NUSES (label) = 1;
12075 (define_insn "ashrsi3_31"
12076 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12077 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12078 (match_operand:SI 2 "const_int_operand" "i,i")))
12079 (clobber (reg:CC FLAGS_REG))]
12080 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12081 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12084 sar{l}\t{%2, %0|%0, %2}"
12085 [(set_attr "type" "imovx,ishift")
12086 (set_attr "prefix_0f" "0,*")
12087 (set_attr "length_immediate" "0,*")
12088 (set_attr "modrm" "0,1")
12089 (set_attr "mode" "SI")])
12091 (define_insn "*ashrsi3_31_zext"
12092 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12093 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12094 (match_operand:SI 2 "const_int_operand" "i,i"))))
12095 (clobber (reg:CC FLAGS_REG))]
12096 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12097 && INTVAL (operands[2]) == 31
12098 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12101 sar{l}\t{%2, %k0|%k0, %2}"
12102 [(set_attr "type" "imovx,ishift")
12103 (set_attr "prefix_0f" "0,*")
12104 (set_attr "length_immediate" "0,*")
12105 (set_attr "modrm" "0,1")
12106 (set_attr "mode" "SI")])
12108 (define_expand "ashrsi3"
12109 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12110 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12111 (match_operand:QI 2 "nonmemory_operand" "")))
12112 (clobber (reg:CC FLAGS_REG))]
12114 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12116 (define_insn "*ashrsi3_1_one_bit"
12117 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12118 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12119 (match_operand:QI 2 "const1_operand" "")))
12120 (clobber (reg:CC FLAGS_REG))]
12121 "(TARGET_SHIFT1 || optimize_size)
12122 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12124 [(set_attr "type" "ishift")
12125 (set (attr "length")
12126 (if_then_else (match_operand:SI 0 "register_operand" "")
12128 (const_string "*")))])
12130 (define_insn "*ashrsi3_1_one_bit_zext"
12131 [(set (match_operand:DI 0 "register_operand" "=r")
12132 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12133 (match_operand:QI 2 "const1_operand" ""))))
12134 (clobber (reg:CC FLAGS_REG))]
12136 && (TARGET_SHIFT1 || optimize_size)
12137 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12139 [(set_attr "type" "ishift")
12140 (set_attr "length" "2")])
12142 (define_insn "*ashrsi3_1"
12143 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12144 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12145 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12149 sar{l}\t{%2, %0|%0, %2}
12150 sar{l}\t{%b2, %0|%0, %b2}"
12151 [(set_attr "type" "ishift")
12152 (set_attr "mode" "SI")])
12154 (define_insn "*ashrsi3_1_zext"
12155 [(set (match_operand:DI 0 "register_operand" "=r,r")
12156 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12157 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12158 (clobber (reg:CC FLAGS_REG))]
12159 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12161 sar{l}\t{%2, %k0|%k0, %2}
12162 sar{l}\t{%b2, %k0|%k0, %b2}"
12163 [(set_attr "type" "ishift")
12164 (set_attr "mode" "SI")])
12166 ;; This pattern can't accept a variable shift count, since shifts by
12167 ;; zero don't affect the flags. We assume that shifts by constant
12168 ;; zero are optimized away.
12169 (define_insn "*ashrsi3_one_bit_cmp"
12170 [(set (reg FLAGS_REG)
12172 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12173 (match_operand:QI 2 "const1_operand" ""))
12175 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12176 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12177 "(TARGET_SHIFT1 || optimize_size)
12178 && ix86_match_ccmode (insn, CCGOCmode)
12179 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12181 [(set_attr "type" "ishift")
12182 (set (attr "length")
12183 (if_then_else (match_operand:SI 0 "register_operand" "")
12185 (const_string "*")))])
12187 (define_insn "*ashrsi3_one_bit_cconly"
12188 [(set (reg FLAGS_REG)
12190 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12191 (match_operand:QI 2 "const1_operand" ""))
12193 (clobber (match_scratch:SI 0 "=r"))]
12194 "(TARGET_SHIFT1 || optimize_size)
12195 && ix86_match_ccmode (insn, CCGOCmode)
12196 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12198 [(set_attr "type" "ishift")
12199 (set_attr "length" "2")])
12201 (define_insn "*ashrsi3_one_bit_cmp_zext"
12202 [(set (reg FLAGS_REG)
12204 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12205 (match_operand:QI 2 "const1_operand" ""))
12207 (set (match_operand:DI 0 "register_operand" "=r")
12208 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12210 && (TARGET_SHIFT1 || optimize_size)
12211 && ix86_match_ccmode (insn, CCmode)
12212 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12214 [(set_attr "type" "ishift")
12215 (set_attr "length" "2")])
12217 ;; This pattern can't accept a variable shift count, since shifts by
12218 ;; zero don't affect the flags. We assume that shifts by constant
12219 ;; zero are optimized away.
12220 (define_insn "*ashrsi3_cmp"
12221 [(set (reg FLAGS_REG)
12223 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12224 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12226 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12227 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12228 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12229 && ix86_match_ccmode (insn, CCGOCmode)
12230 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12231 "sar{l}\t{%2, %0|%0, %2}"
12232 [(set_attr "type" "ishift")
12233 (set_attr "mode" "SI")])
12235 (define_insn "*ashrsi3_cconly"
12236 [(set (reg FLAGS_REG)
12238 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12239 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12241 (clobber (match_scratch:SI 0 "=r"))]
12242 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12243 && ix86_match_ccmode (insn, CCGOCmode)
12244 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12245 "sar{l}\t{%2, %0|%0, %2}"
12246 [(set_attr "type" "ishift")
12247 (set_attr "mode" "SI")])
12249 (define_insn "*ashrsi3_cmp_zext"
12250 [(set (reg FLAGS_REG)
12252 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12253 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12255 (set (match_operand:DI 0 "register_operand" "=r")
12256 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12258 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12259 && ix86_match_ccmode (insn, CCGOCmode)
12260 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12261 "sar{l}\t{%2, %k0|%k0, %2}"
12262 [(set_attr "type" "ishift")
12263 (set_attr "mode" "SI")])
12265 (define_expand "ashrhi3"
12266 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12267 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12268 (match_operand:QI 2 "nonmemory_operand" "")))
12269 (clobber (reg:CC FLAGS_REG))]
12270 "TARGET_HIMODE_MATH"
12271 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12273 (define_insn "*ashrhi3_1_one_bit"
12274 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12275 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12276 (match_operand:QI 2 "const1_operand" "")))
12277 (clobber (reg:CC FLAGS_REG))]
12278 "(TARGET_SHIFT1 || optimize_size)
12279 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12281 [(set_attr "type" "ishift")
12282 (set (attr "length")
12283 (if_then_else (match_operand 0 "register_operand" "")
12285 (const_string "*")))])
12287 (define_insn "*ashrhi3_1"
12288 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12289 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12290 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12291 (clobber (reg:CC FLAGS_REG))]
12292 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12294 sar{w}\t{%2, %0|%0, %2}
12295 sar{w}\t{%b2, %0|%0, %b2}"
12296 [(set_attr "type" "ishift")
12297 (set_attr "mode" "HI")])
12299 ;; This pattern can't accept a variable shift count, since shifts by
12300 ;; zero don't affect the flags. We assume that shifts by constant
12301 ;; zero are optimized away.
12302 (define_insn "*ashrhi3_one_bit_cmp"
12303 [(set (reg FLAGS_REG)
12305 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12306 (match_operand:QI 2 "const1_operand" ""))
12308 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12309 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12310 "(TARGET_SHIFT1 || optimize_size)
12311 && ix86_match_ccmode (insn, CCGOCmode)
12312 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12314 [(set_attr "type" "ishift")
12315 (set (attr "length")
12316 (if_then_else (match_operand 0 "register_operand" "")
12318 (const_string "*")))])
12320 (define_insn "*ashrhi3_one_bit_cconly"
12321 [(set (reg FLAGS_REG)
12323 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12324 (match_operand:QI 2 "const1_operand" ""))
12326 (clobber (match_scratch:HI 0 "=r"))]
12327 "(TARGET_SHIFT1 || optimize_size)
12328 && ix86_match_ccmode (insn, CCGOCmode)
12329 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12331 [(set_attr "type" "ishift")
12332 (set_attr "length" "2")])
12334 ;; This pattern can't accept a variable shift count, since shifts by
12335 ;; zero don't affect the flags. We assume that shifts by constant
12336 ;; zero are optimized away.
12337 (define_insn "*ashrhi3_cmp"
12338 [(set (reg FLAGS_REG)
12340 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12341 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12343 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12344 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12345 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12346 && ix86_match_ccmode (insn, CCGOCmode)
12347 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12348 "sar{w}\t{%2, %0|%0, %2}"
12349 [(set_attr "type" "ishift")
12350 (set_attr "mode" "HI")])
12352 (define_insn "*ashrhi3_cconly"
12353 [(set (reg FLAGS_REG)
12355 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12356 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12358 (clobber (match_scratch:HI 0 "=r"))]
12359 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12360 && ix86_match_ccmode (insn, CCGOCmode)
12361 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12362 "sar{w}\t{%2, %0|%0, %2}"
12363 [(set_attr "type" "ishift")
12364 (set_attr "mode" "HI")])
12366 (define_expand "ashrqi3"
12367 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12368 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12369 (match_operand:QI 2 "nonmemory_operand" "")))
12370 (clobber (reg:CC FLAGS_REG))]
12371 "TARGET_QIMODE_MATH"
12372 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12374 (define_insn "*ashrqi3_1_one_bit"
12375 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12376 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12377 (match_operand:QI 2 "const1_operand" "")))
12378 (clobber (reg:CC FLAGS_REG))]
12379 "(TARGET_SHIFT1 || optimize_size)
12380 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12382 [(set_attr "type" "ishift")
12383 (set (attr "length")
12384 (if_then_else (match_operand 0 "register_operand" "")
12386 (const_string "*")))])
12388 (define_insn "*ashrqi3_1_one_bit_slp"
12389 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12390 (ashiftrt:QI (match_dup 0)
12391 (match_operand:QI 1 "const1_operand" "")))
12392 (clobber (reg:CC FLAGS_REG))]
12393 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12394 && (TARGET_SHIFT1 || optimize_size)
12395 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12397 [(set_attr "type" "ishift1")
12398 (set (attr "length")
12399 (if_then_else (match_operand 0 "register_operand" "")
12401 (const_string "*")))])
12403 (define_insn "*ashrqi3_1"
12404 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12405 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12406 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12407 (clobber (reg:CC FLAGS_REG))]
12408 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12410 sar{b}\t{%2, %0|%0, %2}
12411 sar{b}\t{%b2, %0|%0, %b2}"
12412 [(set_attr "type" "ishift")
12413 (set_attr "mode" "QI")])
12415 (define_insn "*ashrqi3_1_slp"
12416 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12417 (ashiftrt:QI (match_dup 0)
12418 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12419 (clobber (reg:CC FLAGS_REG))]
12420 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12421 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12423 sar{b}\t{%1, %0|%0, %1}
12424 sar{b}\t{%b1, %0|%0, %b1}"
12425 [(set_attr "type" "ishift1")
12426 (set_attr "mode" "QI")])
12428 ;; This pattern can't accept a variable shift count, since shifts by
12429 ;; zero don't affect the flags. We assume that shifts by constant
12430 ;; zero are optimized away.
12431 (define_insn "*ashrqi3_one_bit_cmp"
12432 [(set (reg FLAGS_REG)
12434 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12435 (match_operand:QI 2 "const1_operand" "I"))
12437 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12438 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12439 "(TARGET_SHIFT1 || optimize_size)
12440 && ix86_match_ccmode (insn, CCGOCmode)
12441 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12443 [(set_attr "type" "ishift")
12444 (set (attr "length")
12445 (if_then_else (match_operand 0 "register_operand" "")
12447 (const_string "*")))])
12449 (define_insn "*ashrqi3_one_bit_cconly"
12450 [(set (reg FLAGS_REG)
12452 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12453 (match_operand:QI 2 "const1_operand" ""))
12455 (clobber (match_scratch:QI 0 "=q"))]
12456 "(TARGET_SHIFT1 || optimize_size)
12457 && ix86_match_ccmode (insn, CCGOCmode)
12458 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12460 [(set_attr "type" "ishift")
12461 (set_attr "length" "2")])
12463 ;; This pattern can't accept a variable shift count, since shifts by
12464 ;; zero don't affect the flags. We assume that shifts by constant
12465 ;; zero are optimized away.
12466 (define_insn "*ashrqi3_cmp"
12467 [(set (reg FLAGS_REG)
12469 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12470 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12472 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12473 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12474 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12475 && ix86_match_ccmode (insn, CCGOCmode)
12476 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12477 "sar{b}\t{%2, %0|%0, %2}"
12478 [(set_attr "type" "ishift")
12479 (set_attr "mode" "QI")])
12481 (define_insn "*ashrqi3_cconly"
12482 [(set (reg FLAGS_REG)
12484 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12485 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12487 (clobber (match_scratch:QI 0 "=q"))]
12488 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12489 && ix86_match_ccmode (insn, CCGOCmode)
12490 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12491 "sar{b}\t{%2, %0|%0, %2}"
12492 [(set_attr "type" "ishift")
12493 (set_attr "mode" "QI")])
12496 ;; Logical shift instructions
12498 ;; See comment above `ashldi3' about how this works.
12500 (define_expand "lshrti3"
12501 [(set (match_operand:TI 0 "register_operand" "")
12502 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12503 (match_operand:QI 2 "nonmemory_operand" "")))]
12505 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12507 ;; This pattern must be defined before *lshrti3_1 to prevent
12508 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12510 (define_insn "sse2_lshrti3"
12511 [(set (match_operand:TI 0 "register_operand" "=x")
12512 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12513 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12516 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12517 return "psrldq\t{%2, %0|%0, %2}";
12519 [(set_attr "type" "sseishft")
12520 (set_attr "prefix_data16" "1")
12521 (set_attr "mode" "TI")])
12523 (define_insn "*lshrti3_1"
12524 [(set (match_operand:TI 0 "register_operand" "=r")
12525 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12526 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12527 (clobber (reg:CC FLAGS_REG))]
12530 [(set_attr "type" "multi")])
12533 [(match_scratch:DI 3 "r")
12534 (parallel [(set (match_operand:TI 0 "register_operand" "")
12535 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12536 (match_operand:QI 2 "nonmemory_operand" "")))
12537 (clobber (reg:CC FLAGS_REG))])
12541 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12544 [(set (match_operand:TI 0 "register_operand" "")
12545 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12546 (match_operand:QI 2 "nonmemory_operand" "")))
12547 (clobber (reg:CC FLAGS_REG))]
12548 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12549 ? epilogue_completed : reload_completed)"
12551 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12553 (define_expand "lshrdi3"
12554 [(set (match_operand:DI 0 "shiftdi_operand" "")
12555 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12556 (match_operand:QI 2 "nonmemory_operand" "")))]
12558 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12560 (define_insn "*lshrdi3_1_one_bit_rex64"
12561 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12562 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12563 (match_operand:QI 2 "const1_operand" "")))
12564 (clobber (reg:CC FLAGS_REG))]
12566 && (TARGET_SHIFT1 || optimize_size)
12567 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12569 [(set_attr "type" "ishift")
12570 (set (attr "length")
12571 (if_then_else (match_operand:DI 0 "register_operand" "")
12573 (const_string "*")))])
12575 (define_insn "*lshrdi3_1_rex64"
12576 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12577 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12578 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12579 (clobber (reg:CC FLAGS_REG))]
12580 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12582 shr{q}\t{%2, %0|%0, %2}
12583 shr{q}\t{%b2, %0|%0, %b2}"
12584 [(set_attr "type" "ishift")
12585 (set_attr "mode" "DI")])
12587 ;; This pattern can't accept a variable shift count, since shifts by
12588 ;; zero don't affect the flags. We assume that shifts by constant
12589 ;; zero are optimized away.
12590 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12591 [(set (reg FLAGS_REG)
12593 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12594 (match_operand:QI 2 "const1_operand" ""))
12596 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12597 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12599 && (TARGET_SHIFT1 || optimize_size)
12600 && ix86_match_ccmode (insn, CCGOCmode)
12601 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12603 [(set_attr "type" "ishift")
12604 (set (attr "length")
12605 (if_then_else (match_operand:DI 0 "register_operand" "")
12607 (const_string "*")))])
12609 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12610 [(set (reg FLAGS_REG)
12612 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12613 (match_operand:QI 2 "const1_operand" ""))
12615 (clobber (match_scratch:DI 0 "=r"))]
12617 && (TARGET_SHIFT1 || optimize_size)
12618 && ix86_match_ccmode (insn, CCGOCmode)
12619 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12621 [(set_attr "type" "ishift")
12622 (set_attr "length" "2")])
12624 ;; This pattern can't accept a variable shift count, since shifts by
12625 ;; zero don't affect the flags. We assume that shifts by constant
12626 ;; zero are optimized away.
12627 (define_insn "*lshrdi3_cmp_rex64"
12628 [(set (reg FLAGS_REG)
12630 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12631 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12633 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12634 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12636 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12637 && ix86_match_ccmode (insn, CCGOCmode)
12638 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12639 "shr{q}\t{%2, %0|%0, %2}"
12640 [(set_attr "type" "ishift")
12641 (set_attr "mode" "DI")])
12643 (define_insn "*lshrdi3_cconly_rex64"
12644 [(set (reg FLAGS_REG)
12646 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12647 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12649 (clobber (match_scratch:DI 0 "=r"))]
12651 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12652 && ix86_match_ccmode (insn, CCGOCmode)
12653 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12654 "shr{q}\t{%2, %0|%0, %2}"
12655 [(set_attr "type" "ishift")
12656 (set_attr "mode" "DI")])
12658 (define_insn "*lshrdi3_1"
12659 [(set (match_operand:DI 0 "register_operand" "=r")
12660 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12661 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12662 (clobber (reg:CC FLAGS_REG))]
12665 [(set_attr "type" "multi")])
12667 ;; By default we don't ask for a scratch register, because when DImode
12668 ;; values are manipulated, registers are already at a premium. But if
12669 ;; we have one handy, we won't turn it away.
12671 [(match_scratch:SI 3 "r")
12672 (parallel [(set (match_operand:DI 0 "register_operand" "")
12673 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12674 (match_operand:QI 2 "nonmemory_operand" "")))
12675 (clobber (reg:CC FLAGS_REG))])
12677 "!TARGET_64BIT && TARGET_CMOVE"
12679 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12682 [(set (match_operand:DI 0 "register_operand" "")
12683 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12684 (match_operand:QI 2 "nonmemory_operand" "")))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12687 ? epilogue_completed : reload_completed)"
12689 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12691 (define_expand "lshrsi3"
12692 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12693 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12694 (match_operand:QI 2 "nonmemory_operand" "")))
12695 (clobber (reg:CC FLAGS_REG))]
12697 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12699 (define_insn "*lshrsi3_1_one_bit"
12700 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12701 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12702 (match_operand:QI 2 "const1_operand" "")))
12703 (clobber (reg:CC FLAGS_REG))]
12704 "(TARGET_SHIFT1 || optimize_size)
12705 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12707 [(set_attr "type" "ishift")
12708 (set (attr "length")
12709 (if_then_else (match_operand:SI 0 "register_operand" "")
12711 (const_string "*")))])
12713 (define_insn "*lshrsi3_1_one_bit_zext"
12714 [(set (match_operand:DI 0 "register_operand" "=r")
12715 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12716 (match_operand:QI 2 "const1_operand" "")))
12717 (clobber (reg:CC FLAGS_REG))]
12719 && (TARGET_SHIFT1 || optimize_size)
12720 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12722 [(set_attr "type" "ishift")
12723 (set_attr "length" "2")])
12725 (define_insn "*lshrsi3_1"
12726 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12727 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12728 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12729 (clobber (reg:CC FLAGS_REG))]
12730 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12732 shr{l}\t{%2, %0|%0, %2}
12733 shr{l}\t{%b2, %0|%0, %b2}"
12734 [(set_attr "type" "ishift")
12735 (set_attr "mode" "SI")])
12737 (define_insn "*lshrsi3_1_zext"
12738 [(set (match_operand:DI 0 "register_operand" "=r,r")
12740 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12741 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12742 (clobber (reg:CC FLAGS_REG))]
12743 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12745 shr{l}\t{%2, %k0|%k0, %2}
12746 shr{l}\t{%b2, %k0|%k0, %b2}"
12747 [(set_attr "type" "ishift")
12748 (set_attr "mode" "SI")])
12750 ;; This pattern can't accept a variable shift count, since shifts by
12751 ;; zero don't affect the flags. We assume that shifts by constant
12752 ;; zero are optimized away.
12753 (define_insn "*lshrsi3_one_bit_cmp"
12754 [(set (reg FLAGS_REG)
12756 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12757 (match_operand:QI 2 "const1_operand" ""))
12759 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12760 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12761 "(TARGET_SHIFT1 || optimize_size)
12762 && ix86_match_ccmode (insn, CCGOCmode)
12763 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12765 [(set_attr "type" "ishift")
12766 (set (attr "length")
12767 (if_then_else (match_operand:SI 0 "register_operand" "")
12769 (const_string "*")))])
12771 (define_insn "*lshrsi3_one_bit_cconly"
12772 [(set (reg FLAGS_REG)
12774 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12775 (match_operand:QI 2 "const1_operand" ""))
12777 (clobber (match_scratch:SI 0 "=r"))]
12778 "(TARGET_SHIFT1 || optimize_size)
12779 && ix86_match_ccmode (insn, CCGOCmode)
12780 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12782 [(set_attr "type" "ishift")
12783 (set_attr "length" "2")])
12785 (define_insn "*lshrsi3_cmp_one_bit_zext"
12786 [(set (reg FLAGS_REG)
12788 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12789 (match_operand:QI 2 "const1_operand" ""))
12791 (set (match_operand:DI 0 "register_operand" "=r")
12792 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12794 && (TARGET_SHIFT1 || optimize_size)
12795 && ix86_match_ccmode (insn, CCGOCmode)
12796 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12798 [(set_attr "type" "ishift")
12799 (set_attr "length" "2")])
12801 ;; This pattern can't accept a variable shift count, since shifts by
12802 ;; zero don't affect the flags. We assume that shifts by constant
12803 ;; zero are optimized away.
12804 (define_insn "*lshrsi3_cmp"
12805 [(set (reg FLAGS_REG)
12807 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12808 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12810 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12811 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12812 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12813 && ix86_match_ccmode (insn, CCGOCmode)
12814 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12815 "shr{l}\t{%2, %0|%0, %2}"
12816 [(set_attr "type" "ishift")
12817 (set_attr "mode" "SI")])
12819 (define_insn "*lshrsi3_cconly"
12820 [(set (reg FLAGS_REG)
12822 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12823 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12825 (clobber (match_scratch:SI 0 "=r"))]
12826 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12827 && ix86_match_ccmode (insn, CCGOCmode)
12828 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12829 "shr{l}\t{%2, %0|%0, %2}"
12830 [(set_attr "type" "ishift")
12831 (set_attr "mode" "SI")])
12833 (define_insn "*lshrsi3_cmp_zext"
12834 [(set (reg FLAGS_REG)
12836 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12837 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12839 (set (match_operand:DI 0 "register_operand" "=r")
12840 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12842 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12843 && ix86_match_ccmode (insn, CCGOCmode)
12844 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12845 "shr{l}\t{%2, %k0|%k0, %2}"
12846 [(set_attr "type" "ishift")
12847 (set_attr "mode" "SI")])
12849 (define_expand "lshrhi3"
12850 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12851 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12852 (match_operand:QI 2 "nonmemory_operand" "")))
12853 (clobber (reg:CC FLAGS_REG))]
12854 "TARGET_HIMODE_MATH"
12855 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12857 (define_insn "*lshrhi3_1_one_bit"
12858 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12859 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12860 (match_operand:QI 2 "const1_operand" "")))
12861 (clobber (reg:CC FLAGS_REG))]
12862 "(TARGET_SHIFT1 || optimize_size)
12863 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12865 [(set_attr "type" "ishift")
12866 (set (attr "length")
12867 (if_then_else (match_operand 0 "register_operand" "")
12869 (const_string "*")))])
12871 (define_insn "*lshrhi3_1"
12872 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12873 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12874 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12875 (clobber (reg:CC FLAGS_REG))]
12876 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12878 shr{w}\t{%2, %0|%0, %2}
12879 shr{w}\t{%b2, %0|%0, %b2}"
12880 [(set_attr "type" "ishift")
12881 (set_attr "mode" "HI")])
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 "*lshrhi3_one_bit_cmp"
12887 [(set (reg FLAGS_REG)
12889 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12890 (match_operand:QI 2 "const1_operand" ""))
12892 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12893 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12894 "(TARGET_SHIFT1 || optimize_size)
12895 && ix86_match_ccmode (insn, CCGOCmode)
12896 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12898 [(set_attr "type" "ishift")
12899 (set (attr "length")
12900 (if_then_else (match_operand:SI 0 "register_operand" "")
12902 (const_string "*")))])
12904 (define_insn "*lshrhi3_one_bit_cconly"
12905 [(set (reg FLAGS_REG)
12907 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12908 (match_operand:QI 2 "const1_operand" ""))
12910 (clobber (match_scratch:HI 0 "=r"))]
12911 "(TARGET_SHIFT1 || optimize_size)
12912 && ix86_match_ccmode (insn, CCGOCmode)
12913 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12915 [(set_attr "type" "ishift")
12916 (set_attr "length" "2")])
12918 ;; This pattern can't accept a variable shift count, since shifts by
12919 ;; zero don't affect the flags. We assume that shifts by constant
12920 ;; zero are optimized away.
12921 (define_insn "*lshrhi3_cmp"
12922 [(set (reg FLAGS_REG)
12924 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12925 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12927 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12928 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12929 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12930 && ix86_match_ccmode (insn, CCGOCmode)
12931 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12932 "shr{w}\t{%2, %0|%0, %2}"
12933 [(set_attr "type" "ishift")
12934 (set_attr "mode" "HI")])
12936 (define_insn "*lshrhi3_cconly"
12937 [(set (reg FLAGS_REG)
12939 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12940 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12942 (clobber (match_scratch:HI 0 "=r"))]
12943 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12944 && ix86_match_ccmode (insn, CCGOCmode)
12945 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12946 "shr{w}\t{%2, %0|%0, %2}"
12947 [(set_attr "type" "ishift")
12948 (set_attr "mode" "HI")])
12950 (define_expand "lshrqi3"
12951 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12952 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12953 (match_operand:QI 2 "nonmemory_operand" "")))
12954 (clobber (reg:CC FLAGS_REG))]
12955 "TARGET_QIMODE_MATH"
12956 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12958 (define_insn "*lshrqi3_1_one_bit"
12959 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12960 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12961 (match_operand:QI 2 "const1_operand" "")))
12962 (clobber (reg:CC FLAGS_REG))]
12963 "(TARGET_SHIFT1 || optimize_size)
12964 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12966 [(set_attr "type" "ishift")
12967 (set (attr "length")
12968 (if_then_else (match_operand 0 "register_operand" "")
12970 (const_string "*")))])
12972 (define_insn "*lshrqi3_1_one_bit_slp"
12973 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12974 (lshiftrt:QI (match_dup 0)
12975 (match_operand:QI 1 "const1_operand" "")))
12976 (clobber (reg:CC FLAGS_REG))]
12977 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12978 && (TARGET_SHIFT1 || optimize_size)"
12980 [(set_attr "type" "ishift1")
12981 (set (attr "length")
12982 (if_then_else (match_operand 0 "register_operand" "")
12984 (const_string "*")))])
12986 (define_insn "*lshrqi3_1"
12987 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12988 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12989 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12990 (clobber (reg:CC FLAGS_REG))]
12991 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12993 shr{b}\t{%2, %0|%0, %2}
12994 shr{b}\t{%b2, %0|%0, %b2}"
12995 [(set_attr "type" "ishift")
12996 (set_attr "mode" "QI")])
12998 (define_insn "*lshrqi3_1_slp"
12999 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13000 (lshiftrt:QI (match_dup 0)
13001 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13002 (clobber (reg:CC FLAGS_REG))]
13003 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13004 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13006 shr{b}\t{%1, %0|%0, %1}
13007 shr{b}\t{%b1, %0|%0, %b1}"
13008 [(set_attr "type" "ishift1")
13009 (set_attr "mode" "QI")])
13011 ;; This pattern can't accept a variable shift count, since shifts by
13012 ;; zero don't affect the flags. We assume that shifts by constant
13013 ;; zero are optimized away.
13014 (define_insn "*lshrqi2_one_bit_cmp"
13015 [(set (reg FLAGS_REG)
13017 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13018 (match_operand:QI 2 "const1_operand" ""))
13020 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13021 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13022 "(TARGET_SHIFT1 || optimize_size)
13023 && ix86_match_ccmode (insn, CCGOCmode)
13024 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13026 [(set_attr "type" "ishift")
13027 (set (attr "length")
13028 (if_then_else (match_operand:SI 0 "register_operand" "")
13030 (const_string "*")))])
13032 (define_insn "*lshrqi2_one_bit_cconly"
13033 [(set (reg FLAGS_REG)
13035 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13036 (match_operand:QI 2 "const1_operand" ""))
13038 (clobber (match_scratch:QI 0 "=q"))]
13039 "(TARGET_SHIFT1 || optimize_size)
13040 && ix86_match_ccmode (insn, CCGOCmode)
13041 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13043 [(set_attr "type" "ishift")
13044 (set_attr "length" "2")])
13046 ;; This pattern can't accept a variable shift count, since shifts by
13047 ;; zero don't affect the flags. We assume that shifts by constant
13048 ;; zero are optimized away.
13049 (define_insn "*lshrqi2_cmp"
13050 [(set (reg FLAGS_REG)
13052 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13053 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13055 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13056 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13057 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13058 && ix86_match_ccmode (insn, CCGOCmode)
13059 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13060 "shr{b}\t{%2, %0|%0, %2}"
13061 [(set_attr "type" "ishift")
13062 (set_attr "mode" "QI")])
13064 (define_insn "*lshrqi2_cconly"
13065 [(set (reg FLAGS_REG)
13067 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13068 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13070 (clobber (match_scratch:QI 0 "=q"))]
13071 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13072 && ix86_match_ccmode (insn, CCGOCmode)
13073 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13074 "shr{b}\t{%2, %0|%0, %2}"
13075 [(set_attr "type" "ishift")
13076 (set_attr "mode" "QI")])
13078 ;; Rotate instructions
13080 (define_expand "rotldi3"
13081 [(set (match_operand:DI 0 "shiftdi_operand" "")
13082 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13083 (match_operand:QI 2 "nonmemory_operand" "")))
13084 (clobber (reg:CC FLAGS_REG))]
13089 ix86_expand_binary_operator (ROTATE, DImode, operands);
13092 if (!const_1_to_31_operand (operands[2], VOIDmode))
13094 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13098 ;; Implement rotation using two double-precision shift instructions
13099 ;; and a scratch register.
13100 (define_insn_and_split "ix86_rotldi3"
13101 [(set (match_operand:DI 0 "register_operand" "=r")
13102 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13103 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13104 (clobber (reg:CC FLAGS_REG))
13105 (clobber (match_scratch:SI 3 "=&r"))]
13108 "&& reload_completed"
13109 [(set (match_dup 3) (match_dup 4))
13111 [(set (match_dup 4)
13112 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13113 (lshiftrt:SI (match_dup 5)
13114 (minus:QI (const_int 32) (match_dup 2)))))
13115 (clobber (reg:CC FLAGS_REG))])
13117 [(set (match_dup 5)
13118 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13119 (lshiftrt:SI (match_dup 3)
13120 (minus:QI (const_int 32) (match_dup 2)))))
13121 (clobber (reg:CC FLAGS_REG))])]
13122 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13124 (define_insn "*rotlsi3_1_one_bit_rex64"
13125 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13126 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13127 (match_operand:QI 2 "const1_operand" "")))
13128 (clobber (reg:CC FLAGS_REG))]
13130 && (TARGET_SHIFT1 || optimize_size)
13131 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13133 [(set_attr "type" "rotate")
13134 (set (attr "length")
13135 (if_then_else (match_operand:DI 0 "register_operand" "")
13137 (const_string "*")))])
13139 (define_insn "*rotldi3_1_rex64"
13140 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13141 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13142 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13143 (clobber (reg:CC FLAGS_REG))]
13144 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13146 rol{q}\t{%2, %0|%0, %2}
13147 rol{q}\t{%b2, %0|%0, %b2}"
13148 [(set_attr "type" "rotate")
13149 (set_attr "mode" "DI")])
13151 (define_expand "rotlsi3"
13152 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13153 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13154 (match_operand:QI 2 "nonmemory_operand" "")))
13155 (clobber (reg:CC FLAGS_REG))]
13157 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13159 (define_insn "*rotlsi3_1_one_bit"
13160 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13161 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13162 (match_operand:QI 2 "const1_operand" "")))
13163 (clobber (reg:CC FLAGS_REG))]
13164 "(TARGET_SHIFT1 || optimize_size)
13165 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13167 [(set_attr "type" "rotate")
13168 (set (attr "length")
13169 (if_then_else (match_operand:SI 0 "register_operand" "")
13171 (const_string "*")))])
13173 (define_insn "*rotlsi3_1_one_bit_zext"
13174 [(set (match_operand:DI 0 "register_operand" "=r")
13176 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13177 (match_operand:QI 2 "const1_operand" ""))))
13178 (clobber (reg:CC FLAGS_REG))]
13180 && (TARGET_SHIFT1 || optimize_size)
13181 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13183 [(set_attr "type" "rotate")
13184 (set_attr "length" "2")])
13186 (define_insn "*rotlsi3_1"
13187 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13188 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13189 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13190 (clobber (reg:CC FLAGS_REG))]
13191 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13193 rol{l}\t{%2, %0|%0, %2}
13194 rol{l}\t{%b2, %0|%0, %b2}"
13195 [(set_attr "type" "rotate")
13196 (set_attr "mode" "SI")])
13198 (define_insn "*rotlsi3_1_zext"
13199 [(set (match_operand:DI 0 "register_operand" "=r,r")
13201 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13202 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13203 (clobber (reg:CC FLAGS_REG))]
13204 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13206 rol{l}\t{%2, %k0|%k0, %2}
13207 rol{l}\t{%b2, %k0|%k0, %b2}"
13208 [(set_attr "type" "rotate")
13209 (set_attr "mode" "SI")])
13211 (define_expand "rotlhi3"
13212 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13213 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13214 (match_operand:QI 2 "nonmemory_operand" "")))
13215 (clobber (reg:CC FLAGS_REG))]
13216 "TARGET_HIMODE_MATH"
13217 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13219 (define_insn "*rotlhi3_1_one_bit"
13220 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13221 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13222 (match_operand:QI 2 "const1_operand" "")))
13223 (clobber (reg:CC FLAGS_REG))]
13224 "(TARGET_SHIFT1 || optimize_size)
13225 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13227 [(set_attr "type" "rotate")
13228 (set (attr "length")
13229 (if_then_else (match_operand 0 "register_operand" "")
13231 (const_string "*")))])
13233 (define_insn "*rotlhi3_1"
13234 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13235 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13236 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13237 (clobber (reg:CC FLAGS_REG))]
13238 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13240 rol{w}\t{%2, %0|%0, %2}
13241 rol{w}\t{%b2, %0|%0, %b2}"
13242 [(set_attr "type" "rotate")
13243 (set_attr "mode" "HI")])
13246 [(set (match_operand:HI 0 "register_operand" "")
13247 (rotate:HI (match_dup 0) (const_int 8)))
13248 (clobber (reg:CC FLAGS_REG))]
13250 [(parallel [(set (strict_low_part (match_dup 0))
13251 (bswap:HI (match_dup 0)))
13252 (clobber (reg:CC FLAGS_REG))])]
13255 (define_expand "rotlqi3"
13256 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13257 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13258 (match_operand:QI 2 "nonmemory_operand" "")))
13259 (clobber (reg:CC FLAGS_REG))]
13260 "TARGET_QIMODE_MATH"
13261 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13263 (define_insn "*rotlqi3_1_one_bit_slp"
13264 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13265 (rotate:QI (match_dup 0)
13266 (match_operand:QI 1 "const1_operand" "")))
13267 (clobber (reg:CC FLAGS_REG))]
13268 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13269 && (TARGET_SHIFT1 || optimize_size)"
13271 [(set_attr "type" "rotate1")
13272 (set (attr "length")
13273 (if_then_else (match_operand 0 "register_operand" "")
13275 (const_string "*")))])
13277 (define_insn "*rotlqi3_1_one_bit"
13278 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13279 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13280 (match_operand:QI 2 "const1_operand" "")))
13281 (clobber (reg:CC FLAGS_REG))]
13282 "(TARGET_SHIFT1 || optimize_size)
13283 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13285 [(set_attr "type" "rotate")
13286 (set (attr "length")
13287 (if_then_else (match_operand 0 "register_operand" "")
13289 (const_string "*")))])
13291 (define_insn "*rotlqi3_1_slp"
13292 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13293 (rotate: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_size)
13297 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13299 rol{b}\t{%1, %0|%0, %1}
13300 rol{b}\t{%b1, %0|%0, %b1}"
13301 [(set_attr "type" "rotate1")
13302 (set_attr "mode" "QI")])
13304 (define_insn "*rotlqi3_1"
13305 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13306 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13307 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13308 (clobber (reg:CC FLAGS_REG))]
13309 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13311 rol{b}\t{%2, %0|%0, %2}
13312 rol{b}\t{%b2, %0|%0, %b2}"
13313 [(set_attr "type" "rotate")
13314 (set_attr "mode" "QI")])
13316 (define_expand "rotrdi3"
13317 [(set (match_operand:DI 0 "shiftdi_operand" "")
13318 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13319 (match_operand:QI 2 "nonmemory_operand" "")))
13320 (clobber (reg:CC FLAGS_REG))]
13325 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13328 if (!const_1_to_31_operand (operands[2], VOIDmode))
13330 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13334 ;; Implement rotation using two double-precision shift instructions
13335 ;; and a scratch register.
13336 (define_insn_and_split "ix86_rotrdi3"
13337 [(set (match_operand:DI 0 "register_operand" "=r")
13338 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13339 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13340 (clobber (reg:CC FLAGS_REG))
13341 (clobber (match_scratch:SI 3 "=&r"))]
13344 "&& reload_completed"
13345 [(set (match_dup 3) (match_dup 4))
13347 [(set (match_dup 4)
13348 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13349 (ashift:SI (match_dup 5)
13350 (minus:QI (const_int 32) (match_dup 2)))))
13351 (clobber (reg:CC FLAGS_REG))])
13353 [(set (match_dup 5)
13354 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13355 (ashift:SI (match_dup 3)
13356 (minus:QI (const_int 32) (match_dup 2)))))
13357 (clobber (reg:CC FLAGS_REG))])]
13358 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13360 (define_insn "*rotrdi3_1_one_bit_rex64"
13361 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13362 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13363 (match_operand:QI 2 "const1_operand" "")))
13364 (clobber (reg:CC FLAGS_REG))]
13366 && (TARGET_SHIFT1 || optimize_size)
13367 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13369 [(set_attr "type" "rotate")
13370 (set (attr "length")
13371 (if_then_else (match_operand:DI 0 "register_operand" "")
13373 (const_string "*")))])
13375 (define_insn "*rotrdi3_1_rex64"
13376 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13377 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13378 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13379 (clobber (reg:CC FLAGS_REG))]
13380 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13382 ror{q}\t{%2, %0|%0, %2}
13383 ror{q}\t{%b2, %0|%0, %b2}"
13384 [(set_attr "type" "rotate")
13385 (set_attr "mode" "DI")])
13387 (define_expand "rotrsi3"
13388 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13389 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13390 (match_operand:QI 2 "nonmemory_operand" "")))
13391 (clobber (reg:CC FLAGS_REG))]
13393 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13395 (define_insn "*rotrsi3_1_one_bit"
13396 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13397 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13398 (match_operand:QI 2 "const1_operand" "")))
13399 (clobber (reg:CC FLAGS_REG))]
13400 "(TARGET_SHIFT1 || optimize_size)
13401 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13403 [(set_attr "type" "rotate")
13404 (set (attr "length")
13405 (if_then_else (match_operand:SI 0 "register_operand" "")
13407 (const_string "*")))])
13409 (define_insn "*rotrsi3_1_one_bit_zext"
13410 [(set (match_operand:DI 0 "register_operand" "=r")
13412 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13413 (match_operand:QI 2 "const1_operand" ""))))
13414 (clobber (reg:CC FLAGS_REG))]
13416 && (TARGET_SHIFT1 || optimize_size)
13417 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13419 [(set_attr "type" "rotate")
13420 (set (attr "length")
13421 (if_then_else (match_operand:SI 0 "register_operand" "")
13423 (const_string "*")))])
13425 (define_insn "*rotrsi3_1"
13426 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13427 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13428 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13429 (clobber (reg:CC FLAGS_REG))]
13430 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13432 ror{l}\t{%2, %0|%0, %2}
13433 ror{l}\t{%b2, %0|%0, %b2}"
13434 [(set_attr "type" "rotate")
13435 (set_attr "mode" "SI")])
13437 (define_insn "*rotrsi3_1_zext"
13438 [(set (match_operand:DI 0 "register_operand" "=r,r")
13440 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13441 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13442 (clobber (reg:CC FLAGS_REG))]
13443 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13445 ror{l}\t{%2, %k0|%k0, %2}
13446 ror{l}\t{%b2, %k0|%k0, %b2}"
13447 [(set_attr "type" "rotate")
13448 (set_attr "mode" "SI")])
13450 (define_expand "rotrhi3"
13451 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13452 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13453 (match_operand:QI 2 "nonmemory_operand" "")))
13454 (clobber (reg:CC FLAGS_REG))]
13455 "TARGET_HIMODE_MATH"
13456 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13458 (define_insn "*rotrhi3_one_bit"
13459 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13460 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13461 (match_operand:QI 2 "const1_operand" "")))
13462 (clobber (reg:CC FLAGS_REG))]
13463 "(TARGET_SHIFT1 || optimize_size)
13464 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13466 [(set_attr "type" "rotate")
13467 (set (attr "length")
13468 (if_then_else (match_operand 0 "register_operand" "")
13470 (const_string "*")))])
13472 (define_insn "*rotrhi3_1"
13473 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13474 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13475 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13476 (clobber (reg:CC FLAGS_REG))]
13477 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13479 ror{w}\t{%2, %0|%0, %2}
13480 ror{w}\t{%b2, %0|%0, %b2}"
13481 [(set_attr "type" "rotate")
13482 (set_attr "mode" "HI")])
13485 [(set (match_operand:HI 0 "register_operand" "")
13486 (rotatert:HI (match_dup 0) (const_int 8)))
13487 (clobber (reg:CC FLAGS_REG))]
13489 [(parallel [(set (strict_low_part (match_dup 0))
13490 (bswap:HI (match_dup 0)))
13491 (clobber (reg:CC FLAGS_REG))])]
13494 (define_expand "rotrqi3"
13495 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13496 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13497 (match_operand:QI 2 "nonmemory_operand" "")))
13498 (clobber (reg:CC FLAGS_REG))]
13499 "TARGET_QIMODE_MATH"
13500 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13502 (define_insn "*rotrqi3_1_one_bit"
13503 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13504 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13505 (match_operand:QI 2 "const1_operand" "")))
13506 (clobber (reg:CC FLAGS_REG))]
13507 "(TARGET_SHIFT1 || optimize_size)
13508 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13510 [(set_attr "type" "rotate")
13511 (set (attr "length")
13512 (if_then_else (match_operand 0 "register_operand" "")
13514 (const_string "*")))])
13516 (define_insn "*rotrqi3_1_one_bit_slp"
13517 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13518 (rotatert:QI (match_dup 0)
13519 (match_operand:QI 1 "const1_operand" "")))
13520 (clobber (reg:CC FLAGS_REG))]
13521 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13522 && (TARGET_SHIFT1 || optimize_size)"
13524 [(set_attr "type" "rotate1")
13525 (set (attr "length")
13526 (if_then_else (match_operand 0 "register_operand" "")
13528 (const_string "*")))])
13530 (define_insn "*rotrqi3_1"
13531 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13532 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13533 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13534 (clobber (reg:CC FLAGS_REG))]
13535 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13537 ror{b}\t{%2, %0|%0, %2}
13538 ror{b}\t{%b2, %0|%0, %b2}"
13539 [(set_attr "type" "rotate")
13540 (set_attr "mode" "QI")])
13542 (define_insn "*rotrqi3_1_slp"
13543 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13544 (rotatert:QI (match_dup 0)
13545 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13546 (clobber (reg:CC FLAGS_REG))]
13547 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13548 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13550 ror{b}\t{%1, %0|%0, %1}
13551 ror{b}\t{%b1, %0|%0, %b1}"
13552 [(set_attr "type" "rotate1")
13553 (set_attr "mode" "QI")])
13555 ;; Bit set / bit test instructions
13557 (define_expand "extv"
13558 [(set (match_operand:SI 0 "register_operand" "")
13559 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13560 (match_operand:SI 2 "const8_operand" "")
13561 (match_operand:SI 3 "const8_operand" "")))]
13564 /* Handle extractions from %ah et al. */
13565 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13568 /* From mips.md: extract_bit_field doesn't verify that our source
13569 matches the predicate, so check it again here. */
13570 if (! ext_register_operand (operands[1], VOIDmode))
13574 (define_expand "extzv"
13575 [(set (match_operand:SI 0 "register_operand" "")
13576 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13577 (match_operand:SI 2 "const8_operand" "")
13578 (match_operand:SI 3 "const8_operand" "")))]
13581 /* Handle extractions from %ah et al. */
13582 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13585 /* From mips.md: extract_bit_field doesn't verify that our source
13586 matches the predicate, so check it again here. */
13587 if (! ext_register_operand (operands[1], VOIDmode))
13591 (define_expand "insv"
13592 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13593 (match_operand 1 "const8_operand" "")
13594 (match_operand 2 "const8_operand" ""))
13595 (match_operand 3 "register_operand" ""))]
13598 /* Handle insertions to %ah et al. */
13599 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13602 /* From mips.md: insert_bit_field doesn't verify that our source
13603 matches the predicate, so check it again here. */
13604 if (! ext_register_operand (operands[0], VOIDmode))
13608 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13610 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13615 ;; %%% bts, btr, btc, bt.
13616 ;; In general these instructions are *slow* when applied to memory,
13617 ;; since they enforce atomic operation. When applied to registers,
13618 ;; it depends on the cpu implementation. They're never faster than
13619 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13620 ;; no point. But in 64-bit, we can't hold the relevant immediates
13621 ;; within the instruction itself, so operating on bits in the high
13622 ;; 32-bits of a register becomes easier.
13624 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13625 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13626 ;; negdf respectively, so they can never be disabled entirely.
13628 (define_insn "*btsq"
13629 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13631 (match_operand:DI 1 "const_0_to_63_operand" ""))
13633 (clobber (reg:CC FLAGS_REG))]
13634 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13635 "bts{q}\t{%1, %0|%0, %1}"
13636 [(set_attr "type" "alu1")])
13638 (define_insn "*btrq"
13639 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13641 (match_operand:DI 1 "const_0_to_63_operand" ""))
13643 (clobber (reg:CC FLAGS_REG))]
13644 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13645 "btr{q}\t{%1, %0|%0, %1}"
13646 [(set_attr "type" "alu1")])
13648 (define_insn "*btcq"
13649 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13651 (match_operand:DI 1 "const_0_to_63_operand" ""))
13652 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13653 (clobber (reg:CC FLAGS_REG))]
13654 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13655 "btc{q}\t{%1, %0|%0, %1}"
13656 [(set_attr "type" "alu1")])
13658 ;; Allow Nocona to avoid these instructions if a register is available.
13661 [(match_scratch:DI 2 "r")
13662 (parallel [(set (zero_extract:DI
13663 (match_operand:DI 0 "register_operand" "")
13665 (match_operand:DI 1 "const_0_to_63_operand" ""))
13667 (clobber (reg:CC FLAGS_REG))])]
13668 "TARGET_64BIT && !TARGET_USE_BT"
13671 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13674 if (HOST_BITS_PER_WIDE_INT >= 64)
13675 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13676 else if (i < HOST_BITS_PER_WIDE_INT)
13677 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13679 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13681 op1 = immed_double_const (lo, hi, DImode);
13684 emit_move_insn (operands[2], op1);
13688 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13693 [(match_scratch:DI 2 "r")
13694 (parallel [(set (zero_extract:DI
13695 (match_operand:DI 0 "register_operand" "")
13697 (match_operand:DI 1 "const_0_to_63_operand" ""))
13699 (clobber (reg:CC FLAGS_REG))])]
13700 "TARGET_64BIT && !TARGET_USE_BT"
13703 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13706 if (HOST_BITS_PER_WIDE_INT >= 64)
13707 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13708 else if (i < HOST_BITS_PER_WIDE_INT)
13709 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13711 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13713 op1 = immed_double_const (~lo, ~hi, DImode);
13716 emit_move_insn (operands[2], op1);
13720 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13725 [(match_scratch:DI 2 "r")
13726 (parallel [(set (zero_extract:DI
13727 (match_operand:DI 0 "register_operand" "")
13729 (match_operand:DI 1 "const_0_to_63_operand" ""))
13730 (not:DI (zero_extract:DI
13731 (match_dup 0) (const_int 1) (match_dup 1))))
13732 (clobber (reg:CC FLAGS_REG))])]
13733 "TARGET_64BIT && !TARGET_USE_BT"
13736 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13739 if (HOST_BITS_PER_WIDE_INT >= 64)
13740 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13741 else if (i < HOST_BITS_PER_WIDE_INT)
13742 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13744 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13746 op1 = immed_double_const (lo, hi, DImode);
13749 emit_move_insn (operands[2], op1);
13753 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13757 (define_insn "*btdi_rex64"
13758 [(set (reg:CCC FLAGS_REG)
13761 (match_operand:DI 0 "register_operand" "r")
13763 (match_operand:DI 1 "nonmemory_operand" "rN"))
13765 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
13766 "bt{q}\t{%1, %0|%0, %1}"
13767 [(set_attr "type" "alu1")])
13769 (define_insn "*btsi"
13770 [(set (reg:CCC FLAGS_REG)
13773 (match_operand:SI 0 "register_operand" "r")
13775 (match_operand:SI 1 "nonmemory_operand" "rN"))
13777 "TARGET_USE_BT || optimize_size"
13778 "bt{l}\t{%1, %0|%0, %1}"
13779 [(set_attr "type" "alu1")])
13781 ;; Store-flag instructions.
13783 ;; For all sCOND expanders, also expand the compare or test insn that
13784 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13786 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13787 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13788 ;; way, which can later delete the movzx if only QImode is needed.
13790 (define_expand "s<code>"
13791 [(set (match_operand:QI 0 "register_operand" "")
13792 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13794 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13796 (define_expand "s<code>"
13797 [(set (match_operand:QI 0 "register_operand" "")
13798 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13799 "TARGET_80387 || TARGET_SSE"
13800 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13802 (define_insn "*setcc_1"
13803 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13804 (match_operator:QI 1 "ix86_comparison_operator"
13805 [(reg FLAGS_REG) (const_int 0)]))]
13808 [(set_attr "type" "setcc")
13809 (set_attr "mode" "QI")])
13811 (define_insn "*setcc_2"
13812 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13813 (match_operator:QI 1 "ix86_comparison_operator"
13814 [(reg FLAGS_REG) (const_int 0)]))]
13817 [(set_attr "type" "setcc")
13818 (set_attr "mode" "QI")])
13820 ;; In general it is not safe to assume too much about CCmode registers,
13821 ;; so simplify-rtx stops when it sees a second one. Under certain
13822 ;; conditions this is safe on x86, so help combine not create
13829 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13830 (ne:QI (match_operator 1 "ix86_comparison_operator"
13831 [(reg FLAGS_REG) (const_int 0)])
13834 [(set (match_dup 0) (match_dup 1))]
13836 PUT_MODE (operands[1], QImode);
13840 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13841 (ne:QI (match_operator 1 "ix86_comparison_operator"
13842 [(reg FLAGS_REG) (const_int 0)])
13845 [(set (match_dup 0) (match_dup 1))]
13847 PUT_MODE (operands[1], QImode);
13851 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13852 (eq:QI (match_operator 1 "ix86_comparison_operator"
13853 [(reg FLAGS_REG) (const_int 0)])
13856 [(set (match_dup 0) (match_dup 1))]
13858 rtx new_op1 = copy_rtx (operands[1]);
13859 operands[1] = new_op1;
13860 PUT_MODE (new_op1, QImode);
13861 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13862 GET_MODE (XEXP (new_op1, 0))));
13864 /* Make sure that (a) the CCmode we have for the flags is strong
13865 enough for the reversed compare or (b) we have a valid FP compare. */
13866 if (! ix86_comparison_operator (new_op1, VOIDmode))
13871 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13872 (eq:QI (match_operator 1 "ix86_comparison_operator"
13873 [(reg FLAGS_REG) (const_int 0)])
13876 [(set (match_dup 0) (match_dup 1))]
13878 rtx new_op1 = copy_rtx (operands[1]);
13879 operands[1] = new_op1;
13880 PUT_MODE (new_op1, QImode);
13881 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13882 GET_MODE (XEXP (new_op1, 0))));
13884 /* Make sure that (a) the CCmode we have for the flags is strong
13885 enough for the reversed compare or (b) we have a valid FP compare. */
13886 if (! ix86_comparison_operator (new_op1, VOIDmode))
13890 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13891 ;; subsequent logical operations are used to imitate conditional moves.
13892 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13895 (define_insn "*sse_setcc<mode>"
13896 [(set (match_operand:MODEF 0 "register_operand" "=x")
13897 (match_operator:MODEF 1 "sse_comparison_operator"
13898 [(match_operand:MODEF 2 "register_operand" "0")
13899 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13900 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13901 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13902 [(set_attr "type" "ssecmp")
13903 (set_attr "mode" "<MODE>")])
13905 (define_insn "*sse5_setcc<mode>"
13906 [(set (match_operand:MODEF 0 "register_operand" "=x")
13907 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13908 [(match_operand:MODEF 2 "register_operand" "x")
13909 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13911 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13912 [(set_attr "type" "sse4arg")
13913 (set_attr "mode" "<MODE>")])
13916 ;; Basic conditional jump instructions.
13917 ;; We ignore the overflow flag for signed branch instructions.
13919 ;; For all bCOND expanders, also expand the compare or test insn that
13920 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13922 (define_expand "b<code>"
13924 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13926 (label_ref (match_operand 0 ""))
13929 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13931 (define_expand "b<code>"
13933 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13935 (label_ref (match_operand 0 ""))
13937 "TARGET_80387 || TARGET_SSE_MATH"
13938 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13940 (define_insn "*jcc_1"
13942 (if_then_else (match_operator 1 "ix86_comparison_operator"
13943 [(reg FLAGS_REG) (const_int 0)])
13944 (label_ref (match_operand 0 "" ""))
13948 [(set_attr "type" "ibr")
13949 (set_attr "modrm" "0")
13950 (set (attr "length")
13951 (if_then_else (and (ge (minus (match_dup 0) (pc))
13953 (lt (minus (match_dup 0) (pc))
13958 (define_insn "*jcc_2"
13960 (if_then_else (match_operator 1 "ix86_comparison_operator"
13961 [(reg FLAGS_REG) (const_int 0)])
13963 (label_ref (match_operand 0 "" ""))))]
13966 [(set_attr "type" "ibr")
13967 (set_attr "modrm" "0")
13968 (set (attr "length")
13969 (if_then_else (and (ge (minus (match_dup 0) (pc))
13971 (lt (minus (match_dup 0) (pc))
13976 ;; ??? Handle alignment requirements for compare and branch fused macro-op;
13977 ;; the branch instruction does not start at a 16-byte boundary or cross
13978 ;; a 16-byte boundary.
13980 (define_insn "*jcc_fused_1"
13982 (if_then_else (match_operator 1 "comparison_operator"
13983 [(match_operand:SWI 2 "register_operand" "<r>")
13984 (match_operand:SWI 3 "const0_operand" "")])
13985 (label_ref (match_operand 0 "" ""))
13987 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
13989 return "test{<imodesuffix>}\t%2, %2\n\t"
13990 "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
13992 [(set_attr "type" "multi")
13993 (set_attr "mode" "<MODE>")])
13995 (define_insn "*jcc_fused_2"
13997 (if_then_else (match_operator 1 "comparison_operator"
13998 [(match_operand:SWI 2 "register_operand" "<r>")
13999 (match_operand:SWI 3 "const0_operand" "")])
14001 (label_ref (match_operand 0 "" ""))))]
14002 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
14004 return "test{<imodesuffix>}\t%2, %2\n\t"
14005 "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
14007 [(set_attr "type" "multi")
14008 (set_attr "mode" "<MODE>")])
14010 (define_insn "*jcc_fused_3"
14013 (match_operator 1 "ix86_comparison_uns_operator"
14014 [(match_operand:SWI 2 "nonimmediate_operand" "<r>,m,<r>")
14015 (match_operand:SWI 3 "<general_operand>" "<r><i>,<r>,m")])
14016 (label_ref (match_operand 0 "" ""))
14018 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
14019 && !(MEM_P (operands[2])
14020 && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
14022 return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
14023 "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
14025 [(set_attr "type" "multi")
14026 (set_attr "mode" "<MODE>")])
14028 (define_insn "*jcc_fused_4"
14031 (match_operator 1 "ix86_comparison_uns_operator"
14032 [(match_operand:SWI 2 "nonimmediate_operand" "<r>,m,<r>")
14033 (match_operand:SWI 3 "<general_operand>" "<r><i>,<r>,m")])
14035 (label_ref (match_operand 0 "" ""))))]
14036 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
14037 && !(MEM_P (operands[2])
14038 && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
14040 return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
14041 "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
14043 [(set_attr "type" "multi")
14044 (set_attr "mode" "<MODE>")])
14046 ;; In general it is not safe to assume too much about CCmode registers,
14047 ;; so simplify-rtx stops when it sees a second one. Under certain
14048 ;; conditions this is safe on x86, so help combine not create
14056 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14057 [(reg FLAGS_REG) (const_int 0)])
14059 (label_ref (match_operand 1 "" ""))
14063 (if_then_else (match_dup 0)
14064 (label_ref (match_dup 1))
14067 PUT_MODE (operands[0], VOIDmode);
14072 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14073 [(reg FLAGS_REG) (const_int 0)])
14075 (label_ref (match_operand 1 "" ""))
14079 (if_then_else (match_dup 0)
14080 (label_ref (match_dup 1))
14083 rtx new_op0 = copy_rtx (operands[0]);
14084 operands[0] = new_op0;
14085 PUT_MODE (new_op0, VOIDmode);
14086 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14087 GET_MODE (XEXP (new_op0, 0))));
14089 /* Make sure that (a) the CCmode we have for the flags is strong
14090 enough for the reversed compare or (b) we have a valid FP compare. */
14091 if (! ix86_comparison_operator (new_op0, VOIDmode))
14095 ;; zero_extend in SImode is correct, since this is what combine pass
14096 ;; generates from shift insn with QImode operand. Actually, the mode of
14097 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14098 ;; appropriate modulo of the bit offset value.
14100 (define_insn_and_split "*jcc_btdi_rex64"
14102 (if_then_else (match_operator 0 "bt_comparison_operator"
14104 (match_operand:DI 1 "register_operand" "r")
14107 (match_operand:QI 2 "register_operand" "r")))
14109 (label_ref (match_operand 3 "" ""))
14111 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
14114 [(set (reg:CCC FLAGS_REG)
14122 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14123 (label_ref (match_dup 3))
14126 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14128 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14131 ;; avoid useless masking of bit offset operand
14132 (define_insn_and_split "*jcc_btdi_mask_rex64"
14134 (if_then_else (match_operator 0 "bt_comparison_operator"
14136 (match_operand:DI 1 "register_operand" "r")
14139 (match_operand:SI 2 "register_operand" "r")
14140 (match_operand:SI 3 "const_int_operand" "n")))])
14141 (label_ref (match_operand 4 "" ""))
14143 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)
14144 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14147 [(set (reg:CCC FLAGS_REG)
14155 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14156 (label_ref (match_dup 4))
14159 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14161 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14164 (define_insn_and_split "*jcc_btsi"
14166 (if_then_else (match_operator 0 "bt_comparison_operator"
14168 (match_operand:SI 1 "register_operand" "r")
14171 (match_operand:QI 2 "register_operand" "r")))
14173 (label_ref (match_operand 3 "" ""))
14175 "TARGET_USE_BT || optimize_size"
14178 [(set (reg:CCC FLAGS_REG)
14186 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14187 (label_ref (match_dup 3))
14190 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14192 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14195 ;; avoid useless masking of bit offset operand
14196 (define_insn_and_split "*jcc_btsi_mask"
14198 (if_then_else (match_operator 0 "bt_comparison_operator"
14200 (match_operand:SI 1 "register_operand" "r")
14203 (match_operand:SI 2 "register_operand" "r")
14204 (match_operand:SI 3 "const_int_operand" "n")))])
14205 (label_ref (match_operand 4 "" ""))
14207 "(TARGET_USE_BT || optimize_size)
14208 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14211 [(set (reg:CCC FLAGS_REG)
14219 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14220 (label_ref (match_dup 4))
14222 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14224 (define_insn_and_split "*jcc_btsi_1"
14226 (if_then_else (match_operator 0 "bt_comparison_operator"
14229 (match_operand:SI 1 "register_operand" "r")
14230 (match_operand:QI 2 "register_operand" "r"))
14233 (label_ref (match_operand 3 "" ""))
14235 "TARGET_USE_BT || optimize_size"
14238 [(set (reg:CCC FLAGS_REG)
14246 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14247 (label_ref (match_dup 3))
14250 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14252 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14255 ;; avoid useless masking of bit offset operand
14256 (define_insn_and_split "*jcc_btsi_mask_1"
14259 (match_operator 0 "bt_comparison_operator"
14262 (match_operand:SI 1 "register_operand" "r")
14265 (match_operand:SI 2 "register_operand" "r")
14266 (match_operand:SI 3 "const_int_operand" "n")) 0))
14269 (label_ref (match_operand 4 "" ""))
14271 "(TARGET_USE_BT || optimize_size)
14272 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14275 [(set (reg:CCC FLAGS_REG)
14283 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14284 (label_ref (match_dup 4))
14286 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14288 ;; Define combination compare-and-branch fp compare instructions to use
14289 ;; during early optimization. Splitting the operation apart early makes
14290 ;; for bad code when we want to reverse the operation.
14292 (define_insn "*fp_jcc_1_mixed"
14294 (if_then_else (match_operator 0 "comparison_operator"
14295 [(match_operand 1 "register_operand" "f,x")
14296 (match_operand 2 "nonimmediate_operand" "f,xm")])
14297 (label_ref (match_operand 3 "" ""))
14299 (clobber (reg:CCFP FPSR_REG))
14300 (clobber (reg:CCFP FLAGS_REG))]
14301 "TARGET_MIX_SSE_I387
14302 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14303 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14304 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14307 (define_insn "*fp_jcc_1_sse"
14309 (if_then_else (match_operator 0 "comparison_operator"
14310 [(match_operand 1 "register_operand" "x")
14311 (match_operand 2 "nonimmediate_operand" "xm")])
14312 (label_ref (match_operand 3 "" ""))
14314 (clobber (reg:CCFP FPSR_REG))
14315 (clobber (reg:CCFP FLAGS_REG))]
14317 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14318 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14319 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14322 (define_insn "*fp_jcc_1_387"
14324 (if_then_else (match_operator 0 "comparison_operator"
14325 [(match_operand 1 "register_operand" "f")
14326 (match_operand 2 "register_operand" "f")])
14327 (label_ref (match_operand 3 "" ""))
14329 (clobber (reg:CCFP FPSR_REG))
14330 (clobber (reg:CCFP FLAGS_REG))]
14331 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14333 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14334 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14337 (define_insn "*fp_jcc_2_mixed"
14339 (if_then_else (match_operator 0 "comparison_operator"
14340 [(match_operand 1 "register_operand" "f,x")
14341 (match_operand 2 "nonimmediate_operand" "f,xm")])
14343 (label_ref (match_operand 3 "" ""))))
14344 (clobber (reg:CCFP FPSR_REG))
14345 (clobber (reg:CCFP FLAGS_REG))]
14346 "TARGET_MIX_SSE_I387
14347 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14348 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14349 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14352 (define_insn "*fp_jcc_2_sse"
14354 (if_then_else (match_operator 0 "comparison_operator"
14355 [(match_operand 1 "register_operand" "x")
14356 (match_operand 2 "nonimmediate_operand" "xm")])
14358 (label_ref (match_operand 3 "" ""))))
14359 (clobber (reg:CCFP FPSR_REG))
14360 (clobber (reg:CCFP FLAGS_REG))]
14362 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14363 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14364 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14367 (define_insn "*fp_jcc_2_387"
14369 (if_then_else (match_operator 0 "comparison_operator"
14370 [(match_operand 1 "register_operand" "f")
14371 (match_operand 2 "register_operand" "f")])
14373 (label_ref (match_operand 3 "" ""))))
14374 (clobber (reg:CCFP FPSR_REG))
14375 (clobber (reg:CCFP FLAGS_REG))]
14376 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14378 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14379 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14382 (define_insn "*fp_jcc_3_387"
14384 (if_then_else (match_operator 0 "comparison_operator"
14385 [(match_operand 1 "register_operand" "f")
14386 (match_operand 2 "nonimmediate_operand" "fm")])
14387 (label_ref (match_operand 3 "" ""))
14389 (clobber (reg:CCFP FPSR_REG))
14390 (clobber (reg:CCFP FLAGS_REG))
14391 (clobber (match_scratch:HI 4 "=a"))]
14393 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14394 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14395 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14396 && SELECT_CC_MODE (GET_CODE (operands[0]),
14397 operands[1], operands[2]) == CCFPmode
14398 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14401 (define_insn "*fp_jcc_4_387"
14403 (if_then_else (match_operator 0 "comparison_operator"
14404 [(match_operand 1 "register_operand" "f")
14405 (match_operand 2 "nonimmediate_operand" "fm")])
14407 (label_ref (match_operand 3 "" ""))))
14408 (clobber (reg:CCFP FPSR_REG))
14409 (clobber (reg:CCFP FLAGS_REG))
14410 (clobber (match_scratch:HI 4 "=a"))]
14412 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14413 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14414 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14415 && SELECT_CC_MODE (GET_CODE (operands[0]),
14416 operands[1], operands[2]) == CCFPmode
14417 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14420 (define_insn "*fp_jcc_5_387"
14422 (if_then_else (match_operator 0 "comparison_operator"
14423 [(match_operand 1 "register_operand" "f")
14424 (match_operand 2 "register_operand" "f")])
14425 (label_ref (match_operand 3 "" ""))
14427 (clobber (reg:CCFP FPSR_REG))
14428 (clobber (reg:CCFP FLAGS_REG))
14429 (clobber (match_scratch:HI 4 "=a"))]
14430 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14431 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14432 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14435 (define_insn "*fp_jcc_6_387"
14437 (if_then_else (match_operator 0 "comparison_operator"
14438 [(match_operand 1 "register_operand" "f")
14439 (match_operand 2 "register_operand" "f")])
14441 (label_ref (match_operand 3 "" ""))))
14442 (clobber (reg:CCFP FPSR_REG))
14443 (clobber (reg:CCFP FLAGS_REG))
14444 (clobber (match_scratch:HI 4 "=a"))]
14445 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14446 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14447 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14450 (define_insn "*fp_jcc_7_387"
14452 (if_then_else (match_operator 0 "comparison_operator"
14453 [(match_operand 1 "register_operand" "f")
14454 (match_operand 2 "const0_operand" "")])
14455 (label_ref (match_operand 3 "" ""))
14457 (clobber (reg:CCFP FPSR_REG))
14458 (clobber (reg:CCFP FLAGS_REG))
14459 (clobber (match_scratch:HI 4 "=a"))]
14460 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14461 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14462 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14463 && SELECT_CC_MODE (GET_CODE (operands[0]),
14464 operands[1], operands[2]) == CCFPmode
14465 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14468 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14469 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14470 ;; with a precedence over other operators and is always put in the first
14471 ;; place. Swap condition and operands to match ficom instruction.
14473 (define_insn "*fp_jcc_8<mode>_387"
14475 (if_then_else (match_operator 0 "comparison_operator"
14476 [(match_operator 1 "float_operator"
14477 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14478 (match_operand 3 "register_operand" "f,f")])
14479 (label_ref (match_operand 4 "" ""))
14481 (clobber (reg:CCFP FPSR_REG))
14482 (clobber (reg:CCFP FLAGS_REG))
14483 (clobber (match_scratch:HI 5 "=a,a"))]
14484 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14485 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
14486 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14487 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14488 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14489 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14494 (if_then_else (match_operator 0 "comparison_operator"
14495 [(match_operand 1 "register_operand" "")
14496 (match_operand 2 "nonimmediate_operand" "")])
14497 (match_operand 3 "" "")
14498 (match_operand 4 "" "")))
14499 (clobber (reg:CCFP FPSR_REG))
14500 (clobber (reg:CCFP FLAGS_REG))]
14504 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14505 operands[3], operands[4], NULL_RTX, NULL_RTX);
14511 (if_then_else (match_operator 0 "comparison_operator"
14512 [(match_operand 1 "register_operand" "")
14513 (match_operand 2 "general_operand" "")])
14514 (match_operand 3 "" "")
14515 (match_operand 4 "" "")))
14516 (clobber (reg:CCFP FPSR_REG))
14517 (clobber (reg:CCFP FLAGS_REG))
14518 (clobber (match_scratch:HI 5 "=a"))]
14522 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14523 operands[3], operands[4], operands[5], NULL_RTX);
14529 (if_then_else (match_operator 0 "comparison_operator"
14530 [(match_operator 1 "float_operator"
14531 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14532 (match_operand 3 "register_operand" "")])
14533 (match_operand 4 "" "")
14534 (match_operand 5 "" "")))
14535 (clobber (reg:CCFP FPSR_REG))
14536 (clobber (reg:CCFP FLAGS_REG))
14537 (clobber (match_scratch:HI 6 "=a"))]
14541 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14542 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14543 operands[3], operands[7],
14544 operands[4], operands[5], operands[6], NULL_RTX);
14548 ;; %%% Kill this when reload knows how to do it.
14551 (if_then_else (match_operator 0 "comparison_operator"
14552 [(match_operator 1 "float_operator"
14553 [(match_operand:X87MODEI12 2 "register_operand" "")])
14554 (match_operand 3 "register_operand" "")])
14555 (match_operand 4 "" "")
14556 (match_operand 5 "" "")))
14557 (clobber (reg:CCFP FPSR_REG))
14558 (clobber (reg:CCFP FLAGS_REG))
14559 (clobber (match_scratch:HI 6 "=a"))]
14563 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14564 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14565 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14566 operands[3], operands[7],
14567 operands[4], operands[5], operands[6], operands[2]);
14571 ;; Unconditional and other jump instructions
14573 (define_insn "jump"
14575 (label_ref (match_operand 0 "" "")))]
14578 [(set_attr "type" "ibr")
14579 (set (attr "length")
14580 (if_then_else (and (ge (minus (match_dup 0) (pc))
14582 (lt (minus (match_dup 0) (pc))
14586 (set_attr "modrm" "0")])
14588 (define_expand "indirect_jump"
14589 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14593 (define_insn "*indirect_jump"
14594 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14597 [(set_attr "type" "ibr")
14598 (set_attr "length_immediate" "0")])
14600 (define_expand "tablejump"
14601 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14602 (use (label_ref (match_operand 1 "" "")))])]
14605 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14606 relative. Convert the relative address to an absolute address. */
14610 enum rtx_code code;
14612 /* We can't use @GOTOFF for text labels on VxWorks;
14613 see gotoff_operand. */
14614 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14618 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14620 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14624 op1 = pic_offset_table_rtx;
14629 op0 = pic_offset_table_rtx;
14633 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14638 (define_insn "*tablejump_1"
14639 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14640 (use (label_ref (match_operand 1 "" "")))]
14643 [(set_attr "type" "ibr")
14644 (set_attr "length_immediate" "0")])
14646 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14649 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14650 (set (match_operand:QI 1 "register_operand" "")
14651 (match_operator:QI 2 "ix86_comparison_operator"
14652 [(reg FLAGS_REG) (const_int 0)]))
14653 (set (match_operand 3 "q_regs_operand" "")
14654 (zero_extend (match_dup 1)))]
14655 "(peep2_reg_dead_p (3, operands[1])
14656 || operands_match_p (operands[1], operands[3]))
14657 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14658 [(set (match_dup 4) (match_dup 0))
14659 (set (strict_low_part (match_dup 5))
14662 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14663 operands[5] = gen_lowpart (QImode, operands[3]);
14664 ix86_expand_clear (operands[3]);
14667 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14670 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14671 (set (match_operand:QI 1 "register_operand" "")
14672 (match_operator:QI 2 "ix86_comparison_operator"
14673 [(reg FLAGS_REG) (const_int 0)]))
14674 (parallel [(set (match_operand 3 "q_regs_operand" "")
14675 (zero_extend (match_dup 1)))
14676 (clobber (reg:CC FLAGS_REG))])]
14677 "(peep2_reg_dead_p (3, operands[1])
14678 || operands_match_p (operands[1], operands[3]))
14679 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14680 [(set (match_dup 4) (match_dup 0))
14681 (set (strict_low_part (match_dup 5))
14684 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14685 operands[5] = gen_lowpart (QImode, operands[3]);
14686 ix86_expand_clear (operands[3]);
14689 ;; Call instructions.
14691 ;; The predicates normally associated with named expanders are not properly
14692 ;; checked for calls. This is a bug in the generic code, but it isn't that
14693 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14695 ;; Call subroutine returning no value.
14697 (define_expand "call_pop"
14698 [(parallel [(call (match_operand:QI 0 "" "")
14699 (match_operand:SI 1 "" ""))
14700 (set (reg:SI SP_REG)
14701 (plus:SI (reg:SI SP_REG)
14702 (match_operand:SI 3 "" "")))])]
14705 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14709 (define_insn "*call_pop_0"
14710 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14711 (match_operand:SI 1 "" ""))
14712 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14713 (match_operand:SI 2 "immediate_operand" "")))]
14716 if (SIBLING_CALL_P (insn))
14719 return "call\t%P0";
14721 [(set_attr "type" "call")])
14723 (define_insn "*call_pop_1"
14724 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14725 (match_operand:SI 1 "" ""))
14726 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14727 (match_operand:SI 2 "immediate_operand" "i")))]
14730 if (constant_call_address_operand (operands[0], Pmode))
14732 if (SIBLING_CALL_P (insn))
14735 return "call\t%P0";
14737 if (SIBLING_CALL_P (insn))
14740 return "call\t%A0";
14742 [(set_attr "type" "call")])
14744 (define_expand "call"
14745 [(call (match_operand:QI 0 "" "")
14746 (match_operand 1 "" ""))
14747 (use (match_operand 2 "" ""))]
14750 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14754 (define_expand "sibcall"
14755 [(call (match_operand:QI 0 "" "")
14756 (match_operand 1 "" ""))
14757 (use (match_operand 2 "" ""))]
14760 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14764 (define_insn "*call_0"
14765 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14766 (match_operand 1 "" ""))]
14769 if (SIBLING_CALL_P (insn))
14772 return "call\t%P0";
14774 [(set_attr "type" "call")])
14776 (define_insn "*call_1"
14777 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14778 (match_operand 1 "" ""))]
14779 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14781 if (constant_call_address_operand (operands[0], Pmode))
14782 return "call\t%P0";
14783 return "call\t%A0";
14785 [(set_attr "type" "call")])
14787 (define_insn "*sibcall_1"
14788 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14789 (match_operand 1 "" ""))]
14790 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14792 if (constant_call_address_operand (operands[0], Pmode))
14796 [(set_attr "type" "call")])
14798 (define_insn "*call_1_rex64"
14799 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14800 (match_operand 1 "" ""))]
14801 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14802 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14804 if (constant_call_address_operand (operands[0], Pmode))
14805 return "call\t%P0";
14806 return "call\t%A0";
14808 [(set_attr "type" "call")])
14810 (define_insn "*call_1_rex64_large"
14811 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14812 (match_operand 1 "" ""))]
14813 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14815 [(set_attr "type" "call")])
14817 (define_insn "*sibcall_1_rex64"
14818 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14819 (match_operand 1 "" ""))]
14820 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14822 [(set_attr "type" "call")])
14824 (define_insn "*sibcall_1_rex64_v"
14825 [(call (mem:QI (reg:DI R11_REG))
14826 (match_operand 0 "" ""))]
14827 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14829 [(set_attr "type" "call")])
14832 ;; Call subroutine, returning value in operand 0
14834 (define_expand "call_value_pop"
14835 [(parallel [(set (match_operand 0 "" "")
14836 (call (match_operand:QI 1 "" "")
14837 (match_operand:SI 2 "" "")))
14838 (set (reg:SI SP_REG)
14839 (plus:SI (reg:SI SP_REG)
14840 (match_operand:SI 4 "" "")))])]
14843 ix86_expand_call (operands[0], operands[1], operands[2],
14844 operands[3], operands[4], 0);
14848 (define_expand "call_value"
14849 [(set (match_operand 0 "" "")
14850 (call (match_operand:QI 1 "" "")
14851 (match_operand:SI 2 "" "")))
14852 (use (match_operand:SI 3 "" ""))]
14853 ;; Operand 2 not used on the i386.
14856 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14860 (define_expand "sibcall_value"
14861 [(set (match_operand 0 "" "")
14862 (call (match_operand:QI 1 "" "")
14863 (match_operand:SI 2 "" "")))
14864 (use (match_operand:SI 3 "" ""))]
14865 ;; Operand 2 not used on the i386.
14868 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14872 ;; Call subroutine returning any type.
14874 (define_expand "untyped_call"
14875 [(parallel [(call (match_operand 0 "" "")
14877 (match_operand 1 "" "")
14878 (match_operand 2 "" "")])]
14883 /* In order to give reg-stack an easier job in validating two
14884 coprocessor registers as containing a possible return value,
14885 simply pretend the untyped call returns a complex long double
14888 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14889 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14890 operands[0], const0_rtx,
14891 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
14892 : X64_SSE_REGPARM_MAX)
14896 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14898 rtx set = XVECEXP (operands[2], 0, i);
14899 emit_move_insn (SET_DEST (set), SET_SRC (set));
14902 /* The optimizer does not know that the call sets the function value
14903 registers we stored in the result block. We avoid problems by
14904 claiming that all hard registers are used and clobbered at this
14906 emit_insn (gen_blockage ());
14911 ;; Prologue and epilogue instructions
14913 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14914 ;; all of memory. This blocks insns from being moved across this point.
14916 (define_insn "blockage"
14917 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14920 [(set_attr "length" "0")])
14922 ;; As USE insns aren't meaningful after reload, this is used instead
14923 ;; to prevent deleting instructions setting registers for PIC code
14924 (define_insn "prologue_use"
14925 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14928 [(set_attr "length" "0")])
14930 ;; Insn emitted into the body of a function to return from a function.
14931 ;; This is only done if the function's epilogue is known to be simple.
14932 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14934 (define_expand "return"
14936 "ix86_can_use_return_insn_p ()"
14938 if (crtl->args.pops_args)
14940 rtx popc = GEN_INT (crtl->args.pops_args);
14941 emit_jump_insn (gen_return_pop_internal (popc));
14946 (define_insn "return_internal"
14950 [(set_attr "length" "1")
14951 (set_attr "length_immediate" "0")
14952 (set_attr "modrm" "0")])
14954 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14955 ;; instruction Athlon and K8 have.
14957 (define_insn "return_internal_long"
14959 (unspec [(const_int 0)] UNSPEC_REP)]
14962 [(set_attr "length" "1")
14963 (set_attr "length_immediate" "0")
14964 (set_attr "prefix_rep" "1")
14965 (set_attr "modrm" "0")])
14967 (define_insn "return_pop_internal"
14969 (use (match_operand:SI 0 "const_int_operand" ""))]
14972 [(set_attr "length" "3")
14973 (set_attr "length_immediate" "2")
14974 (set_attr "modrm" "0")])
14976 (define_insn "return_indirect_internal"
14978 (use (match_operand:SI 0 "register_operand" "r"))]
14981 [(set_attr "type" "ibr")
14982 (set_attr "length_immediate" "0")])
14988 [(set_attr "length" "1")
14989 (set_attr "length_immediate" "0")
14990 (set_attr "modrm" "0")])
14992 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14993 ;; branch prediction penalty for the third jump in a 16-byte
14996 (define_insn "align"
14997 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15000 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15001 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15003 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15004 The align insn is used to avoid 3 jump instructions in the row to improve
15005 branch prediction and the benefits hardly outweigh the cost of extra 8
15006 nops on the average inserted by full alignment pseudo operation. */
15010 [(set_attr "length" "16")])
15012 (define_expand "prologue"
15015 "ix86_expand_prologue (); DONE;")
15017 (define_insn "set_got"
15018 [(set (match_operand:SI 0 "register_operand" "=r")
15019 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15020 (clobber (reg:CC FLAGS_REG))]
15022 { return output_set_got (operands[0], NULL_RTX); }
15023 [(set_attr "type" "multi")
15024 (set_attr "length" "12")])
15026 (define_insn "set_got_labelled"
15027 [(set (match_operand:SI 0 "register_operand" "=r")
15028 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15030 (clobber (reg:CC FLAGS_REG))]
15032 { return output_set_got (operands[0], operands[1]); }
15033 [(set_attr "type" "multi")
15034 (set_attr "length" "12")])
15036 (define_insn "set_got_rex64"
15037 [(set (match_operand:DI 0 "register_operand" "=r")
15038 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15040 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15041 [(set_attr "type" "lea")
15042 (set_attr "length" "6")])
15044 (define_insn "set_rip_rex64"
15045 [(set (match_operand:DI 0 "register_operand" "=r")
15046 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15048 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15049 [(set_attr "type" "lea")
15050 (set_attr "length" "6")])
15052 (define_insn "set_got_offset_rex64"
15053 [(set (match_operand:DI 0 "register_operand" "=r")
15054 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15056 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15057 [(set_attr "type" "imov")
15058 (set_attr "length" "11")])
15060 (define_expand "epilogue"
15063 "ix86_expand_epilogue (1); DONE;")
15065 (define_expand "sibcall_epilogue"
15068 "ix86_expand_epilogue (0); DONE;")
15070 (define_expand "eh_return"
15071 [(use (match_operand 0 "register_operand" ""))]
15074 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15076 /* Tricky bit: we write the address of the handler to which we will
15077 be returning into someone else's stack frame, one word below the
15078 stack address we wish to restore. */
15079 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15080 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15081 tmp = gen_rtx_MEM (Pmode, tmp);
15082 emit_move_insn (tmp, ra);
15084 if (Pmode == SImode)
15085 emit_jump_insn (gen_eh_return_si (sa));
15087 emit_jump_insn (gen_eh_return_di (sa));
15092 (define_insn_and_split "eh_return_<mode>"
15094 (unspec [(match_operand:P 0 "register_operand" "c")]
15095 UNSPEC_EH_RETURN))]
15100 "ix86_expand_epilogue (2); DONE;")
15102 (define_insn "leave"
15103 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15104 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15105 (clobber (mem:BLK (scratch)))]
15108 [(set_attr "type" "leave")])
15110 (define_insn "leave_rex64"
15111 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15112 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15113 (clobber (mem:BLK (scratch)))]
15116 [(set_attr "type" "leave")])
15118 (define_expand "ffssi2"
15120 [(set (match_operand:SI 0 "register_operand" "")
15121 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15122 (clobber (match_scratch:SI 2 ""))
15123 (clobber (reg:CC FLAGS_REG))])]
15128 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15133 (define_expand "ffs_cmove"
15134 [(set (match_dup 2) (const_int -1))
15135 (parallel [(set (reg:CCZ FLAGS_REG)
15136 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15138 (set (match_operand:SI 0 "nonimmediate_operand" "")
15139 (ctz:SI (match_dup 1)))])
15140 (set (match_dup 0) (if_then_else:SI
15141 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15144 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15145 (clobber (reg:CC FLAGS_REG))])]
15147 "operands[2] = gen_reg_rtx (SImode);")
15149 (define_insn_and_split "*ffs_no_cmove"
15150 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15151 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15152 (clobber (match_scratch:SI 2 "=&q"))
15153 (clobber (reg:CC FLAGS_REG))]
15156 "&& reload_completed"
15157 [(parallel [(set (reg:CCZ FLAGS_REG)
15158 (compare:CCZ (match_dup 1) (const_int 0)))
15159 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15160 (set (strict_low_part (match_dup 3))
15161 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15162 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15163 (clobber (reg:CC FLAGS_REG))])
15164 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15165 (clobber (reg:CC FLAGS_REG))])
15166 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15167 (clobber (reg:CC FLAGS_REG))])]
15169 operands[3] = gen_lowpart (QImode, operands[2]);
15170 ix86_expand_clear (operands[2]);
15173 (define_insn "*ffssi_1"
15174 [(set (reg:CCZ FLAGS_REG)
15175 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15177 (set (match_operand:SI 0 "register_operand" "=r")
15178 (ctz:SI (match_dup 1)))]
15180 "bsf{l}\t{%1, %0|%0, %1}"
15181 [(set_attr "prefix_0f" "1")])
15183 (define_expand "ffsdi2"
15184 [(set (match_dup 2) (const_int -1))
15185 (parallel [(set (reg:CCZ FLAGS_REG)
15186 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15188 (set (match_operand:DI 0 "nonimmediate_operand" "")
15189 (ctz:DI (match_dup 1)))])
15190 (set (match_dup 0) (if_then_else:DI
15191 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15194 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15195 (clobber (reg:CC FLAGS_REG))])]
15197 "operands[2] = gen_reg_rtx (DImode);")
15199 (define_insn "*ffsdi_1"
15200 [(set (reg:CCZ FLAGS_REG)
15201 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15203 (set (match_operand:DI 0 "register_operand" "=r")
15204 (ctz:DI (match_dup 1)))]
15206 "bsf{q}\t{%1, %0|%0, %1}"
15207 [(set_attr "prefix_0f" "1")])
15209 (define_insn "ctzsi2"
15210 [(set (match_operand:SI 0 "register_operand" "=r")
15211 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15212 (clobber (reg:CC FLAGS_REG))]
15214 "bsf{l}\t{%1, %0|%0, %1}"
15215 [(set_attr "prefix_0f" "1")])
15217 (define_insn "ctzdi2"
15218 [(set (match_operand:DI 0 "register_operand" "=r")
15219 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15220 (clobber (reg:CC FLAGS_REG))]
15222 "bsf{q}\t{%1, %0|%0, %1}"
15223 [(set_attr "prefix_0f" "1")])
15225 (define_expand "clzsi2"
15227 [(set (match_operand:SI 0 "register_operand" "")
15228 (minus:SI (const_int 31)
15229 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15230 (clobber (reg:CC FLAGS_REG))])
15232 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15233 (clobber (reg:CC FLAGS_REG))])]
15238 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15243 (define_insn "clzsi2_abm"
15244 [(set (match_operand:SI 0 "register_operand" "=r")
15245 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15246 (clobber (reg:CC FLAGS_REG))]
15248 "lzcnt{l}\t{%1, %0|%0, %1}"
15249 [(set_attr "prefix_rep" "1")
15250 (set_attr "type" "bitmanip")
15251 (set_attr "mode" "SI")])
15253 (define_insn "*bsr"
15254 [(set (match_operand:SI 0 "register_operand" "=r")
15255 (minus:SI (const_int 31)
15256 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15257 (clobber (reg:CC FLAGS_REG))]
15259 "bsr{l}\t{%1, %0|%0, %1}"
15260 [(set_attr "prefix_0f" "1")
15261 (set_attr "mode" "SI")])
15263 (define_insn "popcountsi2"
15264 [(set (match_operand:SI 0 "register_operand" "=r")
15265 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15266 (clobber (reg:CC FLAGS_REG))]
15268 "popcnt{l}\t{%1, %0|%0, %1}"
15269 [(set_attr "prefix_rep" "1")
15270 (set_attr "type" "bitmanip")
15271 (set_attr "mode" "SI")])
15273 (define_insn "*popcountsi2_cmp"
15274 [(set (reg FLAGS_REG)
15276 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15278 (set (match_operand:SI 0 "register_operand" "=r")
15279 (popcount:SI (match_dup 1)))]
15280 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15281 "popcnt{l}\t{%1, %0|%0, %1}"
15282 [(set_attr "prefix_rep" "1")
15283 (set_attr "type" "bitmanip")
15284 (set_attr "mode" "SI")])
15286 (define_insn "*popcountsi2_cmp_zext"
15287 [(set (reg FLAGS_REG)
15289 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15291 (set (match_operand:DI 0 "register_operand" "=r")
15292 (zero_extend:DI(popcount:SI (match_dup 1))))]
15293 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15294 "popcnt{l}\t{%1, %0|%0, %1}"
15295 [(set_attr "prefix_rep" "1")
15296 (set_attr "type" "bitmanip")
15297 (set_attr "mode" "SI")])
15299 (define_expand "bswapsi2"
15300 [(set (match_operand:SI 0 "register_operand" "")
15301 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15306 rtx x = operands[0];
15308 emit_move_insn (x, operands[1]);
15309 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15310 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15311 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15316 (define_insn "*bswapsi_1"
15317 [(set (match_operand:SI 0 "register_operand" "=r")
15318 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15321 [(set_attr "prefix_0f" "1")
15322 (set_attr "length" "2")])
15324 (define_insn "*bswaphi_lowpart_1"
15325 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15326 (bswap:HI (match_dup 0)))
15327 (clobber (reg:CC FLAGS_REG))]
15328 "TARGET_USE_XCHGB || optimize_size"
15330 xchg{b}\t{%h0, %b0|%b0, %h0}
15331 rol{w}\t{$8, %0|%0, 8}"
15332 [(set_attr "length" "2,4")
15333 (set_attr "mode" "QI,HI")])
15335 (define_insn "bswaphi_lowpart"
15336 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15337 (bswap:HI (match_dup 0)))
15338 (clobber (reg:CC FLAGS_REG))]
15340 "rol{w}\t{$8, %0|%0, 8}"
15341 [(set_attr "length" "4")
15342 (set_attr "mode" "HI")])
15344 (define_insn "bswapdi2"
15345 [(set (match_operand:DI 0 "register_operand" "=r")
15346 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15349 [(set_attr "prefix_0f" "1")
15350 (set_attr "length" "3")])
15352 (define_expand "clzdi2"
15354 [(set (match_operand:DI 0 "register_operand" "")
15355 (minus:DI (const_int 63)
15356 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15357 (clobber (reg:CC FLAGS_REG))])
15359 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15360 (clobber (reg:CC FLAGS_REG))])]
15365 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15370 (define_insn "clzdi2_abm"
15371 [(set (match_operand:DI 0 "register_operand" "=r")
15372 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15373 (clobber (reg:CC FLAGS_REG))]
15374 "TARGET_64BIT && TARGET_ABM"
15375 "lzcnt{q}\t{%1, %0|%0, %1}"
15376 [(set_attr "prefix_rep" "1")
15377 (set_attr "type" "bitmanip")
15378 (set_attr "mode" "DI")])
15380 (define_insn "*bsr_rex64"
15381 [(set (match_operand:DI 0 "register_operand" "=r")
15382 (minus:DI (const_int 63)
15383 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15384 (clobber (reg:CC FLAGS_REG))]
15386 "bsr{q}\t{%1, %0|%0, %1}"
15387 [(set_attr "prefix_0f" "1")
15388 (set_attr "mode" "DI")])
15390 (define_insn "popcountdi2"
15391 [(set (match_operand:DI 0 "register_operand" "=r")
15392 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15393 (clobber (reg:CC FLAGS_REG))]
15394 "TARGET_64BIT && TARGET_POPCNT"
15395 "popcnt{q}\t{%1, %0|%0, %1}"
15396 [(set_attr "prefix_rep" "1")
15397 (set_attr "type" "bitmanip")
15398 (set_attr "mode" "DI")])
15400 (define_insn "*popcountdi2_cmp"
15401 [(set (reg FLAGS_REG)
15403 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15405 (set (match_operand:DI 0 "register_operand" "=r")
15406 (popcount:DI (match_dup 1)))]
15407 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15408 "popcnt{q}\t{%1, %0|%0, %1}"
15409 [(set_attr "prefix_rep" "1")
15410 (set_attr "type" "bitmanip")
15411 (set_attr "mode" "DI")])
15413 (define_expand "clzhi2"
15415 [(set (match_operand:HI 0 "register_operand" "")
15416 (minus:HI (const_int 15)
15417 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15418 (clobber (reg:CC FLAGS_REG))])
15420 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15421 (clobber (reg:CC FLAGS_REG))])]
15426 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15431 (define_insn "clzhi2_abm"
15432 [(set (match_operand:HI 0 "register_operand" "=r")
15433 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15434 (clobber (reg:CC FLAGS_REG))]
15436 "lzcnt{w}\t{%1, %0|%0, %1}"
15437 [(set_attr "prefix_rep" "1")
15438 (set_attr "type" "bitmanip")
15439 (set_attr "mode" "HI")])
15441 (define_insn "*bsrhi"
15442 [(set (match_operand:HI 0 "register_operand" "=r")
15443 (minus:HI (const_int 15)
15444 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15445 (clobber (reg:CC FLAGS_REG))]
15447 "bsr{w}\t{%1, %0|%0, %1}"
15448 [(set_attr "prefix_0f" "1")
15449 (set_attr "mode" "HI")])
15451 (define_insn "popcounthi2"
15452 [(set (match_operand:HI 0 "register_operand" "=r")
15453 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15454 (clobber (reg:CC FLAGS_REG))]
15456 "popcnt{w}\t{%1, %0|%0, %1}"
15457 [(set_attr "prefix_rep" "1")
15458 (set_attr "type" "bitmanip")
15459 (set_attr "mode" "HI")])
15461 (define_insn "*popcounthi2_cmp"
15462 [(set (reg FLAGS_REG)
15464 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15466 (set (match_operand:HI 0 "register_operand" "=r")
15467 (popcount:HI (match_dup 1)))]
15468 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15469 "popcnt{w}\t{%1, %0|%0, %1}"
15470 [(set_attr "prefix_rep" "1")
15471 (set_attr "type" "bitmanip")
15472 (set_attr "mode" "HI")])
15474 (define_expand "paritydi2"
15475 [(set (match_operand:DI 0 "register_operand" "")
15476 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15479 rtx scratch = gen_reg_rtx (QImode);
15482 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15483 NULL_RTX, operands[1]));
15485 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15486 gen_rtx_REG (CCmode, FLAGS_REG),
15488 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15491 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15494 rtx tmp = gen_reg_rtx (SImode);
15496 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15497 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15502 (define_insn_and_split "paritydi2_cmp"
15503 [(set (reg:CC FLAGS_REG)
15504 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15505 (clobber (match_scratch:DI 0 "=r"))
15506 (clobber (match_scratch:SI 1 "=&r"))
15507 (clobber (match_scratch:HI 2 "=Q"))]
15510 "&& reload_completed"
15512 [(set (match_dup 1)
15513 (xor:SI (match_dup 1) (match_dup 4)))
15514 (clobber (reg:CC FLAGS_REG))])
15516 [(set (reg:CC FLAGS_REG)
15517 (parity:CC (match_dup 1)))
15518 (clobber (match_dup 1))
15519 (clobber (match_dup 2))])]
15521 operands[4] = gen_lowpart (SImode, operands[3]);
15525 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15526 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15529 operands[1] = gen_highpart (SImode, operands[3]);
15532 (define_expand "paritysi2"
15533 [(set (match_operand:SI 0 "register_operand" "")
15534 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15537 rtx scratch = gen_reg_rtx (QImode);
15540 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15542 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15543 gen_rtx_REG (CCmode, FLAGS_REG),
15545 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15547 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15551 (define_insn_and_split "paritysi2_cmp"
15552 [(set (reg:CC FLAGS_REG)
15553 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15554 (clobber (match_scratch:SI 0 "=r"))
15555 (clobber (match_scratch:HI 1 "=&Q"))]
15558 "&& reload_completed"
15560 [(set (match_dup 1)
15561 (xor:HI (match_dup 1) (match_dup 3)))
15562 (clobber (reg:CC FLAGS_REG))])
15564 [(set (reg:CC FLAGS_REG)
15565 (parity:CC (match_dup 1)))
15566 (clobber (match_dup 1))])]
15568 operands[3] = gen_lowpart (HImode, operands[2]);
15570 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15571 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15574 (define_insn "*parityhi2_cmp"
15575 [(set (reg:CC FLAGS_REG)
15576 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15577 (clobber (match_scratch:HI 0 "=Q"))]
15579 "xor{b}\t{%h0, %b0|%b0, %h0}"
15580 [(set_attr "length" "2")
15581 (set_attr "mode" "HI")])
15583 (define_insn "*parityqi2_cmp"
15584 [(set (reg:CC FLAGS_REG)
15585 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15588 [(set_attr "length" "2")
15589 (set_attr "mode" "QI")])
15591 ;; Thread-local storage patterns for ELF.
15593 ;; Note that these code sequences must appear exactly as shown
15594 ;; in order to allow linker relaxation.
15596 (define_insn "*tls_global_dynamic_32_gnu"
15597 [(set (match_operand:SI 0 "register_operand" "=a")
15598 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15599 (match_operand:SI 2 "tls_symbolic_operand" "")
15600 (match_operand:SI 3 "call_insn_operand" "")]
15602 (clobber (match_scratch:SI 4 "=d"))
15603 (clobber (match_scratch:SI 5 "=c"))
15604 (clobber (reg:CC FLAGS_REG))]
15605 "!TARGET_64BIT && TARGET_GNU_TLS"
15606 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15607 [(set_attr "type" "multi")
15608 (set_attr "length" "12")])
15610 (define_insn "*tls_global_dynamic_32_sun"
15611 [(set (match_operand:SI 0 "register_operand" "=a")
15612 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15613 (match_operand:SI 2 "tls_symbolic_operand" "")
15614 (match_operand:SI 3 "call_insn_operand" "")]
15616 (clobber (match_scratch:SI 4 "=d"))
15617 (clobber (match_scratch:SI 5 "=c"))
15618 (clobber (reg:CC FLAGS_REG))]
15619 "!TARGET_64BIT && TARGET_SUN_TLS"
15620 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15621 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15622 [(set_attr "type" "multi")
15623 (set_attr "length" "14")])
15625 (define_expand "tls_global_dynamic_32"
15626 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15629 (match_operand:SI 1 "tls_symbolic_operand" "")
15632 (clobber (match_scratch:SI 4 ""))
15633 (clobber (match_scratch:SI 5 ""))
15634 (clobber (reg:CC FLAGS_REG))])]
15638 operands[2] = pic_offset_table_rtx;
15641 operands[2] = gen_reg_rtx (Pmode);
15642 emit_insn (gen_set_got (operands[2]));
15644 if (TARGET_GNU2_TLS)
15646 emit_insn (gen_tls_dynamic_gnu2_32
15647 (operands[0], operands[1], operands[2]));
15650 operands[3] = ix86_tls_get_addr ();
15653 (define_insn "*tls_global_dynamic_64"
15654 [(set (match_operand:DI 0 "register_operand" "=a")
15655 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15656 (match_operand:DI 3 "" "")))
15657 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15660 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15661 [(set_attr "type" "multi")
15662 (set_attr "length" "16")])
15664 (define_expand "tls_global_dynamic_64"
15665 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15666 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15667 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15671 if (TARGET_GNU2_TLS)
15673 emit_insn (gen_tls_dynamic_gnu2_64
15674 (operands[0], operands[1]));
15677 operands[2] = ix86_tls_get_addr ();
15680 (define_insn "*tls_local_dynamic_base_32_gnu"
15681 [(set (match_operand:SI 0 "register_operand" "=a")
15682 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15683 (match_operand:SI 2 "call_insn_operand" "")]
15684 UNSPEC_TLS_LD_BASE))
15685 (clobber (match_scratch:SI 3 "=d"))
15686 (clobber (match_scratch:SI 4 "=c"))
15687 (clobber (reg:CC FLAGS_REG))]
15688 "!TARGET_64BIT && TARGET_GNU_TLS"
15689 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15690 [(set_attr "type" "multi")
15691 (set_attr "length" "11")])
15693 (define_insn "*tls_local_dynamic_base_32_sun"
15694 [(set (match_operand:SI 0 "register_operand" "=a")
15695 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15696 (match_operand:SI 2 "call_insn_operand" "")]
15697 UNSPEC_TLS_LD_BASE))
15698 (clobber (match_scratch:SI 3 "=d"))
15699 (clobber (match_scratch:SI 4 "=c"))
15700 (clobber (reg:CC FLAGS_REG))]
15701 "!TARGET_64BIT && TARGET_SUN_TLS"
15702 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15703 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15704 [(set_attr "type" "multi")
15705 (set_attr "length" "13")])
15707 (define_expand "tls_local_dynamic_base_32"
15708 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15709 (unspec:SI [(match_dup 1) (match_dup 2)]
15710 UNSPEC_TLS_LD_BASE))
15711 (clobber (match_scratch:SI 3 ""))
15712 (clobber (match_scratch:SI 4 ""))
15713 (clobber (reg:CC FLAGS_REG))])]
15717 operands[1] = pic_offset_table_rtx;
15720 operands[1] = gen_reg_rtx (Pmode);
15721 emit_insn (gen_set_got (operands[1]));
15723 if (TARGET_GNU2_TLS)
15725 emit_insn (gen_tls_dynamic_gnu2_32
15726 (operands[0], ix86_tls_module_base (), operands[1]));
15729 operands[2] = ix86_tls_get_addr ();
15732 (define_insn "*tls_local_dynamic_base_64"
15733 [(set (match_operand:DI 0 "register_operand" "=a")
15734 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15735 (match_operand:DI 2 "" "")))
15736 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15738 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15739 [(set_attr "type" "multi")
15740 (set_attr "length" "12")])
15742 (define_expand "tls_local_dynamic_base_64"
15743 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15744 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15745 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15748 if (TARGET_GNU2_TLS)
15750 emit_insn (gen_tls_dynamic_gnu2_64
15751 (operands[0], ix86_tls_module_base ()));
15754 operands[1] = ix86_tls_get_addr ();
15757 ;; Local dynamic of a single variable is a lose. Show combine how
15758 ;; to convert that back to global dynamic.
15760 (define_insn_and_split "*tls_local_dynamic_32_once"
15761 [(set (match_operand:SI 0 "register_operand" "=a")
15762 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15763 (match_operand:SI 2 "call_insn_operand" "")]
15764 UNSPEC_TLS_LD_BASE)
15765 (const:SI (unspec:SI
15766 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15768 (clobber (match_scratch:SI 4 "=d"))
15769 (clobber (match_scratch:SI 5 "=c"))
15770 (clobber (reg:CC FLAGS_REG))]
15774 [(parallel [(set (match_dup 0)
15775 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15777 (clobber (match_dup 4))
15778 (clobber (match_dup 5))
15779 (clobber (reg:CC FLAGS_REG))])]
15782 ;; Load and add the thread base pointer from %gs:0.
15784 (define_insn "*load_tp_si"
15785 [(set (match_operand:SI 0 "register_operand" "=r")
15786 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15788 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15789 [(set_attr "type" "imov")
15790 (set_attr "modrm" "0")
15791 (set_attr "length" "7")
15792 (set_attr "memory" "load")
15793 (set_attr "imm_disp" "false")])
15795 (define_insn "*add_tp_si"
15796 [(set (match_operand:SI 0 "register_operand" "=r")
15797 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15798 (match_operand:SI 1 "register_operand" "0")))
15799 (clobber (reg:CC FLAGS_REG))]
15801 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15802 [(set_attr "type" "alu")
15803 (set_attr "modrm" "0")
15804 (set_attr "length" "7")
15805 (set_attr "memory" "load")
15806 (set_attr "imm_disp" "false")])
15808 (define_insn "*load_tp_di"
15809 [(set (match_operand:DI 0 "register_operand" "=r")
15810 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15812 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15813 [(set_attr "type" "imov")
15814 (set_attr "modrm" "0")
15815 (set_attr "length" "7")
15816 (set_attr "memory" "load")
15817 (set_attr "imm_disp" "false")])
15819 (define_insn "*add_tp_di"
15820 [(set (match_operand:DI 0 "register_operand" "=r")
15821 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15822 (match_operand:DI 1 "register_operand" "0")))
15823 (clobber (reg:CC FLAGS_REG))]
15825 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15826 [(set_attr "type" "alu")
15827 (set_attr "modrm" "0")
15828 (set_attr "length" "7")
15829 (set_attr "memory" "load")
15830 (set_attr "imm_disp" "false")])
15832 ;; GNU2 TLS patterns can be split.
15834 (define_expand "tls_dynamic_gnu2_32"
15835 [(set (match_dup 3)
15836 (plus:SI (match_operand:SI 2 "register_operand" "")
15838 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15841 [(set (match_operand:SI 0 "register_operand" "")
15842 (unspec:SI [(match_dup 1) (match_dup 3)
15843 (match_dup 2) (reg:SI SP_REG)]
15845 (clobber (reg:CC FLAGS_REG))])]
15846 "!TARGET_64BIT && TARGET_GNU2_TLS"
15848 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15849 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15852 (define_insn "*tls_dynamic_lea_32"
15853 [(set (match_operand:SI 0 "register_operand" "=r")
15854 (plus:SI (match_operand:SI 1 "register_operand" "b")
15856 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15857 UNSPEC_TLSDESC))))]
15858 "!TARGET_64BIT && TARGET_GNU2_TLS"
15859 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15860 [(set_attr "type" "lea")
15861 (set_attr "mode" "SI")
15862 (set_attr "length" "6")
15863 (set_attr "length_address" "4")])
15865 (define_insn "*tls_dynamic_call_32"
15866 [(set (match_operand:SI 0 "register_operand" "=a")
15867 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15868 (match_operand:SI 2 "register_operand" "0")
15869 ;; we have to make sure %ebx still points to the GOT
15870 (match_operand:SI 3 "register_operand" "b")
15873 (clobber (reg:CC FLAGS_REG))]
15874 "!TARGET_64BIT && TARGET_GNU2_TLS"
15875 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15876 [(set_attr "type" "call")
15877 (set_attr "length" "2")
15878 (set_attr "length_address" "0")])
15880 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15881 [(set (match_operand:SI 0 "register_operand" "=&a")
15883 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15884 (match_operand:SI 4 "" "")
15885 (match_operand:SI 2 "register_operand" "b")
15888 (const:SI (unspec:SI
15889 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15891 (clobber (reg:CC FLAGS_REG))]
15892 "!TARGET_64BIT && TARGET_GNU2_TLS"
15895 [(set (match_dup 0) (match_dup 5))]
15897 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15898 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15901 (define_expand "tls_dynamic_gnu2_64"
15902 [(set (match_dup 2)
15903 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15906 [(set (match_operand:DI 0 "register_operand" "")
15907 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15909 (clobber (reg:CC FLAGS_REG))])]
15910 "TARGET_64BIT && TARGET_GNU2_TLS"
15912 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15913 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15916 (define_insn "*tls_dynamic_lea_64"
15917 [(set (match_operand:DI 0 "register_operand" "=r")
15918 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15920 "TARGET_64BIT && TARGET_GNU2_TLS"
15921 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15922 [(set_attr "type" "lea")
15923 (set_attr "mode" "DI")
15924 (set_attr "length" "7")
15925 (set_attr "length_address" "4")])
15927 (define_insn "*tls_dynamic_call_64"
15928 [(set (match_operand:DI 0 "register_operand" "=a")
15929 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15930 (match_operand:DI 2 "register_operand" "0")
15933 (clobber (reg:CC FLAGS_REG))]
15934 "TARGET_64BIT && TARGET_GNU2_TLS"
15935 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15936 [(set_attr "type" "call")
15937 (set_attr "length" "2")
15938 (set_attr "length_address" "0")])
15940 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15941 [(set (match_operand:DI 0 "register_operand" "=&a")
15943 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15944 (match_operand:DI 3 "" "")
15947 (const:DI (unspec:DI
15948 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15950 (clobber (reg:CC FLAGS_REG))]
15951 "TARGET_64BIT && TARGET_GNU2_TLS"
15954 [(set (match_dup 0) (match_dup 4))]
15956 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15957 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15962 ;; These patterns match the binary 387 instructions for addM3, subM3,
15963 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15964 ;; SFmode. The first is the normal insn, the second the same insn but
15965 ;; with one operand a conversion, and the third the same insn but with
15966 ;; the other operand a conversion. The conversion may be SFmode or
15967 ;; SImode if the target mode DFmode, but only SImode if the target mode
15970 ;; Gcc is slightly more smart about handling normal two address instructions
15971 ;; so use special patterns for add and mull.
15973 (define_insn "*fop_<mode>_comm_mixed"
15974 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15975 (match_operator:MODEF 3 "binary_fp_operator"
15976 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15977 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15978 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15979 && COMMUTATIVE_ARITH_P (operands[3])
15980 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15981 "* return output_387_binary_op (insn, operands);"
15982 [(set (attr "type")
15983 (if_then_else (eq_attr "alternative" "1")
15984 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15985 (const_string "ssemul")
15986 (const_string "sseadd"))
15987 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15988 (const_string "fmul")
15989 (const_string "fop"))))
15990 (set_attr "mode" "<MODE>")])
15992 (define_insn "*fop_<mode>_comm_sse"
15993 [(set (match_operand:MODEF 0 "register_operand" "=x")
15994 (match_operator:MODEF 3 "binary_fp_operator"
15995 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15996 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15997 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15998 && COMMUTATIVE_ARITH_P (operands[3])
15999 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16000 "* return output_387_binary_op (insn, operands);"
16001 [(set (attr "type")
16002 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16003 (const_string "ssemul")
16004 (const_string "sseadd")))
16005 (set_attr "mode" "<MODE>")])
16007 (define_insn "*fop_<mode>_comm_i387"
16008 [(set (match_operand:MODEF 0 "register_operand" "=f")
16009 (match_operator:MODEF 3 "binary_fp_operator"
16010 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16011 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16013 && COMMUTATIVE_ARITH_P (operands[3])
16014 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16015 "* return output_387_binary_op (insn, operands);"
16016 [(set (attr "type")
16017 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16018 (const_string "fmul")
16019 (const_string "fop")))
16020 (set_attr "mode" "<MODE>")])
16022 (define_insn "*fop_<mode>_1_mixed"
16023 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16024 (match_operator:MODEF 3 "binary_fp_operator"
16025 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16026 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16027 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16028 && !COMMUTATIVE_ARITH_P (operands[3])
16029 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16030 "* return output_387_binary_op (insn, operands);"
16031 [(set (attr "type")
16032 (cond [(and (eq_attr "alternative" "2")
16033 (match_operand:MODEF 3 "mult_operator" ""))
16034 (const_string "ssemul")
16035 (and (eq_attr "alternative" "2")
16036 (match_operand:MODEF 3 "div_operator" ""))
16037 (const_string "ssediv")
16038 (eq_attr "alternative" "2")
16039 (const_string "sseadd")
16040 (match_operand:MODEF 3 "mult_operator" "")
16041 (const_string "fmul")
16042 (match_operand:MODEF 3 "div_operator" "")
16043 (const_string "fdiv")
16045 (const_string "fop")))
16046 (set_attr "mode" "<MODE>")])
16048 (define_insn "*rcpsf2_sse"
16049 [(set (match_operand:SF 0 "register_operand" "=x")
16050 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16053 "rcpss\t{%1, %0|%0, %1}"
16054 [(set_attr "type" "sse")
16055 (set_attr "mode" "SF")])
16057 (define_insn "*fop_<mode>_1_sse"
16058 [(set (match_operand:MODEF 0 "register_operand" "=x")
16059 (match_operator:MODEF 3 "binary_fp_operator"
16060 [(match_operand:MODEF 1 "register_operand" "0")
16061 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16062 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16063 && !COMMUTATIVE_ARITH_P (operands[3])"
16064 "* return output_387_binary_op (insn, operands);"
16065 [(set (attr "type")
16066 (cond [(match_operand:MODEF 3 "mult_operator" "")
16067 (const_string "ssemul")
16068 (match_operand:MODEF 3 "div_operator" "")
16069 (const_string "ssediv")
16071 (const_string "sseadd")))
16072 (set_attr "mode" "<MODE>")])
16074 ;; This pattern is not fully shadowed by the pattern above.
16075 (define_insn "*fop_<mode>_1_i387"
16076 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16077 (match_operator:MODEF 3 "binary_fp_operator"
16078 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16079 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16080 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16081 && !COMMUTATIVE_ARITH_P (operands[3])
16082 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16083 "* return output_387_binary_op (insn, operands);"
16084 [(set (attr "type")
16085 (cond [(match_operand:MODEF 3 "mult_operator" "")
16086 (const_string "fmul")
16087 (match_operand:MODEF 3 "div_operator" "")
16088 (const_string "fdiv")
16090 (const_string "fop")))
16091 (set_attr "mode" "<MODE>")])
16093 ;; ??? Add SSE splitters for these!
16094 (define_insn "*fop_<MODEF:mode>_2_i387"
16095 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16096 (match_operator:MODEF 3 "binary_fp_operator"
16098 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16099 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16100 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16101 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16102 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16103 [(set (attr "type")
16104 (cond [(match_operand:MODEF 3 "mult_operator" "")
16105 (const_string "fmul")
16106 (match_operand:MODEF 3 "div_operator" "")
16107 (const_string "fdiv")
16109 (const_string "fop")))
16110 (set_attr "fp_int_src" "true")
16111 (set_attr "mode" "<X87MODEI12:MODE>")])
16113 (define_insn "*fop_<MODEF:mode>_3_i387"
16114 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16115 (match_operator:MODEF 3 "binary_fp_operator"
16116 [(match_operand:MODEF 1 "register_operand" "0,0")
16118 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16119 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16120 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16121 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16122 [(set (attr "type")
16123 (cond [(match_operand:MODEF 3 "mult_operator" "")
16124 (const_string "fmul")
16125 (match_operand:MODEF 3 "div_operator" "")
16126 (const_string "fdiv")
16128 (const_string "fop")))
16129 (set_attr "fp_int_src" "true")
16130 (set_attr "mode" "<MODE>")])
16132 (define_insn "*fop_df_4_i387"
16133 [(set (match_operand:DF 0 "register_operand" "=f,f")
16134 (match_operator:DF 3 "binary_fp_operator"
16136 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16137 (match_operand:DF 2 "register_operand" "0,f")]))]
16138 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16139 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16140 "* return output_387_binary_op (insn, operands);"
16141 [(set (attr "type")
16142 (cond [(match_operand:DF 3 "mult_operator" "")
16143 (const_string "fmul")
16144 (match_operand:DF 3 "div_operator" "")
16145 (const_string "fdiv")
16147 (const_string "fop")))
16148 (set_attr "mode" "SF")])
16150 (define_insn "*fop_df_5_i387"
16151 [(set (match_operand:DF 0 "register_operand" "=f,f")
16152 (match_operator:DF 3 "binary_fp_operator"
16153 [(match_operand:DF 1 "register_operand" "0,f")
16155 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16156 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16157 "* return output_387_binary_op (insn, operands);"
16158 [(set (attr "type")
16159 (cond [(match_operand:DF 3 "mult_operator" "")
16160 (const_string "fmul")
16161 (match_operand:DF 3 "div_operator" "")
16162 (const_string "fdiv")
16164 (const_string "fop")))
16165 (set_attr "mode" "SF")])
16167 (define_insn "*fop_df_6_i387"
16168 [(set (match_operand:DF 0 "register_operand" "=f,f")
16169 (match_operator:DF 3 "binary_fp_operator"
16171 (match_operand:SF 1 "register_operand" "0,f"))
16173 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16174 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16175 "* return output_387_binary_op (insn, operands);"
16176 [(set (attr "type")
16177 (cond [(match_operand:DF 3 "mult_operator" "")
16178 (const_string "fmul")
16179 (match_operand:DF 3 "div_operator" "")
16180 (const_string "fdiv")
16182 (const_string "fop")))
16183 (set_attr "mode" "SF")])
16185 (define_insn "*fop_xf_comm_i387"
16186 [(set (match_operand:XF 0 "register_operand" "=f")
16187 (match_operator:XF 3 "binary_fp_operator"
16188 [(match_operand:XF 1 "register_operand" "%0")
16189 (match_operand:XF 2 "register_operand" "f")]))]
16191 && COMMUTATIVE_ARITH_P (operands[3])"
16192 "* return output_387_binary_op (insn, operands);"
16193 [(set (attr "type")
16194 (if_then_else (match_operand:XF 3 "mult_operator" "")
16195 (const_string "fmul")
16196 (const_string "fop")))
16197 (set_attr "mode" "XF")])
16199 (define_insn "*fop_xf_1_i387"
16200 [(set (match_operand:XF 0 "register_operand" "=f,f")
16201 (match_operator:XF 3 "binary_fp_operator"
16202 [(match_operand:XF 1 "register_operand" "0,f")
16203 (match_operand:XF 2 "register_operand" "f,0")]))]
16205 && !COMMUTATIVE_ARITH_P (operands[3])"
16206 "* return output_387_binary_op (insn, operands);"
16207 [(set (attr "type")
16208 (cond [(match_operand:XF 3 "mult_operator" "")
16209 (const_string "fmul")
16210 (match_operand:XF 3 "div_operator" "")
16211 (const_string "fdiv")
16213 (const_string "fop")))
16214 (set_attr "mode" "XF")])
16216 (define_insn "*fop_xf_2_i387"
16217 [(set (match_operand:XF 0 "register_operand" "=f,f")
16218 (match_operator:XF 3 "binary_fp_operator"
16220 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16221 (match_operand:XF 2 "register_operand" "0,0")]))]
16222 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16223 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16224 [(set (attr "type")
16225 (cond [(match_operand:XF 3 "mult_operator" "")
16226 (const_string "fmul")
16227 (match_operand:XF 3 "div_operator" "")
16228 (const_string "fdiv")
16230 (const_string "fop")))
16231 (set_attr "fp_int_src" "true")
16232 (set_attr "mode" "<MODE>")])
16234 (define_insn "*fop_xf_3_i387"
16235 [(set (match_operand:XF 0 "register_operand" "=f,f")
16236 (match_operator:XF 3 "binary_fp_operator"
16237 [(match_operand:XF 1 "register_operand" "0,0")
16239 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16240 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16241 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16242 [(set (attr "type")
16243 (cond [(match_operand:XF 3 "mult_operator" "")
16244 (const_string "fmul")
16245 (match_operand:XF 3 "div_operator" "")
16246 (const_string "fdiv")
16248 (const_string "fop")))
16249 (set_attr "fp_int_src" "true")
16250 (set_attr "mode" "<MODE>")])
16252 (define_insn "*fop_xf_4_i387"
16253 [(set (match_operand:XF 0 "register_operand" "=f,f")
16254 (match_operator:XF 3 "binary_fp_operator"
16256 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16257 (match_operand:XF 2 "register_operand" "0,f")]))]
16259 "* return output_387_binary_op (insn, operands);"
16260 [(set (attr "type")
16261 (cond [(match_operand:XF 3 "mult_operator" "")
16262 (const_string "fmul")
16263 (match_operand:XF 3 "div_operator" "")
16264 (const_string "fdiv")
16266 (const_string "fop")))
16267 (set_attr "mode" "<MODE>")])
16269 (define_insn "*fop_xf_5_i387"
16270 [(set (match_operand:XF 0 "register_operand" "=f,f")
16271 (match_operator:XF 3 "binary_fp_operator"
16272 [(match_operand:XF 1 "register_operand" "0,f")
16274 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16276 "* return output_387_binary_op (insn, operands);"
16277 [(set (attr "type")
16278 (cond [(match_operand:XF 3 "mult_operator" "")
16279 (const_string "fmul")
16280 (match_operand:XF 3 "div_operator" "")
16281 (const_string "fdiv")
16283 (const_string "fop")))
16284 (set_attr "mode" "<MODE>")])
16286 (define_insn "*fop_xf_6_i387"
16287 [(set (match_operand:XF 0 "register_operand" "=f,f")
16288 (match_operator:XF 3 "binary_fp_operator"
16290 (match_operand:MODEF 1 "register_operand" "0,f"))
16292 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16294 "* return output_387_binary_op (insn, operands);"
16295 [(set (attr "type")
16296 (cond [(match_operand:XF 3 "mult_operator" "")
16297 (const_string "fmul")
16298 (match_operand:XF 3 "div_operator" "")
16299 (const_string "fdiv")
16301 (const_string "fop")))
16302 (set_attr "mode" "<MODE>")])
16305 [(set (match_operand 0 "register_operand" "")
16306 (match_operator 3 "binary_fp_operator"
16307 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16308 (match_operand 2 "register_operand" "")]))]
16310 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16313 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16314 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16315 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16316 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16317 GET_MODE (operands[3]),
16320 ix86_free_from_memory (GET_MODE (operands[1]));
16325 [(set (match_operand 0 "register_operand" "")
16326 (match_operator 3 "binary_fp_operator"
16327 [(match_operand 1 "register_operand" "")
16328 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16330 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16333 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16334 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16335 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16336 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16337 GET_MODE (operands[3]),
16340 ix86_free_from_memory (GET_MODE (operands[2]));
16344 ;; FPU special functions.
16346 ;; This pattern implements a no-op XFmode truncation for
16347 ;; all fancy i386 XFmode math functions.
16349 (define_insn "truncxf<mode>2_i387_noop_unspec"
16350 [(set (match_operand:MODEF 0 "register_operand" "=f")
16351 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16352 UNSPEC_TRUNC_NOOP))]
16353 "TARGET_USE_FANCY_MATH_387"
16354 "* return output_387_reg_move (insn, operands);"
16355 [(set_attr "type" "fmov")
16356 (set_attr "mode" "<MODE>")])
16358 (define_insn "sqrtxf2"
16359 [(set (match_operand:XF 0 "register_operand" "=f")
16360 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16361 "TARGET_USE_FANCY_MATH_387"
16363 [(set_attr "type" "fpspc")
16364 (set_attr "mode" "XF")
16365 (set_attr "athlon_decode" "direct")
16366 (set_attr "amdfam10_decode" "direct")])
16368 (define_insn "sqrt_extend<mode>xf2_i387"
16369 [(set (match_operand:XF 0 "register_operand" "=f")
16372 (match_operand:MODEF 1 "register_operand" "0"))))]
16373 "TARGET_USE_FANCY_MATH_387"
16375 [(set_attr "type" "fpspc")
16376 (set_attr "mode" "XF")
16377 (set_attr "athlon_decode" "direct")
16378 (set_attr "amdfam10_decode" "direct")])
16380 (define_insn "*rsqrtsf2_sse"
16381 [(set (match_operand:SF 0 "register_operand" "=x")
16382 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16385 "rsqrtss\t{%1, %0|%0, %1}"
16386 [(set_attr "type" "sse")
16387 (set_attr "mode" "SF")])
16389 (define_expand "rsqrtsf2"
16390 [(set (match_operand:SF 0 "register_operand" "")
16391 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16395 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16399 (define_insn "*sqrt<mode>2_sse"
16400 [(set (match_operand:MODEF 0 "register_operand" "=x")
16402 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16403 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16404 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16405 [(set_attr "type" "sse")
16406 (set_attr "mode" "<MODE>")
16407 (set_attr "athlon_decode" "*")
16408 (set_attr "amdfam10_decode" "*")])
16410 (define_expand "sqrt<mode>2"
16411 [(set (match_operand:MODEF 0 "register_operand" "")
16413 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16414 "TARGET_USE_FANCY_MATH_387
16415 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16417 if (<MODE>mode == SFmode
16418 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16419 && flag_finite_math_only && !flag_trapping_math
16420 && flag_unsafe_math_optimizations)
16422 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16426 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16428 rtx op0 = gen_reg_rtx (XFmode);
16429 rtx op1 = force_reg (<MODE>mode, operands[1]);
16431 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16432 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16437 (define_insn "fpremxf4_i387"
16438 [(set (match_operand:XF 0 "register_operand" "=f")
16439 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16440 (match_operand:XF 3 "register_operand" "1")]
16442 (set (match_operand:XF 1 "register_operand" "=u")
16443 (unspec:XF [(match_dup 2) (match_dup 3)]
16445 (set (reg:CCFP FPSR_REG)
16446 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16448 "TARGET_USE_FANCY_MATH_387"
16450 [(set_attr "type" "fpspc")
16451 (set_attr "mode" "XF")])
16453 (define_expand "fmodxf3"
16454 [(use (match_operand:XF 0 "register_operand" ""))
16455 (use (match_operand:XF 1 "general_operand" ""))
16456 (use (match_operand:XF 2 "general_operand" ""))]
16457 "TARGET_USE_FANCY_MATH_387"
16459 rtx label = gen_label_rtx ();
16461 rtx op1 = gen_reg_rtx (XFmode);
16462 rtx op2 = gen_reg_rtx (XFmode);
16464 emit_move_insn (op2, operands[2]);
16465 emit_move_insn (op1, operands[1]);
16467 emit_label (label);
16468 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16469 ix86_emit_fp_unordered_jump (label);
16470 LABEL_NUSES (label) = 1;
16472 emit_move_insn (operands[0], op1);
16476 (define_expand "fmod<mode>3"
16477 [(use (match_operand:MODEF 0 "register_operand" ""))
16478 (use (match_operand:MODEF 1 "general_operand" ""))
16479 (use (match_operand:MODEF 2 "general_operand" ""))]
16480 "TARGET_USE_FANCY_MATH_387"
16482 rtx label = gen_label_rtx ();
16484 rtx op1 = gen_reg_rtx (XFmode);
16485 rtx op2 = gen_reg_rtx (XFmode);
16487 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16488 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16490 emit_label (label);
16491 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16492 ix86_emit_fp_unordered_jump (label);
16493 LABEL_NUSES (label) = 1;
16495 /* Truncate the result properly for strict SSE math. */
16496 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16497 && !TARGET_MIX_SSE_I387)
16498 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16500 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16505 (define_insn "fprem1xf4_i387"
16506 [(set (match_operand:XF 0 "register_operand" "=f")
16507 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16508 (match_operand:XF 3 "register_operand" "1")]
16510 (set (match_operand:XF 1 "register_operand" "=u")
16511 (unspec:XF [(match_dup 2) (match_dup 3)]
16513 (set (reg:CCFP FPSR_REG)
16514 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16516 "TARGET_USE_FANCY_MATH_387"
16518 [(set_attr "type" "fpspc")
16519 (set_attr "mode" "XF")])
16521 (define_expand "remainderxf3"
16522 [(use (match_operand:XF 0 "register_operand" ""))
16523 (use (match_operand:XF 1 "general_operand" ""))
16524 (use (match_operand:XF 2 "general_operand" ""))]
16525 "TARGET_USE_FANCY_MATH_387"
16527 rtx label = gen_label_rtx ();
16529 rtx op1 = gen_reg_rtx (XFmode);
16530 rtx op2 = gen_reg_rtx (XFmode);
16532 emit_move_insn (op2, operands[2]);
16533 emit_move_insn (op1, operands[1]);
16535 emit_label (label);
16536 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16537 ix86_emit_fp_unordered_jump (label);
16538 LABEL_NUSES (label) = 1;
16540 emit_move_insn (operands[0], op1);
16544 (define_expand "remainder<mode>3"
16545 [(use (match_operand:MODEF 0 "register_operand" ""))
16546 (use (match_operand:MODEF 1 "general_operand" ""))
16547 (use (match_operand:MODEF 2 "general_operand" ""))]
16548 "TARGET_USE_FANCY_MATH_387"
16550 rtx label = gen_label_rtx ();
16552 rtx op1 = gen_reg_rtx (XFmode);
16553 rtx op2 = gen_reg_rtx (XFmode);
16555 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16556 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16558 emit_label (label);
16560 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16561 ix86_emit_fp_unordered_jump (label);
16562 LABEL_NUSES (label) = 1;
16564 /* Truncate the result properly for strict SSE math. */
16565 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16566 && !TARGET_MIX_SSE_I387)
16567 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16569 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16574 (define_insn "*sinxf2_i387"
16575 [(set (match_operand:XF 0 "register_operand" "=f")
16576 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16577 "TARGET_USE_FANCY_MATH_387
16578 && flag_unsafe_math_optimizations"
16580 [(set_attr "type" "fpspc")
16581 (set_attr "mode" "XF")])
16583 (define_insn "*sin_extend<mode>xf2_i387"
16584 [(set (match_operand:XF 0 "register_operand" "=f")
16585 (unspec:XF [(float_extend:XF
16586 (match_operand:MODEF 1 "register_operand" "0"))]
16588 "TARGET_USE_FANCY_MATH_387
16589 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16590 || TARGET_MIX_SSE_I387)
16591 && flag_unsafe_math_optimizations"
16593 [(set_attr "type" "fpspc")
16594 (set_attr "mode" "XF")])
16596 (define_insn "*cosxf2_i387"
16597 [(set (match_operand:XF 0 "register_operand" "=f")
16598 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16599 "TARGET_USE_FANCY_MATH_387
16600 && flag_unsafe_math_optimizations"
16602 [(set_attr "type" "fpspc")
16603 (set_attr "mode" "XF")])
16605 (define_insn "*cos_extend<mode>xf2_i387"
16606 [(set (match_operand:XF 0 "register_operand" "=f")
16607 (unspec:XF [(float_extend:XF
16608 (match_operand:MODEF 1 "register_operand" "0"))]
16610 "TARGET_USE_FANCY_MATH_387
16611 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16612 || TARGET_MIX_SSE_I387)
16613 && flag_unsafe_math_optimizations"
16615 [(set_attr "type" "fpspc")
16616 (set_attr "mode" "XF")])
16618 ;; When sincos pattern is defined, sin and cos builtin functions will be
16619 ;; expanded to sincos pattern with one of its outputs left unused.
16620 ;; CSE pass will figure out if two sincos patterns can be combined,
16621 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16622 ;; depending on the unused output.
16624 (define_insn "sincosxf3"
16625 [(set (match_operand:XF 0 "register_operand" "=f")
16626 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16627 UNSPEC_SINCOS_COS))
16628 (set (match_operand:XF 1 "register_operand" "=u")
16629 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16630 "TARGET_USE_FANCY_MATH_387
16631 && flag_unsafe_math_optimizations"
16633 [(set_attr "type" "fpspc")
16634 (set_attr "mode" "XF")])
16637 [(set (match_operand:XF 0 "register_operand" "")
16638 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16639 UNSPEC_SINCOS_COS))
16640 (set (match_operand:XF 1 "register_operand" "")
16641 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16642 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16643 && !(reload_completed || reload_in_progress)"
16644 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16648 [(set (match_operand:XF 0 "register_operand" "")
16649 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16650 UNSPEC_SINCOS_COS))
16651 (set (match_operand:XF 1 "register_operand" "")
16652 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16653 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16654 && !(reload_completed || reload_in_progress)"
16655 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16658 (define_insn "sincos_extend<mode>xf3_i387"
16659 [(set (match_operand:XF 0 "register_operand" "=f")
16660 (unspec:XF [(float_extend:XF
16661 (match_operand:MODEF 2 "register_operand" "0"))]
16662 UNSPEC_SINCOS_COS))
16663 (set (match_operand:XF 1 "register_operand" "=u")
16664 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16665 "TARGET_USE_FANCY_MATH_387
16666 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16667 || TARGET_MIX_SSE_I387)
16668 && flag_unsafe_math_optimizations"
16670 [(set_attr "type" "fpspc")
16671 (set_attr "mode" "XF")])
16674 [(set (match_operand:XF 0 "register_operand" "")
16675 (unspec:XF [(float_extend:XF
16676 (match_operand:MODEF 2 "register_operand" ""))]
16677 UNSPEC_SINCOS_COS))
16678 (set (match_operand:XF 1 "register_operand" "")
16679 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16680 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16681 && !(reload_completed || reload_in_progress)"
16682 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16686 [(set (match_operand:XF 0 "register_operand" "")
16687 (unspec:XF [(float_extend:XF
16688 (match_operand:MODEF 2 "register_operand" ""))]
16689 UNSPEC_SINCOS_COS))
16690 (set (match_operand:XF 1 "register_operand" "")
16691 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16692 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16693 && !(reload_completed || reload_in_progress)"
16694 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16697 (define_expand "sincos<mode>3"
16698 [(use (match_operand:MODEF 0 "register_operand" ""))
16699 (use (match_operand:MODEF 1 "register_operand" ""))
16700 (use (match_operand:MODEF 2 "register_operand" ""))]
16701 "TARGET_USE_FANCY_MATH_387
16702 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16703 || TARGET_MIX_SSE_I387)
16704 && flag_unsafe_math_optimizations"
16706 rtx op0 = gen_reg_rtx (XFmode);
16707 rtx op1 = gen_reg_rtx (XFmode);
16709 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16710 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16711 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16715 (define_insn "fptanxf4_i387"
16716 [(set (match_operand:XF 0 "register_operand" "=f")
16717 (match_operand:XF 3 "const_double_operand" "F"))
16718 (set (match_operand:XF 1 "register_operand" "=u")
16719 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16721 "TARGET_USE_FANCY_MATH_387
16722 && flag_unsafe_math_optimizations
16723 && standard_80387_constant_p (operands[3]) == 2"
16725 [(set_attr "type" "fpspc")
16726 (set_attr "mode" "XF")])
16728 (define_insn "fptan_extend<mode>xf4_i387"
16729 [(set (match_operand:MODEF 0 "register_operand" "=f")
16730 (match_operand:MODEF 3 "const_double_operand" "F"))
16731 (set (match_operand:XF 1 "register_operand" "=u")
16732 (unspec:XF [(float_extend:XF
16733 (match_operand:MODEF 2 "register_operand" "0"))]
16735 "TARGET_USE_FANCY_MATH_387
16736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16737 || TARGET_MIX_SSE_I387)
16738 && flag_unsafe_math_optimizations
16739 && standard_80387_constant_p (operands[3]) == 2"
16741 [(set_attr "type" "fpspc")
16742 (set_attr "mode" "XF")])
16744 (define_expand "tanxf2"
16745 [(use (match_operand:XF 0 "register_operand" ""))
16746 (use (match_operand:XF 1 "register_operand" ""))]
16747 "TARGET_USE_FANCY_MATH_387
16748 && flag_unsafe_math_optimizations"
16750 rtx one = gen_reg_rtx (XFmode);
16751 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16753 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16757 (define_expand "tan<mode>2"
16758 [(use (match_operand:MODEF 0 "register_operand" ""))
16759 (use (match_operand:MODEF 1 "register_operand" ""))]
16760 "TARGET_USE_FANCY_MATH_387
16761 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16762 || TARGET_MIX_SSE_I387)
16763 && flag_unsafe_math_optimizations"
16765 rtx op0 = gen_reg_rtx (XFmode);
16767 rtx one = gen_reg_rtx (<MODE>mode);
16768 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16770 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16771 operands[1], op2));
16772 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16776 (define_insn "*fpatanxf3_i387"
16777 [(set (match_operand:XF 0 "register_operand" "=f")
16778 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16779 (match_operand:XF 2 "register_operand" "u")]
16781 (clobber (match_scratch:XF 3 "=2"))]
16782 "TARGET_USE_FANCY_MATH_387
16783 && flag_unsafe_math_optimizations"
16785 [(set_attr "type" "fpspc")
16786 (set_attr "mode" "XF")])
16788 (define_insn "fpatan_extend<mode>xf3_i387"
16789 [(set (match_operand:XF 0 "register_operand" "=f")
16790 (unspec:XF [(float_extend:XF
16791 (match_operand:MODEF 1 "register_operand" "0"))
16793 (match_operand:MODEF 2 "register_operand" "u"))]
16795 (clobber (match_scratch:XF 3 "=2"))]
16796 "TARGET_USE_FANCY_MATH_387
16797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16798 || TARGET_MIX_SSE_I387)
16799 && flag_unsafe_math_optimizations"
16801 [(set_attr "type" "fpspc")
16802 (set_attr "mode" "XF")])
16804 (define_expand "atan2xf3"
16805 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16806 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16807 (match_operand:XF 1 "register_operand" "")]
16809 (clobber (match_scratch:XF 3 ""))])]
16810 "TARGET_USE_FANCY_MATH_387
16811 && flag_unsafe_math_optimizations"
16814 (define_expand "atan2<mode>3"
16815 [(use (match_operand:MODEF 0 "register_operand" ""))
16816 (use (match_operand:MODEF 1 "register_operand" ""))
16817 (use (match_operand:MODEF 2 "register_operand" ""))]
16818 "TARGET_USE_FANCY_MATH_387
16819 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16820 || TARGET_MIX_SSE_I387)
16821 && flag_unsafe_math_optimizations"
16823 rtx op0 = gen_reg_rtx (XFmode);
16825 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16826 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16830 (define_expand "atanxf2"
16831 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16832 (unspec:XF [(match_dup 2)
16833 (match_operand:XF 1 "register_operand" "")]
16835 (clobber (match_scratch:XF 3 ""))])]
16836 "TARGET_USE_FANCY_MATH_387
16837 && flag_unsafe_math_optimizations"
16839 operands[2] = gen_reg_rtx (XFmode);
16840 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16843 (define_expand "atan<mode>2"
16844 [(use (match_operand:MODEF 0 "register_operand" ""))
16845 (use (match_operand:MODEF 1 "register_operand" ""))]
16846 "TARGET_USE_FANCY_MATH_387
16847 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16848 || TARGET_MIX_SSE_I387)
16849 && flag_unsafe_math_optimizations"
16851 rtx op0 = gen_reg_rtx (XFmode);
16853 rtx op2 = gen_reg_rtx (<MODE>mode);
16854 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16856 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16857 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16861 (define_expand "asinxf2"
16862 [(set (match_dup 2)
16863 (mult:XF (match_operand:XF 1 "register_operand" "")
16865 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16866 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16867 (parallel [(set (match_operand:XF 0 "register_operand" "")
16868 (unspec:XF [(match_dup 5) (match_dup 1)]
16870 (clobber (match_scratch:XF 6 ""))])]
16871 "TARGET_USE_FANCY_MATH_387
16872 && flag_unsafe_math_optimizations && !optimize_size"
16876 for (i = 2; i < 6; i++)
16877 operands[i] = gen_reg_rtx (XFmode);
16879 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16882 (define_expand "asin<mode>2"
16883 [(use (match_operand:MODEF 0 "register_operand" ""))
16884 (use (match_operand:MODEF 1 "general_operand" ""))]
16885 "TARGET_USE_FANCY_MATH_387
16886 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16887 || TARGET_MIX_SSE_I387)
16888 && flag_unsafe_math_optimizations && !optimize_size"
16890 rtx op0 = gen_reg_rtx (XFmode);
16891 rtx op1 = gen_reg_rtx (XFmode);
16893 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16894 emit_insn (gen_asinxf2 (op0, op1));
16895 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16899 (define_expand "acosxf2"
16900 [(set (match_dup 2)
16901 (mult:XF (match_operand:XF 1 "register_operand" "")
16903 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16904 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16905 (parallel [(set (match_operand:XF 0 "register_operand" "")
16906 (unspec:XF [(match_dup 1) (match_dup 5)]
16908 (clobber (match_scratch:XF 6 ""))])]
16909 "TARGET_USE_FANCY_MATH_387
16910 && flag_unsafe_math_optimizations && !optimize_size"
16914 for (i = 2; i < 6; i++)
16915 operands[i] = gen_reg_rtx (XFmode);
16917 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16920 (define_expand "acos<mode>2"
16921 [(use (match_operand:MODEF 0 "register_operand" ""))
16922 (use (match_operand:MODEF 1 "general_operand" ""))]
16923 "TARGET_USE_FANCY_MATH_387
16924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16925 || TARGET_MIX_SSE_I387)
16926 && flag_unsafe_math_optimizations && !optimize_size"
16928 rtx op0 = gen_reg_rtx (XFmode);
16929 rtx op1 = gen_reg_rtx (XFmode);
16931 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16932 emit_insn (gen_acosxf2 (op0, op1));
16933 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16937 (define_insn "fyl2xxf3_i387"
16938 [(set (match_operand:XF 0 "register_operand" "=f")
16939 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16940 (match_operand:XF 2 "register_operand" "u")]
16942 (clobber (match_scratch:XF 3 "=2"))]
16943 "TARGET_USE_FANCY_MATH_387
16944 && flag_unsafe_math_optimizations"
16946 [(set_attr "type" "fpspc")
16947 (set_attr "mode" "XF")])
16949 (define_insn "fyl2x_extend<mode>xf3_i387"
16950 [(set (match_operand:XF 0 "register_operand" "=f")
16951 (unspec:XF [(float_extend:XF
16952 (match_operand:MODEF 1 "register_operand" "0"))
16953 (match_operand:XF 2 "register_operand" "u")]
16955 (clobber (match_scratch:XF 3 "=2"))]
16956 "TARGET_USE_FANCY_MATH_387
16957 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16958 || TARGET_MIX_SSE_I387)
16959 && flag_unsafe_math_optimizations"
16961 [(set_attr "type" "fpspc")
16962 (set_attr "mode" "XF")])
16964 (define_expand "logxf2"
16965 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16966 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16967 (match_dup 2)] UNSPEC_FYL2X))
16968 (clobber (match_scratch:XF 3 ""))])]
16969 "TARGET_USE_FANCY_MATH_387
16970 && flag_unsafe_math_optimizations"
16972 operands[2] = gen_reg_rtx (XFmode);
16973 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16976 (define_expand "log<mode>2"
16977 [(use (match_operand:MODEF 0 "register_operand" ""))
16978 (use (match_operand:MODEF 1 "register_operand" ""))]
16979 "TARGET_USE_FANCY_MATH_387
16980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16981 || TARGET_MIX_SSE_I387)
16982 && flag_unsafe_math_optimizations"
16984 rtx op0 = gen_reg_rtx (XFmode);
16986 rtx op2 = gen_reg_rtx (XFmode);
16987 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16989 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16990 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16994 (define_expand "log10xf2"
16995 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16996 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16997 (match_dup 2)] UNSPEC_FYL2X))
16998 (clobber (match_scratch:XF 3 ""))])]
16999 "TARGET_USE_FANCY_MATH_387
17000 && flag_unsafe_math_optimizations"
17002 operands[2] = gen_reg_rtx (XFmode);
17003 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17006 (define_expand "log10<mode>2"
17007 [(use (match_operand:MODEF 0 "register_operand" ""))
17008 (use (match_operand:MODEF 1 "register_operand" ""))]
17009 "TARGET_USE_FANCY_MATH_387
17010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17011 || TARGET_MIX_SSE_I387)
17012 && flag_unsafe_math_optimizations"
17014 rtx op0 = gen_reg_rtx (XFmode);
17016 rtx op2 = gen_reg_rtx (XFmode);
17017 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17019 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17020 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17024 (define_expand "log2xf2"
17025 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17026 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17027 (match_dup 2)] UNSPEC_FYL2X))
17028 (clobber (match_scratch:XF 3 ""))])]
17029 "TARGET_USE_FANCY_MATH_387
17030 && flag_unsafe_math_optimizations"
17032 operands[2] = gen_reg_rtx (XFmode);
17033 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17036 (define_expand "log2<mode>2"
17037 [(use (match_operand:MODEF 0 "register_operand" ""))
17038 (use (match_operand:MODEF 1 "register_operand" ""))]
17039 "TARGET_USE_FANCY_MATH_387
17040 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17041 || TARGET_MIX_SSE_I387)
17042 && flag_unsafe_math_optimizations"
17044 rtx op0 = gen_reg_rtx (XFmode);
17046 rtx op2 = gen_reg_rtx (XFmode);
17047 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17049 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17054 (define_insn "fyl2xp1xf3_i387"
17055 [(set (match_operand:XF 0 "register_operand" "=f")
17056 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17057 (match_operand:XF 2 "register_operand" "u")]
17059 (clobber (match_scratch:XF 3 "=2"))]
17060 "TARGET_USE_FANCY_MATH_387
17061 && flag_unsafe_math_optimizations"
17063 [(set_attr "type" "fpspc")
17064 (set_attr "mode" "XF")])
17066 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17067 [(set (match_operand:XF 0 "register_operand" "=f")
17068 (unspec:XF [(float_extend:XF
17069 (match_operand:MODEF 1 "register_operand" "0"))
17070 (match_operand:XF 2 "register_operand" "u")]
17072 (clobber (match_scratch:XF 3 "=2"))]
17073 "TARGET_USE_FANCY_MATH_387
17074 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17075 || TARGET_MIX_SSE_I387)
17076 && flag_unsafe_math_optimizations"
17078 [(set_attr "type" "fpspc")
17079 (set_attr "mode" "XF")])
17081 (define_expand "log1pxf2"
17082 [(use (match_operand:XF 0 "register_operand" ""))
17083 (use (match_operand:XF 1 "register_operand" ""))]
17084 "TARGET_USE_FANCY_MATH_387
17085 && flag_unsafe_math_optimizations && !optimize_size"
17087 ix86_emit_i387_log1p (operands[0], operands[1]);
17091 (define_expand "log1p<mode>2"
17092 [(use (match_operand:MODEF 0 "register_operand" ""))
17093 (use (match_operand:MODEF 1 "register_operand" ""))]
17094 "TARGET_USE_FANCY_MATH_387
17095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17096 || TARGET_MIX_SSE_I387)
17097 && flag_unsafe_math_optimizations && !optimize_size"
17099 rtx op0 = gen_reg_rtx (XFmode);
17101 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17103 ix86_emit_i387_log1p (op0, operands[1]);
17104 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17108 (define_insn "fxtractxf3_i387"
17109 [(set (match_operand:XF 0 "register_operand" "=f")
17110 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17111 UNSPEC_XTRACT_FRACT))
17112 (set (match_operand:XF 1 "register_operand" "=u")
17113 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17114 "TARGET_USE_FANCY_MATH_387
17115 && flag_unsafe_math_optimizations"
17117 [(set_attr "type" "fpspc")
17118 (set_attr "mode" "XF")])
17120 (define_insn "fxtract_extend<mode>xf3_i387"
17121 [(set (match_operand:XF 0 "register_operand" "=f")
17122 (unspec:XF [(float_extend:XF
17123 (match_operand:MODEF 2 "register_operand" "0"))]
17124 UNSPEC_XTRACT_FRACT))
17125 (set (match_operand:XF 1 "register_operand" "=u")
17126 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17127 "TARGET_USE_FANCY_MATH_387
17128 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17129 || TARGET_MIX_SSE_I387)
17130 && flag_unsafe_math_optimizations"
17132 [(set_attr "type" "fpspc")
17133 (set_attr "mode" "XF")])
17135 (define_expand "logbxf2"
17136 [(parallel [(set (match_dup 2)
17137 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17138 UNSPEC_XTRACT_FRACT))
17139 (set (match_operand:XF 0 "register_operand" "")
17140 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17141 "TARGET_USE_FANCY_MATH_387
17142 && flag_unsafe_math_optimizations"
17144 operands[2] = gen_reg_rtx (XFmode);
17147 (define_expand "logb<mode>2"
17148 [(use (match_operand:MODEF 0 "register_operand" ""))
17149 (use (match_operand:MODEF 1 "register_operand" ""))]
17150 "TARGET_USE_FANCY_MATH_387
17151 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17152 || TARGET_MIX_SSE_I387)
17153 && flag_unsafe_math_optimizations"
17155 rtx op0 = gen_reg_rtx (XFmode);
17156 rtx op1 = gen_reg_rtx (XFmode);
17158 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17159 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17163 (define_expand "ilogbxf2"
17164 [(use (match_operand:SI 0 "register_operand" ""))
17165 (use (match_operand:XF 1 "register_operand" ""))]
17166 "TARGET_USE_FANCY_MATH_387
17167 && flag_unsafe_math_optimizations && !optimize_size"
17169 rtx op0 = gen_reg_rtx (XFmode);
17170 rtx op1 = gen_reg_rtx (XFmode);
17172 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17173 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17177 (define_expand "ilogb<mode>2"
17178 [(use (match_operand:SI 0 "register_operand" ""))
17179 (use (match_operand:MODEF 1 "register_operand" ""))]
17180 "TARGET_USE_FANCY_MATH_387
17181 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17182 || TARGET_MIX_SSE_I387)
17183 && flag_unsafe_math_optimizations && !optimize_size"
17185 rtx op0 = gen_reg_rtx (XFmode);
17186 rtx op1 = gen_reg_rtx (XFmode);
17188 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17189 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17193 (define_insn "*f2xm1xf2_i387"
17194 [(set (match_operand:XF 0 "register_operand" "=f")
17195 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17197 "TARGET_USE_FANCY_MATH_387
17198 && flag_unsafe_math_optimizations"
17200 [(set_attr "type" "fpspc")
17201 (set_attr "mode" "XF")])
17203 (define_insn "*fscalexf4_i387"
17204 [(set (match_operand:XF 0 "register_operand" "=f")
17205 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17206 (match_operand:XF 3 "register_operand" "1")]
17207 UNSPEC_FSCALE_FRACT))
17208 (set (match_operand:XF 1 "register_operand" "=u")
17209 (unspec:XF [(match_dup 2) (match_dup 3)]
17210 UNSPEC_FSCALE_EXP))]
17211 "TARGET_USE_FANCY_MATH_387
17212 && flag_unsafe_math_optimizations"
17214 [(set_attr "type" "fpspc")
17215 (set_attr "mode" "XF")])
17217 (define_expand "expNcorexf3"
17218 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17219 (match_operand:XF 2 "register_operand" "")))
17220 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17221 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17222 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17223 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17224 (parallel [(set (match_operand:XF 0 "register_operand" "")
17225 (unspec:XF [(match_dup 8) (match_dup 4)]
17226 UNSPEC_FSCALE_FRACT))
17228 (unspec:XF [(match_dup 8) (match_dup 4)]
17229 UNSPEC_FSCALE_EXP))])]
17230 "TARGET_USE_FANCY_MATH_387
17231 && flag_unsafe_math_optimizations && !optimize_size"
17235 for (i = 3; i < 10; i++)
17236 operands[i] = gen_reg_rtx (XFmode);
17238 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17241 (define_expand "expxf2"
17242 [(use (match_operand:XF 0 "register_operand" ""))
17243 (use (match_operand:XF 1 "register_operand" ""))]
17244 "TARGET_USE_FANCY_MATH_387
17245 && flag_unsafe_math_optimizations && !optimize_size"
17247 rtx op2 = gen_reg_rtx (XFmode);
17248 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17250 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17254 (define_expand "exp<mode>2"
17255 [(use (match_operand:MODEF 0 "register_operand" ""))
17256 (use (match_operand:MODEF 1 "general_operand" ""))]
17257 "TARGET_USE_FANCY_MATH_387
17258 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17259 || TARGET_MIX_SSE_I387)
17260 && flag_unsafe_math_optimizations && !optimize_size"
17262 rtx op0 = gen_reg_rtx (XFmode);
17263 rtx op1 = gen_reg_rtx (XFmode);
17265 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17266 emit_insn (gen_expxf2 (op0, op1));
17267 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17271 (define_expand "exp10xf2"
17272 [(use (match_operand:XF 0 "register_operand" ""))
17273 (use (match_operand:XF 1 "register_operand" ""))]
17274 "TARGET_USE_FANCY_MATH_387
17275 && flag_unsafe_math_optimizations && !optimize_size"
17277 rtx op2 = gen_reg_rtx (XFmode);
17278 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17280 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17284 (define_expand "exp10<mode>2"
17285 [(use (match_operand:MODEF 0 "register_operand" ""))
17286 (use (match_operand:MODEF 1 "general_operand" ""))]
17287 "TARGET_USE_FANCY_MATH_387
17288 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17289 || TARGET_MIX_SSE_I387)
17290 && flag_unsafe_math_optimizations && !optimize_size"
17292 rtx op0 = gen_reg_rtx (XFmode);
17293 rtx op1 = gen_reg_rtx (XFmode);
17295 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17296 emit_insn (gen_exp10xf2 (op0, op1));
17297 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17301 (define_expand "exp2xf2"
17302 [(use (match_operand:XF 0 "register_operand" ""))
17303 (use (match_operand:XF 1 "register_operand" ""))]
17304 "TARGET_USE_FANCY_MATH_387
17305 && flag_unsafe_math_optimizations && !optimize_size"
17307 rtx op2 = gen_reg_rtx (XFmode);
17308 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17310 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17314 (define_expand "exp2<mode>2"
17315 [(use (match_operand:MODEF 0 "register_operand" ""))
17316 (use (match_operand:MODEF 1 "general_operand" ""))]
17317 "TARGET_USE_FANCY_MATH_387
17318 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17319 || TARGET_MIX_SSE_I387)
17320 && flag_unsafe_math_optimizations && !optimize_size"
17322 rtx op0 = gen_reg_rtx (XFmode);
17323 rtx op1 = gen_reg_rtx (XFmode);
17325 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17326 emit_insn (gen_exp2xf2 (op0, op1));
17327 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17331 (define_expand "expm1xf2"
17332 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17334 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17335 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17336 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17337 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17338 (parallel [(set (match_dup 7)
17339 (unspec:XF [(match_dup 6) (match_dup 4)]
17340 UNSPEC_FSCALE_FRACT))
17342 (unspec:XF [(match_dup 6) (match_dup 4)]
17343 UNSPEC_FSCALE_EXP))])
17344 (parallel [(set (match_dup 10)
17345 (unspec:XF [(match_dup 9) (match_dup 8)]
17346 UNSPEC_FSCALE_FRACT))
17347 (set (match_dup 11)
17348 (unspec:XF [(match_dup 9) (match_dup 8)]
17349 UNSPEC_FSCALE_EXP))])
17350 (set (match_dup 12) (minus:XF (match_dup 10)
17351 (float_extend:XF (match_dup 13))))
17352 (set (match_operand:XF 0 "register_operand" "")
17353 (plus:XF (match_dup 12) (match_dup 7)))]
17354 "TARGET_USE_FANCY_MATH_387
17355 && flag_unsafe_math_optimizations && !optimize_size"
17359 for (i = 2; i < 13; i++)
17360 operands[i] = gen_reg_rtx (XFmode);
17363 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17365 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17368 (define_expand "expm1<mode>2"
17369 [(use (match_operand:MODEF 0 "register_operand" ""))
17370 (use (match_operand:MODEF 1 "general_operand" ""))]
17371 "TARGET_USE_FANCY_MATH_387
17372 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17373 || TARGET_MIX_SSE_I387)
17374 && flag_unsafe_math_optimizations && !optimize_size"
17376 rtx op0 = gen_reg_rtx (XFmode);
17377 rtx op1 = gen_reg_rtx (XFmode);
17379 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17380 emit_insn (gen_expm1xf2 (op0, op1));
17381 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17385 (define_expand "ldexpxf3"
17386 [(set (match_dup 3)
17387 (float:XF (match_operand:SI 2 "register_operand" "")))
17388 (parallel [(set (match_operand:XF 0 " register_operand" "")
17389 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17391 UNSPEC_FSCALE_FRACT))
17393 (unspec:XF [(match_dup 1) (match_dup 3)]
17394 UNSPEC_FSCALE_EXP))])]
17395 "TARGET_USE_FANCY_MATH_387
17396 && flag_unsafe_math_optimizations && !optimize_size"
17398 operands[3] = gen_reg_rtx (XFmode);
17399 operands[4] = gen_reg_rtx (XFmode);
17402 (define_expand "ldexp<mode>3"
17403 [(use (match_operand:MODEF 0 "register_operand" ""))
17404 (use (match_operand:MODEF 1 "general_operand" ""))
17405 (use (match_operand:SI 2 "register_operand" ""))]
17406 "TARGET_USE_FANCY_MATH_387
17407 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17408 || TARGET_MIX_SSE_I387)
17409 && flag_unsafe_math_optimizations && !optimize_size"
17411 rtx op0 = gen_reg_rtx (XFmode);
17412 rtx op1 = gen_reg_rtx (XFmode);
17414 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17415 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17416 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17420 (define_expand "scalbxf3"
17421 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17422 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17423 (match_operand:XF 2 "register_operand" "")]
17424 UNSPEC_FSCALE_FRACT))
17426 (unspec:XF [(match_dup 1) (match_dup 2)]
17427 UNSPEC_FSCALE_EXP))])]
17428 "TARGET_USE_FANCY_MATH_387
17429 && flag_unsafe_math_optimizations && !optimize_size"
17431 operands[3] = gen_reg_rtx (XFmode);
17434 (define_expand "scalb<mode>3"
17435 [(use (match_operand:MODEF 0 "register_operand" ""))
17436 (use (match_operand:MODEF 1 "general_operand" ""))
17437 (use (match_operand:MODEF 2 "register_operand" ""))]
17438 "TARGET_USE_FANCY_MATH_387
17439 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17440 || TARGET_MIX_SSE_I387)
17441 && flag_unsafe_math_optimizations && !optimize_size"
17443 rtx op0 = gen_reg_rtx (XFmode);
17444 rtx op1 = gen_reg_rtx (XFmode);
17445 rtx op2 = gen_reg_rtx (XFmode);
17447 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17448 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17449 emit_insn (gen_scalbxf3 (op0, op1, op2));
17450 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17455 (define_insn "sse4_1_round<mode>2"
17456 [(set (match_operand:MODEF 0 "register_operand" "=x")
17457 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17458 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17461 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17462 [(set_attr "type" "ssecvt")
17463 (set_attr "prefix_extra" "1")
17464 (set_attr "mode" "<MODE>")])
17466 (define_insn "rintxf2"
17467 [(set (match_operand:XF 0 "register_operand" "=f")
17468 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17470 "TARGET_USE_FANCY_MATH_387
17471 && flag_unsafe_math_optimizations"
17473 [(set_attr "type" "fpspc")
17474 (set_attr "mode" "XF")])
17476 (define_expand "rint<mode>2"
17477 [(use (match_operand:MODEF 0 "register_operand" ""))
17478 (use (match_operand:MODEF 1 "register_operand" ""))]
17479 "(TARGET_USE_FANCY_MATH_387
17480 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17481 || TARGET_MIX_SSE_I387)
17482 && flag_unsafe_math_optimizations)
17483 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17484 && !flag_trapping_math
17485 && (TARGET_ROUND || !optimize_size))"
17487 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17488 && !flag_trapping_math
17489 && (TARGET_ROUND || !optimize_size))
17492 emit_insn (gen_sse4_1_round<mode>2
17493 (operands[0], operands[1], GEN_INT (0x04)));
17495 ix86_expand_rint (operand0, operand1);
17499 rtx op0 = gen_reg_rtx (XFmode);
17500 rtx op1 = gen_reg_rtx (XFmode);
17502 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17503 emit_insn (gen_rintxf2 (op0, op1));
17505 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17510 (define_expand "round<mode>2"
17511 [(match_operand:MODEF 0 "register_operand" "")
17512 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17513 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17514 && !flag_trapping_math && !flag_rounding_math
17517 if (TARGET_64BIT || (<MODE>mode != DFmode))
17518 ix86_expand_round (operand0, operand1);
17520 ix86_expand_rounddf_32 (operand0, operand1);
17524 (define_insn_and_split "*fistdi2_1"
17525 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17526 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17528 "TARGET_USE_FANCY_MATH_387
17529 && !(reload_completed || reload_in_progress)"
17534 if (memory_operand (operands[0], VOIDmode))
17535 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17538 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17539 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17544 [(set_attr "type" "fpspc")
17545 (set_attr "mode" "DI")])
17547 (define_insn "fistdi2"
17548 [(set (match_operand:DI 0 "memory_operand" "=m")
17549 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17551 (clobber (match_scratch:XF 2 "=&1f"))]
17552 "TARGET_USE_FANCY_MATH_387"
17553 "* return output_fix_trunc (insn, operands, 0);"
17554 [(set_attr "type" "fpspc")
17555 (set_attr "mode" "DI")])
17557 (define_insn "fistdi2_with_temp"
17558 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17559 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17561 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17562 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17563 "TARGET_USE_FANCY_MATH_387"
17565 [(set_attr "type" "fpspc")
17566 (set_attr "mode" "DI")])
17569 [(set (match_operand:DI 0 "register_operand" "")
17570 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17572 (clobber (match_operand:DI 2 "memory_operand" ""))
17573 (clobber (match_scratch 3 ""))]
17575 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17576 (clobber (match_dup 3))])
17577 (set (match_dup 0) (match_dup 2))]
17581 [(set (match_operand:DI 0 "memory_operand" "")
17582 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17584 (clobber (match_operand:DI 2 "memory_operand" ""))
17585 (clobber (match_scratch 3 ""))]
17587 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17588 (clobber (match_dup 3))])]
17591 (define_insn_and_split "*fist<mode>2_1"
17592 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17593 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17595 "TARGET_USE_FANCY_MATH_387
17596 && !(reload_completed || reload_in_progress)"
17601 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17602 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17606 [(set_attr "type" "fpspc")
17607 (set_attr "mode" "<MODE>")])
17609 (define_insn "fist<mode>2"
17610 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17611 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17613 "TARGET_USE_FANCY_MATH_387"
17614 "* return output_fix_trunc (insn, operands, 0);"
17615 [(set_attr "type" "fpspc")
17616 (set_attr "mode" "<MODE>")])
17618 (define_insn "fist<mode>2_with_temp"
17619 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17620 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17622 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17623 "TARGET_USE_FANCY_MATH_387"
17625 [(set_attr "type" "fpspc")
17626 (set_attr "mode" "<MODE>")])
17629 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17630 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17632 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17634 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17635 (set (match_dup 0) (match_dup 2))]
17639 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17640 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17642 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17644 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17647 (define_expand "lrintxf<mode>2"
17648 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17649 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17651 "TARGET_USE_FANCY_MATH_387"
17654 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17655 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17656 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17657 UNSPEC_FIX_NOTRUNC))]
17658 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17659 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17662 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17663 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17664 (match_operand:MODEF 1 "register_operand" "")]
17665 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17666 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17667 && !flag_trapping_math && !flag_rounding_math
17670 ix86_expand_lround (operand0, operand1);
17674 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17675 (define_insn_and_split "frndintxf2_floor"
17676 [(set (match_operand:XF 0 "register_operand" "")
17677 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17678 UNSPEC_FRNDINT_FLOOR))
17679 (clobber (reg:CC FLAGS_REG))]
17680 "TARGET_USE_FANCY_MATH_387
17681 && flag_unsafe_math_optimizations
17682 && !(reload_completed || reload_in_progress)"
17687 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17689 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17690 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17692 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17693 operands[2], operands[3]));
17696 [(set_attr "type" "frndint")
17697 (set_attr "i387_cw" "floor")
17698 (set_attr "mode" "XF")])
17700 (define_insn "frndintxf2_floor_i387"
17701 [(set (match_operand:XF 0 "register_operand" "=f")
17702 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17703 UNSPEC_FRNDINT_FLOOR))
17704 (use (match_operand:HI 2 "memory_operand" "m"))
17705 (use (match_operand:HI 3 "memory_operand" "m"))]
17706 "TARGET_USE_FANCY_MATH_387
17707 && flag_unsafe_math_optimizations"
17708 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17709 [(set_attr "type" "frndint")
17710 (set_attr "i387_cw" "floor")
17711 (set_attr "mode" "XF")])
17713 (define_expand "floorxf2"
17714 [(use (match_operand:XF 0 "register_operand" ""))
17715 (use (match_operand:XF 1 "register_operand" ""))]
17716 "TARGET_USE_FANCY_MATH_387
17717 && flag_unsafe_math_optimizations && !optimize_size"
17719 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17723 (define_expand "floor<mode>2"
17724 [(use (match_operand:MODEF 0 "register_operand" ""))
17725 (use (match_operand:MODEF 1 "register_operand" ""))]
17726 "(TARGET_USE_FANCY_MATH_387
17727 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17728 || TARGET_MIX_SSE_I387)
17729 && flag_unsafe_math_optimizations && !optimize_size)
17730 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17731 && !flag_trapping_math
17732 && (TARGET_ROUND || !optimize_size))"
17734 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17735 && !flag_trapping_math
17736 && (TARGET_ROUND || !optimize_size))
17739 emit_insn (gen_sse4_1_round<mode>2
17740 (operands[0], operands[1], GEN_INT (0x01)));
17741 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17742 ix86_expand_floorceil (operand0, operand1, true);
17744 ix86_expand_floorceildf_32 (operand0, operand1, true);
17748 rtx op0 = gen_reg_rtx (XFmode);
17749 rtx op1 = gen_reg_rtx (XFmode);
17751 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17752 emit_insn (gen_frndintxf2_floor (op0, op1));
17754 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17759 (define_insn_and_split "*fist<mode>2_floor_1"
17760 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17761 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17762 UNSPEC_FIST_FLOOR))
17763 (clobber (reg:CC FLAGS_REG))]
17764 "TARGET_USE_FANCY_MATH_387
17765 && flag_unsafe_math_optimizations
17766 && !(reload_completed || reload_in_progress)"
17771 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17773 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17774 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17775 if (memory_operand (operands[0], VOIDmode))
17776 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17777 operands[2], operands[3]));
17780 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17781 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17782 operands[2], operands[3],
17787 [(set_attr "type" "fistp")
17788 (set_attr "i387_cw" "floor")
17789 (set_attr "mode" "<MODE>")])
17791 (define_insn "fistdi2_floor"
17792 [(set (match_operand:DI 0 "memory_operand" "=m")
17793 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17794 UNSPEC_FIST_FLOOR))
17795 (use (match_operand:HI 2 "memory_operand" "m"))
17796 (use (match_operand:HI 3 "memory_operand" "m"))
17797 (clobber (match_scratch:XF 4 "=&1f"))]
17798 "TARGET_USE_FANCY_MATH_387
17799 && flag_unsafe_math_optimizations"
17800 "* return output_fix_trunc (insn, operands, 0);"
17801 [(set_attr "type" "fistp")
17802 (set_attr "i387_cw" "floor")
17803 (set_attr "mode" "DI")])
17805 (define_insn "fistdi2_floor_with_temp"
17806 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17807 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17808 UNSPEC_FIST_FLOOR))
17809 (use (match_operand:HI 2 "memory_operand" "m,m"))
17810 (use (match_operand:HI 3 "memory_operand" "m,m"))
17811 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17812 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17813 "TARGET_USE_FANCY_MATH_387
17814 && flag_unsafe_math_optimizations"
17816 [(set_attr "type" "fistp")
17817 (set_attr "i387_cw" "floor")
17818 (set_attr "mode" "DI")])
17821 [(set (match_operand:DI 0 "register_operand" "")
17822 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17823 UNSPEC_FIST_FLOOR))
17824 (use (match_operand:HI 2 "memory_operand" ""))
17825 (use (match_operand:HI 3 "memory_operand" ""))
17826 (clobber (match_operand:DI 4 "memory_operand" ""))
17827 (clobber (match_scratch 5 ""))]
17829 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17830 (use (match_dup 2))
17831 (use (match_dup 3))
17832 (clobber (match_dup 5))])
17833 (set (match_dup 0) (match_dup 4))]
17837 [(set (match_operand:DI 0 "memory_operand" "")
17838 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17839 UNSPEC_FIST_FLOOR))
17840 (use (match_operand:HI 2 "memory_operand" ""))
17841 (use (match_operand:HI 3 "memory_operand" ""))
17842 (clobber (match_operand:DI 4 "memory_operand" ""))
17843 (clobber (match_scratch 5 ""))]
17845 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17846 (use (match_dup 2))
17847 (use (match_dup 3))
17848 (clobber (match_dup 5))])]
17851 (define_insn "fist<mode>2_floor"
17852 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17853 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17854 UNSPEC_FIST_FLOOR))
17855 (use (match_operand:HI 2 "memory_operand" "m"))
17856 (use (match_operand:HI 3 "memory_operand" "m"))]
17857 "TARGET_USE_FANCY_MATH_387
17858 && flag_unsafe_math_optimizations"
17859 "* return output_fix_trunc (insn, operands, 0);"
17860 [(set_attr "type" "fistp")
17861 (set_attr "i387_cw" "floor")
17862 (set_attr "mode" "<MODE>")])
17864 (define_insn "fist<mode>2_floor_with_temp"
17865 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17866 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17867 UNSPEC_FIST_FLOOR))
17868 (use (match_operand:HI 2 "memory_operand" "m,m"))
17869 (use (match_operand:HI 3 "memory_operand" "m,m"))
17870 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17871 "TARGET_USE_FANCY_MATH_387
17872 && flag_unsafe_math_optimizations"
17874 [(set_attr "type" "fistp")
17875 (set_attr "i387_cw" "floor")
17876 (set_attr "mode" "<MODE>")])
17879 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17880 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17881 UNSPEC_FIST_FLOOR))
17882 (use (match_operand:HI 2 "memory_operand" ""))
17883 (use (match_operand:HI 3 "memory_operand" ""))
17884 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17886 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17887 UNSPEC_FIST_FLOOR))
17888 (use (match_dup 2))
17889 (use (match_dup 3))])
17890 (set (match_dup 0) (match_dup 4))]
17894 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17895 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17896 UNSPEC_FIST_FLOOR))
17897 (use (match_operand:HI 2 "memory_operand" ""))
17898 (use (match_operand:HI 3 "memory_operand" ""))
17899 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17901 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17902 UNSPEC_FIST_FLOOR))
17903 (use (match_dup 2))
17904 (use (match_dup 3))])]
17907 (define_expand "lfloorxf<mode>2"
17908 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17909 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17910 UNSPEC_FIST_FLOOR))
17911 (clobber (reg:CC FLAGS_REG))])]
17912 "TARGET_USE_FANCY_MATH_387
17913 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17914 && flag_unsafe_math_optimizations"
17917 (define_expand "lfloor<mode>di2"
17918 [(match_operand:DI 0 "nonimmediate_operand" "")
17919 (match_operand:MODEF 1 "register_operand" "")]
17920 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17921 && !flag_trapping_math
17924 ix86_expand_lfloorceil (operand0, operand1, true);
17928 (define_expand "lfloor<mode>si2"
17929 [(match_operand:SI 0 "nonimmediate_operand" "")
17930 (match_operand:MODEF 1 "register_operand" "")]
17931 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17932 && !flag_trapping_math
17933 && (!optimize_size || !TARGET_64BIT)"
17935 ix86_expand_lfloorceil (operand0, operand1, true);
17939 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17940 (define_insn_and_split "frndintxf2_ceil"
17941 [(set (match_operand:XF 0 "register_operand" "")
17942 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17943 UNSPEC_FRNDINT_CEIL))
17944 (clobber (reg:CC FLAGS_REG))]
17945 "TARGET_USE_FANCY_MATH_387
17946 && flag_unsafe_math_optimizations
17947 && !(reload_completed || reload_in_progress)"
17952 ix86_optimize_mode_switching[I387_CEIL] = 1;
17954 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17955 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17957 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17958 operands[2], operands[3]));
17961 [(set_attr "type" "frndint")
17962 (set_attr "i387_cw" "ceil")
17963 (set_attr "mode" "XF")])
17965 (define_insn "frndintxf2_ceil_i387"
17966 [(set (match_operand:XF 0 "register_operand" "=f")
17967 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17968 UNSPEC_FRNDINT_CEIL))
17969 (use (match_operand:HI 2 "memory_operand" "m"))
17970 (use (match_operand:HI 3 "memory_operand" "m"))]
17971 "TARGET_USE_FANCY_MATH_387
17972 && flag_unsafe_math_optimizations"
17973 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17974 [(set_attr "type" "frndint")
17975 (set_attr "i387_cw" "ceil")
17976 (set_attr "mode" "XF")])
17978 (define_expand "ceilxf2"
17979 [(use (match_operand:XF 0 "register_operand" ""))
17980 (use (match_operand:XF 1 "register_operand" ""))]
17981 "TARGET_USE_FANCY_MATH_387
17982 && flag_unsafe_math_optimizations && !optimize_size"
17984 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17988 (define_expand "ceil<mode>2"
17989 [(use (match_operand:MODEF 0 "register_operand" ""))
17990 (use (match_operand:MODEF 1 "register_operand" ""))]
17991 "(TARGET_USE_FANCY_MATH_387
17992 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17993 || TARGET_MIX_SSE_I387)
17994 && flag_unsafe_math_optimizations && !optimize_size)
17995 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17996 && !flag_trapping_math
17997 && (TARGET_ROUND || !optimize_size))"
17999 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18000 && !flag_trapping_math
18001 && (TARGET_ROUND || !optimize_size))
18004 emit_insn (gen_sse4_1_round<mode>2
18005 (operands[0], operands[1], GEN_INT (0x02)));
18006 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18007 ix86_expand_floorceil (operand0, operand1, false);
18009 ix86_expand_floorceildf_32 (operand0, operand1, false);
18013 rtx op0 = gen_reg_rtx (XFmode);
18014 rtx op1 = gen_reg_rtx (XFmode);
18016 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18017 emit_insn (gen_frndintxf2_ceil (op0, op1));
18019 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18024 (define_insn_and_split "*fist<mode>2_ceil_1"
18025 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18026 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18028 (clobber (reg:CC FLAGS_REG))]
18029 "TARGET_USE_FANCY_MATH_387
18030 && flag_unsafe_math_optimizations
18031 && !(reload_completed || reload_in_progress)"
18036 ix86_optimize_mode_switching[I387_CEIL] = 1;
18038 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18039 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18040 if (memory_operand (operands[0], VOIDmode))
18041 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18042 operands[2], operands[3]));
18045 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18046 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18047 operands[2], operands[3],
18052 [(set_attr "type" "fistp")
18053 (set_attr "i387_cw" "ceil")
18054 (set_attr "mode" "<MODE>")])
18056 (define_insn "fistdi2_ceil"
18057 [(set (match_operand:DI 0 "memory_operand" "=m")
18058 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18060 (use (match_operand:HI 2 "memory_operand" "m"))
18061 (use (match_operand:HI 3 "memory_operand" "m"))
18062 (clobber (match_scratch:XF 4 "=&1f"))]
18063 "TARGET_USE_FANCY_MATH_387
18064 && flag_unsafe_math_optimizations"
18065 "* return output_fix_trunc (insn, operands, 0);"
18066 [(set_attr "type" "fistp")
18067 (set_attr "i387_cw" "ceil")
18068 (set_attr "mode" "DI")])
18070 (define_insn "fistdi2_ceil_with_temp"
18071 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18072 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18074 (use (match_operand:HI 2 "memory_operand" "m,m"))
18075 (use (match_operand:HI 3 "memory_operand" "m,m"))
18076 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18077 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18078 "TARGET_USE_FANCY_MATH_387
18079 && flag_unsafe_math_optimizations"
18081 [(set_attr "type" "fistp")
18082 (set_attr "i387_cw" "ceil")
18083 (set_attr "mode" "DI")])
18086 [(set (match_operand:DI 0 "register_operand" "")
18087 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18089 (use (match_operand:HI 2 "memory_operand" ""))
18090 (use (match_operand:HI 3 "memory_operand" ""))
18091 (clobber (match_operand:DI 4 "memory_operand" ""))
18092 (clobber (match_scratch 5 ""))]
18094 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18095 (use (match_dup 2))
18096 (use (match_dup 3))
18097 (clobber (match_dup 5))])
18098 (set (match_dup 0) (match_dup 4))]
18102 [(set (match_operand:DI 0 "memory_operand" "")
18103 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18105 (use (match_operand:HI 2 "memory_operand" ""))
18106 (use (match_operand:HI 3 "memory_operand" ""))
18107 (clobber (match_operand:DI 4 "memory_operand" ""))
18108 (clobber (match_scratch 5 ""))]
18110 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18111 (use (match_dup 2))
18112 (use (match_dup 3))
18113 (clobber (match_dup 5))])]
18116 (define_insn "fist<mode>2_ceil"
18117 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18118 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18120 (use (match_operand:HI 2 "memory_operand" "m"))
18121 (use (match_operand:HI 3 "memory_operand" "m"))]
18122 "TARGET_USE_FANCY_MATH_387
18123 && flag_unsafe_math_optimizations"
18124 "* return output_fix_trunc (insn, operands, 0);"
18125 [(set_attr "type" "fistp")
18126 (set_attr "i387_cw" "ceil")
18127 (set_attr "mode" "<MODE>")])
18129 (define_insn "fist<mode>2_ceil_with_temp"
18130 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18131 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18133 (use (match_operand:HI 2 "memory_operand" "m,m"))
18134 (use (match_operand:HI 3 "memory_operand" "m,m"))
18135 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18136 "TARGET_USE_FANCY_MATH_387
18137 && flag_unsafe_math_optimizations"
18139 [(set_attr "type" "fistp")
18140 (set_attr "i387_cw" "ceil")
18141 (set_attr "mode" "<MODE>")])
18144 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18145 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18147 (use (match_operand:HI 2 "memory_operand" ""))
18148 (use (match_operand:HI 3 "memory_operand" ""))
18149 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18151 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18153 (use (match_dup 2))
18154 (use (match_dup 3))])
18155 (set (match_dup 0) (match_dup 4))]
18159 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18160 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18162 (use (match_operand:HI 2 "memory_operand" ""))
18163 (use (match_operand:HI 3 "memory_operand" ""))
18164 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18166 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18168 (use (match_dup 2))
18169 (use (match_dup 3))])]
18172 (define_expand "lceilxf<mode>2"
18173 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18174 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18176 (clobber (reg:CC FLAGS_REG))])]
18177 "TARGET_USE_FANCY_MATH_387
18178 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18179 && flag_unsafe_math_optimizations"
18182 (define_expand "lceil<mode>di2"
18183 [(match_operand:DI 0 "nonimmediate_operand" "")
18184 (match_operand:MODEF 1 "register_operand" "")]
18185 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18186 && !flag_trapping_math"
18188 ix86_expand_lfloorceil (operand0, operand1, false);
18192 (define_expand "lceil<mode>si2"
18193 [(match_operand:SI 0 "nonimmediate_operand" "")
18194 (match_operand:MODEF 1 "register_operand" "")]
18195 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18196 && !flag_trapping_math"
18198 ix86_expand_lfloorceil (operand0, operand1, false);
18202 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18203 (define_insn_and_split "frndintxf2_trunc"
18204 [(set (match_operand:XF 0 "register_operand" "")
18205 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18206 UNSPEC_FRNDINT_TRUNC))
18207 (clobber (reg:CC FLAGS_REG))]
18208 "TARGET_USE_FANCY_MATH_387
18209 && flag_unsafe_math_optimizations
18210 && !(reload_completed || reload_in_progress)"
18215 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18217 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18218 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18220 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18221 operands[2], operands[3]));
18224 [(set_attr "type" "frndint")
18225 (set_attr "i387_cw" "trunc")
18226 (set_attr "mode" "XF")])
18228 (define_insn "frndintxf2_trunc_i387"
18229 [(set (match_operand:XF 0 "register_operand" "=f")
18230 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18231 UNSPEC_FRNDINT_TRUNC))
18232 (use (match_operand:HI 2 "memory_operand" "m"))
18233 (use (match_operand:HI 3 "memory_operand" "m"))]
18234 "TARGET_USE_FANCY_MATH_387
18235 && flag_unsafe_math_optimizations"
18236 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18237 [(set_attr "type" "frndint")
18238 (set_attr "i387_cw" "trunc")
18239 (set_attr "mode" "XF")])
18241 (define_expand "btruncxf2"
18242 [(use (match_operand:XF 0 "register_operand" ""))
18243 (use (match_operand:XF 1 "register_operand" ""))]
18244 "TARGET_USE_FANCY_MATH_387
18245 && flag_unsafe_math_optimizations && !optimize_size"
18247 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18251 (define_expand "btrunc<mode>2"
18252 [(use (match_operand:MODEF 0 "register_operand" ""))
18253 (use (match_operand:MODEF 1 "register_operand" ""))]
18254 "(TARGET_USE_FANCY_MATH_387
18255 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18256 || TARGET_MIX_SSE_I387)
18257 && flag_unsafe_math_optimizations && !optimize_size)
18258 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18259 && !flag_trapping_math
18260 && (TARGET_ROUND || !optimize_size))"
18262 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18263 && !flag_trapping_math
18264 && (TARGET_ROUND || !optimize_size))
18267 emit_insn (gen_sse4_1_round<mode>2
18268 (operands[0], operands[1], GEN_INT (0x03)));
18269 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18270 ix86_expand_trunc (operand0, operand1);
18272 ix86_expand_truncdf_32 (operand0, operand1);
18276 rtx op0 = gen_reg_rtx (XFmode);
18277 rtx op1 = gen_reg_rtx (XFmode);
18279 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18280 emit_insn (gen_frndintxf2_trunc (op0, op1));
18282 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18287 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18288 (define_insn_and_split "frndintxf2_mask_pm"
18289 [(set (match_operand:XF 0 "register_operand" "")
18290 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18291 UNSPEC_FRNDINT_MASK_PM))
18292 (clobber (reg:CC FLAGS_REG))]
18293 "TARGET_USE_FANCY_MATH_387
18294 && flag_unsafe_math_optimizations
18295 && !(reload_completed || reload_in_progress)"
18300 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18302 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18303 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18305 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18306 operands[2], operands[3]));
18309 [(set_attr "type" "frndint")
18310 (set_attr "i387_cw" "mask_pm")
18311 (set_attr "mode" "XF")])
18313 (define_insn "frndintxf2_mask_pm_i387"
18314 [(set (match_operand:XF 0 "register_operand" "=f")
18315 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18316 UNSPEC_FRNDINT_MASK_PM))
18317 (use (match_operand:HI 2 "memory_operand" "m"))
18318 (use (match_operand:HI 3 "memory_operand" "m"))]
18319 "TARGET_USE_FANCY_MATH_387
18320 && flag_unsafe_math_optimizations"
18321 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18322 [(set_attr "type" "frndint")
18323 (set_attr "i387_cw" "mask_pm")
18324 (set_attr "mode" "XF")])
18326 (define_expand "nearbyintxf2"
18327 [(use (match_operand:XF 0 "register_operand" ""))
18328 (use (match_operand:XF 1 "register_operand" ""))]
18329 "TARGET_USE_FANCY_MATH_387
18330 && flag_unsafe_math_optimizations"
18332 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18337 (define_expand "nearbyint<mode>2"
18338 [(use (match_operand:MODEF 0 "register_operand" ""))
18339 (use (match_operand:MODEF 1 "register_operand" ""))]
18340 "TARGET_USE_FANCY_MATH_387
18341 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18342 || TARGET_MIX_SSE_I387)
18343 && flag_unsafe_math_optimizations"
18345 rtx op0 = gen_reg_rtx (XFmode);
18346 rtx op1 = gen_reg_rtx (XFmode);
18348 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18349 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18351 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18355 (define_insn "fxam<mode>2_i387"
18356 [(set (match_operand:HI 0 "register_operand" "=a")
18358 [(match_operand:X87MODEF 1 "register_operand" "f")]
18360 "TARGET_USE_FANCY_MATH_387"
18361 "fxam\n\tfnstsw\t%0"
18362 [(set_attr "type" "multi")
18363 (set_attr "unit" "i387")
18364 (set_attr "mode" "<MODE>")])
18366 (define_expand "isinf<mode>2"
18367 [(use (match_operand:SI 0 "register_operand" ""))
18368 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18369 "TARGET_USE_FANCY_MATH_387
18370 && TARGET_C99_FUNCTIONS
18371 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18373 rtx mask = GEN_INT (0x45);
18374 rtx val = GEN_INT (0x05);
18378 rtx scratch = gen_reg_rtx (HImode);
18379 rtx res = gen_reg_rtx (QImode);
18381 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18382 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18383 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18384 cond = gen_rtx_fmt_ee (EQ, QImode,
18385 gen_rtx_REG (CCmode, FLAGS_REG),
18387 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18388 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18392 (define_expand "signbit<mode>2"
18393 [(use (match_operand:SI 0 "register_operand" ""))
18394 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18395 "TARGET_USE_FANCY_MATH_387
18396 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18398 rtx mask = GEN_INT (0x0200);
18400 rtx scratch = gen_reg_rtx (HImode);
18402 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18403 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18407 ;; Block operation instructions
18410 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18413 [(set_attr "length" "1")
18414 (set_attr "length_immediate" "0")
18415 (set_attr "modrm" "0")])
18417 (define_expand "movmemsi"
18418 [(use (match_operand:BLK 0 "memory_operand" ""))
18419 (use (match_operand:BLK 1 "memory_operand" ""))
18420 (use (match_operand:SI 2 "nonmemory_operand" ""))
18421 (use (match_operand:SI 3 "const_int_operand" ""))
18422 (use (match_operand:SI 4 "const_int_operand" ""))
18423 (use (match_operand:SI 5 "const_int_operand" ""))]
18426 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18427 operands[4], operands[5]))
18433 (define_expand "movmemdi"
18434 [(use (match_operand:BLK 0 "memory_operand" ""))
18435 (use (match_operand:BLK 1 "memory_operand" ""))
18436 (use (match_operand:DI 2 "nonmemory_operand" ""))
18437 (use (match_operand:DI 3 "const_int_operand" ""))
18438 (use (match_operand:SI 4 "const_int_operand" ""))
18439 (use (match_operand:SI 5 "const_int_operand" ""))]
18442 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18443 operands[4], operands[5]))
18449 ;; Most CPUs don't like single string operations
18450 ;; Handle this case here to simplify previous expander.
18452 (define_expand "strmov"
18453 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18454 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18455 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18456 (clobber (reg:CC FLAGS_REG))])
18457 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18458 (clobber (reg:CC FLAGS_REG))])]
18461 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18463 /* If .md ever supports :P for Pmode, these can be directly
18464 in the pattern above. */
18465 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18466 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18468 /* Can't use this if the user has appropriated esi or edi. */
18469 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18470 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18472 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18473 operands[2], operands[3],
18474 operands[5], operands[6]));
18478 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18481 (define_expand "strmov_singleop"
18482 [(parallel [(set (match_operand 1 "memory_operand" "")
18483 (match_operand 3 "memory_operand" ""))
18484 (set (match_operand 0 "register_operand" "")
18485 (match_operand 4 "" ""))
18486 (set (match_operand 2 "register_operand" "")
18487 (match_operand 5 "" ""))])]
18488 "TARGET_SINGLE_STRINGOP || optimize_size"
18489 "ix86_current_function_needs_cld = 1;")
18491 (define_insn "*strmovdi_rex_1"
18492 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18493 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18494 (set (match_operand:DI 0 "register_operand" "=D")
18495 (plus:DI (match_dup 2)
18497 (set (match_operand:DI 1 "register_operand" "=S")
18498 (plus:DI (match_dup 3)
18500 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18502 [(set_attr "type" "str")
18503 (set_attr "mode" "DI")
18504 (set_attr "memory" "both")])
18506 (define_insn "*strmovsi_1"
18507 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18508 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18509 (set (match_operand:SI 0 "register_operand" "=D")
18510 (plus:SI (match_dup 2)
18512 (set (match_operand:SI 1 "register_operand" "=S")
18513 (plus:SI (match_dup 3)
18515 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18517 [(set_attr "type" "str")
18518 (set_attr "mode" "SI")
18519 (set_attr "memory" "both")])
18521 (define_insn "*strmovsi_rex_1"
18522 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18523 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18524 (set (match_operand:DI 0 "register_operand" "=D")
18525 (plus:DI (match_dup 2)
18527 (set (match_operand:DI 1 "register_operand" "=S")
18528 (plus:DI (match_dup 3)
18530 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18532 [(set_attr "type" "str")
18533 (set_attr "mode" "SI")
18534 (set_attr "memory" "both")])
18536 (define_insn "*strmovhi_1"
18537 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18538 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18539 (set (match_operand:SI 0 "register_operand" "=D")
18540 (plus:SI (match_dup 2)
18542 (set (match_operand:SI 1 "register_operand" "=S")
18543 (plus:SI (match_dup 3)
18545 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18547 [(set_attr "type" "str")
18548 (set_attr "memory" "both")
18549 (set_attr "mode" "HI")])
18551 (define_insn "*strmovhi_rex_1"
18552 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18553 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18554 (set (match_operand:DI 0 "register_operand" "=D")
18555 (plus:DI (match_dup 2)
18557 (set (match_operand:DI 1 "register_operand" "=S")
18558 (plus:DI (match_dup 3)
18560 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18562 [(set_attr "type" "str")
18563 (set_attr "memory" "both")
18564 (set_attr "mode" "HI")])
18566 (define_insn "*strmovqi_1"
18567 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18568 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18569 (set (match_operand:SI 0 "register_operand" "=D")
18570 (plus:SI (match_dup 2)
18572 (set (match_operand:SI 1 "register_operand" "=S")
18573 (plus:SI (match_dup 3)
18575 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18577 [(set_attr "type" "str")
18578 (set_attr "memory" "both")
18579 (set_attr "mode" "QI")])
18581 (define_insn "*strmovqi_rex_1"
18582 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18583 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18584 (set (match_operand:DI 0 "register_operand" "=D")
18585 (plus:DI (match_dup 2)
18587 (set (match_operand:DI 1 "register_operand" "=S")
18588 (plus:DI (match_dup 3)
18590 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18592 [(set_attr "type" "str")
18593 (set_attr "memory" "both")
18594 (set_attr "mode" "QI")])
18596 (define_expand "rep_mov"
18597 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18598 (set (match_operand 0 "register_operand" "")
18599 (match_operand 5 "" ""))
18600 (set (match_operand 2 "register_operand" "")
18601 (match_operand 6 "" ""))
18602 (set (match_operand 1 "memory_operand" "")
18603 (match_operand 3 "memory_operand" ""))
18604 (use (match_dup 4))])]
18606 "ix86_current_function_needs_cld = 1;")
18608 (define_insn "*rep_movdi_rex64"
18609 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18610 (set (match_operand:DI 0 "register_operand" "=D")
18611 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18613 (match_operand:DI 3 "register_operand" "0")))
18614 (set (match_operand:DI 1 "register_operand" "=S")
18615 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18616 (match_operand:DI 4 "register_operand" "1")))
18617 (set (mem:BLK (match_dup 3))
18618 (mem:BLK (match_dup 4)))
18619 (use (match_dup 5))]
18622 [(set_attr "type" "str")
18623 (set_attr "prefix_rep" "1")
18624 (set_attr "memory" "both")
18625 (set_attr "mode" "DI")])
18627 (define_insn "*rep_movsi"
18628 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18629 (set (match_operand:SI 0 "register_operand" "=D")
18630 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18632 (match_operand:SI 3 "register_operand" "0")))
18633 (set (match_operand:SI 1 "register_operand" "=S")
18634 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18635 (match_operand:SI 4 "register_operand" "1")))
18636 (set (mem:BLK (match_dup 3))
18637 (mem:BLK (match_dup 4)))
18638 (use (match_dup 5))]
18641 [(set_attr "type" "str")
18642 (set_attr "prefix_rep" "1")
18643 (set_attr "memory" "both")
18644 (set_attr "mode" "SI")])
18646 (define_insn "*rep_movsi_rex64"
18647 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18648 (set (match_operand:DI 0 "register_operand" "=D")
18649 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18651 (match_operand:DI 3 "register_operand" "0")))
18652 (set (match_operand:DI 1 "register_operand" "=S")
18653 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18654 (match_operand:DI 4 "register_operand" "1")))
18655 (set (mem:BLK (match_dup 3))
18656 (mem:BLK (match_dup 4)))
18657 (use (match_dup 5))]
18660 [(set_attr "type" "str")
18661 (set_attr "prefix_rep" "1")
18662 (set_attr "memory" "both")
18663 (set_attr "mode" "SI")])
18665 (define_insn "*rep_movqi"
18666 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18667 (set (match_operand:SI 0 "register_operand" "=D")
18668 (plus:SI (match_operand:SI 3 "register_operand" "0")
18669 (match_operand:SI 5 "register_operand" "2")))
18670 (set (match_operand:SI 1 "register_operand" "=S")
18671 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18672 (set (mem:BLK (match_dup 3))
18673 (mem:BLK (match_dup 4)))
18674 (use (match_dup 5))]
18677 [(set_attr "type" "str")
18678 (set_attr "prefix_rep" "1")
18679 (set_attr "memory" "both")
18680 (set_attr "mode" "SI")])
18682 (define_insn "*rep_movqi_rex64"
18683 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18684 (set (match_operand:DI 0 "register_operand" "=D")
18685 (plus:DI (match_operand:DI 3 "register_operand" "0")
18686 (match_operand:DI 5 "register_operand" "2")))
18687 (set (match_operand:DI 1 "register_operand" "=S")
18688 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18689 (set (mem:BLK (match_dup 3))
18690 (mem:BLK (match_dup 4)))
18691 (use (match_dup 5))]
18694 [(set_attr "type" "str")
18695 (set_attr "prefix_rep" "1")
18696 (set_attr "memory" "both")
18697 (set_attr "mode" "SI")])
18699 (define_expand "setmemsi"
18700 [(use (match_operand:BLK 0 "memory_operand" ""))
18701 (use (match_operand:SI 1 "nonmemory_operand" ""))
18702 (use (match_operand 2 "const_int_operand" ""))
18703 (use (match_operand 3 "const_int_operand" ""))
18704 (use (match_operand:SI 4 "const_int_operand" ""))
18705 (use (match_operand:SI 5 "const_int_operand" ""))]
18708 if (ix86_expand_setmem (operands[0], operands[1],
18709 operands[2], operands[3],
18710 operands[4], operands[5]))
18716 (define_expand "setmemdi"
18717 [(use (match_operand:BLK 0 "memory_operand" ""))
18718 (use (match_operand:DI 1 "nonmemory_operand" ""))
18719 (use (match_operand 2 "const_int_operand" ""))
18720 (use (match_operand 3 "const_int_operand" ""))
18721 (use (match_operand 4 "const_int_operand" ""))
18722 (use (match_operand 5 "const_int_operand" ""))]
18725 if (ix86_expand_setmem (operands[0], operands[1],
18726 operands[2], operands[3],
18727 operands[4], operands[5]))
18733 ;; Most CPUs don't like single string operations
18734 ;; Handle this case here to simplify previous expander.
18736 (define_expand "strset"
18737 [(set (match_operand 1 "memory_operand" "")
18738 (match_operand 2 "register_operand" ""))
18739 (parallel [(set (match_operand 0 "register_operand" "")
18741 (clobber (reg:CC FLAGS_REG))])]
18744 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18745 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18747 /* If .md ever supports :P for Pmode, this can be directly
18748 in the pattern above. */
18749 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18750 GEN_INT (GET_MODE_SIZE (GET_MODE
18752 if (TARGET_SINGLE_STRINGOP || optimize_size)
18754 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18760 (define_expand "strset_singleop"
18761 [(parallel [(set (match_operand 1 "memory_operand" "")
18762 (match_operand 2 "register_operand" ""))
18763 (set (match_operand 0 "register_operand" "")
18764 (match_operand 3 "" ""))])]
18765 "TARGET_SINGLE_STRINGOP || optimize_size"
18766 "ix86_current_function_needs_cld = 1;")
18768 (define_insn "*strsetdi_rex_1"
18769 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18770 (match_operand:DI 2 "register_operand" "a"))
18771 (set (match_operand:DI 0 "register_operand" "=D")
18772 (plus:DI (match_dup 1)
18774 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18776 [(set_attr "type" "str")
18777 (set_attr "memory" "store")
18778 (set_attr "mode" "DI")])
18780 (define_insn "*strsetsi_1"
18781 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18782 (match_operand:SI 2 "register_operand" "a"))
18783 (set (match_operand:SI 0 "register_operand" "=D")
18784 (plus:SI (match_dup 1)
18786 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18788 [(set_attr "type" "str")
18789 (set_attr "memory" "store")
18790 (set_attr "mode" "SI")])
18792 (define_insn "*strsetsi_rex_1"
18793 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18794 (match_operand:SI 2 "register_operand" "a"))
18795 (set (match_operand:DI 0 "register_operand" "=D")
18796 (plus:DI (match_dup 1)
18798 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18800 [(set_attr "type" "str")
18801 (set_attr "memory" "store")
18802 (set_attr "mode" "SI")])
18804 (define_insn "*strsethi_1"
18805 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18806 (match_operand:HI 2 "register_operand" "a"))
18807 (set (match_operand:SI 0 "register_operand" "=D")
18808 (plus:SI (match_dup 1)
18810 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18812 [(set_attr "type" "str")
18813 (set_attr "memory" "store")
18814 (set_attr "mode" "HI")])
18816 (define_insn "*strsethi_rex_1"
18817 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18818 (match_operand:HI 2 "register_operand" "a"))
18819 (set (match_operand:DI 0 "register_operand" "=D")
18820 (plus:DI (match_dup 1)
18822 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18824 [(set_attr "type" "str")
18825 (set_attr "memory" "store")
18826 (set_attr "mode" "HI")])
18828 (define_insn "*strsetqi_1"
18829 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18830 (match_operand:QI 2 "register_operand" "a"))
18831 (set (match_operand:SI 0 "register_operand" "=D")
18832 (plus:SI (match_dup 1)
18834 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18836 [(set_attr "type" "str")
18837 (set_attr "memory" "store")
18838 (set_attr "mode" "QI")])
18840 (define_insn "*strsetqi_rex_1"
18841 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18842 (match_operand:QI 2 "register_operand" "a"))
18843 (set (match_operand:DI 0 "register_operand" "=D")
18844 (plus:DI (match_dup 1)
18846 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18848 [(set_attr "type" "str")
18849 (set_attr "memory" "store")
18850 (set_attr "mode" "QI")])
18852 (define_expand "rep_stos"
18853 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18854 (set (match_operand 0 "register_operand" "")
18855 (match_operand 4 "" ""))
18856 (set (match_operand 2 "memory_operand" "") (const_int 0))
18857 (use (match_operand 3 "register_operand" ""))
18858 (use (match_dup 1))])]
18860 "ix86_current_function_needs_cld = 1;")
18862 (define_insn "*rep_stosdi_rex64"
18863 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18864 (set (match_operand:DI 0 "register_operand" "=D")
18865 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18867 (match_operand:DI 3 "register_operand" "0")))
18868 (set (mem:BLK (match_dup 3))
18870 (use (match_operand:DI 2 "register_operand" "a"))
18871 (use (match_dup 4))]
18874 [(set_attr "type" "str")
18875 (set_attr "prefix_rep" "1")
18876 (set_attr "memory" "store")
18877 (set_attr "mode" "DI")])
18879 (define_insn "*rep_stossi"
18880 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18881 (set (match_operand:SI 0 "register_operand" "=D")
18882 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18884 (match_operand:SI 3 "register_operand" "0")))
18885 (set (mem:BLK (match_dup 3))
18887 (use (match_operand:SI 2 "register_operand" "a"))
18888 (use (match_dup 4))]
18891 [(set_attr "type" "str")
18892 (set_attr "prefix_rep" "1")
18893 (set_attr "memory" "store")
18894 (set_attr "mode" "SI")])
18896 (define_insn "*rep_stossi_rex64"
18897 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18898 (set (match_operand:DI 0 "register_operand" "=D")
18899 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18901 (match_operand:DI 3 "register_operand" "0")))
18902 (set (mem:BLK (match_dup 3))
18904 (use (match_operand:SI 2 "register_operand" "a"))
18905 (use (match_dup 4))]
18908 [(set_attr "type" "str")
18909 (set_attr "prefix_rep" "1")
18910 (set_attr "memory" "store")
18911 (set_attr "mode" "SI")])
18913 (define_insn "*rep_stosqi"
18914 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18915 (set (match_operand:SI 0 "register_operand" "=D")
18916 (plus:SI (match_operand:SI 3 "register_operand" "0")
18917 (match_operand:SI 4 "register_operand" "1")))
18918 (set (mem:BLK (match_dup 3))
18920 (use (match_operand:QI 2 "register_operand" "a"))
18921 (use (match_dup 4))]
18924 [(set_attr "type" "str")
18925 (set_attr "prefix_rep" "1")
18926 (set_attr "memory" "store")
18927 (set_attr "mode" "QI")])
18929 (define_insn "*rep_stosqi_rex64"
18930 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18931 (set (match_operand:DI 0 "register_operand" "=D")
18932 (plus:DI (match_operand:DI 3 "register_operand" "0")
18933 (match_operand:DI 4 "register_operand" "1")))
18934 (set (mem:BLK (match_dup 3))
18936 (use (match_operand:QI 2 "register_operand" "a"))
18937 (use (match_dup 4))]
18940 [(set_attr "type" "str")
18941 (set_attr "prefix_rep" "1")
18942 (set_attr "memory" "store")
18943 (set_attr "mode" "QI")])
18945 (define_expand "cmpstrnsi"
18946 [(set (match_operand:SI 0 "register_operand" "")
18947 (compare:SI (match_operand:BLK 1 "general_operand" "")
18948 (match_operand:BLK 2 "general_operand" "")))
18949 (use (match_operand 3 "general_operand" ""))
18950 (use (match_operand 4 "immediate_operand" ""))]
18951 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18953 rtx addr1, addr2, out, outlow, count, countreg, align;
18955 /* Can't use this if the user has appropriated esi or edi. */
18956 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18961 out = gen_reg_rtx (SImode);
18963 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18964 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18965 if (addr1 != XEXP (operands[1], 0))
18966 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18967 if (addr2 != XEXP (operands[2], 0))
18968 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18970 count = operands[3];
18971 countreg = ix86_zero_extend_to_Pmode (count);
18973 /* %%% Iff we are testing strict equality, we can use known alignment
18974 to good advantage. This may be possible with combine, particularly
18975 once cc0 is dead. */
18976 align = operands[4];
18978 if (CONST_INT_P (count))
18980 if (INTVAL (count) == 0)
18982 emit_move_insn (operands[0], const0_rtx);
18985 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18986 operands[1], operands[2]));
18991 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18993 emit_insn (gen_cmpsi_1 (countreg, countreg));
18994 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18995 operands[1], operands[2]));
18998 outlow = gen_lowpart (QImode, out);
18999 emit_insn (gen_cmpintqi (outlow));
19000 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19002 if (operands[0] != out)
19003 emit_move_insn (operands[0], out);
19008 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19010 (define_expand "cmpintqi"
19011 [(set (match_dup 1)
19012 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19014 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19015 (parallel [(set (match_operand:QI 0 "register_operand" "")
19016 (minus:QI (match_dup 1)
19018 (clobber (reg:CC FLAGS_REG))])]
19020 "operands[1] = gen_reg_rtx (QImode);
19021 operands[2] = gen_reg_rtx (QImode);")
19023 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19024 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19026 (define_expand "cmpstrnqi_nz_1"
19027 [(parallel [(set (reg:CC FLAGS_REG)
19028 (compare:CC (match_operand 4 "memory_operand" "")
19029 (match_operand 5 "memory_operand" "")))
19030 (use (match_operand 2 "register_operand" ""))
19031 (use (match_operand:SI 3 "immediate_operand" ""))
19032 (clobber (match_operand 0 "register_operand" ""))
19033 (clobber (match_operand 1 "register_operand" ""))
19034 (clobber (match_dup 2))])]
19036 "ix86_current_function_needs_cld = 1;")
19038 (define_insn "*cmpstrnqi_nz_1"
19039 [(set (reg:CC FLAGS_REG)
19040 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19041 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19042 (use (match_operand:SI 6 "register_operand" "2"))
19043 (use (match_operand:SI 3 "immediate_operand" "i"))
19044 (clobber (match_operand:SI 0 "register_operand" "=S"))
19045 (clobber (match_operand:SI 1 "register_operand" "=D"))
19046 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19049 [(set_attr "type" "str")
19050 (set_attr "mode" "QI")
19051 (set_attr "prefix_rep" "1")])
19053 (define_insn "*cmpstrnqi_nz_rex_1"
19054 [(set (reg:CC FLAGS_REG)
19055 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19056 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19057 (use (match_operand:DI 6 "register_operand" "2"))
19058 (use (match_operand:SI 3 "immediate_operand" "i"))
19059 (clobber (match_operand:DI 0 "register_operand" "=S"))
19060 (clobber (match_operand:DI 1 "register_operand" "=D"))
19061 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19064 [(set_attr "type" "str")
19065 (set_attr "mode" "QI")
19066 (set_attr "prefix_rep" "1")])
19068 ;; The same, but the count is not known to not be zero.
19070 (define_expand "cmpstrnqi_1"
19071 [(parallel [(set (reg:CC FLAGS_REG)
19072 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19074 (compare:CC (match_operand 4 "memory_operand" "")
19075 (match_operand 5 "memory_operand" ""))
19077 (use (match_operand:SI 3 "immediate_operand" ""))
19078 (use (reg:CC FLAGS_REG))
19079 (clobber (match_operand 0 "register_operand" ""))
19080 (clobber (match_operand 1 "register_operand" ""))
19081 (clobber (match_dup 2))])]
19083 "ix86_current_function_needs_cld = 1;")
19085 (define_insn "*cmpstrnqi_1"
19086 [(set (reg:CC FLAGS_REG)
19087 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19089 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19090 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19092 (use (match_operand:SI 3 "immediate_operand" "i"))
19093 (use (reg:CC FLAGS_REG))
19094 (clobber (match_operand:SI 0 "register_operand" "=S"))
19095 (clobber (match_operand:SI 1 "register_operand" "=D"))
19096 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19099 [(set_attr "type" "str")
19100 (set_attr "mode" "QI")
19101 (set_attr "prefix_rep" "1")])
19103 (define_insn "*cmpstrnqi_rex_1"
19104 [(set (reg:CC FLAGS_REG)
19105 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19107 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19108 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19110 (use (match_operand:SI 3 "immediate_operand" "i"))
19111 (use (reg:CC FLAGS_REG))
19112 (clobber (match_operand:DI 0 "register_operand" "=S"))
19113 (clobber (match_operand:DI 1 "register_operand" "=D"))
19114 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19117 [(set_attr "type" "str")
19118 (set_attr "mode" "QI")
19119 (set_attr "prefix_rep" "1")])
19121 (define_expand "strlensi"
19122 [(set (match_operand:SI 0 "register_operand" "")
19123 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19124 (match_operand:QI 2 "immediate_operand" "")
19125 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19128 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19134 (define_expand "strlendi"
19135 [(set (match_operand:DI 0 "register_operand" "")
19136 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19137 (match_operand:QI 2 "immediate_operand" "")
19138 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19141 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19147 (define_expand "strlenqi_1"
19148 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19149 (clobber (match_operand 1 "register_operand" ""))
19150 (clobber (reg:CC FLAGS_REG))])]
19152 "ix86_current_function_needs_cld = 1;")
19154 (define_insn "*strlenqi_1"
19155 [(set (match_operand:SI 0 "register_operand" "=&c")
19156 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19157 (match_operand:QI 2 "register_operand" "a")
19158 (match_operand:SI 3 "immediate_operand" "i")
19159 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19160 (clobber (match_operand:SI 1 "register_operand" "=D"))
19161 (clobber (reg:CC FLAGS_REG))]
19164 [(set_attr "type" "str")
19165 (set_attr "mode" "QI")
19166 (set_attr "prefix_rep" "1")])
19168 (define_insn "*strlenqi_rex_1"
19169 [(set (match_operand:DI 0 "register_operand" "=&c")
19170 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19171 (match_operand:QI 2 "register_operand" "a")
19172 (match_operand:DI 3 "immediate_operand" "i")
19173 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19174 (clobber (match_operand:DI 1 "register_operand" "=D"))
19175 (clobber (reg:CC FLAGS_REG))]
19178 [(set_attr "type" "str")
19179 (set_attr "mode" "QI")
19180 (set_attr "prefix_rep" "1")])
19182 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19183 ;; handled in combine, but it is not currently up to the task.
19184 ;; When used for their truth value, the cmpstrn* expanders generate
19193 ;; The intermediate three instructions are unnecessary.
19195 ;; This one handles cmpstrn*_nz_1...
19198 (set (reg:CC FLAGS_REG)
19199 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19200 (mem:BLK (match_operand 5 "register_operand" ""))))
19201 (use (match_operand 6 "register_operand" ""))
19202 (use (match_operand:SI 3 "immediate_operand" ""))
19203 (clobber (match_operand 0 "register_operand" ""))
19204 (clobber (match_operand 1 "register_operand" ""))
19205 (clobber (match_operand 2 "register_operand" ""))])
19206 (set (match_operand:QI 7 "register_operand" "")
19207 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19208 (set (match_operand:QI 8 "register_operand" "")
19209 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19210 (set (reg FLAGS_REG)
19211 (compare (match_dup 7) (match_dup 8)))
19213 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19215 (set (reg:CC FLAGS_REG)
19216 (compare:CC (mem:BLK (match_dup 4))
19217 (mem:BLK (match_dup 5))))
19218 (use (match_dup 6))
19219 (use (match_dup 3))
19220 (clobber (match_dup 0))
19221 (clobber (match_dup 1))
19222 (clobber (match_dup 2))])]
19225 ;; ...and this one handles cmpstrn*_1.
19228 (set (reg:CC FLAGS_REG)
19229 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19231 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19232 (mem:BLK (match_operand 5 "register_operand" "")))
19234 (use (match_operand:SI 3 "immediate_operand" ""))
19235 (use (reg:CC FLAGS_REG))
19236 (clobber (match_operand 0 "register_operand" ""))
19237 (clobber (match_operand 1 "register_operand" ""))
19238 (clobber (match_operand 2 "register_operand" ""))])
19239 (set (match_operand:QI 7 "register_operand" "")
19240 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19241 (set (match_operand:QI 8 "register_operand" "")
19242 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19243 (set (reg FLAGS_REG)
19244 (compare (match_dup 7) (match_dup 8)))
19246 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19248 (set (reg:CC FLAGS_REG)
19249 (if_then_else:CC (ne (match_dup 6)
19251 (compare:CC (mem:BLK (match_dup 4))
19252 (mem:BLK (match_dup 5)))
19254 (use (match_dup 3))
19255 (use (reg:CC FLAGS_REG))
19256 (clobber (match_dup 0))
19257 (clobber (match_dup 1))
19258 (clobber (match_dup 2))])]
19263 ;; Conditional move instructions.
19265 (define_expand "movdicc"
19266 [(set (match_operand:DI 0 "register_operand" "")
19267 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19268 (match_operand:DI 2 "general_operand" "")
19269 (match_operand:DI 3 "general_operand" "")))]
19271 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19273 (define_insn "x86_movdicc_0_m1_rex64"
19274 [(set (match_operand:DI 0 "register_operand" "=r")
19275 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19278 (clobber (reg:CC FLAGS_REG))]
19281 ; Since we don't have the proper number of operands for an alu insn,
19282 ; fill in all the blanks.
19283 [(set_attr "type" "alu")
19284 (set_attr "pent_pair" "pu")
19285 (set_attr "memory" "none")
19286 (set_attr "imm_disp" "false")
19287 (set_attr "mode" "DI")
19288 (set_attr "length_immediate" "0")])
19290 (define_insn "*x86_movdicc_0_m1_se"
19291 [(set (match_operand:DI 0 "register_operand" "=r")
19292 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19295 (clobber (reg:CC FLAGS_REG))]
19298 [(set_attr "type" "alu")
19299 (set_attr "pent_pair" "pu")
19300 (set_attr "memory" "none")
19301 (set_attr "imm_disp" "false")
19302 (set_attr "mode" "DI")
19303 (set_attr "length_immediate" "0")])
19305 (define_insn "*movdicc_c_rex64"
19306 [(set (match_operand:DI 0 "register_operand" "=r,r")
19307 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19308 [(reg FLAGS_REG) (const_int 0)])
19309 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19310 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19311 "TARGET_64BIT && TARGET_CMOVE
19312 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19314 cmov%O2%C1\t{%2, %0|%0, %2}
19315 cmov%O2%c1\t{%3, %0|%0, %3}"
19316 [(set_attr "type" "icmov")
19317 (set_attr "mode" "DI")])
19319 (define_expand "movsicc"
19320 [(set (match_operand:SI 0 "register_operand" "")
19321 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19322 (match_operand:SI 2 "general_operand" "")
19323 (match_operand:SI 3 "general_operand" "")))]
19325 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19327 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19328 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19329 ;; So just document what we're doing explicitly.
19331 (define_insn "x86_movsicc_0_m1"
19332 [(set (match_operand:SI 0 "register_operand" "=r")
19333 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19336 (clobber (reg:CC FLAGS_REG))]
19339 ; Since we don't have the proper number of operands for an alu insn,
19340 ; fill in all the blanks.
19341 [(set_attr "type" "alu")
19342 (set_attr "pent_pair" "pu")
19343 (set_attr "memory" "none")
19344 (set_attr "imm_disp" "false")
19345 (set_attr "mode" "SI")
19346 (set_attr "length_immediate" "0")])
19348 (define_insn "*x86_movsicc_0_m1_se"
19349 [(set (match_operand:SI 0 "register_operand" "=r")
19350 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19353 (clobber (reg:CC FLAGS_REG))]
19356 [(set_attr "type" "alu")
19357 (set_attr "pent_pair" "pu")
19358 (set_attr "memory" "none")
19359 (set_attr "imm_disp" "false")
19360 (set_attr "mode" "SI")
19361 (set_attr "length_immediate" "0")])
19363 (define_insn "*movsicc_noc"
19364 [(set (match_operand:SI 0 "register_operand" "=r,r")
19365 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19366 [(reg FLAGS_REG) (const_int 0)])
19367 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19368 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19370 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19372 cmov%O2%C1\t{%2, %0|%0, %2}
19373 cmov%O2%c1\t{%3, %0|%0, %3}"
19374 [(set_attr "type" "icmov")
19375 (set_attr "mode" "SI")])
19377 (define_expand "movhicc"
19378 [(set (match_operand:HI 0 "register_operand" "")
19379 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19380 (match_operand:HI 2 "general_operand" "")
19381 (match_operand:HI 3 "general_operand" "")))]
19382 "TARGET_HIMODE_MATH"
19383 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19385 (define_insn "*movhicc_noc"
19386 [(set (match_operand:HI 0 "register_operand" "=r,r")
19387 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19388 [(reg FLAGS_REG) (const_int 0)])
19389 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19390 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19392 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19394 cmov%O2%C1\t{%2, %0|%0, %2}
19395 cmov%O2%c1\t{%3, %0|%0, %3}"
19396 [(set_attr "type" "icmov")
19397 (set_attr "mode" "HI")])
19399 (define_expand "movqicc"
19400 [(set (match_operand:QI 0 "register_operand" "")
19401 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19402 (match_operand:QI 2 "general_operand" "")
19403 (match_operand:QI 3 "general_operand" "")))]
19404 "TARGET_QIMODE_MATH"
19405 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19407 (define_insn_and_split "*movqicc_noc"
19408 [(set (match_operand:QI 0 "register_operand" "=r,r")
19409 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19410 [(match_operand 4 "flags_reg_operand" "")
19412 (match_operand:QI 2 "register_operand" "r,0")
19413 (match_operand:QI 3 "register_operand" "0,r")))]
19414 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19416 "&& reload_completed"
19417 [(set (match_dup 0)
19418 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19421 "operands[0] = gen_lowpart (SImode, operands[0]);
19422 operands[2] = gen_lowpart (SImode, operands[2]);
19423 operands[3] = gen_lowpart (SImode, operands[3]);"
19424 [(set_attr "type" "icmov")
19425 (set_attr "mode" "SI")])
19427 (define_expand "mov<mode>cc"
19428 [(set (match_operand:X87MODEF 0 "register_operand" "")
19429 (if_then_else:X87MODEF
19430 (match_operand 1 "comparison_operator" "")
19431 (match_operand:X87MODEF 2 "register_operand" "")
19432 (match_operand:X87MODEF 3 "register_operand" "")))]
19433 "(TARGET_80387 && TARGET_CMOVE)
19434 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19435 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19437 (define_insn "*movsfcc_1_387"
19438 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19439 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19440 [(reg FLAGS_REG) (const_int 0)])
19441 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19442 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19443 "TARGET_80387 && TARGET_CMOVE
19444 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19446 fcmov%F1\t{%2, %0|%0, %2}
19447 fcmov%f1\t{%3, %0|%0, %3}
19448 cmov%O2%C1\t{%2, %0|%0, %2}
19449 cmov%O2%c1\t{%3, %0|%0, %3}"
19450 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19451 (set_attr "mode" "SF,SF,SI,SI")])
19453 (define_insn "*movdfcc_1"
19454 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19455 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19456 [(reg FLAGS_REG) (const_int 0)])
19457 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19458 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19459 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19460 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19462 fcmov%F1\t{%2, %0|%0, %2}
19463 fcmov%f1\t{%3, %0|%0, %3}
19466 [(set_attr "type" "fcmov,fcmov,multi,multi")
19467 (set_attr "mode" "DF")])
19469 (define_insn "*movdfcc_1_rex64"
19470 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19471 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19472 [(reg FLAGS_REG) (const_int 0)])
19473 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19474 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19475 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19476 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19478 fcmov%F1\t{%2, %0|%0, %2}
19479 fcmov%f1\t{%3, %0|%0, %3}
19480 cmov%O2%C1\t{%2, %0|%0, %2}
19481 cmov%O2%c1\t{%3, %0|%0, %3}"
19482 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19483 (set_attr "mode" "DF")])
19486 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19487 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19488 [(match_operand 4 "flags_reg_operand" "")
19490 (match_operand:DF 2 "nonimmediate_operand" "")
19491 (match_operand:DF 3 "nonimmediate_operand" "")))]
19492 "!TARGET_64BIT && reload_completed"
19493 [(set (match_dup 2)
19494 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19498 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19501 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19502 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19504 (define_insn "*movxfcc_1"
19505 [(set (match_operand:XF 0 "register_operand" "=f,f")
19506 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19507 [(reg FLAGS_REG) (const_int 0)])
19508 (match_operand:XF 2 "register_operand" "f,0")
19509 (match_operand:XF 3 "register_operand" "0,f")))]
19510 "TARGET_80387 && TARGET_CMOVE"
19512 fcmov%F1\t{%2, %0|%0, %2}
19513 fcmov%f1\t{%3, %0|%0, %3}"
19514 [(set_attr "type" "fcmov")
19515 (set_attr "mode" "XF")])
19517 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19518 ;; the scalar versions to have only XMM registers as operands.
19520 ;; SSE5 conditional move
19521 (define_insn "*sse5_pcmov_<mode>"
19522 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19523 (if_then_else:MODEF
19524 (match_operand:MODEF 1 "register_operand" "x,0")
19525 (match_operand:MODEF 2 "register_operand" "0,x")
19526 (match_operand:MODEF 3 "register_operand" "x,x")))]
19527 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19528 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19529 [(set_attr "type" "sse4arg")])
19531 ;; These versions of the min/max patterns are intentionally ignorant of
19532 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19533 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19534 ;; are undefined in this condition, we're certain this is correct.
19536 (define_insn "<code><mode>3"
19537 [(set (match_operand:MODEF 0 "register_operand" "=x")
19539 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19540 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19541 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19542 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19543 [(set_attr "type" "sseadd")
19544 (set_attr "mode" "<MODE>")])
19546 ;; These versions of the min/max patterns implement exactly the operations
19547 ;; min = (op1 < op2 ? op1 : op2)
19548 ;; max = (!(op1 < op2) ? op1 : op2)
19549 ;; Their operands are not commutative, and thus they may be used in the
19550 ;; presence of -0.0 and NaN.
19552 (define_insn "*ieee_smin<mode>3"
19553 [(set (match_operand:MODEF 0 "register_operand" "=x")
19555 [(match_operand:MODEF 1 "register_operand" "0")
19556 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19558 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19559 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19560 [(set_attr "type" "sseadd")
19561 (set_attr "mode" "<MODE>")])
19563 (define_insn "*ieee_smax<mode>3"
19564 [(set (match_operand:MODEF 0 "register_operand" "=x")
19566 [(match_operand:MODEF 1 "register_operand" "0")
19567 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19569 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19570 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19571 [(set_attr "type" "sseadd")
19572 (set_attr "mode" "<MODE>")])
19574 ;; Make two stack loads independent:
19576 ;; fld %st(0) -> fld bb
19577 ;; fmul bb fmul %st(1), %st
19579 ;; Actually we only match the last two instructions for simplicity.
19581 [(set (match_operand 0 "fp_register_operand" "")
19582 (match_operand 1 "fp_register_operand" ""))
19584 (match_operator 2 "binary_fp_operator"
19586 (match_operand 3 "memory_operand" "")]))]
19587 "REGNO (operands[0]) != REGNO (operands[1])"
19588 [(set (match_dup 0) (match_dup 3))
19589 (set (match_dup 0) (match_dup 4))]
19591 ;; The % modifier is not operational anymore in peephole2's, so we have to
19592 ;; swap the operands manually in the case of addition and multiplication.
19593 "if (COMMUTATIVE_ARITH_P (operands[2]))
19594 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19595 operands[0], operands[1]);
19597 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19598 operands[1], operands[0]);")
19600 ;; Conditional addition patterns
19601 (define_expand "add<mode>cc"
19602 [(match_operand:SWI 0 "register_operand" "")
19603 (match_operand 1 "comparison_operator" "")
19604 (match_operand:SWI 2 "register_operand" "")
19605 (match_operand:SWI 3 "const_int_operand" "")]
19607 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19610 ;; Misc patterns (?)
19612 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19613 ;; Otherwise there will be nothing to keep
19615 ;; [(set (reg ebp) (reg esp))]
19616 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19617 ;; (clobber (eflags)]
19618 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19620 ;; in proper program order.
19621 (define_insn "pro_epilogue_adjust_stack_1"
19622 [(set (match_operand:SI 0 "register_operand" "=r,r")
19623 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19624 (match_operand:SI 2 "immediate_operand" "i,i")))
19625 (clobber (reg:CC FLAGS_REG))
19626 (clobber (mem:BLK (scratch)))]
19629 switch (get_attr_type (insn))
19632 return "mov{l}\t{%1, %0|%0, %1}";
19635 if (CONST_INT_P (operands[2])
19636 && (INTVAL (operands[2]) == 128
19637 || (INTVAL (operands[2]) < 0
19638 && INTVAL (operands[2]) != -128)))
19640 operands[2] = GEN_INT (-INTVAL (operands[2]));
19641 return "sub{l}\t{%2, %0|%0, %2}";
19643 return "add{l}\t{%2, %0|%0, %2}";
19646 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19647 return "lea{l}\t{%a2, %0|%0, %a2}";
19650 gcc_unreachable ();
19653 [(set (attr "type")
19654 (cond [(eq_attr "alternative" "0")
19655 (const_string "alu")
19656 (match_operand:SI 2 "const0_operand" "")
19657 (const_string "imov")
19659 (const_string "lea")))
19660 (set_attr "mode" "SI")])
19662 (define_insn "pro_epilogue_adjust_stack_rex64"
19663 [(set (match_operand:DI 0 "register_operand" "=r,r")
19664 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19665 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19666 (clobber (reg:CC FLAGS_REG))
19667 (clobber (mem:BLK (scratch)))]
19670 switch (get_attr_type (insn))
19673 return "mov{q}\t{%1, %0|%0, %1}";
19676 if (CONST_INT_P (operands[2])
19677 /* Avoid overflows. */
19678 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19679 && (INTVAL (operands[2]) == 128
19680 || (INTVAL (operands[2]) < 0
19681 && INTVAL (operands[2]) != -128)))
19683 operands[2] = GEN_INT (-INTVAL (operands[2]));
19684 return "sub{q}\t{%2, %0|%0, %2}";
19686 return "add{q}\t{%2, %0|%0, %2}";
19689 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19690 return "lea{q}\t{%a2, %0|%0, %a2}";
19693 gcc_unreachable ();
19696 [(set (attr "type")
19697 (cond [(eq_attr "alternative" "0")
19698 (const_string "alu")
19699 (match_operand:DI 2 "const0_operand" "")
19700 (const_string "imov")
19702 (const_string "lea")))
19703 (set_attr "mode" "DI")])
19705 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19706 [(set (match_operand:DI 0 "register_operand" "=r,r")
19707 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19708 (match_operand:DI 3 "immediate_operand" "i,i")))
19709 (use (match_operand:DI 2 "register_operand" "r,r"))
19710 (clobber (reg:CC FLAGS_REG))
19711 (clobber (mem:BLK (scratch)))]
19714 switch (get_attr_type (insn))
19717 return "add{q}\t{%2, %0|%0, %2}";
19720 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19721 return "lea{q}\t{%a2, %0|%0, %a2}";
19724 gcc_unreachable ();
19727 [(set_attr "type" "alu,lea")
19728 (set_attr "mode" "DI")])
19730 (define_insn "allocate_stack_worker_32"
19731 [(set (match_operand:SI 0 "register_operand" "+a")
19732 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19733 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19734 (clobber (reg:CC FLAGS_REG))]
19735 "!TARGET_64BIT && TARGET_STACK_PROBE"
19737 [(set_attr "type" "multi")
19738 (set_attr "length" "5")])
19740 (define_insn "allocate_stack_worker_64"
19741 [(set (match_operand:DI 0 "register_operand" "+a")
19742 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19743 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19744 (clobber (reg:DI R10_REG))
19745 (clobber (reg:DI R11_REG))
19746 (clobber (reg:CC FLAGS_REG))]
19747 "TARGET_64BIT && TARGET_STACK_PROBE"
19749 [(set_attr "type" "multi")
19750 (set_attr "length" "5")])
19752 (define_expand "allocate_stack"
19753 [(match_operand 0 "register_operand" "")
19754 (match_operand 1 "general_operand" "")]
19755 "TARGET_STACK_PROBE"
19759 #ifndef CHECK_STACK_LIMIT
19760 #define CHECK_STACK_LIMIT 0
19763 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19764 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19766 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19767 stack_pointer_rtx, 0, OPTAB_DIRECT);
19768 if (x != stack_pointer_rtx)
19769 emit_move_insn (stack_pointer_rtx, x);
19773 x = copy_to_mode_reg (Pmode, operands[1]);
19775 x = gen_allocate_stack_worker_64 (x);
19777 x = gen_allocate_stack_worker_32 (x);
19781 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19785 (define_expand "builtin_setjmp_receiver"
19786 [(label_ref (match_operand 0 "" ""))]
19787 "!TARGET_64BIT && flag_pic"
19792 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19793 rtx label_rtx = gen_label_rtx ();
19794 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19795 xops[0] = xops[1] = picreg;
19796 xops[2] = gen_rtx_CONST (SImode,
19797 gen_rtx_MINUS (SImode,
19798 gen_rtx_LABEL_REF (SImode, label_rtx),
19799 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19800 ix86_expand_binary_operator (MINUS, SImode, xops);
19803 emit_insn (gen_set_got (pic_offset_table_rtx));
19807 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19810 [(set (match_operand 0 "register_operand" "")
19811 (match_operator 3 "promotable_binary_operator"
19812 [(match_operand 1 "register_operand" "")
19813 (match_operand 2 "aligned_operand" "")]))
19814 (clobber (reg:CC FLAGS_REG))]
19815 "! TARGET_PARTIAL_REG_STALL && reload_completed
19816 && ((GET_MODE (operands[0]) == HImode
19817 && ((!optimize_size && !TARGET_FAST_PREFIX)
19818 /* ??? next two lines just !satisfies_constraint_K (...) */
19819 || !CONST_INT_P (operands[2])
19820 || satisfies_constraint_K (operands[2])))
19821 || (GET_MODE (operands[0]) == QImode
19822 && (TARGET_PROMOTE_QImode || optimize_size)))"
19823 [(parallel [(set (match_dup 0)
19824 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19825 (clobber (reg:CC FLAGS_REG))])]
19826 "operands[0] = gen_lowpart (SImode, operands[0]);
19827 operands[1] = gen_lowpart (SImode, operands[1]);
19828 if (GET_CODE (operands[3]) != ASHIFT)
19829 operands[2] = gen_lowpart (SImode, operands[2]);
19830 PUT_MODE (operands[3], SImode);")
19832 ; Promote the QImode tests, as i386 has encoding of the AND
19833 ; instruction with 32-bit sign-extended immediate and thus the
19834 ; instruction size is unchanged, except in the %eax case for
19835 ; which it is increased by one byte, hence the ! optimize_size.
19837 [(set (match_operand 0 "flags_reg_operand" "")
19838 (match_operator 2 "compare_operator"
19839 [(and (match_operand 3 "aligned_operand" "")
19840 (match_operand 4 "const_int_operand" ""))
19842 (set (match_operand 1 "register_operand" "")
19843 (and (match_dup 3) (match_dup 4)))]
19844 "! TARGET_PARTIAL_REG_STALL && reload_completed
19846 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19847 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19848 /* Ensure that the operand will remain sign-extended immediate. */
19849 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19850 [(parallel [(set (match_dup 0)
19851 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19854 (and:SI (match_dup 3) (match_dup 4)))])]
19857 = gen_int_mode (INTVAL (operands[4])
19858 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19859 operands[1] = gen_lowpart (SImode, operands[1]);
19860 operands[3] = gen_lowpart (SImode, operands[3]);
19863 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19864 ; the TEST instruction with 32-bit sign-extended immediate and thus
19865 ; the instruction size would at least double, which is not what we
19866 ; want even with ! optimize_size.
19868 [(set (match_operand 0 "flags_reg_operand" "")
19869 (match_operator 1 "compare_operator"
19870 [(and (match_operand:HI 2 "aligned_operand" "")
19871 (match_operand:HI 3 "const_int_operand" ""))
19873 "! TARGET_PARTIAL_REG_STALL && reload_completed
19874 && ! TARGET_FAST_PREFIX
19876 /* Ensure that the operand will remain sign-extended immediate. */
19877 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19878 [(set (match_dup 0)
19879 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19883 = gen_int_mode (INTVAL (operands[3])
19884 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19885 operands[2] = gen_lowpart (SImode, operands[2]);
19889 [(set (match_operand 0 "register_operand" "")
19890 (neg (match_operand 1 "register_operand" "")))
19891 (clobber (reg:CC FLAGS_REG))]
19892 "! TARGET_PARTIAL_REG_STALL && reload_completed
19893 && (GET_MODE (operands[0]) == HImode
19894 || (GET_MODE (operands[0]) == QImode
19895 && (TARGET_PROMOTE_QImode || optimize_size)))"
19896 [(parallel [(set (match_dup 0)
19897 (neg:SI (match_dup 1)))
19898 (clobber (reg:CC FLAGS_REG))])]
19899 "operands[0] = gen_lowpart (SImode, operands[0]);
19900 operands[1] = gen_lowpart (SImode, operands[1]);")
19903 [(set (match_operand 0 "register_operand" "")
19904 (not (match_operand 1 "register_operand" "")))]
19905 "! TARGET_PARTIAL_REG_STALL && reload_completed
19906 && (GET_MODE (operands[0]) == HImode
19907 || (GET_MODE (operands[0]) == QImode
19908 && (TARGET_PROMOTE_QImode || optimize_size)))"
19909 [(set (match_dup 0)
19910 (not:SI (match_dup 1)))]
19911 "operands[0] = gen_lowpart (SImode, operands[0]);
19912 operands[1] = gen_lowpart (SImode, operands[1]);")
19915 [(set (match_operand 0 "register_operand" "")
19916 (if_then_else (match_operator 1 "comparison_operator"
19917 [(reg FLAGS_REG) (const_int 0)])
19918 (match_operand 2 "register_operand" "")
19919 (match_operand 3 "register_operand" "")))]
19920 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19921 && (GET_MODE (operands[0]) == HImode
19922 || (GET_MODE (operands[0]) == QImode
19923 && (TARGET_PROMOTE_QImode || optimize_size)))"
19924 [(set (match_dup 0)
19925 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19926 "operands[0] = gen_lowpart (SImode, operands[0]);
19927 operands[2] = gen_lowpart (SImode, operands[2]);
19928 operands[3] = gen_lowpart (SImode, operands[3]);")
19931 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19932 ;; transform a complex memory operation into two memory to register operations.
19934 ;; Don't push memory operands
19936 [(set (match_operand:SI 0 "push_operand" "")
19937 (match_operand:SI 1 "memory_operand" ""))
19938 (match_scratch:SI 2 "r")]
19939 "!optimize_size && !TARGET_PUSH_MEMORY
19940 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19941 [(set (match_dup 2) (match_dup 1))
19942 (set (match_dup 0) (match_dup 2))]
19946 [(set (match_operand:DI 0 "push_operand" "")
19947 (match_operand:DI 1 "memory_operand" ""))
19948 (match_scratch:DI 2 "r")]
19949 "!optimize_size && !TARGET_PUSH_MEMORY
19950 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19951 [(set (match_dup 2) (match_dup 1))
19952 (set (match_dup 0) (match_dup 2))]
19955 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19958 [(set (match_operand:SF 0 "push_operand" "")
19959 (match_operand:SF 1 "memory_operand" ""))
19960 (match_scratch:SF 2 "r")]
19961 "!optimize_size && !TARGET_PUSH_MEMORY
19962 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19963 [(set (match_dup 2) (match_dup 1))
19964 (set (match_dup 0) (match_dup 2))]
19968 [(set (match_operand:HI 0 "push_operand" "")
19969 (match_operand:HI 1 "memory_operand" ""))
19970 (match_scratch:HI 2 "r")]
19971 "!optimize_size && !TARGET_PUSH_MEMORY
19972 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19973 [(set (match_dup 2) (match_dup 1))
19974 (set (match_dup 0) (match_dup 2))]
19978 [(set (match_operand:QI 0 "push_operand" "")
19979 (match_operand:QI 1 "memory_operand" ""))
19980 (match_scratch:QI 2 "q")]
19981 "!optimize_size && !TARGET_PUSH_MEMORY
19982 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19983 [(set (match_dup 2) (match_dup 1))
19984 (set (match_dup 0) (match_dup 2))]
19987 ;; Don't move an immediate directly to memory when the instruction
19990 [(match_scratch:SI 1 "r")
19991 (set (match_operand:SI 0 "memory_operand" "")
19994 && ! TARGET_USE_MOV0
19995 && TARGET_SPLIT_LONG_MOVES
19996 && get_attr_length (insn) >= ix86_cost->large_insn
19997 && peep2_regno_dead_p (0, FLAGS_REG)"
19998 [(parallel [(set (match_dup 1) (const_int 0))
19999 (clobber (reg:CC FLAGS_REG))])
20000 (set (match_dup 0) (match_dup 1))]
20004 [(match_scratch:HI 1 "r")
20005 (set (match_operand:HI 0 "memory_operand" "")
20008 && ! TARGET_USE_MOV0
20009 && TARGET_SPLIT_LONG_MOVES
20010 && get_attr_length (insn) >= ix86_cost->large_insn
20011 && peep2_regno_dead_p (0, FLAGS_REG)"
20012 [(parallel [(set (match_dup 2) (const_int 0))
20013 (clobber (reg:CC FLAGS_REG))])
20014 (set (match_dup 0) (match_dup 1))]
20015 "operands[2] = gen_lowpart (SImode, operands[1]);")
20018 [(match_scratch:QI 1 "q")
20019 (set (match_operand:QI 0 "memory_operand" "")
20022 && ! TARGET_USE_MOV0
20023 && TARGET_SPLIT_LONG_MOVES
20024 && get_attr_length (insn) >= ix86_cost->large_insn
20025 && peep2_regno_dead_p (0, FLAGS_REG)"
20026 [(parallel [(set (match_dup 2) (const_int 0))
20027 (clobber (reg:CC FLAGS_REG))])
20028 (set (match_dup 0) (match_dup 1))]
20029 "operands[2] = gen_lowpart (SImode, operands[1]);")
20032 [(match_scratch:SI 2 "r")
20033 (set (match_operand:SI 0 "memory_operand" "")
20034 (match_operand:SI 1 "immediate_operand" ""))]
20036 && TARGET_SPLIT_LONG_MOVES
20037 && get_attr_length (insn) >= ix86_cost->large_insn"
20038 [(set (match_dup 2) (match_dup 1))
20039 (set (match_dup 0) (match_dup 2))]
20043 [(match_scratch:HI 2 "r")
20044 (set (match_operand:HI 0 "memory_operand" "")
20045 (match_operand:HI 1 "immediate_operand" ""))]
20047 && TARGET_SPLIT_LONG_MOVES
20048 && get_attr_length (insn) >= ix86_cost->large_insn"
20049 [(set (match_dup 2) (match_dup 1))
20050 (set (match_dup 0) (match_dup 2))]
20054 [(match_scratch:QI 2 "q")
20055 (set (match_operand:QI 0 "memory_operand" "")
20056 (match_operand:QI 1 "immediate_operand" ""))]
20058 && TARGET_SPLIT_LONG_MOVES
20059 && get_attr_length (insn) >= ix86_cost->large_insn"
20060 [(set (match_dup 2) (match_dup 1))
20061 (set (match_dup 0) (match_dup 2))]
20064 ;; Don't compare memory with zero, load and use a test instead.
20066 [(set (match_operand 0 "flags_reg_operand" "")
20067 (match_operator 1 "compare_operator"
20068 [(match_operand:SI 2 "memory_operand" "")
20070 (match_scratch:SI 3 "r")]
20071 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20072 [(set (match_dup 3) (match_dup 2))
20073 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20076 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20077 ;; Don't split NOTs with a displacement operand, because resulting XOR
20078 ;; will not be pairable anyway.
20080 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20081 ;; represented using a modRM byte. The XOR replacement is long decoded,
20082 ;; so this split helps here as well.
20084 ;; Note: Can't do this as a regular split because we can't get proper
20085 ;; lifetime information then.
20088 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20089 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20091 && ((TARGET_NOT_UNPAIRABLE
20092 && (!MEM_P (operands[0])
20093 || !memory_displacement_operand (operands[0], SImode)))
20094 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20095 && peep2_regno_dead_p (0, FLAGS_REG)"
20096 [(parallel [(set (match_dup 0)
20097 (xor:SI (match_dup 1) (const_int -1)))
20098 (clobber (reg:CC FLAGS_REG))])]
20102 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20103 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20105 && ((TARGET_NOT_UNPAIRABLE
20106 && (!MEM_P (operands[0])
20107 || !memory_displacement_operand (operands[0], HImode)))
20108 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20109 && peep2_regno_dead_p (0, FLAGS_REG)"
20110 [(parallel [(set (match_dup 0)
20111 (xor:HI (match_dup 1) (const_int -1)))
20112 (clobber (reg:CC FLAGS_REG))])]
20116 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20117 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20119 && ((TARGET_NOT_UNPAIRABLE
20120 && (!MEM_P (operands[0])
20121 || !memory_displacement_operand (operands[0], QImode)))
20122 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20123 && peep2_regno_dead_p (0, FLAGS_REG)"
20124 [(parallel [(set (match_dup 0)
20125 (xor:QI (match_dup 1) (const_int -1)))
20126 (clobber (reg:CC FLAGS_REG))])]
20129 ;; Non pairable "test imm, reg" instructions can be translated to
20130 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20131 ;; byte opcode instead of two, have a short form for byte operands),
20132 ;; so do it for other CPUs as well. Given that the value was dead,
20133 ;; this should not create any new dependencies. Pass on the sub-word
20134 ;; versions if we're concerned about partial register stalls.
20137 [(set (match_operand 0 "flags_reg_operand" "")
20138 (match_operator 1 "compare_operator"
20139 [(and:SI (match_operand:SI 2 "register_operand" "")
20140 (match_operand:SI 3 "immediate_operand" ""))
20142 "ix86_match_ccmode (insn, CCNOmode)
20143 && (true_regnum (operands[2]) != AX_REG
20144 || satisfies_constraint_K (operands[3]))
20145 && peep2_reg_dead_p (1, operands[2])"
20147 [(set (match_dup 0)
20148 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20151 (and:SI (match_dup 2) (match_dup 3)))])]
20154 ;; We don't need to handle HImode case, because it will be promoted to SImode
20155 ;; on ! TARGET_PARTIAL_REG_STALL
20158 [(set (match_operand 0 "flags_reg_operand" "")
20159 (match_operator 1 "compare_operator"
20160 [(and:QI (match_operand:QI 2 "register_operand" "")
20161 (match_operand:QI 3 "immediate_operand" ""))
20163 "! TARGET_PARTIAL_REG_STALL
20164 && ix86_match_ccmode (insn, CCNOmode)
20165 && true_regnum (operands[2]) != AX_REG
20166 && peep2_reg_dead_p (1, operands[2])"
20168 [(set (match_dup 0)
20169 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20172 (and:QI (match_dup 2) (match_dup 3)))])]
20176 [(set (match_operand 0 "flags_reg_operand" "")
20177 (match_operator 1 "compare_operator"
20180 (match_operand 2 "ext_register_operand" "")
20183 (match_operand 3 "const_int_operand" ""))
20185 "! TARGET_PARTIAL_REG_STALL
20186 && ix86_match_ccmode (insn, CCNOmode)
20187 && true_regnum (operands[2]) != AX_REG
20188 && peep2_reg_dead_p (1, operands[2])"
20189 [(parallel [(set (match_dup 0)
20198 (set (zero_extract:SI (match_dup 2)
20209 ;; Don't do logical operations with memory inputs.
20211 [(match_scratch:SI 2 "r")
20212 (parallel [(set (match_operand:SI 0 "register_operand" "")
20213 (match_operator:SI 3 "arith_or_logical_operator"
20215 (match_operand:SI 1 "memory_operand" "")]))
20216 (clobber (reg:CC FLAGS_REG))])]
20217 "! optimize_size && ! TARGET_READ_MODIFY"
20218 [(set (match_dup 2) (match_dup 1))
20219 (parallel [(set (match_dup 0)
20220 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20221 (clobber (reg:CC FLAGS_REG))])]
20225 [(match_scratch:SI 2 "r")
20226 (parallel [(set (match_operand:SI 0 "register_operand" "")
20227 (match_operator:SI 3 "arith_or_logical_operator"
20228 [(match_operand:SI 1 "memory_operand" "")
20230 (clobber (reg:CC FLAGS_REG))])]
20231 "! optimize_size && ! TARGET_READ_MODIFY"
20232 [(set (match_dup 2) (match_dup 1))
20233 (parallel [(set (match_dup 0)
20234 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20235 (clobber (reg:CC FLAGS_REG))])]
20238 ; Don't do logical operations with memory outputs
20240 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20241 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20242 ; the same decoder scheduling characteristics as the original.
20245 [(match_scratch:SI 2 "r")
20246 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20247 (match_operator:SI 3 "arith_or_logical_operator"
20249 (match_operand:SI 1 "nonmemory_operand" "")]))
20250 (clobber (reg:CC FLAGS_REG))])]
20251 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20252 [(set (match_dup 2) (match_dup 0))
20253 (parallel [(set (match_dup 2)
20254 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20255 (clobber (reg:CC FLAGS_REG))])
20256 (set (match_dup 0) (match_dup 2))]
20260 [(match_scratch:SI 2 "r")
20261 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20262 (match_operator:SI 3 "arith_or_logical_operator"
20263 [(match_operand:SI 1 "nonmemory_operand" "")
20265 (clobber (reg:CC FLAGS_REG))])]
20266 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20267 [(set (match_dup 2) (match_dup 0))
20268 (parallel [(set (match_dup 2)
20269 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20270 (clobber (reg:CC FLAGS_REG))])
20271 (set (match_dup 0) (match_dup 2))]
20274 ;; Attempt to always use XOR for zeroing registers.
20276 [(set (match_operand 0 "register_operand" "")
20277 (match_operand 1 "const0_operand" ""))]
20278 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20279 && (! TARGET_USE_MOV0 || optimize_size)
20280 && GENERAL_REG_P (operands[0])
20281 && peep2_regno_dead_p (0, FLAGS_REG)"
20282 [(parallel [(set (match_dup 0) (const_int 0))
20283 (clobber (reg:CC FLAGS_REG))])]
20285 operands[0] = gen_lowpart (word_mode, operands[0]);
20289 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20291 "(GET_MODE (operands[0]) == QImode
20292 || GET_MODE (operands[0]) == HImode)
20293 && (! TARGET_USE_MOV0 || optimize_size)
20294 && peep2_regno_dead_p (0, FLAGS_REG)"
20295 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20296 (clobber (reg:CC FLAGS_REG))])])
20298 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20300 [(set (match_operand 0 "register_operand" "")
20302 "(GET_MODE (operands[0]) == HImode
20303 || GET_MODE (operands[0]) == SImode
20304 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20305 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20306 && peep2_regno_dead_p (0, FLAGS_REG)"
20307 [(parallel [(set (match_dup 0) (const_int -1))
20308 (clobber (reg:CC FLAGS_REG))])]
20309 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20312 ;; Attempt to convert simple leas to adds. These can be created by
20315 [(set (match_operand:SI 0 "register_operand" "")
20316 (plus:SI (match_dup 0)
20317 (match_operand:SI 1 "nonmemory_operand" "")))]
20318 "peep2_regno_dead_p (0, FLAGS_REG)"
20319 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20320 (clobber (reg:CC FLAGS_REG))])]
20324 [(set (match_operand:SI 0 "register_operand" "")
20325 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20326 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20327 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20328 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20329 (clobber (reg:CC FLAGS_REG))])]
20330 "operands[2] = gen_lowpart (SImode, operands[2]);")
20333 [(set (match_operand:DI 0 "register_operand" "")
20334 (plus:DI (match_dup 0)
20335 (match_operand:DI 1 "x86_64_general_operand" "")))]
20336 "peep2_regno_dead_p (0, FLAGS_REG)"
20337 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20338 (clobber (reg:CC FLAGS_REG))])]
20342 [(set (match_operand:SI 0 "register_operand" "")
20343 (mult:SI (match_dup 0)
20344 (match_operand:SI 1 "const_int_operand" "")))]
20345 "exact_log2 (INTVAL (operands[1])) >= 0
20346 && peep2_regno_dead_p (0, FLAGS_REG)"
20347 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20348 (clobber (reg:CC FLAGS_REG))])]
20349 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20352 [(set (match_operand:DI 0 "register_operand" "")
20353 (mult:DI (match_dup 0)
20354 (match_operand:DI 1 "const_int_operand" "")))]
20355 "exact_log2 (INTVAL (operands[1])) >= 0
20356 && peep2_regno_dead_p (0, FLAGS_REG)"
20357 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20358 (clobber (reg:CC FLAGS_REG))])]
20359 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20362 [(set (match_operand:SI 0 "register_operand" "")
20363 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20364 (match_operand:DI 2 "const_int_operand" "")) 0))]
20365 "exact_log2 (INTVAL (operands[2])) >= 0
20366 && REGNO (operands[0]) == REGNO (operands[1])
20367 && peep2_regno_dead_p (0, FLAGS_REG)"
20368 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20369 (clobber (reg:CC FLAGS_REG))])]
20370 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20372 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20373 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20374 ;; many CPUs it is also faster, since special hardware to avoid esp
20375 ;; dependencies is present.
20377 ;; While some of these conversions may be done using splitters, we use peepholes
20378 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20380 ;; Convert prologue esp subtractions to push.
20381 ;; We need register to push. In order to keep verify_flow_info happy we have
20383 ;; - use scratch and clobber it in order to avoid dependencies
20384 ;; - use already live register
20385 ;; We can't use the second way right now, since there is no reliable way how to
20386 ;; verify that given register is live. First choice will also most likely in
20387 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20388 ;; call clobbered registers are dead. We may want to use base pointer as an
20389 ;; alternative when no register is available later.
20392 [(match_scratch:SI 0 "r")
20393 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20394 (clobber (reg:CC FLAGS_REG))
20395 (clobber (mem:BLK (scratch)))])]
20396 "optimize_size || !TARGET_SUB_ESP_4"
20397 [(clobber (match_dup 0))
20398 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20399 (clobber (mem:BLK (scratch)))])])
20402 [(match_scratch:SI 0 "r")
20403 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20404 (clobber (reg:CC FLAGS_REG))
20405 (clobber (mem:BLK (scratch)))])]
20406 "optimize_size || !TARGET_SUB_ESP_8"
20407 [(clobber (match_dup 0))
20408 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20409 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20410 (clobber (mem:BLK (scratch)))])])
20412 ;; Convert esp subtractions to push.
20414 [(match_scratch:SI 0 "r")
20415 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20416 (clobber (reg:CC FLAGS_REG))])]
20417 "optimize_size || !TARGET_SUB_ESP_4"
20418 [(clobber (match_dup 0))
20419 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20422 [(match_scratch:SI 0 "r")
20423 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20424 (clobber (reg:CC FLAGS_REG))])]
20425 "optimize_size || !TARGET_SUB_ESP_8"
20426 [(clobber (match_dup 0))
20427 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20428 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20430 ;; Convert epilogue deallocator to pop.
20432 [(match_scratch:SI 0 "r")
20433 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20434 (clobber (reg:CC FLAGS_REG))
20435 (clobber (mem:BLK (scratch)))])]
20436 "optimize_size || !TARGET_ADD_ESP_4"
20437 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20438 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20439 (clobber (mem:BLK (scratch)))])]
20442 ;; Two pops case is tricky, since pop causes dependency on destination register.
20443 ;; We use two registers if available.
20445 [(match_scratch:SI 0 "r")
20446 (match_scratch:SI 1 "r")
20447 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20448 (clobber (reg:CC FLAGS_REG))
20449 (clobber (mem:BLK (scratch)))])]
20450 "optimize_size || !TARGET_ADD_ESP_8"
20451 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20452 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20453 (clobber (mem:BLK (scratch)))])
20454 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20455 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20459 [(match_scratch:SI 0 "r")
20460 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20461 (clobber (reg:CC FLAGS_REG))
20462 (clobber (mem:BLK (scratch)))])]
20464 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20465 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20466 (clobber (mem:BLK (scratch)))])
20467 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20468 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20471 ;; Convert esp additions to pop.
20473 [(match_scratch:SI 0 "r")
20474 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20475 (clobber (reg:CC FLAGS_REG))])]
20477 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20478 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20481 ;; Two pops case is tricky, since pop causes dependency on destination register.
20482 ;; We use two registers if available.
20484 [(match_scratch:SI 0 "r")
20485 (match_scratch:SI 1 "r")
20486 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20487 (clobber (reg:CC FLAGS_REG))])]
20489 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20490 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20491 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20492 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20496 [(match_scratch:SI 0 "r")
20497 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20498 (clobber (reg:CC FLAGS_REG))])]
20500 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20501 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20502 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20503 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20506 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20507 ;; required and register dies. Similarly for 128 to plus -128.
20509 [(set (match_operand 0 "flags_reg_operand" "")
20510 (match_operator 1 "compare_operator"
20511 [(match_operand 2 "register_operand" "")
20512 (match_operand 3 "const_int_operand" "")]))]
20513 "(INTVAL (operands[3]) == -1
20514 || INTVAL (operands[3]) == 1
20515 || INTVAL (operands[3]) == 128)
20516 && ix86_match_ccmode (insn, CCGCmode)
20517 && peep2_reg_dead_p (1, operands[2])"
20518 [(parallel [(set (match_dup 0)
20519 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20520 (clobber (match_dup 2))])]
20524 [(match_scratch:DI 0 "r")
20525 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20526 (clobber (reg:CC FLAGS_REG))
20527 (clobber (mem:BLK (scratch)))])]
20528 "optimize_size || !TARGET_SUB_ESP_4"
20529 [(clobber (match_dup 0))
20530 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20531 (clobber (mem:BLK (scratch)))])])
20534 [(match_scratch:DI 0 "r")
20535 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20536 (clobber (reg:CC FLAGS_REG))
20537 (clobber (mem:BLK (scratch)))])]
20538 "optimize_size || !TARGET_SUB_ESP_8"
20539 [(clobber (match_dup 0))
20540 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20541 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20542 (clobber (mem:BLK (scratch)))])])
20544 ;; Convert esp subtractions to push.
20546 [(match_scratch:DI 0 "r")
20547 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20548 (clobber (reg:CC FLAGS_REG))])]
20549 "optimize_size || !TARGET_SUB_ESP_4"
20550 [(clobber (match_dup 0))
20551 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20554 [(match_scratch:DI 0 "r")
20555 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20556 (clobber (reg:CC FLAGS_REG))])]
20557 "optimize_size || !TARGET_SUB_ESP_8"
20558 [(clobber (match_dup 0))
20559 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20560 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20562 ;; Convert epilogue deallocator to pop.
20564 [(match_scratch:DI 0 "r")
20565 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20566 (clobber (reg:CC FLAGS_REG))
20567 (clobber (mem:BLK (scratch)))])]
20568 "optimize_size || !TARGET_ADD_ESP_4"
20569 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20570 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20571 (clobber (mem:BLK (scratch)))])]
20574 ;; Two pops case is tricky, since pop causes dependency on destination register.
20575 ;; We use two registers if available.
20577 [(match_scratch:DI 0 "r")
20578 (match_scratch:DI 1 "r")
20579 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20580 (clobber (reg:CC FLAGS_REG))
20581 (clobber (mem:BLK (scratch)))])]
20582 "optimize_size || !TARGET_ADD_ESP_8"
20583 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20584 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20585 (clobber (mem:BLK (scratch)))])
20586 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20587 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20591 [(match_scratch:DI 0 "r")
20592 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20593 (clobber (reg:CC FLAGS_REG))
20594 (clobber (mem:BLK (scratch)))])]
20596 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20597 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20598 (clobber (mem:BLK (scratch)))])
20599 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20600 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20603 ;; Convert esp additions to pop.
20605 [(match_scratch:DI 0 "r")
20606 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20607 (clobber (reg:CC FLAGS_REG))])]
20609 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20610 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20613 ;; Two pops case is tricky, since pop causes dependency on destination register.
20614 ;; We use two registers if available.
20616 [(match_scratch:DI 0 "r")
20617 (match_scratch:DI 1 "r")
20618 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20619 (clobber (reg:CC FLAGS_REG))])]
20621 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20622 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20623 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20624 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20628 [(match_scratch:DI 0 "r")
20629 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20630 (clobber (reg:CC FLAGS_REG))])]
20632 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20633 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20634 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20635 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20638 ;; Convert imul by three, five and nine into lea
20641 [(set (match_operand:SI 0 "register_operand" "")
20642 (mult:SI (match_operand:SI 1 "register_operand" "")
20643 (match_operand:SI 2 "const_int_operand" "")))
20644 (clobber (reg:CC FLAGS_REG))])]
20645 "INTVAL (operands[2]) == 3
20646 || INTVAL (operands[2]) == 5
20647 || INTVAL (operands[2]) == 9"
20648 [(set (match_dup 0)
20649 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20651 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20655 [(set (match_operand:SI 0 "register_operand" "")
20656 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20657 (match_operand:SI 2 "const_int_operand" "")))
20658 (clobber (reg:CC FLAGS_REG))])]
20660 && (INTVAL (operands[2]) == 3
20661 || INTVAL (operands[2]) == 5
20662 || INTVAL (operands[2]) == 9)"
20663 [(set (match_dup 0) (match_dup 1))
20665 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20667 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20671 [(set (match_operand:DI 0 "register_operand" "")
20672 (mult:DI (match_operand:DI 1 "register_operand" "")
20673 (match_operand:DI 2 "const_int_operand" "")))
20674 (clobber (reg:CC FLAGS_REG))])]
20676 && (INTVAL (operands[2]) == 3
20677 || INTVAL (operands[2]) == 5
20678 || INTVAL (operands[2]) == 9)"
20679 [(set (match_dup 0)
20680 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20682 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20686 [(set (match_operand:DI 0 "register_operand" "")
20687 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20688 (match_operand:DI 2 "const_int_operand" "")))
20689 (clobber (reg:CC FLAGS_REG))])]
20692 && (INTVAL (operands[2]) == 3
20693 || INTVAL (operands[2]) == 5
20694 || INTVAL (operands[2]) == 9)"
20695 [(set (match_dup 0) (match_dup 1))
20697 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20699 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20701 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20702 ;; imul $32bit_imm, reg, reg is direct decoded.
20704 [(match_scratch:DI 3 "r")
20705 (parallel [(set (match_operand:DI 0 "register_operand" "")
20706 (mult:DI (match_operand:DI 1 "memory_operand" "")
20707 (match_operand:DI 2 "immediate_operand" "")))
20708 (clobber (reg:CC FLAGS_REG))])]
20709 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20710 && !satisfies_constraint_K (operands[2])"
20711 [(set (match_dup 3) (match_dup 1))
20712 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20713 (clobber (reg:CC FLAGS_REG))])]
20717 [(match_scratch:SI 3 "r")
20718 (parallel [(set (match_operand:SI 0 "register_operand" "")
20719 (mult:SI (match_operand:SI 1 "memory_operand" "")
20720 (match_operand:SI 2 "immediate_operand" "")))
20721 (clobber (reg:CC FLAGS_REG))])]
20722 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20723 && !satisfies_constraint_K (operands[2])"
20724 [(set (match_dup 3) (match_dup 1))
20725 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20726 (clobber (reg:CC FLAGS_REG))])]
20730 [(match_scratch:SI 3 "r")
20731 (parallel [(set (match_operand:DI 0 "register_operand" "")
20733 (mult:SI (match_operand:SI 1 "memory_operand" "")
20734 (match_operand:SI 2 "immediate_operand" ""))))
20735 (clobber (reg:CC FLAGS_REG))])]
20736 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20737 && !satisfies_constraint_K (operands[2])"
20738 [(set (match_dup 3) (match_dup 1))
20739 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20740 (clobber (reg:CC FLAGS_REG))])]
20743 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20744 ;; Convert it into imul reg, reg
20745 ;; It would be better to force assembler to encode instruction using long
20746 ;; immediate, but there is apparently no way to do so.
20748 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20749 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20750 (match_operand:DI 2 "const_int_operand" "")))
20751 (clobber (reg:CC FLAGS_REG))])
20752 (match_scratch:DI 3 "r")]
20753 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20754 && satisfies_constraint_K (operands[2])"
20755 [(set (match_dup 3) (match_dup 2))
20756 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20757 (clobber (reg:CC FLAGS_REG))])]
20759 if (!rtx_equal_p (operands[0], operands[1]))
20760 emit_move_insn (operands[0], operands[1]);
20764 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20765 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20766 (match_operand:SI 2 "const_int_operand" "")))
20767 (clobber (reg:CC FLAGS_REG))])
20768 (match_scratch:SI 3 "r")]
20769 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20770 && satisfies_constraint_K (operands[2])"
20771 [(set (match_dup 3) (match_dup 2))
20772 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20773 (clobber (reg:CC FLAGS_REG))])]
20775 if (!rtx_equal_p (operands[0], operands[1]))
20776 emit_move_insn (operands[0], operands[1]);
20780 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20781 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20782 (match_operand:HI 2 "immediate_operand" "")))
20783 (clobber (reg:CC FLAGS_REG))])
20784 (match_scratch:HI 3 "r")]
20785 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20786 [(set (match_dup 3) (match_dup 2))
20787 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20788 (clobber (reg:CC FLAGS_REG))])]
20790 if (!rtx_equal_p (operands[0], operands[1]))
20791 emit_move_insn (operands[0], operands[1]);
20794 ;; After splitting up read-modify operations, array accesses with memory
20795 ;; operands might end up in form:
20797 ;; movl 4(%esp), %edx
20799 ;; instead of pre-splitting:
20801 ;; addl 4(%esp), %eax
20803 ;; movl 4(%esp), %edx
20804 ;; leal (%edx,%eax,4), %eax
20807 [(parallel [(set (match_operand 0 "register_operand" "")
20808 (ashift (match_operand 1 "register_operand" "")
20809 (match_operand 2 "const_int_operand" "")))
20810 (clobber (reg:CC FLAGS_REG))])
20811 (set (match_operand 3 "register_operand")
20812 (match_operand 4 "x86_64_general_operand" ""))
20813 (parallel [(set (match_operand 5 "register_operand" "")
20814 (plus (match_operand 6 "register_operand" "")
20815 (match_operand 7 "register_operand" "")))
20816 (clobber (reg:CC FLAGS_REG))])]
20817 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20818 /* Validate MODE for lea. */
20819 && ((!TARGET_PARTIAL_REG_STALL
20820 && (GET_MODE (operands[0]) == QImode
20821 || GET_MODE (operands[0]) == HImode))
20822 || GET_MODE (operands[0]) == SImode
20823 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20824 /* We reorder load and the shift. */
20825 && !rtx_equal_p (operands[1], operands[3])
20826 && !reg_overlap_mentioned_p (operands[0], operands[4])
20827 /* Last PLUS must consist of operand 0 and 3. */
20828 && !rtx_equal_p (operands[0], operands[3])
20829 && (rtx_equal_p (operands[3], operands[6])
20830 || rtx_equal_p (operands[3], operands[7]))
20831 && (rtx_equal_p (operands[0], operands[6])
20832 || rtx_equal_p (operands[0], operands[7]))
20833 /* The intermediate operand 0 must die or be same as output. */
20834 && (rtx_equal_p (operands[0], operands[5])
20835 || peep2_reg_dead_p (3, operands[0]))"
20836 [(set (match_dup 3) (match_dup 4))
20837 (set (match_dup 0) (match_dup 1))]
20839 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20840 int scale = 1 << INTVAL (operands[2]);
20841 rtx index = gen_lowpart (Pmode, operands[1]);
20842 rtx base = gen_lowpart (Pmode, operands[3]);
20843 rtx dest = gen_lowpart (mode, operands[5]);
20845 operands[1] = gen_rtx_PLUS (Pmode, base,
20846 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20848 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20849 operands[0] = dest;
20852 ;; Call-value patterns last so that the wildcard operand does not
20853 ;; disrupt insn-recog's switch tables.
20855 (define_insn "*call_value_pop_0"
20856 [(set (match_operand 0 "" "")
20857 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20858 (match_operand:SI 2 "" "")))
20859 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20860 (match_operand:SI 3 "immediate_operand" "")))]
20863 if (SIBLING_CALL_P (insn))
20866 return "call\t%P1";
20868 [(set_attr "type" "callv")])
20870 (define_insn "*call_value_pop_1"
20871 [(set (match_operand 0 "" "")
20872 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20873 (match_operand:SI 2 "" "")))
20874 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20875 (match_operand:SI 3 "immediate_operand" "i")))]
20878 if (constant_call_address_operand (operands[1], Pmode))
20880 if (SIBLING_CALL_P (insn))
20883 return "call\t%P1";
20885 if (SIBLING_CALL_P (insn))
20888 return "call\t%A1";
20890 [(set_attr "type" "callv")])
20892 (define_insn "*call_value_0"
20893 [(set (match_operand 0 "" "")
20894 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20895 (match_operand:SI 2 "" "")))]
20898 if (SIBLING_CALL_P (insn))
20901 return "call\t%P1";
20903 [(set_attr "type" "callv")])
20905 (define_insn "*call_value_0_rex64"
20906 [(set (match_operand 0 "" "")
20907 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20908 (match_operand:DI 2 "const_int_operand" "")))]
20911 if (SIBLING_CALL_P (insn))
20914 return "call\t%P1";
20916 [(set_attr "type" "callv")])
20918 (define_insn "*call_value_1"
20919 [(set (match_operand 0 "" "")
20920 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20921 (match_operand:SI 2 "" "")))]
20922 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20924 if (constant_call_address_operand (operands[1], Pmode))
20925 return "call\t%P1";
20926 return "call\t%A1";
20928 [(set_attr "type" "callv")])
20930 (define_insn "*sibcall_value_1"
20931 [(set (match_operand 0 "" "")
20932 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20933 (match_operand:SI 2 "" "")))]
20934 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20936 if (constant_call_address_operand (operands[1], Pmode))
20940 [(set_attr "type" "callv")])
20942 (define_insn "*call_value_1_rex64"
20943 [(set (match_operand 0 "" "")
20944 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20945 (match_operand:DI 2 "" "")))]
20946 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20947 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20949 if (constant_call_address_operand (operands[1], Pmode))
20950 return "call\t%P1";
20951 return "call\t%A1";
20953 [(set_attr "type" "callv")])
20955 (define_insn "*call_value_1_rex64_large"
20956 [(set (match_operand 0 "" "")
20957 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20958 (match_operand:DI 2 "" "")))]
20959 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20961 [(set_attr "type" "callv")])
20963 (define_insn "*sibcall_value_1_rex64"
20964 [(set (match_operand 0 "" "")
20965 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20966 (match_operand:DI 2 "" "")))]
20967 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20969 [(set_attr "type" "callv")])
20971 (define_insn "*sibcall_value_1_rex64_v"
20972 [(set (match_operand 0 "" "")
20973 (call (mem:QI (reg:DI R11_REG))
20974 (match_operand:DI 1 "" "")))]
20975 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20977 [(set_attr "type" "callv")])
20979 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20980 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20981 ;; caught for use by garbage collectors and the like. Using an insn that
20982 ;; maps to SIGILL makes it more likely the program will rightfully die.
20983 ;; Keeping with tradition, "6" is in honor of #UD.
20984 (define_insn "trap"
20985 [(trap_if (const_int 1) (const_int 6))]
20987 { return ASM_SHORT "0x0b0f"; }
20988 [(set_attr "length" "2")])
20990 (define_expand "sse_prologue_save"
20991 [(parallel [(set (match_operand:BLK 0 "" "")
20992 (unspec:BLK [(reg:DI 21)
20999 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21000 (use (match_operand:DI 1 "register_operand" ""))
21001 (use (match_operand:DI 2 "immediate_operand" ""))
21002 (use (label_ref:DI (match_operand 3 "" "")))])]
21006 (define_insn "*sse_prologue_save_insn"
21007 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21008 (match_operand:DI 4 "const_int_operand" "n")))
21009 (unspec:BLK [(reg:DI 21)
21016 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21017 (use (match_operand:DI 1 "register_operand" "r"))
21018 (use (match_operand:DI 2 "const_int_operand" "i"))
21019 (use (label_ref:DI (match_operand 3 "" "X")))]
21021 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21022 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21025 operands[0] = gen_rtx_MEM (Pmode,
21026 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21027 output_asm_insn ("jmp\t%A1", operands);
21028 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21030 operands[4] = adjust_address (operands[0], DImode, i*16);
21031 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21032 PUT_MODE (operands[4], TImode);
21033 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21034 output_asm_insn ("rex", operands);
21035 output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
21037 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21038 CODE_LABEL_NUMBER (operands[3]));
21041 [(set_attr "type" "other")
21042 (set_attr "length_immediate" "0")
21043 (set_attr "length_address" "0")
21044 (set_attr "length" "34")
21045 (set_attr "memory" "store")
21046 (set_attr "modrm" "0")
21047 (set_attr "mode" "DI")])
21049 (define_expand "prefetch"
21050 [(prefetch (match_operand 0 "address_operand" "")
21051 (match_operand:SI 1 "const_int_operand" "")
21052 (match_operand:SI 2 "const_int_operand" ""))]
21053 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21055 int rw = INTVAL (operands[1]);
21056 int locality = INTVAL (operands[2]);
21058 gcc_assert (rw == 0 || rw == 1);
21059 gcc_assert (locality >= 0 && locality <= 3);
21060 gcc_assert (GET_MODE (operands[0]) == Pmode
21061 || GET_MODE (operands[0]) == VOIDmode);
21063 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21064 supported by SSE counterpart or the SSE prefetch is not available
21065 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21067 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21068 operands[2] = GEN_INT (3);
21070 operands[1] = const0_rtx;
21073 (define_insn "*prefetch_sse"
21074 [(prefetch (match_operand:SI 0 "address_operand" "p")
21076 (match_operand:SI 1 "const_int_operand" ""))]
21077 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21079 static const char * const patterns[4] = {
21080 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21083 int locality = INTVAL (operands[1]);
21084 gcc_assert (locality >= 0 && locality <= 3);
21086 return patterns[locality];
21088 [(set_attr "type" "sse")
21089 (set_attr "memory" "none")])
21091 (define_insn "*prefetch_sse_rex"
21092 [(prefetch (match_operand:DI 0 "address_operand" "p")
21094 (match_operand:SI 1 "const_int_operand" ""))]
21095 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21097 static const char * const patterns[4] = {
21098 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21101 int locality = INTVAL (operands[1]);
21102 gcc_assert (locality >= 0 && locality <= 3);
21104 return patterns[locality];
21106 [(set_attr "type" "sse")
21107 (set_attr "memory" "none")])
21109 (define_insn "*prefetch_3dnow"
21110 [(prefetch (match_operand:SI 0 "address_operand" "p")
21111 (match_operand:SI 1 "const_int_operand" "n")
21113 "TARGET_3DNOW && !TARGET_64BIT"
21115 if (INTVAL (operands[1]) == 0)
21116 return "prefetch\t%a0";
21118 return "prefetchw\t%a0";
21120 [(set_attr "type" "mmx")
21121 (set_attr "memory" "none")])
21123 (define_insn "*prefetch_3dnow_rex"
21124 [(prefetch (match_operand:DI 0 "address_operand" "p")
21125 (match_operand:SI 1 "const_int_operand" "n")
21127 "TARGET_3DNOW && TARGET_64BIT"
21129 if (INTVAL (operands[1]) == 0)
21130 return "prefetch\t%a0";
21132 return "prefetchw\t%a0";
21134 [(set_attr "type" "mmx")
21135 (set_attr "memory" "none")])
21137 (define_expand "stack_protect_set"
21138 [(match_operand 0 "memory_operand" "")
21139 (match_operand 1 "memory_operand" "")]
21142 #ifdef TARGET_THREAD_SSP_OFFSET
21144 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21145 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21147 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21148 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21151 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21153 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21158 (define_insn "stack_protect_set_si"
21159 [(set (match_operand:SI 0 "memory_operand" "=m")
21160 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21161 (set (match_scratch:SI 2 "=&r") (const_int 0))
21162 (clobber (reg:CC FLAGS_REG))]
21164 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21165 [(set_attr "type" "multi")])
21167 (define_insn "stack_protect_set_di"
21168 [(set (match_operand:DI 0 "memory_operand" "=m")
21169 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21170 (set (match_scratch:DI 2 "=&r") (const_int 0))
21171 (clobber (reg:CC FLAGS_REG))]
21173 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21174 [(set_attr "type" "multi")])
21176 (define_insn "stack_tls_protect_set_si"
21177 [(set (match_operand:SI 0 "memory_operand" "=m")
21178 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21179 (set (match_scratch:SI 2 "=&r") (const_int 0))
21180 (clobber (reg:CC FLAGS_REG))]
21182 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21183 [(set_attr "type" "multi")])
21185 (define_insn "stack_tls_protect_set_di"
21186 [(set (match_operand:DI 0 "memory_operand" "=m")
21187 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21188 (set (match_scratch:DI 2 "=&r") (const_int 0))
21189 (clobber (reg:CC FLAGS_REG))]
21192 /* The kernel uses a different segment register for performance reasons; a
21193 system call would not have to trash the userspace segment register,
21194 which would be expensive */
21195 if (ix86_cmodel != CM_KERNEL)
21196 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21198 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21200 [(set_attr "type" "multi")])
21202 (define_expand "stack_protect_test"
21203 [(match_operand 0 "memory_operand" "")
21204 (match_operand 1 "memory_operand" "")
21205 (match_operand 2 "" "")]
21208 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21209 ix86_compare_op0 = operands[0];
21210 ix86_compare_op1 = operands[1];
21211 ix86_compare_emitted = flags;
21213 #ifdef TARGET_THREAD_SSP_OFFSET
21215 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21216 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21218 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21219 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21222 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21224 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21226 emit_jump_insn (gen_beq (operands[2]));
21230 (define_insn "stack_protect_test_si"
21231 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21232 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21233 (match_operand:SI 2 "memory_operand" "m")]
21235 (clobber (match_scratch:SI 3 "=&r"))]
21237 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21238 [(set_attr "type" "multi")])
21240 (define_insn "stack_protect_test_di"
21241 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21242 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21243 (match_operand:DI 2 "memory_operand" "m")]
21245 (clobber (match_scratch:DI 3 "=&r"))]
21247 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21248 [(set_attr "type" "multi")])
21250 (define_insn "stack_tls_protect_test_si"
21251 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21252 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21253 (match_operand:SI 2 "const_int_operand" "i")]
21254 UNSPEC_SP_TLS_TEST))
21255 (clobber (match_scratch:SI 3 "=r"))]
21257 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21258 [(set_attr "type" "multi")])
21260 (define_insn "stack_tls_protect_test_di"
21261 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21262 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21263 (match_operand:DI 2 "const_int_operand" "i")]
21264 UNSPEC_SP_TLS_TEST))
21265 (clobber (match_scratch:DI 3 "=r"))]
21268 /* The kernel uses a different segment register for performance reasons; a
21269 system call would not have to trash the userspace segment register,
21270 which would be expensive */
21271 if (ix86_cmodel != CM_KERNEL)
21272 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21274 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21276 [(set_attr "type" "multi")])
21278 (define_mode_iterator CRC32MODE [QI HI SI])
21279 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21280 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21282 (define_insn "sse4_2_crc32<mode>"
21283 [(set (match_operand:SI 0 "register_operand" "=r")
21285 [(match_operand:SI 1 "register_operand" "0")
21286 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21289 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21290 [(set_attr "type" "sselog1")
21291 (set_attr "prefix_rep" "1")
21292 (set_attr "prefix_extra" "1")
21293 (set_attr "mode" "SI")])
21295 (define_insn "sse4_2_crc32di"
21296 [(set (match_operand:DI 0 "register_operand" "=r")
21298 [(match_operand:DI 1 "register_operand" "0")
21299 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21301 "TARGET_SSE4_2 && TARGET_64BIT"
21302 "crc32q\t{%2, %0|%0, %2}"
21303 [(set_attr "type" "sselog1")
21304 (set_attr "prefix_rep" "1")
21305 (set_attr "prefix_extra" "1")
21306 (set_attr "mode" "DI")])
21310 (include "sync.md")