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 "i") (HI "i") (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" "n,n")))]
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" "n,n")))]
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" "n,n")))]
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" "ri,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" "ri,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" "n,n")))]
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" "qi,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" "qi,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" "n")))]
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" "X"))]
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" "X")))
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" "i"))
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 "rinm,rin,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" "ri"))]
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" "i"))
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" "qi"))]
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" "i"))
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" "i"))
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" "qi,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" "ri,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" "qi,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" "rmni,rni,lni")))
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" "rmni,lni"))))
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" "rmni,rni"))
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" "rmni"))
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" "rmni"))
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" "rmni"))
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" "rmni"))
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" "ri,rm,lni")))
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" "ri,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" "rmni,rni"))
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" "rmni"))
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" "rmni"))
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" "qmni,qni"))
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" "qmni"))
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" "qmni"))
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" "qi,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" "ri,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" "ri,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" "ri,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" "ri,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,qmn")))
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,qmn")))
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" "qi,qm"))
7560 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7561 (minus:HI (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" "qi,qm")))
7572 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7573 (minus:HI (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,i,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" "in,in,rin"))
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" "ri,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" "g,ri"))
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" "qi,qmi,ri")))
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" "qi,qmi")))
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" "qim,qi,i"))
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" "qim,qi"))
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" "qmi,qi"))
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" "g,ri")))
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" "g,ri"))
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" "g"))
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" "qmi,qi,ri")))
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" "qmi,qi")))
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" "qim,qi"))
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" "qim,qi"))
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" "qim"))
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" "g,ri")))
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" "g,ri"))
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" "g"))
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" "qmi,qi,ri")))
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" "qi,qmi")))
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" "qim,qi"))
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" "qim,qi"))
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" "qim"))
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 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10853 (ashift:TI (match_operand:TI 1 "register_operand" "")
10854 (match_operand:QI 2 "nonmemory_operand" "")))
10855 (clobber (reg:CC FLAGS_REG))])]
10858 if (! immediate_operand (operands[2], QImode))
10860 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10863 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10867 (define_insn "ashlti3_1"
10868 [(set (match_operand:TI 0 "register_operand" "=r")
10869 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10870 (match_operand:QI 2 "register_operand" "c")))
10871 (clobber (match_scratch:DI 3 "=&r"))
10872 (clobber (reg:CC FLAGS_REG))]
10875 [(set_attr "type" "multi")])
10877 ;; This pattern must be defined before *ashlti3_2 to prevent
10878 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10880 (define_insn "sse2_ashlti3"
10881 [(set (match_operand:TI 0 "register_operand" "=x")
10882 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10883 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10886 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10887 return "pslldq\t{%2, %0|%0, %2}";
10889 [(set_attr "type" "sseishft")
10890 (set_attr "prefix_data16" "1")
10891 (set_attr "mode" "TI")])
10893 (define_insn "*ashlti3_2"
10894 [(set (match_operand:TI 0 "register_operand" "=r")
10895 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10896 (match_operand:QI 2 "immediate_operand" "O")))
10897 (clobber (reg:CC FLAGS_REG))]
10900 [(set_attr "type" "multi")])
10903 [(set (match_operand:TI 0 "register_operand" "")
10904 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10905 (match_operand:QI 2 "register_operand" "")))
10906 (clobber (match_scratch:DI 3 ""))
10907 (clobber (reg:CC FLAGS_REG))]
10908 "TARGET_64BIT && reload_completed"
10910 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10913 [(set (match_operand:TI 0 "register_operand" "")
10914 (ashift:TI (match_operand:TI 1 "register_operand" "")
10915 (match_operand:QI 2 "immediate_operand" "")))
10916 (clobber (reg:CC FLAGS_REG))]
10917 "TARGET_64BIT && reload_completed"
10919 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10921 (define_insn "x86_64_shld"
10922 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10923 (ior:DI (ashift:DI (match_dup 0)
10924 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10925 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10926 (minus:QI (const_int 64) (match_dup 2)))))
10927 (clobber (reg:CC FLAGS_REG))]
10930 shld{q}\t{%2, %1, %0|%0, %1, %2}
10931 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10932 [(set_attr "type" "ishift")
10933 (set_attr "prefix_0f" "1")
10934 (set_attr "mode" "DI")
10935 (set_attr "athlon_decode" "vector")
10936 (set_attr "amdfam10_decode" "vector")])
10938 (define_expand "x86_64_shift_adj"
10939 [(set (reg:CCZ FLAGS_REG)
10940 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10943 (set (match_operand:DI 0 "register_operand" "")
10944 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10945 (match_operand:DI 1 "register_operand" "")
10948 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10949 (match_operand:DI 3 "register_operand" "r")
10954 (define_expand "ashldi3"
10955 [(set (match_operand:DI 0 "shiftdi_operand" "")
10956 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10957 (match_operand:QI 2 "nonmemory_operand" "")))]
10959 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10961 (define_insn "*ashldi3_1_rex64"
10962 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10963 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10964 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10965 (clobber (reg:CC FLAGS_REG))]
10966 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10968 switch (get_attr_type (insn))
10971 gcc_assert (operands[2] == const1_rtx);
10972 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10973 return "add{q}\t%0, %0";
10976 gcc_assert (CONST_INT_P (operands[2]));
10977 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10978 operands[1] = gen_rtx_MULT (DImode, operands[1],
10979 GEN_INT (1 << INTVAL (operands[2])));
10980 return "lea{q}\t{%a1, %0|%0, %a1}";
10983 if (REG_P (operands[2]))
10984 return "sal{q}\t{%b2, %0|%0, %b2}";
10985 else if (operands[2] == const1_rtx
10986 && (TARGET_SHIFT1 || optimize_size))
10987 return "sal{q}\t%0";
10989 return "sal{q}\t{%2, %0|%0, %2}";
10992 [(set (attr "type")
10993 (cond [(eq_attr "alternative" "1")
10994 (const_string "lea")
10995 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10997 (match_operand 0 "register_operand" ""))
10998 (match_operand 2 "const1_operand" ""))
10999 (const_string "alu")
11001 (const_string "ishift")))
11002 (set_attr "mode" "DI")])
11004 ;; Convert lea to the lea pattern to avoid flags dependency.
11006 [(set (match_operand:DI 0 "register_operand" "")
11007 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11008 (match_operand:QI 2 "immediate_operand" "")))
11009 (clobber (reg:CC FLAGS_REG))]
11010 "TARGET_64BIT && reload_completed
11011 && true_regnum (operands[0]) != true_regnum (operands[1])"
11012 [(set (match_dup 0)
11013 (mult:DI (match_dup 1)
11015 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11017 ;; This pattern can't accept a variable shift count, since shifts by
11018 ;; zero don't affect the flags. We assume that shifts by constant
11019 ;; zero are optimized away.
11020 (define_insn "*ashldi3_cmp_rex64"
11021 [(set (reg FLAGS_REG)
11023 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11024 (match_operand:QI 2 "immediate_operand" "e"))
11026 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11027 (ashift:DI (match_dup 1) (match_dup 2)))]
11030 || !TARGET_PARTIAL_FLAG_REG_STALL
11031 || (operands[2] == const1_rtx
11033 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11034 && ix86_match_ccmode (insn, CCGOCmode)
11035 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11037 switch (get_attr_type (insn))
11040 gcc_assert (operands[2] == const1_rtx);
11041 return "add{q}\t%0, %0";
11044 if (REG_P (operands[2]))
11045 return "sal{q}\t{%b2, %0|%0, %b2}";
11046 else if (operands[2] == const1_rtx
11047 && (TARGET_SHIFT1 || optimize_size))
11048 return "sal{q}\t%0";
11050 return "sal{q}\t{%2, %0|%0, %2}";
11053 [(set (attr "type")
11054 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11056 (match_operand 0 "register_operand" ""))
11057 (match_operand 2 "const1_operand" ""))
11058 (const_string "alu")
11060 (const_string "ishift")))
11061 (set_attr "mode" "DI")])
11063 (define_insn "*ashldi3_cconly_rex64"
11064 [(set (reg FLAGS_REG)
11066 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11067 (match_operand:QI 2 "immediate_operand" "e"))
11069 (clobber (match_scratch:DI 0 "=r"))]
11072 || !TARGET_PARTIAL_FLAG_REG_STALL
11073 || (operands[2] == const1_rtx
11075 || TARGET_DOUBLE_WITH_ADD)))
11076 && ix86_match_ccmode (insn, CCGOCmode)
11077 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11079 switch (get_attr_type (insn))
11082 gcc_assert (operands[2] == const1_rtx);
11083 return "add{q}\t%0, %0";
11086 if (REG_P (operands[2]))
11087 return "sal{q}\t{%b2, %0|%0, %b2}";
11088 else if (operands[2] == const1_rtx
11089 && (TARGET_SHIFT1 || optimize_size))
11090 return "sal{q}\t%0";
11092 return "sal{q}\t{%2, %0|%0, %2}";
11095 [(set (attr "type")
11096 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11098 (match_operand 0 "register_operand" ""))
11099 (match_operand 2 "const1_operand" ""))
11100 (const_string "alu")
11102 (const_string "ishift")))
11103 (set_attr "mode" "DI")])
11105 (define_insn "*ashldi3_1"
11106 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11107 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11108 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11109 (clobber (reg:CC FLAGS_REG))]
11112 [(set_attr "type" "multi")])
11114 ;; By default we don't ask for a scratch register, because when DImode
11115 ;; values are manipulated, registers are already at a premium. But if
11116 ;; we have one handy, we won't turn it away.
11118 [(match_scratch:SI 3 "r")
11119 (parallel [(set (match_operand:DI 0 "register_operand" "")
11120 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11121 (match_operand:QI 2 "nonmemory_operand" "")))
11122 (clobber (reg:CC FLAGS_REG))])
11124 "!TARGET_64BIT && TARGET_CMOVE"
11126 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11129 [(set (match_operand:DI 0 "register_operand" "")
11130 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11131 (match_operand:QI 2 "nonmemory_operand" "")))
11132 (clobber (reg:CC FLAGS_REG))]
11133 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11134 ? epilogue_completed : reload_completed)"
11136 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11138 (define_insn "x86_shld_1"
11139 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11140 (ior:SI (ashift:SI (match_dup 0)
11141 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11142 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11143 (minus:QI (const_int 32) (match_dup 2)))))
11144 (clobber (reg:CC FLAGS_REG))]
11147 shld{l}\t{%2, %1, %0|%0, %1, %2}
11148 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11149 [(set_attr "type" "ishift")
11150 (set_attr "prefix_0f" "1")
11151 (set_attr "mode" "SI")
11152 (set_attr "pent_pair" "np")
11153 (set_attr "athlon_decode" "vector")
11154 (set_attr "amdfam10_decode" "vector")])
11156 (define_expand "x86_shift_adj_1"
11157 [(set (reg:CCZ FLAGS_REG)
11158 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11161 (set (match_operand:SI 0 "register_operand" "")
11162 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11163 (match_operand:SI 1 "register_operand" "")
11166 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11167 (match_operand:SI 3 "register_operand" "r")
11172 (define_expand "x86_shift_adj_2"
11173 [(use (match_operand:SI 0 "register_operand" ""))
11174 (use (match_operand:SI 1 "register_operand" ""))
11175 (use (match_operand:QI 2 "register_operand" ""))]
11178 rtx label = gen_label_rtx ();
11181 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11183 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11184 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11185 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11186 gen_rtx_LABEL_REF (VOIDmode, label),
11188 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11189 JUMP_LABEL (tmp) = label;
11191 emit_move_insn (operands[0], operands[1]);
11192 ix86_expand_clear (operands[1]);
11194 emit_label (label);
11195 LABEL_NUSES (label) = 1;
11200 (define_expand "ashlsi3"
11201 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11202 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11203 (match_operand:QI 2 "nonmemory_operand" "")))
11204 (clobber (reg:CC FLAGS_REG))]
11206 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11208 (define_insn "*ashlsi3_1"
11209 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11210 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11211 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11212 (clobber (reg:CC FLAGS_REG))]
11213 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11215 switch (get_attr_type (insn))
11218 gcc_assert (operands[2] == const1_rtx);
11219 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11220 return "add{l}\t%0, %0";
11226 if (REG_P (operands[2]))
11227 return "sal{l}\t{%b2, %0|%0, %b2}";
11228 else if (operands[2] == const1_rtx
11229 && (TARGET_SHIFT1 || optimize_size))
11230 return "sal{l}\t%0";
11232 return "sal{l}\t{%2, %0|%0, %2}";
11235 [(set (attr "type")
11236 (cond [(eq_attr "alternative" "1")
11237 (const_string "lea")
11238 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11240 (match_operand 0 "register_operand" ""))
11241 (match_operand 2 "const1_operand" ""))
11242 (const_string "alu")
11244 (const_string "ishift")))
11245 (set_attr "mode" "SI")])
11247 ;; Convert lea to the lea pattern to avoid flags dependency.
11249 [(set (match_operand 0 "register_operand" "")
11250 (ashift (match_operand 1 "index_register_operand" "")
11251 (match_operand:QI 2 "const_int_operand" "")))
11252 (clobber (reg:CC FLAGS_REG))]
11254 && true_regnum (operands[0]) != true_regnum (operands[1])
11255 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11259 enum machine_mode mode = GET_MODE (operands[0]);
11261 if (GET_MODE_SIZE (mode) < 4)
11262 operands[0] = gen_lowpart (SImode, operands[0]);
11264 operands[1] = gen_lowpart (Pmode, operands[1]);
11265 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11267 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11268 if (Pmode != SImode)
11269 pat = gen_rtx_SUBREG (SImode, pat, 0);
11270 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11274 ;; Rare case of shifting RSP is handled by generating move and shift
11276 [(set (match_operand 0 "register_operand" "")
11277 (ashift (match_operand 1 "register_operand" "")
11278 (match_operand:QI 2 "const_int_operand" "")))
11279 (clobber (reg:CC FLAGS_REG))]
11281 && true_regnum (operands[0]) != true_regnum (operands[1])"
11285 emit_move_insn (operands[0], operands[1]);
11286 pat = gen_rtx_SET (VOIDmode, operands[0],
11287 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11288 operands[0], operands[2]));
11289 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11290 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11294 (define_insn "*ashlsi3_1_zext"
11295 [(set (match_operand:DI 0 "register_operand" "=r,r")
11296 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11297 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11298 (clobber (reg:CC FLAGS_REG))]
11299 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11301 switch (get_attr_type (insn))
11304 gcc_assert (operands[2] == const1_rtx);
11305 return "add{l}\t%k0, %k0";
11311 if (REG_P (operands[2]))
11312 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11313 else if (operands[2] == const1_rtx
11314 && (TARGET_SHIFT1 || optimize_size))
11315 return "sal{l}\t%k0";
11317 return "sal{l}\t{%2, %k0|%k0, %2}";
11320 [(set (attr "type")
11321 (cond [(eq_attr "alternative" "1")
11322 (const_string "lea")
11323 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11325 (match_operand 2 "const1_operand" ""))
11326 (const_string "alu")
11328 (const_string "ishift")))
11329 (set_attr "mode" "SI")])
11331 ;; Convert lea to the lea pattern to avoid flags dependency.
11333 [(set (match_operand:DI 0 "register_operand" "")
11334 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11335 (match_operand:QI 2 "const_int_operand" ""))))
11336 (clobber (reg:CC FLAGS_REG))]
11337 "TARGET_64BIT && reload_completed
11338 && true_regnum (operands[0]) != true_regnum (operands[1])"
11339 [(set (match_dup 0) (zero_extend:DI
11340 (subreg:SI (mult:SI (match_dup 1)
11341 (match_dup 2)) 0)))]
11343 operands[1] = gen_lowpart (Pmode, operands[1]);
11344 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11347 ;; This pattern can't accept a variable shift count, since shifts by
11348 ;; zero don't affect the flags. We assume that shifts by constant
11349 ;; zero are optimized away.
11350 (define_insn "*ashlsi3_cmp"
11351 [(set (reg FLAGS_REG)
11353 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11354 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11356 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11357 (ashift:SI (match_dup 1) (match_dup 2)))]
11359 || !TARGET_PARTIAL_FLAG_REG_STALL
11360 || (operands[2] == const1_rtx
11362 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11363 && ix86_match_ccmode (insn, CCGOCmode)
11364 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11366 switch (get_attr_type (insn))
11369 gcc_assert (operands[2] == const1_rtx);
11370 return "add{l}\t%0, %0";
11373 if (REG_P (operands[2]))
11374 return "sal{l}\t{%b2, %0|%0, %b2}";
11375 else if (operands[2] == const1_rtx
11376 && (TARGET_SHIFT1 || optimize_size))
11377 return "sal{l}\t%0";
11379 return "sal{l}\t{%2, %0|%0, %2}";
11382 [(set (attr "type")
11383 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11385 (match_operand 0 "register_operand" ""))
11386 (match_operand 2 "const1_operand" ""))
11387 (const_string "alu")
11389 (const_string "ishift")))
11390 (set_attr "mode" "SI")])
11392 (define_insn "*ashlsi3_cconly"
11393 [(set (reg FLAGS_REG)
11395 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11396 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11398 (clobber (match_scratch:SI 0 "=r"))]
11400 || !TARGET_PARTIAL_FLAG_REG_STALL
11401 || (operands[2] == const1_rtx
11403 || TARGET_DOUBLE_WITH_ADD)))
11404 && ix86_match_ccmode (insn, CCGOCmode)
11405 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11407 switch (get_attr_type (insn))
11410 gcc_assert (operands[2] == const1_rtx);
11411 return "add{l}\t%0, %0";
11414 if (REG_P (operands[2]))
11415 return "sal{l}\t{%b2, %0|%0, %b2}";
11416 else if (operands[2] == const1_rtx
11417 && (TARGET_SHIFT1 || optimize_size))
11418 return "sal{l}\t%0";
11420 return "sal{l}\t{%2, %0|%0, %2}";
11423 [(set (attr "type")
11424 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11426 (match_operand 0 "register_operand" ""))
11427 (match_operand 2 "const1_operand" ""))
11428 (const_string "alu")
11430 (const_string "ishift")))
11431 (set_attr "mode" "SI")])
11433 (define_insn "*ashlsi3_cmp_zext"
11434 [(set (reg FLAGS_REG)
11436 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11437 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11439 (set (match_operand:DI 0 "register_operand" "=r")
11440 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11443 || !TARGET_PARTIAL_FLAG_REG_STALL
11444 || (operands[2] == const1_rtx
11446 || TARGET_DOUBLE_WITH_ADD)))
11447 && ix86_match_ccmode (insn, CCGOCmode)
11448 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11450 switch (get_attr_type (insn))
11453 gcc_assert (operands[2] == const1_rtx);
11454 return "add{l}\t%k0, %k0";
11457 if (REG_P (operands[2]))
11458 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11459 else if (operands[2] == const1_rtx
11460 && (TARGET_SHIFT1 || optimize_size))
11461 return "sal{l}\t%k0";
11463 return "sal{l}\t{%2, %k0|%k0, %2}";
11466 [(set (attr "type")
11467 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11469 (match_operand 2 "const1_operand" ""))
11470 (const_string "alu")
11472 (const_string "ishift")))
11473 (set_attr "mode" "SI")])
11475 (define_expand "ashlhi3"
11476 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11477 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11478 (match_operand:QI 2 "nonmemory_operand" "")))
11479 (clobber (reg:CC FLAGS_REG))]
11480 "TARGET_HIMODE_MATH"
11481 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11483 (define_insn "*ashlhi3_1_lea"
11484 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11485 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11486 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11487 (clobber (reg:CC FLAGS_REG))]
11488 "!TARGET_PARTIAL_REG_STALL
11489 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11491 switch (get_attr_type (insn))
11496 gcc_assert (operands[2] == const1_rtx);
11497 return "add{w}\t%0, %0";
11500 if (REG_P (operands[2]))
11501 return "sal{w}\t{%b2, %0|%0, %b2}";
11502 else if (operands[2] == const1_rtx
11503 && (TARGET_SHIFT1 || optimize_size))
11504 return "sal{w}\t%0";
11506 return "sal{w}\t{%2, %0|%0, %2}";
11509 [(set (attr "type")
11510 (cond [(eq_attr "alternative" "1")
11511 (const_string "lea")
11512 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11514 (match_operand 0 "register_operand" ""))
11515 (match_operand 2 "const1_operand" ""))
11516 (const_string "alu")
11518 (const_string "ishift")))
11519 (set_attr "mode" "HI,SI")])
11521 (define_insn "*ashlhi3_1"
11522 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11523 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11524 (match_operand:QI 2 "nonmemory_operand" "cI")))
11525 (clobber (reg:CC FLAGS_REG))]
11526 "TARGET_PARTIAL_REG_STALL
11527 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11529 switch (get_attr_type (insn))
11532 gcc_assert (operands[2] == const1_rtx);
11533 return "add{w}\t%0, %0";
11536 if (REG_P (operands[2]))
11537 return "sal{w}\t{%b2, %0|%0, %b2}";
11538 else if (operands[2] == const1_rtx
11539 && (TARGET_SHIFT1 || optimize_size))
11540 return "sal{w}\t%0";
11542 return "sal{w}\t{%2, %0|%0, %2}";
11545 [(set (attr "type")
11546 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11548 (match_operand 0 "register_operand" ""))
11549 (match_operand 2 "const1_operand" ""))
11550 (const_string "alu")
11552 (const_string "ishift")))
11553 (set_attr "mode" "HI")])
11555 ;; This pattern can't accept a variable shift count, since shifts by
11556 ;; zero don't affect the flags. We assume that shifts by constant
11557 ;; zero are optimized away.
11558 (define_insn "*ashlhi3_cmp"
11559 [(set (reg FLAGS_REG)
11561 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11562 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11564 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11565 (ashift:HI (match_dup 1) (match_dup 2)))]
11567 || !TARGET_PARTIAL_FLAG_REG_STALL
11568 || (operands[2] == const1_rtx
11570 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11571 && ix86_match_ccmode (insn, CCGOCmode)
11572 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11574 switch (get_attr_type (insn))
11577 gcc_assert (operands[2] == const1_rtx);
11578 return "add{w}\t%0, %0";
11581 if (REG_P (operands[2]))
11582 return "sal{w}\t{%b2, %0|%0, %b2}";
11583 else if (operands[2] == const1_rtx
11584 && (TARGET_SHIFT1 || optimize_size))
11585 return "sal{w}\t%0";
11587 return "sal{w}\t{%2, %0|%0, %2}";
11590 [(set (attr "type")
11591 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11593 (match_operand 0 "register_operand" ""))
11594 (match_operand 2 "const1_operand" ""))
11595 (const_string "alu")
11597 (const_string "ishift")))
11598 (set_attr "mode" "HI")])
11600 (define_insn "*ashlhi3_cconly"
11601 [(set (reg FLAGS_REG)
11603 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11604 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11606 (clobber (match_scratch:HI 0 "=r"))]
11608 || !TARGET_PARTIAL_FLAG_REG_STALL
11609 || (operands[2] == const1_rtx
11611 || TARGET_DOUBLE_WITH_ADD)))
11612 && ix86_match_ccmode (insn, CCGOCmode)
11613 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11615 switch (get_attr_type (insn))
11618 gcc_assert (operands[2] == const1_rtx);
11619 return "add{w}\t%0, %0";
11622 if (REG_P (operands[2]))
11623 return "sal{w}\t{%b2, %0|%0, %b2}";
11624 else if (operands[2] == const1_rtx
11625 && (TARGET_SHIFT1 || optimize_size))
11626 return "sal{w}\t%0";
11628 return "sal{w}\t{%2, %0|%0, %2}";
11631 [(set (attr "type")
11632 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11634 (match_operand 0 "register_operand" ""))
11635 (match_operand 2 "const1_operand" ""))
11636 (const_string "alu")
11638 (const_string "ishift")))
11639 (set_attr "mode" "HI")])
11641 (define_expand "ashlqi3"
11642 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11643 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11644 (match_operand:QI 2 "nonmemory_operand" "")))
11645 (clobber (reg:CC FLAGS_REG))]
11646 "TARGET_QIMODE_MATH"
11647 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11649 ;; %%% Potential partial reg stall on alternative 2. What to do?
11651 (define_insn "*ashlqi3_1_lea"
11652 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11653 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11654 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11655 (clobber (reg:CC FLAGS_REG))]
11656 "!TARGET_PARTIAL_REG_STALL
11657 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11659 switch (get_attr_type (insn))
11664 gcc_assert (operands[2] == const1_rtx);
11665 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11666 return "add{l}\t%k0, %k0";
11668 return "add{b}\t%0, %0";
11671 if (REG_P (operands[2]))
11673 if (get_attr_mode (insn) == MODE_SI)
11674 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11676 return "sal{b}\t{%b2, %0|%0, %b2}";
11678 else if (operands[2] == const1_rtx
11679 && (TARGET_SHIFT1 || optimize_size))
11681 if (get_attr_mode (insn) == MODE_SI)
11682 return "sal{l}\t%0";
11684 return "sal{b}\t%0";
11688 if (get_attr_mode (insn) == MODE_SI)
11689 return "sal{l}\t{%2, %k0|%k0, %2}";
11691 return "sal{b}\t{%2, %0|%0, %2}";
11695 [(set (attr "type")
11696 (cond [(eq_attr "alternative" "2")
11697 (const_string "lea")
11698 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11700 (match_operand 0 "register_operand" ""))
11701 (match_operand 2 "const1_operand" ""))
11702 (const_string "alu")
11704 (const_string "ishift")))
11705 (set_attr "mode" "QI,SI,SI")])
11707 (define_insn "*ashlqi3_1"
11708 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11709 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11710 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11711 (clobber (reg:CC FLAGS_REG))]
11712 "TARGET_PARTIAL_REG_STALL
11713 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11715 switch (get_attr_type (insn))
11718 gcc_assert (operands[2] == const1_rtx);
11719 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11720 return "add{l}\t%k0, %k0";
11722 return "add{b}\t%0, %0";
11725 if (REG_P (operands[2]))
11727 if (get_attr_mode (insn) == MODE_SI)
11728 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11730 return "sal{b}\t{%b2, %0|%0, %b2}";
11732 else if (operands[2] == const1_rtx
11733 && (TARGET_SHIFT1 || optimize_size))
11735 if (get_attr_mode (insn) == MODE_SI)
11736 return "sal{l}\t%0";
11738 return "sal{b}\t%0";
11742 if (get_attr_mode (insn) == MODE_SI)
11743 return "sal{l}\t{%2, %k0|%k0, %2}";
11745 return "sal{b}\t{%2, %0|%0, %2}";
11749 [(set (attr "type")
11750 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11752 (match_operand 0 "register_operand" ""))
11753 (match_operand 2 "const1_operand" ""))
11754 (const_string "alu")
11756 (const_string "ishift")))
11757 (set_attr "mode" "QI,SI")])
11759 ;; This pattern can't accept a variable shift count, since shifts by
11760 ;; zero don't affect the flags. We assume that shifts by constant
11761 ;; zero are optimized away.
11762 (define_insn "*ashlqi3_cmp"
11763 [(set (reg FLAGS_REG)
11765 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11766 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11768 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11769 (ashift:QI (match_dup 1) (match_dup 2)))]
11771 || !TARGET_PARTIAL_FLAG_REG_STALL
11772 || (operands[2] == const1_rtx
11774 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11775 && ix86_match_ccmode (insn, CCGOCmode)
11776 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11778 switch (get_attr_type (insn))
11781 gcc_assert (operands[2] == const1_rtx);
11782 return "add{b}\t%0, %0";
11785 if (REG_P (operands[2]))
11786 return "sal{b}\t{%b2, %0|%0, %b2}";
11787 else if (operands[2] == const1_rtx
11788 && (TARGET_SHIFT1 || optimize_size))
11789 return "sal{b}\t%0";
11791 return "sal{b}\t{%2, %0|%0, %2}";
11794 [(set (attr "type")
11795 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11797 (match_operand 0 "register_operand" ""))
11798 (match_operand 2 "const1_operand" ""))
11799 (const_string "alu")
11801 (const_string "ishift")))
11802 (set_attr "mode" "QI")])
11804 (define_insn "*ashlqi3_cconly"
11805 [(set (reg FLAGS_REG)
11807 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11808 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11810 (clobber (match_scratch:QI 0 "=q"))]
11812 || !TARGET_PARTIAL_FLAG_REG_STALL
11813 || (operands[2] == const1_rtx
11815 || TARGET_DOUBLE_WITH_ADD)))
11816 && ix86_match_ccmode (insn, CCGOCmode)
11817 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11819 switch (get_attr_type (insn))
11822 gcc_assert (operands[2] == const1_rtx);
11823 return "add{b}\t%0, %0";
11826 if (REG_P (operands[2]))
11827 return "sal{b}\t{%b2, %0|%0, %b2}";
11828 else if (operands[2] == const1_rtx
11829 && (TARGET_SHIFT1 || optimize_size))
11830 return "sal{b}\t%0";
11832 return "sal{b}\t{%2, %0|%0, %2}";
11835 [(set (attr "type")
11836 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11838 (match_operand 0 "register_operand" ""))
11839 (match_operand 2 "const1_operand" ""))
11840 (const_string "alu")
11842 (const_string "ishift")))
11843 (set_attr "mode" "QI")])
11845 ;; See comment above `ashldi3' about how this works.
11847 (define_expand "ashrti3"
11848 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11849 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11850 (match_operand:QI 2 "nonmemory_operand" "")))
11851 (clobber (reg:CC FLAGS_REG))])]
11854 if (! immediate_operand (operands[2], QImode))
11856 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11859 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11863 (define_insn "ashrti3_1"
11864 [(set (match_operand:TI 0 "register_operand" "=r")
11865 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11866 (match_operand:QI 2 "register_operand" "c")))
11867 (clobber (match_scratch:DI 3 "=&r"))
11868 (clobber (reg:CC FLAGS_REG))]
11871 [(set_attr "type" "multi")])
11873 (define_insn "*ashrti3_2"
11874 [(set (match_operand:TI 0 "register_operand" "=r")
11875 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11876 (match_operand:QI 2 "immediate_operand" "O")))
11877 (clobber (reg:CC FLAGS_REG))]
11880 [(set_attr "type" "multi")])
11883 [(set (match_operand:TI 0 "register_operand" "")
11884 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11885 (match_operand:QI 2 "register_operand" "")))
11886 (clobber (match_scratch:DI 3 ""))
11887 (clobber (reg:CC FLAGS_REG))]
11888 "TARGET_64BIT && reload_completed"
11890 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11893 [(set (match_operand:TI 0 "register_operand" "")
11894 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11895 (match_operand:QI 2 "immediate_operand" "")))
11896 (clobber (reg:CC FLAGS_REG))]
11897 "TARGET_64BIT && reload_completed"
11899 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11901 (define_insn "x86_64_shrd"
11902 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11903 (ior:DI (ashiftrt:DI (match_dup 0)
11904 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11905 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11906 (minus:QI (const_int 64) (match_dup 2)))))
11907 (clobber (reg:CC FLAGS_REG))]
11910 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11911 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11912 [(set_attr "type" "ishift")
11913 (set_attr "prefix_0f" "1")
11914 (set_attr "mode" "DI")
11915 (set_attr "athlon_decode" "vector")
11916 (set_attr "amdfam10_decode" "vector")])
11918 (define_expand "ashrdi3"
11919 [(set (match_operand:DI 0 "shiftdi_operand" "")
11920 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11921 (match_operand:QI 2 "nonmemory_operand" "")))]
11923 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11925 (define_insn "*ashrdi3_63_rex64"
11926 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11927 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11928 (match_operand:DI 2 "const_int_operand" "i,i")))
11929 (clobber (reg:CC FLAGS_REG))]
11930 "TARGET_64BIT && INTVAL (operands[2]) == 63
11931 && (TARGET_USE_CLTD || optimize_size)
11932 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11935 sar{q}\t{%2, %0|%0, %2}"
11936 [(set_attr "type" "imovx,ishift")
11937 (set_attr "prefix_0f" "0,*")
11938 (set_attr "length_immediate" "0,*")
11939 (set_attr "modrm" "0,1")
11940 (set_attr "mode" "DI")])
11942 (define_insn "*ashrdi3_1_one_bit_rex64"
11943 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11944 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11945 (match_operand:QI 2 "const1_operand" "")))
11946 (clobber (reg:CC FLAGS_REG))]
11948 && (TARGET_SHIFT1 || optimize_size)
11949 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11951 [(set_attr "type" "ishift")
11952 (set (attr "length")
11953 (if_then_else (match_operand:DI 0 "register_operand" "")
11955 (const_string "*")))])
11957 (define_insn "*ashrdi3_1_rex64"
11958 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11959 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11960 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11961 (clobber (reg:CC FLAGS_REG))]
11962 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11964 sar{q}\t{%2, %0|%0, %2}
11965 sar{q}\t{%b2, %0|%0, %b2}"
11966 [(set_attr "type" "ishift")
11967 (set_attr "mode" "DI")])
11969 ;; This pattern can't accept a variable shift count, since shifts by
11970 ;; zero don't affect the flags. We assume that shifts by constant
11971 ;; zero are optimized away.
11972 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11973 [(set (reg FLAGS_REG)
11975 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11976 (match_operand:QI 2 "const1_operand" ""))
11978 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11979 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11981 && (TARGET_SHIFT1 || optimize_size)
11982 && ix86_match_ccmode (insn, CCGOCmode)
11983 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11985 [(set_attr "type" "ishift")
11986 (set (attr "length")
11987 (if_then_else (match_operand:DI 0 "register_operand" "")
11989 (const_string "*")))])
11991 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11992 [(set (reg FLAGS_REG)
11994 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11995 (match_operand:QI 2 "const1_operand" ""))
11997 (clobber (match_scratch:DI 0 "=r"))]
11999 && (TARGET_SHIFT1 || optimize_size)
12000 && ix86_match_ccmode (insn, CCGOCmode)
12001 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12003 [(set_attr "type" "ishift")
12004 (set_attr "length" "2")])
12006 ;; This pattern can't accept a variable shift count, since shifts by
12007 ;; zero don't affect the flags. We assume that shifts by constant
12008 ;; zero are optimized away.
12009 (define_insn "*ashrdi3_cmp_rex64"
12010 [(set (reg FLAGS_REG)
12012 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12013 (match_operand:QI 2 "const_int_operand" "n"))
12015 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12016 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12018 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12019 && ix86_match_ccmode (insn, CCGOCmode)
12020 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12021 "sar{q}\t{%2, %0|%0, %2}"
12022 [(set_attr "type" "ishift")
12023 (set_attr "mode" "DI")])
12025 (define_insn "*ashrdi3_cconly_rex64"
12026 [(set (reg FLAGS_REG)
12028 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12029 (match_operand:QI 2 "const_int_operand" "n"))
12031 (clobber (match_scratch:DI 0 "=r"))]
12033 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12034 && ix86_match_ccmode (insn, CCGOCmode)
12035 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12036 "sar{q}\t{%2, %0|%0, %2}"
12037 [(set_attr "type" "ishift")
12038 (set_attr "mode" "DI")])
12040 (define_insn "*ashrdi3_1"
12041 [(set (match_operand:DI 0 "register_operand" "=r")
12042 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12043 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12044 (clobber (reg:CC FLAGS_REG))]
12047 [(set_attr "type" "multi")])
12049 ;; By default we don't ask for a scratch register, because when DImode
12050 ;; values are manipulated, registers are already at a premium. But if
12051 ;; we have one handy, we won't turn it away.
12053 [(match_scratch:SI 3 "r")
12054 (parallel [(set (match_operand:DI 0 "register_operand" "")
12055 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12056 (match_operand:QI 2 "nonmemory_operand" "")))
12057 (clobber (reg:CC FLAGS_REG))])
12059 "!TARGET_64BIT && TARGET_CMOVE"
12061 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12064 [(set (match_operand:DI 0 "register_operand" "")
12065 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12066 (match_operand:QI 2 "nonmemory_operand" "")))
12067 (clobber (reg:CC FLAGS_REG))]
12068 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12069 ? epilogue_completed : reload_completed)"
12071 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12073 (define_insn "x86_shrd_1"
12074 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12075 (ior:SI (ashiftrt:SI (match_dup 0)
12076 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12077 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12078 (minus:QI (const_int 32) (match_dup 2)))))
12079 (clobber (reg:CC FLAGS_REG))]
12082 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12083 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12084 [(set_attr "type" "ishift")
12085 (set_attr "prefix_0f" "1")
12086 (set_attr "pent_pair" "np")
12087 (set_attr "mode" "SI")])
12089 (define_expand "x86_shift_adj_3"
12090 [(use (match_operand:SI 0 "register_operand" ""))
12091 (use (match_operand:SI 1 "register_operand" ""))
12092 (use (match_operand:QI 2 "register_operand" ""))]
12095 rtx label = gen_label_rtx ();
12098 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12100 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12101 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12102 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12103 gen_rtx_LABEL_REF (VOIDmode, label),
12105 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12106 JUMP_LABEL (tmp) = label;
12108 emit_move_insn (operands[0], operands[1]);
12109 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12111 emit_label (label);
12112 LABEL_NUSES (label) = 1;
12117 (define_insn "ashrsi3_31"
12118 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12119 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12120 (match_operand:SI 2 "const_int_operand" "i,i")))
12121 (clobber (reg:CC FLAGS_REG))]
12122 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12123 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12126 sar{l}\t{%2, %0|%0, %2}"
12127 [(set_attr "type" "imovx,ishift")
12128 (set_attr "prefix_0f" "0,*")
12129 (set_attr "length_immediate" "0,*")
12130 (set_attr "modrm" "0,1")
12131 (set_attr "mode" "SI")])
12133 (define_insn "*ashrsi3_31_zext"
12134 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12135 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12136 (match_operand:SI 2 "const_int_operand" "i,i"))))
12137 (clobber (reg:CC FLAGS_REG))]
12138 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12139 && INTVAL (operands[2]) == 31
12140 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12143 sar{l}\t{%2, %k0|%k0, %2}"
12144 [(set_attr "type" "imovx,ishift")
12145 (set_attr "prefix_0f" "0,*")
12146 (set_attr "length_immediate" "0,*")
12147 (set_attr "modrm" "0,1")
12148 (set_attr "mode" "SI")])
12150 (define_expand "ashrsi3"
12151 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12152 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12153 (match_operand:QI 2 "nonmemory_operand" "")))
12154 (clobber (reg:CC FLAGS_REG))]
12156 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12158 (define_insn "*ashrsi3_1_one_bit"
12159 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12160 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12161 (match_operand:QI 2 "const1_operand" "")))
12162 (clobber (reg:CC FLAGS_REG))]
12163 "(TARGET_SHIFT1 || optimize_size)
12164 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12166 [(set_attr "type" "ishift")
12167 (set (attr "length")
12168 (if_then_else (match_operand:SI 0 "register_operand" "")
12170 (const_string "*")))])
12172 (define_insn "*ashrsi3_1_one_bit_zext"
12173 [(set (match_operand:DI 0 "register_operand" "=r")
12174 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12175 (match_operand:QI 2 "const1_operand" ""))))
12176 (clobber (reg:CC FLAGS_REG))]
12178 && (TARGET_SHIFT1 || optimize_size)
12179 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12181 [(set_attr "type" "ishift")
12182 (set_attr "length" "2")])
12184 (define_insn "*ashrsi3_1"
12185 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12186 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12187 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12188 (clobber (reg:CC FLAGS_REG))]
12189 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12191 sar{l}\t{%2, %0|%0, %2}
12192 sar{l}\t{%b2, %0|%0, %b2}"
12193 [(set_attr "type" "ishift")
12194 (set_attr "mode" "SI")])
12196 (define_insn "*ashrsi3_1_zext"
12197 [(set (match_operand:DI 0 "register_operand" "=r,r")
12198 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12199 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12200 (clobber (reg:CC FLAGS_REG))]
12201 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12203 sar{l}\t{%2, %k0|%k0, %2}
12204 sar{l}\t{%b2, %k0|%k0, %b2}"
12205 [(set_attr "type" "ishift")
12206 (set_attr "mode" "SI")])
12208 ;; This pattern can't accept a variable shift count, since shifts by
12209 ;; zero don't affect the flags. We assume that shifts by constant
12210 ;; zero are optimized away.
12211 (define_insn "*ashrsi3_one_bit_cmp"
12212 [(set (reg FLAGS_REG)
12214 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12215 (match_operand:QI 2 "const1_operand" ""))
12217 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12218 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12219 "(TARGET_SHIFT1 || optimize_size)
12220 && ix86_match_ccmode (insn, CCGOCmode)
12221 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12223 [(set_attr "type" "ishift")
12224 (set (attr "length")
12225 (if_then_else (match_operand:SI 0 "register_operand" "")
12227 (const_string "*")))])
12229 (define_insn "*ashrsi3_one_bit_cconly"
12230 [(set (reg FLAGS_REG)
12232 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12233 (match_operand:QI 2 "const1_operand" ""))
12235 (clobber (match_scratch:SI 0 "=r"))]
12236 "(TARGET_SHIFT1 || optimize_size)
12237 && ix86_match_ccmode (insn, CCGOCmode)
12238 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12240 [(set_attr "type" "ishift")
12241 (set_attr "length" "2")])
12243 (define_insn "*ashrsi3_one_bit_cmp_zext"
12244 [(set (reg FLAGS_REG)
12246 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12247 (match_operand:QI 2 "const1_operand" ""))
12249 (set (match_operand:DI 0 "register_operand" "=r")
12250 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12252 && (TARGET_SHIFT1 || optimize_size)
12253 && ix86_match_ccmode (insn, CCmode)
12254 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12256 [(set_attr "type" "ishift")
12257 (set_attr "length" "2")])
12259 ;; This pattern can't accept a variable shift count, since shifts by
12260 ;; zero don't affect the flags. We assume that shifts by constant
12261 ;; zero are optimized away.
12262 (define_insn "*ashrsi3_cmp"
12263 [(set (reg FLAGS_REG)
12265 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12266 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12269 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12270 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12271 && ix86_match_ccmode (insn, CCGOCmode)
12272 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12273 "sar{l}\t{%2, %0|%0, %2}"
12274 [(set_attr "type" "ishift")
12275 (set_attr "mode" "SI")])
12277 (define_insn "*ashrsi3_cconly"
12278 [(set (reg FLAGS_REG)
12280 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12281 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12283 (clobber (match_scratch:SI 0 "=r"))]
12284 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12285 && ix86_match_ccmode (insn, CCGOCmode)
12286 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12287 "sar{l}\t{%2, %0|%0, %2}"
12288 [(set_attr "type" "ishift")
12289 (set_attr "mode" "SI")])
12291 (define_insn "*ashrsi3_cmp_zext"
12292 [(set (reg FLAGS_REG)
12294 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12295 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12297 (set (match_operand:DI 0 "register_operand" "=r")
12298 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12300 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12301 && ix86_match_ccmode (insn, CCGOCmode)
12302 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12303 "sar{l}\t{%2, %k0|%k0, %2}"
12304 [(set_attr "type" "ishift")
12305 (set_attr "mode" "SI")])
12307 (define_expand "ashrhi3"
12308 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12309 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12310 (match_operand:QI 2 "nonmemory_operand" "")))
12311 (clobber (reg:CC FLAGS_REG))]
12312 "TARGET_HIMODE_MATH"
12313 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12315 (define_insn "*ashrhi3_1_one_bit"
12316 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12317 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12318 (match_operand:QI 2 "const1_operand" "")))
12319 (clobber (reg:CC FLAGS_REG))]
12320 "(TARGET_SHIFT1 || optimize_size)
12321 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12323 [(set_attr "type" "ishift")
12324 (set (attr "length")
12325 (if_then_else (match_operand 0 "register_operand" "")
12327 (const_string "*")))])
12329 (define_insn "*ashrhi3_1"
12330 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12331 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12332 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12333 (clobber (reg:CC FLAGS_REG))]
12334 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12336 sar{w}\t{%2, %0|%0, %2}
12337 sar{w}\t{%b2, %0|%0, %b2}"
12338 [(set_attr "type" "ishift")
12339 (set_attr "mode" "HI")])
12341 ;; This pattern can't accept a variable shift count, since shifts by
12342 ;; zero don't affect the flags. We assume that shifts by constant
12343 ;; zero are optimized away.
12344 (define_insn "*ashrhi3_one_bit_cmp"
12345 [(set (reg FLAGS_REG)
12347 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12348 (match_operand:QI 2 "const1_operand" ""))
12350 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12351 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12352 "(TARGET_SHIFT1 || optimize_size)
12353 && ix86_match_ccmode (insn, CCGOCmode)
12354 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12356 [(set_attr "type" "ishift")
12357 (set (attr "length")
12358 (if_then_else (match_operand 0 "register_operand" "")
12360 (const_string "*")))])
12362 (define_insn "*ashrhi3_one_bit_cconly"
12363 [(set (reg FLAGS_REG)
12365 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12366 (match_operand:QI 2 "const1_operand" ""))
12368 (clobber (match_scratch:HI 0 "=r"))]
12369 "(TARGET_SHIFT1 || optimize_size)
12370 && ix86_match_ccmode (insn, CCGOCmode)
12371 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12373 [(set_attr "type" "ishift")
12374 (set_attr "length" "2")])
12376 ;; This pattern can't accept a variable shift count, since shifts by
12377 ;; zero don't affect the flags. We assume that shifts by constant
12378 ;; zero are optimized away.
12379 (define_insn "*ashrhi3_cmp"
12380 [(set (reg FLAGS_REG)
12382 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12383 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12385 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12386 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12387 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12388 && ix86_match_ccmode (insn, CCGOCmode)
12389 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12390 "sar{w}\t{%2, %0|%0, %2}"
12391 [(set_attr "type" "ishift")
12392 (set_attr "mode" "HI")])
12394 (define_insn "*ashrhi3_cconly"
12395 [(set (reg FLAGS_REG)
12397 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12398 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12400 (clobber (match_scratch:HI 0 "=r"))]
12401 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12402 && ix86_match_ccmode (insn, CCGOCmode)
12403 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12404 "sar{w}\t{%2, %0|%0, %2}"
12405 [(set_attr "type" "ishift")
12406 (set_attr "mode" "HI")])
12408 (define_expand "ashrqi3"
12409 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12410 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12411 (match_operand:QI 2 "nonmemory_operand" "")))
12412 (clobber (reg:CC FLAGS_REG))]
12413 "TARGET_QIMODE_MATH"
12414 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12416 (define_insn "*ashrqi3_1_one_bit"
12417 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12418 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12419 (match_operand:QI 2 "const1_operand" "")))
12420 (clobber (reg:CC FLAGS_REG))]
12421 "(TARGET_SHIFT1 || optimize_size)
12422 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12424 [(set_attr "type" "ishift")
12425 (set (attr "length")
12426 (if_then_else (match_operand 0 "register_operand" "")
12428 (const_string "*")))])
12430 (define_insn "*ashrqi3_1_one_bit_slp"
12431 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12432 (ashiftrt:QI (match_dup 0)
12433 (match_operand:QI 1 "const1_operand" "")))
12434 (clobber (reg:CC FLAGS_REG))]
12435 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12436 && (TARGET_SHIFT1 || optimize_size)
12437 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12439 [(set_attr "type" "ishift1")
12440 (set (attr "length")
12441 (if_then_else (match_operand 0 "register_operand" "")
12443 (const_string "*")))])
12445 (define_insn "*ashrqi3_1"
12446 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12447 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12448 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12449 (clobber (reg:CC FLAGS_REG))]
12450 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12452 sar{b}\t{%2, %0|%0, %2}
12453 sar{b}\t{%b2, %0|%0, %b2}"
12454 [(set_attr "type" "ishift")
12455 (set_attr "mode" "QI")])
12457 (define_insn "*ashrqi3_1_slp"
12458 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12459 (ashiftrt:QI (match_dup 0)
12460 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12461 (clobber (reg:CC FLAGS_REG))]
12462 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12463 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12465 sar{b}\t{%1, %0|%0, %1}
12466 sar{b}\t{%b1, %0|%0, %b1}"
12467 [(set_attr "type" "ishift1")
12468 (set_attr "mode" "QI")])
12470 ;; This pattern can't accept a variable shift count, since shifts by
12471 ;; zero don't affect the flags. We assume that shifts by constant
12472 ;; zero are optimized away.
12473 (define_insn "*ashrqi3_one_bit_cmp"
12474 [(set (reg FLAGS_REG)
12476 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12477 (match_operand:QI 2 "const1_operand" "I"))
12479 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12480 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12481 "(TARGET_SHIFT1 || optimize_size)
12482 && ix86_match_ccmode (insn, CCGOCmode)
12483 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12485 [(set_attr "type" "ishift")
12486 (set (attr "length")
12487 (if_then_else (match_operand 0 "register_operand" "")
12489 (const_string "*")))])
12491 (define_insn "*ashrqi3_one_bit_cconly"
12492 [(set (reg FLAGS_REG)
12494 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12495 (match_operand:QI 2 "const1_operand" "I"))
12497 (clobber (match_scratch:QI 0 "=q"))]
12498 "(TARGET_SHIFT1 || optimize_size)
12499 && ix86_match_ccmode (insn, CCGOCmode)
12500 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12502 [(set_attr "type" "ishift")
12503 (set_attr "length" "2")])
12505 ;; This pattern can't accept a variable shift count, since shifts by
12506 ;; zero don't affect the flags. We assume that shifts by constant
12507 ;; zero are optimized away.
12508 (define_insn "*ashrqi3_cmp"
12509 [(set (reg FLAGS_REG)
12511 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12512 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12514 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12515 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12516 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12517 && ix86_match_ccmode (insn, CCGOCmode)
12518 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12519 "sar{b}\t{%2, %0|%0, %2}"
12520 [(set_attr "type" "ishift")
12521 (set_attr "mode" "QI")])
12523 (define_insn "*ashrqi3_cconly"
12524 [(set (reg FLAGS_REG)
12526 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12527 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12529 (clobber (match_scratch:QI 0 "=q"))]
12530 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12531 && ix86_match_ccmode (insn, CCGOCmode)
12532 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12533 "sar{b}\t{%2, %0|%0, %2}"
12534 [(set_attr "type" "ishift")
12535 (set_attr "mode" "QI")])
12538 ;; Logical shift instructions
12540 ;; See comment above `ashldi3' about how this works.
12542 (define_expand "lshrti3"
12543 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12544 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12545 (match_operand:QI 2 "nonmemory_operand" "")))
12546 (clobber (reg:CC FLAGS_REG))])]
12549 if (! immediate_operand (operands[2], QImode))
12551 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12554 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12558 (define_insn "lshrti3_1"
12559 [(set (match_operand:TI 0 "register_operand" "=r")
12560 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12561 (match_operand:QI 2 "register_operand" "c")))
12562 (clobber (match_scratch:DI 3 "=&r"))
12563 (clobber (reg:CC FLAGS_REG))]
12566 [(set_attr "type" "multi")])
12568 ;; This pattern must be defined before *lshrti3_2 to prevent
12569 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12571 (define_insn "sse2_lshrti3"
12572 [(set (match_operand:TI 0 "register_operand" "=x")
12573 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12574 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12577 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12578 return "psrldq\t{%2, %0|%0, %2}";
12580 [(set_attr "type" "sseishft")
12581 (set_attr "prefix_data16" "1")
12582 (set_attr "mode" "TI")])
12584 (define_insn "*lshrti3_2"
12585 [(set (match_operand:TI 0 "register_operand" "=r")
12586 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12587 (match_operand:QI 2 "immediate_operand" "O")))
12588 (clobber (reg:CC FLAGS_REG))]
12591 [(set_attr "type" "multi")])
12594 [(set (match_operand:TI 0 "register_operand" "")
12595 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12596 (match_operand:QI 2 "register_operand" "")))
12597 (clobber (match_scratch:DI 3 ""))
12598 (clobber (reg:CC FLAGS_REG))]
12599 "TARGET_64BIT && reload_completed"
12601 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12604 [(set (match_operand:TI 0 "register_operand" "")
12605 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12606 (match_operand:QI 2 "immediate_operand" "")))
12607 (clobber (reg:CC FLAGS_REG))]
12608 "TARGET_64BIT && reload_completed"
12610 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12612 (define_expand "lshrdi3"
12613 [(set (match_operand:DI 0 "shiftdi_operand" "")
12614 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12615 (match_operand:QI 2 "nonmemory_operand" "")))]
12617 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12619 (define_insn "*lshrdi3_1_one_bit_rex64"
12620 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12621 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12622 (match_operand:QI 2 "const1_operand" "")))
12623 (clobber (reg:CC FLAGS_REG))]
12625 && (TARGET_SHIFT1 || optimize_size)
12626 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12628 [(set_attr "type" "ishift")
12629 (set (attr "length")
12630 (if_then_else (match_operand:DI 0 "register_operand" "")
12632 (const_string "*")))])
12634 (define_insn "*lshrdi3_1_rex64"
12635 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12636 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12637 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12638 (clobber (reg:CC FLAGS_REG))]
12639 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12641 shr{q}\t{%2, %0|%0, %2}
12642 shr{q}\t{%b2, %0|%0, %b2}"
12643 [(set_attr "type" "ishift")
12644 (set_attr "mode" "DI")])
12646 ;; This pattern can't accept a variable shift count, since shifts by
12647 ;; zero don't affect the flags. We assume that shifts by constant
12648 ;; zero are optimized away.
12649 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12650 [(set (reg FLAGS_REG)
12652 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12653 (match_operand:QI 2 "const1_operand" ""))
12655 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12656 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12658 && (TARGET_SHIFT1 || optimize_size)
12659 && ix86_match_ccmode (insn, CCGOCmode)
12660 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12662 [(set_attr "type" "ishift")
12663 (set (attr "length")
12664 (if_then_else (match_operand:DI 0 "register_operand" "")
12666 (const_string "*")))])
12668 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12669 [(set (reg FLAGS_REG)
12671 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12672 (match_operand:QI 2 "const1_operand" ""))
12674 (clobber (match_scratch:DI 0 "=r"))]
12676 && (TARGET_SHIFT1 || optimize_size)
12677 && ix86_match_ccmode (insn, CCGOCmode)
12678 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12680 [(set_attr "type" "ishift")
12681 (set_attr "length" "2")])
12683 ;; This pattern can't accept a variable shift count, since shifts by
12684 ;; zero don't affect the flags. We assume that shifts by constant
12685 ;; zero are optimized away.
12686 (define_insn "*lshrdi3_cmp_rex64"
12687 [(set (reg FLAGS_REG)
12689 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12690 (match_operand:QI 2 "const_int_operand" "e"))
12692 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12693 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12695 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12696 && ix86_match_ccmode (insn, CCGOCmode)
12697 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12698 "shr{q}\t{%2, %0|%0, %2}"
12699 [(set_attr "type" "ishift")
12700 (set_attr "mode" "DI")])
12702 (define_insn "*lshrdi3_cconly_rex64"
12703 [(set (reg FLAGS_REG)
12705 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12706 (match_operand:QI 2 "const_int_operand" "e"))
12708 (clobber (match_scratch:DI 0 "=r"))]
12710 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12711 && ix86_match_ccmode (insn, CCGOCmode)
12712 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12713 "shr{q}\t{%2, %0|%0, %2}"
12714 [(set_attr "type" "ishift")
12715 (set_attr "mode" "DI")])
12717 (define_insn "*lshrdi3_1"
12718 [(set (match_operand:DI 0 "register_operand" "=r")
12719 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12720 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12721 (clobber (reg:CC FLAGS_REG))]
12724 [(set_attr "type" "multi")])
12726 ;; By default we don't ask for a scratch register, because when DImode
12727 ;; values are manipulated, registers are already at a premium. But if
12728 ;; we have one handy, we won't turn it away.
12730 [(match_scratch:SI 3 "r")
12731 (parallel [(set (match_operand:DI 0 "register_operand" "")
12732 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12733 (match_operand:QI 2 "nonmemory_operand" "")))
12734 (clobber (reg:CC FLAGS_REG))])
12736 "!TARGET_64BIT && TARGET_CMOVE"
12738 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12741 [(set (match_operand:DI 0 "register_operand" "")
12742 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12743 (match_operand:QI 2 "nonmemory_operand" "")))
12744 (clobber (reg:CC FLAGS_REG))]
12745 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12746 ? epilogue_completed : reload_completed)"
12748 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12750 (define_expand "lshrsi3"
12751 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12752 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12753 (match_operand:QI 2 "nonmemory_operand" "")))
12754 (clobber (reg:CC FLAGS_REG))]
12756 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12758 (define_insn "*lshrsi3_1_one_bit"
12759 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12760 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12761 (match_operand:QI 2 "const1_operand" "")))
12762 (clobber (reg:CC FLAGS_REG))]
12763 "(TARGET_SHIFT1 || optimize_size)
12764 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12766 [(set_attr "type" "ishift")
12767 (set (attr "length")
12768 (if_then_else (match_operand:SI 0 "register_operand" "")
12770 (const_string "*")))])
12772 (define_insn "*lshrsi3_1_one_bit_zext"
12773 [(set (match_operand:DI 0 "register_operand" "=r")
12774 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12775 (match_operand:QI 2 "const1_operand" "")))
12776 (clobber (reg:CC FLAGS_REG))]
12778 && (TARGET_SHIFT1 || optimize_size)
12779 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12781 [(set_attr "type" "ishift")
12782 (set_attr "length" "2")])
12784 (define_insn "*lshrsi3_1"
12785 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12786 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12787 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12788 (clobber (reg:CC FLAGS_REG))]
12789 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12791 shr{l}\t{%2, %0|%0, %2}
12792 shr{l}\t{%b2, %0|%0, %b2}"
12793 [(set_attr "type" "ishift")
12794 (set_attr "mode" "SI")])
12796 (define_insn "*lshrsi3_1_zext"
12797 [(set (match_operand:DI 0 "register_operand" "=r,r")
12799 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12800 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12801 (clobber (reg:CC FLAGS_REG))]
12802 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12804 shr{l}\t{%2, %k0|%k0, %2}
12805 shr{l}\t{%b2, %k0|%k0, %b2}"
12806 [(set_attr "type" "ishift")
12807 (set_attr "mode" "SI")])
12809 ;; This pattern can't accept a variable shift count, since shifts by
12810 ;; zero don't affect the flags. We assume that shifts by constant
12811 ;; zero are optimized away.
12812 (define_insn "*lshrsi3_one_bit_cmp"
12813 [(set (reg FLAGS_REG)
12815 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12816 (match_operand:QI 2 "const1_operand" ""))
12818 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12819 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12820 "(TARGET_SHIFT1 || optimize_size)
12821 && ix86_match_ccmode (insn, CCGOCmode)
12822 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12824 [(set_attr "type" "ishift")
12825 (set (attr "length")
12826 (if_then_else (match_operand:SI 0 "register_operand" "")
12828 (const_string "*")))])
12830 (define_insn "*lshrsi3_one_bit_cconly"
12831 [(set (reg FLAGS_REG)
12833 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12834 (match_operand:QI 2 "const1_operand" ""))
12836 (clobber (match_scratch:SI 0 "=r"))]
12837 "(TARGET_SHIFT1 || optimize_size)
12838 && ix86_match_ccmode (insn, CCGOCmode)
12839 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12841 [(set_attr "type" "ishift")
12842 (set_attr "length" "2")])
12844 (define_insn "*lshrsi3_cmp_one_bit_zext"
12845 [(set (reg FLAGS_REG)
12847 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12848 (match_operand:QI 2 "const1_operand" ""))
12850 (set (match_operand:DI 0 "register_operand" "=r")
12851 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12853 && (TARGET_SHIFT1 || optimize_size)
12854 && ix86_match_ccmode (insn, CCGOCmode)
12855 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12857 [(set_attr "type" "ishift")
12858 (set_attr "length" "2")])
12860 ;; This pattern can't accept a variable shift count, since shifts by
12861 ;; zero don't affect the flags. We assume that shifts by constant
12862 ;; zero are optimized away.
12863 (define_insn "*lshrsi3_cmp"
12864 [(set (reg FLAGS_REG)
12866 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12867 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12869 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12870 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12871 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12872 && ix86_match_ccmode (insn, CCGOCmode)
12873 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12874 "shr{l}\t{%2, %0|%0, %2}"
12875 [(set_attr "type" "ishift")
12876 (set_attr "mode" "SI")])
12878 (define_insn "*lshrsi3_cconly"
12879 [(set (reg FLAGS_REG)
12881 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12882 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12884 (clobber (match_scratch:SI 0 "=r"))]
12885 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12886 && ix86_match_ccmode (insn, CCGOCmode)
12887 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12888 "shr{l}\t{%2, %0|%0, %2}"
12889 [(set_attr "type" "ishift")
12890 (set_attr "mode" "SI")])
12892 (define_insn "*lshrsi3_cmp_zext"
12893 [(set (reg FLAGS_REG)
12895 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12896 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12898 (set (match_operand:DI 0 "register_operand" "=r")
12899 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12901 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12902 && ix86_match_ccmode (insn, CCGOCmode)
12903 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12904 "shr{l}\t{%2, %k0|%k0, %2}"
12905 [(set_attr "type" "ishift")
12906 (set_attr "mode" "SI")])
12908 (define_expand "lshrhi3"
12909 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12910 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12911 (match_operand:QI 2 "nonmemory_operand" "")))
12912 (clobber (reg:CC FLAGS_REG))]
12913 "TARGET_HIMODE_MATH"
12914 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12916 (define_insn "*lshrhi3_1_one_bit"
12917 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12918 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12919 (match_operand:QI 2 "const1_operand" "")))
12920 (clobber (reg:CC FLAGS_REG))]
12921 "(TARGET_SHIFT1 || optimize_size)
12922 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12924 [(set_attr "type" "ishift")
12925 (set (attr "length")
12926 (if_then_else (match_operand 0 "register_operand" "")
12928 (const_string "*")))])
12930 (define_insn "*lshrhi3_1"
12931 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12932 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12933 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12934 (clobber (reg:CC FLAGS_REG))]
12935 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12937 shr{w}\t{%2, %0|%0, %2}
12938 shr{w}\t{%b2, %0|%0, %b2}"
12939 [(set_attr "type" "ishift")
12940 (set_attr "mode" "HI")])
12942 ;; This pattern can't accept a variable shift count, since shifts by
12943 ;; zero don't affect the flags. We assume that shifts by constant
12944 ;; zero are optimized away.
12945 (define_insn "*lshrhi3_one_bit_cmp"
12946 [(set (reg FLAGS_REG)
12948 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12949 (match_operand:QI 2 "const1_operand" ""))
12951 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12952 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12953 "(TARGET_SHIFT1 || optimize_size)
12954 && ix86_match_ccmode (insn, CCGOCmode)
12955 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12957 [(set_attr "type" "ishift")
12958 (set (attr "length")
12959 (if_then_else (match_operand:SI 0 "register_operand" "")
12961 (const_string "*")))])
12963 (define_insn "*lshrhi3_one_bit_cconly"
12964 [(set (reg FLAGS_REG)
12966 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12967 (match_operand:QI 2 "const1_operand" ""))
12969 (clobber (match_scratch:HI 0 "=r"))]
12970 "(TARGET_SHIFT1 || optimize_size)
12971 && ix86_match_ccmode (insn, CCGOCmode)
12972 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12974 [(set_attr "type" "ishift")
12975 (set_attr "length" "2")])
12977 ;; This pattern can't accept a variable shift count, since shifts by
12978 ;; zero don't affect the flags. We assume that shifts by constant
12979 ;; zero are optimized away.
12980 (define_insn "*lshrhi3_cmp"
12981 [(set (reg FLAGS_REG)
12983 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12984 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12986 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12987 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12988 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12989 && ix86_match_ccmode (insn, CCGOCmode)
12990 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12991 "shr{w}\t{%2, %0|%0, %2}"
12992 [(set_attr "type" "ishift")
12993 (set_attr "mode" "HI")])
12995 (define_insn "*lshrhi3_cconly"
12996 [(set (reg FLAGS_REG)
12998 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12999 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13001 (clobber (match_scratch:HI 0 "=r"))]
13002 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13003 && ix86_match_ccmode (insn, CCGOCmode)
13004 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13005 "shr{w}\t{%2, %0|%0, %2}"
13006 [(set_attr "type" "ishift")
13007 (set_attr "mode" "HI")])
13009 (define_expand "lshrqi3"
13010 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13011 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13012 (match_operand:QI 2 "nonmemory_operand" "")))
13013 (clobber (reg:CC FLAGS_REG))]
13014 "TARGET_QIMODE_MATH"
13015 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13017 (define_insn "*lshrqi3_1_one_bit"
13018 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13019 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13020 (match_operand:QI 2 "const1_operand" "")))
13021 (clobber (reg:CC FLAGS_REG))]
13022 "(TARGET_SHIFT1 || optimize_size)
13023 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13025 [(set_attr "type" "ishift")
13026 (set (attr "length")
13027 (if_then_else (match_operand 0 "register_operand" "")
13029 (const_string "*")))])
13031 (define_insn "*lshrqi3_1_one_bit_slp"
13032 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13033 (lshiftrt:QI (match_dup 0)
13034 (match_operand:QI 1 "const1_operand" "")))
13035 (clobber (reg:CC FLAGS_REG))]
13036 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13037 && (TARGET_SHIFT1 || optimize_size)"
13039 [(set_attr "type" "ishift1")
13040 (set (attr "length")
13041 (if_then_else (match_operand 0 "register_operand" "")
13043 (const_string "*")))])
13045 (define_insn "*lshrqi3_1"
13046 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13047 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13048 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13049 (clobber (reg:CC FLAGS_REG))]
13050 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13052 shr{b}\t{%2, %0|%0, %2}
13053 shr{b}\t{%b2, %0|%0, %b2}"
13054 [(set_attr "type" "ishift")
13055 (set_attr "mode" "QI")])
13057 (define_insn "*lshrqi3_1_slp"
13058 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13059 (lshiftrt:QI (match_dup 0)
13060 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13061 (clobber (reg:CC FLAGS_REG))]
13062 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13063 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13065 shr{b}\t{%1, %0|%0, %1}
13066 shr{b}\t{%b1, %0|%0, %b1}"
13067 [(set_attr "type" "ishift1")
13068 (set_attr "mode" "QI")])
13070 ;; This pattern can't accept a variable shift count, since shifts by
13071 ;; zero don't affect the flags. We assume that shifts by constant
13072 ;; zero are optimized away.
13073 (define_insn "*lshrqi2_one_bit_cmp"
13074 [(set (reg FLAGS_REG)
13076 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13077 (match_operand:QI 2 "const1_operand" ""))
13079 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13080 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13081 "(TARGET_SHIFT1 || optimize_size)
13082 && ix86_match_ccmode (insn, CCGOCmode)
13083 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13085 [(set_attr "type" "ishift")
13086 (set (attr "length")
13087 (if_then_else (match_operand:SI 0 "register_operand" "")
13089 (const_string "*")))])
13091 (define_insn "*lshrqi2_one_bit_cconly"
13092 [(set (reg FLAGS_REG)
13094 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13095 (match_operand:QI 2 "const1_operand" ""))
13097 (clobber (match_scratch:QI 0 "=q"))]
13098 "(TARGET_SHIFT1 || optimize_size)
13099 && ix86_match_ccmode (insn, CCGOCmode)
13100 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13102 [(set_attr "type" "ishift")
13103 (set_attr "length" "2")])
13105 ;; This pattern can't accept a variable shift count, since shifts by
13106 ;; zero don't affect the flags. We assume that shifts by constant
13107 ;; zero are optimized away.
13108 (define_insn "*lshrqi2_cmp"
13109 [(set (reg FLAGS_REG)
13111 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13112 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13114 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13115 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13116 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13117 && ix86_match_ccmode (insn, CCGOCmode)
13118 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13119 "shr{b}\t{%2, %0|%0, %2}"
13120 [(set_attr "type" "ishift")
13121 (set_attr "mode" "QI")])
13123 (define_insn "*lshrqi2_cconly"
13124 [(set (reg FLAGS_REG)
13126 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13127 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13129 (clobber (match_scratch:QI 0 "=q"))]
13130 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13131 && ix86_match_ccmode (insn, CCGOCmode)
13132 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13133 "shr{b}\t{%2, %0|%0, %2}"
13134 [(set_attr "type" "ishift")
13135 (set_attr "mode" "QI")])
13137 ;; Rotate instructions
13139 (define_expand "rotldi3"
13140 [(set (match_operand:DI 0 "shiftdi_operand" "")
13141 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13142 (match_operand:QI 2 "nonmemory_operand" "")))
13143 (clobber (reg:CC FLAGS_REG))]
13148 ix86_expand_binary_operator (ROTATE, DImode, operands);
13151 if (!const_1_to_31_operand (operands[2], VOIDmode))
13153 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13157 ;; Implement rotation using two double-precision shift instructions
13158 ;; and a scratch register.
13159 (define_insn_and_split "ix86_rotldi3"
13160 [(set (match_operand:DI 0 "register_operand" "=r")
13161 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13162 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13163 (clobber (reg:CC FLAGS_REG))
13164 (clobber (match_scratch:SI 3 "=&r"))]
13167 "&& reload_completed"
13168 [(set (match_dup 3) (match_dup 4))
13170 [(set (match_dup 4)
13171 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13172 (lshiftrt:SI (match_dup 5)
13173 (minus:QI (const_int 32) (match_dup 2)))))
13174 (clobber (reg:CC FLAGS_REG))])
13176 [(set (match_dup 5)
13177 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13178 (lshiftrt:SI (match_dup 3)
13179 (minus:QI (const_int 32) (match_dup 2)))))
13180 (clobber (reg:CC FLAGS_REG))])]
13181 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13183 (define_insn "*rotlsi3_1_one_bit_rex64"
13184 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13185 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13186 (match_operand:QI 2 "const1_operand" "")))
13187 (clobber (reg:CC FLAGS_REG))]
13189 && (TARGET_SHIFT1 || optimize_size)
13190 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13192 [(set_attr "type" "rotate")
13193 (set (attr "length")
13194 (if_then_else (match_operand:DI 0 "register_operand" "")
13196 (const_string "*")))])
13198 (define_insn "*rotldi3_1_rex64"
13199 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13200 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13201 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13202 (clobber (reg:CC FLAGS_REG))]
13203 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13205 rol{q}\t{%2, %0|%0, %2}
13206 rol{q}\t{%b2, %0|%0, %b2}"
13207 [(set_attr "type" "rotate")
13208 (set_attr "mode" "DI")])
13210 (define_expand "rotlsi3"
13211 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13212 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13213 (match_operand:QI 2 "nonmemory_operand" "")))
13214 (clobber (reg:CC FLAGS_REG))]
13216 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13218 (define_insn "*rotlsi3_1_one_bit"
13219 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13220 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13221 (match_operand:QI 2 "const1_operand" "")))
13222 (clobber (reg:CC FLAGS_REG))]
13223 "(TARGET_SHIFT1 || optimize_size)
13224 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13226 [(set_attr "type" "rotate")
13227 (set (attr "length")
13228 (if_then_else (match_operand:SI 0 "register_operand" "")
13230 (const_string "*")))])
13232 (define_insn "*rotlsi3_1_one_bit_zext"
13233 [(set (match_operand:DI 0 "register_operand" "=r")
13235 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13236 (match_operand:QI 2 "const1_operand" ""))))
13237 (clobber (reg:CC FLAGS_REG))]
13239 && (TARGET_SHIFT1 || optimize_size)
13240 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13242 [(set_attr "type" "rotate")
13243 (set_attr "length" "2")])
13245 (define_insn "*rotlsi3_1"
13246 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13247 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13248 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13249 (clobber (reg:CC FLAGS_REG))]
13250 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13252 rol{l}\t{%2, %0|%0, %2}
13253 rol{l}\t{%b2, %0|%0, %b2}"
13254 [(set_attr "type" "rotate")
13255 (set_attr "mode" "SI")])
13257 (define_insn "*rotlsi3_1_zext"
13258 [(set (match_operand:DI 0 "register_operand" "=r,r")
13260 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13261 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13262 (clobber (reg:CC FLAGS_REG))]
13263 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13265 rol{l}\t{%2, %k0|%k0, %2}
13266 rol{l}\t{%b2, %k0|%k0, %b2}"
13267 [(set_attr "type" "rotate")
13268 (set_attr "mode" "SI")])
13270 (define_expand "rotlhi3"
13271 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13272 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13273 (match_operand:QI 2 "nonmemory_operand" "")))
13274 (clobber (reg:CC FLAGS_REG))]
13275 "TARGET_HIMODE_MATH"
13276 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13278 (define_insn "*rotlhi3_1_one_bit"
13279 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13280 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13281 (match_operand:QI 2 "const1_operand" "")))
13282 (clobber (reg:CC FLAGS_REG))]
13283 "(TARGET_SHIFT1 || optimize_size)
13284 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13286 [(set_attr "type" "rotate")
13287 (set (attr "length")
13288 (if_then_else (match_operand 0 "register_operand" "")
13290 (const_string "*")))])
13292 (define_insn "*rotlhi3_1"
13293 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13294 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13295 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13296 (clobber (reg:CC FLAGS_REG))]
13297 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13299 rol{w}\t{%2, %0|%0, %2}
13300 rol{w}\t{%b2, %0|%0, %b2}"
13301 [(set_attr "type" "rotate")
13302 (set_attr "mode" "HI")])
13305 [(set (match_operand:HI 0 "register_operand" "")
13306 (rotate:HI (match_dup 0) (const_int 8)))
13307 (clobber (reg:CC FLAGS_REG))]
13309 [(parallel [(set (strict_low_part (match_dup 0))
13310 (bswap:HI (match_dup 0)))
13311 (clobber (reg:CC FLAGS_REG))])]
13314 (define_expand "rotlqi3"
13315 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13316 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13317 (match_operand:QI 2 "nonmemory_operand" "")))
13318 (clobber (reg:CC FLAGS_REG))]
13319 "TARGET_QIMODE_MATH"
13320 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13322 (define_insn "*rotlqi3_1_one_bit_slp"
13323 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13324 (rotate:QI (match_dup 0)
13325 (match_operand:QI 1 "const1_operand" "")))
13326 (clobber (reg:CC FLAGS_REG))]
13327 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13328 && (TARGET_SHIFT1 || optimize_size)"
13330 [(set_attr "type" "rotate1")
13331 (set (attr "length")
13332 (if_then_else (match_operand 0 "register_operand" "")
13334 (const_string "*")))])
13336 (define_insn "*rotlqi3_1_one_bit"
13337 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13338 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13339 (match_operand:QI 2 "const1_operand" "")))
13340 (clobber (reg:CC FLAGS_REG))]
13341 "(TARGET_SHIFT1 || optimize_size)
13342 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13344 [(set_attr "type" "rotate")
13345 (set (attr "length")
13346 (if_then_else (match_operand 0 "register_operand" "")
13348 (const_string "*")))])
13350 (define_insn "*rotlqi3_1_slp"
13351 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13352 (rotate:QI (match_dup 0)
13353 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13354 (clobber (reg:CC FLAGS_REG))]
13355 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13356 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13358 rol{b}\t{%1, %0|%0, %1}
13359 rol{b}\t{%b1, %0|%0, %b1}"
13360 [(set_attr "type" "rotate1")
13361 (set_attr "mode" "QI")])
13363 (define_insn "*rotlqi3_1"
13364 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13365 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13366 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13367 (clobber (reg:CC FLAGS_REG))]
13368 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13370 rol{b}\t{%2, %0|%0, %2}
13371 rol{b}\t{%b2, %0|%0, %b2}"
13372 [(set_attr "type" "rotate")
13373 (set_attr "mode" "QI")])
13375 (define_expand "rotrdi3"
13376 [(set (match_operand:DI 0 "shiftdi_operand" "")
13377 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13378 (match_operand:QI 2 "nonmemory_operand" "")))
13379 (clobber (reg:CC FLAGS_REG))]
13384 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13387 if (!const_1_to_31_operand (operands[2], VOIDmode))
13389 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13393 ;; Implement rotation using two double-precision shift instructions
13394 ;; and a scratch register.
13395 (define_insn_and_split "ix86_rotrdi3"
13396 [(set (match_operand:DI 0 "register_operand" "=r")
13397 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13398 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13399 (clobber (reg:CC FLAGS_REG))
13400 (clobber (match_scratch:SI 3 "=&r"))]
13403 "&& reload_completed"
13404 [(set (match_dup 3) (match_dup 4))
13406 [(set (match_dup 4)
13407 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13408 (ashift:SI (match_dup 5)
13409 (minus:QI (const_int 32) (match_dup 2)))))
13410 (clobber (reg:CC FLAGS_REG))])
13412 [(set (match_dup 5)
13413 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13414 (ashift:SI (match_dup 3)
13415 (minus:QI (const_int 32) (match_dup 2)))))
13416 (clobber (reg:CC FLAGS_REG))])]
13417 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13419 (define_insn "*rotrdi3_1_one_bit_rex64"
13420 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13421 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13422 (match_operand:QI 2 "const1_operand" "")))
13423 (clobber (reg:CC FLAGS_REG))]
13425 && (TARGET_SHIFT1 || optimize_size)
13426 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13428 [(set_attr "type" "rotate")
13429 (set (attr "length")
13430 (if_then_else (match_operand:DI 0 "register_operand" "")
13432 (const_string "*")))])
13434 (define_insn "*rotrdi3_1_rex64"
13435 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13436 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13437 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13438 (clobber (reg:CC FLAGS_REG))]
13439 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13441 ror{q}\t{%2, %0|%0, %2}
13442 ror{q}\t{%b2, %0|%0, %b2}"
13443 [(set_attr "type" "rotate")
13444 (set_attr "mode" "DI")])
13446 (define_expand "rotrsi3"
13447 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13448 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13449 (match_operand:QI 2 "nonmemory_operand" "")))
13450 (clobber (reg:CC FLAGS_REG))]
13452 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13454 (define_insn "*rotrsi3_1_one_bit"
13455 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13456 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13457 (match_operand:QI 2 "const1_operand" "")))
13458 (clobber (reg:CC FLAGS_REG))]
13459 "(TARGET_SHIFT1 || optimize_size)
13460 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13462 [(set_attr "type" "rotate")
13463 (set (attr "length")
13464 (if_then_else (match_operand:SI 0 "register_operand" "")
13466 (const_string "*")))])
13468 (define_insn "*rotrsi3_1_one_bit_zext"
13469 [(set (match_operand:DI 0 "register_operand" "=r")
13471 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13472 (match_operand:QI 2 "const1_operand" ""))))
13473 (clobber (reg:CC FLAGS_REG))]
13475 && (TARGET_SHIFT1 || optimize_size)
13476 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13478 [(set_attr "type" "rotate")
13479 (set (attr "length")
13480 (if_then_else (match_operand:SI 0 "register_operand" "")
13482 (const_string "*")))])
13484 (define_insn "*rotrsi3_1"
13485 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13486 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13487 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13488 (clobber (reg:CC FLAGS_REG))]
13489 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13491 ror{l}\t{%2, %0|%0, %2}
13492 ror{l}\t{%b2, %0|%0, %b2}"
13493 [(set_attr "type" "rotate")
13494 (set_attr "mode" "SI")])
13496 (define_insn "*rotrsi3_1_zext"
13497 [(set (match_operand:DI 0 "register_operand" "=r,r")
13499 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13500 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13501 (clobber (reg:CC FLAGS_REG))]
13502 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13504 ror{l}\t{%2, %k0|%k0, %2}
13505 ror{l}\t{%b2, %k0|%k0, %b2}"
13506 [(set_attr "type" "rotate")
13507 (set_attr "mode" "SI")])
13509 (define_expand "rotrhi3"
13510 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13511 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13512 (match_operand:QI 2 "nonmemory_operand" "")))
13513 (clobber (reg:CC FLAGS_REG))]
13514 "TARGET_HIMODE_MATH"
13515 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13517 (define_insn "*rotrhi3_one_bit"
13518 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13519 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13520 (match_operand:QI 2 "const1_operand" "")))
13521 (clobber (reg:CC FLAGS_REG))]
13522 "(TARGET_SHIFT1 || optimize_size)
13523 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13525 [(set_attr "type" "rotate")
13526 (set (attr "length")
13527 (if_then_else (match_operand 0 "register_operand" "")
13529 (const_string "*")))])
13531 (define_insn "*rotrhi3_1"
13532 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13533 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13534 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13535 (clobber (reg:CC FLAGS_REG))]
13536 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13538 ror{w}\t{%2, %0|%0, %2}
13539 ror{w}\t{%b2, %0|%0, %b2}"
13540 [(set_attr "type" "rotate")
13541 (set_attr "mode" "HI")])
13544 [(set (match_operand:HI 0 "register_operand" "")
13545 (rotatert:HI (match_dup 0) (const_int 8)))
13546 (clobber (reg:CC FLAGS_REG))]
13548 [(parallel [(set (strict_low_part (match_dup 0))
13549 (bswap:HI (match_dup 0)))
13550 (clobber (reg:CC FLAGS_REG))])]
13553 (define_expand "rotrqi3"
13554 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13555 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13556 (match_operand:QI 2 "nonmemory_operand" "")))
13557 (clobber (reg:CC FLAGS_REG))]
13558 "TARGET_QIMODE_MATH"
13559 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13561 (define_insn "*rotrqi3_1_one_bit"
13562 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13563 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13564 (match_operand:QI 2 "const1_operand" "")))
13565 (clobber (reg:CC FLAGS_REG))]
13566 "(TARGET_SHIFT1 || optimize_size)
13567 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13569 [(set_attr "type" "rotate")
13570 (set (attr "length")
13571 (if_then_else (match_operand 0 "register_operand" "")
13573 (const_string "*")))])
13575 (define_insn "*rotrqi3_1_one_bit_slp"
13576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13577 (rotatert:QI (match_dup 0)
13578 (match_operand:QI 1 "const1_operand" "")))
13579 (clobber (reg:CC FLAGS_REG))]
13580 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13581 && (TARGET_SHIFT1 || optimize_size)"
13583 [(set_attr "type" "rotate1")
13584 (set (attr "length")
13585 (if_then_else (match_operand 0 "register_operand" "")
13587 (const_string "*")))])
13589 (define_insn "*rotrqi3_1"
13590 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13591 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13592 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13593 (clobber (reg:CC FLAGS_REG))]
13594 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13596 ror{b}\t{%2, %0|%0, %2}
13597 ror{b}\t{%b2, %0|%0, %b2}"
13598 [(set_attr "type" "rotate")
13599 (set_attr "mode" "QI")])
13601 (define_insn "*rotrqi3_1_slp"
13602 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13603 (rotatert:QI (match_dup 0)
13604 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13605 (clobber (reg:CC FLAGS_REG))]
13606 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13607 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13609 ror{b}\t{%1, %0|%0, %1}
13610 ror{b}\t{%b1, %0|%0, %b1}"
13611 [(set_attr "type" "rotate1")
13612 (set_attr "mode" "QI")])
13614 ;; Bit set / bit test instructions
13616 (define_expand "extv"
13617 [(set (match_operand:SI 0 "register_operand" "")
13618 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13619 (match_operand:SI 2 "const8_operand" "")
13620 (match_operand:SI 3 "const8_operand" "")))]
13623 /* Handle extractions from %ah et al. */
13624 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13627 /* From mips.md: extract_bit_field doesn't verify that our source
13628 matches the predicate, so check it again here. */
13629 if (! ext_register_operand (operands[1], VOIDmode))
13633 (define_expand "extzv"
13634 [(set (match_operand:SI 0 "register_operand" "")
13635 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13636 (match_operand:SI 2 "const8_operand" "")
13637 (match_operand:SI 3 "const8_operand" "")))]
13640 /* Handle extractions from %ah et al. */
13641 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13644 /* From mips.md: extract_bit_field doesn't verify that our source
13645 matches the predicate, so check it again here. */
13646 if (! ext_register_operand (operands[1], VOIDmode))
13650 (define_expand "insv"
13651 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13652 (match_operand 1 "const8_operand" "")
13653 (match_operand 2 "const8_operand" ""))
13654 (match_operand 3 "register_operand" ""))]
13657 /* Handle insertions to %ah et al. */
13658 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13661 /* From mips.md: insert_bit_field doesn't verify that our source
13662 matches the predicate, so check it again here. */
13663 if (! ext_register_operand (operands[0], VOIDmode))
13667 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13669 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13674 ;; %%% bts, btr, btc, bt.
13675 ;; In general these instructions are *slow* when applied to memory,
13676 ;; since they enforce atomic operation. When applied to registers,
13677 ;; it depends on the cpu implementation. They're never faster than
13678 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13679 ;; no point. But in 64-bit, we can't hold the relevant immediates
13680 ;; within the instruction itself, so operating on bits in the high
13681 ;; 32-bits of a register becomes easier.
13683 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13684 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13685 ;; negdf respectively, so they can never be disabled entirely.
13687 (define_insn "*btsq"
13688 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13690 (match_operand:DI 1 "const_0_to_63_operand" ""))
13692 (clobber (reg:CC FLAGS_REG))]
13693 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13694 "bts{q}\t{%1, %0|%0, %1}"
13695 [(set_attr "type" "alu1")])
13697 (define_insn "*btrq"
13698 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13700 (match_operand:DI 1 "const_0_to_63_operand" ""))
13702 (clobber (reg:CC FLAGS_REG))]
13703 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13704 "btr{q}\t{%1, %0|%0, %1}"
13705 [(set_attr "type" "alu1")])
13707 (define_insn "*btcq"
13708 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13710 (match_operand:DI 1 "const_0_to_63_operand" ""))
13711 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13712 (clobber (reg:CC FLAGS_REG))]
13713 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13714 "btc{q}\t{%1, %0|%0, %1}"
13715 [(set_attr "type" "alu1")])
13717 ;; Allow Nocona to avoid these instructions if a register is available.
13720 [(match_scratch:DI 2 "r")
13721 (parallel [(set (zero_extract:DI
13722 (match_operand:DI 0 "register_operand" "")
13724 (match_operand:DI 1 "const_0_to_63_operand" ""))
13726 (clobber (reg:CC FLAGS_REG))])]
13727 "TARGET_64BIT && !TARGET_USE_BT"
13730 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13733 if (HOST_BITS_PER_WIDE_INT >= 64)
13734 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13735 else if (i < HOST_BITS_PER_WIDE_INT)
13736 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13738 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13740 op1 = immed_double_const (lo, hi, DImode);
13743 emit_move_insn (operands[2], op1);
13747 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13752 [(match_scratch:DI 2 "r")
13753 (parallel [(set (zero_extract:DI
13754 (match_operand:DI 0 "register_operand" "")
13756 (match_operand:DI 1 "const_0_to_63_operand" ""))
13758 (clobber (reg:CC FLAGS_REG))])]
13759 "TARGET_64BIT && !TARGET_USE_BT"
13762 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13765 if (HOST_BITS_PER_WIDE_INT >= 64)
13766 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13767 else if (i < HOST_BITS_PER_WIDE_INT)
13768 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13770 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13772 op1 = immed_double_const (~lo, ~hi, DImode);
13775 emit_move_insn (operands[2], op1);
13779 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13784 [(match_scratch:DI 2 "r")
13785 (parallel [(set (zero_extract:DI
13786 (match_operand:DI 0 "register_operand" "")
13788 (match_operand:DI 1 "const_0_to_63_operand" ""))
13789 (not:DI (zero_extract:DI
13790 (match_dup 0) (const_int 1) (match_dup 1))))
13791 (clobber (reg:CC FLAGS_REG))])]
13792 "TARGET_64BIT && !TARGET_USE_BT"
13795 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13798 if (HOST_BITS_PER_WIDE_INT >= 64)
13799 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13800 else if (i < HOST_BITS_PER_WIDE_INT)
13801 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13803 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13805 op1 = immed_double_const (lo, hi, DImode);
13808 emit_move_insn (operands[2], op1);
13812 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13816 (define_insn "*btdi_rex64"
13817 [(set (reg:CCC FLAGS_REG)
13820 (match_operand:DI 0 "register_operand" "r")
13822 (match_operand:DI 1 "register_operand" "r"))
13824 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
13825 "bt{q}\t{%1, %0|%0, %1}"
13826 [(set_attr "type" "alu1")])
13828 (define_insn "*btsi"
13829 [(set (reg:CCC FLAGS_REG)
13832 (match_operand:SI 0 "register_operand" "r")
13834 (match_operand:SI 1 "register_operand" "r"))
13836 "TARGET_USE_BT || optimize_size"
13837 "bt{l}\t{%1, %0|%0, %1}"
13838 [(set_attr "type" "alu1")])
13840 ;; Store-flag instructions.
13842 ;; For all sCOND expanders, also expand the compare or test insn that
13843 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13845 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13846 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13847 ;; way, which can later delete the movzx if only QImode is needed.
13849 (define_expand "s<code>"
13850 [(set (match_operand:QI 0 "register_operand" "")
13851 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13853 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13855 (define_expand "s<code>"
13856 [(set (match_operand:QI 0 "register_operand" "")
13857 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13858 "TARGET_80387 || TARGET_SSE"
13859 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13861 (define_insn "*setcc_1"
13862 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13863 (match_operator:QI 1 "ix86_comparison_operator"
13864 [(reg FLAGS_REG) (const_int 0)]))]
13867 [(set_attr "type" "setcc")
13868 (set_attr "mode" "QI")])
13870 (define_insn "*setcc_2"
13871 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13872 (match_operator:QI 1 "ix86_comparison_operator"
13873 [(reg FLAGS_REG) (const_int 0)]))]
13876 [(set_attr "type" "setcc")
13877 (set_attr "mode" "QI")])
13879 ;; In general it is not safe to assume too much about CCmode registers,
13880 ;; so simplify-rtx stops when it sees a second one. Under certain
13881 ;; conditions this is safe on x86, so help combine not create
13888 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13889 (ne:QI (match_operator 1 "ix86_comparison_operator"
13890 [(reg FLAGS_REG) (const_int 0)])
13893 [(set (match_dup 0) (match_dup 1))]
13895 PUT_MODE (operands[1], QImode);
13899 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13900 (ne:QI (match_operator 1 "ix86_comparison_operator"
13901 [(reg FLAGS_REG) (const_int 0)])
13904 [(set (match_dup 0) (match_dup 1))]
13906 PUT_MODE (operands[1], QImode);
13910 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13911 (eq:QI (match_operator 1 "ix86_comparison_operator"
13912 [(reg FLAGS_REG) (const_int 0)])
13915 [(set (match_dup 0) (match_dup 1))]
13917 rtx new_op1 = copy_rtx (operands[1]);
13918 operands[1] = new_op1;
13919 PUT_MODE (new_op1, QImode);
13920 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13921 GET_MODE (XEXP (new_op1, 0))));
13923 /* Make sure that (a) the CCmode we have for the flags is strong
13924 enough for the reversed compare or (b) we have a valid FP compare. */
13925 if (! ix86_comparison_operator (new_op1, VOIDmode))
13930 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13931 (eq:QI (match_operator 1 "ix86_comparison_operator"
13932 [(reg FLAGS_REG) (const_int 0)])
13935 [(set (match_dup 0) (match_dup 1))]
13937 rtx new_op1 = copy_rtx (operands[1]);
13938 operands[1] = new_op1;
13939 PUT_MODE (new_op1, QImode);
13940 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13941 GET_MODE (XEXP (new_op1, 0))));
13943 /* Make sure that (a) the CCmode we have for the flags is strong
13944 enough for the reversed compare or (b) we have a valid FP compare. */
13945 if (! ix86_comparison_operator (new_op1, VOIDmode))
13949 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13950 ;; subsequent logical operations are used to imitate conditional moves.
13951 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13954 (define_insn "*sse_setcc<mode>"
13955 [(set (match_operand:MODEF 0 "register_operand" "=x")
13956 (match_operator:MODEF 1 "sse_comparison_operator"
13957 [(match_operand:MODEF 2 "register_operand" "0")
13958 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13959 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13960 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13961 [(set_attr "type" "ssecmp")
13962 (set_attr "mode" "<MODE>")])
13964 (define_insn "*sse5_setcc<mode>"
13965 [(set (match_operand:MODEF 0 "register_operand" "=x")
13966 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13967 [(match_operand:MODEF 2 "register_operand" "x")
13968 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13970 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13971 [(set_attr "type" "sse4arg")
13972 (set_attr "mode" "<MODE>")])
13975 ;; Basic conditional jump instructions.
13976 ;; We ignore the overflow flag for signed branch instructions.
13978 ;; For all bCOND expanders, also expand the compare or test insn that
13979 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13981 (define_expand "b<code>"
13983 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13985 (label_ref (match_operand 0 ""))
13988 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13990 (define_expand "b<code>"
13992 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13994 (label_ref (match_operand 0 ""))
13996 "TARGET_80387 || TARGET_SSE_MATH"
13997 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13999 (define_insn "*jcc_1"
14001 (if_then_else (match_operator 1 "ix86_comparison_operator"
14002 [(reg FLAGS_REG) (const_int 0)])
14003 (label_ref (match_operand 0 "" ""))
14007 [(set_attr "type" "ibr")
14008 (set_attr "modrm" "0")
14009 (set (attr "length")
14010 (if_then_else (and (ge (minus (match_dup 0) (pc))
14012 (lt (minus (match_dup 0) (pc))
14017 (define_insn "*jcc_2"
14019 (if_then_else (match_operator 1 "ix86_comparison_operator"
14020 [(reg FLAGS_REG) (const_int 0)])
14022 (label_ref (match_operand 0 "" ""))))]
14025 [(set_attr "type" "ibr")
14026 (set_attr "modrm" "0")
14027 (set (attr "length")
14028 (if_then_else (and (ge (minus (match_dup 0) (pc))
14030 (lt (minus (match_dup 0) (pc))
14035 ;; In general it is not safe to assume too much about CCmode registers,
14036 ;; so simplify-rtx stops when it sees a second one. Under certain
14037 ;; conditions this is safe on x86, so help combine not create
14045 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14046 [(reg FLAGS_REG) (const_int 0)])
14048 (label_ref (match_operand 1 "" ""))
14052 (if_then_else (match_dup 0)
14053 (label_ref (match_dup 1))
14056 PUT_MODE (operands[0], VOIDmode);
14061 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14062 [(reg FLAGS_REG) (const_int 0)])
14064 (label_ref (match_operand 1 "" ""))
14068 (if_then_else (match_dup 0)
14069 (label_ref (match_dup 1))
14072 rtx new_op0 = copy_rtx (operands[0]);
14073 operands[0] = new_op0;
14074 PUT_MODE (new_op0, VOIDmode);
14075 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14076 GET_MODE (XEXP (new_op0, 0))));
14078 /* Make sure that (a) the CCmode we have for the flags is strong
14079 enough for the reversed compare or (b) we have a valid FP compare. */
14080 if (! ix86_comparison_operator (new_op0, VOIDmode))
14084 ;; zero_extend in SImode is correct, since this is what combine pass
14085 ;; generates from shift insn with QImode operand. Actually, the mode of
14086 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14087 ;; appropriate modulo of the bit offset value.
14089 (define_insn_and_split "*jcc_btdi_rex64"
14091 (if_then_else (match_operator 0 "bt_comparison_operator"
14093 (match_operand:DI 1 "register_operand" "r")
14096 (match_operand:QI 2 "register_operand" "r")))
14098 (label_ref (match_operand 3 "" ""))
14100 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
14103 [(set (reg:CCC FLAGS_REG)
14111 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14112 (label_ref (match_dup 3))
14115 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14117 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14120 (define_insn_and_split "*jcc_btsi"
14122 (if_then_else (match_operator 0 "bt_comparison_operator"
14124 (match_operand:SI 1 "register_operand" "r")
14127 (match_operand:QI 2 "register_operand" "r")))
14129 (label_ref (match_operand 3 "" ""))
14131 "TARGET_USE_BT || optimize_size"
14134 [(set (reg:CCC FLAGS_REG)
14142 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14143 (label_ref (match_dup 3))
14146 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14148 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14151 (define_insn_and_split "*jcc_btsi_1"
14153 (if_then_else (match_operator 0 "bt_comparison_operator"
14156 (match_operand:SI 1 "register_operand" "r")
14157 (match_operand:QI 2 "register_operand" "r"))
14160 (label_ref (match_operand 3 "" ""))
14162 "TARGET_USE_BT || optimize_size"
14165 [(set (reg:CCC FLAGS_REG)
14173 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14174 (label_ref (match_dup 3))
14177 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14179 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14182 ;; Define combination compare-and-branch fp compare instructions to use
14183 ;; during early optimization. Splitting the operation apart early makes
14184 ;; for bad code when we want to reverse the operation.
14186 (define_insn "*fp_jcc_1_mixed"
14188 (if_then_else (match_operator 0 "comparison_operator"
14189 [(match_operand 1 "register_operand" "f,x")
14190 (match_operand 2 "nonimmediate_operand" "f,xm")])
14191 (label_ref (match_operand 3 "" ""))
14193 (clobber (reg:CCFP FPSR_REG))
14194 (clobber (reg:CCFP FLAGS_REG))]
14195 "TARGET_MIX_SSE_I387
14196 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14197 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14198 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14201 (define_insn "*fp_jcc_1_sse"
14203 (if_then_else (match_operator 0 "comparison_operator"
14204 [(match_operand 1 "register_operand" "x")
14205 (match_operand 2 "nonimmediate_operand" "xm")])
14206 (label_ref (match_operand 3 "" ""))
14208 (clobber (reg:CCFP FPSR_REG))
14209 (clobber (reg:CCFP FLAGS_REG))]
14211 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14212 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14213 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14216 (define_insn "*fp_jcc_1_387"
14218 (if_then_else (match_operator 0 "comparison_operator"
14219 [(match_operand 1 "register_operand" "f")
14220 (match_operand 2 "register_operand" "f")])
14221 (label_ref (match_operand 3 "" ""))
14223 (clobber (reg:CCFP FPSR_REG))
14224 (clobber (reg:CCFP FLAGS_REG))]
14225 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14227 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14228 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14231 (define_insn "*fp_jcc_2_mixed"
14233 (if_then_else (match_operator 0 "comparison_operator"
14234 [(match_operand 1 "register_operand" "f,x")
14235 (match_operand 2 "nonimmediate_operand" "f,xm")])
14237 (label_ref (match_operand 3 "" ""))))
14238 (clobber (reg:CCFP FPSR_REG))
14239 (clobber (reg:CCFP FLAGS_REG))]
14240 "TARGET_MIX_SSE_I387
14241 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14242 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14243 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14246 (define_insn "*fp_jcc_2_sse"
14248 (if_then_else (match_operator 0 "comparison_operator"
14249 [(match_operand 1 "register_operand" "x")
14250 (match_operand 2 "nonimmediate_operand" "xm")])
14252 (label_ref (match_operand 3 "" ""))))
14253 (clobber (reg:CCFP FPSR_REG))
14254 (clobber (reg:CCFP FLAGS_REG))]
14256 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14257 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14258 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14261 (define_insn "*fp_jcc_2_387"
14263 (if_then_else (match_operator 0 "comparison_operator"
14264 [(match_operand 1 "register_operand" "f")
14265 (match_operand 2 "register_operand" "f")])
14267 (label_ref (match_operand 3 "" ""))))
14268 (clobber (reg:CCFP FPSR_REG))
14269 (clobber (reg:CCFP FLAGS_REG))]
14270 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14272 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14273 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14276 (define_insn "*fp_jcc_3_387"
14278 (if_then_else (match_operator 0 "comparison_operator"
14279 [(match_operand 1 "register_operand" "f")
14280 (match_operand 2 "nonimmediate_operand" "fm")])
14281 (label_ref (match_operand 3 "" ""))
14283 (clobber (reg:CCFP FPSR_REG))
14284 (clobber (reg:CCFP FLAGS_REG))
14285 (clobber (match_scratch:HI 4 "=a"))]
14287 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14288 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14289 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14290 && SELECT_CC_MODE (GET_CODE (operands[0]),
14291 operands[1], operands[2]) == CCFPmode
14292 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14295 (define_insn "*fp_jcc_4_387"
14297 (if_then_else (match_operator 0 "comparison_operator"
14298 [(match_operand 1 "register_operand" "f")
14299 (match_operand 2 "nonimmediate_operand" "fm")])
14301 (label_ref (match_operand 3 "" ""))))
14302 (clobber (reg:CCFP FPSR_REG))
14303 (clobber (reg:CCFP FLAGS_REG))
14304 (clobber (match_scratch:HI 4 "=a"))]
14306 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14307 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14308 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14309 && SELECT_CC_MODE (GET_CODE (operands[0]),
14310 operands[1], operands[2]) == CCFPmode
14311 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14314 (define_insn "*fp_jcc_5_387"
14316 (if_then_else (match_operator 0 "comparison_operator"
14317 [(match_operand 1 "register_operand" "f")
14318 (match_operand 2 "register_operand" "f")])
14319 (label_ref (match_operand 3 "" ""))
14321 (clobber (reg:CCFP FPSR_REG))
14322 (clobber (reg:CCFP FLAGS_REG))
14323 (clobber (match_scratch:HI 4 "=a"))]
14324 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14325 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14326 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14329 (define_insn "*fp_jcc_6_387"
14331 (if_then_else (match_operator 0 "comparison_operator"
14332 [(match_operand 1 "register_operand" "f")
14333 (match_operand 2 "register_operand" "f")])
14335 (label_ref (match_operand 3 "" ""))))
14336 (clobber (reg:CCFP FPSR_REG))
14337 (clobber (reg:CCFP FLAGS_REG))
14338 (clobber (match_scratch:HI 4 "=a"))]
14339 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14340 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14341 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14344 (define_insn "*fp_jcc_7_387"
14346 (if_then_else (match_operator 0 "comparison_operator"
14347 [(match_operand 1 "register_operand" "f")
14348 (match_operand 2 "const0_operand" "X")])
14349 (label_ref (match_operand 3 "" ""))
14351 (clobber (reg:CCFP FPSR_REG))
14352 (clobber (reg:CCFP FLAGS_REG))
14353 (clobber (match_scratch:HI 4 "=a"))]
14354 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14355 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14356 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14357 && SELECT_CC_MODE (GET_CODE (operands[0]),
14358 operands[1], operands[2]) == CCFPmode
14359 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14362 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14363 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14364 ;; with a precedence over other operators and is always put in the first
14365 ;; place. Swap condition and operands to match ficom instruction.
14367 (define_insn "*fp_jcc_8<mode>_387"
14369 (if_then_else (match_operator 0 "comparison_operator"
14370 [(match_operator 1 "float_operator"
14371 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14372 (match_operand 3 "register_operand" "f,f")])
14373 (label_ref (match_operand 4 "" ""))
14375 (clobber (reg:CCFP FPSR_REG))
14376 (clobber (reg:CCFP FLAGS_REG))
14377 (clobber (match_scratch:HI 5 "=a,a"))]
14378 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14379 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
14380 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14381 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14382 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14383 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14388 (if_then_else (match_operator 0 "comparison_operator"
14389 [(match_operand 1 "register_operand" "")
14390 (match_operand 2 "nonimmediate_operand" "")])
14391 (match_operand 3 "" "")
14392 (match_operand 4 "" "")))
14393 (clobber (reg:CCFP FPSR_REG))
14394 (clobber (reg:CCFP FLAGS_REG))]
14398 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14399 operands[3], operands[4], NULL_RTX, NULL_RTX);
14405 (if_then_else (match_operator 0 "comparison_operator"
14406 [(match_operand 1 "register_operand" "")
14407 (match_operand 2 "general_operand" "")])
14408 (match_operand 3 "" "")
14409 (match_operand 4 "" "")))
14410 (clobber (reg:CCFP FPSR_REG))
14411 (clobber (reg:CCFP FLAGS_REG))
14412 (clobber (match_scratch:HI 5 "=a"))]
14416 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14417 operands[3], operands[4], operands[5], NULL_RTX);
14423 (if_then_else (match_operator 0 "comparison_operator"
14424 [(match_operator 1 "float_operator"
14425 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14426 (match_operand 3 "register_operand" "")])
14427 (match_operand 4 "" "")
14428 (match_operand 5 "" "")))
14429 (clobber (reg:CCFP FPSR_REG))
14430 (clobber (reg:CCFP FLAGS_REG))
14431 (clobber (match_scratch:HI 6 "=a"))]
14435 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14436 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14437 operands[3], operands[7],
14438 operands[4], operands[5], operands[6], NULL_RTX);
14442 ;; %%% Kill this when reload knows how to do it.
14445 (if_then_else (match_operator 0 "comparison_operator"
14446 [(match_operator 1 "float_operator"
14447 [(match_operand:X87MODEI12 2 "register_operand" "")])
14448 (match_operand 3 "register_operand" "")])
14449 (match_operand 4 "" "")
14450 (match_operand 5 "" "")))
14451 (clobber (reg:CCFP FPSR_REG))
14452 (clobber (reg:CCFP FLAGS_REG))
14453 (clobber (match_scratch:HI 6 "=a"))]
14457 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14458 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14459 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14460 operands[3], operands[7],
14461 operands[4], operands[5], operands[6], operands[2]);
14465 ;; Unconditional and other jump instructions
14467 (define_insn "jump"
14469 (label_ref (match_operand 0 "" "")))]
14472 [(set_attr "type" "ibr")
14473 (set (attr "length")
14474 (if_then_else (and (ge (minus (match_dup 0) (pc))
14476 (lt (minus (match_dup 0) (pc))
14480 (set_attr "modrm" "0")])
14482 (define_expand "indirect_jump"
14483 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14487 (define_insn "*indirect_jump"
14488 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14491 [(set_attr "type" "ibr")
14492 (set_attr "length_immediate" "0")])
14494 (define_expand "tablejump"
14495 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14496 (use (label_ref (match_operand 1 "" "")))])]
14499 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14500 relative. Convert the relative address to an absolute address. */
14504 enum rtx_code code;
14506 /* We can't use @GOTOFF for text labels on VxWorks;
14507 see gotoff_operand. */
14508 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14512 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14514 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14518 op1 = pic_offset_table_rtx;
14523 op0 = pic_offset_table_rtx;
14527 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14532 (define_insn "*tablejump_1"
14533 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14534 (use (label_ref (match_operand 1 "" "")))]
14537 [(set_attr "type" "ibr")
14538 (set_attr "length_immediate" "0")])
14540 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14543 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14544 (set (match_operand:QI 1 "register_operand" "")
14545 (match_operator:QI 2 "ix86_comparison_operator"
14546 [(reg FLAGS_REG) (const_int 0)]))
14547 (set (match_operand 3 "q_regs_operand" "")
14548 (zero_extend (match_dup 1)))]
14549 "(peep2_reg_dead_p (3, operands[1])
14550 || operands_match_p (operands[1], operands[3]))
14551 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14552 [(set (match_dup 4) (match_dup 0))
14553 (set (strict_low_part (match_dup 5))
14556 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14557 operands[5] = gen_lowpart (QImode, operands[3]);
14558 ix86_expand_clear (operands[3]);
14561 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14564 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14565 (set (match_operand:QI 1 "register_operand" "")
14566 (match_operator:QI 2 "ix86_comparison_operator"
14567 [(reg FLAGS_REG) (const_int 0)]))
14568 (parallel [(set (match_operand 3 "q_regs_operand" "")
14569 (zero_extend (match_dup 1)))
14570 (clobber (reg:CC FLAGS_REG))])]
14571 "(peep2_reg_dead_p (3, operands[1])
14572 || operands_match_p (operands[1], operands[3]))
14573 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14574 [(set (match_dup 4) (match_dup 0))
14575 (set (strict_low_part (match_dup 5))
14578 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14579 operands[5] = gen_lowpart (QImode, operands[3]);
14580 ix86_expand_clear (operands[3]);
14583 ;; Call instructions.
14585 ;; The predicates normally associated with named expanders are not properly
14586 ;; checked for calls. This is a bug in the generic code, but it isn't that
14587 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14589 ;; Call subroutine returning no value.
14591 (define_expand "call_pop"
14592 [(parallel [(call (match_operand:QI 0 "" "")
14593 (match_operand:SI 1 "" ""))
14594 (set (reg:SI SP_REG)
14595 (plus:SI (reg:SI SP_REG)
14596 (match_operand:SI 3 "" "")))])]
14599 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14603 (define_insn "*call_pop_0"
14604 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14605 (match_operand:SI 1 "" ""))
14606 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14607 (match_operand:SI 2 "immediate_operand" "")))]
14610 if (SIBLING_CALL_P (insn))
14613 return "call\t%P0";
14615 [(set_attr "type" "call")])
14617 (define_insn "*call_pop_1"
14618 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14619 (match_operand:SI 1 "" ""))
14620 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14621 (match_operand:SI 2 "immediate_operand" "i")))]
14624 if (constant_call_address_operand (operands[0], Pmode))
14626 if (SIBLING_CALL_P (insn))
14629 return "call\t%P0";
14631 if (SIBLING_CALL_P (insn))
14634 return "call\t%A0";
14636 [(set_attr "type" "call")])
14638 (define_expand "call"
14639 [(call (match_operand:QI 0 "" "")
14640 (match_operand 1 "" ""))
14641 (use (match_operand 2 "" ""))]
14644 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14648 (define_expand "sibcall"
14649 [(call (match_operand:QI 0 "" "")
14650 (match_operand 1 "" ""))
14651 (use (match_operand 2 "" ""))]
14654 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14658 (define_insn "*call_0"
14659 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14660 (match_operand 1 "" ""))]
14663 if (SIBLING_CALL_P (insn))
14666 return "call\t%P0";
14668 [(set_attr "type" "call")])
14670 (define_insn "*call_1"
14671 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14672 (match_operand 1 "" ""))]
14673 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14675 if (constant_call_address_operand (operands[0], Pmode))
14676 return "call\t%P0";
14677 return "call\t%A0";
14679 [(set_attr "type" "call")])
14681 (define_insn "*sibcall_1"
14682 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14683 (match_operand 1 "" ""))]
14684 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14686 if (constant_call_address_operand (operands[0], Pmode))
14690 [(set_attr "type" "call")])
14692 (define_insn "*call_1_rex64"
14693 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14694 (match_operand 1 "" ""))]
14695 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14696 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14698 if (constant_call_address_operand (operands[0], Pmode))
14699 return "call\t%P0";
14700 return "call\t%A0";
14702 [(set_attr "type" "call")])
14704 (define_insn "*call_1_rex64_large"
14705 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14706 (match_operand 1 "" ""))]
14707 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14709 [(set_attr "type" "call")])
14711 (define_insn "*sibcall_1_rex64"
14712 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14713 (match_operand 1 "" ""))]
14714 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14716 [(set_attr "type" "call")])
14718 (define_insn "*sibcall_1_rex64_v"
14719 [(call (mem:QI (reg:DI R11_REG))
14720 (match_operand 0 "" ""))]
14721 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14723 [(set_attr "type" "call")])
14726 ;; Call subroutine, returning value in operand 0
14728 (define_expand "call_value_pop"
14729 [(parallel [(set (match_operand 0 "" "")
14730 (call (match_operand:QI 1 "" "")
14731 (match_operand:SI 2 "" "")))
14732 (set (reg:SI SP_REG)
14733 (plus:SI (reg:SI SP_REG)
14734 (match_operand:SI 4 "" "")))])]
14737 ix86_expand_call (operands[0], operands[1], operands[2],
14738 operands[3], operands[4], 0);
14742 (define_expand "call_value"
14743 [(set (match_operand 0 "" "")
14744 (call (match_operand:QI 1 "" "")
14745 (match_operand:SI 2 "" "")))
14746 (use (match_operand:SI 3 "" ""))]
14747 ;; Operand 2 not used on the i386.
14750 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14754 (define_expand "sibcall_value"
14755 [(set (match_operand 0 "" "")
14756 (call (match_operand:QI 1 "" "")
14757 (match_operand:SI 2 "" "")))
14758 (use (match_operand:SI 3 "" ""))]
14759 ;; Operand 2 not used on the i386.
14762 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14766 ;; Call subroutine returning any type.
14768 (define_expand "untyped_call"
14769 [(parallel [(call (match_operand 0 "" "")
14771 (match_operand 1 "" "")
14772 (match_operand 2 "" "")])]
14777 /* In order to give reg-stack an easier job in validating two
14778 coprocessor registers as containing a possible return value,
14779 simply pretend the untyped call returns a complex long double
14782 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14783 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14784 operands[0], const0_rtx,
14785 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
14786 : X64_SSE_REGPARM_MAX)
14790 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14792 rtx set = XVECEXP (operands[2], 0, i);
14793 emit_move_insn (SET_DEST (set), SET_SRC (set));
14796 /* The optimizer does not know that the call sets the function value
14797 registers we stored in the result block. We avoid problems by
14798 claiming that all hard registers are used and clobbered at this
14800 emit_insn (gen_blockage ());
14805 ;; Prologue and epilogue instructions
14807 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14808 ;; all of memory. This blocks insns from being moved across this point.
14810 (define_insn "blockage"
14811 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14814 [(set_attr "length" "0")])
14816 ;; As USE insns aren't meaningful after reload, this is used instead
14817 ;; to prevent deleting instructions setting registers for PIC code
14818 (define_insn "prologue_use"
14819 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14822 [(set_attr "length" "0")])
14824 ;; Insn emitted into the body of a function to return from a function.
14825 ;; This is only done if the function's epilogue is known to be simple.
14826 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14828 (define_expand "return"
14830 "ix86_can_use_return_insn_p ()"
14832 if (crtl->args.pops_args)
14834 rtx popc = GEN_INT (crtl->args.pops_args);
14835 emit_jump_insn (gen_return_pop_internal (popc));
14840 (define_insn "return_internal"
14844 [(set_attr "length" "1")
14845 (set_attr "length_immediate" "0")
14846 (set_attr "modrm" "0")])
14848 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14849 ;; instruction Athlon and K8 have.
14851 (define_insn "return_internal_long"
14853 (unspec [(const_int 0)] UNSPEC_REP)]
14856 [(set_attr "length" "1")
14857 (set_attr "length_immediate" "0")
14858 (set_attr "prefix_rep" "1")
14859 (set_attr "modrm" "0")])
14861 (define_insn "return_pop_internal"
14863 (use (match_operand:SI 0 "const_int_operand" ""))]
14866 [(set_attr "length" "3")
14867 (set_attr "length_immediate" "2")
14868 (set_attr "modrm" "0")])
14870 (define_insn "return_indirect_internal"
14872 (use (match_operand:SI 0 "register_operand" "r"))]
14875 [(set_attr "type" "ibr")
14876 (set_attr "length_immediate" "0")])
14882 [(set_attr "length" "1")
14883 (set_attr "length_immediate" "0")
14884 (set_attr "modrm" "0")])
14886 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14887 ;; branch prediction penalty for the third jump in a 16-byte
14890 (define_insn "align"
14891 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14894 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14895 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14897 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14898 The align insn is used to avoid 3 jump instructions in the row to improve
14899 branch prediction and the benefits hardly outweigh the cost of extra 8
14900 nops on the average inserted by full alignment pseudo operation. */
14904 [(set_attr "length" "16")])
14906 (define_expand "prologue"
14909 "ix86_expand_prologue (); DONE;")
14911 (define_insn "set_got"
14912 [(set (match_operand:SI 0 "register_operand" "=r")
14913 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14914 (clobber (reg:CC FLAGS_REG))]
14916 { return output_set_got (operands[0], NULL_RTX); }
14917 [(set_attr "type" "multi")
14918 (set_attr "length" "12")])
14920 (define_insn "set_got_labelled"
14921 [(set (match_operand:SI 0 "register_operand" "=r")
14922 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14924 (clobber (reg:CC FLAGS_REG))]
14926 { return output_set_got (operands[0], operands[1]); }
14927 [(set_attr "type" "multi")
14928 (set_attr "length" "12")])
14930 (define_insn "set_got_rex64"
14931 [(set (match_operand:DI 0 "register_operand" "=r")
14932 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14934 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14935 [(set_attr "type" "lea")
14936 (set_attr "length" "6")])
14938 (define_insn "set_rip_rex64"
14939 [(set (match_operand:DI 0 "register_operand" "=r")
14940 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14942 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14943 [(set_attr "type" "lea")
14944 (set_attr "length" "6")])
14946 (define_insn "set_got_offset_rex64"
14947 [(set (match_operand:DI 0 "register_operand" "=r")
14948 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14950 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14951 [(set_attr "type" "imov")
14952 (set_attr "length" "11")])
14954 (define_expand "epilogue"
14957 "ix86_expand_epilogue (1); DONE;")
14959 (define_expand "sibcall_epilogue"
14962 "ix86_expand_epilogue (0); DONE;")
14964 (define_expand "eh_return"
14965 [(use (match_operand 0 "register_operand" ""))]
14968 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14970 /* Tricky bit: we write the address of the handler to which we will
14971 be returning into someone else's stack frame, one word below the
14972 stack address we wish to restore. */
14973 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14974 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14975 tmp = gen_rtx_MEM (Pmode, tmp);
14976 emit_move_insn (tmp, ra);
14978 if (Pmode == SImode)
14979 emit_jump_insn (gen_eh_return_si (sa));
14981 emit_jump_insn (gen_eh_return_di (sa));
14986 (define_insn_and_split "eh_return_<mode>"
14988 (unspec [(match_operand:P 0 "register_operand" "c")]
14989 UNSPEC_EH_RETURN))]
14994 "ix86_expand_epilogue (2); DONE;")
14996 (define_insn "leave"
14997 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14998 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14999 (clobber (mem:BLK (scratch)))]
15002 [(set_attr "type" "leave")])
15004 (define_insn "leave_rex64"
15005 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15006 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15007 (clobber (mem:BLK (scratch)))]
15010 [(set_attr "type" "leave")])
15012 (define_expand "ffssi2"
15014 [(set (match_operand:SI 0 "register_operand" "")
15015 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15016 (clobber (match_scratch:SI 2 ""))
15017 (clobber (reg:CC FLAGS_REG))])]
15022 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15027 (define_expand "ffs_cmove"
15028 [(set (match_dup 2) (const_int -1))
15029 (parallel [(set (reg:CCZ FLAGS_REG)
15030 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15032 (set (match_operand:SI 0 "nonimmediate_operand" "")
15033 (ctz:SI (match_dup 1)))])
15034 (set (match_dup 0) (if_then_else:SI
15035 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15038 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15039 (clobber (reg:CC FLAGS_REG))])]
15041 "operands[2] = gen_reg_rtx (SImode);")
15043 (define_insn_and_split "*ffs_no_cmove"
15044 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15045 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15046 (clobber (match_scratch:SI 2 "=&q"))
15047 (clobber (reg:CC FLAGS_REG))]
15050 "&& reload_completed"
15051 [(parallel [(set (reg:CCZ FLAGS_REG)
15052 (compare:CCZ (match_dup 1) (const_int 0)))
15053 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15054 (set (strict_low_part (match_dup 3))
15055 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15056 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15057 (clobber (reg:CC FLAGS_REG))])
15058 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15059 (clobber (reg:CC FLAGS_REG))])
15060 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15061 (clobber (reg:CC FLAGS_REG))])]
15063 operands[3] = gen_lowpart (QImode, operands[2]);
15064 ix86_expand_clear (operands[2]);
15067 (define_insn "*ffssi_1"
15068 [(set (reg:CCZ FLAGS_REG)
15069 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15071 (set (match_operand:SI 0 "register_operand" "=r")
15072 (ctz:SI (match_dup 1)))]
15074 "bsf{l}\t{%1, %0|%0, %1}"
15075 [(set_attr "prefix_0f" "1")])
15077 (define_expand "ffsdi2"
15078 [(set (match_dup 2) (const_int -1))
15079 (parallel [(set (reg:CCZ FLAGS_REG)
15080 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15082 (set (match_operand:DI 0 "nonimmediate_operand" "")
15083 (ctz:DI (match_dup 1)))])
15084 (set (match_dup 0) (if_then_else:DI
15085 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15088 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15089 (clobber (reg:CC FLAGS_REG))])]
15091 "operands[2] = gen_reg_rtx (DImode);")
15093 (define_insn "*ffsdi_1"
15094 [(set (reg:CCZ FLAGS_REG)
15095 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15097 (set (match_operand:DI 0 "register_operand" "=r")
15098 (ctz:DI (match_dup 1)))]
15100 "bsf{q}\t{%1, %0|%0, %1}"
15101 [(set_attr "prefix_0f" "1")])
15103 (define_insn "ctzsi2"
15104 [(set (match_operand:SI 0 "register_operand" "=r")
15105 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15106 (clobber (reg:CC FLAGS_REG))]
15108 "bsf{l}\t{%1, %0|%0, %1}"
15109 [(set_attr "prefix_0f" "1")])
15111 (define_insn "ctzdi2"
15112 [(set (match_operand:DI 0 "register_operand" "=r")
15113 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15114 (clobber (reg:CC FLAGS_REG))]
15116 "bsf{q}\t{%1, %0|%0, %1}"
15117 [(set_attr "prefix_0f" "1")])
15119 (define_expand "clzsi2"
15121 [(set (match_operand:SI 0 "register_operand" "")
15122 (minus:SI (const_int 31)
15123 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15124 (clobber (reg:CC FLAGS_REG))])
15126 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15127 (clobber (reg:CC FLAGS_REG))])]
15132 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15137 (define_insn "clzsi2_abm"
15138 [(set (match_operand:SI 0 "register_operand" "=r")
15139 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15140 (clobber (reg:CC FLAGS_REG))]
15142 "lzcnt{l}\t{%1, %0|%0, %1}"
15143 [(set_attr "prefix_rep" "1")
15144 (set_attr "type" "bitmanip")
15145 (set_attr "mode" "SI")])
15147 (define_insn "*bsr"
15148 [(set (match_operand:SI 0 "register_operand" "=r")
15149 (minus:SI (const_int 31)
15150 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15151 (clobber (reg:CC FLAGS_REG))]
15153 "bsr{l}\t{%1, %0|%0, %1}"
15154 [(set_attr "prefix_0f" "1")
15155 (set_attr "mode" "SI")])
15157 (define_insn "popcountsi2"
15158 [(set (match_operand:SI 0 "register_operand" "=r")
15159 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15160 (clobber (reg:CC FLAGS_REG))]
15162 "popcnt{l}\t{%1, %0|%0, %1}"
15163 [(set_attr "prefix_rep" "1")
15164 (set_attr "type" "bitmanip")
15165 (set_attr "mode" "SI")])
15167 (define_insn "*popcountsi2_cmp"
15168 [(set (reg FLAGS_REG)
15170 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15172 (set (match_operand:SI 0 "register_operand" "=r")
15173 (popcount:SI (match_dup 1)))]
15174 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15175 "popcnt{l}\t{%1, %0|%0, %1}"
15176 [(set_attr "prefix_rep" "1")
15177 (set_attr "type" "bitmanip")
15178 (set_attr "mode" "SI")])
15180 (define_insn "*popcountsi2_cmp_zext"
15181 [(set (reg FLAGS_REG)
15183 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15185 (set (match_operand:DI 0 "register_operand" "=r")
15186 (zero_extend:DI(popcount:SI (match_dup 1))))]
15187 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15188 "popcnt{l}\t{%1, %0|%0, %1}"
15189 [(set_attr "prefix_rep" "1")
15190 (set_attr "type" "bitmanip")
15191 (set_attr "mode" "SI")])
15193 (define_expand "bswapsi2"
15194 [(set (match_operand:SI 0 "register_operand" "")
15195 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15200 rtx x = operands[0];
15202 emit_move_insn (x, operands[1]);
15203 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15204 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15205 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15210 (define_insn "*bswapsi_1"
15211 [(set (match_operand:SI 0 "register_operand" "=r")
15212 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15215 [(set_attr "prefix_0f" "1")
15216 (set_attr "length" "2")])
15218 (define_insn "*bswaphi_lowpart_1"
15219 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15220 (bswap:HI (match_dup 0)))
15221 (clobber (reg:CC FLAGS_REG))]
15222 "TARGET_USE_XCHGB || optimize_size"
15224 xchg{b}\t{%h0, %b0|%b0, %h0}
15225 rol{w}\t{$8, %0|%0, 8}"
15226 [(set_attr "length" "2,4")
15227 (set_attr "mode" "QI,HI")])
15229 (define_insn "bswaphi_lowpart"
15230 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15231 (bswap:HI (match_dup 0)))
15232 (clobber (reg:CC FLAGS_REG))]
15234 "rol{w}\t{$8, %0|%0, 8}"
15235 [(set_attr "length" "4")
15236 (set_attr "mode" "HI")])
15238 (define_insn "bswapdi2"
15239 [(set (match_operand:DI 0 "register_operand" "=r")
15240 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15243 [(set_attr "prefix_0f" "1")
15244 (set_attr "length" "3")])
15246 (define_expand "clzdi2"
15248 [(set (match_operand:DI 0 "register_operand" "")
15249 (minus:DI (const_int 63)
15250 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15251 (clobber (reg:CC FLAGS_REG))])
15253 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15254 (clobber (reg:CC FLAGS_REG))])]
15259 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15264 (define_insn "clzdi2_abm"
15265 [(set (match_operand:DI 0 "register_operand" "=r")
15266 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15267 (clobber (reg:CC FLAGS_REG))]
15268 "TARGET_64BIT && TARGET_ABM"
15269 "lzcnt{q}\t{%1, %0|%0, %1}"
15270 [(set_attr "prefix_rep" "1")
15271 (set_attr "type" "bitmanip")
15272 (set_attr "mode" "DI")])
15274 (define_insn "*bsr_rex64"
15275 [(set (match_operand:DI 0 "register_operand" "=r")
15276 (minus:DI (const_int 63)
15277 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15278 (clobber (reg:CC FLAGS_REG))]
15280 "bsr{q}\t{%1, %0|%0, %1}"
15281 [(set_attr "prefix_0f" "1")
15282 (set_attr "mode" "DI")])
15284 (define_insn "popcountdi2"
15285 [(set (match_operand:DI 0 "register_operand" "=r")
15286 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15287 (clobber (reg:CC FLAGS_REG))]
15288 "TARGET_64BIT && TARGET_POPCNT"
15289 "popcnt{q}\t{%1, %0|%0, %1}"
15290 [(set_attr "prefix_rep" "1")
15291 (set_attr "type" "bitmanip")
15292 (set_attr "mode" "DI")])
15294 (define_insn "*popcountdi2_cmp"
15295 [(set (reg FLAGS_REG)
15297 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15299 (set (match_operand:DI 0 "register_operand" "=r")
15300 (popcount:DI (match_dup 1)))]
15301 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15302 "popcnt{q}\t{%1, %0|%0, %1}"
15303 [(set_attr "prefix_rep" "1")
15304 (set_attr "type" "bitmanip")
15305 (set_attr "mode" "DI")])
15307 (define_expand "clzhi2"
15309 [(set (match_operand:HI 0 "register_operand" "")
15310 (minus:HI (const_int 15)
15311 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15312 (clobber (reg:CC FLAGS_REG))])
15314 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15315 (clobber (reg:CC FLAGS_REG))])]
15320 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15325 (define_insn "clzhi2_abm"
15326 [(set (match_operand:HI 0 "register_operand" "=r")
15327 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15328 (clobber (reg:CC FLAGS_REG))]
15330 "lzcnt{w}\t{%1, %0|%0, %1}"
15331 [(set_attr "prefix_rep" "1")
15332 (set_attr "type" "bitmanip")
15333 (set_attr "mode" "HI")])
15335 (define_insn "*bsrhi"
15336 [(set (match_operand:HI 0 "register_operand" "=r")
15337 (minus:HI (const_int 15)
15338 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15339 (clobber (reg:CC FLAGS_REG))]
15341 "bsr{w}\t{%1, %0|%0, %1}"
15342 [(set_attr "prefix_0f" "1")
15343 (set_attr "mode" "HI")])
15345 (define_insn "popcounthi2"
15346 [(set (match_operand:HI 0 "register_operand" "=r")
15347 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15348 (clobber (reg:CC FLAGS_REG))]
15350 "popcnt{w}\t{%1, %0|%0, %1}"
15351 [(set_attr "prefix_rep" "1")
15352 (set_attr "type" "bitmanip")
15353 (set_attr "mode" "HI")])
15355 (define_insn "*popcounthi2_cmp"
15356 [(set (reg FLAGS_REG)
15358 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15360 (set (match_operand:HI 0 "register_operand" "=r")
15361 (popcount:HI (match_dup 1)))]
15362 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15363 "popcnt{w}\t{%1, %0|%0, %1}"
15364 [(set_attr "prefix_rep" "1")
15365 (set_attr "type" "bitmanip")
15366 (set_attr "mode" "HI")])
15368 (define_expand "paritydi2"
15369 [(set (match_operand:DI 0 "register_operand" "")
15370 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15373 rtx scratch = gen_reg_rtx (QImode);
15376 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15377 NULL_RTX, operands[1]));
15379 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15380 gen_rtx_REG (CCmode, FLAGS_REG),
15382 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15385 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15388 rtx tmp = gen_reg_rtx (SImode);
15390 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15391 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15396 (define_insn_and_split "paritydi2_cmp"
15397 [(set (reg:CC FLAGS_REG)
15398 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15399 (clobber (match_scratch:DI 0 "=r"))
15400 (clobber (match_scratch:SI 1 "=&r"))
15401 (clobber (match_scratch:HI 2 "=Q"))]
15404 "&& reload_completed"
15406 [(set (match_dup 1)
15407 (xor:SI (match_dup 1) (match_dup 4)))
15408 (clobber (reg:CC FLAGS_REG))])
15410 [(set (reg:CC FLAGS_REG)
15411 (parity:CC (match_dup 1)))
15412 (clobber (match_dup 1))
15413 (clobber (match_dup 2))])]
15415 operands[4] = gen_lowpart (SImode, operands[3]);
15419 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15420 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15423 operands[1] = gen_highpart (SImode, operands[3]);
15426 (define_expand "paritysi2"
15427 [(set (match_operand:SI 0 "register_operand" "")
15428 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15431 rtx scratch = gen_reg_rtx (QImode);
15434 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15436 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15437 gen_rtx_REG (CCmode, FLAGS_REG),
15439 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15441 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15445 (define_insn_and_split "paritysi2_cmp"
15446 [(set (reg:CC FLAGS_REG)
15447 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15448 (clobber (match_scratch:SI 0 "=r"))
15449 (clobber (match_scratch:HI 1 "=&Q"))]
15452 "&& reload_completed"
15454 [(set (match_dup 1)
15455 (xor:HI (match_dup 1) (match_dup 3)))
15456 (clobber (reg:CC FLAGS_REG))])
15458 [(set (reg:CC FLAGS_REG)
15459 (parity:CC (match_dup 1)))
15460 (clobber (match_dup 1))])]
15462 operands[3] = gen_lowpart (HImode, operands[2]);
15464 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15465 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15468 (define_insn "*parityhi2_cmp"
15469 [(set (reg:CC FLAGS_REG)
15470 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15471 (clobber (match_scratch:HI 0 "=Q"))]
15473 "xor{b}\t{%h0, %b0|%b0, %h0}"
15474 [(set_attr "length" "2")
15475 (set_attr "mode" "HI")])
15477 (define_insn "*parityqi2_cmp"
15478 [(set (reg:CC FLAGS_REG)
15479 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15482 [(set_attr "length" "2")
15483 (set_attr "mode" "QI")])
15485 ;; Thread-local storage patterns for ELF.
15487 ;; Note that these code sequences must appear exactly as shown
15488 ;; in order to allow linker relaxation.
15490 (define_insn "*tls_global_dynamic_32_gnu"
15491 [(set (match_operand:SI 0 "register_operand" "=a")
15492 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15493 (match_operand:SI 2 "tls_symbolic_operand" "")
15494 (match_operand:SI 3 "call_insn_operand" "")]
15496 (clobber (match_scratch:SI 4 "=d"))
15497 (clobber (match_scratch:SI 5 "=c"))
15498 (clobber (reg:CC FLAGS_REG))]
15499 "!TARGET_64BIT && TARGET_GNU_TLS"
15500 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15501 [(set_attr "type" "multi")
15502 (set_attr "length" "12")])
15504 (define_insn "*tls_global_dynamic_32_sun"
15505 [(set (match_operand:SI 0 "register_operand" "=a")
15506 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15507 (match_operand:SI 2 "tls_symbolic_operand" "")
15508 (match_operand:SI 3 "call_insn_operand" "")]
15510 (clobber (match_scratch:SI 4 "=d"))
15511 (clobber (match_scratch:SI 5 "=c"))
15512 (clobber (reg:CC FLAGS_REG))]
15513 "!TARGET_64BIT && TARGET_SUN_TLS"
15514 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15515 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15516 [(set_attr "type" "multi")
15517 (set_attr "length" "14")])
15519 (define_expand "tls_global_dynamic_32"
15520 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15523 (match_operand:SI 1 "tls_symbolic_operand" "")
15526 (clobber (match_scratch:SI 4 ""))
15527 (clobber (match_scratch:SI 5 ""))
15528 (clobber (reg:CC FLAGS_REG))])]
15532 operands[2] = pic_offset_table_rtx;
15535 operands[2] = gen_reg_rtx (Pmode);
15536 emit_insn (gen_set_got (operands[2]));
15538 if (TARGET_GNU2_TLS)
15540 emit_insn (gen_tls_dynamic_gnu2_32
15541 (operands[0], operands[1], operands[2]));
15544 operands[3] = ix86_tls_get_addr ();
15547 (define_insn "*tls_global_dynamic_64"
15548 [(set (match_operand:DI 0 "register_operand" "=a")
15549 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15550 (match_operand:DI 3 "" "")))
15551 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15554 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15555 [(set_attr "type" "multi")
15556 (set_attr "length" "16")])
15558 (define_expand "tls_global_dynamic_64"
15559 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15560 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15561 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15565 if (TARGET_GNU2_TLS)
15567 emit_insn (gen_tls_dynamic_gnu2_64
15568 (operands[0], operands[1]));
15571 operands[2] = ix86_tls_get_addr ();
15574 (define_insn "*tls_local_dynamic_base_32_gnu"
15575 [(set (match_operand:SI 0 "register_operand" "=a")
15576 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15577 (match_operand:SI 2 "call_insn_operand" "")]
15578 UNSPEC_TLS_LD_BASE))
15579 (clobber (match_scratch:SI 3 "=d"))
15580 (clobber (match_scratch:SI 4 "=c"))
15581 (clobber (reg:CC FLAGS_REG))]
15582 "!TARGET_64BIT && TARGET_GNU_TLS"
15583 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15584 [(set_attr "type" "multi")
15585 (set_attr "length" "11")])
15587 (define_insn "*tls_local_dynamic_base_32_sun"
15588 [(set (match_operand:SI 0 "register_operand" "=a")
15589 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15590 (match_operand:SI 2 "call_insn_operand" "")]
15591 UNSPEC_TLS_LD_BASE))
15592 (clobber (match_scratch:SI 3 "=d"))
15593 (clobber (match_scratch:SI 4 "=c"))
15594 (clobber (reg:CC FLAGS_REG))]
15595 "!TARGET_64BIT && TARGET_SUN_TLS"
15596 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15597 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15598 [(set_attr "type" "multi")
15599 (set_attr "length" "13")])
15601 (define_expand "tls_local_dynamic_base_32"
15602 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15603 (unspec:SI [(match_dup 1) (match_dup 2)]
15604 UNSPEC_TLS_LD_BASE))
15605 (clobber (match_scratch:SI 3 ""))
15606 (clobber (match_scratch:SI 4 ""))
15607 (clobber (reg:CC FLAGS_REG))])]
15611 operands[1] = pic_offset_table_rtx;
15614 operands[1] = gen_reg_rtx (Pmode);
15615 emit_insn (gen_set_got (operands[1]));
15617 if (TARGET_GNU2_TLS)
15619 emit_insn (gen_tls_dynamic_gnu2_32
15620 (operands[0], ix86_tls_module_base (), operands[1]));
15623 operands[2] = ix86_tls_get_addr ();
15626 (define_insn "*tls_local_dynamic_base_64"
15627 [(set (match_operand:DI 0 "register_operand" "=a")
15628 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15629 (match_operand:DI 2 "" "")))
15630 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15632 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15633 [(set_attr "type" "multi")
15634 (set_attr "length" "12")])
15636 (define_expand "tls_local_dynamic_base_64"
15637 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15638 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15639 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15642 if (TARGET_GNU2_TLS)
15644 emit_insn (gen_tls_dynamic_gnu2_64
15645 (operands[0], ix86_tls_module_base ()));
15648 operands[1] = ix86_tls_get_addr ();
15651 ;; Local dynamic of a single variable is a lose. Show combine how
15652 ;; to convert that back to global dynamic.
15654 (define_insn_and_split "*tls_local_dynamic_32_once"
15655 [(set (match_operand:SI 0 "register_operand" "=a")
15656 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15657 (match_operand:SI 2 "call_insn_operand" "")]
15658 UNSPEC_TLS_LD_BASE)
15659 (const:SI (unspec:SI
15660 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15662 (clobber (match_scratch:SI 4 "=d"))
15663 (clobber (match_scratch:SI 5 "=c"))
15664 (clobber (reg:CC FLAGS_REG))]
15668 [(parallel [(set (match_dup 0)
15669 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15671 (clobber (match_dup 4))
15672 (clobber (match_dup 5))
15673 (clobber (reg:CC FLAGS_REG))])]
15676 ;; Load and add the thread base pointer from %gs:0.
15678 (define_insn "*load_tp_si"
15679 [(set (match_operand:SI 0 "register_operand" "=r")
15680 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15682 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15683 [(set_attr "type" "imov")
15684 (set_attr "modrm" "0")
15685 (set_attr "length" "7")
15686 (set_attr "memory" "load")
15687 (set_attr "imm_disp" "false")])
15689 (define_insn "*add_tp_si"
15690 [(set (match_operand:SI 0 "register_operand" "=r")
15691 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15692 (match_operand:SI 1 "register_operand" "0")))
15693 (clobber (reg:CC FLAGS_REG))]
15695 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15696 [(set_attr "type" "alu")
15697 (set_attr "modrm" "0")
15698 (set_attr "length" "7")
15699 (set_attr "memory" "load")
15700 (set_attr "imm_disp" "false")])
15702 (define_insn "*load_tp_di"
15703 [(set (match_operand:DI 0 "register_operand" "=r")
15704 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15706 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15707 [(set_attr "type" "imov")
15708 (set_attr "modrm" "0")
15709 (set_attr "length" "7")
15710 (set_attr "memory" "load")
15711 (set_attr "imm_disp" "false")])
15713 (define_insn "*add_tp_di"
15714 [(set (match_operand:DI 0 "register_operand" "=r")
15715 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15716 (match_operand:DI 1 "register_operand" "0")))
15717 (clobber (reg:CC FLAGS_REG))]
15719 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15720 [(set_attr "type" "alu")
15721 (set_attr "modrm" "0")
15722 (set_attr "length" "7")
15723 (set_attr "memory" "load")
15724 (set_attr "imm_disp" "false")])
15726 ;; GNU2 TLS patterns can be split.
15728 (define_expand "tls_dynamic_gnu2_32"
15729 [(set (match_dup 3)
15730 (plus:SI (match_operand:SI 2 "register_operand" "")
15732 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15735 [(set (match_operand:SI 0 "register_operand" "")
15736 (unspec:SI [(match_dup 1) (match_dup 3)
15737 (match_dup 2) (reg:SI SP_REG)]
15739 (clobber (reg:CC FLAGS_REG))])]
15740 "!TARGET_64BIT && TARGET_GNU2_TLS"
15742 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15743 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15746 (define_insn "*tls_dynamic_lea_32"
15747 [(set (match_operand:SI 0 "register_operand" "=r")
15748 (plus:SI (match_operand:SI 1 "register_operand" "b")
15750 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15751 UNSPEC_TLSDESC))))]
15752 "!TARGET_64BIT && TARGET_GNU2_TLS"
15753 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15754 [(set_attr "type" "lea")
15755 (set_attr "mode" "SI")
15756 (set_attr "length" "6")
15757 (set_attr "length_address" "4")])
15759 (define_insn "*tls_dynamic_call_32"
15760 [(set (match_operand:SI 0 "register_operand" "=a")
15761 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15762 (match_operand:SI 2 "register_operand" "0")
15763 ;; we have to make sure %ebx still points to the GOT
15764 (match_operand:SI 3 "register_operand" "b")
15767 (clobber (reg:CC FLAGS_REG))]
15768 "!TARGET_64BIT && TARGET_GNU2_TLS"
15769 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15770 [(set_attr "type" "call")
15771 (set_attr "length" "2")
15772 (set_attr "length_address" "0")])
15774 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15775 [(set (match_operand:SI 0 "register_operand" "=&a")
15777 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15778 (match_operand:SI 4 "" "")
15779 (match_operand:SI 2 "register_operand" "b")
15782 (const:SI (unspec:SI
15783 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15785 (clobber (reg:CC FLAGS_REG))]
15786 "!TARGET_64BIT && TARGET_GNU2_TLS"
15789 [(set (match_dup 0) (match_dup 5))]
15791 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15792 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15795 (define_expand "tls_dynamic_gnu2_64"
15796 [(set (match_dup 2)
15797 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15800 [(set (match_operand:DI 0 "register_operand" "")
15801 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15803 (clobber (reg:CC FLAGS_REG))])]
15804 "TARGET_64BIT && TARGET_GNU2_TLS"
15806 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15807 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15810 (define_insn "*tls_dynamic_lea_64"
15811 [(set (match_operand:DI 0 "register_operand" "=r")
15812 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15814 "TARGET_64BIT && TARGET_GNU2_TLS"
15815 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15816 [(set_attr "type" "lea")
15817 (set_attr "mode" "DI")
15818 (set_attr "length" "7")
15819 (set_attr "length_address" "4")])
15821 (define_insn "*tls_dynamic_call_64"
15822 [(set (match_operand:DI 0 "register_operand" "=a")
15823 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15824 (match_operand:DI 2 "register_operand" "0")
15827 (clobber (reg:CC FLAGS_REG))]
15828 "TARGET_64BIT && TARGET_GNU2_TLS"
15829 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15830 [(set_attr "type" "call")
15831 (set_attr "length" "2")
15832 (set_attr "length_address" "0")])
15834 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15835 [(set (match_operand:DI 0 "register_operand" "=&a")
15837 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15838 (match_operand:DI 3 "" "")
15841 (const:DI (unspec:DI
15842 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15844 (clobber (reg:CC FLAGS_REG))]
15845 "TARGET_64BIT && TARGET_GNU2_TLS"
15848 [(set (match_dup 0) (match_dup 4))]
15850 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15851 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15856 ;; These patterns match the binary 387 instructions for addM3, subM3,
15857 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15858 ;; SFmode. The first is the normal insn, the second the same insn but
15859 ;; with one operand a conversion, and the third the same insn but with
15860 ;; the other operand a conversion. The conversion may be SFmode or
15861 ;; SImode if the target mode DFmode, but only SImode if the target mode
15864 ;; Gcc is slightly more smart about handling normal two address instructions
15865 ;; so use special patterns for add and mull.
15867 (define_insn "*fop_<mode>_comm_mixed"
15868 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15869 (match_operator:MODEF 3 "binary_fp_operator"
15870 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15871 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15872 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15873 && COMMUTATIVE_ARITH_P (operands[3])
15874 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15875 "* return output_387_binary_op (insn, operands);"
15876 [(set (attr "type")
15877 (if_then_else (eq_attr "alternative" "1")
15878 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15879 (const_string "ssemul")
15880 (const_string "sseadd"))
15881 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15882 (const_string "fmul")
15883 (const_string "fop"))))
15884 (set_attr "mode" "<MODE>")])
15886 (define_insn "*fop_<mode>_comm_sse"
15887 [(set (match_operand:MODEF 0 "register_operand" "=x")
15888 (match_operator:MODEF 3 "binary_fp_operator"
15889 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15890 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15891 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15892 && COMMUTATIVE_ARITH_P (operands[3])
15893 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15894 "* return output_387_binary_op (insn, operands);"
15895 [(set (attr "type")
15896 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15897 (const_string "ssemul")
15898 (const_string "sseadd")))
15899 (set_attr "mode" "<MODE>")])
15901 (define_insn "*fop_<mode>_comm_i387"
15902 [(set (match_operand:MODEF 0 "register_operand" "=f")
15903 (match_operator:MODEF 3 "binary_fp_operator"
15904 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15905 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15907 && COMMUTATIVE_ARITH_P (operands[3])
15908 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15909 "* return output_387_binary_op (insn, operands);"
15910 [(set (attr "type")
15911 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15912 (const_string "fmul")
15913 (const_string "fop")))
15914 (set_attr "mode" "<MODE>")])
15916 (define_insn "*fop_<mode>_1_mixed"
15917 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15918 (match_operator:MODEF 3 "binary_fp_operator"
15919 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
15920 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15921 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15922 && !COMMUTATIVE_ARITH_P (operands[3])
15923 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15924 "* return output_387_binary_op (insn, operands);"
15925 [(set (attr "type")
15926 (cond [(and (eq_attr "alternative" "2")
15927 (match_operand:MODEF 3 "mult_operator" ""))
15928 (const_string "ssemul")
15929 (and (eq_attr "alternative" "2")
15930 (match_operand:MODEF 3 "div_operator" ""))
15931 (const_string "ssediv")
15932 (eq_attr "alternative" "2")
15933 (const_string "sseadd")
15934 (match_operand:MODEF 3 "mult_operator" "")
15935 (const_string "fmul")
15936 (match_operand:MODEF 3 "div_operator" "")
15937 (const_string "fdiv")
15939 (const_string "fop")))
15940 (set_attr "mode" "<MODE>")])
15942 (define_insn "*rcpsf2_sse"
15943 [(set (match_operand:SF 0 "register_operand" "=x")
15944 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15947 "rcpss\t{%1, %0|%0, %1}"
15948 [(set_attr "type" "sse")
15949 (set_attr "mode" "SF")])
15951 (define_insn "*fop_<mode>_1_sse"
15952 [(set (match_operand:MODEF 0 "register_operand" "=x")
15953 (match_operator:MODEF 3 "binary_fp_operator"
15954 [(match_operand:MODEF 1 "register_operand" "0")
15955 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15956 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15957 && !COMMUTATIVE_ARITH_P (operands[3])"
15958 "* return output_387_binary_op (insn, operands);"
15959 [(set (attr "type")
15960 (cond [(match_operand:MODEF 3 "mult_operator" "")
15961 (const_string "ssemul")
15962 (match_operand:MODEF 3 "div_operator" "")
15963 (const_string "ssediv")
15965 (const_string "sseadd")))
15966 (set_attr "mode" "<MODE>")])
15968 ;; This pattern is not fully shadowed by the pattern above.
15969 (define_insn "*fop_<mode>_1_i387"
15970 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15971 (match_operator:MODEF 3 "binary_fp_operator"
15972 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15973 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15974 "TARGET_80387 && !TARGET_SSE_MATH
15975 && !COMMUTATIVE_ARITH_P (operands[3])
15976 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15977 "* return output_387_binary_op (insn, operands);"
15978 [(set (attr "type")
15979 (cond [(match_operand:MODEF 3 "mult_operator" "")
15980 (const_string "fmul")
15981 (match_operand:MODEF 3 "div_operator" "")
15982 (const_string "fdiv")
15984 (const_string "fop")))
15985 (set_attr "mode" "<MODE>")])
15987 ;; ??? Add SSE splitters for these!
15988 (define_insn "*fop_<MODEF:mode>_2_i387"
15989 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15990 (match_operator:MODEF 3 "binary_fp_operator"
15992 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15993 (match_operand:MODEF 2 "register_operand" "0,0")]))]
15994 "TARGET_80387 && !TARGET_SSE_MATH
15995 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
15996 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15997 [(set (attr "type")
15998 (cond [(match_operand:MODEF 3 "mult_operator" "")
15999 (const_string "fmul")
16000 (match_operand:MODEF 3 "div_operator" "")
16001 (const_string "fdiv")
16003 (const_string "fop")))
16004 (set_attr "fp_int_src" "true")
16005 (set_attr "mode" "<X87MODEI12:MODE>")])
16007 (define_insn "*fop_<MODEF:mode>_3_i387"
16008 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16009 (match_operator:MODEF 3 "binary_fp_operator"
16010 [(match_operand:MODEF 1 "register_operand" "0,0")
16012 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16013 "TARGET_80387 && !TARGET_SSE_MATH
16014 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16015 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16016 [(set (attr "type")
16017 (cond [(match_operand:MODEF 3 "mult_operator" "")
16018 (const_string "fmul")
16019 (match_operand:MODEF 3 "div_operator" "")
16020 (const_string "fdiv")
16022 (const_string "fop")))
16023 (set_attr "fp_int_src" "true")
16024 (set_attr "mode" "<MODE>")])
16026 (define_insn "*fop_df_4_i387"
16027 [(set (match_operand:DF 0 "register_operand" "=f,f")
16028 (match_operator:DF 3 "binary_fp_operator"
16030 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16031 (match_operand:DF 2 "register_operand" "0,f")]))]
16032 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16033 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16034 "* return output_387_binary_op (insn, operands);"
16035 [(set (attr "type")
16036 (cond [(match_operand:DF 3 "mult_operator" "")
16037 (const_string "fmul")
16038 (match_operand:DF 3 "div_operator" "")
16039 (const_string "fdiv")
16041 (const_string "fop")))
16042 (set_attr "mode" "SF")])
16044 (define_insn "*fop_df_5_i387"
16045 [(set (match_operand:DF 0 "register_operand" "=f,f")
16046 (match_operator:DF 3 "binary_fp_operator"
16047 [(match_operand:DF 1 "register_operand" "0,f")
16049 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16050 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16051 "* return output_387_binary_op (insn, operands);"
16052 [(set (attr "type")
16053 (cond [(match_operand:DF 3 "mult_operator" "")
16054 (const_string "fmul")
16055 (match_operand:DF 3 "div_operator" "")
16056 (const_string "fdiv")
16058 (const_string "fop")))
16059 (set_attr "mode" "SF")])
16061 (define_insn "*fop_df_6_i387"
16062 [(set (match_operand:DF 0 "register_operand" "=f,f")
16063 (match_operator:DF 3 "binary_fp_operator"
16065 (match_operand:SF 1 "register_operand" "0,f"))
16067 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16068 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16069 "* return output_387_binary_op (insn, operands);"
16070 [(set (attr "type")
16071 (cond [(match_operand:DF 3 "mult_operator" "")
16072 (const_string "fmul")
16073 (match_operand:DF 3 "div_operator" "")
16074 (const_string "fdiv")
16076 (const_string "fop")))
16077 (set_attr "mode" "SF")])
16079 (define_insn "*fop_xf_comm_i387"
16080 [(set (match_operand:XF 0 "register_operand" "=f")
16081 (match_operator:XF 3 "binary_fp_operator"
16082 [(match_operand:XF 1 "register_operand" "%0")
16083 (match_operand:XF 2 "register_operand" "f")]))]
16085 && COMMUTATIVE_ARITH_P (operands[3])"
16086 "* return output_387_binary_op (insn, operands);"
16087 [(set (attr "type")
16088 (if_then_else (match_operand:XF 3 "mult_operator" "")
16089 (const_string "fmul")
16090 (const_string "fop")))
16091 (set_attr "mode" "XF")])
16093 (define_insn "*fop_xf_1_i387"
16094 [(set (match_operand:XF 0 "register_operand" "=f,f")
16095 (match_operator:XF 3 "binary_fp_operator"
16096 [(match_operand:XF 1 "register_operand" "0,f")
16097 (match_operand:XF 2 "register_operand" "f,0")]))]
16099 && !COMMUTATIVE_ARITH_P (operands[3])"
16100 "* return output_387_binary_op (insn, operands);"
16101 [(set (attr "type")
16102 (cond [(match_operand:XF 3 "mult_operator" "")
16103 (const_string "fmul")
16104 (match_operand:XF 3 "div_operator" "")
16105 (const_string "fdiv")
16107 (const_string "fop")))
16108 (set_attr "mode" "XF")])
16110 (define_insn "*fop_xf_2_i387"
16111 [(set (match_operand:XF 0 "register_operand" "=f,f")
16112 (match_operator:XF 3 "binary_fp_operator"
16114 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16115 (match_operand:XF 2 "register_operand" "0,0")]))]
16116 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16117 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16118 [(set (attr "type")
16119 (cond [(match_operand:XF 3 "mult_operator" "")
16120 (const_string "fmul")
16121 (match_operand:XF 3 "div_operator" "")
16122 (const_string "fdiv")
16124 (const_string "fop")))
16125 (set_attr "fp_int_src" "true")
16126 (set_attr "mode" "<MODE>")])
16128 (define_insn "*fop_xf_3_i387"
16129 [(set (match_operand:XF 0 "register_operand" "=f,f")
16130 (match_operator:XF 3 "binary_fp_operator"
16131 [(match_operand:XF 1 "register_operand" "0,0")
16133 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16134 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16135 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16136 [(set (attr "type")
16137 (cond [(match_operand:XF 3 "mult_operator" "")
16138 (const_string "fmul")
16139 (match_operand:XF 3 "div_operator" "")
16140 (const_string "fdiv")
16142 (const_string "fop")))
16143 (set_attr "fp_int_src" "true")
16144 (set_attr "mode" "<MODE>")])
16146 (define_insn "*fop_xf_4_i387"
16147 [(set (match_operand:XF 0 "register_operand" "=f,f")
16148 (match_operator:XF 3 "binary_fp_operator"
16150 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16151 (match_operand:XF 2 "register_operand" "0,f")]))]
16153 "* return output_387_binary_op (insn, operands);"
16154 [(set (attr "type")
16155 (cond [(match_operand:XF 3 "mult_operator" "")
16156 (const_string "fmul")
16157 (match_operand:XF 3 "div_operator" "")
16158 (const_string "fdiv")
16160 (const_string "fop")))
16161 (set_attr "mode" "<MODE>")])
16163 (define_insn "*fop_xf_5_i387"
16164 [(set (match_operand:XF 0 "register_operand" "=f,f")
16165 (match_operator:XF 3 "binary_fp_operator"
16166 [(match_operand:XF 1 "register_operand" "0,f")
16168 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16170 "* return output_387_binary_op (insn, operands);"
16171 [(set (attr "type")
16172 (cond [(match_operand:XF 3 "mult_operator" "")
16173 (const_string "fmul")
16174 (match_operand:XF 3 "div_operator" "")
16175 (const_string "fdiv")
16177 (const_string "fop")))
16178 (set_attr "mode" "<MODE>")])
16180 (define_insn "*fop_xf_6_i387"
16181 [(set (match_operand:XF 0 "register_operand" "=f,f")
16182 (match_operator:XF 3 "binary_fp_operator"
16184 (match_operand:MODEF 1 "register_operand" "0,f"))
16186 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16188 "* return output_387_binary_op (insn, operands);"
16189 [(set (attr "type")
16190 (cond [(match_operand:XF 3 "mult_operator" "")
16191 (const_string "fmul")
16192 (match_operand:XF 3 "div_operator" "")
16193 (const_string "fdiv")
16195 (const_string "fop")))
16196 (set_attr "mode" "<MODE>")])
16199 [(set (match_operand 0 "register_operand" "")
16200 (match_operator 3 "binary_fp_operator"
16201 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16202 (match_operand 2 "register_operand" "")]))]
16204 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16207 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16208 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16209 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16210 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16211 GET_MODE (operands[3]),
16214 ix86_free_from_memory (GET_MODE (operands[1]));
16219 [(set (match_operand 0 "register_operand" "")
16220 (match_operator 3 "binary_fp_operator"
16221 [(match_operand 1 "register_operand" "")
16222 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16224 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16227 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16228 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16229 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16230 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16231 GET_MODE (operands[3]),
16234 ix86_free_from_memory (GET_MODE (operands[2]));
16238 ;; FPU special functions.
16240 ;; This pattern implements a no-op XFmode truncation for
16241 ;; all fancy i386 XFmode math functions.
16243 (define_insn "truncxf<mode>2_i387_noop_unspec"
16244 [(set (match_operand:MODEF 0 "register_operand" "=f")
16245 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16246 UNSPEC_TRUNC_NOOP))]
16247 "TARGET_USE_FANCY_MATH_387"
16248 "* return output_387_reg_move (insn, operands);"
16249 [(set_attr "type" "fmov")
16250 (set_attr "mode" "<MODE>")])
16252 (define_insn "sqrtxf2"
16253 [(set (match_operand:XF 0 "register_operand" "=f")
16254 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16255 "TARGET_USE_FANCY_MATH_387"
16257 [(set_attr "type" "fpspc")
16258 (set_attr "mode" "XF")
16259 (set_attr "athlon_decode" "direct")
16260 (set_attr "amdfam10_decode" "direct")])
16262 (define_insn "sqrt_extend<mode>xf2_i387"
16263 [(set (match_operand:XF 0 "register_operand" "=f")
16266 (match_operand:MODEF 1 "register_operand" "0"))))]
16267 "TARGET_USE_FANCY_MATH_387"
16269 [(set_attr "type" "fpspc")
16270 (set_attr "mode" "XF")
16271 (set_attr "athlon_decode" "direct")
16272 (set_attr "amdfam10_decode" "direct")])
16274 (define_insn "*rsqrtsf2_sse"
16275 [(set (match_operand:SF 0 "register_operand" "=x")
16276 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16279 "rsqrtss\t{%1, %0|%0, %1}"
16280 [(set_attr "type" "sse")
16281 (set_attr "mode" "SF")])
16283 (define_expand "rsqrtsf2"
16284 [(set (match_operand:SF 0 "register_operand" "")
16285 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16289 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16293 (define_insn "*sqrt<mode>2_sse"
16294 [(set (match_operand:MODEF 0 "register_operand" "=x")
16296 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16297 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16298 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16299 [(set_attr "type" "sse")
16300 (set_attr "mode" "<MODE>")
16301 (set_attr "athlon_decode" "*")
16302 (set_attr "amdfam10_decode" "*")])
16304 (define_expand "sqrt<mode>2"
16305 [(set (match_operand:MODEF 0 "register_operand" "")
16307 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16308 "TARGET_USE_FANCY_MATH_387
16309 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16311 if (<MODE>mode == SFmode
16312 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16313 && flag_finite_math_only && !flag_trapping_math
16314 && flag_unsafe_math_optimizations)
16316 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16320 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16322 rtx op0 = gen_reg_rtx (XFmode);
16323 rtx op1 = force_reg (<MODE>mode, operands[1]);
16325 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16326 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16331 (define_insn "fpremxf4_i387"
16332 [(set (match_operand:XF 0 "register_operand" "=f")
16333 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16334 (match_operand:XF 3 "register_operand" "1")]
16336 (set (match_operand:XF 1 "register_operand" "=u")
16337 (unspec:XF [(match_dup 2) (match_dup 3)]
16339 (set (reg:CCFP FPSR_REG)
16340 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16342 "TARGET_USE_FANCY_MATH_387"
16344 [(set_attr "type" "fpspc")
16345 (set_attr "mode" "XF")])
16347 (define_expand "fmodxf3"
16348 [(use (match_operand:XF 0 "register_operand" ""))
16349 (use (match_operand:XF 1 "general_operand" ""))
16350 (use (match_operand:XF 2 "general_operand" ""))]
16351 "TARGET_USE_FANCY_MATH_387"
16353 rtx label = gen_label_rtx ();
16355 rtx op1 = gen_reg_rtx (XFmode);
16356 rtx op2 = gen_reg_rtx (XFmode);
16358 emit_move_insn (op1, operands[1]);
16359 emit_move_insn (op2, operands[2]);
16361 emit_label (label);
16362 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16363 ix86_emit_fp_unordered_jump (label);
16364 LABEL_NUSES (label) = 1;
16366 emit_move_insn (operands[0], op1);
16370 (define_expand "fmod<mode>3"
16371 [(use (match_operand:MODEF 0 "register_operand" ""))
16372 (use (match_operand:MODEF 1 "general_operand" ""))
16373 (use (match_operand:MODEF 2 "general_operand" ""))]
16374 "TARGET_USE_FANCY_MATH_387"
16376 rtx label = gen_label_rtx ();
16378 rtx op1 = gen_reg_rtx (XFmode);
16379 rtx op2 = gen_reg_rtx (XFmode);
16381 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16382 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16384 emit_label (label);
16385 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16386 ix86_emit_fp_unordered_jump (label);
16387 LABEL_NUSES (label) = 1;
16389 /* Truncate the result properly for strict SSE math. */
16390 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16391 && !TARGET_MIX_SSE_I387)
16392 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16394 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16399 (define_insn "fprem1xf4_i387"
16400 [(set (match_operand:XF 0 "register_operand" "=f")
16401 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16402 (match_operand:XF 3 "register_operand" "1")]
16404 (set (match_operand:XF 1 "register_operand" "=u")
16405 (unspec:XF [(match_dup 2) (match_dup 3)]
16407 (set (reg:CCFP FPSR_REG)
16408 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16410 "TARGET_USE_FANCY_MATH_387"
16412 [(set_attr "type" "fpspc")
16413 (set_attr "mode" "XF")])
16415 (define_expand "remainderxf3"
16416 [(use (match_operand:XF 0 "register_operand" ""))
16417 (use (match_operand:XF 1 "general_operand" ""))
16418 (use (match_operand:XF 2 "general_operand" ""))]
16419 "TARGET_USE_FANCY_MATH_387"
16421 rtx label = gen_label_rtx ();
16423 rtx op1 = gen_reg_rtx (XFmode);
16424 rtx op2 = gen_reg_rtx (XFmode);
16426 emit_move_insn (op1, operands[1]);
16427 emit_move_insn (op2, operands[2]);
16429 emit_label (label);
16430 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16431 ix86_emit_fp_unordered_jump (label);
16432 LABEL_NUSES (label) = 1;
16434 emit_move_insn (operands[0], op1);
16438 (define_expand "remainder<mode>3"
16439 [(use (match_operand:MODEF 0 "register_operand" ""))
16440 (use (match_operand:MODEF 1 "general_operand" ""))
16441 (use (match_operand:MODEF 2 "general_operand" ""))]
16442 "TARGET_USE_FANCY_MATH_387"
16444 rtx label = gen_label_rtx ();
16446 rtx op1 = gen_reg_rtx (XFmode);
16447 rtx op2 = gen_reg_rtx (XFmode);
16449 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16450 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16452 emit_label (label);
16454 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16455 ix86_emit_fp_unordered_jump (label);
16456 LABEL_NUSES (label) = 1;
16458 /* Truncate the result properly for strict SSE math. */
16459 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16460 && !TARGET_MIX_SSE_I387)
16461 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16463 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16468 (define_insn "*sinxf2_i387"
16469 [(set (match_operand:XF 0 "register_operand" "=f")
16470 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16471 "TARGET_USE_FANCY_MATH_387
16472 && flag_unsafe_math_optimizations"
16474 [(set_attr "type" "fpspc")
16475 (set_attr "mode" "XF")])
16477 (define_insn "*sin_extend<mode>xf2_i387"
16478 [(set (match_operand:XF 0 "register_operand" "=f")
16479 (unspec:XF [(float_extend:XF
16480 (match_operand:MODEF 1 "register_operand" "0"))]
16482 "TARGET_USE_FANCY_MATH_387
16483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16484 || TARGET_MIX_SSE_I387)
16485 && flag_unsafe_math_optimizations"
16487 [(set_attr "type" "fpspc")
16488 (set_attr "mode" "XF")])
16490 (define_insn "*cosxf2_i387"
16491 [(set (match_operand:XF 0 "register_operand" "=f")
16492 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16493 "TARGET_USE_FANCY_MATH_387
16494 && flag_unsafe_math_optimizations"
16496 [(set_attr "type" "fpspc")
16497 (set_attr "mode" "XF")])
16499 (define_insn "*cos_extend<mode>xf2_i387"
16500 [(set (match_operand:XF 0 "register_operand" "=f")
16501 (unspec:XF [(float_extend:XF
16502 (match_operand:MODEF 1 "register_operand" "0"))]
16504 "TARGET_USE_FANCY_MATH_387
16505 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16506 || TARGET_MIX_SSE_I387)
16507 && flag_unsafe_math_optimizations"
16509 [(set_attr "type" "fpspc")
16510 (set_attr "mode" "XF")])
16512 ;; When sincos pattern is defined, sin and cos builtin functions will be
16513 ;; expanded to sincos pattern with one of its outputs left unused.
16514 ;; CSE pass will figure out if two sincos patterns can be combined,
16515 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16516 ;; depending on the unused output.
16518 (define_insn "sincosxf3"
16519 [(set (match_operand:XF 0 "register_operand" "=f")
16520 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16521 UNSPEC_SINCOS_COS))
16522 (set (match_operand:XF 1 "register_operand" "=u")
16523 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16524 "TARGET_USE_FANCY_MATH_387
16525 && flag_unsafe_math_optimizations"
16527 [(set_attr "type" "fpspc")
16528 (set_attr "mode" "XF")])
16531 [(set (match_operand:XF 0 "register_operand" "")
16532 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16533 UNSPEC_SINCOS_COS))
16534 (set (match_operand:XF 1 "register_operand" "")
16535 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16536 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16537 && !(reload_completed || reload_in_progress)"
16538 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16542 [(set (match_operand:XF 0 "register_operand" "")
16543 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16544 UNSPEC_SINCOS_COS))
16545 (set (match_operand:XF 1 "register_operand" "")
16546 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16547 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16548 && !(reload_completed || reload_in_progress)"
16549 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16552 (define_insn "sincos_extend<mode>xf3_i387"
16553 [(set (match_operand:XF 0 "register_operand" "=f")
16554 (unspec:XF [(float_extend:XF
16555 (match_operand:MODEF 2 "register_operand" "0"))]
16556 UNSPEC_SINCOS_COS))
16557 (set (match_operand:XF 1 "register_operand" "=u")
16558 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16559 "TARGET_USE_FANCY_MATH_387
16560 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16561 || TARGET_MIX_SSE_I387)
16562 && flag_unsafe_math_optimizations"
16564 [(set_attr "type" "fpspc")
16565 (set_attr "mode" "XF")])
16568 [(set (match_operand:XF 0 "register_operand" "")
16569 (unspec:XF [(float_extend:XF
16570 (match_operand:MODEF 2 "register_operand" ""))]
16571 UNSPEC_SINCOS_COS))
16572 (set (match_operand:XF 1 "register_operand" "")
16573 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16574 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16575 && !(reload_completed || reload_in_progress)"
16576 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16580 [(set (match_operand:XF 0 "register_operand" "")
16581 (unspec:XF [(float_extend:XF
16582 (match_operand:MODEF 2 "register_operand" ""))]
16583 UNSPEC_SINCOS_COS))
16584 (set (match_operand:XF 1 "register_operand" "")
16585 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16586 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16587 && !(reload_completed || reload_in_progress)"
16588 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16591 (define_expand "sincos<mode>3"
16592 [(use (match_operand:MODEF 0 "register_operand" ""))
16593 (use (match_operand:MODEF 1 "register_operand" ""))
16594 (use (match_operand:MODEF 2 "register_operand" ""))]
16595 "TARGET_USE_FANCY_MATH_387
16596 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16597 || TARGET_MIX_SSE_I387)
16598 && flag_unsafe_math_optimizations"
16600 rtx op0 = gen_reg_rtx (XFmode);
16601 rtx op1 = gen_reg_rtx (XFmode);
16603 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16604 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16605 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16609 (define_insn "fptanxf4_i387"
16610 [(set (match_operand:XF 0 "register_operand" "=f")
16611 (match_operand:XF 3 "const_double_operand" "F"))
16612 (set (match_operand:XF 1 "register_operand" "=u")
16613 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16615 "TARGET_USE_FANCY_MATH_387
16616 && flag_unsafe_math_optimizations
16617 && standard_80387_constant_p (operands[3]) == 2"
16619 [(set_attr "type" "fpspc")
16620 (set_attr "mode" "XF")])
16622 (define_insn "fptan_extend<mode>xf4_i387"
16623 [(set (match_operand:MODEF 0 "register_operand" "=f")
16624 (match_operand:MODEF 3 "const_double_operand" "F"))
16625 (set (match_operand:XF 1 "register_operand" "=u")
16626 (unspec:XF [(float_extend:XF
16627 (match_operand:MODEF 2 "register_operand" "0"))]
16629 "TARGET_USE_FANCY_MATH_387
16630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16631 || TARGET_MIX_SSE_I387)
16632 && flag_unsafe_math_optimizations
16633 && standard_80387_constant_p (operands[3]) == 2"
16635 [(set_attr "type" "fpspc")
16636 (set_attr "mode" "XF")])
16638 (define_expand "tanxf2"
16639 [(use (match_operand:XF 0 "register_operand" ""))
16640 (use (match_operand:XF 1 "register_operand" ""))]
16641 "TARGET_USE_FANCY_MATH_387
16642 && flag_unsafe_math_optimizations"
16644 rtx one = gen_reg_rtx (XFmode);
16645 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16647 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16651 (define_expand "tan<mode>2"
16652 [(use (match_operand:MODEF 0 "register_operand" ""))
16653 (use (match_operand:MODEF 1 "register_operand" ""))]
16654 "TARGET_USE_FANCY_MATH_387
16655 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16656 || TARGET_MIX_SSE_I387)
16657 && flag_unsafe_math_optimizations"
16659 rtx op0 = gen_reg_rtx (XFmode);
16661 rtx one = gen_reg_rtx (<MODE>mode);
16662 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16664 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16665 operands[1], op2));
16666 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16670 (define_insn "*fpatanxf3_i387"
16671 [(set (match_operand:XF 0 "register_operand" "=f")
16672 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16673 (match_operand:XF 2 "register_operand" "u")]
16675 (clobber (match_scratch:XF 3 "=2"))]
16676 "TARGET_USE_FANCY_MATH_387
16677 && flag_unsafe_math_optimizations"
16679 [(set_attr "type" "fpspc")
16680 (set_attr "mode" "XF")])
16682 (define_insn "fpatan_extend<mode>xf3_i387"
16683 [(set (match_operand:XF 0 "register_operand" "=f")
16684 (unspec:XF [(float_extend:XF
16685 (match_operand:MODEF 1 "register_operand" "0"))
16687 (match_operand:MODEF 2 "register_operand" "u"))]
16689 (clobber (match_scratch:XF 3 "=2"))]
16690 "TARGET_USE_FANCY_MATH_387
16691 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16692 || TARGET_MIX_SSE_I387)
16693 && flag_unsafe_math_optimizations"
16695 [(set_attr "type" "fpspc")
16696 (set_attr "mode" "XF")])
16698 (define_expand "atan2xf3"
16699 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16700 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16701 (match_operand:XF 1 "register_operand" "")]
16703 (clobber (match_scratch:XF 3 ""))])]
16704 "TARGET_USE_FANCY_MATH_387
16705 && flag_unsafe_math_optimizations"
16708 (define_expand "atan2<mode>3"
16709 [(use (match_operand:MODEF 0 "register_operand" ""))
16710 (use (match_operand:MODEF 1 "register_operand" ""))
16711 (use (match_operand:MODEF 2 "register_operand" ""))]
16712 "TARGET_USE_FANCY_MATH_387
16713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16714 || TARGET_MIX_SSE_I387)
16715 && flag_unsafe_math_optimizations"
16717 rtx op0 = gen_reg_rtx (XFmode);
16719 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16720 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16724 (define_expand "atanxf2"
16725 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16726 (unspec:XF [(match_dup 2)
16727 (match_operand:XF 1 "register_operand" "")]
16729 (clobber (match_scratch:XF 3 ""))])]
16730 "TARGET_USE_FANCY_MATH_387
16731 && flag_unsafe_math_optimizations"
16733 operands[2] = gen_reg_rtx (XFmode);
16734 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16737 (define_expand "atan<mode>2"
16738 [(use (match_operand:MODEF 0 "register_operand" ""))
16739 (use (match_operand:MODEF 1 "register_operand" ""))]
16740 "TARGET_USE_FANCY_MATH_387
16741 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16742 || TARGET_MIX_SSE_I387)
16743 && flag_unsafe_math_optimizations"
16745 rtx op0 = gen_reg_rtx (XFmode);
16747 rtx op2 = gen_reg_rtx (<MODE>mode);
16748 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16750 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16751 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16755 (define_expand "asinxf2"
16756 [(set (match_dup 2)
16757 (mult:XF (match_operand:XF 1 "register_operand" "")
16759 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16760 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16761 (parallel [(set (match_operand:XF 0 "register_operand" "")
16762 (unspec:XF [(match_dup 5) (match_dup 1)]
16764 (clobber (match_scratch:XF 6 ""))])]
16765 "TARGET_USE_FANCY_MATH_387
16766 && flag_unsafe_math_optimizations && !optimize_size"
16770 for (i = 2; i < 6; i++)
16771 operands[i] = gen_reg_rtx (XFmode);
16773 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16776 (define_expand "asin<mode>2"
16777 [(use (match_operand:MODEF 0 "register_operand" ""))
16778 (use (match_operand:MODEF 1 "general_operand" ""))]
16779 "TARGET_USE_FANCY_MATH_387
16780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16781 || TARGET_MIX_SSE_I387)
16782 && flag_unsafe_math_optimizations && !optimize_size"
16784 rtx op0 = gen_reg_rtx (XFmode);
16785 rtx op1 = gen_reg_rtx (XFmode);
16787 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16788 emit_insn (gen_asinxf2 (op0, op1));
16789 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16793 (define_expand "acosxf2"
16794 [(set (match_dup 2)
16795 (mult:XF (match_operand:XF 1 "register_operand" "")
16797 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16798 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16799 (parallel [(set (match_operand:XF 0 "register_operand" "")
16800 (unspec:XF [(match_dup 1) (match_dup 5)]
16802 (clobber (match_scratch:XF 6 ""))])]
16803 "TARGET_USE_FANCY_MATH_387
16804 && flag_unsafe_math_optimizations && !optimize_size"
16808 for (i = 2; i < 6; i++)
16809 operands[i] = gen_reg_rtx (XFmode);
16811 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16814 (define_expand "acos<mode>2"
16815 [(use (match_operand:MODEF 0 "register_operand" ""))
16816 (use (match_operand:MODEF 1 "general_operand" ""))]
16817 "TARGET_USE_FANCY_MATH_387
16818 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16819 || TARGET_MIX_SSE_I387)
16820 && flag_unsafe_math_optimizations && !optimize_size"
16822 rtx op0 = gen_reg_rtx (XFmode);
16823 rtx op1 = gen_reg_rtx (XFmode);
16825 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16826 emit_insn (gen_acosxf2 (op0, op1));
16827 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16831 (define_insn "fyl2xxf3_i387"
16832 [(set (match_operand:XF 0 "register_operand" "=f")
16833 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16834 (match_operand:XF 2 "register_operand" "u")]
16836 (clobber (match_scratch:XF 3 "=2"))]
16837 "TARGET_USE_FANCY_MATH_387
16838 && flag_unsafe_math_optimizations"
16840 [(set_attr "type" "fpspc")
16841 (set_attr "mode" "XF")])
16843 (define_insn "fyl2x_extend<mode>xf3_i387"
16844 [(set (match_operand:XF 0 "register_operand" "=f")
16845 (unspec:XF [(float_extend:XF
16846 (match_operand:MODEF 1 "register_operand" "0"))
16847 (match_operand:XF 2 "register_operand" "u")]
16849 (clobber (match_scratch:XF 3 "=2"))]
16850 "TARGET_USE_FANCY_MATH_387
16851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16852 || TARGET_MIX_SSE_I387)
16853 && flag_unsafe_math_optimizations"
16855 [(set_attr "type" "fpspc")
16856 (set_attr "mode" "XF")])
16858 (define_expand "logxf2"
16859 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16860 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16861 (match_dup 2)] UNSPEC_FYL2X))
16862 (clobber (match_scratch:XF 3 ""))])]
16863 "TARGET_USE_FANCY_MATH_387
16864 && flag_unsafe_math_optimizations"
16866 operands[2] = gen_reg_rtx (XFmode);
16867 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16870 (define_expand "log<mode>2"
16871 [(use (match_operand:MODEF 0 "register_operand" ""))
16872 (use (match_operand:MODEF 1 "register_operand" ""))]
16873 "TARGET_USE_FANCY_MATH_387
16874 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16875 || TARGET_MIX_SSE_I387)
16876 && flag_unsafe_math_optimizations"
16878 rtx op0 = gen_reg_rtx (XFmode);
16880 rtx op2 = gen_reg_rtx (XFmode);
16881 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16883 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16884 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16888 (define_expand "log10xf2"
16889 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16890 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16891 (match_dup 2)] UNSPEC_FYL2X))
16892 (clobber (match_scratch:XF 3 ""))])]
16893 "TARGET_USE_FANCY_MATH_387
16894 && flag_unsafe_math_optimizations"
16896 operands[2] = gen_reg_rtx (XFmode);
16897 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16900 (define_expand "log10<mode>2"
16901 [(use (match_operand:MODEF 0 "register_operand" ""))
16902 (use (match_operand:MODEF 1 "register_operand" ""))]
16903 "TARGET_USE_FANCY_MATH_387
16904 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16905 || TARGET_MIX_SSE_I387)
16906 && flag_unsafe_math_optimizations"
16908 rtx op0 = gen_reg_rtx (XFmode);
16910 rtx op2 = gen_reg_rtx (XFmode);
16911 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16913 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16914 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16918 (define_expand "log2xf2"
16919 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16920 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16921 (match_dup 2)] UNSPEC_FYL2X))
16922 (clobber (match_scratch:XF 3 ""))])]
16923 "TARGET_USE_FANCY_MATH_387
16924 && flag_unsafe_math_optimizations"
16926 operands[2] = gen_reg_rtx (XFmode);
16927 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16930 (define_expand "log2<mode>2"
16931 [(use (match_operand:MODEF 0 "register_operand" ""))
16932 (use (match_operand:MODEF 1 "register_operand" ""))]
16933 "TARGET_USE_FANCY_MATH_387
16934 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16935 || TARGET_MIX_SSE_I387)
16936 && flag_unsafe_math_optimizations"
16938 rtx op0 = gen_reg_rtx (XFmode);
16940 rtx op2 = gen_reg_rtx (XFmode);
16941 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16943 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16944 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16948 (define_insn "fyl2xp1xf3_i387"
16949 [(set (match_operand:XF 0 "register_operand" "=f")
16950 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16951 (match_operand:XF 2 "register_operand" "u")]
16953 (clobber (match_scratch:XF 3 "=2"))]
16954 "TARGET_USE_FANCY_MATH_387
16955 && flag_unsafe_math_optimizations"
16957 [(set_attr "type" "fpspc")
16958 (set_attr "mode" "XF")])
16960 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16961 [(set (match_operand:XF 0 "register_operand" "=f")
16962 (unspec:XF [(float_extend:XF
16963 (match_operand:MODEF 1 "register_operand" "0"))
16964 (match_operand:XF 2 "register_operand" "u")]
16966 (clobber (match_scratch:XF 3 "=2"))]
16967 "TARGET_USE_FANCY_MATH_387
16968 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16969 || TARGET_MIX_SSE_I387)
16970 && flag_unsafe_math_optimizations"
16972 [(set_attr "type" "fpspc")
16973 (set_attr "mode" "XF")])
16975 (define_expand "log1pxf2"
16976 [(use (match_operand:XF 0 "register_operand" ""))
16977 (use (match_operand:XF 1 "register_operand" ""))]
16978 "TARGET_USE_FANCY_MATH_387
16979 && flag_unsafe_math_optimizations && !optimize_size"
16981 ix86_emit_i387_log1p (operands[0], operands[1]);
16985 (define_expand "log1p<mode>2"
16986 [(use (match_operand:MODEF 0 "register_operand" ""))
16987 (use (match_operand:MODEF 1 "register_operand" ""))]
16988 "TARGET_USE_FANCY_MATH_387
16989 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16990 || TARGET_MIX_SSE_I387)
16991 && flag_unsafe_math_optimizations && !optimize_size"
16993 rtx op0 = gen_reg_rtx (XFmode);
16995 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16997 ix86_emit_i387_log1p (op0, operands[1]);
16998 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17002 (define_insn "fxtractxf3_i387"
17003 [(set (match_operand:XF 0 "register_operand" "=f")
17004 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17005 UNSPEC_XTRACT_FRACT))
17006 (set (match_operand:XF 1 "register_operand" "=u")
17007 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17008 "TARGET_USE_FANCY_MATH_387
17009 && flag_unsafe_math_optimizations"
17011 [(set_attr "type" "fpspc")
17012 (set_attr "mode" "XF")])
17014 (define_insn "fxtract_extend<mode>xf3_i387"
17015 [(set (match_operand:XF 0 "register_operand" "=f")
17016 (unspec:XF [(float_extend:XF
17017 (match_operand:MODEF 2 "register_operand" "0"))]
17018 UNSPEC_XTRACT_FRACT))
17019 (set (match_operand:XF 1 "register_operand" "=u")
17020 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17021 "TARGET_USE_FANCY_MATH_387
17022 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17023 || TARGET_MIX_SSE_I387)
17024 && flag_unsafe_math_optimizations"
17026 [(set_attr "type" "fpspc")
17027 (set_attr "mode" "XF")])
17029 (define_expand "logbxf2"
17030 [(parallel [(set (match_dup 2)
17031 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17032 UNSPEC_XTRACT_FRACT))
17033 (set (match_operand:XF 0 "register_operand" "")
17034 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17035 "TARGET_USE_FANCY_MATH_387
17036 && flag_unsafe_math_optimizations"
17038 operands[2] = gen_reg_rtx (XFmode);
17041 (define_expand "logb<mode>2"
17042 [(use (match_operand:MODEF 0 "register_operand" ""))
17043 (use (match_operand:MODEF 1 "register_operand" ""))]
17044 "TARGET_USE_FANCY_MATH_387
17045 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17046 || TARGET_MIX_SSE_I387)
17047 && flag_unsafe_math_optimizations"
17049 rtx op0 = gen_reg_rtx (XFmode);
17050 rtx op1 = gen_reg_rtx (XFmode);
17052 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17053 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17057 (define_expand "ilogbxf2"
17058 [(use (match_operand:SI 0 "register_operand" ""))
17059 (use (match_operand:XF 1 "register_operand" ""))]
17060 "TARGET_USE_FANCY_MATH_387
17061 && flag_unsafe_math_optimizations && !optimize_size"
17063 rtx op0 = gen_reg_rtx (XFmode);
17064 rtx op1 = gen_reg_rtx (XFmode);
17066 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17067 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17071 (define_expand "ilogb<mode>2"
17072 [(use (match_operand:SI 0 "register_operand" ""))
17073 (use (match_operand:MODEF 1 "register_operand" ""))]
17074 "TARGET_USE_FANCY_MATH_387
17075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17076 || TARGET_MIX_SSE_I387)
17077 && flag_unsafe_math_optimizations && !optimize_size"
17079 rtx op0 = gen_reg_rtx (XFmode);
17080 rtx op1 = gen_reg_rtx (XFmode);
17082 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17083 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17087 (define_insn "*f2xm1xf2_i387"
17088 [(set (match_operand:XF 0 "register_operand" "=f")
17089 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17091 "TARGET_USE_FANCY_MATH_387
17092 && flag_unsafe_math_optimizations"
17094 [(set_attr "type" "fpspc")
17095 (set_attr "mode" "XF")])
17097 (define_insn "*fscalexf4_i387"
17098 [(set (match_operand:XF 0 "register_operand" "=f")
17099 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17100 (match_operand:XF 3 "register_operand" "1")]
17101 UNSPEC_FSCALE_FRACT))
17102 (set (match_operand:XF 1 "register_operand" "=u")
17103 (unspec:XF [(match_dup 2) (match_dup 3)]
17104 UNSPEC_FSCALE_EXP))]
17105 "TARGET_USE_FANCY_MATH_387
17106 && flag_unsafe_math_optimizations"
17108 [(set_attr "type" "fpspc")
17109 (set_attr "mode" "XF")])
17111 (define_expand "expNcorexf3"
17112 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17113 (match_operand:XF 2 "register_operand" "")))
17114 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17115 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17116 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17117 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17118 (parallel [(set (match_operand:XF 0 "register_operand" "")
17119 (unspec:XF [(match_dup 8) (match_dup 4)]
17120 UNSPEC_FSCALE_FRACT))
17122 (unspec:XF [(match_dup 8) (match_dup 4)]
17123 UNSPEC_FSCALE_EXP))])]
17124 "TARGET_USE_FANCY_MATH_387
17125 && flag_unsafe_math_optimizations && !optimize_size"
17129 for (i = 3; i < 10; i++)
17130 operands[i] = gen_reg_rtx (XFmode);
17132 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17135 (define_expand "expxf2"
17136 [(use (match_operand:XF 0 "register_operand" ""))
17137 (use (match_operand:XF 1 "register_operand" ""))]
17138 "TARGET_USE_FANCY_MATH_387
17139 && flag_unsafe_math_optimizations && !optimize_size"
17141 rtx op2 = gen_reg_rtx (XFmode);
17142 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17144 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17148 (define_expand "exp<mode>2"
17149 [(use (match_operand:MODEF 0 "register_operand" ""))
17150 (use (match_operand:MODEF 1 "general_operand" ""))]
17151 "TARGET_USE_FANCY_MATH_387
17152 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17153 || TARGET_MIX_SSE_I387)
17154 && flag_unsafe_math_optimizations && !optimize_size"
17156 rtx op0 = gen_reg_rtx (XFmode);
17157 rtx op1 = gen_reg_rtx (XFmode);
17159 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17160 emit_insn (gen_expxf2 (op0, op1));
17161 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17165 (define_expand "exp10xf2"
17166 [(use (match_operand:XF 0 "register_operand" ""))
17167 (use (match_operand:XF 1 "register_operand" ""))]
17168 "TARGET_USE_FANCY_MATH_387
17169 && flag_unsafe_math_optimizations && !optimize_size"
17171 rtx op2 = gen_reg_rtx (XFmode);
17172 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17174 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17178 (define_expand "exp10<mode>2"
17179 [(use (match_operand:MODEF 0 "register_operand" ""))
17180 (use (match_operand:MODEF 1 "general_operand" ""))]
17181 "TARGET_USE_FANCY_MATH_387
17182 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17183 || TARGET_MIX_SSE_I387)
17184 && flag_unsafe_math_optimizations && !optimize_size"
17186 rtx op0 = gen_reg_rtx (XFmode);
17187 rtx op1 = gen_reg_rtx (XFmode);
17189 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17190 emit_insn (gen_exp10xf2 (op0, op1));
17191 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17195 (define_expand "exp2xf2"
17196 [(use (match_operand:XF 0 "register_operand" ""))
17197 (use (match_operand:XF 1 "register_operand" ""))]
17198 "TARGET_USE_FANCY_MATH_387
17199 && flag_unsafe_math_optimizations && !optimize_size"
17201 rtx op2 = gen_reg_rtx (XFmode);
17202 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17204 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17208 (define_expand "exp2<mode>2"
17209 [(use (match_operand:MODEF 0 "register_operand" ""))
17210 (use (match_operand:MODEF 1 "general_operand" ""))]
17211 "TARGET_USE_FANCY_MATH_387
17212 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17213 || TARGET_MIX_SSE_I387)
17214 && flag_unsafe_math_optimizations && !optimize_size"
17216 rtx op0 = gen_reg_rtx (XFmode);
17217 rtx op1 = gen_reg_rtx (XFmode);
17219 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17220 emit_insn (gen_exp2xf2 (op0, op1));
17221 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17225 (define_expand "expm1xf2"
17226 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17228 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17229 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17230 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17231 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17232 (parallel [(set (match_dup 7)
17233 (unspec:XF [(match_dup 6) (match_dup 4)]
17234 UNSPEC_FSCALE_FRACT))
17236 (unspec:XF [(match_dup 6) (match_dup 4)]
17237 UNSPEC_FSCALE_EXP))])
17238 (parallel [(set (match_dup 10)
17239 (unspec:XF [(match_dup 9) (match_dup 8)]
17240 UNSPEC_FSCALE_FRACT))
17241 (set (match_dup 11)
17242 (unspec:XF [(match_dup 9) (match_dup 8)]
17243 UNSPEC_FSCALE_EXP))])
17244 (set (match_dup 12) (minus:XF (match_dup 10)
17245 (float_extend:XF (match_dup 13))))
17246 (set (match_operand:XF 0 "register_operand" "")
17247 (plus:XF (match_dup 12) (match_dup 7)))]
17248 "TARGET_USE_FANCY_MATH_387
17249 && flag_unsafe_math_optimizations && !optimize_size"
17253 for (i = 2; i < 13; i++)
17254 operands[i] = gen_reg_rtx (XFmode);
17257 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17259 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17262 (define_expand "expm1<mode>2"
17263 [(use (match_operand:MODEF 0 "register_operand" ""))
17264 (use (match_operand:MODEF 1 "general_operand" ""))]
17265 "TARGET_USE_FANCY_MATH_387
17266 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17267 || TARGET_MIX_SSE_I387)
17268 && flag_unsafe_math_optimizations && !optimize_size"
17270 rtx op0 = gen_reg_rtx (XFmode);
17271 rtx op1 = gen_reg_rtx (XFmode);
17273 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17274 emit_insn (gen_expm1xf2 (op0, op1));
17275 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17279 (define_expand "ldexpxf3"
17280 [(set (match_dup 3)
17281 (float:XF (match_operand:SI 2 "register_operand" "")))
17282 (parallel [(set (match_operand:XF 0 " register_operand" "")
17283 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17285 UNSPEC_FSCALE_FRACT))
17287 (unspec:XF [(match_dup 1) (match_dup 3)]
17288 UNSPEC_FSCALE_EXP))])]
17289 "TARGET_USE_FANCY_MATH_387
17290 && flag_unsafe_math_optimizations && !optimize_size"
17292 operands[3] = gen_reg_rtx (XFmode);
17293 operands[4] = gen_reg_rtx (XFmode);
17296 (define_expand "ldexp<mode>3"
17297 [(use (match_operand:MODEF 0 "register_operand" ""))
17298 (use (match_operand:MODEF 1 "general_operand" ""))
17299 (use (match_operand:SI 2 "register_operand" ""))]
17300 "TARGET_USE_FANCY_MATH_387
17301 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17302 || TARGET_MIX_SSE_I387)
17303 && flag_unsafe_math_optimizations && !optimize_size"
17305 rtx op0 = gen_reg_rtx (XFmode);
17306 rtx op1 = gen_reg_rtx (XFmode);
17308 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17309 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17310 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17314 (define_expand "scalbxf3"
17315 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17316 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17317 (match_operand:XF 2 "register_operand" "")]
17318 UNSPEC_FSCALE_FRACT))
17320 (unspec:XF [(match_dup 1) (match_dup 2)]
17321 UNSPEC_FSCALE_EXP))])]
17322 "TARGET_USE_FANCY_MATH_387
17323 && flag_unsafe_math_optimizations && !optimize_size"
17325 operands[3] = gen_reg_rtx (XFmode);
17328 (define_expand "scalb<mode>3"
17329 [(use (match_operand:MODEF 0 "register_operand" ""))
17330 (use (match_operand:MODEF 1 "general_operand" ""))
17331 (use (match_operand:MODEF 2 "register_operand" ""))]
17332 "TARGET_USE_FANCY_MATH_387
17333 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17334 || TARGET_MIX_SSE_I387)
17335 && flag_unsafe_math_optimizations && !optimize_size"
17337 rtx op0 = gen_reg_rtx (XFmode);
17338 rtx op1 = gen_reg_rtx (XFmode);
17339 rtx op2 = gen_reg_rtx (XFmode);
17341 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17342 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17343 emit_insn (gen_scalbxf3 (op0, op1, op2));
17344 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17349 (define_insn "sse4_1_round<mode>2"
17350 [(set (match_operand:MODEF 0 "register_operand" "=x")
17351 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17352 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17355 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17356 [(set_attr "type" "ssecvt")
17357 (set_attr "prefix_extra" "1")
17358 (set_attr "mode" "<MODE>")])
17360 (define_insn "rintxf2"
17361 [(set (match_operand:XF 0 "register_operand" "=f")
17362 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17364 "TARGET_USE_FANCY_MATH_387
17365 && flag_unsafe_math_optimizations"
17367 [(set_attr "type" "fpspc")
17368 (set_attr "mode" "XF")])
17370 (define_expand "rint<mode>2"
17371 [(use (match_operand:MODEF 0 "register_operand" ""))
17372 (use (match_operand:MODEF 1 "register_operand" ""))]
17373 "(TARGET_USE_FANCY_MATH_387
17374 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17375 || TARGET_MIX_SSE_I387)
17376 && flag_unsafe_math_optimizations)
17377 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17378 && !flag_trapping_math
17379 && (TARGET_ROUND || !optimize_size))"
17381 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17382 && !flag_trapping_math
17383 && (TARGET_ROUND || !optimize_size))
17386 emit_insn (gen_sse4_1_round<mode>2
17387 (operands[0], operands[1], GEN_INT (0x04)));
17389 ix86_expand_rint (operand0, operand1);
17393 rtx op0 = gen_reg_rtx (XFmode);
17394 rtx op1 = gen_reg_rtx (XFmode);
17396 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17397 emit_insn (gen_rintxf2 (op0, op1));
17399 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17404 (define_expand "round<mode>2"
17405 [(match_operand:MODEF 0 "register_operand" "")
17406 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17407 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17408 && !flag_trapping_math && !flag_rounding_math
17411 if (TARGET_64BIT || (<MODE>mode != DFmode))
17412 ix86_expand_round (operand0, operand1);
17414 ix86_expand_rounddf_32 (operand0, operand1);
17418 (define_insn_and_split "*fistdi2_1"
17419 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17420 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17422 "TARGET_USE_FANCY_MATH_387
17423 && !(reload_completed || reload_in_progress)"
17428 if (memory_operand (operands[0], VOIDmode))
17429 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17432 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17433 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17438 [(set_attr "type" "fpspc")
17439 (set_attr "mode" "DI")])
17441 (define_insn "fistdi2"
17442 [(set (match_operand:DI 0 "memory_operand" "=m")
17443 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17445 (clobber (match_scratch:XF 2 "=&1f"))]
17446 "TARGET_USE_FANCY_MATH_387"
17447 "* return output_fix_trunc (insn, operands, 0);"
17448 [(set_attr "type" "fpspc")
17449 (set_attr "mode" "DI")])
17451 (define_insn "fistdi2_with_temp"
17452 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17453 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17455 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17456 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17457 "TARGET_USE_FANCY_MATH_387"
17459 [(set_attr "type" "fpspc")
17460 (set_attr "mode" "DI")])
17463 [(set (match_operand:DI 0 "register_operand" "")
17464 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17466 (clobber (match_operand:DI 2 "memory_operand" ""))
17467 (clobber (match_scratch 3 ""))]
17469 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17470 (clobber (match_dup 3))])
17471 (set (match_dup 0) (match_dup 2))]
17475 [(set (match_operand:DI 0 "memory_operand" "")
17476 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17478 (clobber (match_operand:DI 2 "memory_operand" ""))
17479 (clobber (match_scratch 3 ""))]
17481 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17482 (clobber (match_dup 3))])]
17485 (define_insn_and_split "*fist<mode>2_1"
17486 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17487 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17489 "TARGET_USE_FANCY_MATH_387
17490 && !(reload_completed || reload_in_progress)"
17495 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17496 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17500 [(set_attr "type" "fpspc")
17501 (set_attr "mode" "<MODE>")])
17503 (define_insn "fist<mode>2"
17504 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17505 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17507 "TARGET_USE_FANCY_MATH_387"
17508 "* return output_fix_trunc (insn, operands, 0);"
17509 [(set_attr "type" "fpspc")
17510 (set_attr "mode" "<MODE>")])
17512 (define_insn "fist<mode>2_with_temp"
17513 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17514 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17516 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17517 "TARGET_USE_FANCY_MATH_387"
17519 [(set_attr "type" "fpspc")
17520 (set_attr "mode" "<MODE>")])
17523 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17524 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17526 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17528 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17529 (set (match_dup 0) (match_dup 2))]
17533 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17534 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17536 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17538 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17541 (define_expand "lrintxf<mode>2"
17542 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17543 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17545 "TARGET_USE_FANCY_MATH_387"
17548 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17549 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17550 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17551 UNSPEC_FIX_NOTRUNC))]
17552 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17553 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17556 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17557 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17558 (match_operand:MODEF 1 "register_operand" "")]
17559 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17560 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17561 && !flag_trapping_math && !flag_rounding_math
17564 ix86_expand_lround (operand0, operand1);
17568 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17569 (define_insn_and_split "frndintxf2_floor"
17570 [(set (match_operand:XF 0 "register_operand" "")
17571 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17572 UNSPEC_FRNDINT_FLOOR))
17573 (clobber (reg:CC FLAGS_REG))]
17574 "TARGET_USE_FANCY_MATH_387
17575 && flag_unsafe_math_optimizations
17576 && !(reload_completed || reload_in_progress)"
17581 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17583 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17584 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17586 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17587 operands[2], operands[3]));
17590 [(set_attr "type" "frndint")
17591 (set_attr "i387_cw" "floor")
17592 (set_attr "mode" "XF")])
17594 (define_insn "frndintxf2_floor_i387"
17595 [(set (match_operand:XF 0 "register_operand" "=f")
17596 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17597 UNSPEC_FRNDINT_FLOOR))
17598 (use (match_operand:HI 2 "memory_operand" "m"))
17599 (use (match_operand:HI 3 "memory_operand" "m"))]
17600 "TARGET_USE_FANCY_MATH_387
17601 && flag_unsafe_math_optimizations"
17602 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17603 [(set_attr "type" "frndint")
17604 (set_attr "i387_cw" "floor")
17605 (set_attr "mode" "XF")])
17607 (define_expand "floorxf2"
17608 [(use (match_operand:XF 0 "register_operand" ""))
17609 (use (match_operand:XF 1 "register_operand" ""))]
17610 "TARGET_USE_FANCY_MATH_387
17611 && flag_unsafe_math_optimizations && !optimize_size"
17613 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17617 (define_expand "floor<mode>2"
17618 [(use (match_operand:MODEF 0 "register_operand" ""))
17619 (use (match_operand:MODEF 1 "register_operand" ""))]
17620 "(TARGET_USE_FANCY_MATH_387
17621 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17622 || TARGET_MIX_SSE_I387)
17623 && flag_unsafe_math_optimizations && !optimize_size)
17624 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17625 && !flag_trapping_math
17626 && (TARGET_ROUND || !optimize_size))"
17628 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17629 && !flag_trapping_math
17630 && (TARGET_ROUND || !optimize_size))
17633 emit_insn (gen_sse4_1_round<mode>2
17634 (operands[0], operands[1], GEN_INT (0x01)));
17635 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17636 ix86_expand_floorceil (operand0, operand1, true);
17638 ix86_expand_floorceildf_32 (operand0, operand1, true);
17642 rtx op0 = gen_reg_rtx (XFmode);
17643 rtx op1 = gen_reg_rtx (XFmode);
17645 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17646 emit_insn (gen_frndintxf2_floor (op0, op1));
17648 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17653 (define_insn_and_split "*fist<mode>2_floor_1"
17654 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17655 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17656 UNSPEC_FIST_FLOOR))
17657 (clobber (reg:CC FLAGS_REG))]
17658 "TARGET_USE_FANCY_MATH_387
17659 && flag_unsafe_math_optimizations
17660 && !(reload_completed || reload_in_progress)"
17665 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17667 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17668 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17669 if (memory_operand (operands[0], VOIDmode))
17670 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17671 operands[2], operands[3]));
17674 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17675 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17676 operands[2], operands[3],
17681 [(set_attr "type" "fistp")
17682 (set_attr "i387_cw" "floor")
17683 (set_attr "mode" "<MODE>")])
17685 (define_insn "fistdi2_floor"
17686 [(set (match_operand:DI 0 "memory_operand" "=m")
17687 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17688 UNSPEC_FIST_FLOOR))
17689 (use (match_operand:HI 2 "memory_operand" "m"))
17690 (use (match_operand:HI 3 "memory_operand" "m"))
17691 (clobber (match_scratch:XF 4 "=&1f"))]
17692 "TARGET_USE_FANCY_MATH_387
17693 && flag_unsafe_math_optimizations"
17694 "* return output_fix_trunc (insn, operands, 0);"
17695 [(set_attr "type" "fistp")
17696 (set_attr "i387_cw" "floor")
17697 (set_attr "mode" "DI")])
17699 (define_insn "fistdi2_floor_with_temp"
17700 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17701 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17702 UNSPEC_FIST_FLOOR))
17703 (use (match_operand:HI 2 "memory_operand" "m,m"))
17704 (use (match_operand:HI 3 "memory_operand" "m,m"))
17705 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17706 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17707 "TARGET_USE_FANCY_MATH_387
17708 && flag_unsafe_math_optimizations"
17710 [(set_attr "type" "fistp")
17711 (set_attr "i387_cw" "floor")
17712 (set_attr "mode" "DI")])
17715 [(set (match_operand:DI 0 "register_operand" "")
17716 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17717 UNSPEC_FIST_FLOOR))
17718 (use (match_operand:HI 2 "memory_operand" ""))
17719 (use (match_operand:HI 3 "memory_operand" ""))
17720 (clobber (match_operand:DI 4 "memory_operand" ""))
17721 (clobber (match_scratch 5 ""))]
17723 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17724 (use (match_dup 2))
17725 (use (match_dup 3))
17726 (clobber (match_dup 5))])
17727 (set (match_dup 0) (match_dup 4))]
17731 [(set (match_operand:DI 0 "memory_operand" "")
17732 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17733 UNSPEC_FIST_FLOOR))
17734 (use (match_operand:HI 2 "memory_operand" ""))
17735 (use (match_operand:HI 3 "memory_operand" ""))
17736 (clobber (match_operand:DI 4 "memory_operand" ""))
17737 (clobber (match_scratch 5 ""))]
17739 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17740 (use (match_dup 2))
17741 (use (match_dup 3))
17742 (clobber (match_dup 5))])]
17745 (define_insn "fist<mode>2_floor"
17746 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17747 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17748 UNSPEC_FIST_FLOOR))
17749 (use (match_operand:HI 2 "memory_operand" "m"))
17750 (use (match_operand:HI 3 "memory_operand" "m"))]
17751 "TARGET_USE_FANCY_MATH_387
17752 && flag_unsafe_math_optimizations"
17753 "* return output_fix_trunc (insn, operands, 0);"
17754 [(set_attr "type" "fistp")
17755 (set_attr "i387_cw" "floor")
17756 (set_attr "mode" "<MODE>")])
17758 (define_insn "fist<mode>2_floor_with_temp"
17759 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17760 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17761 UNSPEC_FIST_FLOOR))
17762 (use (match_operand:HI 2 "memory_operand" "m,m"))
17763 (use (match_operand:HI 3 "memory_operand" "m,m"))
17764 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17765 "TARGET_USE_FANCY_MATH_387
17766 && flag_unsafe_math_optimizations"
17768 [(set_attr "type" "fistp")
17769 (set_attr "i387_cw" "floor")
17770 (set_attr "mode" "<MODE>")])
17773 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17774 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17775 UNSPEC_FIST_FLOOR))
17776 (use (match_operand:HI 2 "memory_operand" ""))
17777 (use (match_operand:HI 3 "memory_operand" ""))
17778 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17780 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17781 UNSPEC_FIST_FLOOR))
17782 (use (match_dup 2))
17783 (use (match_dup 3))])
17784 (set (match_dup 0) (match_dup 4))]
17788 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17789 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17790 UNSPEC_FIST_FLOOR))
17791 (use (match_operand:HI 2 "memory_operand" ""))
17792 (use (match_operand:HI 3 "memory_operand" ""))
17793 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17795 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17796 UNSPEC_FIST_FLOOR))
17797 (use (match_dup 2))
17798 (use (match_dup 3))])]
17801 (define_expand "lfloorxf<mode>2"
17802 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17803 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17804 UNSPEC_FIST_FLOOR))
17805 (clobber (reg:CC FLAGS_REG))])]
17806 "TARGET_USE_FANCY_MATH_387
17807 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17808 && flag_unsafe_math_optimizations"
17811 (define_expand "lfloor<mode>di2"
17812 [(match_operand:DI 0 "nonimmediate_operand" "")
17813 (match_operand:MODEF 1 "register_operand" "")]
17814 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17815 && !flag_trapping_math
17818 ix86_expand_lfloorceil (operand0, operand1, true);
17822 (define_expand "lfloor<mode>si2"
17823 [(match_operand:SI 0 "nonimmediate_operand" "")
17824 (match_operand:MODEF 1 "register_operand" "")]
17825 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17826 && !flag_trapping_math
17827 && (!optimize_size || !TARGET_64BIT)"
17829 ix86_expand_lfloorceil (operand0, operand1, true);
17833 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17834 (define_insn_and_split "frndintxf2_ceil"
17835 [(set (match_operand:XF 0 "register_operand" "")
17836 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17837 UNSPEC_FRNDINT_CEIL))
17838 (clobber (reg:CC FLAGS_REG))]
17839 "TARGET_USE_FANCY_MATH_387
17840 && flag_unsafe_math_optimizations
17841 && !(reload_completed || reload_in_progress)"
17846 ix86_optimize_mode_switching[I387_CEIL] = 1;
17848 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17849 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17851 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17852 operands[2], operands[3]));
17855 [(set_attr "type" "frndint")
17856 (set_attr "i387_cw" "ceil")
17857 (set_attr "mode" "XF")])
17859 (define_insn "frndintxf2_ceil_i387"
17860 [(set (match_operand:XF 0 "register_operand" "=f")
17861 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17862 UNSPEC_FRNDINT_CEIL))
17863 (use (match_operand:HI 2 "memory_operand" "m"))
17864 (use (match_operand:HI 3 "memory_operand" "m"))]
17865 "TARGET_USE_FANCY_MATH_387
17866 && flag_unsafe_math_optimizations"
17867 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17868 [(set_attr "type" "frndint")
17869 (set_attr "i387_cw" "ceil")
17870 (set_attr "mode" "XF")])
17872 (define_expand "ceilxf2"
17873 [(use (match_operand:XF 0 "register_operand" ""))
17874 (use (match_operand:XF 1 "register_operand" ""))]
17875 "TARGET_USE_FANCY_MATH_387
17876 && flag_unsafe_math_optimizations && !optimize_size"
17878 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17882 (define_expand "ceil<mode>2"
17883 [(use (match_operand:MODEF 0 "register_operand" ""))
17884 (use (match_operand:MODEF 1 "register_operand" ""))]
17885 "(TARGET_USE_FANCY_MATH_387
17886 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17887 || TARGET_MIX_SSE_I387)
17888 && flag_unsafe_math_optimizations && !optimize_size)
17889 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17890 && !flag_trapping_math
17891 && (TARGET_ROUND || !optimize_size))"
17893 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17894 && !flag_trapping_math
17895 && (TARGET_ROUND || !optimize_size))
17898 emit_insn (gen_sse4_1_round<mode>2
17899 (operands[0], operands[1], GEN_INT (0x02)));
17900 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17901 ix86_expand_floorceil (operand0, operand1, false);
17903 ix86_expand_floorceildf_32 (operand0, operand1, false);
17907 rtx op0 = gen_reg_rtx (XFmode);
17908 rtx op1 = gen_reg_rtx (XFmode);
17910 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17911 emit_insn (gen_frndintxf2_ceil (op0, op1));
17913 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17918 (define_insn_and_split "*fist<mode>2_ceil_1"
17919 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17920 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17922 (clobber (reg:CC FLAGS_REG))]
17923 "TARGET_USE_FANCY_MATH_387
17924 && flag_unsafe_math_optimizations
17925 && !(reload_completed || reload_in_progress)"
17930 ix86_optimize_mode_switching[I387_CEIL] = 1;
17932 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17933 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17934 if (memory_operand (operands[0], VOIDmode))
17935 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17936 operands[2], operands[3]));
17939 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17940 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17941 operands[2], operands[3],
17946 [(set_attr "type" "fistp")
17947 (set_attr "i387_cw" "ceil")
17948 (set_attr "mode" "<MODE>")])
17950 (define_insn "fistdi2_ceil"
17951 [(set (match_operand:DI 0 "memory_operand" "=m")
17952 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17954 (use (match_operand:HI 2 "memory_operand" "m"))
17955 (use (match_operand:HI 3 "memory_operand" "m"))
17956 (clobber (match_scratch:XF 4 "=&1f"))]
17957 "TARGET_USE_FANCY_MATH_387
17958 && flag_unsafe_math_optimizations"
17959 "* return output_fix_trunc (insn, operands, 0);"
17960 [(set_attr "type" "fistp")
17961 (set_attr "i387_cw" "ceil")
17962 (set_attr "mode" "DI")])
17964 (define_insn "fistdi2_ceil_with_temp"
17965 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17966 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17968 (use (match_operand:HI 2 "memory_operand" "m,m"))
17969 (use (match_operand:HI 3 "memory_operand" "m,m"))
17970 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17971 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17972 "TARGET_USE_FANCY_MATH_387
17973 && flag_unsafe_math_optimizations"
17975 [(set_attr "type" "fistp")
17976 (set_attr "i387_cw" "ceil")
17977 (set_attr "mode" "DI")])
17980 [(set (match_operand:DI 0 "register_operand" "")
17981 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17983 (use (match_operand:HI 2 "memory_operand" ""))
17984 (use (match_operand:HI 3 "memory_operand" ""))
17985 (clobber (match_operand:DI 4 "memory_operand" ""))
17986 (clobber (match_scratch 5 ""))]
17988 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17989 (use (match_dup 2))
17990 (use (match_dup 3))
17991 (clobber (match_dup 5))])
17992 (set (match_dup 0) (match_dup 4))]
17996 [(set (match_operand:DI 0 "memory_operand" "")
17997 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17999 (use (match_operand:HI 2 "memory_operand" ""))
18000 (use (match_operand:HI 3 "memory_operand" ""))
18001 (clobber (match_operand:DI 4 "memory_operand" ""))
18002 (clobber (match_scratch 5 ""))]
18004 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18005 (use (match_dup 2))
18006 (use (match_dup 3))
18007 (clobber (match_dup 5))])]
18010 (define_insn "fist<mode>2_ceil"
18011 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18012 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18014 (use (match_operand:HI 2 "memory_operand" "m"))
18015 (use (match_operand:HI 3 "memory_operand" "m"))]
18016 "TARGET_USE_FANCY_MATH_387
18017 && flag_unsafe_math_optimizations"
18018 "* return output_fix_trunc (insn, operands, 0);"
18019 [(set_attr "type" "fistp")
18020 (set_attr "i387_cw" "ceil")
18021 (set_attr "mode" "<MODE>")])
18023 (define_insn "fist<mode>2_ceil_with_temp"
18024 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18025 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18027 (use (match_operand:HI 2 "memory_operand" "m,m"))
18028 (use (match_operand:HI 3 "memory_operand" "m,m"))
18029 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18030 "TARGET_USE_FANCY_MATH_387
18031 && flag_unsafe_math_optimizations"
18033 [(set_attr "type" "fistp")
18034 (set_attr "i387_cw" "ceil")
18035 (set_attr "mode" "<MODE>")])
18038 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18039 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18041 (use (match_operand:HI 2 "memory_operand" ""))
18042 (use (match_operand:HI 3 "memory_operand" ""))
18043 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18045 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18047 (use (match_dup 2))
18048 (use (match_dup 3))])
18049 (set (match_dup 0) (match_dup 4))]
18053 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18054 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18056 (use (match_operand:HI 2 "memory_operand" ""))
18057 (use (match_operand:HI 3 "memory_operand" ""))
18058 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18060 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18062 (use (match_dup 2))
18063 (use (match_dup 3))])]
18066 (define_expand "lceilxf<mode>2"
18067 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18068 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18070 (clobber (reg:CC FLAGS_REG))])]
18071 "TARGET_USE_FANCY_MATH_387
18072 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18073 && flag_unsafe_math_optimizations"
18076 (define_expand "lceil<mode>di2"
18077 [(match_operand:DI 0 "nonimmediate_operand" "")
18078 (match_operand:MODEF 1 "register_operand" "")]
18079 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18080 && !flag_trapping_math"
18082 ix86_expand_lfloorceil (operand0, operand1, false);
18086 (define_expand "lceil<mode>si2"
18087 [(match_operand:SI 0 "nonimmediate_operand" "")
18088 (match_operand:MODEF 1 "register_operand" "")]
18089 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18090 && !flag_trapping_math"
18092 ix86_expand_lfloorceil (operand0, operand1, false);
18096 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18097 (define_insn_and_split "frndintxf2_trunc"
18098 [(set (match_operand:XF 0 "register_operand" "")
18099 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18100 UNSPEC_FRNDINT_TRUNC))
18101 (clobber (reg:CC FLAGS_REG))]
18102 "TARGET_USE_FANCY_MATH_387
18103 && flag_unsafe_math_optimizations
18104 && !(reload_completed || reload_in_progress)"
18109 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18111 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18112 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18114 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18115 operands[2], operands[3]));
18118 [(set_attr "type" "frndint")
18119 (set_attr "i387_cw" "trunc")
18120 (set_attr "mode" "XF")])
18122 (define_insn "frndintxf2_trunc_i387"
18123 [(set (match_operand:XF 0 "register_operand" "=f")
18124 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18125 UNSPEC_FRNDINT_TRUNC))
18126 (use (match_operand:HI 2 "memory_operand" "m"))
18127 (use (match_operand:HI 3 "memory_operand" "m"))]
18128 "TARGET_USE_FANCY_MATH_387
18129 && flag_unsafe_math_optimizations"
18130 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18131 [(set_attr "type" "frndint")
18132 (set_attr "i387_cw" "trunc")
18133 (set_attr "mode" "XF")])
18135 (define_expand "btruncxf2"
18136 [(use (match_operand:XF 0 "register_operand" ""))
18137 (use (match_operand:XF 1 "register_operand" ""))]
18138 "TARGET_USE_FANCY_MATH_387
18139 && flag_unsafe_math_optimizations && !optimize_size"
18141 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18145 (define_expand "btrunc<mode>2"
18146 [(use (match_operand:MODEF 0 "register_operand" ""))
18147 (use (match_operand:MODEF 1 "register_operand" ""))]
18148 "(TARGET_USE_FANCY_MATH_387
18149 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18150 || TARGET_MIX_SSE_I387)
18151 && flag_unsafe_math_optimizations && !optimize_size)
18152 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18153 && !flag_trapping_math
18154 && (TARGET_ROUND || !optimize_size))"
18156 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18157 && !flag_trapping_math
18158 && (TARGET_ROUND || !optimize_size))
18161 emit_insn (gen_sse4_1_round<mode>2
18162 (operands[0], operands[1], GEN_INT (0x03)));
18163 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18164 ix86_expand_trunc (operand0, operand1);
18166 ix86_expand_truncdf_32 (operand0, operand1);
18170 rtx op0 = gen_reg_rtx (XFmode);
18171 rtx op1 = gen_reg_rtx (XFmode);
18173 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18174 emit_insn (gen_frndintxf2_trunc (op0, op1));
18176 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18181 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18182 (define_insn_and_split "frndintxf2_mask_pm"
18183 [(set (match_operand:XF 0 "register_operand" "")
18184 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18185 UNSPEC_FRNDINT_MASK_PM))
18186 (clobber (reg:CC FLAGS_REG))]
18187 "TARGET_USE_FANCY_MATH_387
18188 && flag_unsafe_math_optimizations
18189 && !(reload_completed || reload_in_progress)"
18194 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18196 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18197 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18199 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18200 operands[2], operands[3]));
18203 [(set_attr "type" "frndint")
18204 (set_attr "i387_cw" "mask_pm")
18205 (set_attr "mode" "XF")])
18207 (define_insn "frndintxf2_mask_pm_i387"
18208 [(set (match_operand:XF 0 "register_operand" "=f")
18209 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18210 UNSPEC_FRNDINT_MASK_PM))
18211 (use (match_operand:HI 2 "memory_operand" "m"))
18212 (use (match_operand:HI 3 "memory_operand" "m"))]
18213 "TARGET_USE_FANCY_MATH_387
18214 && flag_unsafe_math_optimizations"
18215 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18216 [(set_attr "type" "frndint")
18217 (set_attr "i387_cw" "mask_pm")
18218 (set_attr "mode" "XF")])
18220 (define_expand "nearbyintxf2"
18221 [(use (match_operand:XF 0 "register_operand" ""))
18222 (use (match_operand:XF 1 "register_operand" ""))]
18223 "TARGET_USE_FANCY_MATH_387
18224 && flag_unsafe_math_optimizations"
18226 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18231 (define_expand "nearbyint<mode>2"
18232 [(use (match_operand:MODEF 0 "register_operand" ""))
18233 (use (match_operand:MODEF 1 "register_operand" ""))]
18234 "TARGET_USE_FANCY_MATH_387
18235 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18236 || TARGET_MIX_SSE_I387)
18237 && flag_unsafe_math_optimizations"
18239 rtx op0 = gen_reg_rtx (XFmode);
18240 rtx op1 = gen_reg_rtx (XFmode);
18242 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18243 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18245 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18249 (define_insn "fxam<mode>2_i387"
18250 [(set (match_operand:HI 0 "register_operand" "=a")
18252 [(match_operand:X87MODEF 1 "register_operand" "f")]
18254 "TARGET_USE_FANCY_MATH_387"
18255 "fxam\n\tfnstsw\t%0"
18256 [(set_attr "type" "multi")
18257 (set_attr "unit" "i387")
18258 (set_attr "mode" "<MODE>")])
18260 (define_expand "isinf<mode>2"
18261 [(use (match_operand:SI 0 "register_operand" ""))
18262 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18263 "TARGET_USE_FANCY_MATH_387
18264 && TARGET_C99_FUNCTIONS
18265 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18267 rtx mask = GEN_INT (0x45);
18268 rtx val = GEN_INT (0x05);
18272 rtx scratch = gen_reg_rtx (HImode);
18273 rtx res = gen_reg_rtx (QImode);
18275 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18276 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18277 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18278 cond = gen_rtx_fmt_ee (EQ, QImode,
18279 gen_rtx_REG (CCmode, FLAGS_REG),
18281 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18282 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18286 (define_expand "signbit<mode>2"
18287 [(use (match_operand:SI 0 "register_operand" ""))
18288 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18289 "TARGET_USE_FANCY_MATH_387
18290 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18292 rtx mask = GEN_INT (0x0200);
18294 rtx scratch = gen_reg_rtx (HImode);
18296 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18297 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18301 ;; Block operation instructions
18304 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18307 [(set_attr "length" "1")
18308 (set_attr "length_immediate" "0")
18309 (set_attr "modrm" "0")])
18311 (define_expand "movmemsi"
18312 [(use (match_operand:BLK 0 "memory_operand" ""))
18313 (use (match_operand:BLK 1 "memory_operand" ""))
18314 (use (match_operand:SI 2 "nonmemory_operand" ""))
18315 (use (match_operand:SI 3 "const_int_operand" ""))
18316 (use (match_operand:SI 4 "const_int_operand" ""))
18317 (use (match_operand:SI 5 "const_int_operand" ""))]
18320 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18321 operands[4], operands[5]))
18327 (define_expand "movmemdi"
18328 [(use (match_operand:BLK 0 "memory_operand" ""))
18329 (use (match_operand:BLK 1 "memory_operand" ""))
18330 (use (match_operand:DI 2 "nonmemory_operand" ""))
18331 (use (match_operand:DI 3 "const_int_operand" ""))
18332 (use (match_operand:SI 4 "const_int_operand" ""))
18333 (use (match_operand:SI 5 "const_int_operand" ""))]
18336 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18337 operands[4], operands[5]))
18343 ;; Most CPUs don't like single string operations
18344 ;; Handle this case here to simplify previous expander.
18346 (define_expand "strmov"
18347 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18348 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18349 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18350 (clobber (reg:CC FLAGS_REG))])
18351 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18352 (clobber (reg:CC FLAGS_REG))])]
18355 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18357 /* If .md ever supports :P for Pmode, these can be directly
18358 in the pattern above. */
18359 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18360 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18362 /* Can't use this if the user has appropriated esi or edi. */
18363 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18364 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18366 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18367 operands[2], operands[3],
18368 operands[5], operands[6]));
18372 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18375 (define_expand "strmov_singleop"
18376 [(parallel [(set (match_operand 1 "memory_operand" "")
18377 (match_operand 3 "memory_operand" ""))
18378 (set (match_operand 0 "register_operand" "")
18379 (match_operand 4 "" ""))
18380 (set (match_operand 2 "register_operand" "")
18381 (match_operand 5 "" ""))])]
18382 "TARGET_SINGLE_STRINGOP || optimize_size"
18383 "ix86_current_function_needs_cld = 1;")
18385 (define_insn "*strmovdi_rex_1"
18386 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18387 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18388 (set (match_operand:DI 0 "register_operand" "=D")
18389 (plus:DI (match_dup 2)
18391 (set (match_operand:DI 1 "register_operand" "=S")
18392 (plus:DI (match_dup 3)
18394 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18396 [(set_attr "type" "str")
18397 (set_attr "mode" "DI")
18398 (set_attr "memory" "both")])
18400 (define_insn "*strmovsi_1"
18401 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18402 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18403 (set (match_operand:SI 0 "register_operand" "=D")
18404 (plus:SI (match_dup 2)
18406 (set (match_operand:SI 1 "register_operand" "=S")
18407 (plus:SI (match_dup 3)
18409 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18411 [(set_attr "type" "str")
18412 (set_attr "mode" "SI")
18413 (set_attr "memory" "both")])
18415 (define_insn "*strmovsi_rex_1"
18416 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18417 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18418 (set (match_operand:DI 0 "register_operand" "=D")
18419 (plus:DI (match_dup 2)
18421 (set (match_operand:DI 1 "register_operand" "=S")
18422 (plus:DI (match_dup 3)
18424 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18426 [(set_attr "type" "str")
18427 (set_attr "mode" "SI")
18428 (set_attr "memory" "both")])
18430 (define_insn "*strmovhi_1"
18431 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18432 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18433 (set (match_operand:SI 0 "register_operand" "=D")
18434 (plus:SI (match_dup 2)
18436 (set (match_operand:SI 1 "register_operand" "=S")
18437 (plus:SI (match_dup 3)
18439 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18441 [(set_attr "type" "str")
18442 (set_attr "memory" "both")
18443 (set_attr "mode" "HI")])
18445 (define_insn "*strmovhi_rex_1"
18446 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18447 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18448 (set (match_operand:DI 0 "register_operand" "=D")
18449 (plus:DI (match_dup 2)
18451 (set (match_operand:DI 1 "register_operand" "=S")
18452 (plus:DI (match_dup 3)
18454 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18456 [(set_attr "type" "str")
18457 (set_attr "memory" "both")
18458 (set_attr "mode" "HI")])
18460 (define_insn "*strmovqi_1"
18461 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18462 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18463 (set (match_operand:SI 0 "register_operand" "=D")
18464 (plus:SI (match_dup 2)
18466 (set (match_operand:SI 1 "register_operand" "=S")
18467 (plus:SI (match_dup 3)
18469 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18471 [(set_attr "type" "str")
18472 (set_attr "memory" "both")
18473 (set_attr "mode" "QI")])
18475 (define_insn "*strmovqi_rex_1"
18476 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18477 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18478 (set (match_operand:DI 0 "register_operand" "=D")
18479 (plus:DI (match_dup 2)
18481 (set (match_operand:DI 1 "register_operand" "=S")
18482 (plus:DI (match_dup 3)
18484 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18486 [(set_attr "type" "str")
18487 (set_attr "memory" "both")
18488 (set_attr "mode" "QI")])
18490 (define_expand "rep_mov"
18491 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18492 (set (match_operand 0 "register_operand" "")
18493 (match_operand 5 "" ""))
18494 (set (match_operand 2 "register_operand" "")
18495 (match_operand 6 "" ""))
18496 (set (match_operand 1 "memory_operand" "")
18497 (match_operand 3 "memory_operand" ""))
18498 (use (match_dup 4))])]
18500 "ix86_current_function_needs_cld = 1;")
18502 (define_insn "*rep_movdi_rex64"
18503 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18504 (set (match_operand:DI 0 "register_operand" "=D")
18505 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18507 (match_operand:DI 3 "register_operand" "0")))
18508 (set (match_operand:DI 1 "register_operand" "=S")
18509 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18510 (match_operand:DI 4 "register_operand" "1")))
18511 (set (mem:BLK (match_dup 3))
18512 (mem:BLK (match_dup 4)))
18513 (use (match_dup 5))]
18516 [(set_attr "type" "str")
18517 (set_attr "prefix_rep" "1")
18518 (set_attr "memory" "both")
18519 (set_attr "mode" "DI")])
18521 (define_insn "*rep_movsi"
18522 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18523 (set (match_operand:SI 0 "register_operand" "=D")
18524 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18526 (match_operand:SI 3 "register_operand" "0")))
18527 (set (match_operand:SI 1 "register_operand" "=S")
18528 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18529 (match_operand:SI 4 "register_operand" "1")))
18530 (set (mem:BLK (match_dup 3))
18531 (mem:BLK (match_dup 4)))
18532 (use (match_dup 5))]
18535 [(set_attr "type" "str")
18536 (set_attr "prefix_rep" "1")
18537 (set_attr "memory" "both")
18538 (set_attr "mode" "SI")])
18540 (define_insn "*rep_movsi_rex64"
18541 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18542 (set (match_operand:DI 0 "register_operand" "=D")
18543 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18545 (match_operand:DI 3 "register_operand" "0")))
18546 (set (match_operand:DI 1 "register_operand" "=S")
18547 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18548 (match_operand:DI 4 "register_operand" "1")))
18549 (set (mem:BLK (match_dup 3))
18550 (mem:BLK (match_dup 4)))
18551 (use (match_dup 5))]
18554 [(set_attr "type" "str")
18555 (set_attr "prefix_rep" "1")
18556 (set_attr "memory" "both")
18557 (set_attr "mode" "SI")])
18559 (define_insn "*rep_movqi"
18560 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18561 (set (match_operand:SI 0 "register_operand" "=D")
18562 (plus:SI (match_operand:SI 3 "register_operand" "0")
18563 (match_operand:SI 5 "register_operand" "2")))
18564 (set (match_operand:SI 1 "register_operand" "=S")
18565 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18566 (set (mem:BLK (match_dup 3))
18567 (mem:BLK (match_dup 4)))
18568 (use (match_dup 5))]
18571 [(set_attr "type" "str")
18572 (set_attr "prefix_rep" "1")
18573 (set_attr "memory" "both")
18574 (set_attr "mode" "SI")])
18576 (define_insn "*rep_movqi_rex64"
18577 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18578 (set (match_operand:DI 0 "register_operand" "=D")
18579 (plus:DI (match_operand:DI 3 "register_operand" "0")
18580 (match_operand:DI 5 "register_operand" "2")))
18581 (set (match_operand:DI 1 "register_operand" "=S")
18582 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18583 (set (mem:BLK (match_dup 3))
18584 (mem:BLK (match_dup 4)))
18585 (use (match_dup 5))]
18588 [(set_attr "type" "str")
18589 (set_attr "prefix_rep" "1")
18590 (set_attr "memory" "both")
18591 (set_attr "mode" "SI")])
18593 (define_expand "setmemsi"
18594 [(use (match_operand:BLK 0 "memory_operand" ""))
18595 (use (match_operand:SI 1 "nonmemory_operand" ""))
18596 (use (match_operand 2 "const_int_operand" ""))
18597 (use (match_operand 3 "const_int_operand" ""))
18598 (use (match_operand:SI 4 "const_int_operand" ""))
18599 (use (match_operand:SI 5 "const_int_operand" ""))]
18602 if (ix86_expand_setmem (operands[0], operands[1],
18603 operands[2], operands[3],
18604 operands[4], operands[5]))
18610 (define_expand "setmemdi"
18611 [(use (match_operand:BLK 0 "memory_operand" ""))
18612 (use (match_operand:DI 1 "nonmemory_operand" ""))
18613 (use (match_operand 2 "const_int_operand" ""))
18614 (use (match_operand 3 "const_int_operand" ""))
18615 (use (match_operand 4 "const_int_operand" ""))
18616 (use (match_operand 5 "const_int_operand" ""))]
18619 if (ix86_expand_setmem (operands[0], operands[1],
18620 operands[2], operands[3],
18621 operands[4], operands[5]))
18627 ;; Most CPUs don't like single string operations
18628 ;; Handle this case here to simplify previous expander.
18630 (define_expand "strset"
18631 [(set (match_operand 1 "memory_operand" "")
18632 (match_operand 2 "register_operand" ""))
18633 (parallel [(set (match_operand 0 "register_operand" "")
18635 (clobber (reg:CC FLAGS_REG))])]
18638 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18639 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18641 /* If .md ever supports :P for Pmode, this can be directly
18642 in the pattern above. */
18643 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18644 GEN_INT (GET_MODE_SIZE (GET_MODE
18646 if (TARGET_SINGLE_STRINGOP || optimize_size)
18648 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18654 (define_expand "strset_singleop"
18655 [(parallel [(set (match_operand 1 "memory_operand" "")
18656 (match_operand 2 "register_operand" ""))
18657 (set (match_operand 0 "register_operand" "")
18658 (match_operand 3 "" ""))])]
18659 "TARGET_SINGLE_STRINGOP || optimize_size"
18660 "ix86_current_function_needs_cld = 1;")
18662 (define_insn "*strsetdi_rex_1"
18663 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18664 (match_operand:DI 2 "register_operand" "a"))
18665 (set (match_operand:DI 0 "register_operand" "=D")
18666 (plus:DI (match_dup 1)
18668 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18670 [(set_attr "type" "str")
18671 (set_attr "memory" "store")
18672 (set_attr "mode" "DI")])
18674 (define_insn "*strsetsi_1"
18675 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18676 (match_operand:SI 2 "register_operand" "a"))
18677 (set (match_operand:SI 0 "register_operand" "=D")
18678 (plus:SI (match_dup 1)
18680 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18682 [(set_attr "type" "str")
18683 (set_attr "memory" "store")
18684 (set_attr "mode" "SI")])
18686 (define_insn "*strsetsi_rex_1"
18687 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18688 (match_operand:SI 2 "register_operand" "a"))
18689 (set (match_operand:DI 0 "register_operand" "=D")
18690 (plus:DI (match_dup 1)
18692 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18694 [(set_attr "type" "str")
18695 (set_attr "memory" "store")
18696 (set_attr "mode" "SI")])
18698 (define_insn "*strsethi_1"
18699 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18700 (match_operand:HI 2 "register_operand" "a"))
18701 (set (match_operand:SI 0 "register_operand" "=D")
18702 (plus:SI (match_dup 1)
18704 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18706 [(set_attr "type" "str")
18707 (set_attr "memory" "store")
18708 (set_attr "mode" "HI")])
18710 (define_insn "*strsethi_rex_1"
18711 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18712 (match_operand:HI 2 "register_operand" "a"))
18713 (set (match_operand:DI 0 "register_operand" "=D")
18714 (plus:DI (match_dup 1)
18716 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18718 [(set_attr "type" "str")
18719 (set_attr "memory" "store")
18720 (set_attr "mode" "HI")])
18722 (define_insn "*strsetqi_1"
18723 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18724 (match_operand:QI 2 "register_operand" "a"))
18725 (set (match_operand:SI 0 "register_operand" "=D")
18726 (plus:SI (match_dup 1)
18728 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18730 [(set_attr "type" "str")
18731 (set_attr "memory" "store")
18732 (set_attr "mode" "QI")])
18734 (define_insn "*strsetqi_rex_1"
18735 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18736 (match_operand:QI 2 "register_operand" "a"))
18737 (set (match_operand:DI 0 "register_operand" "=D")
18738 (plus:DI (match_dup 1)
18740 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18742 [(set_attr "type" "str")
18743 (set_attr "memory" "store")
18744 (set_attr "mode" "QI")])
18746 (define_expand "rep_stos"
18747 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18748 (set (match_operand 0 "register_operand" "")
18749 (match_operand 4 "" ""))
18750 (set (match_operand 2 "memory_operand" "") (const_int 0))
18751 (use (match_operand 3 "register_operand" ""))
18752 (use (match_dup 1))])]
18754 "ix86_current_function_needs_cld = 1;")
18756 (define_insn "*rep_stosdi_rex64"
18757 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18758 (set (match_operand:DI 0 "register_operand" "=D")
18759 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18761 (match_operand:DI 3 "register_operand" "0")))
18762 (set (mem:BLK (match_dup 3))
18764 (use (match_operand:DI 2 "register_operand" "a"))
18765 (use (match_dup 4))]
18768 [(set_attr "type" "str")
18769 (set_attr "prefix_rep" "1")
18770 (set_attr "memory" "store")
18771 (set_attr "mode" "DI")])
18773 (define_insn "*rep_stossi"
18774 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18775 (set (match_operand:SI 0 "register_operand" "=D")
18776 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18778 (match_operand:SI 3 "register_operand" "0")))
18779 (set (mem:BLK (match_dup 3))
18781 (use (match_operand:SI 2 "register_operand" "a"))
18782 (use (match_dup 4))]
18785 [(set_attr "type" "str")
18786 (set_attr "prefix_rep" "1")
18787 (set_attr "memory" "store")
18788 (set_attr "mode" "SI")])
18790 (define_insn "*rep_stossi_rex64"
18791 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18792 (set (match_operand:DI 0 "register_operand" "=D")
18793 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18795 (match_operand:DI 3 "register_operand" "0")))
18796 (set (mem:BLK (match_dup 3))
18798 (use (match_operand:SI 2 "register_operand" "a"))
18799 (use (match_dup 4))]
18802 [(set_attr "type" "str")
18803 (set_attr "prefix_rep" "1")
18804 (set_attr "memory" "store")
18805 (set_attr "mode" "SI")])
18807 (define_insn "*rep_stosqi"
18808 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18809 (set (match_operand:SI 0 "register_operand" "=D")
18810 (plus:SI (match_operand:SI 3 "register_operand" "0")
18811 (match_operand:SI 4 "register_operand" "1")))
18812 (set (mem:BLK (match_dup 3))
18814 (use (match_operand:QI 2 "register_operand" "a"))
18815 (use (match_dup 4))]
18818 [(set_attr "type" "str")
18819 (set_attr "prefix_rep" "1")
18820 (set_attr "memory" "store")
18821 (set_attr "mode" "QI")])
18823 (define_insn "*rep_stosqi_rex64"
18824 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18825 (set (match_operand:DI 0 "register_operand" "=D")
18826 (plus:DI (match_operand:DI 3 "register_operand" "0")
18827 (match_operand:DI 4 "register_operand" "1")))
18828 (set (mem:BLK (match_dup 3))
18830 (use (match_operand:QI 2 "register_operand" "a"))
18831 (use (match_dup 4))]
18834 [(set_attr "type" "str")
18835 (set_attr "prefix_rep" "1")
18836 (set_attr "memory" "store")
18837 (set_attr "mode" "QI")])
18839 (define_expand "cmpstrnsi"
18840 [(set (match_operand:SI 0 "register_operand" "")
18841 (compare:SI (match_operand:BLK 1 "general_operand" "")
18842 (match_operand:BLK 2 "general_operand" "")))
18843 (use (match_operand 3 "general_operand" ""))
18844 (use (match_operand 4 "immediate_operand" ""))]
18845 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18847 rtx addr1, addr2, out, outlow, count, countreg, align;
18849 /* Can't use this if the user has appropriated esi or edi. */
18850 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18855 out = gen_reg_rtx (SImode);
18857 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18858 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18859 if (addr1 != XEXP (operands[1], 0))
18860 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18861 if (addr2 != XEXP (operands[2], 0))
18862 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18864 count = operands[3];
18865 countreg = ix86_zero_extend_to_Pmode (count);
18867 /* %%% Iff we are testing strict equality, we can use known alignment
18868 to good advantage. This may be possible with combine, particularly
18869 once cc0 is dead. */
18870 align = operands[4];
18872 if (CONST_INT_P (count))
18874 if (INTVAL (count) == 0)
18876 emit_move_insn (operands[0], const0_rtx);
18879 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18880 operands[1], operands[2]));
18885 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18887 emit_insn (gen_cmpsi_1 (countreg, countreg));
18888 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18889 operands[1], operands[2]));
18892 outlow = gen_lowpart (QImode, out);
18893 emit_insn (gen_cmpintqi (outlow));
18894 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18896 if (operands[0] != out)
18897 emit_move_insn (operands[0], out);
18902 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18904 (define_expand "cmpintqi"
18905 [(set (match_dup 1)
18906 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18908 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18909 (parallel [(set (match_operand:QI 0 "register_operand" "")
18910 (minus:QI (match_dup 1)
18912 (clobber (reg:CC FLAGS_REG))])]
18914 "operands[1] = gen_reg_rtx (QImode);
18915 operands[2] = gen_reg_rtx (QImode);")
18917 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18918 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18920 (define_expand "cmpstrnqi_nz_1"
18921 [(parallel [(set (reg:CC FLAGS_REG)
18922 (compare:CC (match_operand 4 "memory_operand" "")
18923 (match_operand 5 "memory_operand" "")))
18924 (use (match_operand 2 "register_operand" ""))
18925 (use (match_operand:SI 3 "immediate_operand" ""))
18926 (clobber (match_operand 0 "register_operand" ""))
18927 (clobber (match_operand 1 "register_operand" ""))
18928 (clobber (match_dup 2))])]
18930 "ix86_current_function_needs_cld = 1;")
18932 (define_insn "*cmpstrnqi_nz_1"
18933 [(set (reg:CC FLAGS_REG)
18934 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18935 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18936 (use (match_operand:SI 6 "register_operand" "2"))
18937 (use (match_operand:SI 3 "immediate_operand" "i"))
18938 (clobber (match_operand:SI 0 "register_operand" "=S"))
18939 (clobber (match_operand:SI 1 "register_operand" "=D"))
18940 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18943 [(set_attr "type" "str")
18944 (set_attr "mode" "QI")
18945 (set_attr "prefix_rep" "1")])
18947 (define_insn "*cmpstrnqi_nz_rex_1"
18948 [(set (reg:CC FLAGS_REG)
18949 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18950 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18951 (use (match_operand:DI 6 "register_operand" "2"))
18952 (use (match_operand:SI 3 "immediate_operand" "i"))
18953 (clobber (match_operand:DI 0 "register_operand" "=S"))
18954 (clobber (match_operand:DI 1 "register_operand" "=D"))
18955 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18958 [(set_attr "type" "str")
18959 (set_attr "mode" "QI")
18960 (set_attr "prefix_rep" "1")])
18962 ;; The same, but the count is not known to not be zero.
18964 (define_expand "cmpstrnqi_1"
18965 [(parallel [(set (reg:CC FLAGS_REG)
18966 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18968 (compare:CC (match_operand 4 "memory_operand" "")
18969 (match_operand 5 "memory_operand" ""))
18971 (use (match_operand:SI 3 "immediate_operand" ""))
18972 (use (reg:CC FLAGS_REG))
18973 (clobber (match_operand 0 "register_operand" ""))
18974 (clobber (match_operand 1 "register_operand" ""))
18975 (clobber (match_dup 2))])]
18977 "ix86_current_function_needs_cld = 1;")
18979 (define_insn "*cmpstrnqi_1"
18980 [(set (reg:CC FLAGS_REG)
18981 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18983 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18984 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18986 (use (match_operand:SI 3 "immediate_operand" "i"))
18987 (use (reg:CC FLAGS_REG))
18988 (clobber (match_operand:SI 0 "register_operand" "=S"))
18989 (clobber (match_operand:SI 1 "register_operand" "=D"))
18990 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18993 [(set_attr "type" "str")
18994 (set_attr "mode" "QI")
18995 (set_attr "prefix_rep" "1")])
18997 (define_insn "*cmpstrnqi_rex_1"
18998 [(set (reg:CC FLAGS_REG)
18999 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19001 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19002 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19004 (use (match_operand:SI 3 "immediate_operand" "i"))
19005 (use (reg:CC FLAGS_REG))
19006 (clobber (match_operand:DI 0 "register_operand" "=S"))
19007 (clobber (match_operand:DI 1 "register_operand" "=D"))
19008 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19011 [(set_attr "type" "str")
19012 (set_attr "mode" "QI")
19013 (set_attr "prefix_rep" "1")])
19015 (define_expand "strlensi"
19016 [(set (match_operand:SI 0 "register_operand" "")
19017 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19018 (match_operand:QI 2 "immediate_operand" "")
19019 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19022 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19028 (define_expand "strlendi"
19029 [(set (match_operand:DI 0 "register_operand" "")
19030 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19031 (match_operand:QI 2 "immediate_operand" "")
19032 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19035 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19041 (define_expand "strlenqi_1"
19042 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19043 (clobber (match_operand 1 "register_operand" ""))
19044 (clobber (reg:CC FLAGS_REG))])]
19046 "ix86_current_function_needs_cld = 1;")
19048 (define_insn "*strlenqi_1"
19049 [(set (match_operand:SI 0 "register_operand" "=&c")
19050 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19051 (match_operand:QI 2 "register_operand" "a")
19052 (match_operand:SI 3 "immediate_operand" "i")
19053 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19054 (clobber (match_operand:SI 1 "register_operand" "=D"))
19055 (clobber (reg:CC FLAGS_REG))]
19058 [(set_attr "type" "str")
19059 (set_attr "mode" "QI")
19060 (set_attr "prefix_rep" "1")])
19062 (define_insn "*strlenqi_rex_1"
19063 [(set (match_operand:DI 0 "register_operand" "=&c")
19064 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19065 (match_operand:QI 2 "register_operand" "a")
19066 (match_operand:DI 3 "immediate_operand" "i")
19067 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19068 (clobber (match_operand:DI 1 "register_operand" "=D"))
19069 (clobber (reg:CC FLAGS_REG))]
19072 [(set_attr "type" "str")
19073 (set_attr "mode" "QI")
19074 (set_attr "prefix_rep" "1")])
19076 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19077 ;; handled in combine, but it is not currently up to the task.
19078 ;; When used for their truth value, the cmpstrn* expanders generate
19087 ;; The intermediate three instructions are unnecessary.
19089 ;; This one handles cmpstrn*_nz_1...
19092 (set (reg:CC FLAGS_REG)
19093 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19094 (mem:BLK (match_operand 5 "register_operand" ""))))
19095 (use (match_operand 6 "register_operand" ""))
19096 (use (match_operand:SI 3 "immediate_operand" ""))
19097 (clobber (match_operand 0 "register_operand" ""))
19098 (clobber (match_operand 1 "register_operand" ""))
19099 (clobber (match_operand 2 "register_operand" ""))])
19100 (set (match_operand:QI 7 "register_operand" "")
19101 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19102 (set (match_operand:QI 8 "register_operand" "")
19103 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19104 (set (reg FLAGS_REG)
19105 (compare (match_dup 7) (match_dup 8)))
19107 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19109 (set (reg:CC FLAGS_REG)
19110 (compare:CC (mem:BLK (match_dup 4))
19111 (mem:BLK (match_dup 5))))
19112 (use (match_dup 6))
19113 (use (match_dup 3))
19114 (clobber (match_dup 0))
19115 (clobber (match_dup 1))
19116 (clobber (match_dup 2))])]
19119 ;; ...and this one handles cmpstrn*_1.
19122 (set (reg:CC FLAGS_REG)
19123 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19125 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19126 (mem:BLK (match_operand 5 "register_operand" "")))
19128 (use (match_operand:SI 3 "immediate_operand" ""))
19129 (use (reg:CC FLAGS_REG))
19130 (clobber (match_operand 0 "register_operand" ""))
19131 (clobber (match_operand 1 "register_operand" ""))
19132 (clobber (match_operand 2 "register_operand" ""))])
19133 (set (match_operand:QI 7 "register_operand" "")
19134 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19135 (set (match_operand:QI 8 "register_operand" "")
19136 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19137 (set (reg FLAGS_REG)
19138 (compare (match_dup 7) (match_dup 8)))
19140 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19142 (set (reg:CC FLAGS_REG)
19143 (if_then_else:CC (ne (match_dup 6)
19145 (compare:CC (mem:BLK (match_dup 4))
19146 (mem:BLK (match_dup 5)))
19148 (use (match_dup 3))
19149 (use (reg:CC FLAGS_REG))
19150 (clobber (match_dup 0))
19151 (clobber (match_dup 1))
19152 (clobber (match_dup 2))])]
19157 ;; Conditional move instructions.
19159 (define_expand "movdicc"
19160 [(set (match_operand:DI 0 "register_operand" "")
19161 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19162 (match_operand:DI 2 "general_operand" "")
19163 (match_operand:DI 3 "general_operand" "")))]
19165 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19167 (define_insn "x86_movdicc_0_m1_rex64"
19168 [(set (match_operand:DI 0 "register_operand" "=r")
19169 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19172 (clobber (reg:CC FLAGS_REG))]
19175 ; Since we don't have the proper number of operands for an alu insn,
19176 ; fill in all the blanks.
19177 [(set_attr "type" "alu")
19178 (set_attr "pent_pair" "pu")
19179 (set_attr "memory" "none")
19180 (set_attr "imm_disp" "false")
19181 (set_attr "mode" "DI")
19182 (set_attr "length_immediate" "0")])
19184 (define_insn "*x86_movdicc_0_m1_se"
19185 [(set (match_operand:DI 0 "register_operand" "=r")
19186 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19189 (clobber (reg:CC FLAGS_REG))]
19192 [(set_attr "type" "alu")
19193 (set_attr "pent_pair" "pu")
19194 (set_attr "memory" "none")
19195 (set_attr "imm_disp" "false")
19196 (set_attr "mode" "DI")
19197 (set_attr "length_immediate" "0")])
19199 (define_insn "*movdicc_c_rex64"
19200 [(set (match_operand:DI 0 "register_operand" "=r,r")
19201 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19202 [(reg FLAGS_REG) (const_int 0)])
19203 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19204 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19205 "TARGET_64BIT && TARGET_CMOVE
19206 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19208 cmov%O2%C1\t{%2, %0|%0, %2}
19209 cmov%O2%c1\t{%3, %0|%0, %3}"
19210 [(set_attr "type" "icmov")
19211 (set_attr "mode" "DI")])
19213 (define_expand "movsicc"
19214 [(set (match_operand:SI 0 "register_operand" "")
19215 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19216 (match_operand:SI 2 "general_operand" "")
19217 (match_operand:SI 3 "general_operand" "")))]
19219 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19221 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19222 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19223 ;; So just document what we're doing explicitly.
19225 (define_insn "x86_movsicc_0_m1"
19226 [(set (match_operand:SI 0 "register_operand" "=r")
19227 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19230 (clobber (reg:CC FLAGS_REG))]
19233 ; Since we don't have the proper number of operands for an alu insn,
19234 ; fill in all the blanks.
19235 [(set_attr "type" "alu")
19236 (set_attr "pent_pair" "pu")
19237 (set_attr "memory" "none")
19238 (set_attr "imm_disp" "false")
19239 (set_attr "mode" "SI")
19240 (set_attr "length_immediate" "0")])
19242 (define_insn "*x86_movsicc_0_m1_se"
19243 [(set (match_operand:SI 0 "register_operand" "=r")
19244 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19247 (clobber (reg:CC FLAGS_REG))]
19250 [(set_attr "type" "alu")
19251 (set_attr "pent_pair" "pu")
19252 (set_attr "memory" "none")
19253 (set_attr "imm_disp" "false")
19254 (set_attr "mode" "SI")
19255 (set_attr "length_immediate" "0")])
19257 (define_insn "*movsicc_noc"
19258 [(set (match_operand:SI 0 "register_operand" "=r,r")
19259 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19260 [(reg FLAGS_REG) (const_int 0)])
19261 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19262 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19264 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19266 cmov%O2%C1\t{%2, %0|%0, %2}
19267 cmov%O2%c1\t{%3, %0|%0, %3}"
19268 [(set_attr "type" "icmov")
19269 (set_attr "mode" "SI")])
19271 (define_expand "movhicc"
19272 [(set (match_operand:HI 0 "register_operand" "")
19273 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19274 (match_operand:HI 2 "general_operand" "")
19275 (match_operand:HI 3 "general_operand" "")))]
19276 "TARGET_HIMODE_MATH"
19277 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19279 (define_insn "*movhicc_noc"
19280 [(set (match_operand:HI 0 "register_operand" "=r,r")
19281 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19282 [(reg FLAGS_REG) (const_int 0)])
19283 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19284 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19286 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19288 cmov%O2%C1\t{%2, %0|%0, %2}
19289 cmov%O2%c1\t{%3, %0|%0, %3}"
19290 [(set_attr "type" "icmov")
19291 (set_attr "mode" "HI")])
19293 (define_expand "movqicc"
19294 [(set (match_operand:QI 0 "register_operand" "")
19295 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19296 (match_operand:QI 2 "general_operand" "")
19297 (match_operand:QI 3 "general_operand" "")))]
19298 "TARGET_QIMODE_MATH"
19299 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19301 (define_insn_and_split "*movqicc_noc"
19302 [(set (match_operand:QI 0 "register_operand" "=r,r")
19303 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19304 [(match_operand 4 "flags_reg_operand" "")
19306 (match_operand:QI 2 "register_operand" "r,0")
19307 (match_operand:QI 3 "register_operand" "0,r")))]
19308 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19310 "&& reload_completed"
19311 [(set (match_dup 0)
19312 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19315 "operands[0] = gen_lowpart (SImode, operands[0]);
19316 operands[2] = gen_lowpart (SImode, operands[2]);
19317 operands[3] = gen_lowpart (SImode, operands[3]);"
19318 [(set_attr "type" "icmov")
19319 (set_attr "mode" "SI")])
19321 (define_expand "mov<mode>cc"
19322 [(set (match_operand:X87MODEF 0 "register_operand" "")
19323 (if_then_else:X87MODEF
19324 (match_operand 1 "comparison_operator" "")
19325 (match_operand:X87MODEF 2 "register_operand" "")
19326 (match_operand:X87MODEF 3 "register_operand" "")))]
19327 "(TARGET_80387 && TARGET_CMOVE)
19328 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19329 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19331 (define_insn "*movsfcc_1_387"
19332 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19333 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19334 [(reg FLAGS_REG) (const_int 0)])
19335 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19336 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19337 "TARGET_80387 && TARGET_CMOVE
19338 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19340 fcmov%F1\t{%2, %0|%0, %2}
19341 fcmov%f1\t{%3, %0|%0, %3}
19342 cmov%O2%C1\t{%2, %0|%0, %2}
19343 cmov%O2%c1\t{%3, %0|%0, %3}"
19344 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19345 (set_attr "mode" "SF,SF,SI,SI")])
19347 (define_insn "*movdfcc_1"
19348 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19349 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19350 [(reg FLAGS_REG) (const_int 0)])
19351 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19352 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19353 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19354 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19356 fcmov%F1\t{%2, %0|%0, %2}
19357 fcmov%f1\t{%3, %0|%0, %3}
19360 [(set_attr "type" "fcmov,fcmov,multi,multi")
19361 (set_attr "mode" "DF")])
19363 (define_insn "*movdfcc_1_rex64"
19364 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19365 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19366 [(reg FLAGS_REG) (const_int 0)])
19367 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19368 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19369 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19370 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19372 fcmov%F1\t{%2, %0|%0, %2}
19373 fcmov%f1\t{%3, %0|%0, %3}
19374 cmov%O2%C1\t{%2, %0|%0, %2}
19375 cmov%O2%c1\t{%3, %0|%0, %3}"
19376 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19377 (set_attr "mode" "DF")])
19380 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19381 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19382 [(match_operand 4 "flags_reg_operand" "")
19384 (match_operand:DF 2 "nonimmediate_operand" "")
19385 (match_operand:DF 3 "nonimmediate_operand" "")))]
19386 "!TARGET_64BIT && reload_completed"
19387 [(set (match_dup 2)
19388 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19392 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19395 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19396 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19398 (define_insn "*movxfcc_1"
19399 [(set (match_operand:XF 0 "register_operand" "=f,f")
19400 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19401 [(reg FLAGS_REG) (const_int 0)])
19402 (match_operand:XF 2 "register_operand" "f,0")
19403 (match_operand:XF 3 "register_operand" "0,f")))]
19404 "TARGET_80387 && TARGET_CMOVE"
19406 fcmov%F1\t{%2, %0|%0, %2}
19407 fcmov%f1\t{%3, %0|%0, %3}"
19408 [(set_attr "type" "fcmov")
19409 (set_attr "mode" "XF")])
19411 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19412 ;; the scalar versions to have only XMM registers as operands.
19414 ;; SSE5 conditional move
19415 (define_insn "*sse5_pcmov_<mode>"
19416 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19417 (if_then_else:MODEF
19418 (match_operand:MODEF 1 "register_operand" "x,0")
19419 (match_operand:MODEF 2 "register_operand" "0,x")
19420 (match_operand:MODEF 3 "register_operand" "x,x")))]
19421 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19422 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19423 [(set_attr "type" "sse4arg")])
19425 ;; These versions of the min/max patterns are intentionally ignorant of
19426 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19427 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19428 ;; are undefined in this condition, we're certain this is correct.
19430 (define_insn "<code><mode>3"
19431 [(set (match_operand:MODEF 0 "register_operand" "=x")
19433 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19434 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19435 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19436 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19437 [(set_attr "type" "sseadd")
19438 (set_attr "mode" "<MODE>")])
19440 ;; These versions of the min/max patterns implement exactly the operations
19441 ;; min = (op1 < op2 ? op1 : op2)
19442 ;; max = (!(op1 < op2) ? op1 : op2)
19443 ;; Their operands are not commutative, and thus they may be used in the
19444 ;; presence of -0.0 and NaN.
19446 (define_insn "*ieee_smin<mode>3"
19447 [(set (match_operand:MODEF 0 "register_operand" "=x")
19449 [(match_operand:MODEF 1 "register_operand" "0")
19450 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19452 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19453 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19454 [(set_attr "type" "sseadd")
19455 (set_attr "mode" "<MODE>")])
19457 (define_insn "*ieee_smax<mode>3"
19458 [(set (match_operand:MODEF 0 "register_operand" "=x")
19460 [(match_operand:MODEF 1 "register_operand" "0")
19461 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19463 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19464 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19465 [(set_attr "type" "sseadd")
19466 (set_attr "mode" "<MODE>")])
19468 ;; Make two stack loads independent:
19470 ;; fld %st(0) -> fld bb
19471 ;; fmul bb fmul %st(1), %st
19473 ;; Actually we only match the last two instructions for simplicity.
19475 [(set (match_operand 0 "fp_register_operand" "")
19476 (match_operand 1 "fp_register_operand" ""))
19478 (match_operator 2 "binary_fp_operator"
19480 (match_operand 3 "memory_operand" "")]))]
19481 "REGNO (operands[0]) != REGNO (operands[1])"
19482 [(set (match_dup 0) (match_dup 3))
19483 (set (match_dup 0) (match_dup 4))]
19485 ;; The % modifier is not operational anymore in peephole2's, so we have to
19486 ;; swap the operands manually in the case of addition and multiplication.
19487 "if (COMMUTATIVE_ARITH_P (operands[2]))
19488 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19489 operands[0], operands[1]);
19491 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19492 operands[1], operands[0]);")
19494 ;; Conditional addition patterns
19495 (define_expand "add<mode>cc"
19496 [(match_operand:SWI 0 "register_operand" "")
19497 (match_operand 1 "comparison_operator" "")
19498 (match_operand:SWI 2 "register_operand" "")
19499 (match_operand:SWI 3 "const_int_operand" "")]
19501 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19504 ;; Misc patterns (?)
19506 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19507 ;; Otherwise there will be nothing to keep
19509 ;; [(set (reg ebp) (reg esp))]
19510 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19511 ;; (clobber (eflags)]
19512 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19514 ;; in proper program order.
19515 (define_insn "pro_epilogue_adjust_stack_1"
19516 [(set (match_operand:SI 0 "register_operand" "=r,r")
19517 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19518 (match_operand:SI 2 "immediate_operand" "i,i")))
19519 (clobber (reg:CC FLAGS_REG))
19520 (clobber (mem:BLK (scratch)))]
19523 switch (get_attr_type (insn))
19526 return "mov{l}\t{%1, %0|%0, %1}";
19529 if (CONST_INT_P (operands[2])
19530 && (INTVAL (operands[2]) == 128
19531 || (INTVAL (operands[2]) < 0
19532 && INTVAL (operands[2]) != -128)))
19534 operands[2] = GEN_INT (-INTVAL (operands[2]));
19535 return "sub{l}\t{%2, %0|%0, %2}";
19537 return "add{l}\t{%2, %0|%0, %2}";
19540 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19541 return "lea{l}\t{%a2, %0|%0, %a2}";
19544 gcc_unreachable ();
19547 [(set (attr "type")
19548 (cond [(eq_attr "alternative" "0")
19549 (const_string "alu")
19550 (match_operand:SI 2 "const0_operand" "")
19551 (const_string "imov")
19553 (const_string "lea")))
19554 (set_attr "mode" "SI")])
19556 (define_insn "pro_epilogue_adjust_stack_rex64"
19557 [(set (match_operand:DI 0 "register_operand" "=r,r")
19558 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19559 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19560 (clobber (reg:CC FLAGS_REG))
19561 (clobber (mem:BLK (scratch)))]
19564 switch (get_attr_type (insn))
19567 return "mov{q}\t{%1, %0|%0, %1}";
19570 if (CONST_INT_P (operands[2])
19571 /* Avoid overflows. */
19572 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19573 && (INTVAL (operands[2]) == 128
19574 || (INTVAL (operands[2]) < 0
19575 && INTVAL (operands[2]) != -128)))
19577 operands[2] = GEN_INT (-INTVAL (operands[2]));
19578 return "sub{q}\t{%2, %0|%0, %2}";
19580 return "add{q}\t{%2, %0|%0, %2}";
19583 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19584 return "lea{q}\t{%a2, %0|%0, %a2}";
19587 gcc_unreachable ();
19590 [(set (attr "type")
19591 (cond [(eq_attr "alternative" "0")
19592 (const_string "alu")
19593 (match_operand:DI 2 "const0_operand" "")
19594 (const_string "imov")
19596 (const_string "lea")))
19597 (set_attr "mode" "DI")])
19599 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19600 [(set (match_operand:DI 0 "register_operand" "=r,r")
19601 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19602 (match_operand:DI 3 "immediate_operand" "i,i")))
19603 (use (match_operand:DI 2 "register_operand" "r,r"))
19604 (clobber (reg:CC FLAGS_REG))
19605 (clobber (mem:BLK (scratch)))]
19608 switch (get_attr_type (insn))
19611 return "add{q}\t{%2, %0|%0, %2}";
19614 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19615 return "lea{q}\t{%a2, %0|%0, %a2}";
19618 gcc_unreachable ();
19621 [(set_attr "type" "alu,lea")
19622 (set_attr "mode" "DI")])
19624 (define_insn "allocate_stack_worker_32"
19625 [(set (match_operand:SI 0 "register_operand" "+a")
19626 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19627 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19628 (clobber (reg:CC FLAGS_REG))]
19629 "!TARGET_64BIT && TARGET_STACK_PROBE"
19631 [(set_attr "type" "multi")
19632 (set_attr "length" "5")])
19634 (define_insn "allocate_stack_worker_64"
19635 [(set (match_operand:DI 0 "register_operand" "+a")
19636 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19637 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19638 (clobber (reg:DI R10_REG))
19639 (clobber (reg:DI R11_REG))
19640 (clobber (reg:CC FLAGS_REG))]
19641 "TARGET_64BIT && TARGET_STACK_PROBE"
19643 [(set_attr "type" "multi")
19644 (set_attr "length" "5")])
19646 (define_expand "allocate_stack"
19647 [(match_operand 0 "register_operand" "")
19648 (match_operand 1 "general_operand" "")]
19649 "TARGET_STACK_PROBE"
19653 #ifndef CHECK_STACK_LIMIT
19654 #define CHECK_STACK_LIMIT 0
19657 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19658 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19660 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19661 stack_pointer_rtx, 0, OPTAB_DIRECT);
19662 if (x != stack_pointer_rtx)
19663 emit_move_insn (stack_pointer_rtx, x);
19667 x = copy_to_mode_reg (Pmode, operands[1]);
19669 x = gen_allocate_stack_worker_64 (x);
19671 x = gen_allocate_stack_worker_32 (x);
19675 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19679 (define_expand "builtin_setjmp_receiver"
19680 [(label_ref (match_operand 0 "" ""))]
19681 "!TARGET_64BIT && flag_pic"
19686 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19687 rtx label_rtx = gen_label_rtx ();
19688 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19689 xops[0] = xops[1] = picreg;
19690 xops[2] = gen_rtx_CONST (SImode,
19691 gen_rtx_MINUS (SImode,
19692 gen_rtx_LABEL_REF (SImode, label_rtx),
19693 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19694 ix86_expand_binary_operator (MINUS, SImode, xops);
19697 emit_insn (gen_set_got (pic_offset_table_rtx));
19701 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19704 [(set (match_operand 0 "register_operand" "")
19705 (match_operator 3 "promotable_binary_operator"
19706 [(match_operand 1 "register_operand" "")
19707 (match_operand 2 "aligned_operand" "")]))
19708 (clobber (reg:CC FLAGS_REG))]
19709 "! TARGET_PARTIAL_REG_STALL && reload_completed
19710 && ((GET_MODE (operands[0]) == HImode
19711 && ((!optimize_size && !TARGET_FAST_PREFIX)
19712 /* ??? next two lines just !satisfies_constraint_K (...) */
19713 || !CONST_INT_P (operands[2])
19714 || satisfies_constraint_K (operands[2])))
19715 || (GET_MODE (operands[0]) == QImode
19716 && (TARGET_PROMOTE_QImode || optimize_size)))"
19717 [(parallel [(set (match_dup 0)
19718 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19719 (clobber (reg:CC FLAGS_REG))])]
19720 "operands[0] = gen_lowpart (SImode, operands[0]);
19721 operands[1] = gen_lowpart (SImode, operands[1]);
19722 if (GET_CODE (operands[3]) != ASHIFT)
19723 operands[2] = gen_lowpart (SImode, operands[2]);
19724 PUT_MODE (operands[3], SImode);")
19726 ; Promote the QImode tests, as i386 has encoding of the AND
19727 ; instruction with 32-bit sign-extended immediate and thus the
19728 ; instruction size is unchanged, except in the %eax case for
19729 ; which it is increased by one byte, hence the ! optimize_size.
19731 [(set (match_operand 0 "flags_reg_operand" "")
19732 (match_operator 2 "compare_operator"
19733 [(and (match_operand 3 "aligned_operand" "")
19734 (match_operand 4 "const_int_operand" ""))
19736 (set (match_operand 1 "register_operand" "")
19737 (and (match_dup 3) (match_dup 4)))]
19738 "! TARGET_PARTIAL_REG_STALL && reload_completed
19740 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19741 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19742 /* Ensure that the operand will remain sign-extended immediate. */
19743 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19744 [(parallel [(set (match_dup 0)
19745 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19748 (and:SI (match_dup 3) (match_dup 4)))])]
19751 = gen_int_mode (INTVAL (operands[4])
19752 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19753 operands[1] = gen_lowpart (SImode, operands[1]);
19754 operands[3] = gen_lowpart (SImode, operands[3]);
19757 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19758 ; the TEST instruction with 32-bit sign-extended immediate and thus
19759 ; the instruction size would at least double, which is not what we
19760 ; want even with ! optimize_size.
19762 [(set (match_operand 0 "flags_reg_operand" "")
19763 (match_operator 1 "compare_operator"
19764 [(and (match_operand:HI 2 "aligned_operand" "")
19765 (match_operand:HI 3 "const_int_operand" ""))
19767 "! TARGET_PARTIAL_REG_STALL && reload_completed
19768 && ! TARGET_FAST_PREFIX
19770 /* Ensure that the operand will remain sign-extended immediate. */
19771 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19772 [(set (match_dup 0)
19773 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19777 = gen_int_mode (INTVAL (operands[3])
19778 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19779 operands[2] = gen_lowpart (SImode, operands[2]);
19783 [(set (match_operand 0 "register_operand" "")
19784 (neg (match_operand 1 "register_operand" "")))
19785 (clobber (reg:CC FLAGS_REG))]
19786 "! TARGET_PARTIAL_REG_STALL && reload_completed
19787 && (GET_MODE (operands[0]) == HImode
19788 || (GET_MODE (operands[0]) == QImode
19789 && (TARGET_PROMOTE_QImode || optimize_size)))"
19790 [(parallel [(set (match_dup 0)
19791 (neg:SI (match_dup 1)))
19792 (clobber (reg:CC FLAGS_REG))])]
19793 "operands[0] = gen_lowpart (SImode, operands[0]);
19794 operands[1] = gen_lowpart (SImode, operands[1]);")
19797 [(set (match_operand 0 "register_operand" "")
19798 (not (match_operand 1 "register_operand" "")))]
19799 "! TARGET_PARTIAL_REG_STALL && reload_completed
19800 && (GET_MODE (operands[0]) == HImode
19801 || (GET_MODE (operands[0]) == QImode
19802 && (TARGET_PROMOTE_QImode || optimize_size)))"
19803 [(set (match_dup 0)
19804 (not:SI (match_dup 1)))]
19805 "operands[0] = gen_lowpart (SImode, operands[0]);
19806 operands[1] = gen_lowpart (SImode, operands[1]);")
19809 [(set (match_operand 0 "register_operand" "")
19810 (if_then_else (match_operator 1 "comparison_operator"
19811 [(reg FLAGS_REG) (const_int 0)])
19812 (match_operand 2 "register_operand" "")
19813 (match_operand 3 "register_operand" "")))]
19814 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19815 && (GET_MODE (operands[0]) == HImode
19816 || (GET_MODE (operands[0]) == QImode
19817 && (TARGET_PROMOTE_QImode || optimize_size)))"
19818 [(set (match_dup 0)
19819 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19820 "operands[0] = gen_lowpart (SImode, operands[0]);
19821 operands[2] = gen_lowpart (SImode, operands[2]);
19822 operands[3] = gen_lowpart (SImode, operands[3]);")
19825 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19826 ;; transform a complex memory operation into two memory to register operations.
19828 ;; Don't push memory operands
19830 [(set (match_operand:SI 0 "push_operand" "")
19831 (match_operand:SI 1 "memory_operand" ""))
19832 (match_scratch:SI 2 "r")]
19833 "!optimize_size && !TARGET_PUSH_MEMORY
19834 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19835 [(set (match_dup 2) (match_dup 1))
19836 (set (match_dup 0) (match_dup 2))]
19840 [(set (match_operand:DI 0 "push_operand" "")
19841 (match_operand:DI 1 "memory_operand" ""))
19842 (match_scratch:DI 2 "r")]
19843 "!optimize_size && !TARGET_PUSH_MEMORY
19844 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19845 [(set (match_dup 2) (match_dup 1))
19846 (set (match_dup 0) (match_dup 2))]
19849 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19852 [(set (match_operand:SF 0 "push_operand" "")
19853 (match_operand:SF 1 "memory_operand" ""))
19854 (match_scratch:SF 2 "r")]
19855 "!optimize_size && !TARGET_PUSH_MEMORY
19856 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19857 [(set (match_dup 2) (match_dup 1))
19858 (set (match_dup 0) (match_dup 2))]
19862 [(set (match_operand:HI 0 "push_operand" "")
19863 (match_operand:HI 1 "memory_operand" ""))
19864 (match_scratch:HI 2 "r")]
19865 "!optimize_size && !TARGET_PUSH_MEMORY
19866 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19867 [(set (match_dup 2) (match_dup 1))
19868 (set (match_dup 0) (match_dup 2))]
19872 [(set (match_operand:QI 0 "push_operand" "")
19873 (match_operand:QI 1 "memory_operand" ""))
19874 (match_scratch:QI 2 "q")]
19875 "!optimize_size && !TARGET_PUSH_MEMORY
19876 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19877 [(set (match_dup 2) (match_dup 1))
19878 (set (match_dup 0) (match_dup 2))]
19881 ;; Don't move an immediate directly to memory when the instruction
19884 [(match_scratch:SI 1 "r")
19885 (set (match_operand:SI 0 "memory_operand" "")
19888 && ! TARGET_USE_MOV0
19889 && TARGET_SPLIT_LONG_MOVES
19890 && get_attr_length (insn) >= ix86_cost->large_insn
19891 && peep2_regno_dead_p (0, FLAGS_REG)"
19892 [(parallel [(set (match_dup 1) (const_int 0))
19893 (clobber (reg:CC FLAGS_REG))])
19894 (set (match_dup 0) (match_dup 1))]
19898 [(match_scratch:HI 1 "r")
19899 (set (match_operand:HI 0 "memory_operand" "")
19902 && ! TARGET_USE_MOV0
19903 && TARGET_SPLIT_LONG_MOVES
19904 && get_attr_length (insn) >= ix86_cost->large_insn
19905 && peep2_regno_dead_p (0, FLAGS_REG)"
19906 [(parallel [(set (match_dup 2) (const_int 0))
19907 (clobber (reg:CC FLAGS_REG))])
19908 (set (match_dup 0) (match_dup 1))]
19909 "operands[2] = gen_lowpart (SImode, operands[1]);")
19912 [(match_scratch:QI 1 "q")
19913 (set (match_operand:QI 0 "memory_operand" "")
19916 && ! TARGET_USE_MOV0
19917 && TARGET_SPLIT_LONG_MOVES
19918 && get_attr_length (insn) >= ix86_cost->large_insn
19919 && peep2_regno_dead_p (0, FLAGS_REG)"
19920 [(parallel [(set (match_dup 2) (const_int 0))
19921 (clobber (reg:CC FLAGS_REG))])
19922 (set (match_dup 0) (match_dup 1))]
19923 "operands[2] = gen_lowpart (SImode, operands[1]);")
19926 [(match_scratch:SI 2 "r")
19927 (set (match_operand:SI 0 "memory_operand" "")
19928 (match_operand:SI 1 "immediate_operand" ""))]
19930 && TARGET_SPLIT_LONG_MOVES
19931 && get_attr_length (insn) >= ix86_cost->large_insn"
19932 [(set (match_dup 2) (match_dup 1))
19933 (set (match_dup 0) (match_dup 2))]
19937 [(match_scratch:HI 2 "r")
19938 (set (match_operand:HI 0 "memory_operand" "")
19939 (match_operand:HI 1 "immediate_operand" ""))]
19941 && TARGET_SPLIT_LONG_MOVES
19942 && get_attr_length (insn) >= ix86_cost->large_insn"
19943 [(set (match_dup 2) (match_dup 1))
19944 (set (match_dup 0) (match_dup 2))]
19948 [(match_scratch:QI 2 "q")
19949 (set (match_operand:QI 0 "memory_operand" "")
19950 (match_operand:QI 1 "immediate_operand" ""))]
19952 && TARGET_SPLIT_LONG_MOVES
19953 && get_attr_length (insn) >= ix86_cost->large_insn"
19954 [(set (match_dup 2) (match_dup 1))
19955 (set (match_dup 0) (match_dup 2))]
19958 ;; Don't compare memory with zero, load and use a test instead.
19960 [(set (match_operand 0 "flags_reg_operand" "")
19961 (match_operator 1 "compare_operator"
19962 [(match_operand:SI 2 "memory_operand" "")
19964 (match_scratch:SI 3 "r")]
19965 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
19966 [(set (match_dup 3) (match_dup 2))
19967 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19970 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19971 ;; Don't split NOTs with a displacement operand, because resulting XOR
19972 ;; will not be pairable anyway.
19974 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19975 ;; represented using a modRM byte. The XOR replacement is long decoded,
19976 ;; so this split helps here as well.
19978 ;; Note: Can't do this as a regular split because we can't get proper
19979 ;; lifetime information then.
19982 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19983 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19985 && ((TARGET_NOT_UNPAIRABLE
19986 && (!MEM_P (operands[0])
19987 || !memory_displacement_operand (operands[0], SImode)))
19988 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19989 && peep2_regno_dead_p (0, FLAGS_REG)"
19990 [(parallel [(set (match_dup 0)
19991 (xor:SI (match_dup 1) (const_int -1)))
19992 (clobber (reg:CC FLAGS_REG))])]
19996 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19997 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19999 && ((TARGET_NOT_UNPAIRABLE
20000 && (!MEM_P (operands[0])
20001 || !memory_displacement_operand (operands[0], HImode)))
20002 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20003 && peep2_regno_dead_p (0, FLAGS_REG)"
20004 [(parallel [(set (match_dup 0)
20005 (xor:HI (match_dup 1) (const_int -1)))
20006 (clobber (reg:CC FLAGS_REG))])]
20010 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20011 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20013 && ((TARGET_NOT_UNPAIRABLE
20014 && (!MEM_P (operands[0])
20015 || !memory_displacement_operand (operands[0], QImode)))
20016 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20017 && peep2_regno_dead_p (0, FLAGS_REG)"
20018 [(parallel [(set (match_dup 0)
20019 (xor:QI (match_dup 1) (const_int -1)))
20020 (clobber (reg:CC FLAGS_REG))])]
20023 ;; Non pairable "test imm, reg" instructions can be translated to
20024 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20025 ;; byte opcode instead of two, have a short form for byte operands),
20026 ;; so do it for other CPUs as well. Given that the value was dead,
20027 ;; this should not create any new dependencies. Pass on the sub-word
20028 ;; versions if we're concerned about partial register stalls.
20031 [(set (match_operand 0 "flags_reg_operand" "")
20032 (match_operator 1 "compare_operator"
20033 [(and:SI (match_operand:SI 2 "register_operand" "")
20034 (match_operand:SI 3 "immediate_operand" ""))
20036 "ix86_match_ccmode (insn, CCNOmode)
20037 && (true_regnum (operands[2]) != AX_REG
20038 || satisfies_constraint_K (operands[3]))
20039 && peep2_reg_dead_p (1, operands[2])"
20041 [(set (match_dup 0)
20042 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20045 (and:SI (match_dup 2) (match_dup 3)))])]
20048 ;; We don't need to handle HImode case, because it will be promoted to SImode
20049 ;; on ! TARGET_PARTIAL_REG_STALL
20052 [(set (match_operand 0 "flags_reg_operand" "")
20053 (match_operator 1 "compare_operator"
20054 [(and:QI (match_operand:QI 2 "register_operand" "")
20055 (match_operand:QI 3 "immediate_operand" ""))
20057 "! TARGET_PARTIAL_REG_STALL
20058 && ix86_match_ccmode (insn, CCNOmode)
20059 && true_regnum (operands[2]) != AX_REG
20060 && peep2_reg_dead_p (1, operands[2])"
20062 [(set (match_dup 0)
20063 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20066 (and:QI (match_dup 2) (match_dup 3)))])]
20070 [(set (match_operand 0 "flags_reg_operand" "")
20071 (match_operator 1 "compare_operator"
20074 (match_operand 2 "ext_register_operand" "")
20077 (match_operand 3 "const_int_operand" ""))
20079 "! TARGET_PARTIAL_REG_STALL
20080 && ix86_match_ccmode (insn, CCNOmode)
20081 && true_regnum (operands[2]) != AX_REG
20082 && peep2_reg_dead_p (1, operands[2])"
20083 [(parallel [(set (match_dup 0)
20092 (set (zero_extract:SI (match_dup 2)
20103 ;; Don't do logical operations with memory inputs.
20105 [(match_scratch:SI 2 "r")
20106 (parallel [(set (match_operand:SI 0 "register_operand" "")
20107 (match_operator:SI 3 "arith_or_logical_operator"
20109 (match_operand:SI 1 "memory_operand" "")]))
20110 (clobber (reg:CC FLAGS_REG))])]
20111 "! optimize_size && ! TARGET_READ_MODIFY"
20112 [(set (match_dup 2) (match_dup 1))
20113 (parallel [(set (match_dup 0)
20114 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20115 (clobber (reg:CC FLAGS_REG))])]
20119 [(match_scratch:SI 2 "r")
20120 (parallel [(set (match_operand:SI 0 "register_operand" "")
20121 (match_operator:SI 3 "arith_or_logical_operator"
20122 [(match_operand:SI 1 "memory_operand" "")
20124 (clobber (reg:CC FLAGS_REG))])]
20125 "! optimize_size && ! TARGET_READ_MODIFY"
20126 [(set (match_dup 2) (match_dup 1))
20127 (parallel [(set (match_dup 0)
20128 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20129 (clobber (reg:CC FLAGS_REG))])]
20132 ; Don't do logical operations with memory outputs
20134 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20135 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20136 ; the same decoder scheduling characteristics as the original.
20139 [(match_scratch:SI 2 "r")
20140 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20141 (match_operator:SI 3 "arith_or_logical_operator"
20143 (match_operand:SI 1 "nonmemory_operand" "")]))
20144 (clobber (reg:CC FLAGS_REG))])]
20145 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20146 [(set (match_dup 2) (match_dup 0))
20147 (parallel [(set (match_dup 2)
20148 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20149 (clobber (reg:CC FLAGS_REG))])
20150 (set (match_dup 0) (match_dup 2))]
20154 [(match_scratch:SI 2 "r")
20155 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20156 (match_operator:SI 3 "arith_or_logical_operator"
20157 [(match_operand:SI 1 "nonmemory_operand" "")
20159 (clobber (reg:CC FLAGS_REG))])]
20160 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20161 [(set (match_dup 2) (match_dup 0))
20162 (parallel [(set (match_dup 2)
20163 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20164 (clobber (reg:CC FLAGS_REG))])
20165 (set (match_dup 0) (match_dup 2))]
20168 ;; Attempt to always use XOR for zeroing registers.
20170 [(set (match_operand 0 "register_operand" "")
20171 (match_operand 1 "const0_operand" ""))]
20172 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20173 && (! TARGET_USE_MOV0 || optimize_size)
20174 && GENERAL_REG_P (operands[0])
20175 && peep2_regno_dead_p (0, FLAGS_REG)"
20176 [(parallel [(set (match_dup 0) (const_int 0))
20177 (clobber (reg:CC FLAGS_REG))])]
20179 operands[0] = gen_lowpart (word_mode, operands[0]);
20183 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20185 "(GET_MODE (operands[0]) == QImode
20186 || GET_MODE (operands[0]) == HImode)
20187 && (! TARGET_USE_MOV0 || optimize_size)
20188 && peep2_regno_dead_p (0, FLAGS_REG)"
20189 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20190 (clobber (reg:CC FLAGS_REG))])])
20192 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20194 [(set (match_operand 0 "register_operand" "")
20196 "(GET_MODE (operands[0]) == HImode
20197 || GET_MODE (operands[0]) == SImode
20198 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20199 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20200 && peep2_regno_dead_p (0, FLAGS_REG)"
20201 [(parallel [(set (match_dup 0) (const_int -1))
20202 (clobber (reg:CC FLAGS_REG))])]
20203 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20206 ;; Attempt to convert simple leas to adds. These can be created by
20209 [(set (match_operand:SI 0 "register_operand" "")
20210 (plus:SI (match_dup 0)
20211 (match_operand:SI 1 "nonmemory_operand" "")))]
20212 "peep2_regno_dead_p (0, FLAGS_REG)"
20213 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20214 (clobber (reg:CC FLAGS_REG))])]
20218 [(set (match_operand:SI 0 "register_operand" "")
20219 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20220 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20221 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20222 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20223 (clobber (reg:CC FLAGS_REG))])]
20224 "operands[2] = gen_lowpart (SImode, operands[2]);")
20227 [(set (match_operand:DI 0 "register_operand" "")
20228 (plus:DI (match_dup 0)
20229 (match_operand:DI 1 "x86_64_general_operand" "")))]
20230 "peep2_regno_dead_p (0, FLAGS_REG)"
20231 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20232 (clobber (reg:CC FLAGS_REG))])]
20236 [(set (match_operand:SI 0 "register_operand" "")
20237 (mult:SI (match_dup 0)
20238 (match_operand:SI 1 "const_int_operand" "")))]
20239 "exact_log2 (INTVAL (operands[1])) >= 0
20240 && peep2_regno_dead_p (0, FLAGS_REG)"
20241 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20242 (clobber (reg:CC FLAGS_REG))])]
20243 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20246 [(set (match_operand:DI 0 "register_operand" "")
20247 (mult:DI (match_dup 0)
20248 (match_operand:DI 1 "const_int_operand" "")))]
20249 "exact_log2 (INTVAL (operands[1])) >= 0
20250 && peep2_regno_dead_p (0, FLAGS_REG)"
20251 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20252 (clobber (reg:CC FLAGS_REG))])]
20253 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20256 [(set (match_operand:SI 0 "register_operand" "")
20257 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20258 (match_operand:DI 2 "const_int_operand" "")) 0))]
20259 "exact_log2 (INTVAL (operands[2])) >= 0
20260 && REGNO (operands[0]) == REGNO (operands[1])
20261 && peep2_regno_dead_p (0, FLAGS_REG)"
20262 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20263 (clobber (reg:CC FLAGS_REG))])]
20264 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20266 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20267 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20268 ;; many CPUs it is also faster, since special hardware to avoid esp
20269 ;; dependencies is present.
20271 ;; While some of these conversions may be done using splitters, we use peepholes
20272 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20274 ;; Convert prologue esp subtractions to push.
20275 ;; We need register to push. In order to keep verify_flow_info happy we have
20277 ;; - use scratch and clobber it in order to avoid dependencies
20278 ;; - use already live register
20279 ;; We can't use the second way right now, since there is no reliable way how to
20280 ;; verify that given register is live. First choice will also most likely in
20281 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20282 ;; call clobbered registers are dead. We may want to use base pointer as an
20283 ;; alternative when no register is available later.
20286 [(match_scratch:SI 0 "r")
20287 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20288 (clobber (reg:CC FLAGS_REG))
20289 (clobber (mem:BLK (scratch)))])]
20290 "optimize_size || !TARGET_SUB_ESP_4"
20291 [(clobber (match_dup 0))
20292 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20293 (clobber (mem:BLK (scratch)))])])
20296 [(match_scratch:SI 0 "r")
20297 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20298 (clobber (reg:CC FLAGS_REG))
20299 (clobber (mem:BLK (scratch)))])]
20300 "optimize_size || !TARGET_SUB_ESP_8"
20301 [(clobber (match_dup 0))
20302 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20303 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20304 (clobber (mem:BLK (scratch)))])])
20306 ;; Convert esp subtractions to push.
20308 [(match_scratch:SI 0 "r")
20309 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20310 (clobber (reg:CC FLAGS_REG))])]
20311 "optimize_size || !TARGET_SUB_ESP_4"
20312 [(clobber (match_dup 0))
20313 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20316 [(match_scratch:SI 0 "r")
20317 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20318 (clobber (reg:CC FLAGS_REG))])]
20319 "optimize_size || !TARGET_SUB_ESP_8"
20320 [(clobber (match_dup 0))
20321 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20322 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20324 ;; Convert epilogue deallocator to pop.
20326 [(match_scratch:SI 0 "r")
20327 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20328 (clobber (reg:CC FLAGS_REG))
20329 (clobber (mem:BLK (scratch)))])]
20330 "optimize_size || !TARGET_ADD_ESP_4"
20331 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20332 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20333 (clobber (mem:BLK (scratch)))])]
20336 ;; Two pops case is tricky, since pop causes dependency on destination register.
20337 ;; We use two registers if available.
20339 [(match_scratch:SI 0 "r")
20340 (match_scratch:SI 1 "r")
20341 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20342 (clobber (reg:CC FLAGS_REG))
20343 (clobber (mem:BLK (scratch)))])]
20344 "optimize_size || !TARGET_ADD_ESP_8"
20345 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20346 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20347 (clobber (mem:BLK (scratch)))])
20348 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20349 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20353 [(match_scratch:SI 0 "r")
20354 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20355 (clobber (reg:CC FLAGS_REG))
20356 (clobber (mem:BLK (scratch)))])]
20358 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20359 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20360 (clobber (mem:BLK (scratch)))])
20361 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20362 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20365 ;; Convert esp additions to pop.
20367 [(match_scratch:SI 0 "r")
20368 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20369 (clobber (reg:CC FLAGS_REG))])]
20371 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20372 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20375 ;; Two pops case is tricky, since pop causes dependency on destination register.
20376 ;; We use two registers if available.
20378 [(match_scratch:SI 0 "r")
20379 (match_scratch:SI 1 "r")
20380 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20381 (clobber (reg:CC FLAGS_REG))])]
20383 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20384 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20385 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20386 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20390 [(match_scratch:SI 0 "r")
20391 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20392 (clobber (reg:CC FLAGS_REG))])]
20394 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20395 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20396 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20397 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20400 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20401 ;; required and register dies. Similarly for 128 to plus -128.
20403 [(set (match_operand 0 "flags_reg_operand" "")
20404 (match_operator 1 "compare_operator"
20405 [(match_operand 2 "register_operand" "")
20406 (match_operand 3 "const_int_operand" "")]))]
20407 "(INTVAL (operands[3]) == -1
20408 || INTVAL (operands[3]) == 1
20409 || INTVAL (operands[3]) == 128)
20410 && ix86_match_ccmode (insn, CCGCmode)
20411 && peep2_reg_dead_p (1, operands[2])"
20412 [(parallel [(set (match_dup 0)
20413 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20414 (clobber (match_dup 2))])]
20418 [(match_scratch:DI 0 "r")
20419 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20420 (clobber (reg:CC FLAGS_REG))
20421 (clobber (mem:BLK (scratch)))])]
20422 "optimize_size || !TARGET_SUB_ESP_4"
20423 [(clobber (match_dup 0))
20424 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20425 (clobber (mem:BLK (scratch)))])])
20428 [(match_scratch:DI 0 "r")
20429 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20430 (clobber (reg:CC FLAGS_REG))
20431 (clobber (mem:BLK (scratch)))])]
20432 "optimize_size || !TARGET_SUB_ESP_8"
20433 [(clobber (match_dup 0))
20434 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20435 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20436 (clobber (mem:BLK (scratch)))])])
20438 ;; Convert esp subtractions to push.
20440 [(match_scratch:DI 0 "r")
20441 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20442 (clobber (reg:CC FLAGS_REG))])]
20443 "optimize_size || !TARGET_SUB_ESP_4"
20444 [(clobber (match_dup 0))
20445 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20448 [(match_scratch:DI 0 "r")
20449 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20450 (clobber (reg:CC FLAGS_REG))])]
20451 "optimize_size || !TARGET_SUB_ESP_8"
20452 [(clobber (match_dup 0))
20453 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20454 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20456 ;; Convert epilogue deallocator to pop.
20458 [(match_scratch:DI 0 "r")
20459 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20460 (clobber (reg:CC FLAGS_REG))
20461 (clobber (mem:BLK (scratch)))])]
20462 "optimize_size || !TARGET_ADD_ESP_4"
20463 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20464 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20465 (clobber (mem:BLK (scratch)))])]
20468 ;; Two pops case is tricky, since pop causes dependency on destination register.
20469 ;; We use two registers if available.
20471 [(match_scratch:DI 0 "r")
20472 (match_scratch:DI 1 "r")
20473 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20474 (clobber (reg:CC FLAGS_REG))
20475 (clobber (mem:BLK (scratch)))])]
20476 "optimize_size || !TARGET_ADD_ESP_8"
20477 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20478 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20479 (clobber (mem:BLK (scratch)))])
20480 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20481 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20485 [(match_scratch:DI 0 "r")
20486 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20487 (clobber (reg:CC FLAGS_REG))
20488 (clobber (mem:BLK (scratch)))])]
20490 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20491 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20492 (clobber (mem:BLK (scratch)))])
20493 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20494 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20497 ;; Convert esp additions to pop.
20499 [(match_scratch:DI 0 "r")
20500 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20501 (clobber (reg:CC FLAGS_REG))])]
20503 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20504 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20507 ;; Two pops case is tricky, since pop causes dependency on destination register.
20508 ;; We use two registers if available.
20510 [(match_scratch:DI 0 "r")
20511 (match_scratch:DI 1 "r")
20512 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20513 (clobber (reg:CC FLAGS_REG))])]
20515 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20516 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20517 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20518 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20522 [(match_scratch:DI 0 "r")
20523 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20524 (clobber (reg:CC FLAGS_REG))])]
20526 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20527 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20528 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20529 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20532 ;; Convert imul by three, five and nine into lea
20535 [(set (match_operand:SI 0 "register_operand" "")
20536 (mult:SI (match_operand:SI 1 "register_operand" "")
20537 (match_operand:SI 2 "const_int_operand" "")))
20538 (clobber (reg:CC FLAGS_REG))])]
20539 "INTVAL (operands[2]) == 3
20540 || INTVAL (operands[2]) == 5
20541 || INTVAL (operands[2]) == 9"
20542 [(set (match_dup 0)
20543 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20545 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20549 [(set (match_operand:SI 0 "register_operand" "")
20550 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20551 (match_operand:SI 2 "const_int_operand" "")))
20552 (clobber (reg:CC FLAGS_REG))])]
20554 && (INTVAL (operands[2]) == 3
20555 || INTVAL (operands[2]) == 5
20556 || INTVAL (operands[2]) == 9)"
20557 [(set (match_dup 0) (match_dup 1))
20559 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20561 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20565 [(set (match_operand:DI 0 "register_operand" "")
20566 (mult:DI (match_operand:DI 1 "register_operand" "")
20567 (match_operand:DI 2 "const_int_operand" "")))
20568 (clobber (reg:CC FLAGS_REG))])]
20570 && (INTVAL (operands[2]) == 3
20571 || INTVAL (operands[2]) == 5
20572 || INTVAL (operands[2]) == 9)"
20573 [(set (match_dup 0)
20574 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20576 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20580 [(set (match_operand:DI 0 "register_operand" "")
20581 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20582 (match_operand:DI 2 "const_int_operand" "")))
20583 (clobber (reg:CC FLAGS_REG))])]
20586 && (INTVAL (operands[2]) == 3
20587 || INTVAL (operands[2]) == 5
20588 || INTVAL (operands[2]) == 9)"
20589 [(set (match_dup 0) (match_dup 1))
20591 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20593 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20595 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20596 ;; imul $32bit_imm, reg, reg is direct decoded.
20598 [(match_scratch:DI 3 "r")
20599 (parallel [(set (match_operand:DI 0 "register_operand" "")
20600 (mult:DI (match_operand:DI 1 "memory_operand" "")
20601 (match_operand:DI 2 "immediate_operand" "")))
20602 (clobber (reg:CC FLAGS_REG))])]
20603 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20604 && !satisfies_constraint_K (operands[2])"
20605 [(set (match_dup 3) (match_dup 1))
20606 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20607 (clobber (reg:CC FLAGS_REG))])]
20611 [(match_scratch:SI 3 "r")
20612 (parallel [(set (match_operand:SI 0 "register_operand" "")
20613 (mult:SI (match_operand:SI 1 "memory_operand" "")
20614 (match_operand:SI 2 "immediate_operand" "")))
20615 (clobber (reg:CC FLAGS_REG))])]
20616 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20617 && !satisfies_constraint_K (operands[2])"
20618 [(set (match_dup 3) (match_dup 1))
20619 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20620 (clobber (reg:CC FLAGS_REG))])]
20624 [(match_scratch:SI 3 "r")
20625 (parallel [(set (match_operand:DI 0 "register_operand" "")
20627 (mult:SI (match_operand:SI 1 "memory_operand" "")
20628 (match_operand:SI 2 "immediate_operand" ""))))
20629 (clobber (reg:CC FLAGS_REG))])]
20630 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20631 && !satisfies_constraint_K (operands[2])"
20632 [(set (match_dup 3) (match_dup 1))
20633 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20634 (clobber (reg:CC FLAGS_REG))])]
20637 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20638 ;; Convert it into imul reg, reg
20639 ;; It would be better to force assembler to encode instruction using long
20640 ;; immediate, but there is apparently no way to do so.
20642 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20643 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20644 (match_operand:DI 2 "const_int_operand" "")))
20645 (clobber (reg:CC FLAGS_REG))])
20646 (match_scratch:DI 3 "r")]
20647 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20648 && satisfies_constraint_K (operands[2])"
20649 [(set (match_dup 3) (match_dup 2))
20650 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20651 (clobber (reg:CC FLAGS_REG))])]
20653 if (!rtx_equal_p (operands[0], operands[1]))
20654 emit_move_insn (operands[0], operands[1]);
20658 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20659 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20660 (match_operand:SI 2 "const_int_operand" "")))
20661 (clobber (reg:CC FLAGS_REG))])
20662 (match_scratch:SI 3 "r")]
20663 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20664 && satisfies_constraint_K (operands[2])"
20665 [(set (match_dup 3) (match_dup 2))
20666 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20667 (clobber (reg:CC FLAGS_REG))])]
20669 if (!rtx_equal_p (operands[0], operands[1]))
20670 emit_move_insn (operands[0], operands[1]);
20674 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20675 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20676 (match_operand:HI 2 "immediate_operand" "")))
20677 (clobber (reg:CC FLAGS_REG))])
20678 (match_scratch:HI 3 "r")]
20679 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20680 [(set (match_dup 3) (match_dup 2))
20681 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20682 (clobber (reg:CC FLAGS_REG))])]
20684 if (!rtx_equal_p (operands[0], operands[1]))
20685 emit_move_insn (operands[0], operands[1]);
20688 ;; After splitting up read-modify operations, array accesses with memory
20689 ;; operands might end up in form:
20691 ;; movl 4(%esp), %edx
20693 ;; instead of pre-splitting:
20695 ;; addl 4(%esp), %eax
20697 ;; movl 4(%esp), %edx
20698 ;; leal (%edx,%eax,4), %eax
20701 [(parallel [(set (match_operand 0 "register_operand" "")
20702 (ashift (match_operand 1 "register_operand" "")
20703 (match_operand 2 "const_int_operand" "")))
20704 (clobber (reg:CC FLAGS_REG))])
20705 (set (match_operand 3 "register_operand")
20706 (match_operand 4 "x86_64_general_operand" ""))
20707 (parallel [(set (match_operand 5 "register_operand" "")
20708 (plus (match_operand 6 "register_operand" "")
20709 (match_operand 7 "register_operand" "")))
20710 (clobber (reg:CC FLAGS_REG))])]
20711 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20712 /* Validate MODE for lea. */
20713 && ((!TARGET_PARTIAL_REG_STALL
20714 && (GET_MODE (operands[0]) == QImode
20715 || GET_MODE (operands[0]) == HImode))
20716 || GET_MODE (operands[0]) == SImode
20717 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20718 /* We reorder load and the shift. */
20719 && !rtx_equal_p (operands[1], operands[3])
20720 && !reg_overlap_mentioned_p (operands[0], operands[4])
20721 /* Last PLUS must consist of operand 0 and 3. */
20722 && !rtx_equal_p (operands[0], operands[3])
20723 && (rtx_equal_p (operands[3], operands[6])
20724 || rtx_equal_p (operands[3], operands[7]))
20725 && (rtx_equal_p (operands[0], operands[6])
20726 || rtx_equal_p (operands[0], operands[7]))
20727 /* The intermediate operand 0 must die or be same as output. */
20728 && (rtx_equal_p (operands[0], operands[5])
20729 || peep2_reg_dead_p (3, operands[0]))"
20730 [(set (match_dup 3) (match_dup 4))
20731 (set (match_dup 0) (match_dup 1))]
20733 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20734 int scale = 1 << INTVAL (operands[2]);
20735 rtx index = gen_lowpart (Pmode, operands[1]);
20736 rtx base = gen_lowpart (Pmode, operands[3]);
20737 rtx dest = gen_lowpart (mode, operands[5]);
20739 operands[1] = gen_rtx_PLUS (Pmode, base,
20740 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20742 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20743 operands[0] = dest;
20746 ;; Call-value patterns last so that the wildcard operand does not
20747 ;; disrupt insn-recog's switch tables.
20749 (define_insn "*call_value_pop_0"
20750 [(set (match_operand 0 "" "")
20751 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20752 (match_operand:SI 2 "" "")))
20753 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20754 (match_operand:SI 3 "immediate_operand" "")))]
20757 if (SIBLING_CALL_P (insn))
20760 return "call\t%P1";
20762 [(set_attr "type" "callv")])
20764 (define_insn "*call_value_pop_1"
20765 [(set (match_operand 0 "" "")
20766 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20767 (match_operand:SI 2 "" "")))
20768 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20769 (match_operand:SI 3 "immediate_operand" "i")))]
20772 if (constant_call_address_operand (operands[1], Pmode))
20774 if (SIBLING_CALL_P (insn))
20777 return "call\t%P1";
20779 if (SIBLING_CALL_P (insn))
20782 return "call\t%A1";
20784 [(set_attr "type" "callv")])
20786 (define_insn "*call_value_0"
20787 [(set (match_operand 0 "" "")
20788 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20789 (match_operand:SI 2 "" "")))]
20792 if (SIBLING_CALL_P (insn))
20795 return "call\t%P1";
20797 [(set_attr "type" "callv")])
20799 (define_insn "*call_value_0_rex64"
20800 [(set (match_operand 0 "" "")
20801 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20802 (match_operand:DI 2 "const_int_operand" "")))]
20805 if (SIBLING_CALL_P (insn))
20808 return "call\t%P1";
20810 [(set_attr "type" "callv")])
20812 (define_insn "*call_value_1"
20813 [(set (match_operand 0 "" "")
20814 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20815 (match_operand:SI 2 "" "")))]
20816 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20818 if (constant_call_address_operand (operands[1], Pmode))
20819 return "call\t%P1";
20820 return "call\t%A1";
20822 [(set_attr "type" "callv")])
20824 (define_insn "*sibcall_value_1"
20825 [(set (match_operand 0 "" "")
20826 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20827 (match_operand:SI 2 "" "")))]
20828 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20830 if (constant_call_address_operand (operands[1], Pmode))
20834 [(set_attr "type" "callv")])
20836 (define_insn "*call_value_1_rex64"
20837 [(set (match_operand 0 "" "")
20838 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20839 (match_operand:DI 2 "" "")))]
20840 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20841 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20843 if (constant_call_address_operand (operands[1], Pmode))
20844 return "call\t%P1";
20845 return "call\t%A1";
20847 [(set_attr "type" "callv")])
20849 (define_insn "*call_value_1_rex64_large"
20850 [(set (match_operand 0 "" "")
20851 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20852 (match_operand:DI 2 "" "")))]
20853 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20855 [(set_attr "type" "callv")])
20857 (define_insn "*sibcall_value_1_rex64"
20858 [(set (match_operand 0 "" "")
20859 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20860 (match_operand:DI 2 "" "")))]
20861 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20863 [(set_attr "type" "callv")])
20865 (define_insn "*sibcall_value_1_rex64_v"
20866 [(set (match_operand 0 "" "")
20867 (call (mem:QI (reg:DI R11_REG))
20868 (match_operand:DI 1 "" "")))]
20869 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20871 [(set_attr "type" "callv")])
20873 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20874 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20875 ;; caught for use by garbage collectors and the like. Using an insn that
20876 ;; maps to SIGILL makes it more likely the program will rightfully die.
20877 ;; Keeping with tradition, "6" is in honor of #UD.
20878 (define_insn "trap"
20879 [(trap_if (const_int 1) (const_int 6))]
20881 { return ASM_SHORT "0x0b0f"; }
20882 [(set_attr "length" "2")])
20884 (define_expand "sse_prologue_save"
20885 [(parallel [(set (match_operand:BLK 0 "" "")
20886 (unspec:BLK [(reg:DI 21)
20893 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20894 (use (match_operand:DI 1 "register_operand" ""))
20895 (use (match_operand:DI 2 "immediate_operand" ""))
20896 (use (label_ref:DI (match_operand 3 "" "")))])]
20900 (define_insn "*sse_prologue_save_insn"
20901 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20902 (match_operand:DI 4 "const_int_operand" "n")))
20903 (unspec:BLK [(reg:DI 21)
20910 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20911 (use (match_operand:DI 1 "register_operand" "r"))
20912 (use (match_operand:DI 2 "const_int_operand" "i"))
20913 (use (label_ref:DI (match_operand 3 "" "X")))]
20915 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20916 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20919 operands[0] = gen_rtx_MEM (Pmode,
20920 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20921 output_asm_insn ("jmp\t%A1", operands);
20922 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20924 operands[4] = adjust_address (operands[0], DImode, i*16);
20925 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20926 PUT_MODE (operands[4], TImode);
20927 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20928 output_asm_insn ("rex", operands);
20929 output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
20931 (*targetm.asm_out.internal_label) (asm_out_file, "L",
20932 CODE_LABEL_NUMBER (operands[3]));
20935 [(set_attr "type" "other")
20936 (set_attr "length_immediate" "0")
20937 (set_attr "length_address" "0")
20938 (set_attr "length" "34")
20939 (set_attr "memory" "store")
20940 (set_attr "modrm" "0")
20941 (set_attr "mode" "DI")])
20943 (define_expand "prefetch"
20944 [(prefetch (match_operand 0 "address_operand" "")
20945 (match_operand:SI 1 "const_int_operand" "")
20946 (match_operand:SI 2 "const_int_operand" ""))]
20947 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20949 int rw = INTVAL (operands[1]);
20950 int locality = INTVAL (operands[2]);
20952 gcc_assert (rw == 0 || rw == 1);
20953 gcc_assert (locality >= 0 && locality <= 3);
20954 gcc_assert (GET_MODE (operands[0]) == Pmode
20955 || GET_MODE (operands[0]) == VOIDmode);
20957 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20958 supported by SSE counterpart or the SSE prefetch is not available
20959 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20961 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20962 operands[2] = GEN_INT (3);
20964 operands[1] = const0_rtx;
20967 (define_insn "*prefetch_sse"
20968 [(prefetch (match_operand:SI 0 "address_operand" "p")
20970 (match_operand:SI 1 "const_int_operand" ""))]
20971 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20973 static const char * const patterns[4] = {
20974 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20977 int locality = INTVAL (operands[1]);
20978 gcc_assert (locality >= 0 && locality <= 3);
20980 return patterns[locality];
20982 [(set_attr "type" "sse")
20983 (set_attr "memory" "none")])
20985 (define_insn "*prefetch_sse_rex"
20986 [(prefetch (match_operand:DI 0 "address_operand" "p")
20988 (match_operand:SI 1 "const_int_operand" ""))]
20989 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20991 static const char * const patterns[4] = {
20992 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20995 int locality = INTVAL (operands[1]);
20996 gcc_assert (locality >= 0 && locality <= 3);
20998 return patterns[locality];
21000 [(set_attr "type" "sse")
21001 (set_attr "memory" "none")])
21003 (define_insn "*prefetch_3dnow"
21004 [(prefetch (match_operand:SI 0 "address_operand" "p")
21005 (match_operand:SI 1 "const_int_operand" "n")
21007 "TARGET_3DNOW && !TARGET_64BIT"
21009 if (INTVAL (operands[1]) == 0)
21010 return "prefetch\t%a0";
21012 return "prefetchw\t%a0";
21014 [(set_attr "type" "mmx")
21015 (set_attr "memory" "none")])
21017 (define_insn "*prefetch_3dnow_rex"
21018 [(prefetch (match_operand:DI 0 "address_operand" "p")
21019 (match_operand:SI 1 "const_int_operand" "n")
21021 "TARGET_3DNOW && TARGET_64BIT"
21023 if (INTVAL (operands[1]) == 0)
21024 return "prefetch\t%a0";
21026 return "prefetchw\t%a0";
21028 [(set_attr "type" "mmx")
21029 (set_attr "memory" "none")])
21031 (define_expand "stack_protect_set"
21032 [(match_operand 0 "memory_operand" "")
21033 (match_operand 1 "memory_operand" "")]
21036 #ifdef TARGET_THREAD_SSP_OFFSET
21038 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21039 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21041 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21042 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21045 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21047 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21052 (define_insn "stack_protect_set_si"
21053 [(set (match_operand:SI 0 "memory_operand" "=m")
21054 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21055 (set (match_scratch:SI 2 "=&r") (const_int 0))
21056 (clobber (reg:CC FLAGS_REG))]
21058 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21059 [(set_attr "type" "multi")])
21061 (define_insn "stack_protect_set_di"
21062 [(set (match_operand:DI 0 "memory_operand" "=m")
21063 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21064 (set (match_scratch:DI 2 "=&r") (const_int 0))
21065 (clobber (reg:CC FLAGS_REG))]
21067 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21068 [(set_attr "type" "multi")])
21070 (define_insn "stack_tls_protect_set_si"
21071 [(set (match_operand:SI 0 "memory_operand" "=m")
21072 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21073 (set (match_scratch:SI 2 "=&r") (const_int 0))
21074 (clobber (reg:CC FLAGS_REG))]
21076 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21077 [(set_attr "type" "multi")])
21079 (define_insn "stack_tls_protect_set_di"
21080 [(set (match_operand:DI 0 "memory_operand" "=m")
21081 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21082 (set (match_scratch:DI 2 "=&r") (const_int 0))
21083 (clobber (reg:CC FLAGS_REG))]
21086 /* The kernel uses a different segment register for performance reasons; a
21087 system call would not have to trash the userspace segment register,
21088 which would be expensive */
21089 if (ix86_cmodel != CM_KERNEL)
21090 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21092 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21094 [(set_attr "type" "multi")])
21096 (define_expand "stack_protect_test"
21097 [(match_operand 0 "memory_operand" "")
21098 (match_operand 1 "memory_operand" "")
21099 (match_operand 2 "" "")]
21102 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21103 ix86_compare_op0 = operands[0];
21104 ix86_compare_op1 = operands[1];
21105 ix86_compare_emitted = flags;
21107 #ifdef TARGET_THREAD_SSP_OFFSET
21109 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21110 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21112 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21113 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21116 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21118 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21120 emit_jump_insn (gen_beq (operands[2]));
21124 (define_insn "stack_protect_test_si"
21125 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21126 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21127 (match_operand:SI 2 "memory_operand" "m")]
21129 (clobber (match_scratch:SI 3 "=&r"))]
21131 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21132 [(set_attr "type" "multi")])
21134 (define_insn "stack_protect_test_di"
21135 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21136 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21137 (match_operand:DI 2 "memory_operand" "m")]
21139 (clobber (match_scratch:DI 3 "=&r"))]
21141 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21142 [(set_attr "type" "multi")])
21144 (define_insn "stack_tls_protect_test_si"
21145 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21146 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21147 (match_operand:SI 2 "const_int_operand" "i")]
21148 UNSPEC_SP_TLS_TEST))
21149 (clobber (match_scratch:SI 3 "=r"))]
21151 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21152 [(set_attr "type" "multi")])
21154 (define_insn "stack_tls_protect_test_di"
21155 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21156 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21157 (match_operand:DI 2 "const_int_operand" "i")]
21158 UNSPEC_SP_TLS_TEST))
21159 (clobber (match_scratch:DI 3 "=r"))]
21162 /* The kernel uses a different segment register for performance reasons; a
21163 system call would not have to trash the userspace segment register,
21164 which would be expensive */
21165 if (ix86_cmodel != CM_KERNEL)
21166 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21168 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21170 [(set_attr "type" "multi")])
21172 (define_mode_iterator CRC32MODE [QI HI SI])
21173 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21174 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21176 (define_insn "sse4_2_crc32<mode>"
21177 [(set (match_operand:SI 0 "register_operand" "=r")
21179 [(match_operand:SI 1 "register_operand" "0")
21180 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21183 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21184 [(set_attr "type" "sselog1")
21185 (set_attr "prefix_rep" "1")
21186 (set_attr "prefix_extra" "1")
21187 (set_attr "mode" "SI")])
21189 (define_insn "sse4_2_crc32di"
21190 [(set (match_operand:DI 0 "register_operand" "=r")
21192 [(match_operand:DI 1 "register_operand" "0")
21193 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21195 "TARGET_SSE4_2 && TARGET_64BIT"
21196 "crc32q\t{%2, %0|%0, %2}"
21197 [(set_attr "type" "sselog1")
21198 (set_attr "prefix_rep" "1")
21199 (set_attr "prefix_extra" "1")
21200 (set_attr "mode" "DI")])
21204 (include "sync.md")