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.
261 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
264 ;; In C guard expressions, put expressions which may be compile-time
265 ;; constants first. This allows for better optimization. For
266 ;; example, write "TARGET_64BIT && reload_completed", not
267 ;; "reload_completed && TARGET_64BIT".
270 ;; Processor type. This attribute must exactly match the processor_type
271 ;; enumeration in i386.h.
272 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
273 nocona,core2,generic32,generic64,amdfam10"
274 (const (symbol_ref "ix86_tune")))
276 ;; A basic instruction type. Refinements due to arguments to be
277 ;; provided in other attributes.
280 alu,alu1,negnot,imov,imovx,lea,
281 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
282 icmp,test,ibr,setcc,icmov,
283 push,pop,call,callv,leave,
285 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
286 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
287 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
289 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
290 (const_string "other"))
292 ;; Main data type used by the insn
294 "unknown,none,QI,HI,SI,DI,TI,SF,DF,XF,TF,V4SF,V2DF,V2SF,V1DF"
295 (const_string "unknown"))
297 ;; The CPU unit operations uses.
298 (define_attr "unit" "integer,i387,sse,mmx,unknown"
299 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
300 (const_string "i387")
301 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
302 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
303 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
305 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
307 (eq_attr "type" "other")
308 (const_string "unknown")]
309 (const_string "integer")))
311 ;; The (bounding maximum) length of an instruction immediate.
312 (define_attr "length_immediate" ""
313 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
316 (eq_attr "unit" "i387,sse,mmx")
318 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
320 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
321 (eq_attr "type" "imov,test")
322 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
323 (eq_attr "type" "call")
324 (if_then_else (match_operand 0 "constant_call_address_operand" "")
327 (eq_attr "type" "callv")
328 (if_then_else (match_operand 1 "constant_call_address_operand" "")
331 ;; We don't know the size before shorten_branches. Expect
332 ;; the instruction to fit for better scheduling.
333 (eq_attr "type" "ibr")
336 (symbol_ref "/* Update immediate_length and other attributes! */
337 gcc_unreachable (),1")))
339 ;; The (bounding maximum) length of an instruction address.
340 (define_attr "length_address" ""
341 (cond [(eq_attr "type" "str,other,multi,fxch")
343 (and (eq_attr "type" "call")
344 (match_operand 0 "constant_call_address_operand" ""))
346 (and (eq_attr "type" "callv")
347 (match_operand 1 "constant_call_address_operand" ""))
350 (symbol_ref "ix86_attr_length_address_default (insn)")))
352 ;; Set when length prefix is used.
353 (define_attr "prefix_data16" ""
354 (if_then_else (ior (eq_attr "mode" "HI")
355 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
359 ;; Set when string REP prefix is used.
360 (define_attr "prefix_rep" ""
361 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
365 ;; Set when 0f opcode prefix is used.
366 (define_attr "prefix_0f" ""
368 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
369 (eq_attr "unit" "sse,mmx"))
373 ;; Set when REX opcode prefix is used.
374 (define_attr "prefix_rex" ""
375 (cond [(and (eq_attr "mode" "DI")
376 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
378 (and (eq_attr "mode" "QI")
379 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
382 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
388 ;; There are also additional prefixes in SSSE3.
389 (define_attr "prefix_extra" "" (const_int 0))
391 ;; Set when modrm byte is used.
392 (define_attr "modrm" ""
393 (cond [(eq_attr "type" "str,leave")
395 (eq_attr "unit" "i387")
397 (and (eq_attr "type" "incdec")
398 (ior (match_operand:SI 1 "register_operand" "")
399 (match_operand:HI 1 "register_operand" "")))
401 (and (eq_attr "type" "push")
402 (not (match_operand 1 "memory_operand" "")))
404 (and (eq_attr "type" "pop")
405 (not (match_operand 0 "memory_operand" "")))
407 (and (eq_attr "type" "imov")
408 (ior (and (match_operand 0 "register_operand" "")
409 (match_operand 1 "immediate_operand" ""))
410 (ior (and (match_operand 0 "ax_reg_operand" "")
411 (match_operand 1 "memory_displacement_only_operand" ""))
412 (and (match_operand 0 "memory_displacement_only_operand" "")
413 (match_operand 1 "ax_reg_operand" "")))))
415 (and (eq_attr "type" "call")
416 (match_operand 0 "constant_call_address_operand" ""))
418 (and (eq_attr "type" "callv")
419 (match_operand 1 "constant_call_address_operand" ""))
424 ;; The (bounding maximum) length of an instruction in bytes.
425 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
426 ;; Later we may want to split them and compute proper length as for
428 (define_attr "length" ""
429 (cond [(eq_attr "type" "other,multi,fistp,frndint")
431 (eq_attr "type" "fcmp")
433 (eq_attr "unit" "i387")
435 (plus (attr "prefix_data16")
436 (attr "length_address")))]
437 (plus (plus (attr "modrm")
438 (plus (attr "prefix_0f")
439 (plus (attr "prefix_rex")
440 (plus (attr "prefix_extra")
442 (plus (attr "prefix_rep")
443 (plus (attr "prefix_data16")
444 (plus (attr "length_immediate")
445 (attr "length_address")))))))
447 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
448 ;; `store' if there is a simple memory reference therein, or `unknown'
449 ;; if the instruction is complex.
451 (define_attr "memory" "none,load,store,both,unknown"
452 (cond [(eq_attr "type" "other,multi,str")
453 (const_string "unknown")
454 (eq_attr "type" "lea,fcmov,fpspc")
455 (const_string "none")
456 (eq_attr "type" "fistp,leave")
457 (const_string "both")
458 (eq_attr "type" "frndint")
459 (const_string "load")
460 (eq_attr "type" "push")
461 (if_then_else (match_operand 1 "memory_operand" "")
462 (const_string "both")
463 (const_string "store"))
464 (eq_attr "type" "pop")
465 (if_then_else (match_operand 0 "memory_operand" "")
466 (const_string "both")
467 (const_string "load"))
468 (eq_attr "type" "setcc")
469 (if_then_else (match_operand 0 "memory_operand" "")
470 (const_string "store")
471 (const_string "none"))
472 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
473 (if_then_else (ior (match_operand 0 "memory_operand" "")
474 (match_operand 1 "memory_operand" ""))
475 (const_string "load")
476 (const_string "none"))
477 (eq_attr "type" "ibr")
478 (if_then_else (match_operand 0 "memory_operand" "")
479 (const_string "load")
480 (const_string "none"))
481 (eq_attr "type" "call")
482 (if_then_else (match_operand 0 "constant_call_address_operand" "")
483 (const_string "none")
484 (const_string "load"))
485 (eq_attr "type" "callv")
486 (if_then_else (match_operand 1 "constant_call_address_operand" "")
487 (const_string "none")
488 (const_string "load"))
489 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
490 (match_operand 1 "memory_operand" ""))
491 (const_string "both")
492 (and (match_operand 0 "memory_operand" "")
493 (match_operand 1 "memory_operand" ""))
494 (const_string "both")
495 (match_operand 0 "memory_operand" "")
496 (const_string "store")
497 (match_operand 1 "memory_operand" "")
498 (const_string "load")
500 "!alu1,negnot,ishift1,
501 imov,imovx,icmp,test,bitmanip,
503 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
504 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
505 (match_operand 2 "memory_operand" ""))
506 (const_string "load")
507 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
508 (match_operand 3 "memory_operand" ""))
509 (const_string "load")
511 (const_string "none")))
513 ;; Indicates if an instruction has both an immediate and a displacement.
515 (define_attr "imm_disp" "false,true,unknown"
516 (cond [(eq_attr "type" "other,multi")
517 (const_string "unknown")
518 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
519 (and (match_operand 0 "memory_displacement_operand" "")
520 (match_operand 1 "immediate_operand" "")))
521 (const_string "true")
522 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
523 (and (match_operand 0 "memory_displacement_operand" "")
524 (match_operand 2 "immediate_operand" "")))
525 (const_string "true")
527 (const_string "false")))
529 ;; Indicates if an FP operation has an integer source.
531 (define_attr "fp_int_src" "false,true"
532 (const_string "false"))
534 ;; Defines rounding mode of an FP operation.
536 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
537 (const_string "any"))
539 ;; Describe a user's asm statement.
540 (define_asm_attributes
541 [(set_attr "length" "128")
542 (set_attr "type" "multi")])
544 ;; All integer comparison codes.
545 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
547 ;; All floating-point comparison codes.
548 (define_code_iterator fp_cond [unordered ordered
549 uneq unge ungt unle unlt ltgt ])
551 (define_code_iterator plusminus [plus minus])
553 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
555 ;; Base name for define_insn
556 (define_code_attr plusminus_insn
557 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
558 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
560 ;; Base name for insn mnemonic.
561 (define_code_attr plusminus_mnemonic
562 [(plus "add") (ss_plus "adds") (us_plus "addus")
563 (minus "sub") (ss_minus "subs") (us_minus "subus")])
565 ;; Mark commutative operators as such in constraints.
566 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
567 (minus "") (ss_minus "") (us_minus "")])
569 ;; Mapping of signed max and min
570 (define_code_iterator smaxmin [smax smin])
572 ;; Mapping of unsigned max and min
573 (define_code_iterator umaxmin [umax umin])
575 ;; Base name for integer and FP insn mnemonic
576 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
577 (umax "maxu") (umin "minu")])
578 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
580 ;; Mapping of parallel logic operators
581 (define_code_iterator plogic [and ior xor])
583 ;; Base name for insn mnemonic.
584 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
586 ;; Mapping of abs neg operators
587 (define_code_iterator absneg [abs neg])
589 ;; Base name for x87 insn mnemonic.
590 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
592 ;; All single word integer modes.
593 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
595 ;; Instruction suffix for integer modes.
596 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
598 ;; Register class for integer modes.
599 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
601 ;; Immediate operand constraint for integer modes.
602 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
604 ;; General operand predicate for integer modes.
605 (define_mode_attr general_operand
606 [(QI "general_operand")
607 (HI "general_operand")
608 (SI "general_operand")
609 (DI "x86_64_general_operand")])
611 ;; SSE and x87 SFmode and DFmode floating point modes
612 (define_mode_iterator MODEF [SF DF])
614 ;; All x87 floating point modes
615 (define_mode_iterator X87MODEF [SF DF XF])
617 ;; All integer modes handled by x87 fisttp operator.
618 (define_mode_iterator X87MODEI [HI SI DI])
620 ;; All integer modes handled by integer x87 operators.
621 (define_mode_iterator X87MODEI12 [HI SI])
623 ;; All integer modes handled by SSE cvtts?2si* operators.
624 (define_mode_iterator SSEMODEI24 [SI DI])
626 ;; SSE asm suffix for floating point modes
627 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
629 ;; SSE vector mode corresponding to a scalar mode
630 (define_mode_attr ssevecmode
631 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
633 ;; Instruction suffix for REX 64bit operators.
634 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
636 ;; This mode iterator allows :P to be used for patterns that operate on
637 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
638 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
641 ;; Scheduling descriptions
643 (include "pentium.md")
646 (include "athlon.md")
650 ;; Operand and operator predicates and constraints
652 (include "predicates.md")
653 (include "constraints.md")
656 ;; Compare instructions.
658 ;; All compare insns have expanders that save the operands away without
659 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
660 ;; after the cmp) will actually emit the cmpM.
662 (define_expand "cmpti"
663 [(set (reg:CC FLAGS_REG)
664 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
665 (match_operand:TI 1 "x86_64_general_operand" "")))]
668 if (MEM_P (operands[0]) && MEM_P (operands[1]))
669 operands[0] = force_reg (TImode, operands[0]);
670 ix86_compare_op0 = operands[0];
671 ix86_compare_op1 = operands[1];
675 (define_expand "cmpdi"
676 [(set (reg:CC FLAGS_REG)
677 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
678 (match_operand:DI 1 "x86_64_general_operand" "")))]
681 if (MEM_P (operands[0]) && MEM_P (operands[1]))
682 operands[0] = force_reg (DImode, operands[0]);
683 ix86_compare_op0 = operands[0];
684 ix86_compare_op1 = operands[1];
688 (define_expand "cmpsi"
689 [(set (reg:CC FLAGS_REG)
690 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
691 (match_operand:SI 1 "general_operand" "")))]
694 if (MEM_P (operands[0]) && MEM_P (operands[1]))
695 operands[0] = force_reg (SImode, operands[0]);
696 ix86_compare_op0 = operands[0];
697 ix86_compare_op1 = operands[1];
701 (define_expand "cmphi"
702 [(set (reg:CC FLAGS_REG)
703 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
704 (match_operand:HI 1 "general_operand" "")))]
707 if (MEM_P (operands[0]) && MEM_P (operands[1]))
708 operands[0] = force_reg (HImode, operands[0]);
709 ix86_compare_op0 = operands[0];
710 ix86_compare_op1 = operands[1];
714 (define_expand "cmpqi"
715 [(set (reg:CC FLAGS_REG)
716 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
717 (match_operand:QI 1 "general_operand" "")))]
720 if (MEM_P (operands[0]) && MEM_P (operands[1]))
721 operands[0] = force_reg (QImode, operands[0]);
722 ix86_compare_op0 = operands[0];
723 ix86_compare_op1 = operands[1];
727 (define_insn "cmpdi_ccno_1_rex64"
728 [(set (reg FLAGS_REG)
729 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
730 (match_operand:DI 1 "const0_operand" "")))]
731 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
734 cmp{q}\t{%1, %0|%0, %1}"
735 [(set_attr "type" "test,icmp")
736 (set_attr "length_immediate" "0,1")
737 (set_attr "mode" "DI")])
739 (define_insn "*cmpdi_minus_1_rex64"
740 [(set (reg FLAGS_REG)
741 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
742 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
744 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
745 "cmp{q}\t{%1, %0|%0, %1}"
746 [(set_attr "type" "icmp")
747 (set_attr "mode" "DI")])
749 (define_expand "cmpdi_1_rex64"
750 [(set (reg:CC FLAGS_REG)
751 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
752 (match_operand:DI 1 "general_operand" "")))]
756 (define_insn "cmpdi_1_insn_rex64"
757 [(set (reg FLAGS_REG)
758 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
759 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
760 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
761 "cmp{q}\t{%1, %0|%0, %1}"
762 [(set_attr "type" "icmp")
763 (set_attr "mode" "DI")])
766 (define_insn "*cmpsi_ccno_1"
767 [(set (reg FLAGS_REG)
768 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
769 (match_operand:SI 1 "const0_operand" "")))]
770 "ix86_match_ccmode (insn, CCNOmode)"
773 cmp{l}\t{%1, %0|%0, %1}"
774 [(set_attr "type" "test,icmp")
775 (set_attr "length_immediate" "0,1")
776 (set_attr "mode" "SI")])
778 (define_insn "*cmpsi_minus_1"
779 [(set (reg FLAGS_REG)
780 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
781 (match_operand:SI 1 "general_operand" "ri,mr"))
783 "ix86_match_ccmode (insn, CCGOCmode)"
784 "cmp{l}\t{%1, %0|%0, %1}"
785 [(set_attr "type" "icmp")
786 (set_attr "mode" "SI")])
788 (define_expand "cmpsi_1"
789 [(set (reg:CC FLAGS_REG)
790 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
791 (match_operand:SI 1 "general_operand" "")))]
795 (define_insn "*cmpsi_1_insn"
796 [(set (reg FLAGS_REG)
797 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
798 (match_operand:SI 1 "general_operand" "ri,mr")))]
799 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
800 && ix86_match_ccmode (insn, CCmode)"
801 "cmp{l}\t{%1, %0|%0, %1}"
802 [(set_attr "type" "icmp")
803 (set_attr "mode" "SI")])
805 (define_insn "*cmphi_ccno_1"
806 [(set (reg FLAGS_REG)
807 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
808 (match_operand:HI 1 "const0_operand" "")))]
809 "ix86_match_ccmode (insn, CCNOmode)"
812 cmp{w}\t{%1, %0|%0, %1}"
813 [(set_attr "type" "test,icmp")
814 (set_attr "length_immediate" "0,1")
815 (set_attr "mode" "HI")])
817 (define_insn "*cmphi_minus_1"
818 [(set (reg FLAGS_REG)
819 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
820 (match_operand:HI 1 "general_operand" "rn,mr"))
822 "ix86_match_ccmode (insn, CCGOCmode)"
823 "cmp{w}\t{%1, %0|%0, %1}"
824 [(set_attr "type" "icmp")
825 (set_attr "mode" "HI")])
827 (define_insn "*cmphi_1"
828 [(set (reg FLAGS_REG)
829 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
830 (match_operand:HI 1 "general_operand" "rn,mr")))]
831 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
832 && ix86_match_ccmode (insn, CCmode)"
833 "cmp{w}\t{%1, %0|%0, %1}"
834 [(set_attr "type" "icmp")
835 (set_attr "mode" "HI")])
837 (define_insn "*cmpqi_ccno_1"
838 [(set (reg FLAGS_REG)
839 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
840 (match_operand:QI 1 "const0_operand" "")))]
841 "ix86_match_ccmode (insn, CCNOmode)"
844 cmp{b}\t{$0, %0|%0, 0}"
845 [(set_attr "type" "test,icmp")
846 (set_attr "length_immediate" "0,1")
847 (set_attr "mode" "QI")])
849 (define_insn "*cmpqi_1"
850 [(set (reg FLAGS_REG)
851 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
852 (match_operand:QI 1 "general_operand" "qn,mq")))]
853 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
854 && ix86_match_ccmode (insn, CCmode)"
855 "cmp{b}\t{%1, %0|%0, %1}"
856 [(set_attr "type" "icmp")
857 (set_attr "mode" "QI")])
859 (define_insn "*cmpqi_minus_1"
860 [(set (reg FLAGS_REG)
861 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
862 (match_operand:QI 1 "general_operand" "qn,mq"))
864 "ix86_match_ccmode (insn, CCGOCmode)"
865 "cmp{b}\t{%1, %0|%0, %1}"
866 [(set_attr "type" "icmp")
867 (set_attr "mode" "QI")])
869 (define_insn "*cmpqi_ext_1"
870 [(set (reg FLAGS_REG)
872 (match_operand:QI 0 "general_operand" "Qm")
875 (match_operand 1 "ext_register_operand" "Q")
878 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
879 "cmp{b}\t{%h1, %0|%0, %h1}"
880 [(set_attr "type" "icmp")
881 (set_attr "mode" "QI")])
883 (define_insn "*cmpqi_ext_1_rex64"
884 [(set (reg FLAGS_REG)
886 (match_operand:QI 0 "register_operand" "Q")
889 (match_operand 1 "ext_register_operand" "Q")
892 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
893 "cmp{b}\t{%h1, %0|%0, %h1}"
894 [(set_attr "type" "icmp")
895 (set_attr "mode" "QI")])
897 (define_insn "*cmpqi_ext_2"
898 [(set (reg FLAGS_REG)
902 (match_operand 0 "ext_register_operand" "Q")
905 (match_operand:QI 1 "const0_operand" "")))]
906 "ix86_match_ccmode (insn, CCNOmode)"
908 [(set_attr "type" "test")
909 (set_attr "length_immediate" "0")
910 (set_attr "mode" "QI")])
912 (define_expand "cmpqi_ext_3"
913 [(set (reg:CC FLAGS_REG)
917 (match_operand 0 "ext_register_operand" "")
920 (match_operand:QI 1 "general_operand" "")))]
924 (define_insn "cmpqi_ext_3_insn"
925 [(set (reg FLAGS_REG)
929 (match_operand 0 "ext_register_operand" "Q")
932 (match_operand:QI 1 "general_operand" "Qmn")))]
933 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
934 "cmp{b}\t{%1, %h0|%h0, %1}"
935 [(set_attr "type" "icmp")
936 (set_attr "mode" "QI")])
938 (define_insn "cmpqi_ext_3_insn_rex64"
939 [(set (reg FLAGS_REG)
943 (match_operand 0 "ext_register_operand" "Q")
946 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
947 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
948 "cmp{b}\t{%1, %h0|%h0, %1}"
949 [(set_attr "type" "icmp")
950 (set_attr "mode" "QI")])
952 (define_insn "*cmpqi_ext_4"
953 [(set (reg FLAGS_REG)
957 (match_operand 0 "ext_register_operand" "Q")
962 (match_operand 1 "ext_register_operand" "Q")
965 "ix86_match_ccmode (insn, CCmode)"
966 "cmp{b}\t{%h1, %h0|%h0, %h1}"
967 [(set_attr "type" "icmp")
968 (set_attr "mode" "QI")])
970 ;; These implement float point compares.
971 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
972 ;; which would allow mix and match FP modes on the compares. Which is what
973 ;; the old patterns did, but with many more of them.
975 (define_expand "cmpxf"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
978 (match_operand:XF 1 "nonmemory_operand" "")))]
981 ix86_compare_op0 = operands[0];
982 ix86_compare_op1 = operands[1];
986 (define_expand "cmp<mode>"
987 [(set (reg:CC FLAGS_REG)
988 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
989 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
990 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
992 ix86_compare_op0 = operands[0];
993 ix86_compare_op1 = operands[1];
997 ;; FP compares, step 1:
998 ;; Set the FP condition codes.
1000 ;; CCFPmode compare with exceptions
1001 ;; CCFPUmode compare with no exceptions
1003 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1004 ;; used to manage the reg stack popping would not be preserved.
1006 (define_insn "*cmpfp_0"
1007 [(set (match_operand:HI 0 "register_operand" "=a")
1010 (match_operand 1 "register_operand" "f")
1011 (match_operand 2 "const0_operand" ""))]
1013 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1014 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1015 "* return output_fp_compare (insn, operands, 0, 0);"
1016 [(set_attr "type" "multi")
1017 (set_attr "unit" "i387")
1019 (cond [(match_operand:SF 1 "" "")
1021 (match_operand:DF 1 "" "")
1024 (const_string "XF")))])
1026 (define_insn_and_split "*cmpfp_0_cc"
1027 [(set (reg:CCFP FLAGS_REG)
1029 (match_operand 1 "register_operand" "f")
1030 (match_operand 2 "const0_operand" "")))
1031 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1032 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1033 && TARGET_SAHF && !TARGET_CMOVE
1034 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1036 "&& reload_completed"
1039 [(compare:CCFP (match_dup 1)(match_dup 2))]
1041 (set (reg:CC FLAGS_REG)
1042 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1044 [(set_attr "type" "multi")
1045 (set_attr "unit" "i387")
1047 (cond [(match_operand:SF 1 "" "")
1049 (match_operand:DF 1 "" "")
1052 (const_string "XF")))])
1054 (define_insn "*cmpfp_xf"
1055 [(set (match_operand:HI 0 "register_operand" "=a")
1058 (match_operand:XF 1 "register_operand" "f")
1059 (match_operand:XF 2 "register_operand" "f"))]
1062 "* return output_fp_compare (insn, operands, 0, 0);"
1063 [(set_attr "type" "multi")
1064 (set_attr "unit" "i387")
1065 (set_attr "mode" "XF")])
1067 (define_insn_and_split "*cmpfp_xf_cc"
1068 [(set (reg:CCFP FLAGS_REG)
1070 (match_operand:XF 1 "register_operand" "f")
1071 (match_operand:XF 2 "register_operand" "f")))
1072 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1074 && TARGET_SAHF && !TARGET_CMOVE"
1076 "&& reload_completed"
1079 [(compare:CCFP (match_dup 1)(match_dup 2))]
1081 (set (reg:CC FLAGS_REG)
1082 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1084 [(set_attr "type" "multi")
1085 (set_attr "unit" "i387")
1086 (set_attr "mode" "XF")])
1088 (define_insn "*cmpfp_<mode>"
1089 [(set (match_operand:HI 0 "register_operand" "=a")
1092 (match_operand:MODEF 1 "register_operand" "f")
1093 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1096 "* return output_fp_compare (insn, operands, 0, 0);"
1097 [(set_attr "type" "multi")
1098 (set_attr "unit" "i387")
1099 (set_attr "mode" "<MODE>")])
1101 (define_insn_and_split "*cmpfp_<mode>_cc"
1102 [(set (reg:CCFP FLAGS_REG)
1104 (match_operand:MODEF 1 "register_operand" "f")
1105 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1106 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1108 && TARGET_SAHF && !TARGET_CMOVE"
1110 "&& reload_completed"
1113 [(compare:CCFP (match_dup 1)(match_dup 2))]
1115 (set (reg:CC FLAGS_REG)
1116 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1118 [(set_attr "type" "multi")
1119 (set_attr "unit" "i387")
1120 (set_attr "mode" "<MODE>")])
1122 (define_insn "*cmpfp_u"
1123 [(set (match_operand:HI 0 "register_operand" "=a")
1126 (match_operand 1 "register_operand" "f")
1127 (match_operand 2 "register_operand" "f"))]
1129 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1130 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1131 "* return output_fp_compare (insn, operands, 0, 1);"
1132 [(set_attr "type" "multi")
1133 (set_attr "unit" "i387")
1135 (cond [(match_operand:SF 1 "" "")
1137 (match_operand:DF 1 "" "")
1140 (const_string "XF")))])
1142 (define_insn_and_split "*cmpfp_u_cc"
1143 [(set (reg:CCFPU FLAGS_REG)
1145 (match_operand 1 "register_operand" "f")
1146 (match_operand 2 "register_operand" "f")))
1147 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1148 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1149 && TARGET_SAHF && !TARGET_CMOVE
1150 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1152 "&& reload_completed"
1155 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1157 (set (reg:CC FLAGS_REG)
1158 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1160 [(set_attr "type" "multi")
1161 (set_attr "unit" "i387")
1163 (cond [(match_operand:SF 1 "" "")
1165 (match_operand:DF 1 "" "")
1168 (const_string "XF")))])
1170 (define_insn "*cmpfp_<mode>"
1171 [(set (match_operand:HI 0 "register_operand" "=a")
1174 (match_operand 1 "register_operand" "f")
1175 (match_operator 3 "float_operator"
1176 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1178 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1179 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
1180 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1181 "* return output_fp_compare (insn, operands, 0, 0);"
1182 [(set_attr "type" "multi")
1183 (set_attr "unit" "i387")
1184 (set_attr "fp_int_src" "true")
1185 (set_attr "mode" "<MODE>")])
1187 (define_insn_and_split "*cmpfp_<mode>_cc"
1188 [(set (reg:CCFP FLAGS_REG)
1190 (match_operand 1 "register_operand" "f")
1191 (match_operator 3 "float_operator"
1192 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1193 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1194 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1195 && TARGET_SAHF && !TARGET_CMOVE
1196 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
1197 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1199 "&& reload_completed"
1204 (match_op_dup 3 [(match_dup 2)]))]
1206 (set (reg:CC FLAGS_REG)
1207 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1209 [(set_attr "type" "multi")
1210 (set_attr "unit" "i387")
1211 (set_attr "fp_int_src" "true")
1212 (set_attr "mode" "<MODE>")])
1214 ;; FP compares, step 2
1215 ;; Move the fpsw to ax.
1217 (define_insn "x86_fnstsw_1"
1218 [(set (match_operand:HI 0 "register_operand" "=a")
1219 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1222 [(set_attr "length" "2")
1223 (set_attr "mode" "SI")
1224 (set_attr "unit" "i387")])
1226 ;; FP compares, step 3
1227 ;; Get ax into flags, general case.
1229 (define_insn "x86_sahf_1"
1230 [(set (reg:CC FLAGS_REG)
1231 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1235 #ifdef HAVE_AS_IX86_SAHF
1238 return ".byte\t0x9e";
1241 [(set_attr "length" "1")
1242 (set_attr "athlon_decode" "vector")
1243 (set_attr "amdfam10_decode" "direct")
1244 (set_attr "mode" "SI")])
1246 ;; Pentium Pro can do steps 1 through 3 in one go.
1247 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1248 (define_insn "*cmpfp_i_mixed"
1249 [(set (reg:CCFP FLAGS_REG)
1250 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1251 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1252 "TARGET_MIX_SSE_I387
1253 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1254 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1255 "* return output_fp_compare (insn, operands, 1, 0);"
1256 [(set_attr "type" "fcmp,ssecomi")
1258 (if_then_else (match_operand:SF 1 "" "")
1260 (const_string "DF")))
1261 (set_attr "athlon_decode" "vector")
1262 (set_attr "amdfam10_decode" "direct")])
1264 (define_insn "*cmpfp_i_sse"
1265 [(set (reg:CCFP FLAGS_REG)
1266 (compare:CCFP (match_operand 0 "register_operand" "x")
1267 (match_operand 1 "nonimmediate_operand" "xm")))]
1269 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1270 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1271 "* return output_fp_compare (insn, operands, 1, 0);"
1272 [(set_attr "type" "ssecomi")
1274 (if_then_else (match_operand:SF 1 "" "")
1276 (const_string "DF")))
1277 (set_attr "athlon_decode" "vector")
1278 (set_attr "amdfam10_decode" "direct")])
1280 (define_insn "*cmpfp_i_i387"
1281 [(set (reg:CCFP FLAGS_REG)
1282 (compare:CCFP (match_operand 0 "register_operand" "f")
1283 (match_operand 1 "register_operand" "f")))]
1284 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1286 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1287 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1288 "* return output_fp_compare (insn, operands, 1, 0);"
1289 [(set_attr "type" "fcmp")
1291 (cond [(match_operand:SF 1 "" "")
1293 (match_operand:DF 1 "" "")
1296 (const_string "XF")))
1297 (set_attr "athlon_decode" "vector")
1298 (set_attr "amdfam10_decode" "direct")])
1300 (define_insn "*cmpfp_iu_mixed"
1301 [(set (reg:CCFPU FLAGS_REG)
1302 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1303 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1304 "TARGET_MIX_SSE_I387
1305 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1306 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1307 "* return output_fp_compare (insn, operands, 1, 1);"
1308 [(set_attr "type" "fcmp,ssecomi")
1310 (if_then_else (match_operand:SF 1 "" "")
1312 (const_string "DF")))
1313 (set_attr "athlon_decode" "vector")
1314 (set_attr "amdfam10_decode" "direct")])
1316 (define_insn "*cmpfp_iu_sse"
1317 [(set (reg:CCFPU FLAGS_REG)
1318 (compare:CCFPU (match_operand 0 "register_operand" "x")
1319 (match_operand 1 "nonimmediate_operand" "xm")))]
1321 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1322 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1323 "* return output_fp_compare (insn, operands, 1, 1);"
1324 [(set_attr "type" "ssecomi")
1326 (if_then_else (match_operand:SF 1 "" "")
1328 (const_string "DF")))
1329 (set_attr "athlon_decode" "vector")
1330 (set_attr "amdfam10_decode" "direct")])
1332 (define_insn "*cmpfp_iu_387"
1333 [(set (reg:CCFPU FLAGS_REG)
1334 (compare:CCFPU (match_operand 0 "register_operand" "f")
1335 (match_operand 1 "register_operand" "f")))]
1336 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1338 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1339 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1340 "* return output_fp_compare (insn, operands, 1, 1);"
1341 [(set_attr "type" "fcmp")
1343 (cond [(match_operand:SF 1 "" "")
1345 (match_operand:DF 1 "" "")
1348 (const_string "XF")))
1349 (set_attr "athlon_decode" "vector")
1350 (set_attr "amdfam10_decode" "direct")])
1352 ;; Move instructions.
1354 ;; General case of fullword move.
1356 (define_expand "movsi"
1357 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1358 (match_operand:SI 1 "general_operand" ""))]
1360 "ix86_expand_move (SImode, operands); DONE;")
1362 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1365 ;; %%% We don't use a post-inc memory reference because x86 is not a
1366 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1367 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1368 ;; targets without our curiosities, and it is just as easy to represent
1369 ;; this differently.
1371 (define_insn "*pushsi2"
1372 [(set (match_operand:SI 0 "push_operand" "=<")
1373 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1376 [(set_attr "type" "push")
1377 (set_attr "mode" "SI")])
1379 ;; For 64BIT abi we always round up to 8 bytes.
1380 (define_insn "*pushsi2_rex64"
1381 [(set (match_operand:SI 0 "push_operand" "=X")
1382 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1385 [(set_attr "type" "push")
1386 (set_attr "mode" "SI")])
1388 (define_insn "*pushsi2_prologue"
1389 [(set (match_operand:SI 0 "push_operand" "=<")
1390 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1391 (clobber (mem:BLK (scratch)))]
1394 [(set_attr "type" "push")
1395 (set_attr "mode" "SI")])
1397 (define_insn "*popsi1_epilogue"
1398 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1399 (mem:SI (reg:SI SP_REG)))
1400 (set (reg:SI SP_REG)
1401 (plus:SI (reg:SI SP_REG) (const_int 4)))
1402 (clobber (mem:BLK (scratch)))]
1405 [(set_attr "type" "pop")
1406 (set_attr "mode" "SI")])
1408 (define_insn "popsi1"
1409 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1410 (mem:SI (reg:SI SP_REG)))
1411 (set (reg:SI SP_REG)
1412 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1415 [(set_attr "type" "pop")
1416 (set_attr "mode" "SI")])
1418 (define_insn "*movsi_xor"
1419 [(set (match_operand:SI 0 "register_operand" "=r")
1420 (match_operand:SI 1 "const0_operand" ""))
1421 (clobber (reg:CC FLAGS_REG))]
1422 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1424 [(set_attr "type" "alu1")
1425 (set_attr "mode" "SI")
1426 (set_attr "length_immediate" "0")])
1428 (define_insn "*movsi_or"
1429 [(set (match_operand:SI 0 "register_operand" "=r")
1430 (match_operand:SI 1 "immediate_operand" "i"))
1431 (clobber (reg:CC FLAGS_REG))]
1433 && operands[1] == constm1_rtx
1434 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1436 operands[1] = constm1_rtx;
1437 return "or{l}\t{%1, %0|%0, %1}";
1439 [(set_attr "type" "alu1")
1440 (set_attr "mode" "SI")
1441 (set_attr "length_immediate" "1")])
1443 (define_insn "*movsi_1"
1444 [(set (match_operand:SI 0 "nonimmediate_operand"
1445 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1446 (match_operand:SI 1 "general_operand"
1447 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1448 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450 switch (get_attr_type (insn))
1453 if (get_attr_mode (insn) == MODE_TI)
1454 return "pxor\t%0, %0";
1455 return "xorps\t%0, %0";
1458 switch (get_attr_mode (insn))
1461 return "movdqa\t{%1, %0|%0, %1}";
1463 return "movaps\t{%1, %0|%0, %1}";
1465 return "movd\t{%1, %0|%0, %1}";
1467 return "movss\t{%1, %0|%0, %1}";
1473 return "pxor\t%0, %0";
1476 if (get_attr_mode (insn) == MODE_DI)
1477 return "movq\t{%1, %0|%0, %1}";
1478 return "movd\t{%1, %0|%0, %1}";
1481 return "lea{l}\t{%1, %0|%0, %1}";
1484 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1485 return "mov{l}\t{%1, %0|%0, %1}";
1489 (cond [(eq_attr "alternative" "2")
1490 (const_string "mmxadd")
1491 (eq_attr "alternative" "3,4,5")
1492 (const_string "mmxmov")
1493 (eq_attr "alternative" "6")
1494 (const_string "sselog1")
1495 (eq_attr "alternative" "7,8,9,10,11")
1496 (const_string "ssemov")
1497 (match_operand:DI 1 "pic_32bit_operand" "")
1498 (const_string "lea")
1500 (const_string "imov")))
1502 (cond [(eq_attr "alternative" "2,3")
1504 (eq_attr "alternative" "6,7")
1506 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1507 (const_string "V4SF")
1508 (const_string "TI"))
1509 (and (eq_attr "alternative" "8,9,10,11")
1510 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1513 (const_string "SI")))])
1515 ;; Stores and loads of ax to arbitrary constant address.
1516 ;; We fake an second form of instruction to force reload to load address
1517 ;; into register when rax is not available
1518 (define_insn "*movabssi_1_rex64"
1519 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1520 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1521 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1523 movabs{l}\t{%1, %P0|%P0, %1}
1524 mov{l}\t{%1, %a0|%a0, %1}"
1525 [(set_attr "type" "imov")
1526 (set_attr "modrm" "0,*")
1527 (set_attr "length_address" "8,0")
1528 (set_attr "length_immediate" "0,*")
1529 (set_attr "memory" "store")
1530 (set_attr "mode" "SI")])
1532 (define_insn "*movabssi_2_rex64"
1533 [(set (match_operand:SI 0 "register_operand" "=a,r")
1534 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1535 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1537 movabs{l}\t{%P1, %0|%0, %P1}
1538 mov{l}\t{%a1, %0|%0, %a1}"
1539 [(set_attr "type" "imov")
1540 (set_attr "modrm" "0,*")
1541 (set_attr "length_address" "8,0")
1542 (set_attr "length_immediate" "0")
1543 (set_attr "memory" "load")
1544 (set_attr "mode" "SI")])
1546 (define_insn "*swapsi"
1547 [(set (match_operand:SI 0 "register_operand" "+r")
1548 (match_operand:SI 1 "register_operand" "+r"))
1553 [(set_attr "type" "imov")
1554 (set_attr "mode" "SI")
1555 (set_attr "pent_pair" "np")
1556 (set_attr "athlon_decode" "vector")
1557 (set_attr "amdfam10_decode" "double")])
1559 (define_expand "movhi"
1560 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1561 (match_operand:HI 1 "general_operand" ""))]
1563 "ix86_expand_move (HImode, operands); DONE;")
1565 (define_insn "*pushhi2"
1566 [(set (match_operand:HI 0 "push_operand" "=X")
1567 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1570 [(set_attr "type" "push")
1571 (set_attr "mode" "SI")])
1573 ;; For 64BIT abi we always round up to 8 bytes.
1574 (define_insn "*pushhi2_rex64"
1575 [(set (match_operand:HI 0 "push_operand" "=X")
1576 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1579 [(set_attr "type" "push")
1580 (set_attr "mode" "DI")])
1582 (define_insn "*movhi_1"
1583 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1584 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1585 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1587 switch (get_attr_type (insn))
1590 /* movzwl is faster than movw on p2 due to partial word stalls,
1591 though not as fast as an aligned movl. */
1592 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1594 if (get_attr_mode (insn) == MODE_SI)
1595 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1597 return "mov{w}\t{%1, %0|%0, %1}";
1601 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1602 (const_string "imov")
1603 (and (eq_attr "alternative" "0")
1604 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1606 (eq (symbol_ref "TARGET_HIMODE_MATH")
1608 (const_string "imov")
1609 (and (eq_attr "alternative" "1,2")
1610 (match_operand:HI 1 "aligned_operand" ""))
1611 (const_string "imov")
1612 (and (ne (symbol_ref "TARGET_MOVX")
1614 (eq_attr "alternative" "0,2"))
1615 (const_string "imovx")
1617 (const_string "imov")))
1619 (cond [(eq_attr "type" "imovx")
1621 (and (eq_attr "alternative" "1,2")
1622 (match_operand:HI 1 "aligned_operand" ""))
1624 (and (eq_attr "alternative" "0")
1625 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1627 (eq (symbol_ref "TARGET_HIMODE_MATH")
1631 (const_string "HI")))])
1633 ;; Stores and loads of ax to arbitrary constant address.
1634 ;; We fake an second form of instruction to force reload to load address
1635 ;; into register when rax is not available
1636 (define_insn "*movabshi_1_rex64"
1637 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1638 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1639 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1641 movabs{w}\t{%1, %P0|%P0, %1}
1642 mov{w}\t{%1, %a0|%a0, %1}"
1643 [(set_attr "type" "imov")
1644 (set_attr "modrm" "0,*")
1645 (set_attr "length_address" "8,0")
1646 (set_attr "length_immediate" "0,*")
1647 (set_attr "memory" "store")
1648 (set_attr "mode" "HI")])
1650 (define_insn "*movabshi_2_rex64"
1651 [(set (match_operand:HI 0 "register_operand" "=a,r")
1652 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1653 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1655 movabs{w}\t{%P1, %0|%0, %P1}
1656 mov{w}\t{%a1, %0|%0, %a1}"
1657 [(set_attr "type" "imov")
1658 (set_attr "modrm" "0,*")
1659 (set_attr "length_address" "8,0")
1660 (set_attr "length_immediate" "0")
1661 (set_attr "memory" "load")
1662 (set_attr "mode" "HI")])
1664 (define_insn "*swaphi_1"
1665 [(set (match_operand:HI 0 "register_operand" "+r")
1666 (match_operand:HI 1 "register_operand" "+r"))
1669 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1671 [(set_attr "type" "imov")
1672 (set_attr "mode" "SI")
1673 (set_attr "pent_pair" "np")
1674 (set_attr "athlon_decode" "vector")
1675 (set_attr "amdfam10_decode" "double")])
1677 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1678 (define_insn "*swaphi_2"
1679 [(set (match_operand:HI 0 "register_operand" "+r")
1680 (match_operand:HI 1 "register_operand" "+r"))
1683 "TARGET_PARTIAL_REG_STALL"
1685 [(set_attr "type" "imov")
1686 (set_attr "mode" "HI")
1687 (set_attr "pent_pair" "np")
1688 (set_attr "athlon_decode" "vector")])
1690 (define_expand "movstricthi"
1691 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1692 (match_operand:HI 1 "general_operand" ""))]
1693 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1695 /* Don't generate memory->memory moves, go through a register */
1696 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1697 operands[1] = force_reg (HImode, operands[1]);
1700 (define_insn "*movstricthi_1"
1701 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1702 (match_operand:HI 1 "general_operand" "rn,m"))]
1703 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1704 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1705 "mov{w}\t{%1, %0|%0, %1}"
1706 [(set_attr "type" "imov")
1707 (set_attr "mode" "HI")])
1709 (define_insn "*movstricthi_xor"
1710 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1711 (match_operand:HI 1 "const0_operand" ""))
1712 (clobber (reg:CC FLAGS_REG))]
1714 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1716 [(set_attr "type" "alu1")
1717 (set_attr "mode" "HI")
1718 (set_attr "length_immediate" "0")])
1720 (define_expand "movqi"
1721 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1722 (match_operand:QI 1 "general_operand" ""))]
1724 "ix86_expand_move (QImode, operands); DONE;")
1726 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1727 ;; "push a byte". But actually we use pushl, which has the effect
1728 ;; of rounding the amount pushed up to a word.
1730 (define_insn "*pushqi2"
1731 [(set (match_operand:QI 0 "push_operand" "=X")
1732 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1735 [(set_attr "type" "push")
1736 (set_attr "mode" "SI")])
1738 ;; For 64BIT abi we always round up to 8 bytes.
1739 (define_insn "*pushqi2_rex64"
1740 [(set (match_operand:QI 0 "push_operand" "=X")
1741 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1744 [(set_attr "type" "push")
1745 (set_attr "mode" "DI")])
1747 ;; Situation is quite tricky about when to choose full sized (SImode) move
1748 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1749 ;; partial register dependency machines (such as AMD Athlon), where QImode
1750 ;; moves issue extra dependency and for partial register stalls machines
1751 ;; that don't use QImode patterns (and QImode move cause stall on the next
1754 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1755 ;; register stall machines with, where we use QImode instructions, since
1756 ;; partial register stall can be caused there. Then we use movzx.
1757 (define_insn "*movqi_1"
1758 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1759 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1760 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1762 switch (get_attr_type (insn))
1765 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1766 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1768 if (get_attr_mode (insn) == MODE_SI)
1769 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1771 return "mov{b}\t{%1, %0|%0, %1}";
1775 (cond [(and (eq_attr "alternative" "5")
1776 (not (match_operand:QI 1 "aligned_operand" "")))
1777 (const_string "imovx")
1778 (ne (symbol_ref "optimize_size") (const_int 0))
1779 (const_string "imov")
1780 (and (eq_attr "alternative" "3")
1781 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1783 (eq (symbol_ref "TARGET_QIMODE_MATH")
1785 (const_string "imov")
1786 (eq_attr "alternative" "3,5")
1787 (const_string "imovx")
1788 (and (ne (symbol_ref "TARGET_MOVX")
1790 (eq_attr "alternative" "2"))
1791 (const_string "imovx")
1793 (const_string "imov")))
1795 (cond [(eq_attr "alternative" "3,4,5")
1797 (eq_attr "alternative" "6")
1799 (eq_attr "type" "imovx")
1801 (and (eq_attr "type" "imov")
1802 (and (eq_attr "alternative" "0,1")
1803 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1805 (and (eq (symbol_ref "optimize_size")
1807 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1810 ;; Avoid partial register stalls when not using QImode arithmetic
1811 (and (eq_attr "type" "imov")
1812 (and (eq_attr "alternative" "0,1")
1813 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1815 (eq (symbol_ref "TARGET_QIMODE_MATH")
1819 (const_string "QI")))])
1821 (define_insn "*swapqi_1"
1822 [(set (match_operand:QI 0 "register_operand" "+r")
1823 (match_operand:QI 1 "register_operand" "+r"))
1826 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1828 [(set_attr "type" "imov")
1829 (set_attr "mode" "SI")
1830 (set_attr "pent_pair" "np")
1831 (set_attr "athlon_decode" "vector")
1832 (set_attr "amdfam10_decode" "vector")])
1834 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1835 (define_insn "*swapqi_2"
1836 [(set (match_operand:QI 0 "register_operand" "+q")
1837 (match_operand:QI 1 "register_operand" "+q"))
1840 "TARGET_PARTIAL_REG_STALL"
1842 [(set_attr "type" "imov")
1843 (set_attr "mode" "QI")
1844 (set_attr "pent_pair" "np")
1845 (set_attr "athlon_decode" "vector")])
1847 (define_expand "movstrictqi"
1848 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1849 (match_operand:QI 1 "general_operand" ""))]
1850 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1852 /* Don't generate memory->memory moves, go through a register. */
1853 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1854 operands[1] = force_reg (QImode, operands[1]);
1857 (define_insn "*movstrictqi_1"
1858 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1859 (match_operand:QI 1 "general_operand" "*qn,m"))]
1860 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1861 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1862 "mov{b}\t{%1, %0|%0, %1}"
1863 [(set_attr "type" "imov")
1864 (set_attr "mode" "QI")])
1866 (define_insn "*movstrictqi_xor"
1867 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1868 (match_operand:QI 1 "const0_operand" ""))
1869 (clobber (reg:CC FLAGS_REG))]
1870 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1872 [(set_attr "type" "alu1")
1873 (set_attr "mode" "QI")
1874 (set_attr "length_immediate" "0")])
1876 (define_insn "*movsi_extv_1"
1877 [(set (match_operand:SI 0 "register_operand" "=R")
1878 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1882 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1883 [(set_attr "type" "imovx")
1884 (set_attr "mode" "SI")])
1886 (define_insn "*movhi_extv_1"
1887 [(set (match_operand:HI 0 "register_operand" "=R")
1888 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1892 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1893 [(set_attr "type" "imovx")
1894 (set_attr "mode" "SI")])
1896 (define_insn "*movqi_extv_1"
1897 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1898 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1903 switch (get_attr_type (insn))
1906 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1908 return "mov{b}\t{%h1, %0|%0, %h1}";
1912 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1913 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1914 (ne (symbol_ref "TARGET_MOVX")
1916 (const_string "imovx")
1917 (const_string "imov")))
1919 (if_then_else (eq_attr "type" "imovx")
1921 (const_string "QI")))])
1923 (define_insn "*movqi_extv_1_rex64"
1924 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1925 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1930 switch (get_attr_type (insn))
1933 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1935 return "mov{b}\t{%h1, %0|%0, %h1}";
1939 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1940 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1941 (ne (symbol_ref "TARGET_MOVX")
1943 (const_string "imovx")
1944 (const_string "imov")))
1946 (if_then_else (eq_attr "type" "imovx")
1948 (const_string "QI")))])
1950 ;; Stores and loads of ax to arbitrary constant address.
1951 ;; We fake an second form of instruction to force reload to load address
1952 ;; into register when rax is not available
1953 (define_insn "*movabsqi_1_rex64"
1954 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1955 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1956 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1958 movabs{b}\t{%1, %P0|%P0, %1}
1959 mov{b}\t{%1, %a0|%a0, %1}"
1960 [(set_attr "type" "imov")
1961 (set_attr "modrm" "0,*")
1962 (set_attr "length_address" "8,0")
1963 (set_attr "length_immediate" "0,*")
1964 (set_attr "memory" "store")
1965 (set_attr "mode" "QI")])
1967 (define_insn "*movabsqi_2_rex64"
1968 [(set (match_operand:QI 0 "register_operand" "=a,r")
1969 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1970 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1972 movabs{b}\t{%P1, %0|%0, %P1}
1973 mov{b}\t{%a1, %0|%0, %a1}"
1974 [(set_attr "type" "imov")
1975 (set_attr "modrm" "0,*")
1976 (set_attr "length_address" "8,0")
1977 (set_attr "length_immediate" "0")
1978 (set_attr "memory" "load")
1979 (set_attr "mode" "QI")])
1981 (define_insn "*movdi_extzv_1"
1982 [(set (match_operand:DI 0 "register_operand" "=R")
1983 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1987 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1988 [(set_attr "type" "imovx")
1989 (set_attr "mode" "DI")])
1991 (define_insn "*movsi_extzv_1"
1992 [(set (match_operand:SI 0 "register_operand" "=R")
1993 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1997 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1998 [(set_attr "type" "imovx")
1999 (set_attr "mode" "SI")])
2001 (define_insn "*movqi_extzv_2"
2002 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2003 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2008 switch (get_attr_type (insn))
2011 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2013 return "mov{b}\t{%h1, %0|%0, %h1}";
2017 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2018 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2019 (ne (symbol_ref "TARGET_MOVX")
2021 (const_string "imovx")
2022 (const_string "imov")))
2024 (if_then_else (eq_attr "type" "imovx")
2026 (const_string "QI")))])
2028 (define_insn "*movqi_extzv_2_rex64"
2029 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2030 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2035 switch (get_attr_type (insn))
2038 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2040 return "mov{b}\t{%h1, %0|%0, %h1}";
2044 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2045 (ne (symbol_ref "TARGET_MOVX")
2047 (const_string "imovx")
2048 (const_string "imov")))
2050 (if_then_else (eq_attr "type" "imovx")
2052 (const_string "QI")))])
2054 (define_insn "movsi_insv_1"
2055 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2058 (match_operand:SI 1 "general_operand" "Qmn"))]
2060 "mov{b}\t{%b1, %h0|%h0, %b1}"
2061 [(set_attr "type" "imov")
2062 (set_attr "mode" "QI")])
2064 (define_insn "*movsi_insv_1_rex64"
2065 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2068 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2070 "mov{b}\t{%b1, %h0|%h0, %b1}"
2071 [(set_attr "type" "imov")
2072 (set_attr "mode" "QI")])
2074 (define_insn "movdi_insv_1_rex64"
2075 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2078 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2080 "mov{b}\t{%b1, %h0|%h0, %b1}"
2081 [(set_attr "type" "imov")
2082 (set_attr "mode" "QI")])
2084 (define_insn "*movqi_insv_2"
2085 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2088 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2091 "mov{b}\t{%h1, %h0|%h0, %h1}"
2092 [(set_attr "type" "imov")
2093 (set_attr "mode" "QI")])
2095 (define_expand "movdi"
2096 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2097 (match_operand:DI 1 "general_operand" ""))]
2099 "ix86_expand_move (DImode, operands); DONE;")
2101 (define_insn "*pushdi"
2102 [(set (match_operand:DI 0 "push_operand" "=<")
2103 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2107 (define_insn "*pushdi2_rex64"
2108 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2109 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2114 [(set_attr "type" "push,multi")
2115 (set_attr "mode" "DI")])
2117 ;; Convert impossible pushes of immediate to existing instructions.
2118 ;; First try to get scratch register and go through it. In case this
2119 ;; fails, push sign extended lower part first and then overwrite
2120 ;; upper part by 32bit move.
2122 [(match_scratch:DI 2 "r")
2123 (set (match_operand:DI 0 "push_operand" "")
2124 (match_operand:DI 1 "immediate_operand" ""))]
2125 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2126 && !x86_64_immediate_operand (operands[1], DImode)"
2127 [(set (match_dup 2) (match_dup 1))
2128 (set (match_dup 0) (match_dup 2))]
2131 ;; We need to define this as both peepholer and splitter for case
2132 ;; peephole2 pass is not run.
2133 ;; "&& 1" is needed to keep it from matching the previous pattern.
2135 [(set (match_operand:DI 0 "push_operand" "")
2136 (match_operand:DI 1 "immediate_operand" ""))]
2137 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2138 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2139 [(set (match_dup 0) (match_dup 1))
2140 (set (match_dup 2) (match_dup 3))]
2141 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2142 operands[1] = gen_lowpart (DImode, operands[2]);
2143 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2148 [(set (match_operand:DI 0 "push_operand" "")
2149 (match_operand:DI 1 "immediate_operand" ""))]
2150 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151 ? epilogue_completed : reload_completed)
2152 && !symbolic_operand (operands[1], DImode)
2153 && !x86_64_immediate_operand (operands[1], DImode)"
2154 [(set (match_dup 0) (match_dup 1))
2155 (set (match_dup 2) (match_dup 3))]
2156 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2157 operands[1] = gen_lowpart (DImode, operands[2]);
2158 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2162 (define_insn "*pushdi2_prologue_rex64"
2163 [(set (match_operand:DI 0 "push_operand" "=<")
2164 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2165 (clobber (mem:BLK (scratch)))]
2168 [(set_attr "type" "push")
2169 (set_attr "mode" "DI")])
2171 (define_insn "*popdi1_epilogue_rex64"
2172 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2173 (mem:DI (reg:DI SP_REG)))
2174 (set (reg:DI SP_REG)
2175 (plus:DI (reg:DI SP_REG) (const_int 8)))
2176 (clobber (mem:BLK (scratch)))]
2179 [(set_attr "type" "pop")
2180 (set_attr "mode" "DI")])
2182 (define_insn "popdi1"
2183 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2184 (mem:DI (reg:DI SP_REG)))
2185 (set (reg:DI SP_REG)
2186 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2189 [(set_attr "type" "pop")
2190 (set_attr "mode" "DI")])
2192 (define_insn "*movdi_xor_rex64"
2193 [(set (match_operand:DI 0 "register_operand" "=r")
2194 (match_operand:DI 1 "const0_operand" ""))
2195 (clobber (reg:CC FLAGS_REG))]
2196 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2197 && reload_completed"
2199 [(set_attr "type" "alu1")
2200 (set_attr "mode" "SI")
2201 (set_attr "length_immediate" "0")])
2203 (define_insn "*movdi_or_rex64"
2204 [(set (match_operand:DI 0 "register_operand" "=r")
2205 (match_operand:DI 1 "const_int_operand" "i"))
2206 (clobber (reg:CC FLAGS_REG))]
2207 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2209 && operands[1] == constm1_rtx"
2211 operands[1] = constm1_rtx;
2212 return "or{q}\t{%1, %0|%0, %1}";
2214 [(set_attr "type" "alu1")
2215 (set_attr "mode" "DI")
2216 (set_attr "length_immediate" "1")])
2218 (define_insn "*movdi_2"
2219 [(set (match_operand:DI 0 "nonimmediate_operand"
2220 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2221 (match_operand:DI 1 "general_operand"
2222 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2223 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2228 movq\t{%1, %0|%0, %1}
2229 movq\t{%1, %0|%0, %1}
2231 movq\t{%1, %0|%0, %1}
2232 movdqa\t{%1, %0|%0, %1}
2233 movq\t{%1, %0|%0, %1}
2235 movlps\t{%1, %0|%0, %1}
2236 movaps\t{%1, %0|%0, %1}
2237 movlps\t{%1, %0|%0, %1}"
2238 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2239 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2242 [(set (match_operand:DI 0 "push_operand" "")
2243 (match_operand:DI 1 "general_operand" ""))]
2244 "!TARGET_64BIT && reload_completed
2245 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2247 "ix86_split_long_move (operands); DONE;")
2249 ;; %%% This multiword shite has got to go.
2251 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2252 (match_operand:DI 1 "general_operand" ""))]
2253 "!TARGET_64BIT && reload_completed
2254 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2255 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2257 "ix86_split_long_move (operands); DONE;")
2259 (define_insn "*movdi_1_rex64"
2260 [(set (match_operand:DI 0 "nonimmediate_operand"
2261 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2262 (match_operand:DI 1 "general_operand"
2263 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2264 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2266 switch (get_attr_type (insn))
2269 if (SSE_REG_P (operands[0]))
2270 return "movq2dq\t{%1, %0|%0, %1}";
2272 return "movdq2q\t{%1, %0|%0, %1}";
2275 if (get_attr_mode (insn) == MODE_TI)
2276 return "movdqa\t{%1, %0|%0, %1}";
2280 /* Moves from and into integer register is done using movd
2281 opcode with REX prefix. */
2282 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2283 return "movd\t{%1, %0|%0, %1}";
2284 return "movq\t{%1, %0|%0, %1}";
2288 return "pxor\t%0, %0";
2294 return "lea{q}\t{%a1, %0|%0, %a1}";
2297 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2298 if (get_attr_mode (insn) == MODE_SI)
2299 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2300 else if (which_alternative == 2)
2301 return "movabs{q}\t{%1, %0|%0, %1}";
2303 return "mov{q}\t{%1, %0|%0, %1}";
2307 (cond [(eq_attr "alternative" "5")
2308 (const_string "mmxadd")
2309 (eq_attr "alternative" "6,7,8,9,10")
2310 (const_string "mmxmov")
2311 (eq_attr "alternative" "11")
2312 (const_string "sselog1")
2313 (eq_attr "alternative" "12,13,14,15,16")
2314 (const_string "ssemov")
2315 (eq_attr "alternative" "17,18")
2316 (const_string "ssecvt")
2317 (eq_attr "alternative" "4")
2318 (const_string "multi")
2319 (match_operand:DI 1 "pic_32bit_operand" "")
2320 (const_string "lea")
2322 (const_string "imov")))
2323 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2324 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2325 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2327 ;; Stores and loads of ax to arbitrary constant address.
2328 ;; We fake an second form of instruction to force reload to load address
2329 ;; into register when rax is not available
2330 (define_insn "*movabsdi_1_rex64"
2331 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2332 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2333 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2335 movabs{q}\t{%1, %P0|%P0, %1}
2336 mov{q}\t{%1, %a0|%a0, %1}"
2337 [(set_attr "type" "imov")
2338 (set_attr "modrm" "0,*")
2339 (set_attr "length_address" "8,0")
2340 (set_attr "length_immediate" "0,*")
2341 (set_attr "memory" "store")
2342 (set_attr "mode" "DI")])
2344 (define_insn "*movabsdi_2_rex64"
2345 [(set (match_operand:DI 0 "register_operand" "=a,r")
2346 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2347 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2349 movabs{q}\t{%P1, %0|%0, %P1}
2350 mov{q}\t{%a1, %0|%0, %a1}"
2351 [(set_attr "type" "imov")
2352 (set_attr "modrm" "0,*")
2353 (set_attr "length_address" "8,0")
2354 (set_attr "length_immediate" "0")
2355 (set_attr "memory" "load")
2356 (set_attr "mode" "DI")])
2358 ;; Convert impossible stores of immediate to existing instructions.
2359 ;; First try to get scratch register and go through it. In case this
2360 ;; fails, move by 32bit parts.
2362 [(match_scratch:DI 2 "r")
2363 (set (match_operand:DI 0 "memory_operand" "")
2364 (match_operand:DI 1 "immediate_operand" ""))]
2365 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2366 && !x86_64_immediate_operand (operands[1], DImode)"
2367 [(set (match_dup 2) (match_dup 1))
2368 (set (match_dup 0) (match_dup 2))]
2371 ;; We need to define this as both peepholer and splitter for case
2372 ;; peephole2 pass is not run.
2373 ;; "&& 1" is needed to keep it from matching the previous pattern.
2375 [(set (match_operand:DI 0 "memory_operand" "")
2376 (match_operand:DI 1 "immediate_operand" ""))]
2377 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2378 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2379 [(set (match_dup 2) (match_dup 3))
2380 (set (match_dup 4) (match_dup 5))]
2381 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2384 [(set (match_operand:DI 0 "memory_operand" "")
2385 (match_operand:DI 1 "immediate_operand" ""))]
2386 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2387 ? epilogue_completed : reload_completed)
2388 && !symbolic_operand (operands[1], DImode)
2389 && !x86_64_immediate_operand (operands[1], DImode)"
2390 [(set (match_dup 2) (match_dup 3))
2391 (set (match_dup 4) (match_dup 5))]
2392 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2394 (define_insn "*swapdi_rex64"
2395 [(set (match_operand:DI 0 "register_operand" "+r")
2396 (match_operand:DI 1 "register_operand" "+r"))
2401 [(set_attr "type" "imov")
2402 (set_attr "mode" "DI")
2403 (set_attr "pent_pair" "np")
2404 (set_attr "athlon_decode" "vector")
2405 (set_attr "amdfam10_decode" "double")])
2407 (define_expand "movti"
2408 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2409 (match_operand:TI 1 "nonimmediate_operand" ""))]
2410 "TARGET_SSE || TARGET_64BIT"
2413 ix86_expand_move (TImode, operands);
2414 else if (push_operand (operands[0], TImode))
2415 ix86_expand_push (TImode, operands[1]);
2417 ix86_expand_vector_move (TImode, operands);
2421 (define_insn "*movti_internal"
2422 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2423 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2424 "TARGET_SSE && !TARGET_64BIT
2425 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2427 switch (which_alternative)
2430 if (get_attr_mode (insn) == MODE_V4SF)
2431 return "xorps\t%0, %0";
2433 return "pxor\t%0, %0";
2436 /* TDmode values are passed as TImode on the stack. Moving them
2437 to stack may result in unaligned memory access. */
2438 if (misaligned_operand (operands[0], TImode)
2439 || misaligned_operand (operands[1], TImode))
2441 if (get_attr_mode (insn) == MODE_V4SF)
2442 return "movups\t{%1, %0|%0, %1}";
2444 return "movdqu\t{%1, %0|%0, %1}";
2448 if (get_attr_mode (insn) == MODE_V4SF)
2449 return "movaps\t{%1, %0|%0, %1}";
2451 return "movdqa\t{%1, %0|%0, %1}";
2457 [(set_attr "type" "sselog1,ssemov,ssemov")
2459 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2460 (ne (symbol_ref "optimize_size") (const_int 0)))
2461 (const_string "V4SF")
2462 (and (eq_attr "alternative" "2")
2463 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2465 (const_string "V4SF")]
2466 (const_string "TI")))])
2468 (define_insn "*movti_rex64"
2469 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2470 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2472 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2474 switch (which_alternative)
2480 if (get_attr_mode (insn) == MODE_V4SF)
2481 return "xorps\t%0, %0";
2483 return "pxor\t%0, %0";
2486 /* TDmode values are passed as TImode on the stack. Moving them
2487 to stack may result in unaligned memory access. */
2488 if (misaligned_operand (operands[0], TImode)
2489 || misaligned_operand (operands[1], TImode))
2491 if (get_attr_mode (insn) == MODE_V4SF)
2492 return "movups\t{%1, %0|%0, %1}";
2494 return "movdqu\t{%1, %0|%0, %1}";
2498 if (get_attr_mode (insn) == MODE_V4SF)
2499 return "movaps\t{%1, %0|%0, %1}";
2501 return "movdqa\t{%1, %0|%0, %1}";
2507 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2509 (cond [(eq_attr "alternative" "2,3")
2511 (ne (symbol_ref "optimize_size")
2513 (const_string "V4SF")
2514 (const_string "TI"))
2515 (eq_attr "alternative" "4")
2517 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2519 (ne (symbol_ref "optimize_size")
2521 (const_string "V4SF")
2522 (const_string "TI"))]
2523 (const_string "DI")))])
2526 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2527 (match_operand:TI 1 "general_operand" ""))]
2528 "reload_completed && !SSE_REG_P (operands[0])
2529 && !SSE_REG_P (operands[1])"
2531 "ix86_split_long_move (operands); DONE;")
2533 ;; This expands to what emit_move_complex would generate if we didn't
2534 ;; have a movti pattern. Having this avoids problems with reload on
2535 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2536 ;; to have around all the time.
2537 (define_expand "movcdi"
2538 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2539 (match_operand:CDI 1 "general_operand" ""))]
2542 if (push_operand (operands[0], CDImode))
2543 emit_move_complex_push (CDImode, operands[0], operands[1]);
2545 emit_move_complex_parts (operands[0], operands[1]);
2549 (define_expand "movsf"
2550 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2551 (match_operand:SF 1 "general_operand" ""))]
2553 "ix86_expand_move (SFmode, operands); DONE;")
2555 (define_insn "*pushsf"
2556 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2557 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2560 /* Anything else should be already split before reg-stack. */
2561 gcc_assert (which_alternative == 1);
2562 return "push{l}\t%1";
2564 [(set_attr "type" "multi,push,multi")
2565 (set_attr "unit" "i387,*,*")
2566 (set_attr "mode" "SF,SI,SF")])
2568 (define_insn "*pushsf_rex64"
2569 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2570 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2573 /* Anything else should be already split before reg-stack. */
2574 gcc_assert (which_alternative == 1);
2575 return "push{q}\t%q1";
2577 [(set_attr "type" "multi,push,multi")
2578 (set_attr "unit" "i387,*,*")
2579 (set_attr "mode" "SF,DI,SF")])
2582 [(set (match_operand:SF 0 "push_operand" "")
2583 (match_operand:SF 1 "memory_operand" ""))]
2585 && MEM_P (operands[1])
2586 && (operands[2] = find_constant_src (insn))"
2591 ;; %%% Kill this when call knows how to work this out.
2593 [(set (match_operand:SF 0 "push_operand" "")
2594 (match_operand:SF 1 "any_fp_register_operand" ""))]
2596 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2597 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2600 [(set (match_operand:SF 0 "push_operand" "")
2601 (match_operand:SF 1 "any_fp_register_operand" ""))]
2603 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2604 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2606 (define_insn "*movsf_1"
2607 [(set (match_operand:SF 0 "nonimmediate_operand"
2608 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2609 (match_operand:SF 1 "general_operand"
2610 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2611 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2612 && (reload_in_progress || reload_completed
2613 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2614 || (!TARGET_SSE_MATH && optimize_size
2615 && standard_80387_constant_p (operands[1]))
2616 || GET_CODE (operands[1]) != CONST_DOUBLE
2617 || memory_operand (operands[0], SFmode))"
2619 switch (which_alternative)
2623 return output_387_reg_move (insn, operands);
2626 return standard_80387_constant_opcode (operands[1]);
2630 return "mov{l}\t{%1, %0|%0, %1}";
2632 if (get_attr_mode (insn) == MODE_TI)
2633 return "pxor\t%0, %0";
2635 return "xorps\t%0, %0";
2637 if (get_attr_mode (insn) == MODE_V4SF)
2638 return "movaps\t{%1, %0|%0, %1}";
2640 return "movss\t{%1, %0|%0, %1}";
2642 return "movss\t{%1, %0|%0, %1}";
2645 case 12: case 13: case 14: case 15:
2646 return "movd\t{%1, %0|%0, %1}";
2649 return "movq\t{%1, %0|%0, %1}";
2655 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2657 (cond [(eq_attr "alternative" "3,4,9,10")
2659 (eq_attr "alternative" "5")
2661 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2663 (ne (symbol_ref "TARGET_SSE2")
2665 (eq (symbol_ref "optimize_size")
2668 (const_string "V4SF"))
2669 /* For architectures resolving dependencies on
2670 whole SSE registers use APS move to break dependency
2671 chains, otherwise use short move to avoid extra work.
2673 Do the same for architectures resolving dependencies on
2674 the parts. While in DF mode it is better to always handle
2675 just register parts, the SF mode is different due to lack
2676 of instructions to load just part of the register. It is
2677 better to maintain the whole registers in single format
2678 to avoid problems on using packed logical operations. */
2679 (eq_attr "alternative" "6")
2681 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2683 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2685 (const_string "V4SF")
2686 (const_string "SF"))
2687 (eq_attr "alternative" "11")
2688 (const_string "DI")]
2689 (const_string "SF")))])
2691 (define_insn "*swapsf"
2692 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2693 (match_operand:SF 1 "fp_register_operand" "+f"))
2696 "reload_completed || TARGET_80387"
2698 if (STACK_TOP_P (operands[0]))
2703 [(set_attr "type" "fxch")
2704 (set_attr "mode" "SF")])
2706 (define_expand "movdf"
2707 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2708 (match_operand:DF 1 "general_operand" ""))]
2710 "ix86_expand_move (DFmode, operands); DONE;")
2712 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2713 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2714 ;; On the average, pushdf using integers can be still shorter. Allow this
2715 ;; pattern for optimize_size too.
2717 (define_insn "*pushdf_nointeger"
2718 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2719 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2720 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2722 /* This insn should be already split before reg-stack. */
2725 [(set_attr "type" "multi")
2726 (set_attr "unit" "i387,*,*,*")
2727 (set_attr "mode" "DF,SI,SI,DF")])
2729 (define_insn "*pushdf_integer"
2730 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2731 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2732 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2734 /* This insn should be already split before reg-stack. */
2737 [(set_attr "type" "multi")
2738 (set_attr "unit" "i387,*,*")
2739 (set_attr "mode" "DF,SI,DF")])
2741 ;; %%% Kill this when call knows how to work this out.
2743 [(set (match_operand:DF 0 "push_operand" "")
2744 (match_operand:DF 1 "any_fp_register_operand" ""))]
2746 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2747 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2751 [(set (match_operand:DF 0 "push_operand" "")
2752 (match_operand:DF 1 "general_operand" ""))]
2755 "ix86_split_long_move (operands); DONE;")
2757 ;; Moving is usually shorter when only FP registers are used. This separate
2758 ;; movdf pattern avoids the use of integer registers for FP operations
2759 ;; when optimizing for size.
2761 (define_insn "*movdf_nointeger"
2762 [(set (match_operand:DF 0 "nonimmediate_operand"
2763 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2764 (match_operand:DF 1 "general_operand"
2765 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2766 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2767 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2768 && (reload_in_progress || reload_completed
2769 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2770 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2771 && !memory_operand (operands[0], DFmode)
2772 && standard_80387_constant_p (operands[1]))
2773 || GET_CODE (operands[1]) != CONST_DOUBLE
2775 || !TARGET_MEMORY_MISMATCH_STALL
2776 || reload_in_progress || reload_completed)
2777 && memory_operand (operands[0], DFmode)))"
2779 switch (which_alternative)
2783 return output_387_reg_move (insn, operands);
2786 return standard_80387_constant_opcode (operands[1]);
2792 switch (get_attr_mode (insn))
2795 return "xorps\t%0, %0";
2797 return "xorpd\t%0, %0";
2799 return "pxor\t%0, %0";
2806 switch (get_attr_mode (insn))
2809 return "movaps\t{%1, %0|%0, %1}";
2811 return "movapd\t{%1, %0|%0, %1}";
2813 return "movdqa\t{%1, %0|%0, %1}";
2815 return "movq\t{%1, %0|%0, %1}";
2817 return "movsd\t{%1, %0|%0, %1}";
2819 return "movlpd\t{%1, %0|%0, %1}";
2821 return "movlps\t{%1, %0|%0, %1}";
2830 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2832 (cond [(eq_attr "alternative" "0,1,2")
2834 (eq_attr "alternative" "3,4")
2837 /* For SSE1, we have many fewer alternatives. */
2838 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2839 (cond [(eq_attr "alternative" "5,6")
2840 (const_string "V4SF")
2842 (const_string "V2SF"))
2844 /* xorps is one byte shorter. */
2845 (eq_attr "alternative" "5")
2846 (cond [(ne (symbol_ref "optimize_size")
2848 (const_string "V4SF")
2849 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2853 (const_string "V2DF"))
2855 /* For architectures resolving dependencies on
2856 whole SSE registers use APD move to break dependency
2857 chains, otherwise use short move to avoid extra work.
2859 movaps encodes one byte shorter. */
2860 (eq_attr "alternative" "6")
2862 [(ne (symbol_ref "optimize_size")
2864 (const_string "V4SF")
2865 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2867 (const_string "V2DF")
2869 (const_string "DF"))
2870 /* For architectures resolving dependencies on register
2871 parts we may avoid extra work to zero out upper part
2873 (eq_attr "alternative" "7")
2875 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2877 (const_string "V1DF")
2878 (const_string "DF"))
2880 (const_string "DF")))])
2882 (define_insn "*movdf_integer_rex64"
2883 [(set (match_operand:DF 0 "nonimmediate_operand"
2884 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2885 (match_operand:DF 1 "general_operand"
2886 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2887 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2888 && (reload_in_progress || reload_completed
2889 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2890 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2891 && standard_80387_constant_p (operands[1]))
2892 || GET_CODE (operands[1]) != CONST_DOUBLE
2893 || memory_operand (operands[0], DFmode))"
2895 switch (which_alternative)
2899 return output_387_reg_move (insn, operands);
2902 return standard_80387_constant_opcode (operands[1]);
2909 switch (get_attr_mode (insn))
2912 return "xorps\t%0, %0";
2914 return "xorpd\t%0, %0";
2916 return "pxor\t%0, %0";
2923 switch (get_attr_mode (insn))
2926 return "movaps\t{%1, %0|%0, %1}";
2928 return "movapd\t{%1, %0|%0, %1}";
2930 return "movdqa\t{%1, %0|%0, %1}";
2932 return "movq\t{%1, %0|%0, %1}";
2934 return "movsd\t{%1, %0|%0, %1}";
2936 return "movlpd\t{%1, %0|%0, %1}";
2938 return "movlps\t{%1, %0|%0, %1}";
2945 return "movd\t{%1, %0|%0, %1}";
2951 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2953 (cond [(eq_attr "alternative" "0,1,2")
2955 (eq_attr "alternative" "3,4,9,10")
2958 /* For SSE1, we have many fewer alternatives. */
2959 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2960 (cond [(eq_attr "alternative" "5,6")
2961 (const_string "V4SF")
2963 (const_string "V2SF"))
2965 /* xorps is one byte shorter. */
2966 (eq_attr "alternative" "5")
2967 (cond [(ne (symbol_ref "optimize_size")
2969 (const_string "V4SF")
2970 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2974 (const_string "V2DF"))
2976 /* For architectures resolving dependencies on
2977 whole SSE registers use APD move to break dependency
2978 chains, otherwise use short move to avoid extra work.
2980 movaps encodes one byte shorter. */
2981 (eq_attr "alternative" "6")
2983 [(ne (symbol_ref "optimize_size")
2985 (const_string "V4SF")
2986 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2988 (const_string "V2DF")
2990 (const_string "DF"))
2991 /* For architectures resolving dependencies on register
2992 parts we may avoid extra work to zero out upper part
2994 (eq_attr "alternative" "7")
2996 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2998 (const_string "V1DF")
2999 (const_string "DF"))
3001 (const_string "DF")))])
3003 (define_insn "*movdf_integer"
3004 [(set (match_operand:DF 0 "nonimmediate_operand"
3005 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3006 (match_operand:DF 1 "general_operand"
3007 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3008 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3009 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3010 && (reload_in_progress || reload_completed
3011 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3012 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3013 && standard_80387_constant_p (operands[1]))
3014 || GET_CODE (operands[1]) != CONST_DOUBLE
3015 || memory_operand (operands[0], DFmode))"
3017 switch (which_alternative)
3021 return output_387_reg_move (insn, operands);
3024 return standard_80387_constant_opcode (operands[1]);
3031 switch (get_attr_mode (insn))
3034 return "xorps\t%0, %0";
3036 return "xorpd\t%0, %0";
3038 return "pxor\t%0, %0";
3045 switch (get_attr_mode (insn))
3048 return "movaps\t{%1, %0|%0, %1}";
3050 return "movapd\t{%1, %0|%0, %1}";
3052 return "movdqa\t{%1, %0|%0, %1}";
3054 return "movq\t{%1, %0|%0, %1}";
3056 return "movsd\t{%1, %0|%0, %1}";
3058 return "movlpd\t{%1, %0|%0, %1}";
3060 return "movlps\t{%1, %0|%0, %1}";
3069 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3071 (cond [(eq_attr "alternative" "0,1,2")
3073 (eq_attr "alternative" "3,4")
3076 /* For SSE1, we have many fewer alternatives. */
3077 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3078 (cond [(eq_attr "alternative" "5,6")
3079 (const_string "V4SF")
3081 (const_string "V2SF"))
3083 /* xorps is one byte shorter. */
3084 (eq_attr "alternative" "5")
3085 (cond [(ne (symbol_ref "optimize_size")
3087 (const_string "V4SF")
3088 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3092 (const_string "V2DF"))
3094 /* For architectures resolving dependencies on
3095 whole SSE registers use APD move to break dependency
3096 chains, otherwise use short move to avoid extra work.
3098 movaps encodes one byte shorter. */
3099 (eq_attr "alternative" "6")
3101 [(ne (symbol_ref "optimize_size")
3103 (const_string "V4SF")
3104 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3106 (const_string "V2DF")
3108 (const_string "DF"))
3109 /* For architectures resolving dependencies on register
3110 parts we may avoid extra work to zero out upper part
3112 (eq_attr "alternative" "7")
3114 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3116 (const_string "V1DF")
3117 (const_string "DF"))
3119 (const_string "DF")))])
3122 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3123 (match_operand:DF 1 "general_operand" ""))]
3125 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3126 && ! (ANY_FP_REG_P (operands[0]) ||
3127 (GET_CODE (operands[0]) == SUBREG
3128 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3129 && ! (ANY_FP_REG_P (operands[1]) ||
3130 (GET_CODE (operands[1]) == SUBREG
3131 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3133 "ix86_split_long_move (operands); DONE;")
3135 (define_insn "*swapdf"
3136 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3137 (match_operand:DF 1 "fp_register_operand" "+f"))
3140 "reload_completed || TARGET_80387"
3142 if (STACK_TOP_P (operands[0]))
3147 [(set_attr "type" "fxch")
3148 (set_attr "mode" "DF")])
3150 (define_expand "movxf"
3151 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3152 (match_operand:XF 1 "general_operand" ""))]
3154 "ix86_expand_move (XFmode, operands); DONE;")
3156 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3157 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3158 ;; Pushing using integer instructions is longer except for constants
3159 ;; and direct memory references.
3160 ;; (assuming that any given constant is pushed only once, but this ought to be
3161 ;; handled elsewhere).
3163 (define_insn "*pushxf_nointeger"
3164 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3165 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3168 /* This insn should be already split before reg-stack. */
3171 [(set_attr "type" "multi")
3172 (set_attr "unit" "i387,*,*")
3173 (set_attr "mode" "XF,SI,SI")])
3175 (define_insn "*pushxf_integer"
3176 [(set (match_operand:XF 0 "push_operand" "=<,<")
3177 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3180 /* This insn should be already split before reg-stack. */
3183 [(set_attr "type" "multi")
3184 (set_attr "unit" "i387,*")
3185 (set_attr "mode" "XF,SI")])
3188 [(set (match_operand 0 "push_operand" "")
3189 (match_operand 1 "general_operand" ""))]
3191 && (GET_MODE (operands[0]) == XFmode
3192 || GET_MODE (operands[0]) == DFmode)
3193 && !ANY_FP_REG_P (operands[1])"
3195 "ix86_split_long_move (operands); DONE;")
3198 [(set (match_operand:XF 0 "push_operand" "")
3199 (match_operand:XF 1 "any_fp_register_operand" ""))]
3201 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3202 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3203 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3205 ;; Do not use integer registers when optimizing for size
3206 (define_insn "*movxf_nointeger"
3207 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3208 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3210 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3211 && (reload_in_progress || reload_completed
3212 || (optimize_size && standard_80387_constant_p (operands[1]))
3213 || GET_CODE (operands[1]) != CONST_DOUBLE
3214 || memory_operand (operands[0], XFmode))"
3216 switch (which_alternative)
3220 return output_387_reg_move (insn, operands);
3223 return standard_80387_constant_opcode (operands[1]);
3231 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3232 (set_attr "mode" "XF,XF,XF,SI,SI")])
3234 (define_insn "*movxf_integer"
3235 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3236 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3238 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3239 && (reload_in_progress || reload_completed
3240 || (optimize_size && standard_80387_constant_p (operands[1]))
3241 || GET_CODE (operands[1]) != CONST_DOUBLE
3242 || memory_operand (operands[0], XFmode))"
3244 switch (which_alternative)
3248 return output_387_reg_move (insn, operands);
3251 return standard_80387_constant_opcode (operands[1]);
3260 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3261 (set_attr "mode" "XF,XF,XF,SI,SI")])
3263 (define_expand "movtf"
3264 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3265 (match_operand:TF 1 "nonimmediate_operand" ""))]
3268 ix86_expand_move (TFmode, operands);
3272 (define_insn "*movtf_internal"
3273 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3274 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3276 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3278 switch (which_alternative)
3282 if (get_attr_mode (insn) == MODE_V4SF)
3283 return "movaps\t{%1, %0|%0, %1}";
3285 return "movdqa\t{%1, %0|%0, %1}";
3287 if (get_attr_mode (insn) == MODE_V4SF)
3288 return "xorps\t%0, %0";
3290 return "pxor\t%0, %0";
3298 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3300 (cond [(eq_attr "alternative" "0,2")
3302 (ne (symbol_ref "optimize_size")
3304 (const_string "V4SF")
3305 (const_string "TI"))
3306 (eq_attr "alternative" "1")
3308 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3310 (ne (symbol_ref "optimize_size")
3312 (const_string "V4SF")
3313 (const_string "TI"))]
3314 (const_string "DI")))])
3316 (define_insn "*pushtf_sse"
3317 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3318 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3321 /* This insn should be already split before reg-stack. */
3324 [(set_attr "type" "multi")
3325 (set_attr "unit" "sse,*,*")
3326 (set_attr "mode" "TF,SI,SI")])
3329 [(set (match_operand:TF 0 "push_operand" "")
3330 (match_operand:TF 1 "general_operand" ""))]
3331 "TARGET_SSE2 && reload_completed
3332 && !SSE_REG_P (operands[1])"
3334 "ix86_split_long_move (operands); DONE;")
3337 [(set (match_operand:TF 0 "push_operand" "")
3338 (match_operand:TF 1 "any_fp_register_operand" ""))]
3340 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3341 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3345 [(set (match_operand 0 "nonimmediate_operand" "")
3346 (match_operand 1 "general_operand" ""))]
3348 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3349 && GET_MODE (operands[0]) == XFmode
3350 && ! (ANY_FP_REG_P (operands[0]) ||
3351 (GET_CODE (operands[0]) == SUBREG
3352 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3353 && ! (ANY_FP_REG_P (operands[1]) ||
3354 (GET_CODE (operands[1]) == SUBREG
3355 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3357 "ix86_split_long_move (operands); DONE;")
3360 [(set (match_operand 0 "register_operand" "")
3361 (match_operand 1 "memory_operand" ""))]
3363 && MEM_P (operands[1])
3364 && (GET_MODE (operands[0]) == TFmode
3365 || GET_MODE (operands[0]) == XFmode
3366 || GET_MODE (operands[0]) == SFmode
3367 || GET_MODE (operands[0]) == DFmode)
3368 && (operands[2] = find_constant_src (insn))"
3369 [(set (match_dup 0) (match_dup 2))]
3371 rtx c = operands[2];
3372 rtx r = operands[0];
3374 if (GET_CODE (r) == SUBREG)
3379 if (!standard_sse_constant_p (c))
3382 else if (FP_REG_P (r))
3384 if (!standard_80387_constant_p (c))
3387 else if (MMX_REG_P (r))
3392 [(set (match_operand 0 "register_operand" "")
3393 (float_extend (match_operand 1 "memory_operand" "")))]
3395 && MEM_P (operands[1])
3396 && (GET_MODE (operands[0]) == TFmode
3397 || GET_MODE (operands[0]) == XFmode
3398 || GET_MODE (operands[0]) == SFmode
3399 || GET_MODE (operands[0]) == DFmode)
3400 && (operands[2] = find_constant_src (insn))"
3401 [(set (match_dup 0) (match_dup 2))]
3403 rtx c = operands[2];
3404 rtx r = operands[0];
3406 if (GET_CODE (r) == SUBREG)
3411 if (!standard_sse_constant_p (c))
3414 else if (FP_REG_P (r))
3416 if (!standard_80387_constant_p (c))
3419 else if (MMX_REG_P (r))
3423 (define_insn "swapxf"
3424 [(set (match_operand:XF 0 "register_operand" "+f")
3425 (match_operand:XF 1 "register_operand" "+f"))
3430 if (STACK_TOP_P (operands[0]))
3435 [(set_attr "type" "fxch")
3436 (set_attr "mode" "XF")])
3438 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3440 [(set (match_operand:X87MODEF 0 "register_operand" "")
3441 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3442 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3443 && (standard_80387_constant_p (operands[1]) == 8
3444 || standard_80387_constant_p (operands[1]) == 9)"
3445 [(set (match_dup 0)(match_dup 1))
3447 (neg:X87MODEF (match_dup 0)))]
3451 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3452 if (real_isnegzero (&r))
3453 operands[1] = CONST0_RTX (<MODE>mode);
3455 operands[1] = CONST1_RTX (<MODE>mode);
3459 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3460 (match_operand:TF 1 "general_operand" ""))]
3462 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3464 "ix86_split_long_move (operands); DONE;")
3466 ;; Zero extension instructions
3468 (define_expand "zero_extendhisi2"
3469 [(set (match_operand:SI 0 "register_operand" "")
3470 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3473 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3475 operands[1] = force_reg (HImode, operands[1]);
3476 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3481 (define_insn "zero_extendhisi2_and"
3482 [(set (match_operand:SI 0 "register_operand" "=r")
3483 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3484 (clobber (reg:CC FLAGS_REG))]
3485 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3487 [(set_attr "type" "alu1")
3488 (set_attr "mode" "SI")])
3491 [(set (match_operand:SI 0 "register_operand" "")
3492 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3493 (clobber (reg:CC FLAGS_REG))]
3494 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3495 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3496 (clobber (reg:CC FLAGS_REG))])]
3499 (define_insn "*zero_extendhisi2_movzwl"
3500 [(set (match_operand:SI 0 "register_operand" "=r")
3501 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3502 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3503 "movz{wl|x}\t{%1, %0|%0, %1}"
3504 [(set_attr "type" "imovx")
3505 (set_attr "mode" "SI")])
3507 (define_expand "zero_extendqihi2"
3509 [(set (match_operand:HI 0 "register_operand" "")
3510 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3511 (clobber (reg:CC FLAGS_REG))])]
3515 (define_insn "*zero_extendqihi2_and"
3516 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3517 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3518 (clobber (reg:CC FLAGS_REG))]
3519 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3521 [(set_attr "type" "alu1")
3522 (set_attr "mode" "HI")])
3524 (define_insn "*zero_extendqihi2_movzbw_and"
3525 [(set (match_operand:HI 0 "register_operand" "=r,r")
3526 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3527 (clobber (reg:CC FLAGS_REG))]
3528 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3530 [(set_attr "type" "imovx,alu1")
3531 (set_attr "mode" "HI")])
3533 ; zero extend to SImode here to avoid partial register stalls
3534 (define_insn "*zero_extendqihi2_movzbl"
3535 [(set (match_operand:HI 0 "register_operand" "=r")
3536 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3537 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3538 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3539 [(set_attr "type" "imovx")
3540 (set_attr "mode" "SI")])
3542 ;; For the movzbw case strip only the clobber
3544 [(set (match_operand:HI 0 "register_operand" "")
3545 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3546 (clobber (reg:CC FLAGS_REG))]
3548 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3549 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3550 [(set (match_operand:HI 0 "register_operand" "")
3551 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3553 ;; When source and destination does not overlap, clear destination
3554 ;; first and then do the movb
3556 [(set (match_operand:HI 0 "register_operand" "")
3557 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3558 (clobber (reg:CC FLAGS_REG))]
3560 && ANY_QI_REG_P (operands[0])
3561 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3562 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3563 [(set (match_dup 0) (const_int 0))
3564 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3565 "operands[2] = gen_lowpart (QImode, operands[0]);")
3567 ;; Rest is handled by single and.
3569 [(set (match_operand:HI 0 "register_operand" "")
3570 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3571 (clobber (reg:CC FLAGS_REG))]
3573 && true_regnum (operands[0]) == true_regnum (operands[1])"
3574 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3575 (clobber (reg:CC FLAGS_REG))])]
3578 (define_expand "zero_extendqisi2"
3580 [(set (match_operand:SI 0 "register_operand" "")
3581 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3582 (clobber (reg:CC FLAGS_REG))])]
3586 (define_insn "*zero_extendqisi2_and"
3587 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3588 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3589 (clobber (reg:CC FLAGS_REG))]
3590 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3592 [(set_attr "type" "alu1")
3593 (set_attr "mode" "SI")])
3595 (define_insn "*zero_extendqisi2_movzbw_and"
3596 [(set (match_operand:SI 0 "register_operand" "=r,r")
3597 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3598 (clobber (reg:CC FLAGS_REG))]
3599 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3601 [(set_attr "type" "imovx,alu1")
3602 (set_attr "mode" "SI")])
3604 (define_insn "*zero_extendqisi2_movzbw"
3605 [(set (match_operand:SI 0 "register_operand" "=r")
3606 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3607 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3608 "movz{bl|x}\t{%1, %0|%0, %1}"
3609 [(set_attr "type" "imovx")
3610 (set_attr "mode" "SI")])
3612 ;; For the movzbl case strip only the clobber
3614 [(set (match_operand:SI 0 "register_operand" "")
3615 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3616 (clobber (reg:CC FLAGS_REG))]
3618 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3619 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3621 (zero_extend:SI (match_dup 1)))])
3623 ;; When source and destination does not overlap, clear destination
3624 ;; first and then do the movb
3626 [(set (match_operand:SI 0 "register_operand" "")
3627 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3628 (clobber (reg:CC FLAGS_REG))]
3630 && ANY_QI_REG_P (operands[0])
3631 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3632 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3633 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3634 [(set (match_dup 0) (const_int 0))
3635 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3636 "operands[2] = gen_lowpart (QImode, operands[0]);")
3638 ;; Rest is handled by single and.
3640 [(set (match_operand:SI 0 "register_operand" "")
3641 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3642 (clobber (reg:CC FLAGS_REG))]
3644 && true_regnum (operands[0]) == true_regnum (operands[1])"
3645 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3646 (clobber (reg:CC FLAGS_REG))])]
3649 ;; %%% Kill me once multi-word ops are sane.
3650 (define_expand "zero_extendsidi2"
3651 [(set (match_operand:DI 0 "register_operand" "")
3652 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3657 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3662 (define_insn "zero_extendsidi2_32"
3663 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3665 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3666 (clobber (reg:CC FLAGS_REG))]
3672 movd\t{%1, %0|%0, %1}
3673 movd\t{%1, %0|%0, %1}
3674 movd\t{%1, %0|%0, %1}
3675 movd\t{%1, %0|%0, %1}"
3676 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3677 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3679 (define_insn "zero_extendsidi2_rex64"
3680 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3682 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3685 mov\t{%k1, %k0|%k0, %k1}
3687 movd\t{%1, %0|%0, %1}
3688 movd\t{%1, %0|%0, %1}
3689 movd\t{%1, %0|%0, %1}
3690 movd\t{%1, %0|%0, %1}"
3691 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3692 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3695 [(set (match_operand:DI 0 "memory_operand" "")
3696 (zero_extend:DI (match_dup 0)))]
3698 [(set (match_dup 4) (const_int 0))]
3699 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3702 [(set (match_operand:DI 0 "register_operand" "")
3703 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3704 (clobber (reg:CC FLAGS_REG))]
3705 "!TARGET_64BIT && reload_completed
3706 && true_regnum (operands[0]) == true_regnum (operands[1])"
3707 [(set (match_dup 4) (const_int 0))]
3708 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3711 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3712 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3713 (clobber (reg:CC FLAGS_REG))]
3714 "!TARGET_64BIT && reload_completed
3715 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3716 [(set (match_dup 3) (match_dup 1))
3717 (set (match_dup 4) (const_int 0))]
3718 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3720 (define_insn "zero_extendhidi2"
3721 [(set (match_operand:DI 0 "register_operand" "=r")
3722 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3724 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3725 [(set_attr "type" "imovx")
3726 (set_attr "mode" "DI")])
3728 (define_insn "zero_extendqidi2"
3729 [(set (match_operand:DI 0 "register_operand" "=r")
3730 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3732 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3733 [(set_attr "type" "imovx")
3734 (set_attr "mode" "DI")])
3736 ;; Sign extension instructions
3738 (define_expand "extendsidi2"
3739 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3740 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3741 (clobber (reg:CC FLAGS_REG))
3742 (clobber (match_scratch:SI 2 ""))])]
3747 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3752 (define_insn "*extendsidi2_1"
3753 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3754 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3755 (clobber (reg:CC FLAGS_REG))
3756 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3760 (define_insn "extendsidi2_rex64"
3761 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3762 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3766 movs{lq|x}\t{%1,%0|%0, %1}"
3767 [(set_attr "type" "imovx")
3768 (set_attr "mode" "DI")
3769 (set_attr "prefix_0f" "0")
3770 (set_attr "modrm" "0,1")])
3772 (define_insn "extendhidi2"
3773 [(set (match_operand:DI 0 "register_operand" "=r")
3774 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3776 "movs{wq|x}\t{%1,%0|%0, %1}"
3777 [(set_attr "type" "imovx")
3778 (set_attr "mode" "DI")])
3780 (define_insn "extendqidi2"
3781 [(set (match_operand:DI 0 "register_operand" "=r")
3782 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3784 "movs{bq|x}\t{%1,%0|%0, %1}"
3785 [(set_attr "type" "imovx")
3786 (set_attr "mode" "DI")])
3788 ;; Extend to memory case when source register does die.
3790 [(set (match_operand:DI 0 "memory_operand" "")
3791 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3792 (clobber (reg:CC FLAGS_REG))
3793 (clobber (match_operand:SI 2 "register_operand" ""))]
3795 && dead_or_set_p (insn, operands[1])
3796 && !reg_mentioned_p (operands[1], operands[0]))"
3797 [(set (match_dup 3) (match_dup 1))
3798 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3799 (clobber (reg:CC FLAGS_REG))])
3800 (set (match_dup 4) (match_dup 1))]
3801 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3803 ;; Extend to memory case when source register does not die.
3805 [(set (match_operand:DI 0 "memory_operand" "")
3806 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3807 (clobber (reg:CC FLAGS_REG))
3808 (clobber (match_operand:SI 2 "register_operand" ""))]
3812 split_di (&operands[0], 1, &operands[3], &operands[4]);
3814 emit_move_insn (operands[3], operands[1]);
3816 /* Generate a cltd if possible and doing so it profitable. */
3817 if ((optimize_size || TARGET_USE_CLTD)
3818 && true_regnum (operands[1]) == AX_REG
3819 && true_regnum (operands[2]) == DX_REG)
3821 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3825 emit_move_insn (operands[2], operands[1]);
3826 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3828 emit_move_insn (operands[4], operands[2]);
3832 ;; Extend to register case. Optimize case where source and destination
3833 ;; registers match and cases where we can use cltd.
3835 [(set (match_operand:DI 0 "register_operand" "")
3836 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3837 (clobber (reg:CC FLAGS_REG))
3838 (clobber (match_scratch:SI 2 ""))]
3842 split_di (&operands[0], 1, &operands[3], &operands[4]);
3844 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3845 emit_move_insn (operands[3], operands[1]);
3847 /* Generate a cltd if possible and doing so it profitable. */
3848 if ((optimize_size || TARGET_USE_CLTD)
3849 && true_regnum (operands[3]) == AX_REG)
3851 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3855 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3856 emit_move_insn (operands[4], operands[1]);
3858 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3862 (define_insn "extendhisi2"
3863 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3864 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3867 switch (get_attr_prefix_0f (insn))
3870 return "{cwtl|cwde}";
3872 return "movs{wl|x}\t{%1,%0|%0, %1}";
3875 [(set_attr "type" "imovx")
3876 (set_attr "mode" "SI")
3877 (set (attr "prefix_0f")
3878 ;; movsx is short decodable while cwtl is vector decoded.
3879 (if_then_else (and (eq_attr "cpu" "!k6")
3880 (eq_attr "alternative" "0"))
3882 (const_string "1")))
3884 (if_then_else (eq_attr "prefix_0f" "0")
3886 (const_string "1")))])
3888 (define_insn "*extendhisi2_zext"
3889 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3891 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3894 switch (get_attr_prefix_0f (insn))
3897 return "{cwtl|cwde}";
3899 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3902 [(set_attr "type" "imovx")
3903 (set_attr "mode" "SI")
3904 (set (attr "prefix_0f")
3905 ;; movsx is short decodable while cwtl is vector decoded.
3906 (if_then_else (and (eq_attr "cpu" "!k6")
3907 (eq_attr "alternative" "0"))
3909 (const_string "1")))
3911 (if_then_else (eq_attr "prefix_0f" "0")
3913 (const_string "1")))])
3915 (define_insn "extendqihi2"
3916 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3917 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3920 switch (get_attr_prefix_0f (insn))
3923 return "{cbtw|cbw}";
3925 return "movs{bw|x}\t{%1,%0|%0, %1}";
3928 [(set_attr "type" "imovx")
3929 (set_attr "mode" "HI")
3930 (set (attr "prefix_0f")
3931 ;; movsx is short decodable while cwtl is vector decoded.
3932 (if_then_else (and (eq_attr "cpu" "!k6")
3933 (eq_attr "alternative" "0"))
3935 (const_string "1")))
3937 (if_then_else (eq_attr "prefix_0f" "0")
3939 (const_string "1")))])
3941 (define_insn "extendqisi2"
3942 [(set (match_operand:SI 0 "register_operand" "=r")
3943 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3945 "movs{bl|x}\t{%1,%0|%0, %1}"
3946 [(set_attr "type" "imovx")
3947 (set_attr "mode" "SI")])
3949 (define_insn "*extendqisi2_zext"
3950 [(set (match_operand:DI 0 "register_operand" "=r")
3952 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3954 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3955 [(set_attr "type" "imovx")
3956 (set_attr "mode" "SI")])
3958 ;; Conversions between float and double.
3960 ;; These are all no-ops in the model used for the 80387. So just
3963 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3964 (define_insn "*dummy_extendsfdf2"
3965 [(set (match_operand:DF 0 "push_operand" "=<")
3966 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3971 [(set (match_operand:DF 0 "push_operand" "")
3972 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3974 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3975 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3977 (define_insn "*dummy_extendsfxf2"
3978 [(set (match_operand:XF 0 "push_operand" "=<")
3979 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3984 [(set (match_operand:XF 0 "push_operand" "")
3985 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3987 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3988 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3989 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3992 [(set (match_operand:XF 0 "push_operand" "")
3993 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3995 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3996 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3997 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3999 (define_expand "extendsfdf2"
4000 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4001 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4002 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4004 /* ??? Needed for compress_float_constant since all fp constants
4005 are LEGITIMATE_CONSTANT_P. */
4006 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4008 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4009 && standard_80387_constant_p (operands[1]) > 0)
4011 operands[1] = simplify_const_unary_operation
4012 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4013 emit_move_insn_1 (operands[0], operands[1]);
4016 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4020 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4022 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4024 We do the conversion post reload to avoid producing of 128bit spills
4025 that might lead to ICE on 32bit target. The sequence unlikely combine
4028 [(set (match_operand:DF 0 "register_operand" "")
4030 (match_operand:SF 1 "nonimmediate_operand" "")))]
4031 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4032 && reload_completed && SSE_REG_P (operands[0])"
4037 (parallel [(const_int 0) (const_int 1)]))))]
4039 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4040 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4041 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4042 Try to avoid move when unpacking can be done in source. */
4043 if (REG_P (operands[1]))
4045 /* If it is unsafe to overwrite upper half of source, we need
4046 to move to destination and unpack there. */
4047 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4048 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4049 && true_regnum (operands[0]) != true_regnum (operands[1]))
4051 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4052 emit_move_insn (tmp, operands[1]);
4055 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4056 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4059 emit_insn (gen_vec_setv4sf_0 (operands[3],
4060 CONST0_RTX (V4SFmode), operands[1]));
4063 (define_insn "*extendsfdf2_mixed"
4064 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4066 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4067 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4069 switch (which_alternative)
4073 return output_387_reg_move (insn, operands);
4076 return "cvtss2sd\t{%1, %0|%0, %1}";
4082 [(set_attr "type" "fmov,fmov,ssecvt")
4083 (set_attr "mode" "SF,XF,DF")])
4085 (define_insn "*extendsfdf2_sse"
4086 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4087 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4088 "TARGET_SSE2 && TARGET_SSE_MATH"
4089 "cvtss2sd\t{%1, %0|%0, %1}"
4090 [(set_attr "type" "ssecvt")
4091 (set_attr "mode" "DF")])
4093 (define_insn "*extendsfdf2_i387"
4094 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4095 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4097 "* return output_387_reg_move (insn, operands);"
4098 [(set_attr "type" "fmov")
4099 (set_attr "mode" "SF,XF")])
4101 (define_expand "extend<mode>xf2"
4102 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4103 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4106 /* ??? Needed for compress_float_constant since all fp constants
4107 are LEGITIMATE_CONSTANT_P. */
4108 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4110 if (standard_80387_constant_p (operands[1]) > 0)
4112 operands[1] = simplify_const_unary_operation
4113 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4114 emit_move_insn_1 (operands[0], operands[1]);
4117 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4121 (define_insn "*extend<mode>xf2_i387"
4122 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4124 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4126 "* return output_387_reg_move (insn, operands);"
4127 [(set_attr "type" "fmov")
4128 (set_attr "mode" "<MODE>,XF")])
4130 ;; %%% This seems bad bad news.
4131 ;; This cannot output into an f-reg because there is no way to be sure
4132 ;; of truncating in that case. Otherwise this is just like a simple move
4133 ;; insn. So we pretend we can output to a reg in order to get better
4134 ;; register preferencing, but we really use a stack slot.
4136 ;; Conversion from DFmode to SFmode.
4138 (define_expand "truncdfsf2"
4139 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4141 (match_operand:DF 1 "nonimmediate_operand" "")))]
4142 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4144 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4146 else if (flag_unsafe_math_optimizations)
4150 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4151 rtx temp = assign_386_stack_local (SFmode, slot);
4152 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4157 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4159 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4161 We do the conversion post reload to avoid producing of 128bit spills
4162 that might lead to ICE on 32bit target. The sequence unlikely combine
4165 [(set (match_operand:SF 0 "register_operand" "")
4167 (match_operand:DF 1 "nonimmediate_operand" "")))]
4168 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4169 && reload_completed && SSE_REG_P (operands[0])"
4172 (float_truncate:V2SF
4176 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4177 operands[3] = CONST0_RTX (V2SFmode);
4178 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4179 /* Use movsd for loading from memory, unpcklpd for registers.
4180 Try to avoid move when unpacking can be done in source, or SSE3
4181 movddup is available. */
4182 if (REG_P (operands[1]))
4185 && true_regnum (operands[0]) != true_regnum (operands[1])
4186 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4187 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4189 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4190 emit_move_insn (tmp, operands[1]);
4193 else if (!TARGET_SSE3)
4194 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4195 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4198 emit_insn (gen_sse2_loadlpd (operands[4],
4199 CONST0_RTX (V2DFmode), operands[1]));
4202 (define_expand "truncdfsf2_with_temp"
4203 [(parallel [(set (match_operand:SF 0 "" "")
4204 (float_truncate:SF (match_operand:DF 1 "" "")))
4205 (clobber (match_operand:SF 2 "" ""))])]
4208 (define_insn "*truncdfsf_fast_mixed"
4209 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4211 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4212 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4214 switch (which_alternative)
4217 return output_387_reg_move (insn, operands);
4219 return "cvtsd2ss\t{%1, %0|%0, %1}";
4224 [(set_attr "type" "fmov,ssecvt")
4225 (set_attr "mode" "SF")])
4227 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4228 ;; because nothing we do here is unsafe.
4229 (define_insn "*truncdfsf_fast_sse"
4230 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4232 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4233 "TARGET_SSE2 && TARGET_SSE_MATH"
4234 "cvtsd2ss\t{%1, %0|%0, %1}"
4235 [(set_attr "type" "ssecvt")
4236 (set_attr "mode" "SF")])
4238 (define_insn "*truncdfsf_fast_i387"
4239 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4241 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4242 "TARGET_80387 && flag_unsafe_math_optimizations"
4243 "* return output_387_reg_move (insn, operands);"
4244 [(set_attr "type" "fmov")
4245 (set_attr "mode" "SF")])
4247 (define_insn "*truncdfsf_mixed"
4248 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4250 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4251 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4252 "TARGET_MIX_SSE_I387"
4254 switch (which_alternative)
4257 return output_387_reg_move (insn, operands);
4262 return "cvtsd2ss\t{%1, %0|%0, %1}";
4267 [(set_attr "type" "fmov,multi,ssecvt")
4268 (set_attr "unit" "*,i387,*")
4269 (set_attr "mode" "SF")])
4271 (define_insn "*truncdfsf_i387"
4272 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4274 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4275 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4278 switch (which_alternative)
4281 return output_387_reg_move (insn, operands);
4289 [(set_attr "type" "fmov,multi")
4290 (set_attr "unit" "*,i387")
4291 (set_attr "mode" "SF")])
4293 (define_insn "*truncdfsf2_i387_1"
4294 [(set (match_operand:SF 0 "memory_operand" "=m")
4296 (match_operand:DF 1 "register_operand" "f")))]
4298 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299 && !TARGET_MIX_SSE_I387"
4300 "* return output_387_reg_move (insn, operands);"
4301 [(set_attr "type" "fmov")
4302 (set_attr "mode" "SF")])
4305 [(set (match_operand:SF 0 "register_operand" "")
4307 (match_operand:DF 1 "fp_register_operand" "")))
4308 (clobber (match_operand 2 "" ""))]
4310 [(set (match_dup 2) (match_dup 1))
4311 (set (match_dup 0) (match_dup 2))]
4313 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4316 ;; Conversion from XFmode to {SF,DF}mode
4318 (define_expand "truncxf<mode>2"
4319 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4320 (float_truncate:MODEF
4321 (match_operand:XF 1 "register_operand" "")))
4322 (clobber (match_dup 2))])]
4325 if (flag_unsafe_math_optimizations)
4327 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4328 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4329 if (reg != operands[0])
4330 emit_move_insn (operands[0], reg);
4335 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4336 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4340 (define_insn "*truncxfsf2_mixed"
4341 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4343 (match_operand:XF 1 "register_operand" "f,f")))
4344 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4347 gcc_assert (!which_alternative);
4348 return output_387_reg_move (insn, operands);
4350 [(set_attr "type" "fmov,multi")
4351 (set_attr "unit" "*,i387")
4352 (set_attr "mode" "SF")])
4354 (define_insn "*truncxfdf2_mixed"
4355 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4357 (match_operand:XF 1 "register_operand" "f,f")))
4358 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4361 gcc_assert (!which_alternative);
4362 return output_387_reg_move (insn, operands);
4364 [(set_attr "type" "fmov,multi")
4365 (set_attr "unit" "*,i387")
4366 (set_attr "mode" "DF")])
4368 (define_insn "truncxf<mode>2_i387_noop"
4369 [(set (match_operand:MODEF 0 "register_operand" "=f")
4370 (float_truncate:MODEF
4371 (match_operand:XF 1 "register_operand" "f")))]
4372 "TARGET_80387 && flag_unsafe_math_optimizations"
4373 "* return output_387_reg_move (insn, operands);"
4374 [(set_attr "type" "fmov")
4375 (set_attr "mode" "<MODE>")])
4377 (define_insn "*truncxf<mode>2_i387"
4378 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4379 (float_truncate:MODEF
4380 (match_operand:XF 1 "register_operand" "f")))]
4382 "* return output_387_reg_move (insn, operands);"
4383 [(set_attr "type" "fmov")
4384 (set_attr "mode" "<MODE>")])
4387 [(set (match_operand:MODEF 0 "register_operand" "")
4388 (float_truncate:MODEF
4389 (match_operand:XF 1 "register_operand" "")))
4390 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4391 "TARGET_80387 && reload_completed"
4392 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4393 (set (match_dup 0) (match_dup 2))]
4397 [(set (match_operand:MODEF 0 "memory_operand" "")
4398 (float_truncate:MODEF
4399 (match_operand:XF 1 "register_operand" "")))
4400 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4402 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4405 ;; Signed conversion to DImode.
4407 (define_expand "fix_truncxfdi2"
4408 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4409 (fix:DI (match_operand:XF 1 "register_operand" "")))
4410 (clobber (reg:CC FLAGS_REG))])]
4415 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4420 (define_expand "fix_trunc<mode>di2"
4421 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4422 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4423 (clobber (reg:CC FLAGS_REG))])]
4424 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4427 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4429 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4432 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4434 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4435 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4436 if (out != operands[0])
4437 emit_move_insn (operands[0], out);
4442 ;; Signed conversion to SImode.
4444 (define_expand "fix_truncxfsi2"
4445 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4446 (fix:SI (match_operand:XF 1 "register_operand" "")))
4447 (clobber (reg:CC FLAGS_REG))])]
4452 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4457 (define_expand "fix_trunc<mode>si2"
4458 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4459 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4460 (clobber (reg:CC FLAGS_REG))])]
4461 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4464 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4466 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4469 if (SSE_FLOAT_MODE_P (<MODE>mode))
4471 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4472 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4473 if (out != operands[0])
4474 emit_move_insn (operands[0], out);
4479 ;; Signed conversion to HImode.
4481 (define_expand "fix_trunc<mode>hi2"
4482 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4483 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4484 (clobber (reg:CC FLAGS_REG))])]
4486 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4490 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4495 ;; Unsigned conversion to SImode.
4497 (define_expand "fixuns_trunc<mode>si2"
4499 [(set (match_operand:SI 0 "register_operand" "")
4501 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4503 (clobber (match_scratch:<ssevecmode> 3 ""))
4504 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4505 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4507 enum machine_mode mode = <MODE>mode;
4508 enum machine_mode vecmode = <ssevecmode>mode;
4509 REAL_VALUE_TYPE TWO31r;
4512 real_ldexp (&TWO31r, &dconst1, 31);
4513 two31 = const_double_from_real_value (TWO31r, mode);
4514 two31 = ix86_build_const_vector (mode, true, two31);
4515 operands[2] = force_reg (vecmode, two31);
4518 (define_insn_and_split "*fixuns_trunc<mode>_1"
4519 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4521 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4522 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4523 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4524 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4525 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4527 "&& reload_completed"
4530 ix86_split_convert_uns_si_sse (operands);
4534 ;; Unsigned conversion to HImode.
4535 ;; Without these patterns, we'll try the unsigned SI conversion which
4536 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4538 (define_expand "fixuns_trunc<mode>hi2"
4540 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4541 (set (match_operand:HI 0 "nonimmediate_operand" "")
4542 (subreg:HI (match_dup 2) 0))]
4543 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4544 "operands[2] = gen_reg_rtx (SImode);")
4546 ;; When SSE is available, it is always faster to use it!
4547 (define_insn "fix_trunc<mode>di_sse"
4548 [(set (match_operand:DI 0 "register_operand" "=r,r")
4549 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4550 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4551 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4552 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4553 [(set_attr "type" "sseicvt")
4554 (set_attr "mode" "<MODE>")
4555 (set_attr "athlon_decode" "double,vector")
4556 (set_attr "amdfam10_decode" "double,double")])
4558 (define_insn "fix_trunc<mode>si_sse"
4559 [(set (match_operand:SI 0 "register_operand" "=r,r")
4560 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4561 "SSE_FLOAT_MODE_P (<MODE>mode)
4562 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4563 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4564 [(set_attr "type" "sseicvt")
4565 (set_attr "mode" "<MODE>")
4566 (set_attr "athlon_decode" "double,vector")
4567 (set_attr "amdfam10_decode" "double,double")])
4569 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4571 [(set (match_operand:MODEF 0 "register_operand" "")
4572 (match_operand:MODEF 1 "memory_operand" ""))
4573 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4574 (fix:SSEMODEI24 (match_dup 0)))]
4575 "TARGET_SHORTEN_X87_SSE
4576 && peep2_reg_dead_p (2, operands[0])"
4577 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4580 ;; Avoid vector decoded forms of the instruction.
4582 [(match_scratch:DF 2 "Y2")
4583 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4584 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4585 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4586 [(set (match_dup 2) (match_dup 1))
4587 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4591 [(match_scratch:SF 2 "x")
4592 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4593 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4594 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4595 [(set (match_dup 2) (match_dup 1))
4596 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4599 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4600 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4601 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4602 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4604 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4605 && (TARGET_64BIT || <MODE>mode != DImode))
4607 && !(reload_completed || reload_in_progress)"
4612 if (memory_operand (operands[0], VOIDmode))
4613 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4616 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4617 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4623 [(set_attr "type" "fisttp")
4624 (set_attr "mode" "<MODE>")])
4626 (define_insn "fix_trunc<mode>_i387_fisttp"
4627 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4628 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4629 (clobber (match_scratch:XF 2 "=&1f"))]
4630 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4632 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4633 && (TARGET_64BIT || <MODE>mode != DImode))
4634 && TARGET_SSE_MATH)"
4635 "* return output_fix_trunc (insn, operands, 1);"
4636 [(set_attr "type" "fisttp")
4637 (set_attr "mode" "<MODE>")])
4639 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4640 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4641 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4642 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4643 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4644 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4646 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4647 && (TARGET_64BIT || <MODE>mode != DImode))
4648 && TARGET_SSE_MATH)"
4650 [(set_attr "type" "fisttp")
4651 (set_attr "mode" "<MODE>")])
4654 [(set (match_operand:X87MODEI 0 "register_operand" "")
4655 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4656 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4657 (clobber (match_scratch 3 ""))]
4659 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4660 (clobber (match_dup 3))])
4661 (set (match_dup 0) (match_dup 2))]
4665 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4666 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4667 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4668 (clobber (match_scratch 3 ""))]
4670 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4671 (clobber (match_dup 3))])]
4674 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4675 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4676 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4677 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4678 ;; function in i386.c.
4679 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4680 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4681 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4682 (clobber (reg:CC FLAGS_REG))]
4683 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4685 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4686 && (TARGET_64BIT || <MODE>mode != DImode))
4687 && !(reload_completed || reload_in_progress)"
4692 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4694 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4695 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4696 if (memory_operand (operands[0], VOIDmode))
4697 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4698 operands[2], operands[3]));
4701 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4702 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4703 operands[2], operands[3],
4708 [(set_attr "type" "fistp")
4709 (set_attr "i387_cw" "trunc")
4710 (set_attr "mode" "<MODE>")])
4712 (define_insn "fix_truncdi_i387"
4713 [(set (match_operand:DI 0 "memory_operand" "=m")
4714 (fix:DI (match_operand 1 "register_operand" "f")))
4715 (use (match_operand:HI 2 "memory_operand" "m"))
4716 (use (match_operand:HI 3 "memory_operand" "m"))
4717 (clobber (match_scratch:XF 4 "=&1f"))]
4718 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4720 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4721 "* return output_fix_trunc (insn, operands, 0);"
4722 [(set_attr "type" "fistp")
4723 (set_attr "i387_cw" "trunc")
4724 (set_attr "mode" "DI")])
4726 (define_insn "fix_truncdi_i387_with_temp"
4727 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4728 (fix:DI (match_operand 1 "register_operand" "f,f")))
4729 (use (match_operand:HI 2 "memory_operand" "m,m"))
4730 (use (match_operand:HI 3 "memory_operand" "m,m"))
4731 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4732 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4733 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4735 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4737 [(set_attr "type" "fistp")
4738 (set_attr "i387_cw" "trunc")
4739 (set_attr "mode" "DI")])
4742 [(set (match_operand:DI 0 "register_operand" "")
4743 (fix:DI (match_operand 1 "register_operand" "")))
4744 (use (match_operand:HI 2 "memory_operand" ""))
4745 (use (match_operand:HI 3 "memory_operand" ""))
4746 (clobber (match_operand:DI 4 "memory_operand" ""))
4747 (clobber (match_scratch 5 ""))]
4749 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4752 (clobber (match_dup 5))])
4753 (set (match_dup 0) (match_dup 4))]
4757 [(set (match_operand:DI 0 "memory_operand" "")
4758 (fix:DI (match_operand 1 "register_operand" "")))
4759 (use (match_operand:HI 2 "memory_operand" ""))
4760 (use (match_operand:HI 3 "memory_operand" ""))
4761 (clobber (match_operand:DI 4 "memory_operand" ""))
4762 (clobber (match_scratch 5 ""))]
4764 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4767 (clobber (match_dup 5))])]
4770 (define_insn "fix_trunc<mode>_i387"
4771 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4772 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4773 (use (match_operand:HI 2 "memory_operand" "m"))
4774 (use (match_operand:HI 3 "memory_operand" "m"))]
4775 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4777 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4778 "* return output_fix_trunc (insn, operands, 0);"
4779 [(set_attr "type" "fistp")
4780 (set_attr "i387_cw" "trunc")
4781 (set_attr "mode" "<MODE>")])
4783 (define_insn "fix_trunc<mode>_i387_with_temp"
4784 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4785 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4786 (use (match_operand:HI 2 "memory_operand" "m,m"))
4787 (use (match_operand:HI 3 "memory_operand" "m,m"))
4788 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4789 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4791 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4793 [(set_attr "type" "fistp")
4794 (set_attr "i387_cw" "trunc")
4795 (set_attr "mode" "<MODE>")])
4798 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4799 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4800 (use (match_operand:HI 2 "memory_operand" ""))
4801 (use (match_operand:HI 3 "memory_operand" ""))
4802 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4804 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4806 (use (match_dup 3))])
4807 (set (match_dup 0) (match_dup 4))]
4811 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4812 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4813 (use (match_operand:HI 2 "memory_operand" ""))
4814 (use (match_operand:HI 3 "memory_operand" ""))
4815 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4817 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4819 (use (match_dup 3))])]
4822 (define_insn "x86_fnstcw_1"
4823 [(set (match_operand:HI 0 "memory_operand" "=m")
4824 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4827 [(set_attr "length" "2")
4828 (set_attr "mode" "HI")
4829 (set_attr "unit" "i387")])
4831 (define_insn "x86_fldcw_1"
4832 [(set (reg:HI FPCR_REG)
4833 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4836 [(set_attr "length" "2")
4837 (set_attr "mode" "HI")
4838 (set_attr "unit" "i387")
4839 (set_attr "athlon_decode" "vector")
4840 (set_attr "amdfam10_decode" "vector")])
4842 ;; Conversion between fixed point and floating point.
4844 ;; Even though we only accept memory inputs, the backend _really_
4845 ;; wants to be able to do this between registers.
4847 (define_expand "floathi<mode>2"
4848 [(set (match_operand:X87MODEF 0 "register_operand" "")
4849 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4852 || TARGET_MIX_SSE_I387)"
4855 ;; Pre-reload splitter to add memory clobber to the pattern.
4856 (define_insn_and_split "*floathi<mode>2_1"
4857 [(set (match_operand:X87MODEF 0 "register_operand" "")
4858 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4860 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4861 || TARGET_MIX_SSE_I387)
4862 && !(reload_completed || reload_in_progress)"
4865 [(parallel [(set (match_dup 0)
4866 (float:X87MODEF (match_dup 1)))
4867 (clobber (match_dup 2))])]
4868 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4870 (define_insn "*floathi<mode>2_i387_with_temp"
4871 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4872 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4873 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4875 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4876 || TARGET_MIX_SSE_I387)"
4878 [(set_attr "type" "fmov,multi")
4879 (set_attr "mode" "<MODE>")
4880 (set_attr "unit" "*,i387")
4881 (set_attr "fp_int_src" "true")])
4883 (define_insn "*floathi<mode>2_i387"
4884 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4885 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4887 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4888 || TARGET_MIX_SSE_I387)"
4890 [(set_attr "type" "fmov")
4891 (set_attr "mode" "<MODE>")
4892 (set_attr "fp_int_src" "true")])
4895 [(set (match_operand:X87MODEF 0 "register_operand" "")
4896 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4897 (clobber (match_operand:HI 2 "memory_operand" ""))]
4899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4900 || TARGET_MIX_SSE_I387)
4901 && reload_completed"
4902 [(set (match_dup 2) (match_dup 1))
4903 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4907 [(set (match_operand:X87MODEF 0 "register_operand" "")
4908 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4909 (clobber (match_operand:HI 2 "memory_operand" ""))]
4911 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4912 || TARGET_MIX_SSE_I387)
4913 && reload_completed"
4914 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4917 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4918 [(set (match_operand:X87MODEF 0 "register_operand" "")
4920 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4922 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4923 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4926 ;; Pre-reload splitter to add memory clobber to the pattern.
4927 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4928 [(set (match_operand:X87MODEF 0 "register_operand" "")
4929 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4931 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4932 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4933 || TARGET_MIX_SSE_I387))
4934 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4935 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4936 && ((<SSEMODEI24:MODE>mode == SImode
4937 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4938 && flag_trapping_math)
4939 || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4940 && !(reload_completed || reload_in_progress)"
4943 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4944 (clobber (match_dup 2))])]
4946 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4948 /* Avoid store forwarding (partial memory) stall penalty
4949 by passing DImode value through XMM registers. */
4950 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4951 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4954 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4961 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4962 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4964 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4965 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4966 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4967 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4969 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4970 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4971 (set_attr "unit" "*,i387,*,*,*")
4972 (set_attr "athlon_decode" "*,*,double,direct,double")
4973 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4974 (set_attr "fp_int_src" "true")])
4976 (define_insn "*floatsi<mode>2_vector_mixed"
4977 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4978 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4979 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4980 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4984 [(set_attr "type" "fmov,sseicvt")
4985 (set_attr "mode" "<MODE>,<ssevecmode>")
4986 (set_attr "unit" "i387,*")
4987 (set_attr "athlon_decode" "*,direct")
4988 (set_attr "amdfam10_decode" "*,double")
4989 (set_attr "fp_int_src" "true")])
4991 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4992 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4994 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4995 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4996 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4997 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4999 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5000 (set_attr "mode" "<MODEF:MODE>")
5001 (set_attr "unit" "*,i387,*,*")
5002 (set_attr "athlon_decode" "*,*,double,direct")
5003 (set_attr "amdfam10_decode" "*,*,vector,double")
5004 (set_attr "fp_int_src" "true")])
5007 [(set (match_operand:MODEF 0 "register_operand" "")
5008 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5009 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5010 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5011 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5012 && TARGET_INTER_UNIT_CONVERSIONS
5014 && (SSE_REG_P (operands[0])
5015 || (GET_CODE (operands[0]) == SUBREG
5016 && SSE_REG_P (operands[0])))"
5017 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5021 [(set (match_operand:MODEF 0 "register_operand" "")
5022 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5023 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5024 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5025 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5026 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5028 && (SSE_REG_P (operands[0])
5029 || (GET_CODE (operands[0]) == SUBREG
5030 && SSE_REG_P (operands[0])))"
5031 [(set (match_dup 2) (match_dup 1))
5032 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5035 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5036 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5038 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5039 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5040 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5041 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5044 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5045 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5046 [(set_attr "type" "fmov,sseicvt,sseicvt")
5047 (set_attr "mode" "<MODEF:MODE>")
5048 (set_attr "unit" "i387,*,*")
5049 (set_attr "athlon_decode" "*,double,direct")
5050 (set_attr "amdfam10_decode" "*,vector,double")
5051 (set_attr "fp_int_src" "true")])
5053 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5054 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5056 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5057 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5058 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5059 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5062 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5063 [(set_attr "type" "fmov,sseicvt")
5064 (set_attr "mode" "<MODEF:MODE>")
5065 (set_attr "athlon_decode" "*,direct")
5066 (set_attr "amdfam10_decode" "*,double")
5067 (set_attr "fp_int_src" "true")])
5069 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5070 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5072 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5073 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5074 "TARGET_SSE2 && TARGET_SSE_MATH
5075 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5077 [(set_attr "type" "sseicvt")
5078 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5079 (set_attr "athlon_decode" "double,direct,double")
5080 (set_attr "amdfam10_decode" "vector,double,double")
5081 (set_attr "fp_int_src" "true")])
5083 (define_insn "*floatsi<mode>2_vector_sse"
5084 [(set (match_operand:MODEF 0 "register_operand" "=x")
5085 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5086 "TARGET_SSE2 && TARGET_SSE_MATH
5087 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5089 [(set_attr "type" "sseicvt")
5090 (set_attr "mode" "<MODE>")
5091 (set_attr "athlon_decode" "direct")
5092 (set_attr "amdfam10_decode" "double")
5093 (set_attr "fp_int_src" "true")])
5096 [(set (match_operand:MODEF 0 "register_operand" "")
5097 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5098 (clobber (match_operand:SI 2 "memory_operand" ""))]
5099 "TARGET_SSE2 && TARGET_SSE_MATH
5100 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5102 && (SSE_REG_P (operands[0])
5103 || (GET_CODE (operands[0]) == SUBREG
5104 && SSE_REG_P (operands[0])))"
5107 rtx op1 = operands[1];
5109 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5111 if (GET_CODE (op1) == SUBREG)
5112 op1 = SUBREG_REG (op1);
5114 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5116 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5117 emit_insn (gen_sse2_loadld (operands[4],
5118 CONST0_RTX (V4SImode), operands[1]));
5120 /* We can ignore possible trapping value in the
5121 high part of SSE register for non-trapping math. */
5122 else if (SSE_REG_P (op1) && !flag_trapping_math)
5123 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5126 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5127 emit_move_insn (operands[2], operands[1]);
5128 emit_insn (gen_sse2_loadld (operands[4],
5129 CONST0_RTX (V4SImode), operands[2]));
5132 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5137 [(set (match_operand:MODEF 0 "register_operand" "")
5138 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5139 (clobber (match_operand:SI 2 "memory_operand" ""))]
5140 "TARGET_SSE2 && TARGET_SSE_MATH
5141 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5143 && (SSE_REG_P (operands[0])
5144 || (GET_CODE (operands[0]) == SUBREG
5145 && SSE_REG_P (operands[0])))"
5148 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5150 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5152 emit_insn (gen_sse2_loadld (operands[4],
5153 CONST0_RTX (V4SImode), operands[1]));
5155 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5160 [(set (match_operand:MODEF 0 "register_operand" "")
5161 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5162 "TARGET_SSE2 && TARGET_SSE_MATH
5163 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5165 && (SSE_REG_P (operands[0])
5166 || (GET_CODE (operands[0]) == SUBREG
5167 && SSE_REG_P (operands[0])))"
5170 rtx op1 = operands[1];
5172 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5174 if (GET_CODE (op1) == SUBREG)
5175 op1 = SUBREG_REG (op1);
5177 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5179 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5180 emit_insn (gen_sse2_loadld (operands[4],
5181 CONST0_RTX (V4SImode), operands[1]));
5183 /* We can ignore possible trapping value in the
5184 high part of SSE register for non-trapping math. */
5185 else if (SSE_REG_P (op1) && !flag_trapping_math)
5186 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5192 [(set (match_operand:MODEF 0 "register_operand" "")
5193 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5194 "TARGET_SSE2 && TARGET_SSE_MATH
5195 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5197 && (SSE_REG_P (operands[0])
5198 || (GET_CODE (operands[0]) == SUBREG
5199 && SSE_REG_P (operands[0])))"
5202 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5204 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5206 emit_insn (gen_sse2_loadld (operands[4],
5207 CONST0_RTX (V4SImode), operands[1]));
5209 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5213 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5214 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5216 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5217 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5218 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5219 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5221 [(set_attr "type" "sseicvt")
5222 (set_attr "mode" "<MODEF:MODE>")
5223 (set_attr "athlon_decode" "double,direct")
5224 (set_attr "amdfam10_decode" "vector,double")
5225 (set_attr "fp_int_src" "true")])
5227 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5228 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5230 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5231 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5232 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5233 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5234 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5235 [(set_attr "type" "sseicvt")
5236 (set_attr "mode" "<MODEF:MODE>")
5237 (set_attr "athlon_decode" "double,direct")
5238 (set_attr "amdfam10_decode" "vector,double")
5239 (set_attr "fp_int_src" "true")])
5242 [(set (match_operand:MODEF 0 "register_operand" "")
5243 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5244 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5245 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5246 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5247 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5249 && (SSE_REG_P (operands[0])
5250 || (GET_CODE (operands[0]) == SUBREG
5251 && SSE_REG_P (operands[0])))"
5252 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5255 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5256 [(set (match_operand:MODEF 0 "register_operand" "=x")
5258 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5259 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5260 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5261 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5262 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5263 [(set_attr "type" "sseicvt")
5264 (set_attr "mode" "<MODEF:MODE>")
5265 (set_attr "athlon_decode" "direct")
5266 (set_attr "amdfam10_decode" "double")
5267 (set_attr "fp_int_src" "true")])
5270 [(set (match_operand:MODEF 0 "register_operand" "")
5271 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5272 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5273 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5274 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5275 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5277 && (SSE_REG_P (operands[0])
5278 || (GET_CODE (operands[0]) == SUBREG
5279 && SSE_REG_P (operands[0])))"
5280 [(set (match_dup 2) (match_dup 1))
5281 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5285 [(set (match_operand:MODEF 0 "register_operand" "")
5286 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5287 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5288 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5289 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5291 && (SSE_REG_P (operands[0])
5292 || (GET_CODE (operands[0]) == SUBREG
5293 && SSE_REG_P (operands[0])))"
5294 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5297 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5298 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5300 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5301 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5306 [(set_attr "type" "fmov,multi")
5307 (set_attr "mode" "<X87MODEF:MODE>")
5308 (set_attr "unit" "*,i387")
5309 (set_attr "fp_int_src" "true")])
5311 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5312 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5314 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5317 [(set_attr "type" "fmov")
5318 (set_attr "mode" "<X87MODEF:MODE>")
5319 (set_attr "fp_int_src" "true")])
5322 [(set (match_operand:X87MODEF 0 "register_operand" "")
5323 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5324 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5327 && FP_REG_P (operands[0])"
5328 [(set (match_dup 2) (match_dup 1))
5329 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5333 [(set (match_operand:X87MODEF 0 "register_operand" "")
5334 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5335 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5338 && FP_REG_P (operands[0])"
5339 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5342 ;; Avoid store forwarding (partial memory) stall penalty
5343 ;; by passing DImode value through XMM registers. */
5345 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5346 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5348 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5349 (clobber (match_scratch:V4SI 3 "=X,x"))
5350 (clobber (match_scratch:V4SI 4 "=X,x"))
5351 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5352 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5353 && !TARGET_64BIT && !optimize_size"
5355 [(set_attr "type" "multi")
5356 (set_attr "mode" "<X87MODEF:MODE>")
5357 (set_attr "unit" "i387")
5358 (set_attr "fp_int_src" "true")])
5361 [(set (match_operand:X87MODEF 0 "register_operand" "")
5362 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5363 (clobber (match_scratch:V4SI 3 ""))
5364 (clobber (match_scratch:V4SI 4 ""))
5365 (clobber (match_operand:DI 2 "memory_operand" ""))]
5366 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5367 && !TARGET_64BIT && !optimize_size
5369 && FP_REG_P (operands[0])"
5370 [(set (match_dup 2) (match_dup 3))
5371 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5373 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5374 Assemble the 64-bit DImode value in an xmm register. */
5375 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5376 gen_rtx_SUBREG (SImode, operands[1], 0)));
5377 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5378 gen_rtx_SUBREG (SImode, operands[1], 4)));
5379 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5381 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5385 [(set (match_operand:X87MODEF 0 "register_operand" "")
5386 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5387 (clobber (match_scratch:V4SI 3 ""))
5388 (clobber (match_scratch:V4SI 4 ""))
5389 (clobber (match_operand:DI 2 "memory_operand" ""))]
5390 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5391 && !TARGET_64BIT && !optimize_size
5393 && FP_REG_P (operands[0])"
5394 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5397 ;; Avoid store forwarding (partial memory) stall penalty by extending
5398 ;; SImode value to DImode through XMM register instead of pushing two
5399 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5400 ;; targets benefit from this optimization. Also note that fild
5401 ;; loads from memory only.
5403 (define_insn "*floatunssi<mode>2_1"
5404 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5405 (unsigned_float:X87MODEF
5406 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5407 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5408 (clobber (match_scratch:SI 3 "=X,x"))]
5410 && TARGET_80387 && TARGET_SSE"
5412 [(set_attr "type" "multi")
5413 (set_attr "mode" "<MODE>")])
5416 [(set (match_operand:X87MODEF 0 "register_operand" "")
5417 (unsigned_float:X87MODEF
5418 (match_operand:SI 1 "register_operand" "")))
5419 (clobber (match_operand:DI 2 "memory_operand" ""))
5420 (clobber (match_scratch:SI 3 ""))]
5422 && TARGET_80387 && TARGET_SSE
5423 && reload_completed"
5424 [(set (match_dup 2) (match_dup 1))
5426 (float:X87MODEF (match_dup 2)))]
5427 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5430 [(set (match_operand:X87MODEF 0 "register_operand" "")
5431 (unsigned_float:X87MODEF
5432 (match_operand:SI 1 "memory_operand" "")))
5433 (clobber (match_operand:DI 2 "memory_operand" ""))
5434 (clobber (match_scratch:SI 3 ""))]
5436 && TARGET_80387 && TARGET_SSE
5437 && reload_completed"
5438 [(set (match_dup 2) (match_dup 3))
5440 (float:X87MODEF (match_dup 2)))]
5442 emit_move_insn (operands[3], operands[1]);
5443 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5446 (define_expand "floatunssi<mode>2"
5448 [(set (match_operand:X87MODEF 0 "register_operand" "")
5449 (unsigned_float:X87MODEF
5450 (match_operand:SI 1 "nonimmediate_operand" "")))
5451 (clobber (match_dup 2))
5452 (clobber (match_scratch:SI 3 ""))])]
5454 && ((TARGET_80387 && TARGET_SSE)
5455 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5457 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5459 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5464 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5465 operands[2] = assign_386_stack_local (DImode, slot);
5469 (define_expand "floatunsdisf2"
5470 [(use (match_operand:SF 0 "register_operand" ""))
5471 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5472 "TARGET_64BIT && TARGET_SSE_MATH"
5473 "x86_emit_floatuns (operands); DONE;")
5475 (define_expand "floatunsdidf2"
5476 [(use (match_operand:DF 0 "register_operand" ""))
5477 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5478 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5479 && TARGET_SSE2 && TARGET_SSE_MATH"
5482 x86_emit_floatuns (operands);
5484 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5490 ;; %%% splits for addditi3
5492 (define_expand "addti3"
5493 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5494 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5495 (match_operand:TI 2 "x86_64_general_operand" "")))]
5497 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5499 (define_insn "*addti3_1"
5500 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5501 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5502 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5503 (clobber (reg:CC FLAGS_REG))]
5504 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5508 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5509 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5510 (match_operand:TI 2 "x86_64_general_operand" "")))
5511 (clobber (reg:CC FLAGS_REG))]
5512 "TARGET_64BIT && reload_completed"
5513 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5515 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5516 (parallel [(set (match_dup 3)
5517 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5520 (clobber (reg:CC FLAGS_REG))])]
5521 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5523 ;; %%% splits for addsidi3
5524 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5525 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5526 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5528 (define_expand "adddi3"
5529 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5530 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5531 (match_operand:DI 2 "x86_64_general_operand" "")))]
5533 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5535 (define_insn "*adddi3_1"
5536 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5537 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5538 (match_operand:DI 2 "general_operand" "roiF,riF")))
5539 (clobber (reg:CC FLAGS_REG))]
5540 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5544 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5545 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5546 (match_operand:DI 2 "general_operand" "")))
5547 (clobber (reg:CC FLAGS_REG))]
5548 "!TARGET_64BIT && reload_completed"
5549 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5551 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5552 (parallel [(set (match_dup 3)
5553 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5556 (clobber (reg:CC FLAGS_REG))])]
5557 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5559 (define_insn "adddi3_carry_rex64"
5560 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5561 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5562 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5563 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5564 (clobber (reg:CC FLAGS_REG))]
5565 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5566 "adc{q}\t{%2, %0|%0, %2}"
5567 [(set_attr "type" "alu")
5568 (set_attr "pent_pair" "pu")
5569 (set_attr "mode" "DI")])
5571 (define_insn "*adddi3_cc_rex64"
5572 [(set (reg:CC FLAGS_REG)
5573 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5574 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5576 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5577 (plus:DI (match_dup 1) (match_dup 2)))]
5578 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5579 "add{q}\t{%2, %0|%0, %2}"
5580 [(set_attr "type" "alu")
5581 (set_attr "mode" "DI")])
5583 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5584 [(set (reg:CCC FLAGS_REG)
5587 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5588 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5590 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5591 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5592 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5593 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5594 [(set_attr "type" "alu")
5595 (set_attr "mode" "<MODE>")])
5597 (define_insn "*add<mode>3_cconly_overflow"
5598 [(set (reg:CCC FLAGS_REG)
5600 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5601 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5603 (clobber (match_scratch:SWI 0 "=<r>"))]
5604 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5605 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5606 [(set_attr "type" "alu")
5607 (set_attr "mode" "<MODE>")])
5609 (define_insn "*sub<mode>3_cconly_overflow"
5610 [(set (reg:CCC FLAGS_REG)
5612 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5613 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5616 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5617 [(set_attr "type" "icmp")
5618 (set_attr "mode" "<MODE>")])
5620 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5621 [(set (reg:CCC FLAGS_REG)
5623 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5624 (match_operand:SI 2 "general_operand" "g"))
5626 (set (match_operand:DI 0 "register_operand" "=r")
5627 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5628 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5629 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5630 [(set_attr "type" "alu")
5631 (set_attr "mode" "SI")])
5633 (define_insn "addqi3_carry"
5634 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5635 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5636 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5637 (match_operand:QI 2 "general_operand" "qn,qm")))
5638 (clobber (reg:CC FLAGS_REG))]
5639 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5640 "adc{b}\t{%2, %0|%0, %2}"
5641 [(set_attr "type" "alu")
5642 (set_attr "pent_pair" "pu")
5643 (set_attr "mode" "QI")])
5645 (define_insn "addhi3_carry"
5646 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5647 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5648 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5649 (match_operand:HI 2 "general_operand" "rn,rm")))
5650 (clobber (reg:CC FLAGS_REG))]
5651 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5652 "adc{w}\t{%2, %0|%0, %2}"
5653 [(set_attr "type" "alu")
5654 (set_attr "pent_pair" "pu")
5655 (set_attr "mode" "HI")])
5657 (define_insn "addsi3_carry"
5658 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5659 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5660 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5661 (match_operand:SI 2 "general_operand" "ri,rm")))
5662 (clobber (reg:CC FLAGS_REG))]
5663 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5664 "adc{l}\t{%2, %0|%0, %2}"
5665 [(set_attr "type" "alu")
5666 (set_attr "pent_pair" "pu")
5667 (set_attr "mode" "SI")])
5669 (define_insn "*addsi3_carry_zext"
5670 [(set (match_operand:DI 0 "register_operand" "=r")
5672 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5673 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5674 (match_operand:SI 2 "general_operand" "g"))))
5675 (clobber (reg:CC FLAGS_REG))]
5676 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5677 "adc{l}\t{%2, %k0|%k0, %2}"
5678 [(set_attr "type" "alu")
5679 (set_attr "pent_pair" "pu")
5680 (set_attr "mode" "SI")])
5682 (define_insn "*addsi3_cc"
5683 [(set (reg:CC FLAGS_REG)
5684 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5685 (match_operand:SI 2 "general_operand" "ri,rm")]
5687 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5688 (plus:SI (match_dup 1) (match_dup 2)))]
5689 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5690 "add{l}\t{%2, %0|%0, %2}"
5691 [(set_attr "type" "alu")
5692 (set_attr "mode" "SI")])
5694 (define_insn "addqi3_cc"
5695 [(set (reg:CC FLAGS_REG)
5696 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5697 (match_operand:QI 2 "general_operand" "qn,qm")]
5699 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5700 (plus:QI (match_dup 1) (match_dup 2)))]
5701 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5702 "add{b}\t{%2, %0|%0, %2}"
5703 [(set_attr "type" "alu")
5704 (set_attr "mode" "QI")])
5706 (define_expand "addsi3"
5707 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5708 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5709 (match_operand:SI 2 "general_operand" "")))]
5711 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5713 (define_insn "*lea_1"
5714 [(set (match_operand:SI 0 "register_operand" "=r")
5715 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5717 "lea{l}\t{%a1, %0|%0, %a1}"
5718 [(set_attr "type" "lea")
5719 (set_attr "mode" "SI")])
5721 (define_insn "*lea_1_rex64"
5722 [(set (match_operand:SI 0 "register_operand" "=r")
5723 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5725 "lea{l}\t{%a1, %0|%0, %a1}"
5726 [(set_attr "type" "lea")
5727 (set_attr "mode" "SI")])
5729 (define_insn "*lea_1_zext"
5730 [(set (match_operand:DI 0 "register_operand" "=r")
5732 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5734 "lea{l}\t{%a1, %k0|%k0, %a1}"
5735 [(set_attr "type" "lea")
5736 (set_attr "mode" "SI")])
5738 (define_insn "*lea_2_rex64"
5739 [(set (match_operand:DI 0 "register_operand" "=r")
5740 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5742 "lea{q}\t{%a1, %0|%0, %a1}"
5743 [(set_attr "type" "lea")
5744 (set_attr "mode" "DI")])
5746 ;; The lea patterns for non-Pmodes needs to be matched by several
5747 ;; insns converted to real lea by splitters.
5749 (define_insn_and_split "*lea_general_1"
5750 [(set (match_operand 0 "register_operand" "=r")
5751 (plus (plus (match_operand 1 "index_register_operand" "l")
5752 (match_operand 2 "register_operand" "r"))
5753 (match_operand 3 "immediate_operand" "i")))]
5754 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5755 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5756 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5757 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5758 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5759 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5760 || GET_MODE (operands[3]) == VOIDmode)"
5762 "&& reload_completed"
5766 operands[0] = gen_lowpart (SImode, operands[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]);
5770 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5772 if (Pmode != SImode)
5773 pat = gen_rtx_SUBREG (SImode, pat, 0);
5774 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5777 [(set_attr "type" "lea")
5778 (set_attr "mode" "SI")])
5780 (define_insn_and_split "*lea_general_1_zext"
5781 [(set (match_operand:DI 0 "register_operand" "=r")
5783 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5784 (match_operand:SI 2 "register_operand" "r"))
5785 (match_operand:SI 3 "immediate_operand" "i"))))]
5788 "&& reload_completed"
5790 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5792 (match_dup 3)) 0)))]
5794 operands[1] = gen_lowpart (Pmode, operands[1]);
5795 operands[2] = gen_lowpart (Pmode, operands[2]);
5796 operands[3] = gen_lowpart (Pmode, operands[3]);
5798 [(set_attr "type" "lea")
5799 (set_attr "mode" "SI")])
5801 (define_insn_and_split "*lea_general_2"
5802 [(set (match_operand 0 "register_operand" "=r")
5803 (plus (mult (match_operand 1 "index_register_operand" "l")
5804 (match_operand 2 "const248_operand" "i"))
5805 (match_operand 3 "nonmemory_operand" "ri")))]
5806 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5807 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5808 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5809 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5810 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5811 || GET_MODE (operands[3]) == VOIDmode)"
5813 "&& reload_completed"
5817 operands[0] = gen_lowpart (SImode, operands[0]);
5818 operands[1] = gen_lowpart (Pmode, operands[1]);
5819 operands[3] = gen_lowpart (Pmode, operands[3]);
5820 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5822 if (Pmode != SImode)
5823 pat = gen_rtx_SUBREG (SImode, pat, 0);
5824 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5827 [(set_attr "type" "lea")
5828 (set_attr "mode" "SI")])
5830 (define_insn_and_split "*lea_general_2_zext"
5831 [(set (match_operand:DI 0 "register_operand" "=r")
5833 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5834 (match_operand:SI 2 "const248_operand" "n"))
5835 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5838 "&& reload_completed"
5840 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5842 (match_dup 3)) 0)))]
5844 operands[1] = gen_lowpart (Pmode, operands[1]);
5845 operands[3] = gen_lowpart (Pmode, operands[3]);
5847 [(set_attr "type" "lea")
5848 (set_attr "mode" "SI")])
5850 (define_insn_and_split "*lea_general_3"
5851 [(set (match_operand 0 "register_operand" "=r")
5852 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5853 (match_operand 2 "const248_operand" "i"))
5854 (match_operand 3 "register_operand" "r"))
5855 (match_operand 4 "immediate_operand" "i")))]
5856 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5857 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5858 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5859 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5860 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5862 "&& reload_completed"
5866 operands[0] = gen_lowpart (SImode, operands[0]);
5867 operands[1] = gen_lowpart (Pmode, operands[1]);
5868 operands[3] = gen_lowpart (Pmode, operands[3]);
5869 operands[4] = gen_lowpart (Pmode, operands[4]);
5870 pat = gen_rtx_PLUS (Pmode,
5871 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5875 if (Pmode != SImode)
5876 pat = gen_rtx_SUBREG (SImode, pat, 0);
5877 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5880 [(set_attr "type" "lea")
5881 (set_attr "mode" "SI")])
5883 (define_insn_and_split "*lea_general_3_zext"
5884 [(set (match_operand:DI 0 "register_operand" "=r")
5886 (plus:SI (plus:SI (mult:SI
5887 (match_operand:SI 1 "index_register_operand" "l")
5888 (match_operand:SI 2 "const248_operand" "n"))
5889 (match_operand:SI 3 "register_operand" "r"))
5890 (match_operand:SI 4 "immediate_operand" "i"))))]
5893 "&& reload_completed"
5895 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5898 (match_dup 4)) 0)))]
5900 operands[1] = gen_lowpart (Pmode, operands[1]);
5901 operands[3] = gen_lowpart (Pmode, operands[3]);
5902 operands[4] = gen_lowpart (Pmode, operands[4]);
5904 [(set_attr "type" "lea")
5905 (set_attr "mode" "SI")])
5907 (define_insn "*adddi_1_rex64"
5908 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5909 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5910 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5911 (clobber (reg:CC FLAGS_REG))]
5912 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5914 switch (get_attr_type (insn))
5917 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5918 return "lea{q}\t{%a2, %0|%0, %a2}";
5921 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5922 if (operands[2] == const1_rtx)
5923 return "inc{q}\t%0";
5926 gcc_assert (operands[2] == constm1_rtx);
5927 return "dec{q}\t%0";
5931 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5933 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5934 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5935 if (CONST_INT_P (operands[2])
5936 /* Avoid overflows. */
5937 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5938 && (INTVAL (operands[2]) == 128
5939 || (INTVAL (operands[2]) < 0
5940 && INTVAL (operands[2]) != -128)))
5942 operands[2] = GEN_INT (-INTVAL (operands[2]));
5943 return "sub{q}\t{%2, %0|%0, %2}";
5945 return "add{q}\t{%2, %0|%0, %2}";
5949 (cond [(eq_attr "alternative" "2")
5950 (const_string "lea")
5951 ; Current assemblers are broken and do not allow @GOTOFF in
5952 ; ought but a memory context.
5953 (match_operand:DI 2 "pic_symbolic_operand" "")
5954 (const_string "lea")
5955 (match_operand:DI 2 "incdec_operand" "")
5956 (const_string "incdec")
5958 (const_string "alu")))
5959 (set_attr "mode" "DI")])
5961 ;; Convert lea to the lea pattern to avoid flags dependency.
5963 [(set (match_operand:DI 0 "register_operand" "")
5964 (plus:DI (match_operand:DI 1 "register_operand" "")
5965 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5966 (clobber (reg:CC FLAGS_REG))]
5967 "TARGET_64BIT && reload_completed
5968 && true_regnum (operands[0]) != true_regnum (operands[1])"
5970 (plus:DI (match_dup 1)
5974 (define_insn "*adddi_2_rex64"
5975 [(set (reg FLAGS_REG)
5977 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5978 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5980 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5981 (plus:DI (match_dup 1) (match_dup 2)))]
5982 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5983 && ix86_binary_operator_ok (PLUS, DImode, operands)
5984 /* Current assemblers are broken and do not allow @GOTOFF in
5985 ought but a memory context. */
5986 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5988 switch (get_attr_type (insn))
5991 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5992 if (operands[2] == const1_rtx)
5993 return "inc{q}\t%0";
5996 gcc_assert (operands[2] == constm1_rtx);
5997 return "dec{q}\t%0";
6001 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6002 /* ???? We ought to handle there the 32bit case too
6003 - do we need new constraint? */
6004 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6005 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6006 if (CONST_INT_P (operands[2])
6007 /* Avoid overflows. */
6008 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6009 && (INTVAL (operands[2]) == 128
6010 || (INTVAL (operands[2]) < 0
6011 && INTVAL (operands[2]) != -128)))
6013 operands[2] = GEN_INT (-INTVAL (operands[2]));
6014 return "sub{q}\t{%2, %0|%0, %2}";
6016 return "add{q}\t{%2, %0|%0, %2}";
6020 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6021 (const_string "incdec")
6022 (const_string "alu")))
6023 (set_attr "mode" "DI")])
6025 (define_insn "*adddi_3_rex64"
6026 [(set (reg FLAGS_REG)
6027 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6028 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6029 (clobber (match_scratch:DI 0 "=r"))]
6031 && ix86_match_ccmode (insn, CCZmode)
6032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6033 /* Current assemblers are broken and do not allow @GOTOFF in
6034 ought but a memory context. */
6035 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6037 switch (get_attr_type (insn))
6040 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6041 if (operands[2] == const1_rtx)
6042 return "inc{q}\t%0";
6045 gcc_assert (operands[2] == constm1_rtx);
6046 return "dec{q}\t%0";
6050 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6051 /* ???? We ought to handle there the 32bit case too
6052 - do we need new constraint? */
6053 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6055 if (CONST_INT_P (operands[2])
6056 /* Avoid overflows. */
6057 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6058 && (INTVAL (operands[2]) == 128
6059 || (INTVAL (operands[2]) < 0
6060 && INTVAL (operands[2]) != -128)))
6062 operands[2] = GEN_INT (-INTVAL (operands[2]));
6063 return "sub{q}\t{%2, %0|%0, %2}";
6065 return "add{q}\t{%2, %0|%0, %2}";
6069 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6070 (const_string "incdec")
6071 (const_string "alu")))
6072 (set_attr "mode" "DI")])
6074 ; For comparisons against 1, -1 and 128, we may generate better code
6075 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6076 ; is matched then. We can't accept general immediate, because for
6077 ; case of overflows, the result is messed up.
6078 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6080 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6081 ; only for comparisons not depending on it.
6082 (define_insn "*adddi_4_rex64"
6083 [(set (reg FLAGS_REG)
6084 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6085 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6086 (clobber (match_scratch:DI 0 "=rm"))]
6088 && ix86_match_ccmode (insn, CCGCmode)"
6090 switch (get_attr_type (insn))
6093 if (operands[2] == constm1_rtx)
6094 return "inc{q}\t%0";
6097 gcc_assert (operands[2] == const1_rtx);
6098 return "dec{q}\t%0";
6102 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6103 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6104 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6105 if ((INTVAL (operands[2]) == -128
6106 || (INTVAL (operands[2]) > 0
6107 && INTVAL (operands[2]) != 128))
6108 /* Avoid overflows. */
6109 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6110 return "sub{q}\t{%2, %0|%0, %2}";
6111 operands[2] = GEN_INT (-INTVAL (operands[2]));
6112 return "add{q}\t{%2, %0|%0, %2}";
6116 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6117 (const_string "incdec")
6118 (const_string "alu")))
6119 (set_attr "mode" "DI")])
6121 (define_insn "*adddi_5_rex64"
6122 [(set (reg FLAGS_REG)
6124 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6125 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6127 (clobber (match_scratch:DI 0 "=r"))]
6129 && ix86_match_ccmode (insn, CCGOCmode)
6130 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6131 /* Current assemblers are broken and do not allow @GOTOFF in
6132 ought but a memory context. */
6133 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6135 switch (get_attr_type (insn))
6138 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6139 if (operands[2] == const1_rtx)
6140 return "inc{q}\t%0";
6143 gcc_assert (operands[2] == constm1_rtx);
6144 return "dec{q}\t%0";
6148 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6149 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6150 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6151 if (CONST_INT_P (operands[2])
6152 /* Avoid overflows. */
6153 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6154 && (INTVAL (operands[2]) == 128
6155 || (INTVAL (operands[2]) < 0
6156 && INTVAL (operands[2]) != -128)))
6158 operands[2] = GEN_INT (-INTVAL (operands[2]));
6159 return "sub{q}\t{%2, %0|%0, %2}";
6161 return "add{q}\t{%2, %0|%0, %2}";
6165 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6166 (const_string "incdec")
6167 (const_string "alu")))
6168 (set_attr "mode" "DI")])
6171 (define_insn "*addsi_1"
6172 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6173 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6174 (match_operand:SI 2 "general_operand" "g,ri,li")))
6175 (clobber (reg:CC FLAGS_REG))]
6176 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6178 switch (get_attr_type (insn))
6181 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6182 return "lea{l}\t{%a2, %0|%0, %a2}";
6185 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6186 if (operands[2] == const1_rtx)
6187 return "inc{l}\t%0";
6190 gcc_assert (operands[2] == constm1_rtx);
6191 return "dec{l}\t%0";
6195 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6197 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6198 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6199 if (CONST_INT_P (operands[2])
6200 && (INTVAL (operands[2]) == 128
6201 || (INTVAL (operands[2]) < 0
6202 && INTVAL (operands[2]) != -128)))
6204 operands[2] = GEN_INT (-INTVAL (operands[2]));
6205 return "sub{l}\t{%2, %0|%0, %2}";
6207 return "add{l}\t{%2, %0|%0, %2}";
6211 (cond [(eq_attr "alternative" "2")
6212 (const_string "lea")
6213 ; Current assemblers are broken and do not allow @GOTOFF in
6214 ; ought but a memory context.
6215 (match_operand:SI 2 "pic_symbolic_operand" "")
6216 (const_string "lea")
6217 (match_operand:SI 2 "incdec_operand" "")
6218 (const_string "incdec")
6220 (const_string "alu")))
6221 (set_attr "mode" "SI")])
6223 ;; Convert lea to the lea pattern to avoid flags dependency.
6225 [(set (match_operand 0 "register_operand" "")
6226 (plus (match_operand 1 "register_operand" "")
6227 (match_operand 2 "nonmemory_operand" "")))
6228 (clobber (reg:CC FLAGS_REG))]
6230 && true_regnum (operands[0]) != true_regnum (operands[1])"
6234 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6235 may confuse gen_lowpart. */
6236 if (GET_MODE (operands[0]) != Pmode)
6238 operands[1] = gen_lowpart (Pmode, operands[1]);
6239 operands[2] = gen_lowpart (Pmode, operands[2]);
6241 operands[0] = gen_lowpart (SImode, operands[0]);
6242 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6243 if (Pmode != SImode)
6244 pat = gen_rtx_SUBREG (SImode, pat, 0);
6245 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6249 ;; It may seem that nonimmediate operand is proper one for operand 1.
6250 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6251 ;; we take care in ix86_binary_operator_ok to not allow two memory
6252 ;; operands so proper swapping will be done in reload. This allow
6253 ;; patterns constructed from addsi_1 to match.
6254 (define_insn "addsi_1_zext"
6255 [(set (match_operand:DI 0 "register_operand" "=r,r")
6257 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6258 (match_operand:SI 2 "general_operand" "g,li"))))
6259 (clobber (reg:CC FLAGS_REG))]
6260 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6262 switch (get_attr_type (insn))
6265 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6266 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6269 if (operands[2] == const1_rtx)
6270 return "inc{l}\t%k0";
6273 gcc_assert (operands[2] == constm1_rtx);
6274 return "dec{l}\t%k0";
6278 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6279 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6280 if (CONST_INT_P (operands[2])
6281 && (INTVAL (operands[2]) == 128
6282 || (INTVAL (operands[2]) < 0
6283 && INTVAL (operands[2]) != -128)))
6285 operands[2] = GEN_INT (-INTVAL (operands[2]));
6286 return "sub{l}\t{%2, %k0|%k0, %2}";
6288 return "add{l}\t{%2, %k0|%k0, %2}";
6292 (cond [(eq_attr "alternative" "1")
6293 (const_string "lea")
6294 ; Current assemblers are broken and do not allow @GOTOFF in
6295 ; ought but a memory context.
6296 (match_operand:SI 2 "pic_symbolic_operand" "")
6297 (const_string "lea")
6298 (match_operand:SI 2 "incdec_operand" "")
6299 (const_string "incdec")
6301 (const_string "alu")))
6302 (set_attr "mode" "SI")])
6304 ;; Convert lea to the lea pattern to avoid flags dependency.
6306 [(set (match_operand:DI 0 "register_operand" "")
6308 (plus:SI (match_operand:SI 1 "register_operand" "")
6309 (match_operand:SI 2 "nonmemory_operand" ""))))
6310 (clobber (reg:CC FLAGS_REG))]
6311 "TARGET_64BIT && reload_completed
6312 && true_regnum (operands[0]) != true_regnum (operands[1])"
6314 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6316 operands[1] = gen_lowpart (Pmode, operands[1]);
6317 operands[2] = gen_lowpart (Pmode, operands[2]);
6320 (define_insn "*addsi_2"
6321 [(set (reg FLAGS_REG)
6323 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6324 (match_operand:SI 2 "general_operand" "g,ri"))
6326 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6327 (plus:SI (match_dup 1) (match_dup 2)))]
6328 "ix86_match_ccmode (insn, CCGOCmode)
6329 && ix86_binary_operator_ok (PLUS, SImode, operands)
6330 /* Current assemblers are broken and do not allow @GOTOFF in
6331 ought but a memory context. */
6332 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6334 switch (get_attr_type (insn))
6337 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6338 if (operands[2] == const1_rtx)
6339 return "inc{l}\t%0";
6342 gcc_assert (operands[2] == constm1_rtx);
6343 return "dec{l}\t%0";
6347 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6348 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6349 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6350 if (CONST_INT_P (operands[2])
6351 && (INTVAL (operands[2]) == 128
6352 || (INTVAL (operands[2]) < 0
6353 && INTVAL (operands[2]) != -128)))
6355 operands[2] = GEN_INT (-INTVAL (operands[2]));
6356 return "sub{l}\t{%2, %0|%0, %2}";
6358 return "add{l}\t{%2, %0|%0, %2}";
6362 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6363 (const_string "incdec")
6364 (const_string "alu")))
6365 (set_attr "mode" "SI")])
6367 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6368 (define_insn "*addsi_2_zext"
6369 [(set (reg FLAGS_REG)
6371 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6372 (match_operand:SI 2 "general_operand" "g"))
6374 (set (match_operand:DI 0 "register_operand" "=r")
6375 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6376 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6377 && ix86_binary_operator_ok (PLUS, SImode, operands)
6378 /* Current assemblers are broken and do not allow @GOTOFF in
6379 ought but a memory context. */
6380 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6382 switch (get_attr_type (insn))
6385 if (operands[2] == const1_rtx)
6386 return "inc{l}\t%k0";
6389 gcc_assert (operands[2] == constm1_rtx);
6390 return "dec{l}\t%k0";
6394 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6395 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6396 if (CONST_INT_P (operands[2])
6397 && (INTVAL (operands[2]) == 128
6398 || (INTVAL (operands[2]) < 0
6399 && INTVAL (operands[2]) != -128)))
6401 operands[2] = GEN_INT (-INTVAL (operands[2]));
6402 return "sub{l}\t{%2, %k0|%k0, %2}";
6404 return "add{l}\t{%2, %k0|%k0, %2}";
6408 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6409 (const_string "incdec")
6410 (const_string "alu")))
6411 (set_attr "mode" "SI")])
6413 (define_insn "*addsi_3"
6414 [(set (reg FLAGS_REG)
6415 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6416 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6417 (clobber (match_scratch:SI 0 "=r"))]
6418 "ix86_match_ccmode (insn, CCZmode)
6419 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6420 /* Current assemblers are broken and do not allow @GOTOFF in
6421 ought but a memory context. */
6422 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6424 switch (get_attr_type (insn))
6427 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6428 if (operands[2] == const1_rtx)
6429 return "inc{l}\t%0";
6432 gcc_assert (operands[2] == constm1_rtx);
6433 return "dec{l}\t%0";
6437 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6438 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6439 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6440 if (CONST_INT_P (operands[2])
6441 && (INTVAL (operands[2]) == 128
6442 || (INTVAL (operands[2]) < 0
6443 && INTVAL (operands[2]) != -128)))
6445 operands[2] = GEN_INT (-INTVAL (operands[2]));
6446 return "sub{l}\t{%2, %0|%0, %2}";
6448 return "add{l}\t{%2, %0|%0, %2}";
6452 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6453 (const_string "incdec")
6454 (const_string "alu")))
6455 (set_attr "mode" "SI")])
6457 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6458 (define_insn "*addsi_3_zext"
6459 [(set (reg FLAGS_REG)
6460 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6461 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6462 (set (match_operand:DI 0 "register_operand" "=r")
6463 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6464 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6465 && ix86_binary_operator_ok (PLUS, SImode, operands)
6466 /* Current assemblers are broken and do not allow @GOTOFF in
6467 ought but a memory context. */
6468 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6470 switch (get_attr_type (insn))
6473 if (operands[2] == const1_rtx)
6474 return "inc{l}\t%k0";
6477 gcc_assert (operands[2] == constm1_rtx);
6478 return "dec{l}\t%k0";
6482 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6483 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6484 if (CONST_INT_P (operands[2])
6485 && (INTVAL (operands[2]) == 128
6486 || (INTVAL (operands[2]) < 0
6487 && INTVAL (operands[2]) != -128)))
6489 operands[2] = GEN_INT (-INTVAL (operands[2]));
6490 return "sub{l}\t{%2, %k0|%k0, %2}";
6492 return "add{l}\t{%2, %k0|%k0, %2}";
6496 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6497 (const_string "incdec")
6498 (const_string "alu")))
6499 (set_attr "mode" "SI")])
6501 ; For comparisons against 1, -1 and 128, we may generate better code
6502 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6503 ; is matched then. We can't accept general immediate, because for
6504 ; case of overflows, the result is messed up.
6505 ; This pattern also don't hold of 0x80000000, since the value overflows
6507 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6508 ; only for comparisons not depending on it.
6509 (define_insn "*addsi_4"
6510 [(set (reg FLAGS_REG)
6511 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6512 (match_operand:SI 2 "const_int_operand" "n")))
6513 (clobber (match_scratch:SI 0 "=rm"))]
6514 "ix86_match_ccmode (insn, CCGCmode)
6515 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6517 switch (get_attr_type (insn))
6520 if (operands[2] == constm1_rtx)
6521 return "inc{l}\t%0";
6524 gcc_assert (operands[2] == const1_rtx);
6525 return "dec{l}\t%0";
6529 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6530 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6531 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6532 if ((INTVAL (operands[2]) == -128
6533 || (INTVAL (operands[2]) > 0
6534 && INTVAL (operands[2]) != 128)))
6535 return "sub{l}\t{%2, %0|%0, %2}";
6536 operands[2] = GEN_INT (-INTVAL (operands[2]));
6537 return "add{l}\t{%2, %0|%0, %2}";
6541 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6542 (const_string "incdec")
6543 (const_string "alu")))
6544 (set_attr "mode" "SI")])
6546 (define_insn "*addsi_5"
6547 [(set (reg FLAGS_REG)
6549 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6550 (match_operand:SI 2 "general_operand" "g"))
6552 (clobber (match_scratch:SI 0 "=r"))]
6553 "ix86_match_ccmode (insn, CCGOCmode)
6554 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6555 /* Current assemblers are broken and do not allow @GOTOFF in
6556 ought but a memory context. */
6557 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6559 switch (get_attr_type (insn))
6562 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6563 if (operands[2] == const1_rtx)
6564 return "inc{l}\t%0";
6567 gcc_assert (operands[2] == constm1_rtx);
6568 return "dec{l}\t%0";
6572 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6573 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6574 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6575 if (CONST_INT_P (operands[2])
6576 && (INTVAL (operands[2]) == 128
6577 || (INTVAL (operands[2]) < 0
6578 && INTVAL (operands[2]) != -128)))
6580 operands[2] = GEN_INT (-INTVAL (operands[2]));
6581 return "sub{l}\t{%2, %0|%0, %2}";
6583 return "add{l}\t{%2, %0|%0, %2}";
6587 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6588 (const_string "incdec")
6589 (const_string "alu")))
6590 (set_attr "mode" "SI")])
6592 (define_expand "addhi3"
6593 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6594 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6595 (match_operand:HI 2 "general_operand" "")))]
6596 "TARGET_HIMODE_MATH"
6597 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6599 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6600 ;; type optimizations enabled by define-splits. This is not important
6601 ;; for PII, and in fact harmful because of partial register stalls.
6603 (define_insn "*addhi_1_lea"
6604 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6605 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6606 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6607 (clobber (reg:CC FLAGS_REG))]
6608 "!TARGET_PARTIAL_REG_STALL
6609 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6611 switch (get_attr_type (insn))
6616 if (operands[2] == const1_rtx)
6617 return "inc{w}\t%0";
6620 gcc_assert (operands[2] == constm1_rtx);
6621 return "dec{w}\t%0";
6625 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6626 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6627 if (CONST_INT_P (operands[2])
6628 && (INTVAL (operands[2]) == 128
6629 || (INTVAL (operands[2]) < 0
6630 && INTVAL (operands[2]) != -128)))
6632 operands[2] = GEN_INT (-INTVAL (operands[2]));
6633 return "sub{w}\t{%2, %0|%0, %2}";
6635 return "add{w}\t{%2, %0|%0, %2}";
6639 (if_then_else (eq_attr "alternative" "2")
6640 (const_string "lea")
6641 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6642 (const_string "incdec")
6643 (const_string "alu"))))
6644 (set_attr "mode" "HI,HI,SI")])
6646 (define_insn "*addhi_1"
6647 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6648 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6649 (match_operand:HI 2 "general_operand" "rn,rm")))
6650 (clobber (reg:CC FLAGS_REG))]
6651 "TARGET_PARTIAL_REG_STALL
6652 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6654 switch (get_attr_type (insn))
6657 if (operands[2] == const1_rtx)
6658 return "inc{w}\t%0";
6661 gcc_assert (operands[2] == constm1_rtx);
6662 return "dec{w}\t%0";
6666 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6667 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6668 if (CONST_INT_P (operands[2])
6669 && (INTVAL (operands[2]) == 128
6670 || (INTVAL (operands[2]) < 0
6671 && INTVAL (operands[2]) != -128)))
6673 operands[2] = GEN_INT (-INTVAL (operands[2]));
6674 return "sub{w}\t{%2, %0|%0, %2}";
6676 return "add{w}\t{%2, %0|%0, %2}";
6680 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6681 (const_string "incdec")
6682 (const_string "alu")))
6683 (set_attr "mode" "HI")])
6685 (define_insn "*addhi_2"
6686 [(set (reg FLAGS_REG)
6688 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6689 (match_operand:HI 2 "general_operand" "rmn,rn"))
6691 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6692 (plus:HI (match_dup 1) (match_dup 2)))]
6693 "ix86_match_ccmode (insn, CCGOCmode)
6694 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6696 switch (get_attr_type (insn))
6699 if (operands[2] == const1_rtx)
6700 return "inc{w}\t%0";
6703 gcc_assert (operands[2] == constm1_rtx);
6704 return "dec{w}\t%0";
6708 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6709 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6710 if (CONST_INT_P (operands[2])
6711 && (INTVAL (operands[2]) == 128
6712 || (INTVAL (operands[2]) < 0
6713 && INTVAL (operands[2]) != -128)))
6715 operands[2] = GEN_INT (-INTVAL (operands[2]));
6716 return "sub{w}\t{%2, %0|%0, %2}";
6718 return "add{w}\t{%2, %0|%0, %2}";
6722 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6723 (const_string "incdec")
6724 (const_string "alu")))
6725 (set_attr "mode" "HI")])
6727 (define_insn "*addhi_3"
6728 [(set (reg FLAGS_REG)
6729 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6730 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6731 (clobber (match_scratch:HI 0 "=r"))]
6732 "ix86_match_ccmode (insn, CCZmode)
6733 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6735 switch (get_attr_type (insn))
6738 if (operands[2] == const1_rtx)
6739 return "inc{w}\t%0";
6742 gcc_assert (operands[2] == constm1_rtx);
6743 return "dec{w}\t%0";
6747 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6748 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6749 if (CONST_INT_P (operands[2])
6750 && (INTVAL (operands[2]) == 128
6751 || (INTVAL (operands[2]) < 0
6752 && INTVAL (operands[2]) != -128)))
6754 operands[2] = GEN_INT (-INTVAL (operands[2]));
6755 return "sub{w}\t{%2, %0|%0, %2}";
6757 return "add{w}\t{%2, %0|%0, %2}";
6761 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6762 (const_string "incdec")
6763 (const_string "alu")))
6764 (set_attr "mode" "HI")])
6766 ; See comments above addsi_4 for details.
6767 (define_insn "*addhi_4"
6768 [(set (reg FLAGS_REG)
6769 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6770 (match_operand:HI 2 "const_int_operand" "n")))
6771 (clobber (match_scratch:HI 0 "=rm"))]
6772 "ix86_match_ccmode (insn, CCGCmode)
6773 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6775 switch (get_attr_type (insn))
6778 if (operands[2] == constm1_rtx)
6779 return "inc{w}\t%0";
6782 gcc_assert (operands[2] == const1_rtx);
6783 return "dec{w}\t%0";
6787 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6788 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6789 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6790 if ((INTVAL (operands[2]) == -128
6791 || (INTVAL (operands[2]) > 0
6792 && INTVAL (operands[2]) != 128)))
6793 return "sub{w}\t{%2, %0|%0, %2}";
6794 operands[2] = GEN_INT (-INTVAL (operands[2]));
6795 return "add{w}\t{%2, %0|%0, %2}";
6799 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6800 (const_string "incdec")
6801 (const_string "alu")))
6802 (set_attr "mode" "SI")])
6805 (define_insn "*addhi_5"
6806 [(set (reg FLAGS_REG)
6808 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6809 (match_operand:HI 2 "general_operand" "rmn"))
6811 (clobber (match_scratch:HI 0 "=r"))]
6812 "ix86_match_ccmode (insn, CCGOCmode)
6813 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6815 switch (get_attr_type (insn))
6818 if (operands[2] == const1_rtx)
6819 return "inc{w}\t%0";
6822 gcc_assert (operands[2] == constm1_rtx);
6823 return "dec{w}\t%0";
6827 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6828 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6829 if (CONST_INT_P (operands[2])
6830 && (INTVAL (operands[2]) == 128
6831 || (INTVAL (operands[2]) < 0
6832 && INTVAL (operands[2]) != -128)))
6834 operands[2] = GEN_INT (-INTVAL (operands[2]));
6835 return "sub{w}\t{%2, %0|%0, %2}";
6837 return "add{w}\t{%2, %0|%0, %2}";
6841 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6842 (const_string "incdec")
6843 (const_string "alu")))
6844 (set_attr "mode" "HI")])
6846 (define_expand "addqi3"
6847 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6848 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6849 (match_operand:QI 2 "general_operand" "")))]
6850 "TARGET_QIMODE_MATH"
6851 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6853 ;; %%% Potential partial reg stall on alternative 2. What to do?
6854 (define_insn "*addqi_1_lea"
6855 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6856 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6857 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6858 (clobber (reg:CC FLAGS_REG))]
6859 "!TARGET_PARTIAL_REG_STALL
6860 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6862 int widen = (which_alternative == 2);
6863 switch (get_attr_type (insn))
6868 if (operands[2] == const1_rtx)
6869 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6872 gcc_assert (operands[2] == constm1_rtx);
6873 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6877 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6878 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6879 if (CONST_INT_P (operands[2])
6880 && (INTVAL (operands[2]) == 128
6881 || (INTVAL (operands[2]) < 0
6882 && INTVAL (operands[2]) != -128)))
6884 operands[2] = GEN_INT (-INTVAL (operands[2]));
6886 return "sub{l}\t{%2, %k0|%k0, %2}";
6888 return "sub{b}\t{%2, %0|%0, %2}";
6891 return "add{l}\t{%k2, %k0|%k0, %k2}";
6893 return "add{b}\t{%2, %0|%0, %2}";
6897 (if_then_else (eq_attr "alternative" "3")
6898 (const_string "lea")
6899 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6900 (const_string "incdec")
6901 (const_string "alu"))))
6902 (set_attr "mode" "QI,QI,SI,SI")])
6904 (define_insn "*addqi_1"
6905 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6906 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6907 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6908 (clobber (reg:CC FLAGS_REG))]
6909 "TARGET_PARTIAL_REG_STALL
6910 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6912 int widen = (which_alternative == 2);
6913 switch (get_attr_type (insn))
6916 if (operands[2] == const1_rtx)
6917 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6920 gcc_assert (operands[2] == constm1_rtx);
6921 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6925 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6926 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6927 if (CONST_INT_P (operands[2])
6928 && (INTVAL (operands[2]) == 128
6929 || (INTVAL (operands[2]) < 0
6930 && INTVAL (operands[2]) != -128)))
6932 operands[2] = GEN_INT (-INTVAL (operands[2]));
6934 return "sub{l}\t{%2, %k0|%k0, %2}";
6936 return "sub{b}\t{%2, %0|%0, %2}";
6939 return "add{l}\t{%k2, %k0|%k0, %k2}";
6941 return "add{b}\t{%2, %0|%0, %2}";
6945 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6946 (const_string "incdec")
6947 (const_string "alu")))
6948 (set_attr "mode" "QI,QI,SI")])
6950 (define_insn "*addqi_1_slp"
6951 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6952 (plus:QI (match_dup 0)
6953 (match_operand:QI 1 "general_operand" "qn,qnm")))
6954 (clobber (reg:CC FLAGS_REG))]
6955 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6956 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6958 switch (get_attr_type (insn))
6961 if (operands[1] == const1_rtx)
6962 return "inc{b}\t%0";
6965 gcc_assert (operands[1] == constm1_rtx);
6966 return "dec{b}\t%0";
6970 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6971 if (CONST_INT_P (operands[1])
6972 && INTVAL (operands[1]) < 0)
6974 operands[1] = GEN_INT (-INTVAL (operands[1]));
6975 return "sub{b}\t{%1, %0|%0, %1}";
6977 return "add{b}\t{%1, %0|%0, %1}";
6981 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6982 (const_string "incdec")
6983 (const_string "alu1")))
6984 (set (attr "memory")
6985 (if_then_else (match_operand 1 "memory_operand" "")
6986 (const_string "load")
6987 (const_string "none")))
6988 (set_attr "mode" "QI")])
6990 (define_insn "*addqi_2"
6991 [(set (reg FLAGS_REG)
6993 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6994 (match_operand:QI 2 "general_operand" "qmn,qn"))
6996 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6997 (plus:QI (match_dup 1) (match_dup 2)))]
6998 "ix86_match_ccmode (insn, CCGOCmode)
6999 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7001 switch (get_attr_type (insn))
7004 if (operands[2] == const1_rtx)
7005 return "inc{b}\t%0";
7008 gcc_assert (operands[2] == constm1_rtx
7009 || (CONST_INT_P (operands[2])
7010 && INTVAL (operands[2]) == 255));
7011 return "dec{b}\t%0";
7015 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7016 if (CONST_INT_P (operands[2])
7017 && INTVAL (operands[2]) < 0)
7019 operands[2] = GEN_INT (-INTVAL (operands[2]));
7020 return "sub{b}\t{%2, %0|%0, %2}";
7022 return "add{b}\t{%2, %0|%0, %2}";
7026 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7027 (const_string "incdec")
7028 (const_string "alu")))
7029 (set_attr "mode" "QI")])
7031 (define_insn "*addqi_3"
7032 [(set (reg FLAGS_REG)
7033 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7034 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7035 (clobber (match_scratch:QI 0 "=q"))]
7036 "ix86_match_ccmode (insn, CCZmode)
7037 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7039 switch (get_attr_type (insn))
7042 if (operands[2] == const1_rtx)
7043 return "inc{b}\t%0";
7046 gcc_assert (operands[2] == constm1_rtx
7047 || (CONST_INT_P (operands[2])
7048 && INTVAL (operands[2]) == 255));
7049 return "dec{b}\t%0";
7053 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7054 if (CONST_INT_P (operands[2])
7055 && INTVAL (operands[2]) < 0)
7057 operands[2] = GEN_INT (-INTVAL (operands[2]));
7058 return "sub{b}\t{%2, %0|%0, %2}";
7060 return "add{b}\t{%2, %0|%0, %2}";
7064 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7065 (const_string "incdec")
7066 (const_string "alu")))
7067 (set_attr "mode" "QI")])
7069 ; See comments above addsi_4 for details.
7070 (define_insn "*addqi_4"
7071 [(set (reg FLAGS_REG)
7072 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7073 (match_operand:QI 2 "const_int_operand" "n")))
7074 (clobber (match_scratch:QI 0 "=qm"))]
7075 "ix86_match_ccmode (insn, CCGCmode)
7076 && (INTVAL (operands[2]) & 0xff) != 0x80"
7078 switch (get_attr_type (insn))
7081 if (operands[2] == constm1_rtx
7082 || (CONST_INT_P (operands[2])
7083 && INTVAL (operands[2]) == 255))
7084 return "inc{b}\t%0";
7087 gcc_assert (operands[2] == const1_rtx);
7088 return "dec{b}\t%0";
7092 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7093 if (INTVAL (operands[2]) < 0)
7095 operands[2] = GEN_INT (-INTVAL (operands[2]));
7096 return "add{b}\t{%2, %0|%0, %2}";
7098 return "sub{b}\t{%2, %0|%0, %2}";
7102 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7103 (const_string "incdec")
7104 (const_string "alu")))
7105 (set_attr "mode" "QI")])
7108 (define_insn "*addqi_5"
7109 [(set (reg FLAGS_REG)
7111 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7112 (match_operand:QI 2 "general_operand" "qmn"))
7114 (clobber (match_scratch:QI 0 "=q"))]
7115 "ix86_match_ccmode (insn, CCGOCmode)
7116 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7118 switch (get_attr_type (insn))
7121 if (operands[2] == const1_rtx)
7122 return "inc{b}\t%0";
7125 gcc_assert (operands[2] == constm1_rtx
7126 || (CONST_INT_P (operands[2])
7127 && INTVAL (operands[2]) == 255));
7128 return "dec{b}\t%0";
7132 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7133 if (CONST_INT_P (operands[2])
7134 && INTVAL (operands[2]) < 0)
7136 operands[2] = GEN_INT (-INTVAL (operands[2]));
7137 return "sub{b}\t{%2, %0|%0, %2}";
7139 return "add{b}\t{%2, %0|%0, %2}";
7143 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7144 (const_string "incdec")
7145 (const_string "alu")))
7146 (set_attr "mode" "QI")])
7149 (define_insn "addqi_ext_1"
7150 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7155 (match_operand 1 "ext_register_operand" "0")
7158 (match_operand:QI 2 "general_operand" "Qmn")))
7159 (clobber (reg:CC FLAGS_REG))]
7162 switch (get_attr_type (insn))
7165 if (operands[2] == const1_rtx)
7166 return "inc{b}\t%h0";
7169 gcc_assert (operands[2] == constm1_rtx
7170 || (CONST_INT_P (operands[2])
7171 && INTVAL (operands[2]) == 255));
7172 return "dec{b}\t%h0";
7176 return "add{b}\t{%2, %h0|%h0, %2}";
7180 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7181 (const_string "incdec")
7182 (const_string "alu")))
7183 (set_attr "mode" "QI")])
7185 (define_insn "*addqi_ext_1_rex64"
7186 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7191 (match_operand 1 "ext_register_operand" "0")
7194 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7195 (clobber (reg:CC FLAGS_REG))]
7198 switch (get_attr_type (insn))
7201 if (operands[2] == const1_rtx)
7202 return "inc{b}\t%h0";
7205 gcc_assert (operands[2] == constm1_rtx
7206 || (CONST_INT_P (operands[2])
7207 && INTVAL (operands[2]) == 255));
7208 return "dec{b}\t%h0";
7212 return "add{b}\t{%2, %h0|%h0, %2}";
7216 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7217 (const_string "incdec")
7218 (const_string "alu")))
7219 (set_attr "mode" "QI")])
7221 (define_insn "*addqi_ext_2"
7222 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7227 (match_operand 1 "ext_register_operand" "%0")
7231 (match_operand 2 "ext_register_operand" "Q")
7234 (clobber (reg:CC FLAGS_REG))]
7236 "add{b}\t{%h2, %h0|%h0, %h2}"
7237 [(set_attr "type" "alu")
7238 (set_attr "mode" "QI")])
7240 ;; The patterns that match these are at the end of this file.
7242 (define_expand "addxf3"
7243 [(set (match_operand:XF 0 "register_operand" "")
7244 (plus:XF (match_operand:XF 1 "register_operand" "")
7245 (match_operand:XF 2 "register_operand" "")))]
7249 (define_expand "add<mode>3"
7250 [(set (match_operand:MODEF 0 "register_operand" "")
7251 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7252 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7253 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7256 ;; Subtract instructions
7258 ;; %%% splits for subditi3
7260 (define_expand "subti3"
7261 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7262 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7263 (match_operand:TI 2 "x86_64_general_operand" "")))]
7265 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7267 (define_insn "*subti3_1"
7268 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7269 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7270 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7271 (clobber (reg:CC FLAGS_REG))]
7272 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7276 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7277 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7278 (match_operand:TI 2 "x86_64_general_operand" "")))
7279 (clobber (reg:CC FLAGS_REG))]
7280 "TARGET_64BIT && reload_completed"
7281 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7282 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7283 (parallel [(set (match_dup 3)
7284 (minus:DI (match_dup 4)
7285 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7287 (clobber (reg:CC FLAGS_REG))])]
7288 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7290 ;; %%% splits for subsidi3
7292 (define_expand "subdi3"
7293 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7294 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7295 (match_operand:DI 2 "x86_64_general_operand" "")))]
7297 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7299 (define_insn "*subdi3_1"
7300 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7301 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7302 (match_operand:DI 2 "general_operand" "roiF,riF")))
7303 (clobber (reg:CC FLAGS_REG))]
7304 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7308 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7309 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7310 (match_operand:DI 2 "general_operand" "")))
7311 (clobber (reg:CC FLAGS_REG))]
7312 "!TARGET_64BIT && reload_completed"
7313 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7314 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7315 (parallel [(set (match_dup 3)
7316 (minus:SI (match_dup 4)
7317 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7319 (clobber (reg:CC FLAGS_REG))])]
7320 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7322 (define_insn "subdi3_carry_rex64"
7323 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7324 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7325 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7326 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7327 (clobber (reg:CC FLAGS_REG))]
7328 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7329 "sbb{q}\t{%2, %0|%0, %2}"
7330 [(set_attr "type" "alu")
7331 (set_attr "pent_pair" "pu")
7332 (set_attr "mode" "DI")])
7334 (define_insn "*subdi_1_rex64"
7335 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7336 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7337 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7338 (clobber (reg:CC FLAGS_REG))]
7339 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7340 "sub{q}\t{%2, %0|%0, %2}"
7341 [(set_attr "type" "alu")
7342 (set_attr "mode" "DI")])
7344 (define_insn "*subdi_2_rex64"
7345 [(set (reg FLAGS_REG)
7347 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7348 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7350 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7351 (minus:DI (match_dup 1) (match_dup 2)))]
7352 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7353 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7354 "sub{q}\t{%2, %0|%0, %2}"
7355 [(set_attr "type" "alu")
7356 (set_attr "mode" "DI")])
7358 (define_insn "*subdi_3_rex63"
7359 [(set (reg FLAGS_REG)
7360 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7361 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7362 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7363 (minus:DI (match_dup 1) (match_dup 2)))]
7364 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7365 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7366 "sub{q}\t{%2, %0|%0, %2}"
7367 [(set_attr "type" "alu")
7368 (set_attr "mode" "DI")])
7370 (define_insn "subqi3_carry"
7371 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7372 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7373 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7374 (match_operand:QI 2 "general_operand" "qn,qm"))))
7375 (clobber (reg:CC FLAGS_REG))]
7376 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7377 "sbb{b}\t{%2, %0|%0, %2}"
7378 [(set_attr "type" "alu")
7379 (set_attr "pent_pair" "pu")
7380 (set_attr "mode" "QI")])
7382 (define_insn "subhi3_carry"
7383 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7384 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7385 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7386 (match_operand:HI 2 "general_operand" "rn,rm"))))
7387 (clobber (reg:CC FLAGS_REG))]
7388 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7389 "sbb{w}\t{%2, %0|%0, %2}"
7390 [(set_attr "type" "alu")
7391 (set_attr "pent_pair" "pu")
7392 (set_attr "mode" "HI")])
7394 (define_insn "subsi3_carry"
7395 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7396 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7397 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7398 (match_operand:SI 2 "general_operand" "ri,rm"))))
7399 (clobber (reg:CC FLAGS_REG))]
7400 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7401 "sbb{l}\t{%2, %0|%0, %2}"
7402 [(set_attr "type" "alu")
7403 (set_attr "pent_pair" "pu")
7404 (set_attr "mode" "SI")])
7406 (define_insn "subsi3_carry_zext"
7407 [(set (match_operand:DI 0 "register_operand" "=r")
7409 (minus:SI (match_operand:SI 1 "register_operand" "0")
7410 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7411 (match_operand:SI 2 "general_operand" "g")))))
7412 (clobber (reg:CC FLAGS_REG))]
7413 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7414 "sbb{l}\t{%2, %k0|%k0, %2}"
7415 [(set_attr "type" "alu")
7416 (set_attr "pent_pair" "pu")
7417 (set_attr "mode" "SI")])
7419 (define_expand "subsi3"
7420 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7421 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7422 (match_operand:SI 2 "general_operand" "")))]
7424 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7426 (define_insn "*subsi_1"
7427 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7428 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7429 (match_operand:SI 2 "general_operand" "ri,rm")))
7430 (clobber (reg:CC FLAGS_REG))]
7431 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7432 "sub{l}\t{%2, %0|%0, %2}"
7433 [(set_attr "type" "alu")
7434 (set_attr "mode" "SI")])
7436 (define_insn "*subsi_1_zext"
7437 [(set (match_operand:DI 0 "register_operand" "=r")
7439 (minus:SI (match_operand:SI 1 "register_operand" "0")
7440 (match_operand:SI 2 "general_operand" "g"))))
7441 (clobber (reg:CC FLAGS_REG))]
7442 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7443 "sub{l}\t{%2, %k0|%k0, %2}"
7444 [(set_attr "type" "alu")
7445 (set_attr "mode" "SI")])
7447 (define_insn "*subsi_2"
7448 [(set (reg FLAGS_REG)
7450 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7451 (match_operand:SI 2 "general_operand" "ri,rm"))
7453 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7454 (minus:SI (match_dup 1) (match_dup 2)))]
7455 "ix86_match_ccmode (insn, CCGOCmode)
7456 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7457 "sub{l}\t{%2, %0|%0, %2}"
7458 [(set_attr "type" "alu")
7459 (set_attr "mode" "SI")])
7461 (define_insn "*subsi_2_zext"
7462 [(set (reg FLAGS_REG)
7464 (minus:SI (match_operand:SI 1 "register_operand" "0")
7465 (match_operand:SI 2 "general_operand" "g"))
7467 (set (match_operand:DI 0 "register_operand" "=r")
7469 (minus:SI (match_dup 1)
7471 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7472 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7473 "sub{l}\t{%2, %k0|%k0, %2}"
7474 [(set_attr "type" "alu")
7475 (set_attr "mode" "SI")])
7477 (define_insn "*subsi_3"
7478 [(set (reg FLAGS_REG)
7479 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7480 (match_operand:SI 2 "general_operand" "ri,rm")))
7481 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7482 (minus:SI (match_dup 1) (match_dup 2)))]
7483 "ix86_match_ccmode (insn, CCmode)
7484 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7485 "sub{l}\t{%2, %0|%0, %2}"
7486 [(set_attr "type" "alu")
7487 (set_attr "mode" "SI")])
7489 (define_insn "*subsi_3_zext"
7490 [(set (reg FLAGS_REG)
7491 (compare (match_operand:SI 1 "register_operand" "0")
7492 (match_operand:SI 2 "general_operand" "g")))
7493 (set (match_operand:DI 0 "register_operand" "=r")
7495 (minus:SI (match_dup 1)
7497 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7498 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7499 "sub{l}\t{%2, %1|%1, %2}"
7500 [(set_attr "type" "alu")
7501 (set_attr "mode" "DI")])
7503 (define_expand "subhi3"
7504 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7505 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7506 (match_operand:HI 2 "general_operand" "")))]
7507 "TARGET_HIMODE_MATH"
7508 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7510 (define_insn "*subhi_1"
7511 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7512 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7513 (match_operand:HI 2 "general_operand" "rn,rm")))
7514 (clobber (reg:CC FLAGS_REG))]
7515 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7516 "sub{w}\t{%2, %0|%0, %2}"
7517 [(set_attr "type" "alu")
7518 (set_attr "mode" "HI")])
7520 (define_insn "*subhi_2"
7521 [(set (reg FLAGS_REG)
7523 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7524 (match_operand:HI 2 "general_operand" "rn,rm"))
7526 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7527 (minus:HI (match_dup 1) (match_dup 2)))]
7528 "ix86_match_ccmode (insn, CCGOCmode)
7529 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7530 "sub{w}\t{%2, %0|%0, %2}"
7531 [(set_attr "type" "alu")
7532 (set_attr "mode" "HI")])
7534 (define_insn "*subhi_3"
7535 [(set (reg FLAGS_REG)
7536 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7537 (match_operand:HI 2 "general_operand" "rn,rm")))
7538 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7539 (minus:HI (match_dup 1) (match_dup 2)))]
7540 "ix86_match_ccmode (insn, CCmode)
7541 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7542 "sub{w}\t{%2, %0|%0, %2}"
7543 [(set_attr "type" "alu")
7544 (set_attr "mode" "HI")])
7546 (define_expand "subqi3"
7547 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7548 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7549 (match_operand:QI 2 "general_operand" "")))]
7550 "TARGET_QIMODE_MATH"
7551 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7553 (define_insn "*subqi_1"
7554 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7555 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7556 (match_operand:QI 2 "general_operand" "qn,qm")))
7557 (clobber (reg:CC FLAGS_REG))]
7558 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7559 "sub{b}\t{%2, %0|%0, %2}"
7560 [(set_attr "type" "alu")
7561 (set_attr "mode" "QI")])
7563 (define_insn "*subqi_1_slp"
7564 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7565 (minus:QI (match_dup 0)
7566 (match_operand:QI 1 "general_operand" "qn,qm")))
7567 (clobber (reg:CC FLAGS_REG))]
7568 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7569 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7570 "sub{b}\t{%1, %0|%0, %1}"
7571 [(set_attr "type" "alu1")
7572 (set_attr "mode" "QI")])
7574 (define_insn "*subqi_2"
7575 [(set (reg FLAGS_REG)
7577 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7578 (match_operand:QI 2 "general_operand" "qn,qm"))
7580 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7581 (minus:QI (match_dup 1) (match_dup 2)))]
7582 "ix86_match_ccmode (insn, CCGOCmode)
7583 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7584 "sub{b}\t{%2, %0|%0, %2}"
7585 [(set_attr "type" "alu")
7586 (set_attr "mode" "QI")])
7588 (define_insn "*subqi_3"
7589 [(set (reg FLAGS_REG)
7590 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7591 (match_operand:QI 2 "general_operand" "qn,qm")))
7592 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7593 (minus:QI (match_dup 1) (match_dup 2)))]
7594 "ix86_match_ccmode (insn, CCmode)
7595 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7596 "sub{b}\t{%2, %0|%0, %2}"
7597 [(set_attr "type" "alu")
7598 (set_attr "mode" "QI")])
7600 ;; The patterns that match these are at the end of this file.
7602 (define_expand "subxf3"
7603 [(set (match_operand:XF 0 "register_operand" "")
7604 (minus:XF (match_operand:XF 1 "register_operand" "")
7605 (match_operand:XF 2 "register_operand" "")))]
7609 (define_expand "sub<mode>3"
7610 [(set (match_operand:MODEF 0 "register_operand" "")
7611 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7612 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7613 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7616 ;; Multiply instructions
7618 (define_expand "muldi3"
7619 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7620 (mult:DI (match_operand:DI 1 "register_operand" "")
7621 (match_operand:DI 2 "x86_64_general_operand" "")))
7622 (clobber (reg:CC FLAGS_REG))])]
7627 ;; IMUL reg64, reg64, imm8 Direct
7628 ;; IMUL reg64, mem64, imm8 VectorPath
7629 ;; IMUL reg64, reg64, imm32 Direct
7630 ;; IMUL reg64, mem64, imm32 VectorPath
7631 ;; IMUL reg64, reg64 Direct
7632 ;; IMUL reg64, mem64 Direct
7634 (define_insn "*muldi3_1_rex64"
7635 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7636 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7637 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7638 (clobber (reg:CC FLAGS_REG))]
7640 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7642 imul{q}\t{%2, %1, %0|%0, %1, %2}
7643 imul{q}\t{%2, %1, %0|%0, %1, %2}
7644 imul{q}\t{%2, %0|%0, %2}"
7645 [(set_attr "type" "imul")
7646 (set_attr "prefix_0f" "0,0,1")
7647 (set (attr "athlon_decode")
7648 (cond [(eq_attr "cpu" "athlon")
7649 (const_string "vector")
7650 (eq_attr "alternative" "1")
7651 (const_string "vector")
7652 (and (eq_attr "alternative" "2")
7653 (match_operand 1 "memory_operand" ""))
7654 (const_string "vector")]
7655 (const_string "direct")))
7656 (set (attr "amdfam10_decode")
7657 (cond [(and (eq_attr "alternative" "0,1")
7658 (match_operand 1 "memory_operand" ""))
7659 (const_string "vector")]
7660 (const_string "direct")))
7661 (set_attr "mode" "DI")])
7663 (define_expand "mulsi3"
7664 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7665 (mult:SI (match_operand:SI 1 "register_operand" "")
7666 (match_operand:SI 2 "general_operand" "")))
7667 (clobber (reg:CC FLAGS_REG))])]
7672 ;; IMUL reg32, reg32, imm8 Direct
7673 ;; IMUL reg32, mem32, imm8 VectorPath
7674 ;; IMUL reg32, reg32, imm32 Direct
7675 ;; IMUL reg32, mem32, imm32 VectorPath
7676 ;; IMUL reg32, reg32 Direct
7677 ;; IMUL reg32, mem32 Direct
7679 (define_insn "*mulsi3_1"
7680 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7681 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7682 (match_operand:SI 2 "general_operand" "K,i,mr")))
7683 (clobber (reg:CC FLAGS_REG))]
7684 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7686 imul{l}\t{%2, %1, %0|%0, %1, %2}
7687 imul{l}\t{%2, %1, %0|%0, %1, %2}
7688 imul{l}\t{%2, %0|%0, %2}"
7689 [(set_attr "type" "imul")
7690 (set_attr "prefix_0f" "0,0,1")
7691 (set (attr "athlon_decode")
7692 (cond [(eq_attr "cpu" "athlon")
7693 (const_string "vector")
7694 (eq_attr "alternative" "1")
7695 (const_string "vector")
7696 (and (eq_attr "alternative" "2")
7697 (match_operand 1 "memory_operand" ""))
7698 (const_string "vector")]
7699 (const_string "direct")))
7700 (set (attr "amdfam10_decode")
7701 (cond [(and (eq_attr "alternative" "0,1")
7702 (match_operand 1 "memory_operand" ""))
7703 (const_string "vector")]
7704 (const_string "direct")))
7705 (set_attr "mode" "SI")])
7707 (define_insn "*mulsi3_1_zext"
7708 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7710 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7711 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7712 (clobber (reg:CC FLAGS_REG))]
7714 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7716 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7717 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7718 imul{l}\t{%2, %k0|%k0, %2}"
7719 [(set_attr "type" "imul")
7720 (set_attr "prefix_0f" "0,0,1")
7721 (set (attr "athlon_decode")
7722 (cond [(eq_attr "cpu" "athlon")
7723 (const_string "vector")
7724 (eq_attr "alternative" "1")
7725 (const_string "vector")
7726 (and (eq_attr "alternative" "2")
7727 (match_operand 1 "memory_operand" ""))
7728 (const_string "vector")]
7729 (const_string "direct")))
7730 (set (attr "amdfam10_decode")
7731 (cond [(and (eq_attr "alternative" "0,1")
7732 (match_operand 1 "memory_operand" ""))
7733 (const_string "vector")]
7734 (const_string "direct")))
7735 (set_attr "mode" "SI")])
7737 (define_expand "mulhi3"
7738 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7739 (mult:HI (match_operand:HI 1 "register_operand" "")
7740 (match_operand:HI 2 "general_operand" "")))
7741 (clobber (reg:CC FLAGS_REG))])]
7742 "TARGET_HIMODE_MATH"
7746 ;; IMUL reg16, reg16, imm8 VectorPath
7747 ;; IMUL reg16, mem16, imm8 VectorPath
7748 ;; IMUL reg16, reg16, imm16 VectorPath
7749 ;; IMUL reg16, mem16, imm16 VectorPath
7750 ;; IMUL reg16, reg16 Direct
7751 ;; IMUL reg16, mem16 Direct
7752 (define_insn "*mulhi3_1"
7753 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7754 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7755 (match_operand:HI 2 "general_operand" "K,n,mr")))
7756 (clobber (reg:CC FLAGS_REG))]
7757 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7759 imul{w}\t{%2, %1, %0|%0, %1, %2}
7760 imul{w}\t{%2, %1, %0|%0, %1, %2}
7761 imul{w}\t{%2, %0|%0, %2}"
7762 [(set_attr "type" "imul")
7763 (set_attr "prefix_0f" "0,0,1")
7764 (set (attr "athlon_decode")
7765 (cond [(eq_attr "cpu" "athlon")
7766 (const_string "vector")
7767 (eq_attr "alternative" "1,2")
7768 (const_string "vector")]
7769 (const_string "direct")))
7770 (set (attr "amdfam10_decode")
7771 (cond [(eq_attr "alternative" "0,1")
7772 (const_string "vector")]
7773 (const_string "direct")))
7774 (set_attr "mode" "HI")])
7776 (define_expand "mulqi3"
7777 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7778 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7779 (match_operand:QI 2 "register_operand" "")))
7780 (clobber (reg:CC FLAGS_REG))])]
7781 "TARGET_QIMODE_MATH"
7788 (define_insn "*mulqi3_1"
7789 [(set (match_operand:QI 0 "register_operand" "=a")
7790 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7791 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7792 (clobber (reg:CC FLAGS_REG))]
7794 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7796 [(set_attr "type" "imul")
7797 (set_attr "length_immediate" "0")
7798 (set (attr "athlon_decode")
7799 (if_then_else (eq_attr "cpu" "athlon")
7800 (const_string "vector")
7801 (const_string "direct")))
7802 (set_attr "amdfam10_decode" "direct")
7803 (set_attr "mode" "QI")])
7805 (define_expand "umulqihi3"
7806 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7807 (mult:HI (zero_extend:HI
7808 (match_operand:QI 1 "nonimmediate_operand" ""))
7810 (match_operand:QI 2 "register_operand" ""))))
7811 (clobber (reg:CC FLAGS_REG))])]
7812 "TARGET_QIMODE_MATH"
7815 (define_insn "*umulqihi3_1"
7816 [(set (match_operand:HI 0 "register_operand" "=a")
7817 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7818 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7819 (clobber (reg:CC FLAGS_REG))]
7821 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7823 [(set_attr "type" "imul")
7824 (set_attr "length_immediate" "0")
7825 (set (attr "athlon_decode")
7826 (if_then_else (eq_attr "cpu" "athlon")
7827 (const_string "vector")
7828 (const_string "direct")))
7829 (set_attr "amdfam10_decode" "direct")
7830 (set_attr "mode" "QI")])
7832 (define_expand "mulqihi3"
7833 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7834 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7835 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7836 (clobber (reg:CC FLAGS_REG))])]
7837 "TARGET_QIMODE_MATH"
7840 (define_insn "*mulqihi3_insn"
7841 [(set (match_operand:HI 0 "register_operand" "=a")
7842 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7843 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7844 (clobber (reg:CC FLAGS_REG))]
7846 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7848 [(set_attr "type" "imul")
7849 (set_attr "length_immediate" "0")
7850 (set (attr "athlon_decode")
7851 (if_then_else (eq_attr "cpu" "athlon")
7852 (const_string "vector")
7853 (const_string "direct")))
7854 (set_attr "amdfam10_decode" "direct")
7855 (set_attr "mode" "QI")])
7857 (define_expand "umulditi3"
7858 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7859 (mult:TI (zero_extend:TI
7860 (match_operand:DI 1 "nonimmediate_operand" ""))
7862 (match_operand:DI 2 "register_operand" ""))))
7863 (clobber (reg:CC FLAGS_REG))])]
7867 (define_insn "*umulditi3_insn"
7868 [(set (match_operand:TI 0 "register_operand" "=A")
7869 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7870 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7871 (clobber (reg:CC FLAGS_REG))]
7873 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7875 [(set_attr "type" "imul")
7876 (set_attr "length_immediate" "0")
7877 (set (attr "athlon_decode")
7878 (if_then_else (eq_attr "cpu" "athlon")
7879 (const_string "vector")
7880 (const_string "double")))
7881 (set_attr "amdfam10_decode" "double")
7882 (set_attr "mode" "DI")])
7884 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7885 (define_expand "umulsidi3"
7886 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7887 (mult:DI (zero_extend:DI
7888 (match_operand:SI 1 "nonimmediate_operand" ""))
7890 (match_operand:SI 2 "register_operand" ""))))
7891 (clobber (reg:CC FLAGS_REG))])]
7895 (define_insn "*umulsidi3_insn"
7896 [(set (match_operand:DI 0 "register_operand" "=A")
7897 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7898 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7899 (clobber (reg:CC FLAGS_REG))]
7901 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7903 [(set_attr "type" "imul")
7904 (set_attr "length_immediate" "0")
7905 (set (attr "athlon_decode")
7906 (if_then_else (eq_attr "cpu" "athlon")
7907 (const_string "vector")
7908 (const_string "double")))
7909 (set_attr "amdfam10_decode" "double")
7910 (set_attr "mode" "SI")])
7912 (define_expand "mulditi3"
7913 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7914 (mult:TI (sign_extend:TI
7915 (match_operand:DI 1 "nonimmediate_operand" ""))
7917 (match_operand:DI 2 "register_operand" ""))))
7918 (clobber (reg:CC FLAGS_REG))])]
7922 (define_insn "*mulditi3_insn"
7923 [(set (match_operand:TI 0 "register_operand" "=A")
7924 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7925 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7926 (clobber (reg:CC FLAGS_REG))]
7928 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7930 [(set_attr "type" "imul")
7931 (set_attr "length_immediate" "0")
7932 (set (attr "athlon_decode")
7933 (if_then_else (eq_attr "cpu" "athlon")
7934 (const_string "vector")
7935 (const_string "double")))
7936 (set_attr "amdfam10_decode" "double")
7937 (set_attr "mode" "DI")])
7939 (define_expand "mulsidi3"
7940 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7941 (mult:DI (sign_extend:DI
7942 (match_operand:SI 1 "nonimmediate_operand" ""))
7944 (match_operand:SI 2 "register_operand" ""))))
7945 (clobber (reg:CC FLAGS_REG))])]
7949 (define_insn "*mulsidi3_insn"
7950 [(set (match_operand:DI 0 "register_operand" "=A")
7951 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7952 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7953 (clobber (reg:CC FLAGS_REG))]
7955 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7957 [(set_attr "type" "imul")
7958 (set_attr "length_immediate" "0")
7959 (set (attr "athlon_decode")
7960 (if_then_else (eq_attr "cpu" "athlon")
7961 (const_string "vector")
7962 (const_string "double")))
7963 (set_attr "amdfam10_decode" "double")
7964 (set_attr "mode" "SI")])
7966 (define_expand "umuldi3_highpart"
7967 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7970 (mult:TI (zero_extend:TI
7971 (match_operand:DI 1 "nonimmediate_operand" ""))
7973 (match_operand:DI 2 "register_operand" "")))
7975 (clobber (match_scratch:DI 3 ""))
7976 (clobber (reg:CC FLAGS_REG))])]
7980 (define_insn "*umuldi3_highpart_rex64"
7981 [(set (match_operand:DI 0 "register_operand" "=d")
7984 (mult:TI (zero_extend:TI
7985 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7987 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7989 (clobber (match_scratch:DI 3 "=1"))
7990 (clobber (reg:CC FLAGS_REG))]
7992 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7994 [(set_attr "type" "imul")
7995 (set_attr "length_immediate" "0")
7996 (set (attr "athlon_decode")
7997 (if_then_else (eq_attr "cpu" "athlon")
7998 (const_string "vector")
7999 (const_string "double")))
8000 (set_attr "amdfam10_decode" "double")
8001 (set_attr "mode" "DI")])
8003 (define_expand "umulsi3_highpart"
8004 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8007 (mult:DI (zero_extend:DI
8008 (match_operand:SI 1 "nonimmediate_operand" ""))
8010 (match_operand:SI 2 "register_operand" "")))
8012 (clobber (match_scratch:SI 3 ""))
8013 (clobber (reg:CC FLAGS_REG))])]
8017 (define_insn "*umulsi3_highpart_insn"
8018 [(set (match_operand:SI 0 "register_operand" "=d")
8021 (mult:DI (zero_extend:DI
8022 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8024 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8026 (clobber (match_scratch:SI 3 "=1"))
8027 (clobber (reg:CC FLAGS_REG))]
8028 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8030 [(set_attr "type" "imul")
8031 (set_attr "length_immediate" "0")
8032 (set (attr "athlon_decode")
8033 (if_then_else (eq_attr "cpu" "athlon")
8034 (const_string "vector")
8035 (const_string "double")))
8036 (set_attr "amdfam10_decode" "double")
8037 (set_attr "mode" "SI")])
8039 (define_insn "*umulsi3_highpart_zext"
8040 [(set (match_operand:DI 0 "register_operand" "=d")
8041 (zero_extend:DI (truncate:SI
8043 (mult:DI (zero_extend:DI
8044 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8046 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8048 (clobber (match_scratch:SI 3 "=1"))
8049 (clobber (reg:CC FLAGS_REG))]
8051 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8053 [(set_attr "type" "imul")
8054 (set_attr "length_immediate" "0")
8055 (set (attr "athlon_decode")
8056 (if_then_else (eq_attr "cpu" "athlon")
8057 (const_string "vector")
8058 (const_string "double")))
8059 (set_attr "amdfam10_decode" "double")
8060 (set_attr "mode" "SI")])
8062 (define_expand "smuldi3_highpart"
8063 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8066 (mult:TI (sign_extend:TI
8067 (match_operand:DI 1 "nonimmediate_operand" ""))
8069 (match_operand:DI 2 "register_operand" "")))
8071 (clobber (match_scratch:DI 3 ""))
8072 (clobber (reg:CC FLAGS_REG))])]
8076 (define_insn "*smuldi3_highpart_rex64"
8077 [(set (match_operand:DI 0 "register_operand" "=d")
8080 (mult:TI (sign_extend:TI
8081 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8083 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8085 (clobber (match_scratch:DI 3 "=1"))
8086 (clobber (reg:CC FLAGS_REG))]
8088 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8090 [(set_attr "type" "imul")
8091 (set (attr "athlon_decode")
8092 (if_then_else (eq_attr "cpu" "athlon")
8093 (const_string "vector")
8094 (const_string "double")))
8095 (set_attr "amdfam10_decode" "double")
8096 (set_attr "mode" "DI")])
8098 (define_expand "smulsi3_highpart"
8099 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8102 (mult:DI (sign_extend:DI
8103 (match_operand:SI 1 "nonimmediate_operand" ""))
8105 (match_operand:SI 2 "register_operand" "")))
8107 (clobber (match_scratch:SI 3 ""))
8108 (clobber (reg:CC FLAGS_REG))])]
8112 (define_insn "*smulsi3_highpart_insn"
8113 [(set (match_operand:SI 0 "register_operand" "=d")
8116 (mult:DI (sign_extend:DI
8117 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8119 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8121 (clobber (match_scratch:SI 3 "=1"))
8122 (clobber (reg:CC FLAGS_REG))]
8123 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8125 [(set_attr "type" "imul")
8126 (set (attr "athlon_decode")
8127 (if_then_else (eq_attr "cpu" "athlon")
8128 (const_string "vector")
8129 (const_string "double")))
8130 (set_attr "amdfam10_decode" "double")
8131 (set_attr "mode" "SI")])
8133 (define_insn "*smulsi3_highpart_zext"
8134 [(set (match_operand:DI 0 "register_operand" "=d")
8135 (zero_extend:DI (truncate:SI
8137 (mult:DI (sign_extend:DI
8138 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8140 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8142 (clobber (match_scratch:SI 3 "=1"))
8143 (clobber (reg:CC FLAGS_REG))]
8145 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8147 [(set_attr "type" "imul")
8148 (set (attr "athlon_decode")
8149 (if_then_else (eq_attr "cpu" "athlon")
8150 (const_string "vector")
8151 (const_string "double")))
8152 (set_attr "amdfam10_decode" "double")
8153 (set_attr "mode" "SI")])
8155 ;; The patterns that match these are at the end of this file.
8157 (define_expand "mulxf3"
8158 [(set (match_operand:XF 0 "register_operand" "")
8159 (mult:XF (match_operand:XF 1 "register_operand" "")
8160 (match_operand:XF 2 "register_operand" "")))]
8164 (define_expand "mul<mode>3"
8165 [(set (match_operand:MODEF 0 "register_operand" "")
8166 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8167 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8168 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8171 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8174 ;; Divide instructions
8176 (define_insn "divqi3"
8177 [(set (match_operand:QI 0 "register_operand" "=a")
8178 (div:QI (match_operand:HI 1 "register_operand" "0")
8179 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8180 (clobber (reg:CC FLAGS_REG))]
8181 "TARGET_QIMODE_MATH"
8183 [(set_attr "type" "idiv")
8184 (set_attr "mode" "QI")])
8186 (define_insn "udivqi3"
8187 [(set (match_operand:QI 0 "register_operand" "=a")
8188 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8189 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8190 (clobber (reg:CC FLAGS_REG))]
8191 "TARGET_QIMODE_MATH"
8193 [(set_attr "type" "idiv")
8194 (set_attr "mode" "QI")])
8196 ;; The patterns that match these are at the end of this file.
8198 (define_expand "divxf3"
8199 [(set (match_operand:XF 0 "register_operand" "")
8200 (div:XF (match_operand:XF 1 "register_operand" "")
8201 (match_operand:XF 2 "register_operand" "")))]
8205 (define_expand "divdf3"
8206 [(set (match_operand:DF 0 "register_operand" "")
8207 (div:DF (match_operand:DF 1 "register_operand" "")
8208 (match_operand:DF 2 "nonimmediate_operand" "")))]
8209 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8212 (define_expand "divsf3"
8213 [(set (match_operand:SF 0 "register_operand" "")
8214 (div:SF (match_operand:SF 1 "register_operand" "")
8215 (match_operand:SF 2 "nonimmediate_operand" "")))]
8216 "TARGET_80387 || TARGET_SSE_MATH"
8218 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8219 && flag_finite_math_only && !flag_trapping_math
8220 && flag_unsafe_math_optimizations)
8222 ix86_emit_swdivsf (operands[0], operands[1],
8223 operands[2], SFmode);
8228 ;; Remainder instructions.
8230 (define_expand "divmoddi4"
8231 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8232 (div:DI (match_operand:DI 1 "register_operand" "")
8233 (match_operand:DI 2 "nonimmediate_operand" "")))
8234 (set (match_operand:DI 3 "register_operand" "")
8235 (mod:DI (match_dup 1) (match_dup 2)))
8236 (clobber (reg:CC FLAGS_REG))])]
8240 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8241 ;; Penalize eax case slightly because it results in worse scheduling
8243 (define_insn "*divmoddi4_nocltd_rex64"
8244 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8245 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8246 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8247 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8248 (mod:DI (match_dup 2) (match_dup 3)))
8249 (clobber (reg:CC FLAGS_REG))]
8250 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8252 [(set_attr "type" "multi")])
8254 (define_insn "*divmoddi4_cltd_rex64"
8255 [(set (match_operand:DI 0 "register_operand" "=a")
8256 (div:DI (match_operand:DI 2 "register_operand" "a")
8257 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8258 (set (match_operand:DI 1 "register_operand" "=&d")
8259 (mod:DI (match_dup 2) (match_dup 3)))
8260 (clobber (reg:CC FLAGS_REG))]
8261 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8263 [(set_attr "type" "multi")])
8265 (define_insn "*divmoddi_noext_rex64"
8266 [(set (match_operand:DI 0 "register_operand" "=a")
8267 (div:DI (match_operand:DI 1 "register_operand" "0")
8268 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8269 (set (match_operand:DI 3 "register_operand" "=d")
8270 (mod:DI (match_dup 1) (match_dup 2)))
8271 (use (match_operand:DI 4 "register_operand" "3"))
8272 (clobber (reg:CC FLAGS_REG))]
8275 [(set_attr "type" "idiv")
8276 (set_attr "mode" "DI")])
8279 [(set (match_operand:DI 0 "register_operand" "")
8280 (div:DI (match_operand:DI 1 "register_operand" "")
8281 (match_operand:DI 2 "nonimmediate_operand" "")))
8282 (set (match_operand:DI 3 "register_operand" "")
8283 (mod:DI (match_dup 1) (match_dup 2)))
8284 (clobber (reg:CC FLAGS_REG))]
8285 "TARGET_64BIT && reload_completed"
8286 [(parallel [(set (match_dup 3)
8287 (ashiftrt:DI (match_dup 4) (const_int 63)))
8288 (clobber (reg:CC FLAGS_REG))])
8289 (parallel [(set (match_dup 0)
8290 (div:DI (reg:DI 0) (match_dup 2)))
8292 (mod:DI (reg:DI 0) (match_dup 2)))
8294 (clobber (reg:CC FLAGS_REG))])]
8296 /* Avoid use of cltd in favor of a mov+shift. */
8297 if (!TARGET_USE_CLTD && !optimize_size)
8299 if (true_regnum (operands[1]))
8300 emit_move_insn (operands[0], operands[1]);
8302 emit_move_insn (operands[3], operands[1]);
8303 operands[4] = operands[3];
8307 gcc_assert (!true_regnum (operands[1]));
8308 operands[4] = operands[1];
8313 (define_expand "divmodsi4"
8314 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8315 (div:SI (match_operand:SI 1 "register_operand" "")
8316 (match_operand:SI 2 "nonimmediate_operand" "")))
8317 (set (match_operand:SI 3 "register_operand" "")
8318 (mod:SI (match_dup 1) (match_dup 2)))
8319 (clobber (reg:CC FLAGS_REG))])]
8323 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8324 ;; Penalize eax case slightly because it results in worse scheduling
8326 (define_insn "*divmodsi4_nocltd"
8327 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8328 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8329 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8330 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8331 (mod:SI (match_dup 2) (match_dup 3)))
8332 (clobber (reg:CC FLAGS_REG))]
8333 "!optimize_size && !TARGET_USE_CLTD"
8335 [(set_attr "type" "multi")])
8337 (define_insn "*divmodsi4_cltd"
8338 [(set (match_operand:SI 0 "register_operand" "=a")
8339 (div:SI (match_operand:SI 2 "register_operand" "a")
8340 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8341 (set (match_operand:SI 1 "register_operand" "=&d")
8342 (mod:SI (match_dup 2) (match_dup 3)))
8343 (clobber (reg:CC FLAGS_REG))]
8344 "optimize_size || TARGET_USE_CLTD"
8346 [(set_attr "type" "multi")])
8348 (define_insn "*divmodsi_noext"
8349 [(set (match_operand:SI 0 "register_operand" "=a")
8350 (div:SI (match_operand:SI 1 "register_operand" "0")
8351 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8352 (set (match_operand:SI 3 "register_operand" "=d")
8353 (mod:SI (match_dup 1) (match_dup 2)))
8354 (use (match_operand:SI 4 "register_operand" "3"))
8355 (clobber (reg:CC FLAGS_REG))]
8358 [(set_attr "type" "idiv")
8359 (set_attr "mode" "SI")])
8362 [(set (match_operand:SI 0 "register_operand" "")
8363 (div:SI (match_operand:SI 1 "register_operand" "")
8364 (match_operand:SI 2 "nonimmediate_operand" "")))
8365 (set (match_operand:SI 3 "register_operand" "")
8366 (mod:SI (match_dup 1) (match_dup 2)))
8367 (clobber (reg:CC FLAGS_REG))]
8369 [(parallel [(set (match_dup 3)
8370 (ashiftrt:SI (match_dup 4) (const_int 31)))
8371 (clobber (reg:CC FLAGS_REG))])
8372 (parallel [(set (match_dup 0)
8373 (div:SI (reg:SI 0) (match_dup 2)))
8375 (mod:SI (reg:SI 0) (match_dup 2)))
8377 (clobber (reg:CC FLAGS_REG))])]
8379 /* Avoid use of cltd in favor of a mov+shift. */
8380 if (!TARGET_USE_CLTD && !optimize_size)
8382 if (true_regnum (operands[1]))
8383 emit_move_insn (operands[0], operands[1]);
8385 emit_move_insn (operands[3], operands[1]);
8386 operands[4] = operands[3];
8390 gcc_assert (!true_regnum (operands[1]));
8391 operands[4] = operands[1];
8395 (define_insn "divmodhi4"
8396 [(set (match_operand:HI 0 "register_operand" "=a")
8397 (div:HI (match_operand:HI 1 "register_operand" "0")
8398 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8399 (set (match_operand:HI 3 "register_operand" "=&d")
8400 (mod:HI (match_dup 1) (match_dup 2)))
8401 (clobber (reg:CC FLAGS_REG))]
8402 "TARGET_HIMODE_MATH"
8404 [(set_attr "type" "multi")
8405 (set_attr "length_immediate" "0")
8406 (set_attr "mode" "SI")])
8408 (define_insn "udivmoddi4"
8409 [(set (match_operand:DI 0 "register_operand" "=a")
8410 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8411 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8412 (set (match_operand:DI 3 "register_operand" "=&d")
8413 (umod:DI (match_dup 1) (match_dup 2)))
8414 (clobber (reg:CC FLAGS_REG))]
8416 "xor{q}\t%3, %3\;div{q}\t%2"
8417 [(set_attr "type" "multi")
8418 (set_attr "length_immediate" "0")
8419 (set_attr "mode" "DI")])
8421 (define_insn "*udivmoddi4_noext"
8422 [(set (match_operand:DI 0 "register_operand" "=a")
8423 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8424 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8425 (set (match_operand:DI 3 "register_operand" "=d")
8426 (umod:DI (match_dup 1) (match_dup 2)))
8428 (clobber (reg:CC FLAGS_REG))]
8431 [(set_attr "type" "idiv")
8432 (set_attr "mode" "DI")])
8435 [(set (match_operand:DI 0 "register_operand" "")
8436 (udiv:DI (match_operand:DI 1 "register_operand" "")
8437 (match_operand:DI 2 "nonimmediate_operand" "")))
8438 (set (match_operand:DI 3 "register_operand" "")
8439 (umod:DI (match_dup 1) (match_dup 2)))
8440 (clobber (reg:CC FLAGS_REG))]
8441 "TARGET_64BIT && reload_completed"
8442 [(set (match_dup 3) (const_int 0))
8443 (parallel [(set (match_dup 0)
8444 (udiv:DI (match_dup 1) (match_dup 2)))
8446 (umod:DI (match_dup 1) (match_dup 2)))
8448 (clobber (reg:CC FLAGS_REG))])]
8451 (define_insn "udivmodsi4"
8452 [(set (match_operand:SI 0 "register_operand" "=a")
8453 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8454 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8455 (set (match_operand:SI 3 "register_operand" "=&d")
8456 (umod:SI (match_dup 1) (match_dup 2)))
8457 (clobber (reg:CC FLAGS_REG))]
8459 "xor{l}\t%3, %3\;div{l}\t%2"
8460 [(set_attr "type" "multi")
8461 (set_attr "length_immediate" "0")
8462 (set_attr "mode" "SI")])
8464 (define_insn "*udivmodsi4_noext"
8465 [(set (match_operand:SI 0 "register_operand" "=a")
8466 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8467 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8468 (set (match_operand:SI 3 "register_operand" "=d")
8469 (umod:SI (match_dup 1) (match_dup 2)))
8471 (clobber (reg:CC FLAGS_REG))]
8474 [(set_attr "type" "idiv")
8475 (set_attr "mode" "SI")])
8478 [(set (match_operand:SI 0 "register_operand" "")
8479 (udiv:SI (match_operand:SI 1 "register_operand" "")
8480 (match_operand:SI 2 "nonimmediate_operand" "")))
8481 (set (match_operand:SI 3 "register_operand" "")
8482 (umod:SI (match_dup 1) (match_dup 2)))
8483 (clobber (reg:CC FLAGS_REG))]
8485 [(set (match_dup 3) (const_int 0))
8486 (parallel [(set (match_dup 0)
8487 (udiv:SI (match_dup 1) (match_dup 2)))
8489 (umod:SI (match_dup 1) (match_dup 2)))
8491 (clobber (reg:CC FLAGS_REG))])]
8494 (define_expand "udivmodhi4"
8495 [(set (match_dup 4) (const_int 0))
8496 (parallel [(set (match_operand:HI 0 "register_operand" "")
8497 (udiv:HI (match_operand:HI 1 "register_operand" "")
8498 (match_operand:HI 2 "nonimmediate_operand" "")))
8499 (set (match_operand:HI 3 "register_operand" "")
8500 (umod:HI (match_dup 1) (match_dup 2)))
8502 (clobber (reg:CC FLAGS_REG))])]
8503 "TARGET_HIMODE_MATH"
8504 "operands[4] = gen_reg_rtx (HImode);")
8506 (define_insn "*udivmodhi_noext"
8507 [(set (match_operand:HI 0 "register_operand" "=a")
8508 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8509 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8510 (set (match_operand:HI 3 "register_operand" "=d")
8511 (umod:HI (match_dup 1) (match_dup 2)))
8512 (use (match_operand:HI 4 "register_operand" "3"))
8513 (clobber (reg:CC FLAGS_REG))]
8516 [(set_attr "type" "idiv")
8517 (set_attr "mode" "HI")])
8519 ;; We cannot use div/idiv for double division, because it causes
8520 ;; "division by zero" on the overflow and that's not what we expect
8521 ;; from truncate. Because true (non truncating) double division is
8522 ;; never generated, we can't create this insn anyway.
8525 ; [(set (match_operand:SI 0 "register_operand" "=a")
8527 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8529 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8530 ; (set (match_operand:SI 3 "register_operand" "=d")
8532 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8533 ; (clobber (reg:CC FLAGS_REG))]
8535 ; "div{l}\t{%2, %0|%0, %2}"
8536 ; [(set_attr "type" "idiv")])
8538 ;;- Logical AND instructions
8540 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8541 ;; Note that this excludes ah.
8543 (define_insn "*testdi_1_rex64"
8544 [(set (reg FLAGS_REG)
8546 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8547 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8549 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8550 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8552 test{l}\t{%k1, %k0|%k0, %k1}
8553 test{l}\t{%k1, %k0|%k0, %k1}
8554 test{q}\t{%1, %0|%0, %1}
8555 test{q}\t{%1, %0|%0, %1}
8556 test{q}\t{%1, %0|%0, %1}"
8557 [(set_attr "type" "test")
8558 (set_attr "modrm" "0,1,0,1,1")
8559 (set_attr "mode" "SI,SI,DI,DI,DI")
8560 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8562 (define_insn "testsi_1"
8563 [(set (reg FLAGS_REG)
8565 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8566 (match_operand:SI 1 "general_operand" "i,i,ri"))
8568 "ix86_match_ccmode (insn, CCNOmode)
8569 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8570 "test{l}\t{%1, %0|%0, %1}"
8571 [(set_attr "type" "test")
8572 (set_attr "modrm" "0,1,1")
8573 (set_attr "mode" "SI")
8574 (set_attr "pent_pair" "uv,np,uv")])
8576 (define_expand "testsi_ccno_1"
8577 [(set (reg:CCNO FLAGS_REG)
8579 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8580 (match_operand:SI 1 "nonmemory_operand" ""))
8585 (define_insn "*testhi_1"
8586 [(set (reg FLAGS_REG)
8587 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8588 (match_operand:HI 1 "general_operand" "n,n,rn"))
8590 "ix86_match_ccmode (insn, CCNOmode)
8591 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8592 "test{w}\t{%1, %0|%0, %1}"
8593 [(set_attr "type" "test")
8594 (set_attr "modrm" "0,1,1")
8595 (set_attr "mode" "HI")
8596 (set_attr "pent_pair" "uv,np,uv")])
8598 (define_expand "testqi_ccz_1"
8599 [(set (reg:CCZ FLAGS_REG)
8600 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8601 (match_operand:QI 1 "nonmemory_operand" ""))
8606 (define_insn "*testqi_1_maybe_si"
8607 [(set (reg FLAGS_REG)
8610 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8611 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8613 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8614 && ix86_match_ccmode (insn,
8615 CONST_INT_P (operands[1])
8616 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8618 if (which_alternative == 3)
8620 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8621 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8622 return "test{l}\t{%1, %k0|%k0, %1}";
8624 return "test{b}\t{%1, %0|%0, %1}";
8626 [(set_attr "type" "test")
8627 (set_attr "modrm" "0,1,1,1")
8628 (set_attr "mode" "QI,QI,QI,SI")
8629 (set_attr "pent_pair" "uv,np,uv,np")])
8631 (define_insn "*testqi_1"
8632 [(set (reg FLAGS_REG)
8635 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8636 (match_operand:QI 1 "general_operand" "n,n,qn"))
8638 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8639 && ix86_match_ccmode (insn, CCNOmode)"
8640 "test{b}\t{%1, %0|%0, %1}"
8641 [(set_attr "type" "test")
8642 (set_attr "modrm" "0,1,1")
8643 (set_attr "mode" "QI")
8644 (set_attr "pent_pair" "uv,np,uv")])
8646 (define_expand "testqi_ext_ccno_0"
8647 [(set (reg:CCNO FLAGS_REG)
8651 (match_operand 0 "ext_register_operand" "")
8654 (match_operand 1 "const_int_operand" ""))
8659 (define_insn "*testqi_ext_0"
8660 [(set (reg FLAGS_REG)
8664 (match_operand 0 "ext_register_operand" "Q")
8667 (match_operand 1 "const_int_operand" "n"))
8669 "ix86_match_ccmode (insn, CCNOmode)"
8670 "test{b}\t{%1, %h0|%h0, %1}"
8671 [(set_attr "type" "test")
8672 (set_attr "mode" "QI")
8673 (set_attr "length_immediate" "1")
8674 (set_attr "pent_pair" "np")])
8676 (define_insn "*testqi_ext_1"
8677 [(set (reg FLAGS_REG)
8681 (match_operand 0 "ext_register_operand" "Q")
8685 (match_operand:QI 1 "general_operand" "Qm")))
8687 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8688 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8689 "test{b}\t{%1, %h0|%h0, %1}"
8690 [(set_attr "type" "test")
8691 (set_attr "mode" "QI")])
8693 (define_insn "*testqi_ext_1_rex64"
8694 [(set (reg FLAGS_REG)
8698 (match_operand 0 "ext_register_operand" "Q")
8702 (match_operand:QI 1 "register_operand" "Q")))
8704 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8705 "test{b}\t{%1, %h0|%h0, %1}"
8706 [(set_attr "type" "test")
8707 (set_attr "mode" "QI")])
8709 (define_insn "*testqi_ext_2"
8710 [(set (reg FLAGS_REG)
8714 (match_operand 0 "ext_register_operand" "Q")
8718 (match_operand 1 "ext_register_operand" "Q")
8722 "ix86_match_ccmode (insn, CCNOmode)"
8723 "test{b}\t{%h1, %h0|%h0, %h1}"
8724 [(set_attr "type" "test")
8725 (set_attr "mode" "QI")])
8727 ;; Combine likes to form bit extractions for some tests. Humor it.
8728 (define_insn "*testqi_ext_3"
8729 [(set (reg FLAGS_REG)
8730 (compare (zero_extract:SI
8731 (match_operand 0 "nonimmediate_operand" "rm")
8732 (match_operand:SI 1 "const_int_operand" "")
8733 (match_operand:SI 2 "const_int_operand" ""))
8735 "ix86_match_ccmode (insn, CCNOmode)
8736 && INTVAL (operands[1]) > 0
8737 && INTVAL (operands[2]) >= 0
8738 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8739 && (GET_MODE (operands[0]) == SImode
8740 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8741 || GET_MODE (operands[0]) == HImode
8742 || GET_MODE (operands[0]) == QImode)"
8745 (define_insn "*testqi_ext_3_rex64"
8746 [(set (reg FLAGS_REG)
8747 (compare (zero_extract:DI
8748 (match_operand 0 "nonimmediate_operand" "rm")
8749 (match_operand:DI 1 "const_int_operand" "")
8750 (match_operand:DI 2 "const_int_operand" ""))
8753 && ix86_match_ccmode (insn, CCNOmode)
8754 && INTVAL (operands[1]) > 0
8755 && INTVAL (operands[2]) >= 0
8756 /* Ensure that resulting mask is zero or sign extended operand. */
8757 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8758 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8759 && INTVAL (operands[1]) > 32))
8760 && (GET_MODE (operands[0]) == SImode
8761 || GET_MODE (operands[0]) == DImode
8762 || GET_MODE (operands[0]) == HImode
8763 || GET_MODE (operands[0]) == QImode)"
8767 [(set (match_operand 0 "flags_reg_operand" "")
8768 (match_operator 1 "compare_operator"
8770 (match_operand 2 "nonimmediate_operand" "")
8771 (match_operand 3 "const_int_operand" "")
8772 (match_operand 4 "const_int_operand" ""))
8774 "ix86_match_ccmode (insn, CCNOmode)"
8775 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8777 rtx val = operands[2];
8778 HOST_WIDE_INT len = INTVAL (operands[3]);
8779 HOST_WIDE_INT pos = INTVAL (operands[4]);
8781 enum machine_mode mode, submode;
8783 mode = GET_MODE (val);
8786 /* ??? Combine likes to put non-volatile mem extractions in QImode
8787 no matter the size of the test. So find a mode that works. */
8788 if (! MEM_VOLATILE_P (val))
8790 mode = smallest_mode_for_size (pos + len, MODE_INT);
8791 val = adjust_address (val, mode, 0);
8794 else if (GET_CODE (val) == SUBREG
8795 && (submode = GET_MODE (SUBREG_REG (val)),
8796 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8797 && pos + len <= GET_MODE_BITSIZE (submode))
8799 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8801 val = SUBREG_REG (val);
8803 else if (mode == HImode && pos + len <= 8)
8805 /* Small HImode tests can be converted to QImode. */
8807 val = gen_lowpart (QImode, val);
8810 if (len == HOST_BITS_PER_WIDE_INT)
8813 mask = ((HOST_WIDE_INT)1 << len) - 1;
8816 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8819 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8820 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8821 ;; this is relatively important trick.
8822 ;; Do the conversion only post-reload to avoid limiting of the register class
8825 [(set (match_operand 0 "flags_reg_operand" "")
8826 (match_operator 1 "compare_operator"
8827 [(and (match_operand 2 "register_operand" "")
8828 (match_operand 3 "const_int_operand" ""))
8831 && QI_REG_P (operands[2])
8832 && GET_MODE (operands[2]) != QImode
8833 && ((ix86_match_ccmode (insn, CCZmode)
8834 && !(INTVAL (operands[3]) & ~(255 << 8)))
8835 || (ix86_match_ccmode (insn, CCNOmode)
8836 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8839 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8842 "operands[2] = gen_lowpart (SImode, operands[2]);
8843 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8846 [(set (match_operand 0 "flags_reg_operand" "")
8847 (match_operator 1 "compare_operator"
8848 [(and (match_operand 2 "nonimmediate_operand" "")
8849 (match_operand 3 "const_int_operand" ""))
8852 && GET_MODE (operands[2]) != QImode
8853 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8854 && ((ix86_match_ccmode (insn, CCZmode)
8855 && !(INTVAL (operands[3]) & ~255))
8856 || (ix86_match_ccmode (insn, CCNOmode)
8857 && !(INTVAL (operands[3]) & ~127)))"
8859 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8861 "operands[2] = gen_lowpart (QImode, operands[2]);
8862 operands[3] = gen_lowpart (QImode, operands[3]);")
8865 ;; %%% This used to optimize known byte-wide and operations to memory,
8866 ;; and sometimes to QImode registers. If this is considered useful,
8867 ;; it should be done with splitters.
8869 (define_expand "anddi3"
8870 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8871 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8872 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8874 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8876 (define_insn "*anddi_1_rex64"
8877 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8878 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8879 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8880 (clobber (reg:CC FLAGS_REG))]
8881 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8883 switch (get_attr_type (insn))
8887 enum machine_mode mode;
8889 gcc_assert (CONST_INT_P (operands[2]));
8890 if (INTVAL (operands[2]) == 0xff)
8894 gcc_assert (INTVAL (operands[2]) == 0xffff);
8898 operands[1] = gen_lowpart (mode, operands[1]);
8900 return "movz{bq|x}\t{%1,%0|%0, %1}";
8902 return "movz{wq|x}\t{%1,%0|%0, %1}";
8906 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8907 if (get_attr_mode (insn) == MODE_SI)
8908 return "and{l}\t{%k2, %k0|%k0, %k2}";
8910 return "and{q}\t{%2, %0|%0, %2}";
8913 [(set_attr "type" "alu,alu,alu,imovx")
8914 (set_attr "length_immediate" "*,*,*,0")
8915 (set_attr "mode" "SI,DI,DI,DI")])
8917 (define_insn "*anddi_2"
8918 [(set (reg FLAGS_REG)
8919 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8920 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8922 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8923 (and:DI (match_dup 1) (match_dup 2)))]
8924 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8925 && ix86_binary_operator_ok (AND, DImode, operands)"
8927 and{l}\t{%k2, %k0|%k0, %k2}
8928 and{q}\t{%2, %0|%0, %2}
8929 and{q}\t{%2, %0|%0, %2}"
8930 [(set_attr "type" "alu")
8931 (set_attr "mode" "SI,DI,DI")])
8933 (define_expand "andsi3"
8934 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8935 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8936 (match_operand:SI 2 "general_operand" "")))]
8938 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8940 (define_insn "*andsi_1"
8941 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8942 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8943 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8944 (clobber (reg:CC FLAGS_REG))]
8945 "ix86_binary_operator_ok (AND, SImode, operands)"
8947 switch (get_attr_type (insn))
8951 enum machine_mode mode;
8953 gcc_assert (CONST_INT_P (operands[2]));
8954 if (INTVAL (operands[2]) == 0xff)
8958 gcc_assert (INTVAL (operands[2]) == 0xffff);
8962 operands[1] = gen_lowpart (mode, operands[1]);
8964 return "movz{bl|x}\t{%1,%0|%0, %1}";
8966 return "movz{wl|x}\t{%1,%0|%0, %1}";
8970 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8971 return "and{l}\t{%2, %0|%0, %2}";
8974 [(set_attr "type" "alu,alu,imovx")
8975 (set_attr "length_immediate" "*,*,0")
8976 (set_attr "mode" "SI")])
8979 [(set (match_operand 0 "register_operand" "")
8981 (const_int -65536)))
8982 (clobber (reg:CC FLAGS_REG))]
8983 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8984 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8985 "operands[1] = gen_lowpart (HImode, operands[0]);")
8988 [(set (match_operand 0 "ext_register_operand" "")
8991 (clobber (reg:CC FLAGS_REG))]
8992 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8993 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8994 "operands[1] = gen_lowpart (QImode, operands[0]);")
8997 [(set (match_operand 0 "ext_register_operand" "")
8999 (const_int -65281)))
9000 (clobber (reg:CC FLAGS_REG))]
9001 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9002 [(parallel [(set (zero_extract:SI (match_dup 0)
9006 (zero_extract:SI (match_dup 0)
9009 (zero_extract:SI (match_dup 0)
9012 (clobber (reg:CC FLAGS_REG))])]
9013 "operands[0] = gen_lowpart (SImode, operands[0]);")
9015 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9016 (define_insn "*andsi_1_zext"
9017 [(set (match_operand:DI 0 "register_operand" "=r")
9019 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9020 (match_operand:SI 2 "general_operand" "g"))))
9021 (clobber (reg:CC FLAGS_REG))]
9022 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9023 "and{l}\t{%2, %k0|%k0, %2}"
9024 [(set_attr "type" "alu")
9025 (set_attr "mode" "SI")])
9027 (define_insn "*andsi_2"
9028 [(set (reg FLAGS_REG)
9029 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9030 (match_operand:SI 2 "general_operand" "g,ri"))
9032 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9033 (and:SI (match_dup 1) (match_dup 2)))]
9034 "ix86_match_ccmode (insn, CCNOmode)
9035 && ix86_binary_operator_ok (AND, SImode, operands)"
9036 "and{l}\t{%2, %0|%0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "SI")])
9040 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9041 (define_insn "*andsi_2_zext"
9042 [(set (reg FLAGS_REG)
9043 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9044 (match_operand:SI 2 "general_operand" "g"))
9046 (set (match_operand:DI 0 "register_operand" "=r")
9047 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9048 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9049 && ix86_binary_operator_ok (AND, SImode, operands)"
9050 "and{l}\t{%2, %k0|%k0, %2}"
9051 [(set_attr "type" "alu")
9052 (set_attr "mode" "SI")])
9054 (define_expand "andhi3"
9055 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9056 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9057 (match_operand:HI 2 "general_operand" "")))]
9058 "TARGET_HIMODE_MATH"
9059 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9061 (define_insn "*andhi_1"
9062 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9063 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9064 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9065 (clobber (reg:CC FLAGS_REG))]
9066 "ix86_binary_operator_ok (AND, HImode, operands)"
9068 switch (get_attr_type (insn))
9071 gcc_assert (CONST_INT_P (operands[2]));
9072 gcc_assert (INTVAL (operands[2]) == 0xff);
9073 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9076 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9078 return "and{w}\t{%2, %0|%0, %2}";
9081 [(set_attr "type" "alu,alu,imovx")
9082 (set_attr "length_immediate" "*,*,0")
9083 (set_attr "mode" "HI,HI,SI")])
9085 (define_insn "*andhi_2"
9086 [(set (reg FLAGS_REG)
9087 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9088 (match_operand:HI 2 "general_operand" "rmn,rn"))
9090 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9091 (and:HI (match_dup 1) (match_dup 2)))]
9092 "ix86_match_ccmode (insn, CCNOmode)
9093 && ix86_binary_operator_ok (AND, HImode, operands)"
9094 "and{w}\t{%2, %0|%0, %2}"
9095 [(set_attr "type" "alu")
9096 (set_attr "mode" "HI")])
9098 (define_expand "andqi3"
9099 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9100 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9101 (match_operand:QI 2 "general_operand" "")))]
9102 "TARGET_QIMODE_MATH"
9103 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9105 ;; %%% Potential partial reg stall on alternative 2. What to do?
9106 (define_insn "*andqi_1"
9107 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9108 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9109 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9110 (clobber (reg:CC FLAGS_REG))]
9111 "ix86_binary_operator_ok (AND, QImode, operands)"
9113 and{b}\t{%2, %0|%0, %2}
9114 and{b}\t{%2, %0|%0, %2}
9115 and{l}\t{%k2, %k0|%k0, %k2}"
9116 [(set_attr "type" "alu")
9117 (set_attr "mode" "QI,QI,SI")])
9119 (define_insn "*andqi_1_slp"
9120 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9121 (and:QI (match_dup 0)
9122 (match_operand:QI 1 "general_operand" "qn,qmn")))
9123 (clobber (reg:CC FLAGS_REG))]
9124 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9125 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9126 "and{b}\t{%1, %0|%0, %1}"
9127 [(set_attr "type" "alu1")
9128 (set_attr "mode" "QI")])
9130 (define_insn "*andqi_2_maybe_si"
9131 [(set (reg FLAGS_REG)
9133 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9134 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9136 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9137 (and:QI (match_dup 1) (match_dup 2)))]
9138 "ix86_binary_operator_ok (AND, QImode, operands)
9139 && ix86_match_ccmode (insn,
9140 CONST_INT_P (operands[2])
9141 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9143 if (which_alternative == 2)
9145 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9146 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9147 return "and{l}\t{%2, %k0|%k0, %2}";
9149 return "and{b}\t{%2, %0|%0, %2}";
9151 [(set_attr "type" "alu")
9152 (set_attr "mode" "QI,QI,SI")])
9154 (define_insn "*andqi_2"
9155 [(set (reg FLAGS_REG)
9157 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9158 (match_operand:QI 2 "general_operand" "qmn,qn"))
9160 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9161 (and:QI (match_dup 1) (match_dup 2)))]
9162 "ix86_match_ccmode (insn, CCNOmode)
9163 && ix86_binary_operator_ok (AND, QImode, operands)"
9164 "and{b}\t{%2, %0|%0, %2}"
9165 [(set_attr "type" "alu")
9166 (set_attr "mode" "QI")])
9168 (define_insn "*andqi_2_slp"
9169 [(set (reg FLAGS_REG)
9171 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9172 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9174 (set (strict_low_part (match_dup 0))
9175 (and:QI (match_dup 0) (match_dup 1)))]
9176 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9177 && ix86_match_ccmode (insn, CCNOmode)
9178 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9179 "and{b}\t{%1, %0|%0, %1}"
9180 [(set_attr "type" "alu1")
9181 (set_attr "mode" "QI")])
9183 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9184 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9185 ;; for a QImode operand, which of course failed.
9187 (define_insn "andqi_ext_0"
9188 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9193 (match_operand 1 "ext_register_operand" "0")
9196 (match_operand 2 "const_int_operand" "n")))
9197 (clobber (reg:CC FLAGS_REG))]
9199 "and{b}\t{%2, %h0|%h0, %2}"
9200 [(set_attr "type" "alu")
9201 (set_attr "length_immediate" "1")
9202 (set_attr "mode" "QI")])
9204 ;; Generated by peephole translating test to and. This shows up
9205 ;; often in fp comparisons.
9207 (define_insn "*andqi_ext_0_cc"
9208 [(set (reg FLAGS_REG)
9212 (match_operand 1 "ext_register_operand" "0")
9215 (match_operand 2 "const_int_operand" "n"))
9217 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9226 "ix86_match_ccmode (insn, CCNOmode)"
9227 "and{b}\t{%2, %h0|%h0, %2}"
9228 [(set_attr "type" "alu")
9229 (set_attr "length_immediate" "1")
9230 (set_attr "mode" "QI")])
9232 (define_insn "*andqi_ext_1"
9233 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9238 (match_operand 1 "ext_register_operand" "0")
9242 (match_operand:QI 2 "general_operand" "Qm"))))
9243 (clobber (reg:CC FLAGS_REG))]
9245 "and{b}\t{%2, %h0|%h0, %2}"
9246 [(set_attr "type" "alu")
9247 (set_attr "length_immediate" "0")
9248 (set_attr "mode" "QI")])
9250 (define_insn "*andqi_ext_1_rex64"
9251 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9256 (match_operand 1 "ext_register_operand" "0")
9260 (match_operand 2 "ext_register_operand" "Q"))))
9261 (clobber (reg:CC FLAGS_REG))]
9263 "and{b}\t{%2, %h0|%h0, %2}"
9264 [(set_attr "type" "alu")
9265 (set_attr "length_immediate" "0")
9266 (set_attr "mode" "QI")])
9268 (define_insn "*andqi_ext_2"
9269 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9274 (match_operand 1 "ext_register_operand" "%0")
9278 (match_operand 2 "ext_register_operand" "Q")
9281 (clobber (reg:CC FLAGS_REG))]
9283 "and{b}\t{%h2, %h0|%h0, %h2}"
9284 [(set_attr "type" "alu")
9285 (set_attr "length_immediate" "0")
9286 (set_attr "mode" "QI")])
9288 ;; Convert wide AND instructions with immediate operand to shorter QImode
9289 ;; equivalents when possible.
9290 ;; Don't do the splitting with memory operands, since it introduces risk
9291 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9292 ;; for size, but that can (should?) be handled by generic code instead.
9294 [(set (match_operand 0 "register_operand" "")
9295 (and (match_operand 1 "register_operand" "")
9296 (match_operand 2 "const_int_operand" "")))
9297 (clobber (reg:CC FLAGS_REG))]
9299 && QI_REG_P (operands[0])
9300 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9301 && !(~INTVAL (operands[2]) & ~(255 << 8))
9302 && GET_MODE (operands[0]) != QImode"
9303 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9304 (and:SI (zero_extract:SI (match_dup 1)
9305 (const_int 8) (const_int 8))
9307 (clobber (reg:CC FLAGS_REG))])]
9308 "operands[0] = gen_lowpart (SImode, operands[0]);
9309 operands[1] = gen_lowpart (SImode, operands[1]);
9310 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9312 ;; Since AND can be encoded with sign extended immediate, this is only
9313 ;; profitable when 7th bit is not set.
9315 [(set (match_operand 0 "register_operand" "")
9316 (and (match_operand 1 "general_operand" "")
9317 (match_operand 2 "const_int_operand" "")))
9318 (clobber (reg:CC FLAGS_REG))]
9320 && ANY_QI_REG_P (operands[0])
9321 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9322 && !(~INTVAL (operands[2]) & ~255)
9323 && !(INTVAL (operands[2]) & 128)
9324 && GET_MODE (operands[0]) != QImode"
9325 [(parallel [(set (strict_low_part (match_dup 0))
9326 (and:QI (match_dup 1)
9328 (clobber (reg:CC FLAGS_REG))])]
9329 "operands[0] = gen_lowpart (QImode, operands[0]);
9330 operands[1] = gen_lowpart (QImode, operands[1]);
9331 operands[2] = gen_lowpart (QImode, operands[2]);")
9333 ;; Logical inclusive OR instructions
9335 ;; %%% This used to optimize known byte-wide and operations to memory.
9336 ;; If this is considered useful, it should be done with splitters.
9338 (define_expand "iordi3"
9339 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9340 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9341 (match_operand:DI 2 "x86_64_general_operand" "")))]
9343 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9345 (define_insn "*iordi_1_rex64"
9346 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9347 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9348 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9349 (clobber (reg:CC FLAGS_REG))]
9351 && ix86_binary_operator_ok (IOR, DImode, operands)"
9352 "or{q}\t{%2, %0|%0, %2}"
9353 [(set_attr "type" "alu")
9354 (set_attr "mode" "DI")])
9356 (define_insn "*iordi_2_rex64"
9357 [(set (reg FLAGS_REG)
9358 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9359 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9361 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9362 (ior:DI (match_dup 1) (match_dup 2)))]
9364 && ix86_match_ccmode (insn, CCNOmode)
9365 && ix86_binary_operator_ok (IOR, DImode, operands)"
9366 "or{q}\t{%2, %0|%0, %2}"
9367 [(set_attr "type" "alu")
9368 (set_attr "mode" "DI")])
9370 (define_insn "*iordi_3_rex64"
9371 [(set (reg FLAGS_REG)
9372 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9373 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9375 (clobber (match_scratch:DI 0 "=r"))]
9377 && ix86_match_ccmode (insn, CCNOmode)
9378 && ix86_binary_operator_ok (IOR, DImode, operands)"
9379 "or{q}\t{%2, %0|%0, %2}"
9380 [(set_attr "type" "alu")
9381 (set_attr "mode" "DI")])
9384 (define_expand "iorsi3"
9385 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9386 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9387 (match_operand:SI 2 "general_operand" "")))]
9389 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9391 (define_insn "*iorsi_1"
9392 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9393 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9394 (match_operand:SI 2 "general_operand" "ri,g")))
9395 (clobber (reg:CC FLAGS_REG))]
9396 "ix86_binary_operator_ok (IOR, SImode, operands)"
9397 "or{l}\t{%2, %0|%0, %2}"
9398 [(set_attr "type" "alu")
9399 (set_attr "mode" "SI")])
9401 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9402 (define_insn "*iorsi_1_zext"
9403 [(set (match_operand:DI 0 "register_operand" "=r")
9405 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9406 (match_operand:SI 2 "general_operand" "g"))))
9407 (clobber (reg:CC FLAGS_REG))]
9408 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9409 "or{l}\t{%2, %k0|%k0, %2}"
9410 [(set_attr "type" "alu")
9411 (set_attr "mode" "SI")])
9413 (define_insn "*iorsi_1_zext_imm"
9414 [(set (match_operand:DI 0 "register_operand" "=r")
9415 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9416 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9417 (clobber (reg:CC FLAGS_REG))]
9419 "or{l}\t{%2, %k0|%k0, %2}"
9420 [(set_attr "type" "alu")
9421 (set_attr "mode" "SI")])
9423 (define_insn "*iorsi_2"
9424 [(set (reg FLAGS_REG)
9425 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9426 (match_operand:SI 2 "general_operand" "g,ri"))
9428 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9429 (ior:SI (match_dup 1) (match_dup 2)))]
9430 "ix86_match_ccmode (insn, CCNOmode)
9431 && ix86_binary_operator_ok (IOR, SImode, operands)"
9432 "or{l}\t{%2, %0|%0, %2}"
9433 [(set_attr "type" "alu")
9434 (set_attr "mode" "SI")])
9436 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9437 ;; ??? Special case for immediate operand is missing - it is tricky.
9438 (define_insn "*iorsi_2_zext"
9439 [(set (reg FLAGS_REG)
9440 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9441 (match_operand:SI 2 "general_operand" "g"))
9443 (set (match_operand:DI 0 "register_operand" "=r")
9444 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9445 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9446 && ix86_binary_operator_ok (IOR, SImode, operands)"
9447 "or{l}\t{%2, %k0|%k0, %2}"
9448 [(set_attr "type" "alu")
9449 (set_attr "mode" "SI")])
9451 (define_insn "*iorsi_2_zext_imm"
9452 [(set (reg FLAGS_REG)
9453 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9454 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9456 (set (match_operand:DI 0 "register_operand" "=r")
9457 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9458 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9459 && ix86_binary_operator_ok (IOR, SImode, operands)"
9460 "or{l}\t{%2, %k0|%k0, %2}"
9461 [(set_attr "type" "alu")
9462 (set_attr "mode" "SI")])
9464 (define_insn "*iorsi_3"
9465 [(set (reg FLAGS_REG)
9466 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9467 (match_operand:SI 2 "general_operand" "g"))
9469 (clobber (match_scratch:SI 0 "=r"))]
9470 "ix86_match_ccmode (insn, CCNOmode)
9471 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9472 "or{l}\t{%2, %0|%0, %2}"
9473 [(set_attr "type" "alu")
9474 (set_attr "mode" "SI")])
9476 (define_expand "iorhi3"
9477 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9478 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9479 (match_operand:HI 2 "general_operand" "")))]
9480 "TARGET_HIMODE_MATH"
9481 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9483 (define_insn "*iorhi_1"
9484 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9485 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9486 (match_operand:HI 2 "general_operand" "rmn,rn")))
9487 (clobber (reg:CC FLAGS_REG))]
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_2"
9494 [(set (reg FLAGS_REG)
9495 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9496 (match_operand:HI 2 "general_operand" "rmn,rn"))
9498 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9499 (ior:HI (match_dup 1) (match_dup 2)))]
9500 "ix86_match_ccmode (insn, CCNOmode)
9501 && ix86_binary_operator_ok (IOR, HImode, operands)"
9502 "or{w}\t{%2, %0|%0, %2}"
9503 [(set_attr "type" "alu")
9504 (set_attr "mode" "HI")])
9506 (define_insn "*iorhi_3"
9507 [(set (reg FLAGS_REG)
9508 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9509 (match_operand:HI 2 "general_operand" "rmn"))
9511 (clobber (match_scratch:HI 0 "=r"))]
9512 "ix86_match_ccmode (insn, CCNOmode)
9513 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9514 "or{w}\t{%2, %0|%0, %2}"
9515 [(set_attr "type" "alu")
9516 (set_attr "mode" "HI")])
9518 (define_expand "iorqi3"
9519 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9520 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9521 (match_operand:QI 2 "general_operand" "")))]
9522 "TARGET_QIMODE_MATH"
9523 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9525 ;; %%% Potential partial reg stall on alternative 2. What to do?
9526 (define_insn "*iorqi_1"
9527 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9528 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9529 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9530 (clobber (reg:CC FLAGS_REG))]
9531 "ix86_binary_operator_ok (IOR, QImode, operands)"
9533 or{b}\t{%2, %0|%0, %2}
9534 or{b}\t{%2, %0|%0, %2}
9535 or{l}\t{%k2, %k0|%k0, %k2}"
9536 [(set_attr "type" "alu")
9537 (set_attr "mode" "QI,QI,SI")])
9539 (define_insn "*iorqi_1_slp"
9540 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9541 (ior:QI (match_dup 0)
9542 (match_operand:QI 1 "general_operand" "qmn,qn")))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9545 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9546 "or{b}\t{%1, %0|%0, %1}"
9547 [(set_attr "type" "alu1")
9548 (set_attr "mode" "QI")])
9550 (define_insn "*iorqi_2"
9551 [(set (reg FLAGS_REG)
9552 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9553 (match_operand:QI 2 "general_operand" "qmn,qn"))
9555 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9556 (ior:QI (match_dup 1) (match_dup 2)))]
9557 "ix86_match_ccmode (insn, CCNOmode)
9558 && ix86_binary_operator_ok (IOR, QImode, operands)"
9559 "or{b}\t{%2, %0|%0, %2}"
9560 [(set_attr "type" "alu")
9561 (set_attr "mode" "QI")])
9563 (define_insn "*iorqi_2_slp"
9564 [(set (reg FLAGS_REG)
9565 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9566 (match_operand:QI 1 "general_operand" "qmn,qn"))
9568 (set (strict_low_part (match_dup 0))
9569 (ior:QI (match_dup 0) (match_dup 1)))]
9570 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9571 && ix86_match_ccmode (insn, CCNOmode)
9572 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9573 "or{b}\t{%1, %0|%0, %1}"
9574 [(set_attr "type" "alu1")
9575 (set_attr "mode" "QI")])
9577 (define_insn "*iorqi_3"
9578 [(set (reg FLAGS_REG)
9579 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9580 (match_operand:QI 2 "general_operand" "qmn"))
9582 (clobber (match_scratch:QI 0 "=q"))]
9583 "ix86_match_ccmode (insn, CCNOmode)
9584 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9585 "or{b}\t{%2, %0|%0, %2}"
9586 [(set_attr "type" "alu")
9587 (set_attr "mode" "QI")])
9589 (define_insn "iorqi_ext_0"
9590 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9595 (match_operand 1 "ext_register_operand" "0")
9598 (match_operand 2 "const_int_operand" "n")))
9599 (clobber (reg:CC FLAGS_REG))]
9600 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9601 "or{b}\t{%2, %h0|%h0, %2}"
9602 [(set_attr "type" "alu")
9603 (set_attr "length_immediate" "1")
9604 (set_attr "mode" "QI")])
9606 (define_insn "*iorqi_ext_1"
9607 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9612 (match_operand 1 "ext_register_operand" "0")
9616 (match_operand:QI 2 "general_operand" "Qm"))))
9617 (clobber (reg:CC FLAGS_REG))]
9619 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9620 "or{b}\t{%2, %h0|%h0, %2}"
9621 [(set_attr "type" "alu")
9622 (set_attr "length_immediate" "0")
9623 (set_attr "mode" "QI")])
9625 (define_insn "*iorqi_ext_1_rex64"
9626 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9631 (match_operand 1 "ext_register_operand" "0")
9635 (match_operand 2 "ext_register_operand" "Q"))))
9636 (clobber (reg:CC FLAGS_REG))]
9638 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9639 "or{b}\t{%2, %h0|%h0, %2}"
9640 [(set_attr "type" "alu")
9641 (set_attr "length_immediate" "0")
9642 (set_attr "mode" "QI")])
9644 (define_insn "*iorqi_ext_2"
9645 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9649 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9652 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9655 (clobber (reg:CC FLAGS_REG))]
9656 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9657 "ior{b}\t{%h2, %h0|%h0, %h2}"
9658 [(set_attr "type" "alu")
9659 (set_attr "length_immediate" "0")
9660 (set_attr "mode" "QI")])
9663 [(set (match_operand 0 "register_operand" "")
9664 (ior (match_operand 1 "register_operand" "")
9665 (match_operand 2 "const_int_operand" "")))
9666 (clobber (reg:CC FLAGS_REG))]
9668 && QI_REG_P (operands[0])
9669 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9670 && !(INTVAL (operands[2]) & ~(255 << 8))
9671 && GET_MODE (operands[0]) != QImode"
9672 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9673 (ior:SI (zero_extract:SI (match_dup 1)
9674 (const_int 8) (const_int 8))
9676 (clobber (reg:CC FLAGS_REG))])]
9677 "operands[0] = gen_lowpart (SImode, operands[0]);
9678 operands[1] = gen_lowpart (SImode, operands[1]);
9679 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9681 ;; Since OR can be encoded with sign extended immediate, this is only
9682 ;; profitable when 7th bit is set.
9684 [(set (match_operand 0 "register_operand" "")
9685 (ior (match_operand 1 "general_operand" "")
9686 (match_operand 2 "const_int_operand" "")))
9687 (clobber (reg:CC FLAGS_REG))]
9689 && ANY_QI_REG_P (operands[0])
9690 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9691 && !(INTVAL (operands[2]) & ~255)
9692 && (INTVAL (operands[2]) & 128)
9693 && GET_MODE (operands[0]) != QImode"
9694 [(parallel [(set (strict_low_part (match_dup 0))
9695 (ior:QI (match_dup 1)
9697 (clobber (reg:CC FLAGS_REG))])]
9698 "operands[0] = gen_lowpart (QImode, operands[0]);
9699 operands[1] = gen_lowpart (QImode, operands[1]);
9700 operands[2] = gen_lowpart (QImode, operands[2]);")
9702 ;; Logical XOR instructions
9704 ;; %%% This used to optimize known byte-wide and operations to memory.
9705 ;; If this is considered useful, it should be done with splitters.
9707 (define_expand "xordi3"
9708 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9709 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9710 (match_operand:DI 2 "x86_64_general_operand" "")))]
9712 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9714 (define_insn "*xordi_1_rex64"
9715 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9716 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9717 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9718 (clobber (reg:CC FLAGS_REG))]
9720 && ix86_binary_operator_ok (XOR, DImode, operands)"
9721 "xor{q}\t{%2, %0|%0, %2}"
9722 [(set_attr "type" "alu")
9723 (set_attr "mode" "DI")])
9725 (define_insn "*xordi_2_rex64"
9726 [(set (reg FLAGS_REG)
9727 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9728 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9730 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9731 (xor:DI (match_dup 1) (match_dup 2)))]
9733 && ix86_match_ccmode (insn, CCNOmode)
9734 && ix86_binary_operator_ok (XOR, DImode, operands)"
9735 "xor{q}\t{%2, %0|%0, %2}"
9736 [(set_attr "type" "alu")
9737 (set_attr "mode" "DI")])
9739 (define_insn "*xordi_3_rex64"
9740 [(set (reg FLAGS_REG)
9741 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9742 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9744 (clobber (match_scratch:DI 0 "=r"))]
9746 && ix86_match_ccmode (insn, CCNOmode)
9747 && ix86_binary_operator_ok (XOR, DImode, operands)"
9748 "xor{q}\t{%2, %0|%0, %2}"
9749 [(set_attr "type" "alu")
9750 (set_attr "mode" "DI")])
9752 (define_expand "xorsi3"
9753 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9754 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9755 (match_operand:SI 2 "general_operand" "")))]
9757 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9759 (define_insn "*xorsi_1"
9760 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9761 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9762 (match_operand:SI 2 "general_operand" "ri,rm")))
9763 (clobber (reg:CC FLAGS_REG))]
9764 "ix86_binary_operator_ok (XOR, SImode, operands)"
9765 "xor{l}\t{%2, %0|%0, %2}"
9766 [(set_attr "type" "alu")
9767 (set_attr "mode" "SI")])
9769 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9770 ;; Add speccase for immediates
9771 (define_insn "*xorsi_1_zext"
9772 [(set (match_operand:DI 0 "register_operand" "=r")
9774 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9775 (match_operand:SI 2 "general_operand" "g"))))
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_1_zext_imm"
9783 [(set (match_operand:DI 0 "register_operand" "=r")
9784 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9785 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9788 "xor{l}\t{%2, %k0|%k0, %2}"
9789 [(set_attr "type" "alu")
9790 (set_attr "mode" "SI")])
9792 (define_insn "*xorsi_2"
9793 [(set (reg FLAGS_REG)
9794 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9795 (match_operand:SI 2 "general_operand" "g,ri"))
9797 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9798 (xor:SI (match_dup 1) (match_dup 2)))]
9799 "ix86_match_ccmode (insn, CCNOmode)
9800 && ix86_binary_operator_ok (XOR, SImode, operands)"
9801 "xor{l}\t{%2, %0|%0, %2}"
9802 [(set_attr "type" "alu")
9803 (set_attr "mode" "SI")])
9805 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9806 ;; ??? Special case for immediate operand is missing - it is tricky.
9807 (define_insn "*xorsi_2_zext"
9808 [(set (reg FLAGS_REG)
9809 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9810 (match_operand:SI 2 "general_operand" "g"))
9812 (set (match_operand:DI 0 "register_operand" "=r")
9813 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9814 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9815 && ix86_binary_operator_ok (XOR, SImode, operands)"
9816 "xor{l}\t{%2, %k0|%k0, %2}"
9817 [(set_attr "type" "alu")
9818 (set_attr "mode" "SI")])
9820 (define_insn "*xorsi_2_zext_imm"
9821 [(set (reg FLAGS_REG)
9822 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9823 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9825 (set (match_operand:DI 0 "register_operand" "=r")
9826 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9827 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9828 && ix86_binary_operator_ok (XOR, SImode, operands)"
9829 "xor{l}\t{%2, %k0|%k0, %2}"
9830 [(set_attr "type" "alu")
9831 (set_attr "mode" "SI")])
9833 (define_insn "*xorsi_3"
9834 [(set (reg FLAGS_REG)
9835 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9836 (match_operand:SI 2 "general_operand" "g"))
9838 (clobber (match_scratch:SI 0 "=r"))]
9839 "ix86_match_ccmode (insn, CCNOmode)
9840 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9841 "xor{l}\t{%2, %0|%0, %2}"
9842 [(set_attr "type" "alu")
9843 (set_attr "mode" "SI")])
9845 (define_expand "xorhi3"
9846 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9847 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9848 (match_operand:HI 2 "general_operand" "")))]
9849 "TARGET_HIMODE_MATH"
9850 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9852 (define_insn "*xorhi_1"
9853 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9854 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9855 (match_operand:HI 2 "general_operand" "rmn,rn")))
9856 (clobber (reg:CC FLAGS_REG))]
9857 "ix86_binary_operator_ok (XOR, HImode, operands)"
9858 "xor{w}\t{%2, %0|%0, %2}"
9859 [(set_attr "type" "alu")
9860 (set_attr "mode" "HI")])
9862 (define_insn "*xorhi_2"
9863 [(set (reg FLAGS_REG)
9864 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9865 (match_operand:HI 2 "general_operand" "rmn,rn"))
9867 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9868 (xor:HI (match_dup 1) (match_dup 2)))]
9869 "ix86_match_ccmode (insn, CCNOmode)
9870 && ix86_binary_operator_ok (XOR, HImode, operands)"
9871 "xor{w}\t{%2, %0|%0, %2}"
9872 [(set_attr "type" "alu")
9873 (set_attr "mode" "HI")])
9875 (define_insn "*xorhi_3"
9876 [(set (reg FLAGS_REG)
9877 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9878 (match_operand:HI 2 "general_operand" "rmn"))
9880 (clobber (match_scratch:HI 0 "=r"))]
9881 "ix86_match_ccmode (insn, CCNOmode)
9882 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9883 "xor{w}\t{%2, %0|%0, %2}"
9884 [(set_attr "type" "alu")
9885 (set_attr "mode" "HI")])
9887 (define_expand "xorqi3"
9888 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9889 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9890 (match_operand:QI 2 "general_operand" "")))]
9891 "TARGET_QIMODE_MATH"
9892 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9894 ;; %%% Potential partial reg stall on alternative 2. What to do?
9895 (define_insn "*xorqi_1"
9896 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9897 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9898 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9899 (clobber (reg:CC FLAGS_REG))]
9900 "ix86_binary_operator_ok (XOR, QImode, operands)"
9902 xor{b}\t{%2, %0|%0, %2}
9903 xor{b}\t{%2, %0|%0, %2}
9904 xor{l}\t{%k2, %k0|%k0, %k2}"
9905 [(set_attr "type" "alu")
9906 (set_attr "mode" "QI,QI,SI")])
9908 (define_insn "*xorqi_1_slp"
9909 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9910 (xor:QI (match_dup 0)
9911 (match_operand:QI 1 "general_operand" "qn,qmn")))
9912 (clobber (reg:CC FLAGS_REG))]
9913 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9914 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9915 "xor{b}\t{%1, %0|%0, %1}"
9916 [(set_attr "type" "alu1")
9917 (set_attr "mode" "QI")])
9919 (define_insn "xorqi_ext_0"
9920 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9925 (match_operand 1 "ext_register_operand" "0")
9928 (match_operand 2 "const_int_operand" "n")))
9929 (clobber (reg:CC FLAGS_REG))]
9930 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9931 "xor{b}\t{%2, %h0|%h0, %2}"
9932 [(set_attr "type" "alu")
9933 (set_attr "length_immediate" "1")
9934 (set_attr "mode" "QI")])
9936 (define_insn "*xorqi_ext_1"
9937 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9942 (match_operand 1 "ext_register_operand" "0")
9946 (match_operand:QI 2 "general_operand" "Qm"))))
9947 (clobber (reg:CC FLAGS_REG))]
9949 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9950 "xor{b}\t{%2, %h0|%h0, %2}"
9951 [(set_attr "type" "alu")
9952 (set_attr "length_immediate" "0")
9953 (set_attr "mode" "QI")])
9955 (define_insn "*xorqi_ext_1_rex64"
9956 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9961 (match_operand 1 "ext_register_operand" "0")
9965 (match_operand 2 "ext_register_operand" "Q"))))
9966 (clobber (reg:CC FLAGS_REG))]
9968 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9969 "xor{b}\t{%2, %h0|%h0, %2}"
9970 [(set_attr "type" "alu")
9971 (set_attr "length_immediate" "0")
9972 (set_attr "mode" "QI")])
9974 (define_insn "*xorqi_ext_2"
9975 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9979 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9982 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9985 (clobber (reg:CC FLAGS_REG))]
9986 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9987 "xor{b}\t{%h2, %h0|%h0, %h2}"
9988 [(set_attr "type" "alu")
9989 (set_attr "length_immediate" "0")
9990 (set_attr "mode" "QI")])
9992 (define_insn "*xorqi_cc_1"
9993 [(set (reg FLAGS_REG)
9995 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9996 (match_operand:QI 2 "general_operand" "qmn,qn"))
9998 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9999 (xor:QI (match_dup 1) (match_dup 2)))]
10000 "ix86_match_ccmode (insn, CCNOmode)
10001 && ix86_binary_operator_ok (XOR, QImode, operands)"
10002 "xor{b}\t{%2, %0|%0, %2}"
10003 [(set_attr "type" "alu")
10004 (set_attr "mode" "QI")])
10006 (define_insn "*xorqi_2_slp"
10007 [(set (reg FLAGS_REG)
10008 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10009 (match_operand:QI 1 "general_operand" "qmn,qn"))
10011 (set (strict_low_part (match_dup 0))
10012 (xor:QI (match_dup 0) (match_dup 1)))]
10013 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10014 && ix86_match_ccmode (insn, CCNOmode)
10015 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10016 "xor{b}\t{%1, %0|%0, %1}"
10017 [(set_attr "type" "alu1")
10018 (set_attr "mode" "QI")])
10020 (define_insn "*xorqi_cc_2"
10021 [(set (reg FLAGS_REG)
10023 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10024 (match_operand:QI 2 "general_operand" "qmn"))
10026 (clobber (match_scratch:QI 0 "=q"))]
10027 "ix86_match_ccmode (insn, CCNOmode)
10028 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10029 "xor{b}\t{%2, %0|%0, %2}"
10030 [(set_attr "type" "alu")
10031 (set_attr "mode" "QI")])
10033 (define_insn "*xorqi_cc_ext_1"
10034 [(set (reg FLAGS_REG)
10038 (match_operand 1 "ext_register_operand" "0")
10041 (match_operand:QI 2 "general_operand" "qmn"))
10043 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10047 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10049 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10050 "xor{b}\t{%2, %h0|%h0, %2}"
10051 [(set_attr "type" "alu")
10052 (set_attr "mode" "QI")])
10054 (define_insn "*xorqi_cc_ext_1_rex64"
10055 [(set (reg FLAGS_REG)
10059 (match_operand 1 "ext_register_operand" "0")
10062 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10064 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10068 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10070 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10071 "xor{b}\t{%2, %h0|%h0, %2}"
10072 [(set_attr "type" "alu")
10073 (set_attr "mode" "QI")])
10075 (define_expand "xorqi_cc_ext_1"
10077 (set (reg:CCNO FLAGS_REG)
10081 (match_operand 1 "ext_register_operand" "")
10084 (match_operand:QI 2 "general_operand" ""))
10086 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10090 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10096 [(set (match_operand 0 "register_operand" "")
10097 (xor (match_operand 1 "register_operand" "")
10098 (match_operand 2 "const_int_operand" "")))
10099 (clobber (reg:CC FLAGS_REG))]
10101 && QI_REG_P (operands[0])
10102 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10103 && !(INTVAL (operands[2]) & ~(255 << 8))
10104 && GET_MODE (operands[0]) != QImode"
10105 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10106 (xor:SI (zero_extract:SI (match_dup 1)
10107 (const_int 8) (const_int 8))
10109 (clobber (reg:CC FLAGS_REG))])]
10110 "operands[0] = gen_lowpart (SImode, operands[0]);
10111 operands[1] = gen_lowpart (SImode, operands[1]);
10112 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10114 ;; Since XOR can be encoded with sign extended immediate, this is only
10115 ;; profitable when 7th bit is set.
10117 [(set (match_operand 0 "register_operand" "")
10118 (xor (match_operand 1 "general_operand" "")
10119 (match_operand 2 "const_int_operand" "")))
10120 (clobber (reg:CC FLAGS_REG))]
10122 && ANY_QI_REG_P (operands[0])
10123 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10124 && !(INTVAL (operands[2]) & ~255)
10125 && (INTVAL (operands[2]) & 128)
10126 && GET_MODE (operands[0]) != QImode"
10127 [(parallel [(set (strict_low_part (match_dup 0))
10128 (xor:QI (match_dup 1)
10130 (clobber (reg:CC FLAGS_REG))])]
10131 "operands[0] = gen_lowpart (QImode, operands[0]);
10132 operands[1] = gen_lowpart (QImode, operands[1]);
10133 operands[2] = gen_lowpart (QImode, operands[2]);")
10135 ;; Negation instructions
10137 (define_expand "negti2"
10138 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10139 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10141 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10143 (define_insn "*negti2_1"
10144 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10145 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10146 (clobber (reg:CC FLAGS_REG))]
10148 && ix86_unary_operator_ok (NEG, TImode, operands)"
10152 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10153 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10154 (clobber (reg:CC FLAGS_REG))]
10155 "TARGET_64BIT && reload_completed"
10157 [(set (reg:CCZ FLAGS_REG)
10158 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10159 (set (match_dup 0) (neg:DI (match_dup 1)))])
10161 [(set (match_dup 2)
10162 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10165 (clobber (reg:CC FLAGS_REG))])
10167 [(set (match_dup 2)
10168 (neg:DI (match_dup 2)))
10169 (clobber (reg:CC FLAGS_REG))])]
10170 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10172 (define_expand "negdi2"
10173 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10174 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10176 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10178 (define_insn "*negdi2_1"
10179 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10180 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10181 (clobber (reg:CC FLAGS_REG))]
10183 && ix86_unary_operator_ok (NEG, DImode, operands)"
10187 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10188 (neg:DI (match_operand:DI 1 "general_operand" "")))
10189 (clobber (reg:CC FLAGS_REG))]
10190 "!TARGET_64BIT && reload_completed"
10192 [(set (reg:CCZ FLAGS_REG)
10193 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10194 (set (match_dup 0) (neg:SI (match_dup 1)))])
10196 [(set (match_dup 2)
10197 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10200 (clobber (reg:CC FLAGS_REG))])
10202 [(set (match_dup 2)
10203 (neg:SI (match_dup 2)))
10204 (clobber (reg:CC FLAGS_REG))])]
10205 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10207 (define_insn "*negdi2_1_rex64"
10208 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10209 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10210 (clobber (reg:CC FLAGS_REG))]
10211 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10213 [(set_attr "type" "negnot")
10214 (set_attr "mode" "DI")])
10216 ;; The problem with neg is that it does not perform (compare x 0),
10217 ;; it really performs (compare 0 x), which leaves us with the zero
10218 ;; flag being the only useful item.
10220 (define_insn "*negdi2_cmpz_rex64"
10221 [(set (reg:CCZ FLAGS_REG)
10222 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10224 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10225 (neg:DI (match_dup 1)))]
10226 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10228 [(set_attr "type" "negnot")
10229 (set_attr "mode" "DI")])
10232 (define_expand "negsi2"
10233 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10234 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10236 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10238 (define_insn "*negsi2_1"
10239 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10240 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10241 (clobber (reg:CC FLAGS_REG))]
10242 "ix86_unary_operator_ok (NEG, SImode, operands)"
10244 [(set_attr "type" "negnot")
10245 (set_attr "mode" "SI")])
10247 ;; Combine is quite creative about this pattern.
10248 (define_insn "*negsi2_1_zext"
10249 [(set (match_operand:DI 0 "register_operand" "=r")
10250 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10253 (clobber (reg:CC FLAGS_REG))]
10254 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10256 [(set_attr "type" "negnot")
10257 (set_attr "mode" "SI")])
10259 ;; The problem with neg is that it does not perform (compare x 0),
10260 ;; it really performs (compare 0 x), which leaves us with the zero
10261 ;; flag being the only useful item.
10263 (define_insn "*negsi2_cmpz"
10264 [(set (reg:CCZ FLAGS_REG)
10265 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10267 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10268 (neg:SI (match_dup 1)))]
10269 "ix86_unary_operator_ok (NEG, SImode, operands)"
10271 [(set_attr "type" "negnot")
10272 (set_attr "mode" "SI")])
10274 (define_insn "*negsi2_cmpz_zext"
10275 [(set (reg:CCZ FLAGS_REG)
10276 (compare:CCZ (lshiftrt:DI
10278 (match_operand:DI 1 "register_operand" "0")
10282 (set (match_operand:DI 0 "register_operand" "=r")
10283 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10286 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10288 [(set_attr "type" "negnot")
10289 (set_attr "mode" "SI")])
10291 (define_expand "neghi2"
10292 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10293 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10294 "TARGET_HIMODE_MATH"
10295 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10297 (define_insn "*neghi2_1"
10298 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10299 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "ix86_unary_operator_ok (NEG, HImode, operands)"
10303 [(set_attr "type" "negnot")
10304 (set_attr "mode" "HI")])
10306 (define_insn "*neghi2_cmpz"
10307 [(set (reg:CCZ FLAGS_REG)
10308 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10310 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10311 (neg:HI (match_dup 1)))]
10312 "ix86_unary_operator_ok (NEG, HImode, operands)"
10314 [(set_attr "type" "negnot")
10315 (set_attr "mode" "HI")])
10317 (define_expand "negqi2"
10318 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10319 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10320 "TARGET_QIMODE_MATH"
10321 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10323 (define_insn "*negqi2_1"
10324 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10325 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10326 (clobber (reg:CC FLAGS_REG))]
10327 "ix86_unary_operator_ok (NEG, QImode, operands)"
10329 [(set_attr "type" "negnot")
10330 (set_attr "mode" "QI")])
10332 (define_insn "*negqi2_cmpz"
10333 [(set (reg:CCZ FLAGS_REG)
10334 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10336 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10337 (neg:QI (match_dup 1)))]
10338 "ix86_unary_operator_ok (NEG, QImode, operands)"
10340 [(set_attr "type" "negnot")
10341 (set_attr "mode" "QI")])
10343 ;; Changing of sign for FP values is doable using integer unit too.
10345 (define_expand "<code><mode>2"
10346 [(set (match_operand:X87MODEF 0 "register_operand" "")
10347 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10348 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10349 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10351 (define_insn "*absneg<mode>2_mixed"
10352 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10353 (match_operator:MODEF 3 "absneg_operator"
10354 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10355 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10356 (clobber (reg:CC FLAGS_REG))]
10357 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10360 (define_insn "*absneg<mode>2_sse"
10361 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10362 (match_operator:MODEF 3 "absneg_operator"
10363 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10364 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10369 (define_insn "*absneg<mode>2_i387"
10370 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10371 (match_operator:X87MODEF 3 "absneg_operator"
10372 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10373 (use (match_operand 2 "" ""))
10374 (clobber (reg:CC FLAGS_REG))]
10375 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10378 (define_expand "<code>tf2"
10379 [(set (match_operand:TF 0 "register_operand" "")
10380 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10382 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10384 (define_insn "*absnegtf2_sse"
10385 [(set (match_operand:TF 0 "register_operand" "=x,x")
10386 (match_operator:TF 3 "absneg_operator"
10387 [(match_operand:TF 1 "register_operand" "0,x")]))
10388 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10389 (clobber (reg:CC FLAGS_REG))]
10393 ;; Splitters for fp abs and neg.
10396 [(set (match_operand 0 "fp_register_operand" "")
10397 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10398 (use (match_operand 2 "" ""))
10399 (clobber (reg:CC FLAGS_REG))]
10401 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10404 [(set (match_operand 0 "register_operand" "")
10405 (match_operator 3 "absneg_operator"
10406 [(match_operand 1 "register_operand" "")]))
10407 (use (match_operand 2 "nonimmediate_operand" ""))
10408 (clobber (reg:CC FLAGS_REG))]
10409 "reload_completed && SSE_REG_P (operands[0])"
10410 [(set (match_dup 0) (match_dup 3))]
10412 enum machine_mode mode = GET_MODE (operands[0]);
10413 enum machine_mode vmode = GET_MODE (operands[2]);
10416 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10417 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10418 if (operands_match_p (operands[0], operands[2]))
10421 operands[1] = operands[2];
10424 if (GET_CODE (operands[3]) == ABS)
10425 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10427 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10432 [(set (match_operand:SF 0 "register_operand" "")
10433 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10434 (use (match_operand:V4SF 2 "" ""))
10435 (clobber (reg:CC FLAGS_REG))]
10437 [(parallel [(set (match_dup 0) (match_dup 1))
10438 (clobber (reg:CC FLAGS_REG))])]
10441 operands[0] = gen_lowpart (SImode, operands[0]);
10442 if (GET_CODE (operands[1]) == ABS)
10444 tmp = gen_int_mode (0x7fffffff, SImode);
10445 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10449 tmp = gen_int_mode (0x80000000, SImode);
10450 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10456 [(set (match_operand:DF 0 "register_operand" "")
10457 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10458 (use (match_operand 2 "" ""))
10459 (clobber (reg:CC FLAGS_REG))]
10461 [(parallel [(set (match_dup 0) (match_dup 1))
10462 (clobber (reg:CC FLAGS_REG))])]
10467 tmp = gen_lowpart (DImode, operands[0]);
10468 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10471 if (GET_CODE (operands[1]) == ABS)
10474 tmp = gen_rtx_NOT (DImode, tmp);
10478 operands[0] = gen_highpart (SImode, operands[0]);
10479 if (GET_CODE (operands[1]) == ABS)
10481 tmp = gen_int_mode (0x7fffffff, SImode);
10482 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10486 tmp = gen_int_mode (0x80000000, SImode);
10487 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10494 [(set (match_operand:XF 0 "register_operand" "")
10495 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10496 (use (match_operand 2 "" ""))
10497 (clobber (reg:CC FLAGS_REG))]
10499 [(parallel [(set (match_dup 0) (match_dup 1))
10500 (clobber (reg:CC FLAGS_REG))])]
10503 operands[0] = gen_rtx_REG (SImode,
10504 true_regnum (operands[0])
10505 + (TARGET_64BIT ? 1 : 2));
10506 if (GET_CODE (operands[1]) == ABS)
10508 tmp = GEN_INT (0x7fff);
10509 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10513 tmp = GEN_INT (0x8000);
10514 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10519 ;; Conditionalize these after reload. If they match before reload, we
10520 ;; lose the clobber and ability to use integer instructions.
10522 (define_insn "*<code><mode>2_1"
10523 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10524 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10526 && (reload_completed
10527 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10529 [(set_attr "type" "fsgn")
10530 (set_attr "mode" "<MODE>")])
10532 (define_insn "*<code>extendsfdf2"
10533 [(set (match_operand:DF 0 "register_operand" "=f")
10534 (absneg:DF (float_extend:DF
10535 (match_operand:SF 1 "register_operand" "0"))))]
10536 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10538 [(set_attr "type" "fsgn")
10539 (set_attr "mode" "DF")])
10541 (define_insn "*<code>extendsfxf2"
10542 [(set (match_operand:XF 0 "register_operand" "=f")
10543 (absneg:XF (float_extend:XF
10544 (match_operand:SF 1 "register_operand" "0"))))]
10547 [(set_attr "type" "fsgn")
10548 (set_attr "mode" "XF")])
10550 (define_insn "*<code>extenddfxf2"
10551 [(set (match_operand:XF 0 "register_operand" "=f")
10552 (absneg:XF (float_extend:XF
10553 (match_operand:DF 1 "register_operand" "0"))))]
10556 [(set_attr "type" "fsgn")
10557 (set_attr "mode" "XF")])
10559 ;; Copysign instructions
10561 (define_mode_iterator CSGNMODE [SF DF TF])
10562 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10564 (define_expand "copysign<mode>3"
10565 [(match_operand:CSGNMODE 0 "register_operand" "")
10566 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10567 (match_operand:CSGNMODE 2 "register_operand" "")]
10568 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10569 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10571 ix86_expand_copysign (operands);
10575 (define_insn_and_split "copysign<mode>3_const"
10576 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10578 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10579 (match_operand:CSGNMODE 2 "register_operand" "0")
10580 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10582 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10583 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10585 "&& reload_completed"
10588 ix86_split_copysign_const (operands);
10592 (define_insn "copysign<mode>3_var"
10593 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10595 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10596 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10597 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10598 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10600 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10601 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10602 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10606 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10608 [(match_operand:CSGNMODE 2 "register_operand" "")
10609 (match_operand:CSGNMODE 3 "register_operand" "")
10610 (match_operand:<CSGNVMODE> 4 "" "")
10611 (match_operand:<CSGNVMODE> 5 "" "")]
10613 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10614 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10615 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10616 && reload_completed"
10619 ix86_split_copysign_var (operands);
10623 ;; One complement instructions
10625 (define_expand "one_cmpldi2"
10626 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10627 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10629 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10631 (define_insn "*one_cmpldi2_1_rex64"
10632 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10633 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10634 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10636 [(set_attr "type" "negnot")
10637 (set_attr "mode" "DI")])
10639 (define_insn "*one_cmpldi2_2_rex64"
10640 [(set (reg FLAGS_REG)
10641 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10643 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10644 (not:DI (match_dup 1)))]
10645 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10646 && ix86_unary_operator_ok (NOT, DImode, operands)"
10648 [(set_attr "type" "alu1")
10649 (set_attr "mode" "DI")])
10652 [(set (match_operand 0 "flags_reg_operand" "")
10653 (match_operator 2 "compare_operator"
10654 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10656 (set (match_operand:DI 1 "nonimmediate_operand" "")
10657 (not:DI (match_dup 3)))]
10658 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10659 [(parallel [(set (match_dup 0)
10661 [(xor:DI (match_dup 3) (const_int -1))
10664 (xor:DI (match_dup 3) (const_int -1)))])]
10667 (define_expand "one_cmplsi2"
10668 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10669 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10671 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10673 (define_insn "*one_cmplsi2_1"
10674 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10675 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10676 "ix86_unary_operator_ok (NOT, SImode, operands)"
10678 [(set_attr "type" "negnot")
10679 (set_attr "mode" "SI")])
10681 ;; ??? Currently never generated - xor is used instead.
10682 (define_insn "*one_cmplsi2_1_zext"
10683 [(set (match_operand:DI 0 "register_operand" "=r")
10684 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10685 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10687 [(set_attr "type" "negnot")
10688 (set_attr "mode" "SI")])
10690 (define_insn "*one_cmplsi2_2"
10691 [(set (reg FLAGS_REG)
10692 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10694 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10695 (not:SI (match_dup 1)))]
10696 "ix86_match_ccmode (insn, CCNOmode)
10697 && ix86_unary_operator_ok (NOT, SImode, operands)"
10699 [(set_attr "type" "alu1")
10700 (set_attr "mode" "SI")])
10703 [(set (match_operand 0 "flags_reg_operand" "")
10704 (match_operator 2 "compare_operator"
10705 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10707 (set (match_operand:SI 1 "nonimmediate_operand" "")
10708 (not:SI (match_dup 3)))]
10709 "ix86_match_ccmode (insn, CCNOmode)"
10710 [(parallel [(set (match_dup 0)
10711 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10714 (xor:SI (match_dup 3) (const_int -1)))])]
10717 ;; ??? Currently never generated - xor is used instead.
10718 (define_insn "*one_cmplsi2_2_zext"
10719 [(set (reg FLAGS_REG)
10720 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10722 (set (match_operand:DI 0 "register_operand" "=r")
10723 (zero_extend:DI (not:SI (match_dup 1))))]
10724 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10725 && ix86_unary_operator_ok (NOT, SImode, operands)"
10727 [(set_attr "type" "alu1")
10728 (set_attr "mode" "SI")])
10731 [(set (match_operand 0 "flags_reg_operand" "")
10732 (match_operator 2 "compare_operator"
10733 [(not:SI (match_operand:SI 3 "register_operand" ""))
10735 (set (match_operand:DI 1 "register_operand" "")
10736 (zero_extend:DI (not:SI (match_dup 3))))]
10737 "ix86_match_ccmode (insn, CCNOmode)"
10738 [(parallel [(set (match_dup 0)
10739 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10742 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10745 (define_expand "one_cmplhi2"
10746 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10747 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10748 "TARGET_HIMODE_MATH"
10749 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10751 (define_insn "*one_cmplhi2_1"
10752 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10753 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10754 "ix86_unary_operator_ok (NOT, HImode, operands)"
10756 [(set_attr "type" "negnot")
10757 (set_attr "mode" "HI")])
10759 (define_insn "*one_cmplhi2_2"
10760 [(set (reg FLAGS_REG)
10761 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10763 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10764 (not:HI (match_dup 1)))]
10765 "ix86_match_ccmode (insn, CCNOmode)
10766 && ix86_unary_operator_ok (NEG, HImode, operands)"
10768 [(set_attr "type" "alu1")
10769 (set_attr "mode" "HI")])
10772 [(set (match_operand 0 "flags_reg_operand" "")
10773 (match_operator 2 "compare_operator"
10774 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10776 (set (match_operand:HI 1 "nonimmediate_operand" "")
10777 (not:HI (match_dup 3)))]
10778 "ix86_match_ccmode (insn, CCNOmode)"
10779 [(parallel [(set (match_dup 0)
10780 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10783 (xor:HI (match_dup 3) (const_int -1)))])]
10786 ;; %%% Potential partial reg stall on alternative 1. What to do?
10787 (define_expand "one_cmplqi2"
10788 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10789 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10790 "TARGET_QIMODE_MATH"
10791 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10793 (define_insn "*one_cmplqi2_1"
10794 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10795 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10796 "ix86_unary_operator_ok (NOT, QImode, operands)"
10800 [(set_attr "type" "negnot")
10801 (set_attr "mode" "QI,SI")])
10803 (define_insn "*one_cmplqi2_2"
10804 [(set (reg FLAGS_REG)
10805 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10807 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10808 (not:QI (match_dup 1)))]
10809 "ix86_match_ccmode (insn, CCNOmode)
10810 && ix86_unary_operator_ok (NOT, QImode, operands)"
10812 [(set_attr "type" "alu1")
10813 (set_attr "mode" "QI")])
10816 [(set (match_operand 0 "flags_reg_operand" "")
10817 (match_operator 2 "compare_operator"
10818 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10820 (set (match_operand:QI 1 "nonimmediate_operand" "")
10821 (not:QI (match_dup 3)))]
10822 "ix86_match_ccmode (insn, CCNOmode)"
10823 [(parallel [(set (match_dup 0)
10824 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10827 (xor:QI (match_dup 3) (const_int -1)))])]
10830 ;; Arithmetic shift instructions
10832 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10833 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10834 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10835 ;; from the assembler input.
10837 ;; This instruction shifts the target reg/mem as usual, but instead of
10838 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10839 ;; is a left shift double, bits are taken from the high order bits of
10840 ;; reg, else if the insn is a shift right double, bits are taken from the
10841 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10842 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10844 ;; Since sh[lr]d does not change the `reg' operand, that is done
10845 ;; separately, making all shifts emit pairs of shift double and normal
10846 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10847 ;; support a 63 bit shift, each shift where the count is in a reg expands
10848 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10850 ;; If the shift count is a constant, we need never emit more than one
10851 ;; shift pair, instead using moves and sign extension for counts greater
10854 (define_expand "ashlti3"
10855 [(set (match_operand:TI 0 "register_operand" "")
10856 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10857 (match_operand:QI 2 "nonmemory_operand" "")))]
10859 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10861 ;; This pattern must be defined before *ashlti3_1 to prevent
10862 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10864 (define_insn "sse2_ashlti3"
10865 [(set (match_operand:TI 0 "register_operand" "=x")
10866 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10867 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10870 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10871 return "pslldq\t{%2, %0|%0, %2}";
10873 [(set_attr "type" "sseishft")
10874 (set_attr "prefix_data16" "1")
10875 (set_attr "mode" "TI")])
10877 (define_insn "*ashlti3_1"
10878 [(set (match_operand:TI 0 "register_operand" "=&r,r")
10879 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10880 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10881 (clobber (reg:CC FLAGS_REG))]
10884 [(set_attr "type" "multi")])
10887 [(match_scratch:DI 3 "r")
10888 (parallel [(set (match_operand:TI 0 "register_operand" "")
10889 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10890 (match_operand:QI 2 "nonmemory_operand" "")))
10891 (clobber (reg:CC FLAGS_REG))])
10895 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10898 [(set (match_operand:TI 0 "register_operand" "")
10899 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10900 (match_operand:QI 2 "nonmemory_operand" "")))
10901 (clobber (reg:CC FLAGS_REG))]
10902 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10903 ? epilogue_completed : reload_completed)"
10905 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10907 (define_insn "x86_64_shld"
10908 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10909 (ior:DI (ashift:DI (match_dup 0)
10910 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10911 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10912 (minus:QI (const_int 64) (match_dup 2)))))
10913 (clobber (reg:CC FLAGS_REG))]
10915 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10916 [(set_attr "type" "ishift")
10917 (set_attr "prefix_0f" "1")
10918 (set_attr "mode" "DI")
10919 (set_attr "athlon_decode" "vector")
10920 (set_attr "amdfam10_decode" "vector")])
10922 (define_expand "x86_64_shift_adj_1"
10923 [(set (reg:CCZ FLAGS_REG)
10924 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10927 (set (match_operand:DI 0 "register_operand" "")
10928 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10929 (match_operand:DI 1 "register_operand" "")
10932 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10933 (match_operand:DI 3 "register_operand" "r")
10938 (define_expand "x86_64_shift_adj_2"
10939 [(use (match_operand:DI 0 "register_operand" ""))
10940 (use (match_operand:DI 1 "register_operand" ""))
10941 (use (match_operand:QI 2 "register_operand" ""))]
10944 rtx label = gen_label_rtx ();
10947 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10949 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10950 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10951 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10952 gen_rtx_LABEL_REF (VOIDmode, label),
10954 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10955 JUMP_LABEL (tmp) = label;
10957 emit_move_insn (operands[0], operands[1]);
10958 ix86_expand_clear (operands[1]);
10960 emit_label (label);
10961 LABEL_NUSES (label) = 1;
10966 (define_expand "ashldi3"
10967 [(set (match_operand:DI 0 "shiftdi_operand" "")
10968 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10969 (match_operand:QI 2 "nonmemory_operand" "")))]
10971 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10973 (define_insn "*ashldi3_1_rex64"
10974 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10975 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10976 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10977 (clobber (reg:CC FLAGS_REG))]
10978 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10980 switch (get_attr_type (insn))
10983 gcc_assert (operands[2] == const1_rtx);
10984 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10985 return "add{q}\t%0, %0";
10988 gcc_assert (CONST_INT_P (operands[2]));
10989 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10990 operands[1] = gen_rtx_MULT (DImode, operands[1],
10991 GEN_INT (1 << INTVAL (operands[2])));
10992 return "lea{q}\t{%a1, %0|%0, %a1}";
10995 if (REG_P (operands[2]))
10996 return "sal{q}\t{%b2, %0|%0, %b2}";
10997 else if (operands[2] == const1_rtx
10998 && (TARGET_SHIFT1 || optimize_size))
10999 return "sal{q}\t%0";
11001 return "sal{q}\t{%2, %0|%0, %2}";
11004 [(set (attr "type")
11005 (cond [(eq_attr "alternative" "1")
11006 (const_string "lea")
11007 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11009 (match_operand 0 "register_operand" ""))
11010 (match_operand 2 "const1_operand" ""))
11011 (const_string "alu")
11013 (const_string "ishift")))
11014 (set_attr "mode" "DI")])
11016 ;; Convert lea to the lea pattern to avoid flags dependency.
11018 [(set (match_operand:DI 0 "register_operand" "")
11019 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11020 (match_operand:QI 2 "immediate_operand" "")))
11021 (clobber (reg:CC FLAGS_REG))]
11022 "TARGET_64BIT && reload_completed
11023 && true_regnum (operands[0]) != true_regnum (operands[1])"
11024 [(set (match_dup 0)
11025 (mult:DI (match_dup 1)
11027 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11029 ;; This pattern can't accept a variable shift count, since shifts by
11030 ;; zero don't affect the flags. We assume that shifts by constant
11031 ;; zero are optimized away.
11032 (define_insn "*ashldi3_cmp_rex64"
11033 [(set (reg FLAGS_REG)
11035 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11036 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11038 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11039 (ashift:DI (match_dup 1) (match_dup 2)))]
11042 || !TARGET_PARTIAL_FLAG_REG_STALL
11043 || (operands[2] == const1_rtx
11045 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11046 && ix86_match_ccmode (insn, CCGOCmode)
11047 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11049 switch (get_attr_type (insn))
11052 gcc_assert (operands[2] == const1_rtx);
11053 return "add{q}\t%0, %0";
11056 if (REG_P (operands[2]))
11057 return "sal{q}\t{%b2, %0|%0, %b2}";
11058 else if (operands[2] == const1_rtx
11059 && (TARGET_SHIFT1 || optimize_size))
11060 return "sal{q}\t%0";
11062 return "sal{q}\t{%2, %0|%0, %2}";
11065 [(set (attr "type")
11066 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11068 (match_operand 0 "register_operand" ""))
11069 (match_operand 2 "const1_operand" ""))
11070 (const_string "alu")
11072 (const_string "ishift")))
11073 (set_attr "mode" "DI")])
11075 (define_insn "*ashldi3_cconly_rex64"
11076 [(set (reg FLAGS_REG)
11078 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11079 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11081 (clobber (match_scratch:DI 0 "=r"))]
11084 || !TARGET_PARTIAL_FLAG_REG_STALL
11085 || (operands[2] == const1_rtx
11087 || TARGET_DOUBLE_WITH_ADD)))
11088 && ix86_match_ccmode (insn, CCGOCmode)
11089 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11091 switch (get_attr_type (insn))
11094 gcc_assert (operands[2] == const1_rtx);
11095 return "add{q}\t%0, %0";
11098 if (REG_P (operands[2]))
11099 return "sal{q}\t{%b2, %0|%0, %b2}";
11100 else if (operands[2] == const1_rtx
11101 && (TARGET_SHIFT1 || optimize_size))
11102 return "sal{q}\t%0";
11104 return "sal{q}\t{%2, %0|%0, %2}";
11107 [(set (attr "type")
11108 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11110 (match_operand 0 "register_operand" ""))
11111 (match_operand 2 "const1_operand" ""))
11112 (const_string "alu")
11114 (const_string "ishift")))
11115 (set_attr "mode" "DI")])
11117 (define_insn "*ashldi3_1"
11118 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11119 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11120 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11121 (clobber (reg:CC FLAGS_REG))]
11124 [(set_attr "type" "multi")])
11126 ;; By default we don't ask for a scratch register, because when DImode
11127 ;; values are manipulated, registers are already at a premium. But if
11128 ;; we have one handy, we won't turn it away.
11130 [(match_scratch:SI 3 "r")
11131 (parallel [(set (match_operand:DI 0 "register_operand" "")
11132 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11133 (match_operand:QI 2 "nonmemory_operand" "")))
11134 (clobber (reg:CC FLAGS_REG))])
11136 "!TARGET_64BIT && TARGET_CMOVE"
11138 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11141 [(set (match_operand:DI 0 "register_operand" "")
11142 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11143 (match_operand:QI 2 "nonmemory_operand" "")))
11144 (clobber (reg:CC FLAGS_REG))]
11145 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11146 ? epilogue_completed : reload_completed)"
11148 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11150 (define_insn "x86_shld"
11151 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11152 (ior:SI (ashift:SI (match_dup 0)
11153 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11154 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11155 (minus:QI (const_int 32) (match_dup 2)))))
11156 (clobber (reg:CC FLAGS_REG))]
11158 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11159 [(set_attr "type" "ishift")
11160 (set_attr "prefix_0f" "1")
11161 (set_attr "mode" "SI")
11162 (set_attr "pent_pair" "np")
11163 (set_attr "athlon_decode" "vector")
11164 (set_attr "amdfam10_decode" "vector")])
11166 (define_expand "x86_shift_adj_1"
11167 [(set (reg:CCZ FLAGS_REG)
11168 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11171 (set (match_operand:SI 0 "register_operand" "")
11172 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11173 (match_operand:SI 1 "register_operand" "")
11176 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11177 (match_operand:SI 3 "register_operand" "r")
11182 (define_expand "x86_shift_adj_2"
11183 [(use (match_operand:SI 0 "register_operand" ""))
11184 (use (match_operand:SI 1 "register_operand" ""))
11185 (use (match_operand:QI 2 "register_operand" ""))]
11188 rtx label = gen_label_rtx ();
11191 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11193 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11194 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11195 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11196 gen_rtx_LABEL_REF (VOIDmode, label),
11198 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11199 JUMP_LABEL (tmp) = label;
11201 emit_move_insn (operands[0], operands[1]);
11202 ix86_expand_clear (operands[1]);
11204 emit_label (label);
11205 LABEL_NUSES (label) = 1;
11210 (define_expand "ashlsi3"
11211 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11212 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11213 (match_operand:QI 2 "nonmemory_operand" "")))]
11215 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11217 (define_insn "*ashlsi3_1"
11218 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11219 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11220 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11221 (clobber (reg:CC FLAGS_REG))]
11222 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11224 switch (get_attr_type (insn))
11227 gcc_assert (operands[2] == const1_rtx);
11228 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11229 return "add{l}\t%0, %0";
11235 if (REG_P (operands[2]))
11236 return "sal{l}\t{%b2, %0|%0, %b2}";
11237 else if (operands[2] == const1_rtx
11238 && (TARGET_SHIFT1 || optimize_size))
11239 return "sal{l}\t%0";
11241 return "sal{l}\t{%2, %0|%0, %2}";
11244 [(set (attr "type")
11245 (cond [(eq_attr "alternative" "1")
11246 (const_string "lea")
11247 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11249 (match_operand 0 "register_operand" ""))
11250 (match_operand 2 "const1_operand" ""))
11251 (const_string "alu")
11253 (const_string "ishift")))
11254 (set_attr "mode" "SI")])
11256 ;; Convert lea to the lea pattern to avoid flags dependency.
11258 [(set (match_operand 0 "register_operand" "")
11259 (ashift (match_operand 1 "index_register_operand" "")
11260 (match_operand:QI 2 "const_int_operand" "")))
11261 (clobber (reg:CC FLAGS_REG))]
11263 && true_regnum (operands[0]) != true_regnum (operands[1])
11264 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11268 enum machine_mode mode = GET_MODE (operands[0]);
11270 if (GET_MODE_SIZE (mode) < 4)
11271 operands[0] = gen_lowpart (SImode, operands[0]);
11273 operands[1] = gen_lowpart (Pmode, operands[1]);
11274 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11276 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11277 if (Pmode != SImode)
11278 pat = gen_rtx_SUBREG (SImode, pat, 0);
11279 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11283 ;; Rare case of shifting RSP is handled by generating move and shift
11285 [(set (match_operand 0 "register_operand" "")
11286 (ashift (match_operand 1 "register_operand" "")
11287 (match_operand:QI 2 "const_int_operand" "")))
11288 (clobber (reg:CC FLAGS_REG))]
11290 && true_regnum (operands[0]) != true_regnum (operands[1])"
11294 emit_move_insn (operands[0], operands[1]);
11295 pat = gen_rtx_SET (VOIDmode, operands[0],
11296 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11297 operands[0], operands[2]));
11298 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11299 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11303 (define_insn "*ashlsi3_1_zext"
11304 [(set (match_operand:DI 0 "register_operand" "=r,r")
11305 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11306 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11307 (clobber (reg:CC FLAGS_REG))]
11308 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11310 switch (get_attr_type (insn))
11313 gcc_assert (operands[2] == const1_rtx);
11314 return "add{l}\t%k0, %k0";
11320 if (REG_P (operands[2]))
11321 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11322 else if (operands[2] == const1_rtx
11323 && (TARGET_SHIFT1 || optimize_size))
11324 return "sal{l}\t%k0";
11326 return "sal{l}\t{%2, %k0|%k0, %2}";
11329 [(set (attr "type")
11330 (cond [(eq_attr "alternative" "1")
11331 (const_string "lea")
11332 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11334 (match_operand 2 "const1_operand" ""))
11335 (const_string "alu")
11337 (const_string "ishift")))
11338 (set_attr "mode" "SI")])
11340 ;; Convert lea to the lea pattern to avoid flags dependency.
11342 [(set (match_operand:DI 0 "register_operand" "")
11343 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11344 (match_operand:QI 2 "const_int_operand" ""))))
11345 (clobber (reg:CC FLAGS_REG))]
11346 "TARGET_64BIT && reload_completed
11347 && true_regnum (operands[0]) != true_regnum (operands[1])"
11348 [(set (match_dup 0) (zero_extend:DI
11349 (subreg:SI (mult:SI (match_dup 1)
11350 (match_dup 2)) 0)))]
11352 operands[1] = gen_lowpart (Pmode, operands[1]);
11353 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11356 ;; This pattern can't accept a variable shift count, since shifts by
11357 ;; zero don't affect the flags. We assume that shifts by constant
11358 ;; zero are optimized away.
11359 (define_insn "*ashlsi3_cmp"
11360 [(set (reg FLAGS_REG)
11362 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11363 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11365 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11366 (ashift:SI (match_dup 1) (match_dup 2)))]
11368 || !TARGET_PARTIAL_FLAG_REG_STALL
11369 || (operands[2] == const1_rtx
11371 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11372 && ix86_match_ccmode (insn, CCGOCmode)
11373 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11375 switch (get_attr_type (insn))
11378 gcc_assert (operands[2] == const1_rtx);
11379 return "add{l}\t%0, %0";
11382 if (REG_P (operands[2]))
11383 return "sal{l}\t{%b2, %0|%0, %b2}";
11384 else if (operands[2] == const1_rtx
11385 && (TARGET_SHIFT1 || optimize_size))
11386 return "sal{l}\t%0";
11388 return "sal{l}\t{%2, %0|%0, %2}";
11391 [(set (attr "type")
11392 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11394 (match_operand 0 "register_operand" ""))
11395 (match_operand 2 "const1_operand" ""))
11396 (const_string "alu")
11398 (const_string "ishift")))
11399 (set_attr "mode" "SI")])
11401 (define_insn "*ashlsi3_cconly"
11402 [(set (reg FLAGS_REG)
11404 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11405 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11407 (clobber (match_scratch:SI 0 "=r"))]
11409 || !TARGET_PARTIAL_FLAG_REG_STALL
11410 || (operands[2] == const1_rtx
11412 || TARGET_DOUBLE_WITH_ADD)))
11413 && ix86_match_ccmode (insn, CCGOCmode)
11414 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11416 switch (get_attr_type (insn))
11419 gcc_assert (operands[2] == const1_rtx);
11420 return "add{l}\t%0, %0";
11423 if (REG_P (operands[2]))
11424 return "sal{l}\t{%b2, %0|%0, %b2}";
11425 else if (operands[2] == const1_rtx
11426 && (TARGET_SHIFT1 || optimize_size))
11427 return "sal{l}\t%0";
11429 return "sal{l}\t{%2, %0|%0, %2}";
11432 [(set (attr "type")
11433 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11435 (match_operand 0 "register_operand" ""))
11436 (match_operand 2 "const1_operand" ""))
11437 (const_string "alu")
11439 (const_string "ishift")))
11440 (set_attr "mode" "SI")])
11442 (define_insn "*ashlsi3_cmp_zext"
11443 [(set (reg FLAGS_REG)
11445 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11446 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11448 (set (match_operand:DI 0 "register_operand" "=r")
11449 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11452 || !TARGET_PARTIAL_FLAG_REG_STALL
11453 || (operands[2] == const1_rtx
11455 || TARGET_DOUBLE_WITH_ADD)))
11456 && ix86_match_ccmode (insn, CCGOCmode)
11457 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11459 switch (get_attr_type (insn))
11462 gcc_assert (operands[2] == const1_rtx);
11463 return "add{l}\t%k0, %k0";
11466 if (REG_P (operands[2]))
11467 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11468 else if (operands[2] == const1_rtx
11469 && (TARGET_SHIFT1 || optimize_size))
11470 return "sal{l}\t%k0";
11472 return "sal{l}\t{%2, %k0|%k0, %2}";
11475 [(set (attr "type")
11476 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11478 (match_operand 2 "const1_operand" ""))
11479 (const_string "alu")
11481 (const_string "ishift")))
11482 (set_attr "mode" "SI")])
11484 (define_expand "ashlhi3"
11485 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11486 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11487 (match_operand:QI 2 "nonmemory_operand" "")))]
11488 "TARGET_HIMODE_MATH"
11489 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11491 (define_insn "*ashlhi3_1_lea"
11492 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11493 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11494 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11495 (clobber (reg:CC FLAGS_REG))]
11496 "!TARGET_PARTIAL_REG_STALL
11497 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11499 switch (get_attr_type (insn))
11504 gcc_assert (operands[2] == const1_rtx);
11505 return "add{w}\t%0, %0";
11508 if (REG_P (operands[2]))
11509 return "sal{w}\t{%b2, %0|%0, %b2}";
11510 else if (operands[2] == const1_rtx
11511 && (TARGET_SHIFT1 || optimize_size))
11512 return "sal{w}\t%0";
11514 return "sal{w}\t{%2, %0|%0, %2}";
11517 [(set (attr "type")
11518 (cond [(eq_attr "alternative" "1")
11519 (const_string "lea")
11520 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11522 (match_operand 0 "register_operand" ""))
11523 (match_operand 2 "const1_operand" ""))
11524 (const_string "alu")
11526 (const_string "ishift")))
11527 (set_attr "mode" "HI,SI")])
11529 (define_insn "*ashlhi3_1"
11530 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11531 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11532 (match_operand:QI 2 "nonmemory_operand" "cI")))
11533 (clobber (reg:CC FLAGS_REG))]
11534 "TARGET_PARTIAL_REG_STALL
11535 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11537 switch (get_attr_type (insn))
11540 gcc_assert (operands[2] == const1_rtx);
11541 return "add{w}\t%0, %0";
11544 if (REG_P (operands[2]))
11545 return "sal{w}\t{%b2, %0|%0, %b2}";
11546 else if (operands[2] == const1_rtx
11547 && (TARGET_SHIFT1 || optimize_size))
11548 return "sal{w}\t%0";
11550 return "sal{w}\t{%2, %0|%0, %2}";
11553 [(set (attr "type")
11554 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11556 (match_operand 0 "register_operand" ""))
11557 (match_operand 2 "const1_operand" ""))
11558 (const_string "alu")
11560 (const_string "ishift")))
11561 (set_attr "mode" "HI")])
11563 ;; This pattern can't accept a variable shift count, since shifts by
11564 ;; zero don't affect the flags. We assume that shifts by constant
11565 ;; zero are optimized away.
11566 (define_insn "*ashlhi3_cmp"
11567 [(set (reg FLAGS_REG)
11569 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11570 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11572 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11573 (ashift:HI (match_dup 1) (match_dup 2)))]
11575 || !TARGET_PARTIAL_FLAG_REG_STALL
11576 || (operands[2] == const1_rtx
11578 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11579 && ix86_match_ccmode (insn, CCGOCmode)
11580 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11582 switch (get_attr_type (insn))
11585 gcc_assert (operands[2] == const1_rtx);
11586 return "add{w}\t%0, %0";
11589 if (REG_P (operands[2]))
11590 return "sal{w}\t{%b2, %0|%0, %b2}";
11591 else if (operands[2] == const1_rtx
11592 && (TARGET_SHIFT1 || optimize_size))
11593 return "sal{w}\t%0";
11595 return "sal{w}\t{%2, %0|%0, %2}";
11598 [(set (attr "type")
11599 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11601 (match_operand 0 "register_operand" ""))
11602 (match_operand 2 "const1_operand" ""))
11603 (const_string "alu")
11605 (const_string "ishift")))
11606 (set_attr "mode" "HI")])
11608 (define_insn "*ashlhi3_cconly"
11609 [(set (reg FLAGS_REG)
11611 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11612 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11614 (clobber (match_scratch:HI 0 "=r"))]
11616 || !TARGET_PARTIAL_FLAG_REG_STALL
11617 || (operands[2] == const1_rtx
11619 || TARGET_DOUBLE_WITH_ADD)))
11620 && ix86_match_ccmode (insn, CCGOCmode)
11621 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11623 switch (get_attr_type (insn))
11626 gcc_assert (operands[2] == const1_rtx);
11627 return "add{w}\t%0, %0";
11630 if (REG_P (operands[2]))
11631 return "sal{w}\t{%b2, %0|%0, %b2}";
11632 else if (operands[2] == const1_rtx
11633 && (TARGET_SHIFT1 || optimize_size))
11634 return "sal{w}\t%0";
11636 return "sal{w}\t{%2, %0|%0, %2}";
11639 [(set (attr "type")
11640 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11642 (match_operand 0 "register_operand" ""))
11643 (match_operand 2 "const1_operand" ""))
11644 (const_string "alu")
11646 (const_string "ishift")))
11647 (set_attr "mode" "HI")])
11649 (define_expand "ashlqi3"
11650 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11651 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11652 (match_operand:QI 2 "nonmemory_operand" "")))]
11653 "TARGET_QIMODE_MATH"
11654 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11656 ;; %%% Potential partial reg stall on alternative 2. What to do?
11658 (define_insn "*ashlqi3_1_lea"
11659 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11660 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11661 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11662 (clobber (reg:CC FLAGS_REG))]
11663 "!TARGET_PARTIAL_REG_STALL
11664 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11666 switch (get_attr_type (insn))
11671 gcc_assert (operands[2] == const1_rtx);
11672 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11673 return "add{l}\t%k0, %k0";
11675 return "add{b}\t%0, %0";
11678 if (REG_P (operands[2]))
11680 if (get_attr_mode (insn) == MODE_SI)
11681 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11683 return "sal{b}\t{%b2, %0|%0, %b2}";
11685 else if (operands[2] == const1_rtx
11686 && (TARGET_SHIFT1 || optimize_size))
11688 if (get_attr_mode (insn) == MODE_SI)
11689 return "sal{l}\t%0";
11691 return "sal{b}\t%0";
11695 if (get_attr_mode (insn) == MODE_SI)
11696 return "sal{l}\t{%2, %k0|%k0, %2}";
11698 return "sal{b}\t{%2, %0|%0, %2}";
11702 [(set (attr "type")
11703 (cond [(eq_attr "alternative" "2")
11704 (const_string "lea")
11705 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11707 (match_operand 0 "register_operand" ""))
11708 (match_operand 2 "const1_operand" ""))
11709 (const_string "alu")
11711 (const_string "ishift")))
11712 (set_attr "mode" "QI,SI,SI")])
11714 (define_insn "*ashlqi3_1"
11715 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11716 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11717 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11718 (clobber (reg:CC FLAGS_REG))]
11719 "TARGET_PARTIAL_REG_STALL
11720 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11722 switch (get_attr_type (insn))
11725 gcc_assert (operands[2] == const1_rtx);
11726 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11727 return "add{l}\t%k0, %k0";
11729 return "add{b}\t%0, %0";
11732 if (REG_P (operands[2]))
11734 if (get_attr_mode (insn) == MODE_SI)
11735 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11737 return "sal{b}\t{%b2, %0|%0, %b2}";
11739 else if (operands[2] == const1_rtx
11740 && (TARGET_SHIFT1 || optimize_size))
11742 if (get_attr_mode (insn) == MODE_SI)
11743 return "sal{l}\t%0";
11745 return "sal{b}\t%0";
11749 if (get_attr_mode (insn) == MODE_SI)
11750 return "sal{l}\t{%2, %k0|%k0, %2}";
11752 return "sal{b}\t{%2, %0|%0, %2}";
11756 [(set (attr "type")
11757 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11759 (match_operand 0 "register_operand" ""))
11760 (match_operand 2 "const1_operand" ""))
11761 (const_string "alu")
11763 (const_string "ishift")))
11764 (set_attr "mode" "QI,SI")])
11766 ;; This pattern can't accept a variable shift count, since shifts by
11767 ;; zero don't affect the flags. We assume that shifts by constant
11768 ;; zero are optimized away.
11769 (define_insn "*ashlqi3_cmp"
11770 [(set (reg FLAGS_REG)
11772 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11773 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11775 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11776 (ashift:QI (match_dup 1) (match_dup 2)))]
11778 || !TARGET_PARTIAL_FLAG_REG_STALL
11779 || (operands[2] == const1_rtx
11781 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11782 && ix86_match_ccmode (insn, CCGOCmode)
11783 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11785 switch (get_attr_type (insn))
11788 gcc_assert (operands[2] == const1_rtx);
11789 return "add{b}\t%0, %0";
11792 if (REG_P (operands[2]))
11793 return "sal{b}\t{%b2, %0|%0, %b2}";
11794 else if (operands[2] == const1_rtx
11795 && (TARGET_SHIFT1 || optimize_size))
11796 return "sal{b}\t%0";
11798 return "sal{b}\t{%2, %0|%0, %2}";
11801 [(set (attr "type")
11802 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11804 (match_operand 0 "register_operand" ""))
11805 (match_operand 2 "const1_operand" ""))
11806 (const_string "alu")
11808 (const_string "ishift")))
11809 (set_attr "mode" "QI")])
11811 (define_insn "*ashlqi3_cconly"
11812 [(set (reg FLAGS_REG)
11814 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11815 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11817 (clobber (match_scratch:QI 0 "=q"))]
11819 || !TARGET_PARTIAL_FLAG_REG_STALL
11820 || (operands[2] == const1_rtx
11822 || TARGET_DOUBLE_WITH_ADD)))
11823 && ix86_match_ccmode (insn, CCGOCmode)
11824 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11826 switch (get_attr_type (insn))
11829 gcc_assert (operands[2] == const1_rtx);
11830 return "add{b}\t%0, %0";
11833 if (REG_P (operands[2]))
11834 return "sal{b}\t{%b2, %0|%0, %b2}";
11835 else if (operands[2] == const1_rtx
11836 && (TARGET_SHIFT1 || optimize_size))
11837 return "sal{b}\t%0";
11839 return "sal{b}\t{%2, %0|%0, %2}";
11842 [(set (attr "type")
11843 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11845 (match_operand 0 "register_operand" ""))
11846 (match_operand 2 "const1_operand" ""))
11847 (const_string "alu")
11849 (const_string "ishift")))
11850 (set_attr "mode" "QI")])
11852 ;; See comment above `ashldi3' about how this works.
11854 (define_expand "ashrti3"
11855 [(set (match_operand:TI 0 "register_operand" "")
11856 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11857 (match_operand:QI 2 "nonmemory_operand" "")))]
11859 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11861 (define_insn "*ashrti3_1"
11862 [(set (match_operand:TI 0 "register_operand" "=r")
11863 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11864 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11865 (clobber (reg:CC FLAGS_REG))]
11868 [(set_attr "type" "multi")])
11871 [(match_scratch:DI 3 "r")
11872 (parallel [(set (match_operand:TI 0 "register_operand" "")
11873 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11874 (match_operand:QI 2 "nonmemory_operand" "")))
11875 (clobber (reg:CC FLAGS_REG))])
11879 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11882 [(set (match_operand:TI 0 "register_operand" "")
11883 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11884 (match_operand:QI 2 "nonmemory_operand" "")))
11885 (clobber (reg:CC FLAGS_REG))]
11886 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11887 ? epilogue_completed : reload_completed)"
11889 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11891 (define_insn "x86_64_shrd"
11892 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11893 (ior:DI (ashiftrt:DI (match_dup 0)
11894 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11895 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11896 (minus:QI (const_int 64) (match_dup 2)))))
11897 (clobber (reg:CC FLAGS_REG))]
11899 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11900 [(set_attr "type" "ishift")
11901 (set_attr "prefix_0f" "1")
11902 (set_attr "mode" "DI")
11903 (set_attr "athlon_decode" "vector")
11904 (set_attr "amdfam10_decode" "vector")])
11906 (define_expand "ashrdi3"
11907 [(set (match_operand:DI 0 "shiftdi_operand" "")
11908 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11909 (match_operand:QI 2 "nonmemory_operand" "")))]
11911 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11913 (define_expand "x86_64_shift_adj_3"
11914 [(use (match_operand:DI 0 "register_operand" ""))
11915 (use (match_operand:DI 1 "register_operand" ""))
11916 (use (match_operand:QI 2 "register_operand" ""))]
11919 rtx label = gen_label_rtx ();
11922 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11924 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11925 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11926 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11927 gen_rtx_LABEL_REF (VOIDmode, label),
11929 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11930 JUMP_LABEL (tmp) = label;
11932 emit_move_insn (operands[0], operands[1]);
11933 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
11935 emit_label (label);
11936 LABEL_NUSES (label) = 1;
11941 (define_insn "ashrdi3_63_rex64"
11942 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11943 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11944 (match_operand:DI 2 "const_int_operand" "i,i")))
11945 (clobber (reg:CC FLAGS_REG))]
11946 "TARGET_64BIT && INTVAL (operands[2]) == 63
11947 && (TARGET_USE_CLTD || optimize_size)
11948 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11951 sar{q}\t{%2, %0|%0, %2}"
11952 [(set_attr "type" "imovx,ishift")
11953 (set_attr "prefix_0f" "0,*")
11954 (set_attr "length_immediate" "0,*")
11955 (set_attr "modrm" "0,1")
11956 (set_attr "mode" "DI")])
11958 (define_insn "*ashrdi3_1_one_bit_rex64"
11959 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11960 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11961 (match_operand:QI 2 "const1_operand" "")))
11962 (clobber (reg:CC FLAGS_REG))]
11964 && (TARGET_SHIFT1 || optimize_size)
11965 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11967 [(set_attr "type" "ishift")
11968 (set (attr "length")
11969 (if_then_else (match_operand:DI 0 "register_operand" "")
11971 (const_string "*")))])
11973 (define_insn "*ashrdi3_1_rex64"
11974 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11975 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11976 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11977 (clobber (reg:CC FLAGS_REG))]
11978 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11980 sar{q}\t{%2, %0|%0, %2}
11981 sar{q}\t{%b2, %0|%0, %b2}"
11982 [(set_attr "type" "ishift")
11983 (set_attr "mode" "DI")])
11985 ;; This pattern can't accept a variable shift count, since shifts by
11986 ;; zero don't affect the flags. We assume that shifts by constant
11987 ;; zero are optimized away.
11988 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11989 [(set (reg FLAGS_REG)
11991 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11992 (match_operand:QI 2 "const1_operand" ""))
11994 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11995 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11997 && (TARGET_SHIFT1 || optimize_size)
11998 && ix86_match_ccmode (insn, CCGOCmode)
11999 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12001 [(set_attr "type" "ishift")
12002 (set (attr "length")
12003 (if_then_else (match_operand:DI 0 "register_operand" "")
12005 (const_string "*")))])
12007 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12008 [(set (reg FLAGS_REG)
12010 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12011 (match_operand:QI 2 "const1_operand" ""))
12013 (clobber (match_scratch:DI 0 "=r"))]
12015 && (TARGET_SHIFT1 || optimize_size)
12016 && ix86_match_ccmode (insn, CCGOCmode)
12017 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12019 [(set_attr "type" "ishift")
12020 (set_attr "length" "2")])
12022 ;; This pattern can't accept a variable shift count, since shifts by
12023 ;; zero don't affect the flags. We assume that shifts by constant
12024 ;; zero are optimized away.
12025 (define_insn "*ashrdi3_cmp_rex64"
12026 [(set (reg FLAGS_REG)
12028 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12029 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12031 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12032 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12034 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12035 && ix86_match_ccmode (insn, CCGOCmode)
12036 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12037 "sar{q}\t{%2, %0|%0, %2}"
12038 [(set_attr "type" "ishift")
12039 (set_attr "mode" "DI")])
12041 (define_insn "*ashrdi3_cconly_rex64"
12042 [(set (reg FLAGS_REG)
12044 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12045 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12047 (clobber (match_scratch:DI 0 "=r"))]
12049 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12050 && ix86_match_ccmode (insn, CCGOCmode)
12051 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12052 "sar{q}\t{%2, %0|%0, %2}"
12053 [(set_attr "type" "ishift")
12054 (set_attr "mode" "DI")])
12056 (define_insn "*ashrdi3_1"
12057 [(set (match_operand:DI 0 "register_operand" "=r")
12058 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12059 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12060 (clobber (reg:CC FLAGS_REG))]
12063 [(set_attr "type" "multi")])
12065 ;; By default we don't ask for a scratch register, because when DImode
12066 ;; values are manipulated, registers are already at a premium. But if
12067 ;; we have one handy, we won't turn it away.
12069 [(match_scratch:SI 3 "r")
12070 (parallel [(set (match_operand:DI 0 "register_operand" "")
12071 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12072 (match_operand:QI 2 "nonmemory_operand" "")))
12073 (clobber (reg:CC FLAGS_REG))])
12075 "!TARGET_64BIT && TARGET_CMOVE"
12077 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12080 [(set (match_operand:DI 0 "register_operand" "")
12081 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12082 (match_operand:QI 2 "nonmemory_operand" "")))
12083 (clobber (reg:CC FLAGS_REG))]
12084 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12085 ? epilogue_completed : reload_completed)"
12087 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12089 (define_insn "x86_shrd"
12090 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12091 (ior:SI (ashiftrt:SI (match_dup 0)
12092 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12093 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12094 (minus:QI (const_int 32) (match_dup 2)))))
12095 (clobber (reg:CC FLAGS_REG))]
12097 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12098 [(set_attr "type" "ishift")
12099 (set_attr "prefix_0f" "1")
12100 (set_attr "pent_pair" "np")
12101 (set_attr "mode" "SI")])
12103 (define_expand "x86_shift_adj_3"
12104 [(use (match_operand:SI 0 "register_operand" ""))
12105 (use (match_operand:SI 1 "register_operand" ""))
12106 (use (match_operand:QI 2 "register_operand" ""))]
12109 rtx label = gen_label_rtx ();
12112 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12114 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12115 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12116 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12117 gen_rtx_LABEL_REF (VOIDmode, label),
12119 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12120 JUMP_LABEL (tmp) = label;
12122 emit_move_insn (operands[0], operands[1]);
12123 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12125 emit_label (label);
12126 LABEL_NUSES (label) = 1;
12131 (define_insn "ashrsi3_31"
12132 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12133 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12134 (match_operand:SI 2 "const_int_operand" "i,i")))
12135 (clobber (reg:CC FLAGS_REG))]
12136 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12137 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12140 sar{l}\t{%2, %0|%0, %2}"
12141 [(set_attr "type" "imovx,ishift")
12142 (set_attr "prefix_0f" "0,*")
12143 (set_attr "length_immediate" "0,*")
12144 (set_attr "modrm" "0,1")
12145 (set_attr "mode" "SI")])
12147 (define_insn "*ashrsi3_31_zext"
12148 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12149 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12150 (match_operand:SI 2 "const_int_operand" "i,i"))))
12151 (clobber (reg:CC FLAGS_REG))]
12152 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12153 && INTVAL (operands[2]) == 31
12154 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12157 sar{l}\t{%2, %k0|%k0, %2}"
12158 [(set_attr "type" "imovx,ishift")
12159 (set_attr "prefix_0f" "0,*")
12160 (set_attr "length_immediate" "0,*")
12161 (set_attr "modrm" "0,1")
12162 (set_attr "mode" "SI")])
12164 (define_expand "ashrsi3"
12165 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12166 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12167 (match_operand:QI 2 "nonmemory_operand" "")))]
12169 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12171 (define_insn "*ashrsi3_1_one_bit"
12172 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12173 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12174 (match_operand:QI 2 "const1_operand" "")))
12175 (clobber (reg:CC FLAGS_REG))]
12176 "(TARGET_SHIFT1 || optimize_size)
12177 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12179 [(set_attr "type" "ishift")
12180 (set (attr "length")
12181 (if_then_else (match_operand:SI 0 "register_operand" "")
12183 (const_string "*")))])
12185 (define_insn "*ashrsi3_1_one_bit_zext"
12186 [(set (match_operand:DI 0 "register_operand" "=r")
12187 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12188 (match_operand:QI 2 "const1_operand" ""))))
12189 (clobber (reg:CC FLAGS_REG))]
12191 && (TARGET_SHIFT1 || optimize_size)
12192 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12194 [(set_attr "type" "ishift")
12195 (set_attr "length" "2")])
12197 (define_insn "*ashrsi3_1"
12198 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12199 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12200 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12201 (clobber (reg:CC FLAGS_REG))]
12202 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12204 sar{l}\t{%2, %0|%0, %2}
12205 sar{l}\t{%b2, %0|%0, %b2}"
12206 [(set_attr "type" "ishift")
12207 (set_attr "mode" "SI")])
12209 (define_insn "*ashrsi3_1_zext"
12210 [(set (match_operand:DI 0 "register_operand" "=r,r")
12211 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12212 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12213 (clobber (reg:CC FLAGS_REG))]
12214 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12216 sar{l}\t{%2, %k0|%k0, %2}
12217 sar{l}\t{%b2, %k0|%k0, %b2}"
12218 [(set_attr "type" "ishift")
12219 (set_attr "mode" "SI")])
12221 ;; This pattern can't accept a variable shift count, since shifts by
12222 ;; zero don't affect the flags. We assume that shifts by constant
12223 ;; zero are optimized away.
12224 (define_insn "*ashrsi3_one_bit_cmp"
12225 [(set (reg FLAGS_REG)
12227 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12228 (match_operand:QI 2 "const1_operand" ""))
12230 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12231 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12232 "(TARGET_SHIFT1 || optimize_size)
12233 && ix86_match_ccmode (insn, CCGOCmode)
12234 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12236 [(set_attr "type" "ishift")
12237 (set (attr "length")
12238 (if_then_else (match_operand:SI 0 "register_operand" "")
12240 (const_string "*")))])
12242 (define_insn "*ashrsi3_one_bit_cconly"
12243 [(set (reg FLAGS_REG)
12245 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12246 (match_operand:QI 2 "const1_operand" ""))
12248 (clobber (match_scratch:SI 0 "=r"))]
12249 "(TARGET_SHIFT1 || optimize_size)
12250 && ix86_match_ccmode (insn, CCGOCmode)
12251 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12253 [(set_attr "type" "ishift")
12254 (set_attr "length" "2")])
12256 (define_insn "*ashrsi3_one_bit_cmp_zext"
12257 [(set (reg FLAGS_REG)
12259 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12260 (match_operand:QI 2 "const1_operand" ""))
12262 (set (match_operand:DI 0 "register_operand" "=r")
12263 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12265 && (TARGET_SHIFT1 || optimize_size)
12266 && ix86_match_ccmode (insn, CCmode)
12267 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12269 [(set_attr "type" "ishift")
12270 (set_attr "length" "2")])
12272 ;; This pattern can't accept a variable shift count, since shifts by
12273 ;; zero don't affect the flags. We assume that shifts by constant
12274 ;; zero are optimized away.
12275 (define_insn "*ashrsi3_cmp"
12276 [(set (reg FLAGS_REG)
12278 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12279 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12281 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12282 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12283 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12284 && ix86_match_ccmode (insn, CCGOCmode)
12285 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12286 "sar{l}\t{%2, %0|%0, %2}"
12287 [(set_attr "type" "ishift")
12288 (set_attr "mode" "SI")])
12290 (define_insn "*ashrsi3_cconly"
12291 [(set (reg FLAGS_REG)
12293 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12294 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12296 (clobber (match_scratch:SI 0 "=r"))]
12297 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12298 && ix86_match_ccmode (insn, CCGOCmode)
12299 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12300 "sar{l}\t{%2, %0|%0, %2}"
12301 [(set_attr "type" "ishift")
12302 (set_attr "mode" "SI")])
12304 (define_insn "*ashrsi3_cmp_zext"
12305 [(set (reg FLAGS_REG)
12307 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12308 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12310 (set (match_operand:DI 0 "register_operand" "=r")
12311 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12313 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12314 && ix86_match_ccmode (insn, CCGOCmode)
12315 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12316 "sar{l}\t{%2, %k0|%k0, %2}"
12317 [(set_attr "type" "ishift")
12318 (set_attr "mode" "SI")])
12320 (define_expand "ashrhi3"
12321 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12322 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12323 (match_operand:QI 2 "nonmemory_operand" "")))]
12324 "TARGET_HIMODE_MATH"
12325 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12327 (define_insn "*ashrhi3_1_one_bit"
12328 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12329 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12330 (match_operand:QI 2 "const1_operand" "")))
12331 (clobber (reg:CC FLAGS_REG))]
12332 "(TARGET_SHIFT1 || optimize_size)
12333 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12335 [(set_attr "type" "ishift")
12336 (set (attr "length")
12337 (if_then_else (match_operand 0 "register_operand" "")
12339 (const_string "*")))])
12341 (define_insn "*ashrhi3_1"
12342 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12343 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12344 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12345 (clobber (reg:CC FLAGS_REG))]
12346 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12348 sar{w}\t{%2, %0|%0, %2}
12349 sar{w}\t{%b2, %0|%0, %b2}"
12350 [(set_attr "type" "ishift")
12351 (set_attr "mode" "HI")])
12353 ;; This pattern can't accept a variable shift count, since shifts by
12354 ;; zero don't affect the flags. We assume that shifts by constant
12355 ;; zero are optimized away.
12356 (define_insn "*ashrhi3_one_bit_cmp"
12357 [(set (reg FLAGS_REG)
12359 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12360 (match_operand:QI 2 "const1_operand" ""))
12362 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12363 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12364 "(TARGET_SHIFT1 || optimize_size)
12365 && ix86_match_ccmode (insn, CCGOCmode)
12366 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12368 [(set_attr "type" "ishift")
12369 (set (attr "length")
12370 (if_then_else (match_operand 0 "register_operand" "")
12372 (const_string "*")))])
12374 (define_insn "*ashrhi3_one_bit_cconly"
12375 [(set (reg FLAGS_REG)
12377 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12378 (match_operand:QI 2 "const1_operand" ""))
12380 (clobber (match_scratch:HI 0 "=r"))]
12381 "(TARGET_SHIFT1 || optimize_size)
12382 && ix86_match_ccmode (insn, CCGOCmode)
12383 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12385 [(set_attr "type" "ishift")
12386 (set_attr "length" "2")])
12388 ;; This pattern can't accept a variable shift count, since shifts by
12389 ;; zero don't affect the flags. We assume that shifts by constant
12390 ;; zero are optimized away.
12391 (define_insn "*ashrhi3_cmp"
12392 [(set (reg FLAGS_REG)
12394 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12395 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12397 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12398 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12399 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12400 && ix86_match_ccmode (insn, CCGOCmode)
12401 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12402 "sar{w}\t{%2, %0|%0, %2}"
12403 [(set_attr "type" "ishift")
12404 (set_attr "mode" "HI")])
12406 (define_insn "*ashrhi3_cconly"
12407 [(set (reg FLAGS_REG)
12409 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12410 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12412 (clobber (match_scratch:HI 0 "=r"))]
12413 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12414 && ix86_match_ccmode (insn, CCGOCmode)
12415 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12416 "sar{w}\t{%2, %0|%0, %2}"
12417 [(set_attr "type" "ishift")
12418 (set_attr "mode" "HI")])
12420 (define_expand "ashrqi3"
12421 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12422 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12423 (match_operand:QI 2 "nonmemory_operand" "")))]
12424 "TARGET_QIMODE_MATH"
12425 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12427 (define_insn "*ashrqi3_1_one_bit"
12428 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12429 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12430 (match_operand:QI 2 "const1_operand" "")))
12431 (clobber (reg:CC FLAGS_REG))]
12432 "(TARGET_SHIFT1 || optimize_size)
12433 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12435 [(set_attr "type" "ishift")
12436 (set (attr "length")
12437 (if_then_else (match_operand 0 "register_operand" "")
12439 (const_string "*")))])
12441 (define_insn "*ashrqi3_1_one_bit_slp"
12442 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12443 (ashiftrt:QI (match_dup 0)
12444 (match_operand:QI 1 "const1_operand" "")))
12445 (clobber (reg:CC FLAGS_REG))]
12446 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12447 && (TARGET_SHIFT1 || optimize_size)
12448 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12450 [(set_attr "type" "ishift1")
12451 (set (attr "length")
12452 (if_then_else (match_operand 0 "register_operand" "")
12454 (const_string "*")))])
12456 (define_insn "*ashrqi3_1"
12457 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12458 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12459 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12460 (clobber (reg:CC FLAGS_REG))]
12461 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12463 sar{b}\t{%2, %0|%0, %2}
12464 sar{b}\t{%b2, %0|%0, %b2}"
12465 [(set_attr "type" "ishift")
12466 (set_attr "mode" "QI")])
12468 (define_insn "*ashrqi3_1_slp"
12469 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12470 (ashiftrt:QI (match_dup 0)
12471 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12472 (clobber (reg:CC FLAGS_REG))]
12473 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12474 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12476 sar{b}\t{%1, %0|%0, %1}
12477 sar{b}\t{%b1, %0|%0, %b1}"
12478 [(set_attr "type" "ishift1")
12479 (set_attr "mode" "QI")])
12481 ;; This pattern can't accept a variable shift count, since shifts by
12482 ;; zero don't affect the flags. We assume that shifts by constant
12483 ;; zero are optimized away.
12484 (define_insn "*ashrqi3_one_bit_cmp"
12485 [(set (reg FLAGS_REG)
12487 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12488 (match_operand:QI 2 "const1_operand" "I"))
12490 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12491 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12492 "(TARGET_SHIFT1 || optimize_size)
12493 && ix86_match_ccmode (insn, CCGOCmode)
12494 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12496 [(set_attr "type" "ishift")
12497 (set (attr "length")
12498 (if_then_else (match_operand 0 "register_operand" "")
12500 (const_string "*")))])
12502 (define_insn "*ashrqi3_one_bit_cconly"
12503 [(set (reg FLAGS_REG)
12505 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12506 (match_operand:QI 2 "const1_operand" ""))
12508 (clobber (match_scratch:QI 0 "=q"))]
12509 "(TARGET_SHIFT1 || optimize_size)
12510 && ix86_match_ccmode (insn, CCGOCmode)
12511 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12513 [(set_attr "type" "ishift")
12514 (set_attr "length" "2")])
12516 ;; This pattern can't accept a variable shift count, since shifts by
12517 ;; zero don't affect the flags. We assume that shifts by constant
12518 ;; zero are optimized away.
12519 (define_insn "*ashrqi3_cmp"
12520 [(set (reg FLAGS_REG)
12522 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12523 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12525 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12526 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12527 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12528 && ix86_match_ccmode (insn, CCGOCmode)
12529 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12530 "sar{b}\t{%2, %0|%0, %2}"
12531 [(set_attr "type" "ishift")
12532 (set_attr "mode" "QI")])
12534 (define_insn "*ashrqi3_cconly"
12535 [(set (reg FLAGS_REG)
12537 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12538 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12540 (clobber (match_scratch:QI 0 "=q"))]
12541 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12542 && ix86_match_ccmode (insn, CCGOCmode)
12543 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12544 "sar{b}\t{%2, %0|%0, %2}"
12545 [(set_attr "type" "ishift")
12546 (set_attr "mode" "QI")])
12549 ;; Logical shift instructions
12551 ;; See comment above `ashldi3' about how this works.
12553 (define_expand "lshrti3"
12554 [(set (match_operand:TI 0 "register_operand" "")
12555 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12556 (match_operand:QI 2 "nonmemory_operand" "")))]
12558 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12560 ;; This pattern must be defined before *lshrti3_1 to prevent
12561 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12563 (define_insn "sse2_lshrti3"
12564 [(set (match_operand:TI 0 "register_operand" "=x")
12565 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12566 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12569 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12570 return "psrldq\t{%2, %0|%0, %2}";
12572 [(set_attr "type" "sseishft")
12573 (set_attr "prefix_data16" "1")
12574 (set_attr "mode" "TI")])
12576 (define_insn "*lshrti3_1"
12577 [(set (match_operand:TI 0 "register_operand" "=r")
12578 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12579 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12580 (clobber (reg:CC FLAGS_REG))]
12583 [(set_attr "type" "multi")])
12586 [(match_scratch:DI 3 "r")
12587 (parallel [(set (match_operand:TI 0 "register_operand" "")
12588 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12589 (match_operand:QI 2 "nonmemory_operand" "")))
12590 (clobber (reg:CC FLAGS_REG))])
12594 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12597 [(set (match_operand:TI 0 "register_operand" "")
12598 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12599 (match_operand:QI 2 "nonmemory_operand" "")))
12600 (clobber (reg:CC FLAGS_REG))]
12601 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12602 ? epilogue_completed : reload_completed)"
12604 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12606 (define_expand "lshrdi3"
12607 [(set (match_operand:DI 0 "shiftdi_operand" "")
12608 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12609 (match_operand:QI 2 "nonmemory_operand" "")))]
12611 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12613 (define_insn "*lshrdi3_1_one_bit_rex64"
12614 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12615 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12616 (match_operand:QI 2 "const1_operand" "")))
12617 (clobber (reg:CC FLAGS_REG))]
12619 && (TARGET_SHIFT1 || optimize_size)
12620 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12622 [(set_attr "type" "ishift")
12623 (set (attr "length")
12624 (if_then_else (match_operand:DI 0 "register_operand" "")
12626 (const_string "*")))])
12628 (define_insn "*lshrdi3_1_rex64"
12629 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12630 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12631 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12632 (clobber (reg:CC FLAGS_REG))]
12633 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12635 shr{q}\t{%2, %0|%0, %2}
12636 shr{q}\t{%b2, %0|%0, %b2}"
12637 [(set_attr "type" "ishift")
12638 (set_attr "mode" "DI")])
12640 ;; This pattern can't accept a variable shift count, since shifts by
12641 ;; zero don't affect the flags. We assume that shifts by constant
12642 ;; zero are optimized away.
12643 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12644 [(set (reg FLAGS_REG)
12646 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12647 (match_operand:QI 2 "const1_operand" ""))
12649 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12650 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12652 && (TARGET_SHIFT1 || optimize_size)
12653 && ix86_match_ccmode (insn, CCGOCmode)
12654 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12656 [(set_attr "type" "ishift")
12657 (set (attr "length")
12658 (if_then_else (match_operand:DI 0 "register_operand" "")
12660 (const_string "*")))])
12662 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12663 [(set (reg FLAGS_REG)
12665 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12666 (match_operand:QI 2 "const1_operand" ""))
12668 (clobber (match_scratch:DI 0 "=r"))]
12670 && (TARGET_SHIFT1 || optimize_size)
12671 && ix86_match_ccmode (insn, CCGOCmode)
12672 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12674 [(set_attr "type" "ishift")
12675 (set_attr "length" "2")])
12677 ;; This pattern can't accept a variable shift count, since shifts by
12678 ;; zero don't affect the flags. We assume that shifts by constant
12679 ;; zero are optimized away.
12680 (define_insn "*lshrdi3_cmp_rex64"
12681 [(set (reg FLAGS_REG)
12683 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12684 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12686 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12687 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12689 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12690 && ix86_match_ccmode (insn, CCGOCmode)
12691 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12692 "shr{q}\t{%2, %0|%0, %2}"
12693 [(set_attr "type" "ishift")
12694 (set_attr "mode" "DI")])
12696 (define_insn "*lshrdi3_cconly_rex64"
12697 [(set (reg FLAGS_REG)
12699 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12700 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12702 (clobber (match_scratch:DI 0 "=r"))]
12704 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12705 && ix86_match_ccmode (insn, CCGOCmode)
12706 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12707 "shr{q}\t{%2, %0|%0, %2}"
12708 [(set_attr "type" "ishift")
12709 (set_attr "mode" "DI")])
12711 (define_insn "*lshrdi3_1"
12712 [(set (match_operand:DI 0 "register_operand" "=r")
12713 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12714 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12715 (clobber (reg:CC FLAGS_REG))]
12718 [(set_attr "type" "multi")])
12720 ;; By default we don't ask for a scratch register, because when DImode
12721 ;; values are manipulated, registers are already at a premium. But if
12722 ;; we have one handy, we won't turn it away.
12724 [(match_scratch:SI 3 "r")
12725 (parallel [(set (match_operand:DI 0 "register_operand" "")
12726 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12727 (match_operand:QI 2 "nonmemory_operand" "")))
12728 (clobber (reg:CC FLAGS_REG))])
12730 "!TARGET_64BIT && TARGET_CMOVE"
12732 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12735 [(set (match_operand:DI 0 "register_operand" "")
12736 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12737 (match_operand:QI 2 "nonmemory_operand" "")))
12738 (clobber (reg:CC FLAGS_REG))]
12739 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12740 ? epilogue_completed : reload_completed)"
12742 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12744 (define_expand "lshrsi3"
12745 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12746 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12747 (match_operand:QI 2 "nonmemory_operand" "")))]
12749 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12751 (define_insn "*lshrsi3_1_one_bit"
12752 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12753 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12754 (match_operand:QI 2 "const1_operand" "")))
12755 (clobber (reg:CC FLAGS_REG))]
12756 "(TARGET_SHIFT1 || optimize_size)
12757 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12759 [(set_attr "type" "ishift")
12760 (set (attr "length")
12761 (if_then_else (match_operand:SI 0 "register_operand" "")
12763 (const_string "*")))])
12765 (define_insn "*lshrsi3_1_one_bit_zext"
12766 [(set (match_operand:DI 0 "register_operand" "=r")
12767 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12768 (match_operand:QI 2 "const1_operand" "")))
12769 (clobber (reg:CC FLAGS_REG))]
12771 && (TARGET_SHIFT1 || optimize_size)
12772 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12774 [(set_attr "type" "ishift")
12775 (set_attr "length" "2")])
12777 (define_insn "*lshrsi3_1"
12778 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12779 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12780 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12781 (clobber (reg:CC FLAGS_REG))]
12782 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12784 shr{l}\t{%2, %0|%0, %2}
12785 shr{l}\t{%b2, %0|%0, %b2}"
12786 [(set_attr "type" "ishift")
12787 (set_attr "mode" "SI")])
12789 (define_insn "*lshrsi3_1_zext"
12790 [(set (match_operand:DI 0 "register_operand" "=r,r")
12792 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12793 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12794 (clobber (reg:CC FLAGS_REG))]
12795 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12797 shr{l}\t{%2, %k0|%k0, %2}
12798 shr{l}\t{%b2, %k0|%k0, %b2}"
12799 [(set_attr "type" "ishift")
12800 (set_attr "mode" "SI")])
12802 ;; This pattern can't accept a variable shift count, since shifts by
12803 ;; zero don't affect the flags. We assume that shifts by constant
12804 ;; zero are optimized away.
12805 (define_insn "*lshrsi3_one_bit_cmp"
12806 [(set (reg FLAGS_REG)
12808 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12809 (match_operand:QI 2 "const1_operand" ""))
12811 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12812 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12813 "(TARGET_SHIFT1 || optimize_size)
12814 && ix86_match_ccmode (insn, CCGOCmode)
12815 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12817 [(set_attr "type" "ishift")
12818 (set (attr "length")
12819 (if_then_else (match_operand:SI 0 "register_operand" "")
12821 (const_string "*")))])
12823 (define_insn "*lshrsi3_one_bit_cconly"
12824 [(set (reg FLAGS_REG)
12826 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12827 (match_operand:QI 2 "const1_operand" ""))
12829 (clobber (match_scratch:SI 0 "=r"))]
12830 "(TARGET_SHIFT1 || optimize_size)
12831 && ix86_match_ccmode (insn, CCGOCmode)
12832 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12834 [(set_attr "type" "ishift")
12835 (set_attr "length" "2")])
12837 (define_insn "*lshrsi3_cmp_one_bit_zext"
12838 [(set (reg FLAGS_REG)
12840 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12841 (match_operand:QI 2 "const1_operand" ""))
12843 (set (match_operand:DI 0 "register_operand" "=r")
12844 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12846 && (TARGET_SHIFT1 || optimize_size)
12847 && ix86_match_ccmode (insn, CCGOCmode)
12848 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12850 [(set_attr "type" "ishift")
12851 (set_attr "length" "2")])
12853 ;; This pattern can't accept a variable shift count, since shifts by
12854 ;; zero don't affect the flags. We assume that shifts by constant
12855 ;; zero are optimized away.
12856 (define_insn "*lshrsi3_cmp"
12857 [(set (reg FLAGS_REG)
12859 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12860 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12862 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12863 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12864 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12865 && ix86_match_ccmode (insn, CCGOCmode)
12866 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12867 "shr{l}\t{%2, %0|%0, %2}"
12868 [(set_attr "type" "ishift")
12869 (set_attr "mode" "SI")])
12871 (define_insn "*lshrsi3_cconly"
12872 [(set (reg FLAGS_REG)
12874 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12875 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12877 (clobber (match_scratch:SI 0 "=r"))]
12878 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12879 && ix86_match_ccmode (insn, CCGOCmode)
12880 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12881 "shr{l}\t{%2, %0|%0, %2}"
12882 [(set_attr "type" "ishift")
12883 (set_attr "mode" "SI")])
12885 (define_insn "*lshrsi3_cmp_zext"
12886 [(set (reg FLAGS_REG)
12888 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12889 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12891 (set (match_operand:DI 0 "register_operand" "=r")
12892 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12894 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12895 && ix86_match_ccmode (insn, CCGOCmode)
12896 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12897 "shr{l}\t{%2, %k0|%k0, %2}"
12898 [(set_attr "type" "ishift")
12899 (set_attr "mode" "SI")])
12901 (define_expand "lshrhi3"
12902 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12903 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12904 (match_operand:QI 2 "nonmemory_operand" "")))]
12905 "TARGET_HIMODE_MATH"
12906 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12908 (define_insn "*lshrhi3_1_one_bit"
12909 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12910 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12911 (match_operand:QI 2 "const1_operand" "")))
12912 (clobber (reg:CC FLAGS_REG))]
12913 "(TARGET_SHIFT1 || optimize_size)
12914 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12916 [(set_attr "type" "ishift")
12917 (set (attr "length")
12918 (if_then_else (match_operand 0 "register_operand" "")
12920 (const_string "*")))])
12922 (define_insn "*lshrhi3_1"
12923 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12924 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12925 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12926 (clobber (reg:CC FLAGS_REG))]
12927 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12929 shr{w}\t{%2, %0|%0, %2}
12930 shr{w}\t{%b2, %0|%0, %b2}"
12931 [(set_attr "type" "ishift")
12932 (set_attr "mode" "HI")])
12934 ;; This pattern can't accept a variable shift count, since shifts by
12935 ;; zero don't affect the flags. We assume that shifts by constant
12936 ;; zero are optimized away.
12937 (define_insn "*lshrhi3_one_bit_cmp"
12938 [(set (reg FLAGS_REG)
12940 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12941 (match_operand:QI 2 "const1_operand" ""))
12943 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12944 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12945 "(TARGET_SHIFT1 || optimize_size)
12946 && ix86_match_ccmode (insn, CCGOCmode)
12947 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12949 [(set_attr "type" "ishift")
12950 (set (attr "length")
12951 (if_then_else (match_operand:SI 0 "register_operand" "")
12953 (const_string "*")))])
12955 (define_insn "*lshrhi3_one_bit_cconly"
12956 [(set (reg FLAGS_REG)
12958 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12959 (match_operand:QI 2 "const1_operand" ""))
12961 (clobber (match_scratch:HI 0 "=r"))]
12962 "(TARGET_SHIFT1 || optimize_size)
12963 && ix86_match_ccmode (insn, CCGOCmode)
12964 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12966 [(set_attr "type" "ishift")
12967 (set_attr "length" "2")])
12969 ;; This pattern can't accept a variable shift count, since shifts by
12970 ;; zero don't affect the flags. We assume that shifts by constant
12971 ;; zero are optimized away.
12972 (define_insn "*lshrhi3_cmp"
12973 [(set (reg FLAGS_REG)
12975 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12976 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12978 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12979 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12980 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12981 && ix86_match_ccmode (insn, CCGOCmode)
12982 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12983 "shr{w}\t{%2, %0|%0, %2}"
12984 [(set_attr "type" "ishift")
12985 (set_attr "mode" "HI")])
12987 (define_insn "*lshrhi3_cconly"
12988 [(set (reg FLAGS_REG)
12990 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12991 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12993 (clobber (match_scratch:HI 0 "=r"))]
12994 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12995 && ix86_match_ccmode (insn, CCGOCmode)
12996 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12997 "shr{w}\t{%2, %0|%0, %2}"
12998 [(set_attr "type" "ishift")
12999 (set_attr "mode" "HI")])
13001 (define_expand "lshrqi3"
13002 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13003 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13004 (match_operand:QI 2 "nonmemory_operand" "")))]
13005 "TARGET_QIMODE_MATH"
13006 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13008 (define_insn "*lshrqi3_1_one_bit"
13009 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13010 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13011 (match_operand:QI 2 "const1_operand" "")))
13012 (clobber (reg:CC FLAGS_REG))]
13013 "(TARGET_SHIFT1 || optimize_size)
13014 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13016 [(set_attr "type" "ishift")
13017 (set (attr "length")
13018 (if_then_else (match_operand 0 "register_operand" "")
13020 (const_string "*")))])
13022 (define_insn "*lshrqi3_1_one_bit_slp"
13023 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13024 (lshiftrt:QI (match_dup 0)
13025 (match_operand:QI 1 "const1_operand" "")))
13026 (clobber (reg:CC FLAGS_REG))]
13027 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13028 && (TARGET_SHIFT1 || optimize_size)"
13030 [(set_attr "type" "ishift1")
13031 (set (attr "length")
13032 (if_then_else (match_operand 0 "register_operand" "")
13034 (const_string "*")))])
13036 (define_insn "*lshrqi3_1"
13037 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13038 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13039 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13040 (clobber (reg:CC FLAGS_REG))]
13041 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13043 shr{b}\t{%2, %0|%0, %2}
13044 shr{b}\t{%b2, %0|%0, %b2}"
13045 [(set_attr "type" "ishift")
13046 (set_attr "mode" "QI")])
13048 (define_insn "*lshrqi3_1_slp"
13049 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13050 (lshiftrt:QI (match_dup 0)
13051 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13052 (clobber (reg:CC FLAGS_REG))]
13053 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13054 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13056 shr{b}\t{%1, %0|%0, %1}
13057 shr{b}\t{%b1, %0|%0, %b1}"
13058 [(set_attr "type" "ishift1")
13059 (set_attr "mode" "QI")])
13061 ;; This pattern can't accept a variable shift count, since shifts by
13062 ;; zero don't affect the flags. We assume that shifts by constant
13063 ;; zero are optimized away.
13064 (define_insn "*lshrqi2_one_bit_cmp"
13065 [(set (reg FLAGS_REG)
13067 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13068 (match_operand:QI 2 "const1_operand" ""))
13070 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13071 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13072 "(TARGET_SHIFT1 || optimize_size)
13073 && ix86_match_ccmode (insn, CCGOCmode)
13074 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13076 [(set_attr "type" "ishift")
13077 (set (attr "length")
13078 (if_then_else (match_operand:SI 0 "register_operand" "")
13080 (const_string "*")))])
13082 (define_insn "*lshrqi2_one_bit_cconly"
13083 [(set (reg FLAGS_REG)
13085 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13086 (match_operand:QI 2 "const1_operand" ""))
13088 (clobber (match_scratch:QI 0 "=q"))]
13089 "(TARGET_SHIFT1 || optimize_size)
13090 && ix86_match_ccmode (insn, CCGOCmode)
13091 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13093 [(set_attr "type" "ishift")
13094 (set_attr "length" "2")])
13096 ;; This pattern can't accept a variable shift count, since shifts by
13097 ;; zero don't affect the flags. We assume that shifts by constant
13098 ;; zero are optimized away.
13099 (define_insn "*lshrqi2_cmp"
13100 [(set (reg FLAGS_REG)
13102 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13103 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13105 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13106 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13107 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13108 && ix86_match_ccmode (insn, CCGOCmode)
13109 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13110 "shr{b}\t{%2, %0|%0, %2}"
13111 [(set_attr "type" "ishift")
13112 (set_attr "mode" "QI")])
13114 (define_insn "*lshrqi2_cconly"
13115 [(set (reg FLAGS_REG)
13117 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13118 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13120 (clobber (match_scratch:QI 0 "=q"))]
13121 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13122 && ix86_match_ccmode (insn, CCGOCmode)
13123 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13124 "shr{b}\t{%2, %0|%0, %2}"
13125 [(set_attr "type" "ishift")
13126 (set_attr "mode" "QI")])
13128 ;; Rotate instructions
13130 (define_expand "rotldi3"
13131 [(set (match_operand:DI 0 "shiftdi_operand" "")
13132 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13133 (match_operand:QI 2 "nonmemory_operand" "")))]
13138 ix86_expand_binary_operator (ROTATE, DImode, operands);
13141 if (!const_1_to_31_operand (operands[2], VOIDmode))
13143 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13147 ;; Implement rotation using two double-precision shift instructions
13148 ;; and a scratch register.
13149 (define_insn_and_split "ix86_rotldi3"
13150 [(set (match_operand:DI 0 "register_operand" "=r")
13151 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13152 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13153 (clobber (reg:CC FLAGS_REG))
13154 (clobber (match_scratch:SI 3 "=&r"))]
13157 "&& reload_completed"
13158 [(set (match_dup 3) (match_dup 4))
13160 [(set (match_dup 4)
13161 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13162 (lshiftrt:SI (match_dup 5)
13163 (minus:QI (const_int 32) (match_dup 2)))))
13164 (clobber (reg:CC FLAGS_REG))])
13166 [(set (match_dup 5)
13167 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13168 (lshiftrt:SI (match_dup 3)
13169 (minus:QI (const_int 32) (match_dup 2)))))
13170 (clobber (reg:CC FLAGS_REG))])]
13171 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13173 (define_insn "*rotlsi3_1_one_bit_rex64"
13174 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13175 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13176 (match_operand:QI 2 "const1_operand" "")))
13177 (clobber (reg:CC FLAGS_REG))]
13179 && (TARGET_SHIFT1 || optimize_size)
13180 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13182 [(set_attr "type" "rotate")
13183 (set (attr "length")
13184 (if_then_else (match_operand:DI 0 "register_operand" "")
13186 (const_string "*")))])
13188 (define_insn "*rotldi3_1_rex64"
13189 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13190 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13191 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13192 (clobber (reg:CC FLAGS_REG))]
13193 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13195 rol{q}\t{%2, %0|%0, %2}
13196 rol{q}\t{%b2, %0|%0, %b2}"
13197 [(set_attr "type" "rotate")
13198 (set_attr "mode" "DI")])
13200 (define_expand "rotlsi3"
13201 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13202 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13203 (match_operand:QI 2 "nonmemory_operand" "")))]
13205 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13207 (define_insn "*rotlsi3_1_one_bit"
13208 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13209 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13210 (match_operand:QI 2 "const1_operand" "")))
13211 (clobber (reg:CC FLAGS_REG))]
13212 "(TARGET_SHIFT1 || optimize_size)
13213 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13215 [(set_attr "type" "rotate")
13216 (set (attr "length")
13217 (if_then_else (match_operand:SI 0 "register_operand" "")
13219 (const_string "*")))])
13221 (define_insn "*rotlsi3_1_one_bit_zext"
13222 [(set (match_operand:DI 0 "register_operand" "=r")
13224 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13225 (match_operand:QI 2 "const1_operand" ""))))
13226 (clobber (reg:CC FLAGS_REG))]
13228 && (TARGET_SHIFT1 || optimize_size)
13229 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13231 [(set_attr "type" "rotate")
13232 (set_attr "length" "2")])
13234 (define_insn "*rotlsi3_1"
13235 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13236 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13237 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13238 (clobber (reg:CC FLAGS_REG))]
13239 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13241 rol{l}\t{%2, %0|%0, %2}
13242 rol{l}\t{%b2, %0|%0, %b2}"
13243 [(set_attr "type" "rotate")
13244 (set_attr "mode" "SI")])
13246 (define_insn "*rotlsi3_1_zext"
13247 [(set (match_operand:DI 0 "register_operand" "=r,r")
13249 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13250 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13251 (clobber (reg:CC FLAGS_REG))]
13252 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13254 rol{l}\t{%2, %k0|%k0, %2}
13255 rol{l}\t{%b2, %k0|%k0, %b2}"
13256 [(set_attr "type" "rotate")
13257 (set_attr "mode" "SI")])
13259 (define_expand "rotlhi3"
13260 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13261 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13262 (match_operand:QI 2 "nonmemory_operand" "")))]
13263 "TARGET_HIMODE_MATH"
13264 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13266 (define_insn "*rotlhi3_1_one_bit"
13267 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13268 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13269 (match_operand:QI 2 "const1_operand" "")))
13270 (clobber (reg:CC FLAGS_REG))]
13271 "(TARGET_SHIFT1 || optimize_size)
13272 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13274 [(set_attr "type" "rotate")
13275 (set (attr "length")
13276 (if_then_else (match_operand 0 "register_operand" "")
13278 (const_string "*")))])
13280 (define_insn "*rotlhi3_1"
13281 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13282 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13283 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13284 (clobber (reg:CC FLAGS_REG))]
13285 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13287 rol{w}\t{%2, %0|%0, %2}
13288 rol{w}\t{%b2, %0|%0, %b2}"
13289 [(set_attr "type" "rotate")
13290 (set_attr "mode" "HI")])
13293 [(set (match_operand:HI 0 "register_operand" "")
13294 (rotate:HI (match_dup 0) (const_int 8)))
13295 (clobber (reg:CC FLAGS_REG))]
13297 [(parallel [(set (strict_low_part (match_dup 0))
13298 (bswap:HI (match_dup 0)))
13299 (clobber (reg:CC FLAGS_REG))])]
13302 (define_expand "rotlqi3"
13303 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13304 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13305 (match_operand:QI 2 "nonmemory_operand" "")))]
13306 "TARGET_QIMODE_MATH"
13307 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13309 (define_insn "*rotlqi3_1_one_bit_slp"
13310 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13311 (rotate:QI (match_dup 0)
13312 (match_operand:QI 1 "const1_operand" "")))
13313 (clobber (reg:CC FLAGS_REG))]
13314 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13315 && (TARGET_SHIFT1 || optimize_size)"
13317 [(set_attr "type" "rotate1")
13318 (set (attr "length")
13319 (if_then_else (match_operand 0 "register_operand" "")
13321 (const_string "*")))])
13323 (define_insn "*rotlqi3_1_one_bit"
13324 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13325 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13326 (match_operand:QI 2 "const1_operand" "")))
13327 (clobber (reg:CC FLAGS_REG))]
13328 "(TARGET_SHIFT1 || optimize_size)
13329 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13331 [(set_attr "type" "rotate")
13332 (set (attr "length")
13333 (if_then_else (match_operand 0 "register_operand" "")
13335 (const_string "*")))])
13337 (define_insn "*rotlqi3_1_slp"
13338 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13339 (rotate:QI (match_dup 0)
13340 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13341 (clobber (reg:CC FLAGS_REG))]
13342 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13343 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13345 rol{b}\t{%1, %0|%0, %1}
13346 rol{b}\t{%b1, %0|%0, %b1}"
13347 [(set_attr "type" "rotate1")
13348 (set_attr "mode" "QI")])
13350 (define_insn "*rotlqi3_1"
13351 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13352 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13353 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13354 (clobber (reg:CC FLAGS_REG))]
13355 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13357 rol{b}\t{%2, %0|%0, %2}
13358 rol{b}\t{%b2, %0|%0, %b2}"
13359 [(set_attr "type" "rotate")
13360 (set_attr "mode" "QI")])
13362 (define_expand "rotrdi3"
13363 [(set (match_operand:DI 0 "shiftdi_operand" "")
13364 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13365 (match_operand:QI 2 "nonmemory_operand" "")))]
13370 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13373 if (!const_1_to_31_operand (operands[2], VOIDmode))
13375 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13379 ;; Implement rotation using two double-precision shift instructions
13380 ;; and a scratch register.
13381 (define_insn_and_split "ix86_rotrdi3"
13382 [(set (match_operand:DI 0 "register_operand" "=r")
13383 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13384 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13385 (clobber (reg:CC FLAGS_REG))
13386 (clobber (match_scratch:SI 3 "=&r"))]
13389 "&& reload_completed"
13390 [(set (match_dup 3) (match_dup 4))
13392 [(set (match_dup 4)
13393 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13394 (ashift:SI (match_dup 5)
13395 (minus:QI (const_int 32) (match_dup 2)))))
13396 (clobber (reg:CC FLAGS_REG))])
13398 [(set (match_dup 5)
13399 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13400 (ashift:SI (match_dup 3)
13401 (minus:QI (const_int 32) (match_dup 2)))))
13402 (clobber (reg:CC FLAGS_REG))])]
13403 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13405 (define_insn "*rotrdi3_1_one_bit_rex64"
13406 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13407 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13408 (match_operand:QI 2 "const1_operand" "")))
13409 (clobber (reg:CC FLAGS_REG))]
13411 && (TARGET_SHIFT1 || optimize_size)
13412 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13414 [(set_attr "type" "rotate")
13415 (set (attr "length")
13416 (if_then_else (match_operand:DI 0 "register_operand" "")
13418 (const_string "*")))])
13420 (define_insn "*rotrdi3_1_rex64"
13421 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13422 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13423 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13424 (clobber (reg:CC FLAGS_REG))]
13425 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13427 ror{q}\t{%2, %0|%0, %2}
13428 ror{q}\t{%b2, %0|%0, %b2}"
13429 [(set_attr "type" "rotate")
13430 (set_attr "mode" "DI")])
13432 (define_expand "rotrsi3"
13433 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13434 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13435 (match_operand:QI 2 "nonmemory_operand" "")))]
13437 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13439 (define_insn "*rotrsi3_1_one_bit"
13440 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13441 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13442 (match_operand:QI 2 "const1_operand" "")))
13443 (clobber (reg:CC FLAGS_REG))]
13444 "(TARGET_SHIFT1 || optimize_size)
13445 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13447 [(set_attr "type" "rotate")
13448 (set (attr "length")
13449 (if_then_else (match_operand:SI 0 "register_operand" "")
13451 (const_string "*")))])
13453 (define_insn "*rotrsi3_1_one_bit_zext"
13454 [(set (match_operand:DI 0 "register_operand" "=r")
13456 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13457 (match_operand:QI 2 "const1_operand" ""))))
13458 (clobber (reg:CC FLAGS_REG))]
13460 && (TARGET_SHIFT1 || optimize_size)
13461 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13463 [(set_attr "type" "rotate")
13464 (set (attr "length")
13465 (if_then_else (match_operand:SI 0 "register_operand" "")
13467 (const_string "*")))])
13469 (define_insn "*rotrsi3_1"
13470 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13471 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13472 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13473 (clobber (reg:CC FLAGS_REG))]
13474 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13476 ror{l}\t{%2, %0|%0, %2}
13477 ror{l}\t{%b2, %0|%0, %b2}"
13478 [(set_attr "type" "rotate")
13479 (set_attr "mode" "SI")])
13481 (define_insn "*rotrsi3_1_zext"
13482 [(set (match_operand:DI 0 "register_operand" "=r,r")
13484 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13485 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13486 (clobber (reg:CC FLAGS_REG))]
13487 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13489 ror{l}\t{%2, %k0|%k0, %2}
13490 ror{l}\t{%b2, %k0|%k0, %b2}"
13491 [(set_attr "type" "rotate")
13492 (set_attr "mode" "SI")])
13494 (define_expand "rotrhi3"
13495 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13496 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13497 (match_operand:QI 2 "nonmemory_operand" "")))]
13498 "TARGET_HIMODE_MATH"
13499 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13501 (define_insn "*rotrhi3_one_bit"
13502 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13503 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13504 (match_operand:QI 2 "const1_operand" "")))
13505 (clobber (reg:CC FLAGS_REG))]
13506 "(TARGET_SHIFT1 || optimize_size)
13507 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13509 [(set_attr "type" "rotate")
13510 (set (attr "length")
13511 (if_then_else (match_operand 0 "register_operand" "")
13513 (const_string "*")))])
13515 (define_insn "*rotrhi3_1"
13516 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13517 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13518 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13519 (clobber (reg:CC FLAGS_REG))]
13520 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13522 ror{w}\t{%2, %0|%0, %2}
13523 ror{w}\t{%b2, %0|%0, %b2}"
13524 [(set_attr "type" "rotate")
13525 (set_attr "mode" "HI")])
13528 [(set (match_operand:HI 0 "register_operand" "")
13529 (rotatert:HI (match_dup 0) (const_int 8)))
13530 (clobber (reg:CC FLAGS_REG))]
13532 [(parallel [(set (strict_low_part (match_dup 0))
13533 (bswap:HI (match_dup 0)))
13534 (clobber (reg:CC FLAGS_REG))])]
13537 (define_expand "rotrqi3"
13538 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13539 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13540 (match_operand:QI 2 "nonmemory_operand" "")))]
13541 "TARGET_QIMODE_MATH"
13542 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13544 (define_insn "*rotrqi3_1_one_bit"
13545 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13546 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13547 (match_operand:QI 2 "const1_operand" "")))
13548 (clobber (reg:CC FLAGS_REG))]
13549 "(TARGET_SHIFT1 || optimize_size)
13550 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13552 [(set_attr "type" "rotate")
13553 (set (attr "length")
13554 (if_then_else (match_operand 0 "register_operand" "")
13556 (const_string "*")))])
13558 (define_insn "*rotrqi3_1_one_bit_slp"
13559 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13560 (rotatert:QI (match_dup 0)
13561 (match_operand:QI 1 "const1_operand" "")))
13562 (clobber (reg:CC FLAGS_REG))]
13563 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13564 && (TARGET_SHIFT1 || optimize_size)"
13566 [(set_attr "type" "rotate1")
13567 (set (attr "length")
13568 (if_then_else (match_operand 0 "register_operand" "")
13570 (const_string "*")))])
13572 (define_insn "*rotrqi3_1"
13573 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13574 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13575 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13576 (clobber (reg:CC FLAGS_REG))]
13577 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13579 ror{b}\t{%2, %0|%0, %2}
13580 ror{b}\t{%b2, %0|%0, %b2}"
13581 [(set_attr "type" "rotate")
13582 (set_attr "mode" "QI")])
13584 (define_insn "*rotrqi3_1_slp"
13585 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13586 (rotatert:QI (match_dup 0)
13587 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13588 (clobber (reg:CC FLAGS_REG))]
13589 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13590 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13592 ror{b}\t{%1, %0|%0, %1}
13593 ror{b}\t{%b1, %0|%0, %b1}"
13594 [(set_attr "type" "rotate1")
13595 (set_attr "mode" "QI")])
13597 ;; Bit set / bit test instructions
13599 (define_expand "extv"
13600 [(set (match_operand:SI 0 "register_operand" "")
13601 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13602 (match_operand:SI 2 "const8_operand" "")
13603 (match_operand:SI 3 "const8_operand" "")))]
13606 /* Handle extractions from %ah et al. */
13607 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13610 /* From mips.md: extract_bit_field doesn't verify that our source
13611 matches the predicate, so check it again here. */
13612 if (! ext_register_operand (operands[1], VOIDmode))
13616 (define_expand "extzv"
13617 [(set (match_operand:SI 0 "register_operand" "")
13618 (zero_extract:SI (match_operand 1 "ext_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 "insv"
13634 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13635 (match_operand 1 "const8_operand" "")
13636 (match_operand 2 "const8_operand" ""))
13637 (match_operand 3 "register_operand" ""))]
13640 /* Handle insertions to %ah et al. */
13641 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13644 /* From mips.md: insert_bit_field doesn't verify that our source
13645 matches the predicate, so check it again here. */
13646 if (! ext_register_operand (operands[0], VOIDmode))
13650 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13652 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13657 ;; %%% bts, btr, btc, bt.
13658 ;; In general these instructions are *slow* when applied to memory,
13659 ;; since they enforce atomic operation. When applied to registers,
13660 ;; it depends on the cpu implementation. They're never faster than
13661 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13662 ;; no point. But in 64-bit, we can't hold the relevant immediates
13663 ;; within the instruction itself, so operating on bits in the high
13664 ;; 32-bits of a register becomes easier.
13666 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13667 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13668 ;; negdf respectively, so they can never be disabled entirely.
13670 (define_insn "*btsq"
13671 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13673 (match_operand:DI 1 "const_0_to_63_operand" ""))
13675 (clobber (reg:CC FLAGS_REG))]
13676 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13677 "bts{q}\t{%1, %0|%0, %1}"
13678 [(set_attr "type" "alu1")])
13680 (define_insn "*btrq"
13681 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13683 (match_operand:DI 1 "const_0_to_63_operand" ""))
13685 (clobber (reg:CC FLAGS_REG))]
13686 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13687 "btr{q}\t{%1, %0|%0, %1}"
13688 [(set_attr "type" "alu1")])
13690 (define_insn "*btcq"
13691 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13693 (match_operand:DI 1 "const_0_to_63_operand" ""))
13694 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13695 (clobber (reg:CC FLAGS_REG))]
13696 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13697 "btc{q}\t{%1, %0|%0, %1}"
13698 [(set_attr "type" "alu1")])
13700 ;; Allow Nocona to avoid these instructions if a register is available.
13703 [(match_scratch:DI 2 "r")
13704 (parallel [(set (zero_extract:DI
13705 (match_operand:DI 0 "register_operand" "")
13707 (match_operand:DI 1 "const_0_to_63_operand" ""))
13709 (clobber (reg:CC FLAGS_REG))])]
13710 "TARGET_64BIT && !TARGET_USE_BT"
13713 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13716 if (HOST_BITS_PER_WIDE_INT >= 64)
13717 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13718 else if (i < HOST_BITS_PER_WIDE_INT)
13719 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13721 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13723 op1 = immed_double_const (lo, hi, DImode);
13726 emit_move_insn (operands[2], op1);
13730 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13735 [(match_scratch:DI 2 "r")
13736 (parallel [(set (zero_extract:DI
13737 (match_operand:DI 0 "register_operand" "")
13739 (match_operand:DI 1 "const_0_to_63_operand" ""))
13741 (clobber (reg:CC FLAGS_REG))])]
13742 "TARGET_64BIT && !TARGET_USE_BT"
13745 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13748 if (HOST_BITS_PER_WIDE_INT >= 64)
13749 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13750 else if (i < HOST_BITS_PER_WIDE_INT)
13751 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13753 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13755 op1 = immed_double_const (~lo, ~hi, DImode);
13758 emit_move_insn (operands[2], op1);
13762 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13767 [(match_scratch:DI 2 "r")
13768 (parallel [(set (zero_extract:DI
13769 (match_operand:DI 0 "register_operand" "")
13771 (match_operand:DI 1 "const_0_to_63_operand" ""))
13772 (not:DI (zero_extract:DI
13773 (match_dup 0) (const_int 1) (match_dup 1))))
13774 (clobber (reg:CC FLAGS_REG))])]
13775 "TARGET_64BIT && !TARGET_USE_BT"
13778 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13781 if (HOST_BITS_PER_WIDE_INT >= 64)
13782 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13783 else if (i < HOST_BITS_PER_WIDE_INT)
13784 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13786 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13788 op1 = immed_double_const (lo, hi, DImode);
13791 emit_move_insn (operands[2], op1);
13795 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13799 (define_insn "*btdi_rex64"
13800 [(set (reg:CCC FLAGS_REG)
13803 (match_operand:DI 0 "register_operand" "r")
13805 (match_operand:DI 1 "nonmemory_operand" "rN"))
13807 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
13808 "bt{q}\t{%1, %0|%0, %1}"
13809 [(set_attr "type" "alu1")])
13811 (define_insn "*btsi"
13812 [(set (reg:CCC FLAGS_REG)
13815 (match_operand:SI 0 "register_operand" "r")
13817 (match_operand:SI 1 "nonmemory_operand" "rN"))
13819 "TARGET_USE_BT || optimize_size"
13820 "bt{l}\t{%1, %0|%0, %1}"
13821 [(set_attr "type" "alu1")])
13823 ;; Store-flag instructions.
13825 ;; For all sCOND expanders, also expand the compare or test insn that
13826 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13828 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13829 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13830 ;; way, which can later delete the movzx if only QImode is needed.
13832 (define_expand "s<code>"
13833 [(set (match_operand:QI 0 "register_operand" "")
13834 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13836 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13838 (define_expand "s<code>"
13839 [(set (match_operand:QI 0 "register_operand" "")
13840 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13841 "TARGET_80387 || TARGET_SSE"
13842 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13844 (define_insn "*setcc_1"
13845 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13846 (match_operator:QI 1 "ix86_comparison_operator"
13847 [(reg FLAGS_REG) (const_int 0)]))]
13850 [(set_attr "type" "setcc")
13851 (set_attr "mode" "QI")])
13853 (define_insn "*setcc_2"
13854 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13855 (match_operator:QI 1 "ix86_comparison_operator"
13856 [(reg FLAGS_REG) (const_int 0)]))]
13859 [(set_attr "type" "setcc")
13860 (set_attr "mode" "QI")])
13862 ;; In general it is not safe to assume too much about CCmode registers,
13863 ;; so simplify-rtx stops when it sees a second one. Under certain
13864 ;; conditions this is safe on x86, so help combine not create
13871 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13872 (ne:QI (match_operator 1 "ix86_comparison_operator"
13873 [(reg FLAGS_REG) (const_int 0)])
13876 [(set (match_dup 0) (match_dup 1))]
13878 PUT_MODE (operands[1], QImode);
13882 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13883 (ne:QI (match_operator 1 "ix86_comparison_operator"
13884 [(reg FLAGS_REG) (const_int 0)])
13887 [(set (match_dup 0) (match_dup 1))]
13889 PUT_MODE (operands[1], QImode);
13893 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13894 (eq:QI (match_operator 1 "ix86_comparison_operator"
13895 [(reg FLAGS_REG) (const_int 0)])
13898 [(set (match_dup 0) (match_dup 1))]
13900 rtx new_op1 = copy_rtx (operands[1]);
13901 operands[1] = new_op1;
13902 PUT_MODE (new_op1, QImode);
13903 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13904 GET_MODE (XEXP (new_op1, 0))));
13906 /* Make sure that (a) the CCmode we have for the flags is strong
13907 enough for the reversed compare or (b) we have a valid FP compare. */
13908 if (! ix86_comparison_operator (new_op1, VOIDmode))
13913 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13914 (eq:QI (match_operator 1 "ix86_comparison_operator"
13915 [(reg FLAGS_REG) (const_int 0)])
13918 [(set (match_dup 0) (match_dup 1))]
13920 rtx new_op1 = copy_rtx (operands[1]);
13921 operands[1] = new_op1;
13922 PUT_MODE (new_op1, QImode);
13923 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13924 GET_MODE (XEXP (new_op1, 0))));
13926 /* Make sure that (a) the CCmode we have for the flags is strong
13927 enough for the reversed compare or (b) we have a valid FP compare. */
13928 if (! ix86_comparison_operator (new_op1, VOIDmode))
13932 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13933 ;; subsequent logical operations are used to imitate conditional moves.
13934 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13937 (define_insn "*sse_setcc<mode>"
13938 [(set (match_operand:MODEF 0 "register_operand" "=x")
13939 (match_operator:MODEF 1 "sse_comparison_operator"
13940 [(match_operand:MODEF 2 "register_operand" "0")
13941 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13942 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13943 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13944 [(set_attr "type" "ssecmp")
13945 (set_attr "mode" "<MODE>")])
13947 (define_insn "*sse5_setcc<mode>"
13948 [(set (match_operand:MODEF 0 "register_operand" "=x")
13949 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13950 [(match_operand:MODEF 2 "register_operand" "x")
13951 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13953 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13954 [(set_attr "type" "sse4arg")
13955 (set_attr "mode" "<MODE>")])
13958 ;; Basic conditional jump instructions.
13959 ;; We ignore the overflow flag for signed branch instructions.
13961 ;; For all bCOND expanders, also expand the compare or test insn that
13962 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13964 (define_expand "b<code>"
13966 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13968 (label_ref (match_operand 0 ""))
13971 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13973 (define_expand "b<code>"
13975 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13977 (label_ref (match_operand 0 ""))
13979 "TARGET_80387 || TARGET_SSE_MATH"
13980 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13982 (define_insn "*jcc_1"
13984 (if_then_else (match_operator 1 "ix86_comparison_operator"
13985 [(reg FLAGS_REG) (const_int 0)])
13986 (label_ref (match_operand 0 "" ""))
13990 [(set_attr "type" "ibr")
13991 (set_attr "modrm" "0")
13992 (set (attr "length")
13993 (if_then_else (and (ge (minus (match_dup 0) (pc))
13995 (lt (minus (match_dup 0) (pc))
14000 (define_insn "*jcc_2"
14002 (if_then_else (match_operator 1 "ix86_comparison_operator"
14003 [(reg FLAGS_REG) (const_int 0)])
14005 (label_ref (match_operand 0 "" ""))))]
14008 [(set_attr "type" "ibr")
14009 (set_attr "modrm" "0")
14010 (set (attr "length")
14011 (if_then_else (and (ge (minus (match_dup 0) (pc))
14013 (lt (minus (match_dup 0) (pc))
14018 ;; ??? Handle alignment requirements for compare and branch fused macro-op;
14019 ;; the branch instruction does not start at a 16-byte boundary or cross
14020 ;; a 16-byte boundary.
14022 (define_insn "*jcc_fused_1"
14024 (if_then_else (match_operator 1 "comparison_operator"
14025 [(match_operand:SWI 2 "register_operand" "<r>")
14026 (match_operand:SWI 3 "const0_operand" "")])
14027 (label_ref (match_operand 0 "" ""))
14029 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
14031 return "test{<imodesuffix>}\t%2, %2\n\t"
14032 "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
14034 [(set_attr "type" "multi")
14035 (set_attr "mode" "<MODE>")])
14037 (define_insn "*jcc_fused_2"
14039 (if_then_else (match_operator 1 "comparison_operator"
14040 [(match_operand:SWI 2 "register_operand" "<r>")
14041 (match_operand:SWI 3 "const0_operand" "")])
14043 (label_ref (match_operand 0 "" ""))))]
14044 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
14046 return "test{<imodesuffix>}\t%2, %2\n\t"
14047 "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
14049 [(set_attr "type" "multi")
14050 (set_attr "mode" "<MODE>")])
14052 (define_insn "*jcc_fused_3"
14055 (match_operator 1 "ix86_comparison_uns_operator"
14056 [(match_operand:SWI 2 "nonimmediate_operand" "<r>,m,<r>")
14057 (match_operand:SWI 3 "<general_operand>" "<r><i>,<r>,m")])
14058 (label_ref (match_operand 0 "" ""))
14060 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
14061 && !(MEM_P (operands[2])
14062 && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
14064 return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
14065 "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
14067 [(set_attr "type" "multi")
14068 (set_attr "mode" "<MODE>")])
14070 (define_insn "*jcc_fused_4"
14073 (match_operator 1 "ix86_comparison_uns_operator"
14074 [(match_operand:SWI 2 "nonimmediate_operand" "<r>,m,<r>")
14075 (match_operand:SWI 3 "<general_operand>" "<r><i>,<r>,m")])
14077 (label_ref (match_operand 0 "" ""))))]
14078 "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
14079 && !(MEM_P (operands[2])
14080 && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
14082 return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
14083 "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
14085 [(set_attr "type" "multi")
14086 (set_attr "mode" "<MODE>")])
14088 ;; In general it is not safe to assume too much about CCmode registers,
14089 ;; so simplify-rtx stops when it sees a second one. Under certain
14090 ;; conditions this is safe on x86, so help combine not create
14098 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14099 [(reg FLAGS_REG) (const_int 0)])
14101 (label_ref (match_operand 1 "" ""))
14105 (if_then_else (match_dup 0)
14106 (label_ref (match_dup 1))
14109 PUT_MODE (operands[0], VOIDmode);
14114 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14115 [(reg FLAGS_REG) (const_int 0)])
14117 (label_ref (match_operand 1 "" ""))
14121 (if_then_else (match_dup 0)
14122 (label_ref (match_dup 1))
14125 rtx new_op0 = copy_rtx (operands[0]);
14126 operands[0] = new_op0;
14127 PUT_MODE (new_op0, VOIDmode);
14128 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14129 GET_MODE (XEXP (new_op0, 0))));
14131 /* Make sure that (a) the CCmode we have for the flags is strong
14132 enough for the reversed compare or (b) we have a valid FP compare. */
14133 if (! ix86_comparison_operator (new_op0, VOIDmode))
14137 ;; zero_extend in SImode is correct, since this is what combine pass
14138 ;; generates from shift insn with QImode operand. Actually, the mode of
14139 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14140 ;; appropriate modulo of the bit offset value.
14142 (define_insn_and_split "*jcc_btdi_rex64"
14144 (if_then_else (match_operator 0 "bt_comparison_operator"
14146 (match_operand:DI 1 "register_operand" "r")
14149 (match_operand:QI 2 "register_operand" "r")))
14151 (label_ref (match_operand 3 "" ""))
14153 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
14156 [(set (reg:CCC FLAGS_REG)
14164 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14165 (label_ref (match_dup 3))
14168 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14170 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14173 ;; avoid useless masking of bit offset operand
14174 (define_insn_and_split "*jcc_btdi_mask_rex64"
14176 (if_then_else (match_operator 0 "bt_comparison_operator"
14178 (match_operand:DI 1 "register_operand" "r")
14181 (match_operand:SI 2 "register_operand" "r")
14182 (match_operand:SI 3 "const_int_operand" "n")))])
14183 (label_ref (match_operand 4 "" ""))
14185 "TARGET_64BIT && (TARGET_USE_BT || optimize_size)
14186 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14189 [(set (reg:CCC FLAGS_REG)
14197 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14198 (label_ref (match_dup 4))
14201 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14203 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14206 (define_insn_and_split "*jcc_btsi"
14208 (if_then_else (match_operator 0 "bt_comparison_operator"
14210 (match_operand:SI 1 "register_operand" "r")
14213 (match_operand:QI 2 "register_operand" "r")))
14215 (label_ref (match_operand 3 "" ""))
14217 "TARGET_USE_BT || optimize_size"
14220 [(set (reg:CCC FLAGS_REG)
14228 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14229 (label_ref (match_dup 3))
14232 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14234 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14237 ;; avoid useless masking of bit offset operand
14238 (define_insn_and_split "*jcc_btsi_mask"
14240 (if_then_else (match_operator 0 "bt_comparison_operator"
14242 (match_operand:SI 1 "register_operand" "r")
14245 (match_operand:SI 2 "register_operand" "r")
14246 (match_operand:SI 3 "const_int_operand" "n")))])
14247 (label_ref (match_operand 4 "" ""))
14249 "(TARGET_USE_BT || optimize_size)
14250 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14253 [(set (reg:CCC FLAGS_REG)
14261 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14262 (label_ref (match_dup 4))
14264 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14266 (define_insn_and_split "*jcc_btsi_1"
14268 (if_then_else (match_operator 0 "bt_comparison_operator"
14271 (match_operand:SI 1 "register_operand" "r")
14272 (match_operand:QI 2 "register_operand" "r"))
14275 (label_ref (match_operand 3 "" ""))
14277 "TARGET_USE_BT || optimize_size"
14280 [(set (reg:CCC FLAGS_REG)
14288 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14289 (label_ref (match_dup 3))
14292 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14294 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14297 ;; avoid useless masking of bit offset operand
14298 (define_insn_and_split "*jcc_btsi_mask_1"
14301 (match_operator 0 "bt_comparison_operator"
14304 (match_operand:SI 1 "register_operand" "r")
14307 (match_operand:SI 2 "register_operand" "r")
14308 (match_operand:SI 3 "const_int_operand" "n")) 0))
14311 (label_ref (match_operand 4 "" ""))
14313 "(TARGET_USE_BT || optimize_size)
14314 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14317 [(set (reg:CCC FLAGS_REG)
14325 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14326 (label_ref (match_dup 4))
14328 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14330 ;; Define combination compare-and-branch fp compare instructions to use
14331 ;; during early optimization. Splitting the operation apart early makes
14332 ;; for bad code when we want to reverse the operation.
14334 (define_insn "*fp_jcc_1_mixed"
14336 (if_then_else (match_operator 0 "comparison_operator"
14337 [(match_operand 1 "register_operand" "f,x")
14338 (match_operand 2 "nonimmediate_operand" "f,xm")])
14339 (label_ref (match_operand 3 "" ""))
14341 (clobber (reg:CCFP FPSR_REG))
14342 (clobber (reg:CCFP FLAGS_REG))]
14343 "TARGET_MIX_SSE_I387
14344 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14345 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14346 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14349 (define_insn "*fp_jcc_1_sse"
14351 (if_then_else (match_operator 0 "comparison_operator"
14352 [(match_operand 1 "register_operand" "x")
14353 (match_operand 2 "nonimmediate_operand" "xm")])
14354 (label_ref (match_operand 3 "" ""))
14356 (clobber (reg:CCFP FPSR_REG))
14357 (clobber (reg:CCFP FLAGS_REG))]
14359 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14360 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14361 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14364 (define_insn "*fp_jcc_1_387"
14366 (if_then_else (match_operator 0 "comparison_operator"
14367 [(match_operand 1 "register_operand" "f")
14368 (match_operand 2 "register_operand" "f")])
14369 (label_ref (match_operand 3 "" ""))
14371 (clobber (reg:CCFP FPSR_REG))
14372 (clobber (reg:CCFP FLAGS_REG))]
14373 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14375 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14376 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14379 (define_insn "*fp_jcc_2_mixed"
14381 (if_then_else (match_operator 0 "comparison_operator"
14382 [(match_operand 1 "register_operand" "f,x")
14383 (match_operand 2 "nonimmediate_operand" "f,xm")])
14385 (label_ref (match_operand 3 "" ""))))
14386 (clobber (reg:CCFP FPSR_REG))
14387 (clobber (reg:CCFP FLAGS_REG))]
14388 "TARGET_MIX_SSE_I387
14389 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14390 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14391 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14394 (define_insn "*fp_jcc_2_sse"
14396 (if_then_else (match_operator 0 "comparison_operator"
14397 [(match_operand 1 "register_operand" "x")
14398 (match_operand 2 "nonimmediate_operand" "xm")])
14400 (label_ref (match_operand 3 "" ""))))
14401 (clobber (reg:CCFP FPSR_REG))
14402 (clobber (reg:CCFP FLAGS_REG))]
14404 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14405 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14406 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14409 (define_insn "*fp_jcc_2_387"
14411 (if_then_else (match_operator 0 "comparison_operator"
14412 [(match_operand 1 "register_operand" "f")
14413 (match_operand 2 "register_operand" "f")])
14415 (label_ref (match_operand 3 "" ""))))
14416 (clobber (reg:CCFP FPSR_REG))
14417 (clobber (reg:CCFP FLAGS_REG))]
14418 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14420 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14421 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14424 (define_insn "*fp_jcc_3_387"
14426 (if_then_else (match_operator 0 "comparison_operator"
14427 [(match_operand 1 "register_operand" "f")
14428 (match_operand 2 "nonimmediate_operand" "fm")])
14429 (label_ref (match_operand 3 "" ""))
14431 (clobber (reg:CCFP FPSR_REG))
14432 (clobber (reg:CCFP FLAGS_REG))
14433 (clobber (match_scratch:HI 4 "=a"))]
14435 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14436 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14437 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14438 && SELECT_CC_MODE (GET_CODE (operands[0]),
14439 operands[1], operands[2]) == CCFPmode
14440 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14443 (define_insn "*fp_jcc_4_387"
14445 (if_then_else (match_operator 0 "comparison_operator"
14446 [(match_operand 1 "register_operand" "f")
14447 (match_operand 2 "nonimmediate_operand" "fm")])
14449 (label_ref (match_operand 3 "" ""))))
14450 (clobber (reg:CCFP FPSR_REG))
14451 (clobber (reg:CCFP FLAGS_REG))
14452 (clobber (match_scratch:HI 4 "=a"))]
14454 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14455 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14456 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14457 && SELECT_CC_MODE (GET_CODE (operands[0]),
14458 operands[1], operands[2]) == CCFPmode
14459 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14462 (define_insn "*fp_jcc_5_387"
14464 (if_then_else (match_operator 0 "comparison_operator"
14465 [(match_operand 1 "register_operand" "f")
14466 (match_operand 2 "register_operand" "f")])
14467 (label_ref (match_operand 3 "" ""))
14469 (clobber (reg:CCFP FPSR_REG))
14470 (clobber (reg:CCFP FLAGS_REG))
14471 (clobber (match_scratch:HI 4 "=a"))]
14472 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14473 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14474 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14477 (define_insn "*fp_jcc_6_387"
14479 (if_then_else (match_operator 0 "comparison_operator"
14480 [(match_operand 1 "register_operand" "f")
14481 (match_operand 2 "register_operand" "f")])
14483 (label_ref (match_operand 3 "" ""))))
14484 (clobber (reg:CCFP FPSR_REG))
14485 (clobber (reg:CCFP FLAGS_REG))
14486 (clobber (match_scratch:HI 4 "=a"))]
14487 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14488 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14489 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14492 (define_insn "*fp_jcc_7_387"
14494 (if_then_else (match_operator 0 "comparison_operator"
14495 [(match_operand 1 "register_operand" "f")
14496 (match_operand 2 "const0_operand" "")])
14497 (label_ref (match_operand 3 "" ""))
14499 (clobber (reg:CCFP FPSR_REG))
14500 (clobber (reg:CCFP FLAGS_REG))
14501 (clobber (match_scratch:HI 4 "=a"))]
14502 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14503 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14504 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14505 && SELECT_CC_MODE (GET_CODE (operands[0]),
14506 operands[1], operands[2]) == CCFPmode
14507 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14510 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14511 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14512 ;; with a precedence over other operators and is always put in the first
14513 ;; place. Swap condition and operands to match ficom instruction.
14515 (define_insn "*fp_jcc_8<mode>_387"
14517 (if_then_else (match_operator 0 "comparison_operator"
14518 [(match_operator 1 "float_operator"
14519 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14520 (match_operand 3 "register_operand" "f,f")])
14521 (label_ref (match_operand 4 "" ""))
14523 (clobber (reg:CCFP FPSR_REG))
14524 (clobber (reg:CCFP FLAGS_REG))
14525 (clobber (match_scratch:HI 5 "=a,a"))]
14526 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14527 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
14528 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14529 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14530 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14531 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14536 (if_then_else (match_operator 0 "comparison_operator"
14537 [(match_operand 1 "register_operand" "")
14538 (match_operand 2 "nonimmediate_operand" "")])
14539 (match_operand 3 "" "")
14540 (match_operand 4 "" "")))
14541 (clobber (reg:CCFP FPSR_REG))
14542 (clobber (reg:CCFP FLAGS_REG))]
14546 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14547 operands[3], operands[4], NULL_RTX, NULL_RTX);
14553 (if_then_else (match_operator 0 "comparison_operator"
14554 [(match_operand 1 "register_operand" "")
14555 (match_operand 2 "general_operand" "")])
14556 (match_operand 3 "" "")
14557 (match_operand 4 "" "")))
14558 (clobber (reg:CCFP FPSR_REG))
14559 (clobber (reg:CCFP FLAGS_REG))
14560 (clobber (match_scratch:HI 5 "=a"))]
14564 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14565 operands[3], operands[4], operands[5], NULL_RTX);
14571 (if_then_else (match_operator 0 "comparison_operator"
14572 [(match_operator 1 "float_operator"
14573 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14574 (match_operand 3 "register_operand" "")])
14575 (match_operand 4 "" "")
14576 (match_operand 5 "" "")))
14577 (clobber (reg:CCFP FPSR_REG))
14578 (clobber (reg:CCFP FLAGS_REG))
14579 (clobber (match_scratch:HI 6 "=a"))]
14583 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14584 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14585 operands[3], operands[7],
14586 operands[4], operands[5], operands[6], NULL_RTX);
14590 ;; %%% Kill this when reload knows how to do it.
14593 (if_then_else (match_operator 0 "comparison_operator"
14594 [(match_operator 1 "float_operator"
14595 [(match_operand:X87MODEI12 2 "register_operand" "")])
14596 (match_operand 3 "register_operand" "")])
14597 (match_operand 4 "" "")
14598 (match_operand 5 "" "")))
14599 (clobber (reg:CCFP FPSR_REG))
14600 (clobber (reg:CCFP FLAGS_REG))
14601 (clobber (match_scratch:HI 6 "=a"))]
14605 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14606 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14607 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14608 operands[3], operands[7],
14609 operands[4], operands[5], operands[6], operands[2]);
14613 ;; Unconditional and other jump instructions
14615 (define_insn "jump"
14617 (label_ref (match_operand 0 "" "")))]
14620 [(set_attr "type" "ibr")
14621 (set (attr "length")
14622 (if_then_else (and (ge (minus (match_dup 0) (pc))
14624 (lt (minus (match_dup 0) (pc))
14628 (set_attr "modrm" "0")])
14630 (define_expand "indirect_jump"
14631 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14635 (define_insn "*indirect_jump"
14636 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14639 [(set_attr "type" "ibr")
14640 (set_attr "length_immediate" "0")])
14642 (define_expand "tablejump"
14643 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14644 (use (label_ref (match_operand 1 "" "")))])]
14647 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14648 relative. Convert the relative address to an absolute address. */
14652 enum rtx_code code;
14654 /* We can't use @GOTOFF for text labels on VxWorks;
14655 see gotoff_operand. */
14656 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14660 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14662 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14666 op1 = pic_offset_table_rtx;
14671 op0 = pic_offset_table_rtx;
14675 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14680 (define_insn "*tablejump_1"
14681 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14682 (use (label_ref (match_operand 1 "" "")))]
14685 [(set_attr "type" "ibr")
14686 (set_attr "length_immediate" "0")])
14688 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14691 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14692 (set (match_operand:QI 1 "register_operand" "")
14693 (match_operator:QI 2 "ix86_comparison_operator"
14694 [(reg FLAGS_REG) (const_int 0)]))
14695 (set (match_operand 3 "q_regs_operand" "")
14696 (zero_extend (match_dup 1)))]
14697 "(peep2_reg_dead_p (3, operands[1])
14698 || operands_match_p (operands[1], operands[3]))
14699 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14700 [(set (match_dup 4) (match_dup 0))
14701 (set (strict_low_part (match_dup 5))
14704 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14705 operands[5] = gen_lowpart (QImode, operands[3]);
14706 ix86_expand_clear (operands[3]);
14709 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14712 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14713 (set (match_operand:QI 1 "register_operand" "")
14714 (match_operator:QI 2 "ix86_comparison_operator"
14715 [(reg FLAGS_REG) (const_int 0)]))
14716 (parallel [(set (match_operand 3 "q_regs_operand" "")
14717 (zero_extend (match_dup 1)))
14718 (clobber (reg:CC FLAGS_REG))])]
14719 "(peep2_reg_dead_p (3, operands[1])
14720 || operands_match_p (operands[1], operands[3]))
14721 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14722 [(set (match_dup 4) (match_dup 0))
14723 (set (strict_low_part (match_dup 5))
14726 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14727 operands[5] = gen_lowpart (QImode, operands[3]);
14728 ix86_expand_clear (operands[3]);
14731 ;; Call instructions.
14733 ;; The predicates normally associated with named expanders are not properly
14734 ;; checked for calls. This is a bug in the generic code, but it isn't that
14735 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14737 ;; Call subroutine returning no value.
14739 (define_expand "call_pop"
14740 [(parallel [(call (match_operand:QI 0 "" "")
14741 (match_operand:SI 1 "" ""))
14742 (set (reg:SI SP_REG)
14743 (plus:SI (reg:SI SP_REG)
14744 (match_operand:SI 3 "" "")))])]
14747 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14751 (define_insn "*call_pop_0"
14752 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14753 (match_operand:SI 1 "" ""))
14754 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14755 (match_operand:SI 2 "immediate_operand" "")))]
14758 if (SIBLING_CALL_P (insn))
14761 return "call\t%P0";
14763 [(set_attr "type" "call")])
14765 (define_insn "*call_pop_1"
14766 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14767 (match_operand:SI 1 "" ""))
14768 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14769 (match_operand:SI 2 "immediate_operand" "i")))]
14772 if (constant_call_address_operand (operands[0], Pmode))
14774 if (SIBLING_CALL_P (insn))
14777 return "call\t%P0";
14779 if (SIBLING_CALL_P (insn))
14782 return "call\t%A0";
14784 [(set_attr "type" "call")])
14786 (define_expand "call"
14787 [(call (match_operand:QI 0 "" "")
14788 (match_operand 1 "" ""))
14789 (use (match_operand 2 "" ""))]
14792 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14796 (define_expand "sibcall"
14797 [(call (match_operand:QI 0 "" "")
14798 (match_operand 1 "" ""))
14799 (use (match_operand 2 "" ""))]
14802 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14806 (define_insn "*call_0"
14807 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14808 (match_operand 1 "" ""))]
14811 if (SIBLING_CALL_P (insn))
14814 return "call\t%P0";
14816 [(set_attr "type" "call")])
14818 (define_insn "*call_1"
14819 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14820 (match_operand 1 "" ""))]
14821 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14823 if (constant_call_address_operand (operands[0], Pmode))
14824 return "call\t%P0";
14825 return "call\t%A0";
14827 [(set_attr "type" "call")])
14829 (define_insn "*sibcall_1"
14830 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14831 (match_operand 1 "" ""))]
14832 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14834 if (constant_call_address_operand (operands[0], Pmode))
14838 [(set_attr "type" "call")])
14840 (define_insn "*call_1_rex64"
14841 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14842 (match_operand 1 "" ""))]
14843 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14844 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14846 if (constant_call_address_operand (operands[0], Pmode))
14847 return "call\t%P0";
14848 return "call\t%A0";
14850 [(set_attr "type" "call")])
14852 (define_insn "*call_1_rex64_large"
14853 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14854 (match_operand 1 "" ""))]
14855 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14857 [(set_attr "type" "call")])
14859 (define_insn "*sibcall_1_rex64"
14860 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14861 (match_operand 1 "" ""))]
14862 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14864 [(set_attr "type" "call")])
14866 (define_insn "*sibcall_1_rex64_v"
14867 [(call (mem:QI (reg:DI R11_REG))
14868 (match_operand 0 "" ""))]
14869 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14871 [(set_attr "type" "call")])
14874 ;; Call subroutine, returning value in operand 0
14876 (define_expand "call_value_pop"
14877 [(parallel [(set (match_operand 0 "" "")
14878 (call (match_operand:QI 1 "" "")
14879 (match_operand:SI 2 "" "")))
14880 (set (reg:SI SP_REG)
14881 (plus:SI (reg:SI SP_REG)
14882 (match_operand:SI 4 "" "")))])]
14885 ix86_expand_call (operands[0], operands[1], operands[2],
14886 operands[3], operands[4], 0);
14890 (define_expand "call_value"
14891 [(set (match_operand 0 "" "")
14892 (call (match_operand:QI 1 "" "")
14893 (match_operand:SI 2 "" "")))
14894 (use (match_operand:SI 3 "" ""))]
14895 ;; Operand 2 not used on the i386.
14898 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14902 (define_expand "sibcall_value"
14903 [(set (match_operand 0 "" "")
14904 (call (match_operand:QI 1 "" "")
14905 (match_operand:SI 2 "" "")))
14906 (use (match_operand:SI 3 "" ""))]
14907 ;; Operand 2 not used on the i386.
14910 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14914 ;; Call subroutine returning any type.
14916 (define_expand "untyped_call"
14917 [(parallel [(call (match_operand 0 "" "")
14919 (match_operand 1 "" "")
14920 (match_operand 2 "" "")])]
14925 /* In order to give reg-stack an easier job in validating two
14926 coprocessor registers as containing a possible return value,
14927 simply pretend the untyped call returns a complex long double
14930 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14931 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14932 operands[0], const0_rtx,
14933 GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
14934 : X64_SSE_REGPARM_MAX)
14938 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14940 rtx set = XVECEXP (operands[2], 0, i);
14941 emit_move_insn (SET_DEST (set), SET_SRC (set));
14944 /* The optimizer does not know that the call sets the function value
14945 registers we stored in the result block. We avoid problems by
14946 claiming that all hard registers are used and clobbered at this
14948 emit_insn (gen_blockage ());
14953 ;; Prologue and epilogue instructions
14955 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14956 ;; all of memory. This blocks insns from being moved across this point.
14958 (define_insn "blockage"
14959 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14962 [(set_attr "length" "0")])
14964 ;; As USE insns aren't meaningful after reload, this is used instead
14965 ;; to prevent deleting instructions setting registers for PIC code
14966 (define_insn "prologue_use"
14967 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14970 [(set_attr "length" "0")])
14972 ;; Insn emitted into the body of a function to return from a function.
14973 ;; This is only done if the function's epilogue is known to be simple.
14974 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14976 (define_expand "return"
14978 "ix86_can_use_return_insn_p ()"
14980 if (crtl->args.pops_args)
14982 rtx popc = GEN_INT (crtl->args.pops_args);
14983 emit_jump_insn (gen_return_pop_internal (popc));
14988 (define_insn "return_internal"
14992 [(set_attr "length" "1")
14993 (set_attr "length_immediate" "0")
14994 (set_attr "modrm" "0")])
14996 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14997 ;; instruction Athlon and K8 have.
14999 (define_insn "return_internal_long"
15001 (unspec [(const_int 0)] UNSPEC_REP)]
15004 [(set_attr "length" "1")
15005 (set_attr "length_immediate" "0")
15006 (set_attr "prefix_rep" "1")
15007 (set_attr "modrm" "0")])
15009 (define_insn "return_pop_internal"
15011 (use (match_operand:SI 0 "const_int_operand" ""))]
15014 [(set_attr "length" "3")
15015 (set_attr "length_immediate" "2")
15016 (set_attr "modrm" "0")])
15018 (define_insn "return_indirect_internal"
15020 (use (match_operand:SI 0 "register_operand" "r"))]
15023 [(set_attr "type" "ibr")
15024 (set_attr "length_immediate" "0")])
15030 [(set_attr "length" "1")
15031 (set_attr "length_immediate" "0")
15032 (set_attr "modrm" "0")])
15034 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15035 ;; branch prediction penalty for the third jump in a 16-byte
15038 (define_insn "align"
15039 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15042 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15043 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15045 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15046 The align insn is used to avoid 3 jump instructions in the row to improve
15047 branch prediction and the benefits hardly outweigh the cost of extra 8
15048 nops on the average inserted by full alignment pseudo operation. */
15052 [(set_attr "length" "16")])
15054 (define_expand "prologue"
15057 "ix86_expand_prologue (); DONE;")
15059 (define_insn "set_got"
15060 [(set (match_operand:SI 0 "register_operand" "=r")
15061 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15062 (clobber (reg:CC FLAGS_REG))]
15064 { return output_set_got (operands[0], NULL_RTX); }
15065 [(set_attr "type" "multi")
15066 (set_attr "length" "12")])
15068 (define_insn "set_got_labelled"
15069 [(set (match_operand:SI 0 "register_operand" "=r")
15070 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15072 (clobber (reg:CC FLAGS_REG))]
15074 { return output_set_got (operands[0], operands[1]); }
15075 [(set_attr "type" "multi")
15076 (set_attr "length" "12")])
15078 (define_insn "set_got_rex64"
15079 [(set (match_operand:DI 0 "register_operand" "=r")
15080 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15082 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15083 [(set_attr "type" "lea")
15084 (set_attr "length" "6")])
15086 (define_insn "set_rip_rex64"
15087 [(set (match_operand:DI 0 "register_operand" "=r")
15088 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15090 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15091 [(set_attr "type" "lea")
15092 (set_attr "length" "6")])
15094 (define_insn "set_got_offset_rex64"
15095 [(set (match_operand:DI 0 "register_operand" "=r")
15096 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15098 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15099 [(set_attr "type" "imov")
15100 (set_attr "length" "11")])
15102 (define_expand "epilogue"
15105 "ix86_expand_epilogue (1); DONE;")
15107 (define_expand "sibcall_epilogue"
15110 "ix86_expand_epilogue (0); DONE;")
15112 (define_expand "eh_return"
15113 [(use (match_operand 0 "register_operand" ""))]
15116 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15118 /* Tricky bit: we write the address of the handler to which we will
15119 be returning into someone else's stack frame, one word below the
15120 stack address we wish to restore. */
15121 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15122 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15123 tmp = gen_rtx_MEM (Pmode, tmp);
15124 emit_move_insn (tmp, ra);
15126 if (Pmode == SImode)
15127 emit_jump_insn (gen_eh_return_si (sa));
15129 emit_jump_insn (gen_eh_return_di (sa));
15134 (define_insn_and_split "eh_return_<mode>"
15136 (unspec [(match_operand:P 0 "register_operand" "c")]
15137 UNSPEC_EH_RETURN))]
15142 "ix86_expand_epilogue (2); DONE;")
15144 (define_insn "leave"
15145 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15146 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15147 (clobber (mem:BLK (scratch)))]
15150 [(set_attr "type" "leave")])
15152 (define_insn "leave_rex64"
15153 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15154 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15155 (clobber (mem:BLK (scratch)))]
15158 [(set_attr "type" "leave")])
15160 (define_expand "ffssi2"
15162 [(set (match_operand:SI 0 "register_operand" "")
15163 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15164 (clobber (match_scratch:SI 2 ""))
15165 (clobber (reg:CC FLAGS_REG))])]
15170 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15175 (define_expand "ffs_cmove"
15176 [(set (match_dup 2) (const_int -1))
15177 (parallel [(set (reg:CCZ FLAGS_REG)
15178 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15180 (set (match_operand:SI 0 "nonimmediate_operand" "")
15181 (ctz:SI (match_dup 1)))])
15182 (set (match_dup 0) (if_then_else:SI
15183 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15186 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15187 (clobber (reg:CC FLAGS_REG))])]
15189 "operands[2] = gen_reg_rtx (SImode);")
15191 (define_insn_and_split "*ffs_no_cmove"
15192 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15193 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15194 (clobber (match_scratch:SI 2 "=&q"))
15195 (clobber (reg:CC FLAGS_REG))]
15198 "&& reload_completed"
15199 [(parallel [(set (reg:CCZ FLAGS_REG)
15200 (compare:CCZ (match_dup 1) (const_int 0)))
15201 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15202 (set (strict_low_part (match_dup 3))
15203 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15204 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15205 (clobber (reg:CC FLAGS_REG))])
15206 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15207 (clobber (reg:CC FLAGS_REG))])
15208 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15209 (clobber (reg:CC FLAGS_REG))])]
15211 operands[3] = gen_lowpart (QImode, operands[2]);
15212 ix86_expand_clear (operands[2]);
15215 (define_insn "*ffssi_1"
15216 [(set (reg:CCZ FLAGS_REG)
15217 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15219 (set (match_operand:SI 0 "register_operand" "=r")
15220 (ctz:SI (match_dup 1)))]
15222 "bsf{l}\t{%1, %0|%0, %1}"
15223 [(set_attr "prefix_0f" "1")])
15225 (define_expand "ffsdi2"
15226 [(set (match_dup 2) (const_int -1))
15227 (parallel [(set (reg:CCZ FLAGS_REG)
15228 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15230 (set (match_operand:DI 0 "nonimmediate_operand" "")
15231 (ctz:DI (match_dup 1)))])
15232 (set (match_dup 0) (if_then_else:DI
15233 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15236 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15237 (clobber (reg:CC FLAGS_REG))])]
15239 "operands[2] = gen_reg_rtx (DImode);")
15241 (define_insn "*ffsdi_1"
15242 [(set (reg:CCZ FLAGS_REG)
15243 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15245 (set (match_operand:DI 0 "register_operand" "=r")
15246 (ctz:DI (match_dup 1)))]
15248 "bsf{q}\t{%1, %0|%0, %1}"
15249 [(set_attr "prefix_0f" "1")])
15251 (define_insn "ctzsi2"
15252 [(set (match_operand:SI 0 "register_operand" "=r")
15253 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15254 (clobber (reg:CC FLAGS_REG))]
15256 "bsf{l}\t{%1, %0|%0, %1}"
15257 [(set_attr "prefix_0f" "1")])
15259 (define_insn "ctzdi2"
15260 [(set (match_operand:DI 0 "register_operand" "=r")
15261 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15262 (clobber (reg:CC FLAGS_REG))]
15264 "bsf{q}\t{%1, %0|%0, %1}"
15265 [(set_attr "prefix_0f" "1")])
15267 (define_expand "clzsi2"
15269 [(set (match_operand:SI 0 "register_operand" "")
15270 (minus:SI (const_int 31)
15271 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15272 (clobber (reg:CC FLAGS_REG))])
15274 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15275 (clobber (reg:CC FLAGS_REG))])]
15280 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15285 (define_insn "clzsi2_abm"
15286 [(set (match_operand:SI 0 "register_operand" "=r")
15287 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15288 (clobber (reg:CC FLAGS_REG))]
15290 "lzcnt{l}\t{%1, %0|%0, %1}"
15291 [(set_attr "prefix_rep" "1")
15292 (set_attr "type" "bitmanip")
15293 (set_attr "mode" "SI")])
15295 (define_insn "*bsr"
15296 [(set (match_operand:SI 0 "register_operand" "=r")
15297 (minus:SI (const_int 31)
15298 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15299 (clobber (reg:CC FLAGS_REG))]
15301 "bsr{l}\t{%1, %0|%0, %1}"
15302 [(set_attr "prefix_0f" "1")
15303 (set_attr "mode" "SI")])
15305 (define_insn "popcountsi2"
15306 [(set (match_operand:SI 0 "register_operand" "=r")
15307 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15308 (clobber (reg:CC FLAGS_REG))]
15310 "popcnt{l}\t{%1, %0|%0, %1}"
15311 [(set_attr "prefix_rep" "1")
15312 (set_attr "type" "bitmanip")
15313 (set_attr "mode" "SI")])
15315 (define_insn "*popcountsi2_cmp"
15316 [(set (reg FLAGS_REG)
15318 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15320 (set (match_operand:SI 0 "register_operand" "=r")
15321 (popcount:SI (match_dup 1)))]
15322 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15323 "popcnt{l}\t{%1, %0|%0, %1}"
15324 [(set_attr "prefix_rep" "1")
15325 (set_attr "type" "bitmanip")
15326 (set_attr "mode" "SI")])
15328 (define_insn "*popcountsi2_cmp_zext"
15329 [(set (reg FLAGS_REG)
15331 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15333 (set (match_operand:DI 0 "register_operand" "=r")
15334 (zero_extend:DI(popcount:SI (match_dup 1))))]
15335 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15336 "popcnt{l}\t{%1, %0|%0, %1}"
15337 [(set_attr "prefix_rep" "1")
15338 (set_attr "type" "bitmanip")
15339 (set_attr "mode" "SI")])
15341 (define_expand "bswapsi2"
15342 [(set (match_operand:SI 0 "register_operand" "")
15343 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15348 rtx x = operands[0];
15350 emit_move_insn (x, operands[1]);
15351 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15352 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15353 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15358 (define_insn "*bswapsi_1"
15359 [(set (match_operand:SI 0 "register_operand" "=r")
15360 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15363 [(set_attr "prefix_0f" "1")
15364 (set_attr "length" "2")])
15366 (define_insn "*bswaphi_lowpart_1"
15367 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15368 (bswap:HI (match_dup 0)))
15369 (clobber (reg:CC FLAGS_REG))]
15370 "TARGET_USE_XCHGB || optimize_size"
15372 xchg{b}\t{%h0, %b0|%b0, %h0}
15373 rol{w}\t{$8, %0|%0, 8}"
15374 [(set_attr "length" "2,4")
15375 (set_attr "mode" "QI,HI")])
15377 (define_insn "bswaphi_lowpart"
15378 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15379 (bswap:HI (match_dup 0)))
15380 (clobber (reg:CC FLAGS_REG))]
15382 "rol{w}\t{$8, %0|%0, 8}"
15383 [(set_attr "length" "4")
15384 (set_attr "mode" "HI")])
15386 (define_insn "bswapdi2"
15387 [(set (match_operand:DI 0 "register_operand" "=r")
15388 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15391 [(set_attr "prefix_0f" "1")
15392 (set_attr "length" "3")])
15394 (define_expand "clzdi2"
15396 [(set (match_operand:DI 0 "register_operand" "")
15397 (minus:DI (const_int 63)
15398 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15399 (clobber (reg:CC FLAGS_REG))])
15401 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15402 (clobber (reg:CC FLAGS_REG))])]
15407 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15412 (define_insn "clzdi2_abm"
15413 [(set (match_operand:DI 0 "register_operand" "=r")
15414 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15415 (clobber (reg:CC FLAGS_REG))]
15416 "TARGET_64BIT && TARGET_ABM"
15417 "lzcnt{q}\t{%1, %0|%0, %1}"
15418 [(set_attr "prefix_rep" "1")
15419 (set_attr "type" "bitmanip")
15420 (set_attr "mode" "DI")])
15422 (define_insn "*bsr_rex64"
15423 [(set (match_operand:DI 0 "register_operand" "=r")
15424 (minus:DI (const_int 63)
15425 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15426 (clobber (reg:CC FLAGS_REG))]
15428 "bsr{q}\t{%1, %0|%0, %1}"
15429 [(set_attr "prefix_0f" "1")
15430 (set_attr "mode" "DI")])
15432 (define_insn "popcountdi2"
15433 [(set (match_operand:DI 0 "register_operand" "=r")
15434 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15435 (clobber (reg:CC FLAGS_REG))]
15436 "TARGET_64BIT && TARGET_POPCNT"
15437 "popcnt{q}\t{%1, %0|%0, %1}"
15438 [(set_attr "prefix_rep" "1")
15439 (set_attr "type" "bitmanip")
15440 (set_attr "mode" "DI")])
15442 (define_insn "*popcountdi2_cmp"
15443 [(set (reg FLAGS_REG)
15445 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15447 (set (match_operand:DI 0 "register_operand" "=r")
15448 (popcount:DI (match_dup 1)))]
15449 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15450 "popcnt{q}\t{%1, %0|%0, %1}"
15451 [(set_attr "prefix_rep" "1")
15452 (set_attr "type" "bitmanip")
15453 (set_attr "mode" "DI")])
15455 (define_expand "clzhi2"
15457 [(set (match_operand:HI 0 "register_operand" "")
15458 (minus:HI (const_int 15)
15459 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15460 (clobber (reg:CC FLAGS_REG))])
15462 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15463 (clobber (reg:CC FLAGS_REG))])]
15468 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15473 (define_insn "clzhi2_abm"
15474 [(set (match_operand:HI 0 "register_operand" "=r")
15475 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15476 (clobber (reg:CC FLAGS_REG))]
15478 "lzcnt{w}\t{%1, %0|%0, %1}"
15479 [(set_attr "prefix_rep" "1")
15480 (set_attr "type" "bitmanip")
15481 (set_attr "mode" "HI")])
15483 (define_insn "*bsrhi"
15484 [(set (match_operand:HI 0 "register_operand" "=r")
15485 (minus:HI (const_int 15)
15486 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15487 (clobber (reg:CC FLAGS_REG))]
15489 "bsr{w}\t{%1, %0|%0, %1}"
15490 [(set_attr "prefix_0f" "1")
15491 (set_attr "mode" "HI")])
15493 (define_insn "popcounthi2"
15494 [(set (match_operand:HI 0 "register_operand" "=r")
15495 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15496 (clobber (reg:CC FLAGS_REG))]
15498 "popcnt{w}\t{%1, %0|%0, %1}"
15499 [(set_attr "prefix_rep" "1")
15500 (set_attr "type" "bitmanip")
15501 (set_attr "mode" "HI")])
15503 (define_insn "*popcounthi2_cmp"
15504 [(set (reg FLAGS_REG)
15506 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15508 (set (match_operand:HI 0 "register_operand" "=r")
15509 (popcount:HI (match_dup 1)))]
15510 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15511 "popcnt{w}\t{%1, %0|%0, %1}"
15512 [(set_attr "prefix_rep" "1")
15513 (set_attr "type" "bitmanip")
15514 (set_attr "mode" "HI")])
15516 (define_expand "paritydi2"
15517 [(set (match_operand:DI 0 "register_operand" "")
15518 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15521 rtx scratch = gen_reg_rtx (QImode);
15524 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15525 NULL_RTX, operands[1]));
15527 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15528 gen_rtx_REG (CCmode, FLAGS_REG),
15530 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15533 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15536 rtx tmp = gen_reg_rtx (SImode);
15538 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15539 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15544 (define_insn_and_split "paritydi2_cmp"
15545 [(set (reg:CC FLAGS_REG)
15546 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15547 (clobber (match_scratch:DI 0 "=r"))
15548 (clobber (match_scratch:SI 1 "=&r"))
15549 (clobber (match_scratch:HI 2 "=Q"))]
15552 "&& reload_completed"
15554 [(set (match_dup 1)
15555 (xor:SI (match_dup 1) (match_dup 4)))
15556 (clobber (reg:CC FLAGS_REG))])
15558 [(set (reg:CC FLAGS_REG)
15559 (parity:CC (match_dup 1)))
15560 (clobber (match_dup 1))
15561 (clobber (match_dup 2))])]
15563 operands[4] = gen_lowpart (SImode, operands[3]);
15567 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15568 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15571 operands[1] = gen_highpart (SImode, operands[3]);
15574 (define_expand "paritysi2"
15575 [(set (match_operand:SI 0 "register_operand" "")
15576 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15579 rtx scratch = gen_reg_rtx (QImode);
15582 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15584 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15585 gen_rtx_REG (CCmode, FLAGS_REG),
15587 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15589 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15593 (define_insn_and_split "paritysi2_cmp"
15594 [(set (reg:CC FLAGS_REG)
15595 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15596 (clobber (match_scratch:SI 0 "=r"))
15597 (clobber (match_scratch:HI 1 "=&Q"))]
15600 "&& reload_completed"
15602 [(set (match_dup 1)
15603 (xor:HI (match_dup 1) (match_dup 3)))
15604 (clobber (reg:CC FLAGS_REG))])
15606 [(set (reg:CC FLAGS_REG)
15607 (parity:CC (match_dup 1)))
15608 (clobber (match_dup 1))])]
15610 operands[3] = gen_lowpart (HImode, operands[2]);
15612 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15613 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15616 (define_insn "*parityhi2_cmp"
15617 [(set (reg:CC FLAGS_REG)
15618 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15619 (clobber (match_scratch:HI 0 "=Q"))]
15621 "xor{b}\t{%h0, %b0|%b0, %h0}"
15622 [(set_attr "length" "2")
15623 (set_attr "mode" "HI")])
15625 (define_insn "*parityqi2_cmp"
15626 [(set (reg:CC FLAGS_REG)
15627 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15630 [(set_attr "length" "2")
15631 (set_attr "mode" "QI")])
15633 ;; Thread-local storage patterns for ELF.
15635 ;; Note that these code sequences must appear exactly as shown
15636 ;; in order to allow linker relaxation.
15638 (define_insn "*tls_global_dynamic_32_gnu"
15639 [(set (match_operand:SI 0 "register_operand" "=a")
15640 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15641 (match_operand:SI 2 "tls_symbolic_operand" "")
15642 (match_operand:SI 3 "call_insn_operand" "")]
15644 (clobber (match_scratch:SI 4 "=d"))
15645 (clobber (match_scratch:SI 5 "=c"))
15646 (clobber (reg:CC FLAGS_REG))]
15647 "!TARGET_64BIT && TARGET_GNU_TLS"
15648 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15649 [(set_attr "type" "multi")
15650 (set_attr "length" "12")])
15652 (define_insn "*tls_global_dynamic_32_sun"
15653 [(set (match_operand:SI 0 "register_operand" "=a")
15654 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15655 (match_operand:SI 2 "tls_symbolic_operand" "")
15656 (match_operand:SI 3 "call_insn_operand" "")]
15658 (clobber (match_scratch:SI 4 "=d"))
15659 (clobber (match_scratch:SI 5 "=c"))
15660 (clobber (reg:CC FLAGS_REG))]
15661 "!TARGET_64BIT && TARGET_SUN_TLS"
15662 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15663 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15664 [(set_attr "type" "multi")
15665 (set_attr "length" "14")])
15667 (define_expand "tls_global_dynamic_32"
15668 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15671 (match_operand:SI 1 "tls_symbolic_operand" "")
15674 (clobber (match_scratch:SI 4 ""))
15675 (clobber (match_scratch:SI 5 ""))
15676 (clobber (reg:CC FLAGS_REG))])]
15680 operands[2] = pic_offset_table_rtx;
15683 operands[2] = gen_reg_rtx (Pmode);
15684 emit_insn (gen_set_got (operands[2]));
15686 if (TARGET_GNU2_TLS)
15688 emit_insn (gen_tls_dynamic_gnu2_32
15689 (operands[0], operands[1], operands[2]));
15692 operands[3] = ix86_tls_get_addr ();
15695 (define_insn "*tls_global_dynamic_64"
15696 [(set (match_operand:DI 0 "register_operand" "=a")
15697 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15698 (match_operand:DI 3 "" "")))
15699 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15702 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15703 [(set_attr "type" "multi")
15704 (set_attr "length" "16")])
15706 (define_expand "tls_global_dynamic_64"
15707 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15708 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15709 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15713 if (TARGET_GNU2_TLS)
15715 emit_insn (gen_tls_dynamic_gnu2_64
15716 (operands[0], operands[1]));
15719 operands[2] = ix86_tls_get_addr ();
15722 (define_insn "*tls_local_dynamic_base_32_gnu"
15723 [(set (match_operand:SI 0 "register_operand" "=a")
15724 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15725 (match_operand:SI 2 "call_insn_operand" "")]
15726 UNSPEC_TLS_LD_BASE))
15727 (clobber (match_scratch:SI 3 "=d"))
15728 (clobber (match_scratch:SI 4 "=c"))
15729 (clobber (reg:CC FLAGS_REG))]
15730 "!TARGET_64BIT && TARGET_GNU_TLS"
15731 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15732 [(set_attr "type" "multi")
15733 (set_attr "length" "11")])
15735 (define_insn "*tls_local_dynamic_base_32_sun"
15736 [(set (match_operand:SI 0 "register_operand" "=a")
15737 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15738 (match_operand:SI 2 "call_insn_operand" "")]
15739 UNSPEC_TLS_LD_BASE))
15740 (clobber (match_scratch:SI 3 "=d"))
15741 (clobber (match_scratch:SI 4 "=c"))
15742 (clobber (reg:CC FLAGS_REG))]
15743 "!TARGET_64BIT && TARGET_SUN_TLS"
15744 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15745 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15746 [(set_attr "type" "multi")
15747 (set_attr "length" "13")])
15749 (define_expand "tls_local_dynamic_base_32"
15750 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15751 (unspec:SI [(match_dup 1) (match_dup 2)]
15752 UNSPEC_TLS_LD_BASE))
15753 (clobber (match_scratch:SI 3 ""))
15754 (clobber (match_scratch:SI 4 ""))
15755 (clobber (reg:CC FLAGS_REG))])]
15759 operands[1] = pic_offset_table_rtx;
15762 operands[1] = gen_reg_rtx (Pmode);
15763 emit_insn (gen_set_got (operands[1]));
15765 if (TARGET_GNU2_TLS)
15767 emit_insn (gen_tls_dynamic_gnu2_32
15768 (operands[0], ix86_tls_module_base (), operands[1]));
15771 operands[2] = ix86_tls_get_addr ();
15774 (define_insn "*tls_local_dynamic_base_64"
15775 [(set (match_operand:DI 0 "register_operand" "=a")
15776 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15777 (match_operand:DI 2 "" "")))
15778 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15780 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15781 [(set_attr "type" "multi")
15782 (set_attr "length" "12")])
15784 (define_expand "tls_local_dynamic_base_64"
15785 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15786 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15787 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15790 if (TARGET_GNU2_TLS)
15792 emit_insn (gen_tls_dynamic_gnu2_64
15793 (operands[0], ix86_tls_module_base ()));
15796 operands[1] = ix86_tls_get_addr ();
15799 ;; Local dynamic of a single variable is a lose. Show combine how
15800 ;; to convert that back to global dynamic.
15802 (define_insn_and_split "*tls_local_dynamic_32_once"
15803 [(set (match_operand:SI 0 "register_operand" "=a")
15804 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15805 (match_operand:SI 2 "call_insn_operand" "")]
15806 UNSPEC_TLS_LD_BASE)
15807 (const:SI (unspec:SI
15808 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15810 (clobber (match_scratch:SI 4 "=d"))
15811 (clobber (match_scratch:SI 5 "=c"))
15812 (clobber (reg:CC FLAGS_REG))]
15816 [(parallel [(set (match_dup 0)
15817 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15819 (clobber (match_dup 4))
15820 (clobber (match_dup 5))
15821 (clobber (reg:CC FLAGS_REG))])]
15824 ;; Load and add the thread base pointer from %gs:0.
15826 (define_insn "*load_tp_si"
15827 [(set (match_operand:SI 0 "register_operand" "=r")
15828 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15830 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15831 [(set_attr "type" "imov")
15832 (set_attr "modrm" "0")
15833 (set_attr "length" "7")
15834 (set_attr "memory" "load")
15835 (set_attr "imm_disp" "false")])
15837 (define_insn "*add_tp_si"
15838 [(set (match_operand:SI 0 "register_operand" "=r")
15839 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15840 (match_operand:SI 1 "register_operand" "0")))
15841 (clobber (reg:CC FLAGS_REG))]
15843 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15844 [(set_attr "type" "alu")
15845 (set_attr "modrm" "0")
15846 (set_attr "length" "7")
15847 (set_attr "memory" "load")
15848 (set_attr "imm_disp" "false")])
15850 (define_insn "*load_tp_di"
15851 [(set (match_operand:DI 0 "register_operand" "=r")
15852 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15854 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15855 [(set_attr "type" "imov")
15856 (set_attr "modrm" "0")
15857 (set_attr "length" "7")
15858 (set_attr "memory" "load")
15859 (set_attr "imm_disp" "false")])
15861 (define_insn "*add_tp_di"
15862 [(set (match_operand:DI 0 "register_operand" "=r")
15863 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15864 (match_operand:DI 1 "register_operand" "0")))
15865 (clobber (reg:CC FLAGS_REG))]
15867 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15868 [(set_attr "type" "alu")
15869 (set_attr "modrm" "0")
15870 (set_attr "length" "7")
15871 (set_attr "memory" "load")
15872 (set_attr "imm_disp" "false")])
15874 ;; GNU2 TLS patterns can be split.
15876 (define_expand "tls_dynamic_gnu2_32"
15877 [(set (match_dup 3)
15878 (plus:SI (match_operand:SI 2 "register_operand" "")
15880 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15883 [(set (match_operand:SI 0 "register_operand" "")
15884 (unspec:SI [(match_dup 1) (match_dup 3)
15885 (match_dup 2) (reg:SI SP_REG)]
15887 (clobber (reg:CC FLAGS_REG))])]
15888 "!TARGET_64BIT && TARGET_GNU2_TLS"
15890 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15891 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15894 (define_insn "*tls_dynamic_lea_32"
15895 [(set (match_operand:SI 0 "register_operand" "=r")
15896 (plus:SI (match_operand:SI 1 "register_operand" "b")
15898 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15899 UNSPEC_TLSDESC))))]
15900 "!TARGET_64BIT && TARGET_GNU2_TLS"
15901 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15902 [(set_attr "type" "lea")
15903 (set_attr "mode" "SI")
15904 (set_attr "length" "6")
15905 (set_attr "length_address" "4")])
15907 (define_insn "*tls_dynamic_call_32"
15908 [(set (match_operand:SI 0 "register_operand" "=a")
15909 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15910 (match_operand:SI 2 "register_operand" "0")
15911 ;; we have to make sure %ebx still points to the GOT
15912 (match_operand:SI 3 "register_operand" "b")
15915 (clobber (reg:CC FLAGS_REG))]
15916 "!TARGET_64BIT && TARGET_GNU2_TLS"
15917 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15918 [(set_attr "type" "call")
15919 (set_attr "length" "2")
15920 (set_attr "length_address" "0")])
15922 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15923 [(set (match_operand:SI 0 "register_operand" "=&a")
15925 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15926 (match_operand:SI 4 "" "")
15927 (match_operand:SI 2 "register_operand" "b")
15930 (const:SI (unspec:SI
15931 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15933 (clobber (reg:CC FLAGS_REG))]
15934 "!TARGET_64BIT && TARGET_GNU2_TLS"
15937 [(set (match_dup 0) (match_dup 5))]
15939 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15940 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15943 (define_expand "tls_dynamic_gnu2_64"
15944 [(set (match_dup 2)
15945 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15948 [(set (match_operand:DI 0 "register_operand" "")
15949 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15951 (clobber (reg:CC FLAGS_REG))])]
15952 "TARGET_64BIT && TARGET_GNU2_TLS"
15954 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15955 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15958 (define_insn "*tls_dynamic_lea_64"
15959 [(set (match_operand:DI 0 "register_operand" "=r")
15960 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15962 "TARGET_64BIT && TARGET_GNU2_TLS"
15963 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15964 [(set_attr "type" "lea")
15965 (set_attr "mode" "DI")
15966 (set_attr "length" "7")
15967 (set_attr "length_address" "4")])
15969 (define_insn "*tls_dynamic_call_64"
15970 [(set (match_operand:DI 0 "register_operand" "=a")
15971 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15972 (match_operand:DI 2 "register_operand" "0")
15975 (clobber (reg:CC FLAGS_REG))]
15976 "TARGET_64BIT && TARGET_GNU2_TLS"
15977 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15978 [(set_attr "type" "call")
15979 (set_attr "length" "2")
15980 (set_attr "length_address" "0")])
15982 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15983 [(set (match_operand:DI 0 "register_operand" "=&a")
15985 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15986 (match_operand:DI 3 "" "")
15989 (const:DI (unspec:DI
15990 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15992 (clobber (reg:CC FLAGS_REG))]
15993 "TARGET_64BIT && TARGET_GNU2_TLS"
15996 [(set (match_dup 0) (match_dup 4))]
15998 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15999 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16004 ;; These patterns match the binary 387 instructions for addM3, subM3,
16005 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16006 ;; SFmode. The first is the normal insn, the second the same insn but
16007 ;; with one operand a conversion, and the third the same insn but with
16008 ;; the other operand a conversion. The conversion may be SFmode or
16009 ;; SImode if the target mode DFmode, but only SImode if the target mode
16012 ;; Gcc is slightly more smart about handling normal two address instructions
16013 ;; so use special patterns for add and mull.
16015 (define_insn "*fop_<mode>_comm_mixed"
16016 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16017 (match_operator:MODEF 3 "binary_fp_operator"
16018 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16019 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16020 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16021 && COMMUTATIVE_ARITH_P (operands[3])
16022 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16023 "* return output_387_binary_op (insn, operands);"
16024 [(set (attr "type")
16025 (if_then_else (eq_attr "alternative" "1")
16026 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16027 (const_string "ssemul")
16028 (const_string "sseadd"))
16029 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16030 (const_string "fmul")
16031 (const_string "fop"))))
16032 (set_attr "mode" "<MODE>")])
16034 (define_insn "*fop_<mode>_comm_sse"
16035 [(set (match_operand:MODEF 0 "register_operand" "=x")
16036 (match_operator:MODEF 3 "binary_fp_operator"
16037 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16038 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16039 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16040 && COMMUTATIVE_ARITH_P (operands[3])
16041 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16042 "* return output_387_binary_op (insn, operands);"
16043 [(set (attr "type")
16044 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16045 (const_string "ssemul")
16046 (const_string "sseadd")))
16047 (set_attr "mode" "<MODE>")])
16049 (define_insn "*fop_<mode>_comm_i387"
16050 [(set (match_operand:MODEF 0 "register_operand" "=f")
16051 (match_operator:MODEF 3 "binary_fp_operator"
16052 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16053 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16055 && COMMUTATIVE_ARITH_P (operands[3])
16056 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16057 "* return output_387_binary_op (insn, operands);"
16058 [(set (attr "type")
16059 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16060 (const_string "fmul")
16061 (const_string "fop")))
16062 (set_attr "mode" "<MODE>")])
16064 (define_insn "*fop_<mode>_1_mixed"
16065 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16066 (match_operator:MODEF 3 "binary_fp_operator"
16067 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16068 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16069 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16070 && !COMMUTATIVE_ARITH_P (operands[3])
16071 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16072 "* return output_387_binary_op (insn, operands);"
16073 [(set (attr "type")
16074 (cond [(and (eq_attr "alternative" "2")
16075 (match_operand:MODEF 3 "mult_operator" ""))
16076 (const_string "ssemul")
16077 (and (eq_attr "alternative" "2")
16078 (match_operand:MODEF 3 "div_operator" ""))
16079 (const_string "ssediv")
16080 (eq_attr "alternative" "2")
16081 (const_string "sseadd")
16082 (match_operand:MODEF 3 "mult_operator" "")
16083 (const_string "fmul")
16084 (match_operand:MODEF 3 "div_operator" "")
16085 (const_string "fdiv")
16087 (const_string "fop")))
16088 (set_attr "mode" "<MODE>")])
16090 (define_insn "*rcpsf2_sse"
16091 [(set (match_operand:SF 0 "register_operand" "=x")
16092 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16095 "rcpss\t{%1, %0|%0, %1}"
16096 [(set_attr "type" "sse")
16097 (set_attr "mode" "SF")])
16099 (define_insn "*fop_<mode>_1_sse"
16100 [(set (match_operand:MODEF 0 "register_operand" "=x")
16101 (match_operator:MODEF 3 "binary_fp_operator"
16102 [(match_operand:MODEF 1 "register_operand" "0")
16103 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16104 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16105 && !COMMUTATIVE_ARITH_P (operands[3])"
16106 "* return output_387_binary_op (insn, operands);"
16107 [(set (attr "type")
16108 (cond [(match_operand:MODEF 3 "mult_operator" "")
16109 (const_string "ssemul")
16110 (match_operand:MODEF 3 "div_operator" "")
16111 (const_string "ssediv")
16113 (const_string "sseadd")))
16114 (set_attr "mode" "<MODE>")])
16116 ;; This pattern is not fully shadowed by the pattern above.
16117 (define_insn "*fop_<mode>_1_i387"
16118 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16119 (match_operator:MODEF 3 "binary_fp_operator"
16120 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16121 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16122 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16123 && !COMMUTATIVE_ARITH_P (operands[3])
16124 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16125 "* return output_387_binary_op (insn, operands);"
16126 [(set (attr "type")
16127 (cond [(match_operand:MODEF 3 "mult_operator" "")
16128 (const_string "fmul")
16129 (match_operand:MODEF 3 "div_operator" "")
16130 (const_string "fdiv")
16132 (const_string "fop")))
16133 (set_attr "mode" "<MODE>")])
16135 ;; ??? Add SSE splitters for these!
16136 (define_insn "*fop_<MODEF:mode>_2_i387"
16137 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16138 (match_operator:MODEF 3 "binary_fp_operator"
16140 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16141 (match_operand:MODEF 2 "register_operand" "0,0")]))]
16142 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16143 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16144 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16145 [(set (attr "type")
16146 (cond [(match_operand:MODEF 3 "mult_operator" "")
16147 (const_string "fmul")
16148 (match_operand:MODEF 3 "div_operator" "")
16149 (const_string "fdiv")
16151 (const_string "fop")))
16152 (set_attr "fp_int_src" "true")
16153 (set_attr "mode" "<X87MODEI12:MODE>")])
16155 (define_insn "*fop_<MODEF:mode>_3_i387"
16156 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16157 (match_operator:MODEF 3 "binary_fp_operator"
16158 [(match_operand:MODEF 1 "register_operand" "0,0")
16160 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16161 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16162 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16163 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16164 [(set (attr "type")
16165 (cond [(match_operand:MODEF 3 "mult_operator" "")
16166 (const_string "fmul")
16167 (match_operand:MODEF 3 "div_operator" "")
16168 (const_string "fdiv")
16170 (const_string "fop")))
16171 (set_attr "fp_int_src" "true")
16172 (set_attr "mode" "<MODE>")])
16174 (define_insn "*fop_df_4_i387"
16175 [(set (match_operand:DF 0 "register_operand" "=f,f")
16176 (match_operator:DF 3 "binary_fp_operator"
16178 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16179 (match_operand:DF 2 "register_operand" "0,f")]))]
16180 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16181 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16182 "* return output_387_binary_op (insn, operands);"
16183 [(set (attr "type")
16184 (cond [(match_operand:DF 3 "mult_operator" "")
16185 (const_string "fmul")
16186 (match_operand:DF 3 "div_operator" "")
16187 (const_string "fdiv")
16189 (const_string "fop")))
16190 (set_attr "mode" "SF")])
16192 (define_insn "*fop_df_5_i387"
16193 [(set (match_operand:DF 0 "register_operand" "=f,f")
16194 (match_operator:DF 3 "binary_fp_operator"
16195 [(match_operand:DF 1 "register_operand" "0,f")
16197 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16198 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16199 "* return output_387_binary_op (insn, operands);"
16200 [(set (attr "type")
16201 (cond [(match_operand:DF 3 "mult_operator" "")
16202 (const_string "fmul")
16203 (match_operand:DF 3 "div_operator" "")
16204 (const_string "fdiv")
16206 (const_string "fop")))
16207 (set_attr "mode" "SF")])
16209 (define_insn "*fop_df_6_i387"
16210 [(set (match_operand:DF 0 "register_operand" "=f,f")
16211 (match_operator:DF 3 "binary_fp_operator"
16213 (match_operand:SF 1 "register_operand" "0,f"))
16215 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16216 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16217 "* return output_387_binary_op (insn, operands);"
16218 [(set (attr "type")
16219 (cond [(match_operand:DF 3 "mult_operator" "")
16220 (const_string "fmul")
16221 (match_operand:DF 3 "div_operator" "")
16222 (const_string "fdiv")
16224 (const_string "fop")))
16225 (set_attr "mode" "SF")])
16227 (define_insn "*fop_xf_comm_i387"
16228 [(set (match_operand:XF 0 "register_operand" "=f")
16229 (match_operator:XF 3 "binary_fp_operator"
16230 [(match_operand:XF 1 "register_operand" "%0")
16231 (match_operand:XF 2 "register_operand" "f")]))]
16233 && COMMUTATIVE_ARITH_P (operands[3])"
16234 "* return output_387_binary_op (insn, operands);"
16235 [(set (attr "type")
16236 (if_then_else (match_operand:XF 3 "mult_operator" "")
16237 (const_string "fmul")
16238 (const_string "fop")))
16239 (set_attr "mode" "XF")])
16241 (define_insn "*fop_xf_1_i387"
16242 [(set (match_operand:XF 0 "register_operand" "=f,f")
16243 (match_operator:XF 3 "binary_fp_operator"
16244 [(match_operand:XF 1 "register_operand" "0,f")
16245 (match_operand:XF 2 "register_operand" "f,0")]))]
16247 && !COMMUTATIVE_ARITH_P (operands[3])"
16248 "* return output_387_binary_op (insn, operands);"
16249 [(set (attr "type")
16250 (cond [(match_operand:XF 3 "mult_operator" "")
16251 (const_string "fmul")
16252 (match_operand:XF 3 "div_operator" "")
16253 (const_string "fdiv")
16255 (const_string "fop")))
16256 (set_attr "mode" "XF")])
16258 (define_insn "*fop_xf_2_i387"
16259 [(set (match_operand:XF 0 "register_operand" "=f,f")
16260 (match_operator:XF 3 "binary_fp_operator"
16262 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16263 (match_operand:XF 2 "register_operand" "0,0")]))]
16264 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16265 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16266 [(set (attr "type")
16267 (cond [(match_operand:XF 3 "mult_operator" "")
16268 (const_string "fmul")
16269 (match_operand:XF 3 "div_operator" "")
16270 (const_string "fdiv")
16272 (const_string "fop")))
16273 (set_attr "fp_int_src" "true")
16274 (set_attr "mode" "<MODE>")])
16276 (define_insn "*fop_xf_3_i387"
16277 [(set (match_operand:XF 0 "register_operand" "=f,f")
16278 (match_operator:XF 3 "binary_fp_operator"
16279 [(match_operand:XF 1 "register_operand" "0,0")
16281 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16282 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16283 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16284 [(set (attr "type")
16285 (cond [(match_operand:XF 3 "mult_operator" "")
16286 (const_string "fmul")
16287 (match_operand:XF 3 "div_operator" "")
16288 (const_string "fdiv")
16290 (const_string "fop")))
16291 (set_attr "fp_int_src" "true")
16292 (set_attr "mode" "<MODE>")])
16294 (define_insn "*fop_xf_4_i387"
16295 [(set (match_operand:XF 0 "register_operand" "=f,f")
16296 (match_operator:XF 3 "binary_fp_operator"
16298 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16299 (match_operand:XF 2 "register_operand" "0,f")]))]
16301 "* return output_387_binary_op (insn, operands);"
16302 [(set (attr "type")
16303 (cond [(match_operand:XF 3 "mult_operator" "")
16304 (const_string "fmul")
16305 (match_operand:XF 3 "div_operator" "")
16306 (const_string "fdiv")
16308 (const_string "fop")))
16309 (set_attr "mode" "<MODE>")])
16311 (define_insn "*fop_xf_5_i387"
16312 [(set (match_operand:XF 0 "register_operand" "=f,f")
16313 (match_operator:XF 3 "binary_fp_operator"
16314 [(match_operand:XF 1 "register_operand" "0,f")
16316 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16318 "* return output_387_binary_op (insn, operands);"
16319 [(set (attr "type")
16320 (cond [(match_operand:XF 3 "mult_operator" "")
16321 (const_string "fmul")
16322 (match_operand:XF 3 "div_operator" "")
16323 (const_string "fdiv")
16325 (const_string "fop")))
16326 (set_attr "mode" "<MODE>")])
16328 (define_insn "*fop_xf_6_i387"
16329 [(set (match_operand:XF 0 "register_operand" "=f,f")
16330 (match_operator:XF 3 "binary_fp_operator"
16332 (match_operand:MODEF 1 "register_operand" "0,f"))
16334 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16336 "* return output_387_binary_op (insn, operands);"
16337 [(set (attr "type")
16338 (cond [(match_operand:XF 3 "mult_operator" "")
16339 (const_string "fmul")
16340 (match_operand:XF 3 "div_operator" "")
16341 (const_string "fdiv")
16343 (const_string "fop")))
16344 (set_attr "mode" "<MODE>")])
16347 [(set (match_operand 0 "register_operand" "")
16348 (match_operator 3 "binary_fp_operator"
16349 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16350 (match_operand 2 "register_operand" "")]))]
16352 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16355 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16356 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16357 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16358 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16359 GET_MODE (operands[3]),
16362 ix86_free_from_memory (GET_MODE (operands[1]));
16367 [(set (match_operand 0 "register_operand" "")
16368 (match_operator 3 "binary_fp_operator"
16369 [(match_operand 1 "register_operand" "")
16370 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16372 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16375 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16376 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16377 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16378 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16379 GET_MODE (operands[3]),
16382 ix86_free_from_memory (GET_MODE (operands[2]));
16386 ;; FPU special functions.
16388 ;; This pattern implements a no-op XFmode truncation for
16389 ;; all fancy i386 XFmode math functions.
16391 (define_insn "truncxf<mode>2_i387_noop_unspec"
16392 [(set (match_operand:MODEF 0 "register_operand" "=f")
16393 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16394 UNSPEC_TRUNC_NOOP))]
16395 "TARGET_USE_FANCY_MATH_387"
16396 "* return output_387_reg_move (insn, operands);"
16397 [(set_attr "type" "fmov")
16398 (set_attr "mode" "<MODE>")])
16400 (define_insn "sqrtxf2"
16401 [(set (match_operand:XF 0 "register_operand" "=f")
16402 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16403 "TARGET_USE_FANCY_MATH_387"
16405 [(set_attr "type" "fpspc")
16406 (set_attr "mode" "XF")
16407 (set_attr "athlon_decode" "direct")
16408 (set_attr "amdfam10_decode" "direct")])
16410 (define_insn "sqrt_extend<mode>xf2_i387"
16411 [(set (match_operand:XF 0 "register_operand" "=f")
16414 (match_operand:MODEF 1 "register_operand" "0"))))]
16415 "TARGET_USE_FANCY_MATH_387"
16417 [(set_attr "type" "fpspc")
16418 (set_attr "mode" "XF")
16419 (set_attr "athlon_decode" "direct")
16420 (set_attr "amdfam10_decode" "direct")])
16422 (define_insn "*rsqrtsf2_sse"
16423 [(set (match_operand:SF 0 "register_operand" "=x")
16424 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16427 "rsqrtss\t{%1, %0|%0, %1}"
16428 [(set_attr "type" "sse")
16429 (set_attr "mode" "SF")])
16431 (define_expand "rsqrtsf2"
16432 [(set (match_operand:SF 0 "register_operand" "")
16433 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16437 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16441 (define_insn "*sqrt<mode>2_sse"
16442 [(set (match_operand:MODEF 0 "register_operand" "=x")
16444 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16445 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16446 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16447 [(set_attr "type" "sse")
16448 (set_attr "mode" "<MODE>")
16449 (set_attr "athlon_decode" "*")
16450 (set_attr "amdfam10_decode" "*")])
16452 (define_expand "sqrt<mode>2"
16453 [(set (match_operand:MODEF 0 "register_operand" "")
16455 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16456 "TARGET_USE_FANCY_MATH_387
16457 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16459 if (<MODE>mode == SFmode
16460 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16461 && flag_finite_math_only && !flag_trapping_math
16462 && flag_unsafe_math_optimizations)
16464 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16468 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16470 rtx op0 = gen_reg_rtx (XFmode);
16471 rtx op1 = force_reg (<MODE>mode, operands[1]);
16473 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16474 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16479 (define_insn "fpremxf4_i387"
16480 [(set (match_operand:XF 0 "register_operand" "=f")
16481 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16482 (match_operand:XF 3 "register_operand" "1")]
16484 (set (match_operand:XF 1 "register_operand" "=u")
16485 (unspec:XF [(match_dup 2) (match_dup 3)]
16487 (set (reg:CCFP FPSR_REG)
16488 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16490 "TARGET_USE_FANCY_MATH_387"
16492 [(set_attr "type" "fpspc")
16493 (set_attr "mode" "XF")])
16495 (define_expand "fmodxf3"
16496 [(use (match_operand:XF 0 "register_operand" ""))
16497 (use (match_operand:XF 1 "general_operand" ""))
16498 (use (match_operand:XF 2 "general_operand" ""))]
16499 "TARGET_USE_FANCY_MATH_387"
16501 rtx label = gen_label_rtx ();
16503 rtx op1 = gen_reg_rtx (XFmode);
16504 rtx op2 = gen_reg_rtx (XFmode);
16506 emit_move_insn (op2, operands[2]);
16507 emit_move_insn (op1, operands[1]);
16509 emit_label (label);
16510 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16511 ix86_emit_fp_unordered_jump (label);
16512 LABEL_NUSES (label) = 1;
16514 emit_move_insn (operands[0], op1);
16518 (define_expand "fmod<mode>3"
16519 [(use (match_operand:MODEF 0 "register_operand" ""))
16520 (use (match_operand:MODEF 1 "general_operand" ""))
16521 (use (match_operand:MODEF 2 "general_operand" ""))]
16522 "TARGET_USE_FANCY_MATH_387"
16524 rtx label = gen_label_rtx ();
16526 rtx op1 = gen_reg_rtx (XFmode);
16527 rtx op2 = gen_reg_rtx (XFmode);
16529 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16530 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16532 emit_label (label);
16533 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16534 ix86_emit_fp_unordered_jump (label);
16535 LABEL_NUSES (label) = 1;
16537 /* Truncate the result properly for strict SSE math. */
16538 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16539 && !TARGET_MIX_SSE_I387)
16540 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16542 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16547 (define_insn "fprem1xf4_i387"
16548 [(set (match_operand:XF 0 "register_operand" "=f")
16549 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16550 (match_operand:XF 3 "register_operand" "1")]
16552 (set (match_operand:XF 1 "register_operand" "=u")
16553 (unspec:XF [(match_dup 2) (match_dup 3)]
16555 (set (reg:CCFP FPSR_REG)
16556 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16558 "TARGET_USE_FANCY_MATH_387"
16560 [(set_attr "type" "fpspc")
16561 (set_attr "mode" "XF")])
16563 (define_expand "remainderxf3"
16564 [(use (match_operand:XF 0 "register_operand" ""))
16565 (use (match_operand:XF 1 "general_operand" ""))
16566 (use (match_operand:XF 2 "general_operand" ""))]
16567 "TARGET_USE_FANCY_MATH_387"
16569 rtx label = gen_label_rtx ();
16571 rtx op1 = gen_reg_rtx (XFmode);
16572 rtx op2 = gen_reg_rtx (XFmode);
16574 emit_move_insn (op2, operands[2]);
16575 emit_move_insn (op1, operands[1]);
16577 emit_label (label);
16578 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16579 ix86_emit_fp_unordered_jump (label);
16580 LABEL_NUSES (label) = 1;
16582 emit_move_insn (operands[0], op1);
16586 (define_expand "remainder<mode>3"
16587 [(use (match_operand:MODEF 0 "register_operand" ""))
16588 (use (match_operand:MODEF 1 "general_operand" ""))
16589 (use (match_operand:MODEF 2 "general_operand" ""))]
16590 "TARGET_USE_FANCY_MATH_387"
16592 rtx label = gen_label_rtx ();
16594 rtx op1 = gen_reg_rtx (XFmode);
16595 rtx op2 = gen_reg_rtx (XFmode);
16597 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16598 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16600 emit_label (label);
16602 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16603 ix86_emit_fp_unordered_jump (label);
16604 LABEL_NUSES (label) = 1;
16606 /* Truncate the result properly for strict SSE math. */
16607 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16608 && !TARGET_MIX_SSE_I387)
16609 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16611 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16616 (define_insn "*sinxf2_i387"
16617 [(set (match_operand:XF 0 "register_operand" "=f")
16618 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16619 "TARGET_USE_FANCY_MATH_387
16620 && flag_unsafe_math_optimizations"
16622 [(set_attr "type" "fpspc")
16623 (set_attr "mode" "XF")])
16625 (define_insn "*sin_extend<mode>xf2_i387"
16626 [(set (match_operand:XF 0 "register_operand" "=f")
16627 (unspec:XF [(float_extend:XF
16628 (match_operand:MODEF 1 "register_operand" "0"))]
16630 "TARGET_USE_FANCY_MATH_387
16631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16632 || TARGET_MIX_SSE_I387)
16633 && flag_unsafe_math_optimizations"
16635 [(set_attr "type" "fpspc")
16636 (set_attr "mode" "XF")])
16638 (define_insn "*cosxf2_i387"
16639 [(set (match_operand:XF 0 "register_operand" "=f")
16640 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16641 "TARGET_USE_FANCY_MATH_387
16642 && flag_unsafe_math_optimizations"
16644 [(set_attr "type" "fpspc")
16645 (set_attr "mode" "XF")])
16647 (define_insn "*cos_extend<mode>xf2_i387"
16648 [(set (match_operand:XF 0 "register_operand" "=f")
16649 (unspec:XF [(float_extend:XF
16650 (match_operand:MODEF 1 "register_operand" "0"))]
16652 "TARGET_USE_FANCY_MATH_387
16653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16654 || TARGET_MIX_SSE_I387)
16655 && flag_unsafe_math_optimizations"
16657 [(set_attr "type" "fpspc")
16658 (set_attr "mode" "XF")])
16660 ;; When sincos pattern is defined, sin and cos builtin functions will be
16661 ;; expanded to sincos pattern with one of its outputs left unused.
16662 ;; CSE pass will figure out if two sincos patterns can be combined,
16663 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16664 ;; depending on the unused output.
16666 (define_insn "sincosxf3"
16667 [(set (match_operand:XF 0 "register_operand" "=f")
16668 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16669 UNSPEC_SINCOS_COS))
16670 (set (match_operand:XF 1 "register_operand" "=u")
16671 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16672 "TARGET_USE_FANCY_MATH_387
16673 && flag_unsafe_math_optimizations"
16675 [(set_attr "type" "fpspc")
16676 (set_attr "mode" "XF")])
16679 [(set (match_operand:XF 0 "register_operand" "")
16680 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16681 UNSPEC_SINCOS_COS))
16682 (set (match_operand:XF 1 "register_operand" "")
16683 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16684 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16685 && !(reload_completed || reload_in_progress)"
16686 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16690 [(set (match_operand:XF 0 "register_operand" "")
16691 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16692 UNSPEC_SINCOS_COS))
16693 (set (match_operand:XF 1 "register_operand" "")
16694 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16695 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16696 && !(reload_completed || reload_in_progress)"
16697 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16700 (define_insn "sincos_extend<mode>xf3_i387"
16701 [(set (match_operand:XF 0 "register_operand" "=f")
16702 (unspec:XF [(float_extend:XF
16703 (match_operand:MODEF 2 "register_operand" "0"))]
16704 UNSPEC_SINCOS_COS))
16705 (set (match_operand:XF 1 "register_operand" "=u")
16706 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16707 "TARGET_USE_FANCY_MATH_387
16708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16709 || TARGET_MIX_SSE_I387)
16710 && flag_unsafe_math_optimizations"
16712 [(set_attr "type" "fpspc")
16713 (set_attr "mode" "XF")])
16716 [(set (match_operand:XF 0 "register_operand" "")
16717 (unspec:XF [(float_extend:XF
16718 (match_operand:MODEF 2 "register_operand" ""))]
16719 UNSPEC_SINCOS_COS))
16720 (set (match_operand:XF 1 "register_operand" "")
16721 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16722 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16723 && !(reload_completed || reload_in_progress)"
16724 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16728 [(set (match_operand:XF 0 "register_operand" "")
16729 (unspec:XF [(float_extend:XF
16730 (match_operand:MODEF 2 "register_operand" ""))]
16731 UNSPEC_SINCOS_COS))
16732 (set (match_operand:XF 1 "register_operand" "")
16733 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16734 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16735 && !(reload_completed || reload_in_progress)"
16736 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16739 (define_expand "sincos<mode>3"
16740 [(use (match_operand:MODEF 0 "register_operand" ""))
16741 (use (match_operand:MODEF 1 "register_operand" ""))
16742 (use (match_operand:MODEF 2 "register_operand" ""))]
16743 "TARGET_USE_FANCY_MATH_387
16744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16745 || TARGET_MIX_SSE_I387)
16746 && flag_unsafe_math_optimizations"
16748 rtx op0 = gen_reg_rtx (XFmode);
16749 rtx op1 = gen_reg_rtx (XFmode);
16751 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16752 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16753 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16757 (define_insn "fptanxf4_i387"
16758 [(set (match_operand:XF 0 "register_operand" "=f")
16759 (match_operand:XF 3 "const_double_operand" "F"))
16760 (set (match_operand:XF 1 "register_operand" "=u")
16761 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16763 "TARGET_USE_FANCY_MATH_387
16764 && flag_unsafe_math_optimizations
16765 && standard_80387_constant_p (operands[3]) == 2"
16767 [(set_attr "type" "fpspc")
16768 (set_attr "mode" "XF")])
16770 (define_insn "fptan_extend<mode>xf4_i387"
16771 [(set (match_operand:MODEF 0 "register_operand" "=f")
16772 (match_operand:MODEF 3 "const_double_operand" "F"))
16773 (set (match_operand:XF 1 "register_operand" "=u")
16774 (unspec:XF [(float_extend:XF
16775 (match_operand:MODEF 2 "register_operand" "0"))]
16777 "TARGET_USE_FANCY_MATH_387
16778 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16779 || TARGET_MIX_SSE_I387)
16780 && flag_unsafe_math_optimizations
16781 && standard_80387_constant_p (operands[3]) == 2"
16783 [(set_attr "type" "fpspc")
16784 (set_attr "mode" "XF")])
16786 (define_expand "tanxf2"
16787 [(use (match_operand:XF 0 "register_operand" ""))
16788 (use (match_operand:XF 1 "register_operand" ""))]
16789 "TARGET_USE_FANCY_MATH_387
16790 && flag_unsafe_math_optimizations"
16792 rtx one = gen_reg_rtx (XFmode);
16793 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16795 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16799 (define_expand "tan<mode>2"
16800 [(use (match_operand:MODEF 0 "register_operand" ""))
16801 (use (match_operand:MODEF 1 "register_operand" ""))]
16802 "TARGET_USE_FANCY_MATH_387
16803 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16804 || TARGET_MIX_SSE_I387)
16805 && flag_unsafe_math_optimizations"
16807 rtx op0 = gen_reg_rtx (XFmode);
16809 rtx one = gen_reg_rtx (<MODE>mode);
16810 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16812 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16813 operands[1], op2));
16814 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16818 (define_insn "*fpatanxf3_i387"
16819 [(set (match_operand:XF 0 "register_operand" "=f")
16820 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16821 (match_operand:XF 2 "register_operand" "u")]
16823 (clobber (match_scratch:XF 3 "=2"))]
16824 "TARGET_USE_FANCY_MATH_387
16825 && flag_unsafe_math_optimizations"
16827 [(set_attr "type" "fpspc")
16828 (set_attr "mode" "XF")])
16830 (define_insn "fpatan_extend<mode>xf3_i387"
16831 [(set (match_operand:XF 0 "register_operand" "=f")
16832 (unspec:XF [(float_extend:XF
16833 (match_operand:MODEF 1 "register_operand" "0"))
16835 (match_operand:MODEF 2 "register_operand" "u"))]
16837 (clobber (match_scratch:XF 3 "=2"))]
16838 "TARGET_USE_FANCY_MATH_387
16839 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16840 || TARGET_MIX_SSE_I387)
16841 && flag_unsafe_math_optimizations"
16843 [(set_attr "type" "fpspc")
16844 (set_attr "mode" "XF")])
16846 (define_expand "atan2xf3"
16847 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16848 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16849 (match_operand:XF 1 "register_operand" "")]
16851 (clobber (match_scratch:XF 3 ""))])]
16852 "TARGET_USE_FANCY_MATH_387
16853 && flag_unsafe_math_optimizations"
16856 (define_expand "atan2<mode>3"
16857 [(use (match_operand:MODEF 0 "register_operand" ""))
16858 (use (match_operand:MODEF 1 "register_operand" ""))
16859 (use (match_operand:MODEF 2 "register_operand" ""))]
16860 "TARGET_USE_FANCY_MATH_387
16861 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16862 || TARGET_MIX_SSE_I387)
16863 && flag_unsafe_math_optimizations"
16865 rtx op0 = gen_reg_rtx (XFmode);
16867 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16868 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16872 (define_expand "atanxf2"
16873 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16874 (unspec:XF [(match_dup 2)
16875 (match_operand:XF 1 "register_operand" "")]
16877 (clobber (match_scratch:XF 3 ""))])]
16878 "TARGET_USE_FANCY_MATH_387
16879 && flag_unsafe_math_optimizations"
16881 operands[2] = gen_reg_rtx (XFmode);
16882 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16885 (define_expand "atan<mode>2"
16886 [(use (match_operand:MODEF 0 "register_operand" ""))
16887 (use (match_operand:MODEF 1 "register_operand" ""))]
16888 "TARGET_USE_FANCY_MATH_387
16889 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16890 || TARGET_MIX_SSE_I387)
16891 && flag_unsafe_math_optimizations"
16893 rtx op0 = gen_reg_rtx (XFmode);
16895 rtx op2 = gen_reg_rtx (<MODE>mode);
16896 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16898 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16899 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16903 (define_expand "asinxf2"
16904 [(set (match_dup 2)
16905 (mult:XF (match_operand:XF 1 "register_operand" "")
16907 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16908 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16909 (parallel [(set (match_operand:XF 0 "register_operand" "")
16910 (unspec:XF [(match_dup 5) (match_dup 1)]
16912 (clobber (match_scratch:XF 6 ""))])]
16913 "TARGET_USE_FANCY_MATH_387
16914 && flag_unsafe_math_optimizations && !optimize_size"
16918 for (i = 2; i < 6; i++)
16919 operands[i] = gen_reg_rtx (XFmode);
16921 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16924 (define_expand "asin<mode>2"
16925 [(use (match_operand:MODEF 0 "register_operand" ""))
16926 (use (match_operand:MODEF 1 "general_operand" ""))]
16927 "TARGET_USE_FANCY_MATH_387
16928 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16929 || TARGET_MIX_SSE_I387)
16930 && flag_unsafe_math_optimizations && !optimize_size"
16932 rtx op0 = gen_reg_rtx (XFmode);
16933 rtx op1 = gen_reg_rtx (XFmode);
16935 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16936 emit_insn (gen_asinxf2 (op0, op1));
16937 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16941 (define_expand "acosxf2"
16942 [(set (match_dup 2)
16943 (mult:XF (match_operand:XF 1 "register_operand" "")
16945 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16946 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16947 (parallel [(set (match_operand:XF 0 "register_operand" "")
16948 (unspec:XF [(match_dup 1) (match_dup 5)]
16950 (clobber (match_scratch:XF 6 ""))])]
16951 "TARGET_USE_FANCY_MATH_387
16952 && flag_unsafe_math_optimizations && !optimize_size"
16956 for (i = 2; i < 6; i++)
16957 operands[i] = gen_reg_rtx (XFmode);
16959 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16962 (define_expand "acos<mode>2"
16963 [(use (match_operand:MODEF 0 "register_operand" ""))
16964 (use (match_operand:MODEF 1 "general_operand" ""))]
16965 "TARGET_USE_FANCY_MATH_387
16966 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16967 || TARGET_MIX_SSE_I387)
16968 && flag_unsafe_math_optimizations && !optimize_size"
16970 rtx op0 = gen_reg_rtx (XFmode);
16971 rtx op1 = gen_reg_rtx (XFmode);
16973 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16974 emit_insn (gen_acosxf2 (op0, op1));
16975 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16979 (define_insn "fyl2xxf3_i387"
16980 [(set (match_operand:XF 0 "register_operand" "=f")
16981 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16982 (match_operand:XF 2 "register_operand" "u")]
16984 (clobber (match_scratch:XF 3 "=2"))]
16985 "TARGET_USE_FANCY_MATH_387
16986 && flag_unsafe_math_optimizations"
16988 [(set_attr "type" "fpspc")
16989 (set_attr "mode" "XF")])
16991 (define_insn "fyl2x_extend<mode>xf3_i387"
16992 [(set (match_operand:XF 0 "register_operand" "=f")
16993 (unspec:XF [(float_extend:XF
16994 (match_operand:MODEF 1 "register_operand" "0"))
16995 (match_operand:XF 2 "register_operand" "u")]
16997 (clobber (match_scratch:XF 3 "=2"))]
16998 "TARGET_USE_FANCY_MATH_387
16999 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17000 || TARGET_MIX_SSE_I387)
17001 && flag_unsafe_math_optimizations"
17003 [(set_attr "type" "fpspc")
17004 (set_attr "mode" "XF")])
17006 (define_expand "logxf2"
17007 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17008 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17009 (match_dup 2)] UNSPEC_FYL2X))
17010 (clobber (match_scratch:XF 3 ""))])]
17011 "TARGET_USE_FANCY_MATH_387
17012 && flag_unsafe_math_optimizations"
17014 operands[2] = gen_reg_rtx (XFmode);
17015 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17018 (define_expand "log<mode>2"
17019 [(use (match_operand:MODEF 0 "register_operand" ""))
17020 (use (match_operand:MODEF 1 "register_operand" ""))]
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 rtx op0 = gen_reg_rtx (XFmode);
17028 rtx op2 = gen_reg_rtx (XFmode);
17029 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17031 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17032 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17036 (define_expand "log10xf2"
17037 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17038 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17039 (match_dup 2)] UNSPEC_FYL2X))
17040 (clobber (match_scratch:XF 3 ""))])]
17041 "TARGET_USE_FANCY_MATH_387
17042 && flag_unsafe_math_optimizations"
17044 operands[2] = gen_reg_rtx (XFmode);
17045 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17048 (define_expand "log10<mode>2"
17049 [(use (match_operand:MODEF 0 "register_operand" ""))
17050 (use (match_operand:MODEF 1 "register_operand" ""))]
17051 "TARGET_USE_FANCY_MATH_387
17052 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17053 || TARGET_MIX_SSE_I387)
17054 && flag_unsafe_math_optimizations"
17056 rtx op0 = gen_reg_rtx (XFmode);
17058 rtx op2 = gen_reg_rtx (XFmode);
17059 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17061 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17062 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17066 (define_expand "log2xf2"
17067 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17068 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17069 (match_dup 2)] UNSPEC_FYL2X))
17070 (clobber (match_scratch:XF 3 ""))])]
17071 "TARGET_USE_FANCY_MATH_387
17072 && flag_unsafe_math_optimizations"
17074 operands[2] = gen_reg_rtx (XFmode);
17075 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17078 (define_expand "log2<mode>2"
17079 [(use (match_operand:MODEF 0 "register_operand" ""))
17080 (use (match_operand:MODEF 1 "register_operand" ""))]
17081 "TARGET_USE_FANCY_MATH_387
17082 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17083 || TARGET_MIX_SSE_I387)
17084 && flag_unsafe_math_optimizations"
17086 rtx op0 = gen_reg_rtx (XFmode);
17088 rtx op2 = gen_reg_rtx (XFmode);
17089 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17091 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17096 (define_insn "fyl2xp1xf3_i387"
17097 [(set (match_operand:XF 0 "register_operand" "=f")
17098 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17099 (match_operand:XF 2 "register_operand" "u")]
17101 (clobber (match_scratch:XF 3 "=2"))]
17102 "TARGET_USE_FANCY_MATH_387
17103 && flag_unsafe_math_optimizations"
17105 [(set_attr "type" "fpspc")
17106 (set_attr "mode" "XF")])
17108 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17109 [(set (match_operand:XF 0 "register_operand" "=f")
17110 (unspec:XF [(float_extend:XF
17111 (match_operand:MODEF 1 "register_operand" "0"))
17112 (match_operand:XF 2 "register_operand" "u")]
17114 (clobber (match_scratch:XF 3 "=2"))]
17115 "TARGET_USE_FANCY_MATH_387
17116 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17117 || TARGET_MIX_SSE_I387)
17118 && flag_unsafe_math_optimizations"
17120 [(set_attr "type" "fpspc")
17121 (set_attr "mode" "XF")])
17123 (define_expand "log1pxf2"
17124 [(use (match_operand:XF 0 "register_operand" ""))
17125 (use (match_operand:XF 1 "register_operand" ""))]
17126 "TARGET_USE_FANCY_MATH_387
17127 && flag_unsafe_math_optimizations && !optimize_size"
17129 ix86_emit_i387_log1p (operands[0], operands[1]);
17133 (define_expand "log1p<mode>2"
17134 [(use (match_operand:MODEF 0 "register_operand" ""))
17135 (use (match_operand:MODEF 1 "register_operand" ""))]
17136 "TARGET_USE_FANCY_MATH_387
17137 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17138 || TARGET_MIX_SSE_I387)
17139 && flag_unsafe_math_optimizations && !optimize_size"
17141 rtx op0 = gen_reg_rtx (XFmode);
17143 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17145 ix86_emit_i387_log1p (op0, operands[1]);
17146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17150 (define_insn "fxtractxf3_i387"
17151 [(set (match_operand:XF 0 "register_operand" "=f")
17152 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17153 UNSPEC_XTRACT_FRACT))
17154 (set (match_operand:XF 1 "register_operand" "=u")
17155 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17156 "TARGET_USE_FANCY_MATH_387
17157 && flag_unsafe_math_optimizations"
17159 [(set_attr "type" "fpspc")
17160 (set_attr "mode" "XF")])
17162 (define_insn "fxtract_extend<mode>xf3_i387"
17163 [(set (match_operand:XF 0 "register_operand" "=f")
17164 (unspec:XF [(float_extend:XF
17165 (match_operand:MODEF 2 "register_operand" "0"))]
17166 UNSPEC_XTRACT_FRACT))
17167 (set (match_operand:XF 1 "register_operand" "=u")
17168 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17169 "TARGET_USE_FANCY_MATH_387
17170 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17171 || TARGET_MIX_SSE_I387)
17172 && flag_unsafe_math_optimizations"
17174 [(set_attr "type" "fpspc")
17175 (set_attr "mode" "XF")])
17177 (define_expand "logbxf2"
17178 [(parallel [(set (match_dup 2)
17179 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17180 UNSPEC_XTRACT_FRACT))
17181 (set (match_operand:XF 0 "register_operand" "")
17182 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17183 "TARGET_USE_FANCY_MATH_387
17184 && flag_unsafe_math_optimizations"
17186 operands[2] = gen_reg_rtx (XFmode);
17189 (define_expand "logb<mode>2"
17190 [(use (match_operand:MODEF 0 "register_operand" ""))
17191 (use (match_operand:MODEF 1 "register_operand" ""))]
17192 "TARGET_USE_FANCY_MATH_387
17193 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17194 || TARGET_MIX_SSE_I387)
17195 && flag_unsafe_math_optimizations"
17197 rtx op0 = gen_reg_rtx (XFmode);
17198 rtx op1 = gen_reg_rtx (XFmode);
17200 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17201 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17205 (define_expand "ilogbxf2"
17206 [(use (match_operand:SI 0 "register_operand" ""))
17207 (use (match_operand:XF 1 "register_operand" ""))]
17208 "TARGET_USE_FANCY_MATH_387
17209 && flag_unsafe_math_optimizations && !optimize_size"
17211 rtx op0 = gen_reg_rtx (XFmode);
17212 rtx op1 = gen_reg_rtx (XFmode);
17214 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17215 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17219 (define_expand "ilogb<mode>2"
17220 [(use (match_operand:SI 0 "register_operand" ""))
17221 (use (match_operand:MODEF 1 "register_operand" ""))]
17222 "TARGET_USE_FANCY_MATH_387
17223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17224 || TARGET_MIX_SSE_I387)
17225 && flag_unsafe_math_optimizations && !optimize_size"
17227 rtx op0 = gen_reg_rtx (XFmode);
17228 rtx op1 = gen_reg_rtx (XFmode);
17230 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17231 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17235 (define_insn "*f2xm1xf2_i387"
17236 [(set (match_operand:XF 0 "register_operand" "=f")
17237 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17239 "TARGET_USE_FANCY_MATH_387
17240 && flag_unsafe_math_optimizations"
17242 [(set_attr "type" "fpspc")
17243 (set_attr "mode" "XF")])
17245 (define_insn "*fscalexf4_i387"
17246 [(set (match_operand:XF 0 "register_operand" "=f")
17247 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17248 (match_operand:XF 3 "register_operand" "1")]
17249 UNSPEC_FSCALE_FRACT))
17250 (set (match_operand:XF 1 "register_operand" "=u")
17251 (unspec:XF [(match_dup 2) (match_dup 3)]
17252 UNSPEC_FSCALE_EXP))]
17253 "TARGET_USE_FANCY_MATH_387
17254 && flag_unsafe_math_optimizations"
17256 [(set_attr "type" "fpspc")
17257 (set_attr "mode" "XF")])
17259 (define_expand "expNcorexf3"
17260 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17261 (match_operand:XF 2 "register_operand" "")))
17262 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17263 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17264 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17265 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17266 (parallel [(set (match_operand:XF 0 "register_operand" "")
17267 (unspec:XF [(match_dup 8) (match_dup 4)]
17268 UNSPEC_FSCALE_FRACT))
17270 (unspec:XF [(match_dup 8) (match_dup 4)]
17271 UNSPEC_FSCALE_EXP))])]
17272 "TARGET_USE_FANCY_MATH_387
17273 && flag_unsafe_math_optimizations && !optimize_size"
17277 for (i = 3; i < 10; i++)
17278 operands[i] = gen_reg_rtx (XFmode);
17280 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17283 (define_expand "expxf2"
17284 [(use (match_operand:XF 0 "register_operand" ""))
17285 (use (match_operand:XF 1 "register_operand" ""))]
17286 "TARGET_USE_FANCY_MATH_387
17287 && flag_unsafe_math_optimizations && !optimize_size"
17289 rtx op2 = gen_reg_rtx (XFmode);
17290 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17292 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17296 (define_expand "exp<mode>2"
17297 [(use (match_operand:MODEF 0 "register_operand" ""))
17298 (use (match_operand:MODEF 1 "general_operand" ""))]
17299 "TARGET_USE_FANCY_MATH_387
17300 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17301 || TARGET_MIX_SSE_I387)
17302 && flag_unsafe_math_optimizations && !optimize_size"
17304 rtx op0 = gen_reg_rtx (XFmode);
17305 rtx op1 = gen_reg_rtx (XFmode);
17307 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17308 emit_insn (gen_expxf2 (op0, op1));
17309 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17313 (define_expand "exp10xf2"
17314 [(use (match_operand:XF 0 "register_operand" ""))
17315 (use (match_operand:XF 1 "register_operand" ""))]
17316 "TARGET_USE_FANCY_MATH_387
17317 && flag_unsafe_math_optimizations && !optimize_size"
17319 rtx op2 = gen_reg_rtx (XFmode);
17320 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17322 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17326 (define_expand "exp10<mode>2"
17327 [(use (match_operand:MODEF 0 "register_operand" ""))
17328 (use (match_operand:MODEF 1 "general_operand" ""))]
17329 "TARGET_USE_FANCY_MATH_387
17330 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17331 || TARGET_MIX_SSE_I387)
17332 && flag_unsafe_math_optimizations && !optimize_size"
17334 rtx op0 = gen_reg_rtx (XFmode);
17335 rtx op1 = gen_reg_rtx (XFmode);
17337 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17338 emit_insn (gen_exp10xf2 (op0, op1));
17339 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17343 (define_expand "exp2xf2"
17344 [(use (match_operand:XF 0 "register_operand" ""))
17345 (use (match_operand:XF 1 "register_operand" ""))]
17346 "TARGET_USE_FANCY_MATH_387
17347 && flag_unsafe_math_optimizations && !optimize_size"
17349 rtx op2 = gen_reg_rtx (XFmode);
17350 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17352 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17356 (define_expand "exp2<mode>2"
17357 [(use (match_operand:MODEF 0 "register_operand" ""))
17358 (use (match_operand:MODEF 1 "general_operand" ""))]
17359 "TARGET_USE_FANCY_MATH_387
17360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17361 || TARGET_MIX_SSE_I387)
17362 && flag_unsafe_math_optimizations && !optimize_size"
17364 rtx op0 = gen_reg_rtx (XFmode);
17365 rtx op1 = gen_reg_rtx (XFmode);
17367 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17368 emit_insn (gen_exp2xf2 (op0, op1));
17369 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17373 (define_expand "expm1xf2"
17374 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17376 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17377 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17378 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17379 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17380 (parallel [(set (match_dup 7)
17381 (unspec:XF [(match_dup 6) (match_dup 4)]
17382 UNSPEC_FSCALE_FRACT))
17384 (unspec:XF [(match_dup 6) (match_dup 4)]
17385 UNSPEC_FSCALE_EXP))])
17386 (parallel [(set (match_dup 10)
17387 (unspec:XF [(match_dup 9) (match_dup 8)]
17388 UNSPEC_FSCALE_FRACT))
17389 (set (match_dup 11)
17390 (unspec:XF [(match_dup 9) (match_dup 8)]
17391 UNSPEC_FSCALE_EXP))])
17392 (set (match_dup 12) (minus:XF (match_dup 10)
17393 (float_extend:XF (match_dup 13))))
17394 (set (match_operand:XF 0 "register_operand" "")
17395 (plus:XF (match_dup 12) (match_dup 7)))]
17396 "TARGET_USE_FANCY_MATH_387
17397 && flag_unsafe_math_optimizations && !optimize_size"
17401 for (i = 2; i < 13; i++)
17402 operands[i] = gen_reg_rtx (XFmode);
17405 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17407 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17410 (define_expand "expm1<mode>2"
17411 [(use (match_operand:MODEF 0 "register_operand" ""))
17412 (use (match_operand:MODEF 1 "general_operand" ""))]
17413 "TARGET_USE_FANCY_MATH_387
17414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17415 || TARGET_MIX_SSE_I387)
17416 && flag_unsafe_math_optimizations && !optimize_size"
17418 rtx op0 = gen_reg_rtx (XFmode);
17419 rtx op1 = gen_reg_rtx (XFmode);
17421 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17422 emit_insn (gen_expm1xf2 (op0, op1));
17423 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17427 (define_expand "ldexpxf3"
17428 [(set (match_dup 3)
17429 (float:XF (match_operand:SI 2 "register_operand" "")))
17430 (parallel [(set (match_operand:XF 0 " register_operand" "")
17431 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17433 UNSPEC_FSCALE_FRACT))
17435 (unspec:XF [(match_dup 1) (match_dup 3)]
17436 UNSPEC_FSCALE_EXP))])]
17437 "TARGET_USE_FANCY_MATH_387
17438 && flag_unsafe_math_optimizations && !optimize_size"
17440 operands[3] = gen_reg_rtx (XFmode);
17441 operands[4] = gen_reg_rtx (XFmode);
17444 (define_expand "ldexp<mode>3"
17445 [(use (match_operand:MODEF 0 "register_operand" ""))
17446 (use (match_operand:MODEF 1 "general_operand" ""))
17447 (use (match_operand:SI 2 "register_operand" ""))]
17448 "TARGET_USE_FANCY_MATH_387
17449 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17450 || TARGET_MIX_SSE_I387)
17451 && flag_unsafe_math_optimizations && !optimize_size"
17453 rtx op0 = gen_reg_rtx (XFmode);
17454 rtx op1 = gen_reg_rtx (XFmode);
17456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17457 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17458 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17462 (define_expand "scalbxf3"
17463 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17464 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17465 (match_operand:XF 2 "register_operand" "")]
17466 UNSPEC_FSCALE_FRACT))
17468 (unspec:XF [(match_dup 1) (match_dup 2)]
17469 UNSPEC_FSCALE_EXP))])]
17470 "TARGET_USE_FANCY_MATH_387
17471 && flag_unsafe_math_optimizations && !optimize_size"
17473 operands[3] = gen_reg_rtx (XFmode);
17476 (define_expand "scalb<mode>3"
17477 [(use (match_operand:MODEF 0 "register_operand" ""))
17478 (use (match_operand:MODEF 1 "general_operand" ""))
17479 (use (match_operand:MODEF 2 "register_operand" ""))]
17480 "TARGET_USE_FANCY_MATH_387
17481 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17482 || TARGET_MIX_SSE_I387)
17483 && flag_unsafe_math_optimizations && !optimize_size"
17485 rtx op0 = gen_reg_rtx (XFmode);
17486 rtx op1 = gen_reg_rtx (XFmode);
17487 rtx op2 = gen_reg_rtx (XFmode);
17489 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17490 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17491 emit_insn (gen_scalbxf3 (op0, op1, op2));
17492 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17497 (define_insn "sse4_1_round<mode>2"
17498 [(set (match_operand:MODEF 0 "register_operand" "=x")
17499 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17500 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17503 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17504 [(set_attr "type" "ssecvt")
17505 (set_attr "prefix_extra" "1")
17506 (set_attr "mode" "<MODE>")])
17508 (define_insn "rintxf2"
17509 [(set (match_operand:XF 0 "register_operand" "=f")
17510 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17512 "TARGET_USE_FANCY_MATH_387
17513 && flag_unsafe_math_optimizations"
17515 [(set_attr "type" "fpspc")
17516 (set_attr "mode" "XF")])
17518 (define_expand "rint<mode>2"
17519 [(use (match_operand:MODEF 0 "register_operand" ""))
17520 (use (match_operand:MODEF 1 "register_operand" ""))]
17521 "(TARGET_USE_FANCY_MATH_387
17522 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17523 || TARGET_MIX_SSE_I387)
17524 && flag_unsafe_math_optimizations)
17525 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17526 && !flag_trapping_math
17527 && (TARGET_ROUND || !optimize_size))"
17529 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17530 && !flag_trapping_math
17531 && (TARGET_ROUND || !optimize_size))
17534 emit_insn (gen_sse4_1_round<mode>2
17535 (operands[0], operands[1], GEN_INT (0x04)));
17537 ix86_expand_rint (operand0, operand1);
17541 rtx op0 = gen_reg_rtx (XFmode);
17542 rtx op1 = gen_reg_rtx (XFmode);
17544 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17545 emit_insn (gen_rintxf2 (op0, op1));
17547 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17552 (define_expand "round<mode>2"
17553 [(match_operand:MODEF 0 "register_operand" "")
17554 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17555 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17556 && !flag_trapping_math && !flag_rounding_math
17559 if (TARGET_64BIT || (<MODE>mode != DFmode))
17560 ix86_expand_round (operand0, operand1);
17562 ix86_expand_rounddf_32 (operand0, operand1);
17566 (define_insn_and_split "*fistdi2_1"
17567 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17568 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17570 "TARGET_USE_FANCY_MATH_387
17571 && !(reload_completed || reload_in_progress)"
17576 if (memory_operand (operands[0], VOIDmode))
17577 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17580 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17581 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17586 [(set_attr "type" "fpspc")
17587 (set_attr "mode" "DI")])
17589 (define_insn "fistdi2"
17590 [(set (match_operand:DI 0 "memory_operand" "=m")
17591 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17593 (clobber (match_scratch:XF 2 "=&1f"))]
17594 "TARGET_USE_FANCY_MATH_387"
17595 "* return output_fix_trunc (insn, operands, 0);"
17596 [(set_attr "type" "fpspc")
17597 (set_attr "mode" "DI")])
17599 (define_insn "fistdi2_with_temp"
17600 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17601 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17603 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17604 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17605 "TARGET_USE_FANCY_MATH_387"
17607 [(set_attr "type" "fpspc")
17608 (set_attr "mode" "DI")])
17611 [(set (match_operand:DI 0 "register_operand" "")
17612 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17614 (clobber (match_operand:DI 2 "memory_operand" ""))
17615 (clobber (match_scratch 3 ""))]
17617 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17618 (clobber (match_dup 3))])
17619 (set (match_dup 0) (match_dup 2))]
17623 [(set (match_operand:DI 0 "memory_operand" "")
17624 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17626 (clobber (match_operand:DI 2 "memory_operand" ""))
17627 (clobber (match_scratch 3 ""))]
17629 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17630 (clobber (match_dup 3))])]
17633 (define_insn_and_split "*fist<mode>2_1"
17634 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17635 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17637 "TARGET_USE_FANCY_MATH_387
17638 && !(reload_completed || reload_in_progress)"
17643 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17644 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17648 [(set_attr "type" "fpspc")
17649 (set_attr "mode" "<MODE>")])
17651 (define_insn "fist<mode>2"
17652 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17653 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17655 "TARGET_USE_FANCY_MATH_387"
17656 "* return output_fix_trunc (insn, operands, 0);"
17657 [(set_attr "type" "fpspc")
17658 (set_attr "mode" "<MODE>")])
17660 (define_insn "fist<mode>2_with_temp"
17661 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17662 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17664 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17665 "TARGET_USE_FANCY_MATH_387"
17667 [(set_attr "type" "fpspc")
17668 (set_attr "mode" "<MODE>")])
17671 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17672 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17674 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17676 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17677 (set (match_dup 0) (match_dup 2))]
17681 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17682 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17684 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17686 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17689 (define_expand "lrintxf<mode>2"
17690 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17691 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17693 "TARGET_USE_FANCY_MATH_387"
17696 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17697 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17698 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17699 UNSPEC_FIX_NOTRUNC))]
17700 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17701 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17704 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17705 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17706 (match_operand:MODEF 1 "register_operand" "")]
17707 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17708 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17709 && !flag_trapping_math && !flag_rounding_math
17712 ix86_expand_lround (operand0, operand1);
17716 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17717 (define_insn_and_split "frndintxf2_floor"
17718 [(set (match_operand:XF 0 "register_operand" "")
17719 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17720 UNSPEC_FRNDINT_FLOOR))
17721 (clobber (reg:CC FLAGS_REG))]
17722 "TARGET_USE_FANCY_MATH_387
17723 && flag_unsafe_math_optimizations
17724 && !(reload_completed || reload_in_progress)"
17729 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17731 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17732 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17734 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17735 operands[2], operands[3]));
17738 [(set_attr "type" "frndint")
17739 (set_attr "i387_cw" "floor")
17740 (set_attr "mode" "XF")])
17742 (define_insn "frndintxf2_floor_i387"
17743 [(set (match_operand:XF 0 "register_operand" "=f")
17744 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17745 UNSPEC_FRNDINT_FLOOR))
17746 (use (match_operand:HI 2 "memory_operand" "m"))
17747 (use (match_operand:HI 3 "memory_operand" "m"))]
17748 "TARGET_USE_FANCY_MATH_387
17749 && flag_unsafe_math_optimizations"
17750 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17751 [(set_attr "type" "frndint")
17752 (set_attr "i387_cw" "floor")
17753 (set_attr "mode" "XF")])
17755 (define_expand "floorxf2"
17756 [(use (match_operand:XF 0 "register_operand" ""))
17757 (use (match_operand:XF 1 "register_operand" ""))]
17758 "TARGET_USE_FANCY_MATH_387
17759 && flag_unsafe_math_optimizations && !optimize_size"
17761 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17765 (define_expand "floor<mode>2"
17766 [(use (match_operand:MODEF 0 "register_operand" ""))
17767 (use (match_operand:MODEF 1 "register_operand" ""))]
17768 "(TARGET_USE_FANCY_MATH_387
17769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17770 || TARGET_MIX_SSE_I387)
17771 && flag_unsafe_math_optimizations && !optimize_size)
17772 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17773 && !flag_trapping_math
17774 && (TARGET_ROUND || !optimize_size))"
17776 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17777 && !flag_trapping_math
17778 && (TARGET_ROUND || !optimize_size))
17781 emit_insn (gen_sse4_1_round<mode>2
17782 (operands[0], operands[1], GEN_INT (0x01)));
17783 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17784 ix86_expand_floorceil (operand0, operand1, true);
17786 ix86_expand_floorceildf_32 (operand0, operand1, true);
17790 rtx op0 = gen_reg_rtx (XFmode);
17791 rtx op1 = gen_reg_rtx (XFmode);
17793 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17794 emit_insn (gen_frndintxf2_floor (op0, op1));
17796 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17801 (define_insn_and_split "*fist<mode>2_floor_1"
17802 [(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 && flag_unsafe_math_optimizations
17808 && !(reload_completed || reload_in_progress)"
17813 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17815 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17816 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17817 if (memory_operand (operands[0], VOIDmode))
17818 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17819 operands[2], operands[3]));
17822 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17823 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17824 operands[2], operands[3],
17829 [(set_attr "type" "fistp")
17830 (set_attr "i387_cw" "floor")
17831 (set_attr "mode" "<MODE>")])
17833 (define_insn "fistdi2_floor"
17834 [(set (match_operand:DI 0 "memory_operand" "=m")
17835 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17836 UNSPEC_FIST_FLOOR))
17837 (use (match_operand:HI 2 "memory_operand" "m"))
17838 (use (match_operand:HI 3 "memory_operand" "m"))
17839 (clobber (match_scratch:XF 4 "=&1f"))]
17840 "TARGET_USE_FANCY_MATH_387
17841 && flag_unsafe_math_optimizations"
17842 "* return output_fix_trunc (insn, operands, 0);"
17843 [(set_attr "type" "fistp")
17844 (set_attr "i387_cw" "floor")
17845 (set_attr "mode" "DI")])
17847 (define_insn "fistdi2_floor_with_temp"
17848 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17849 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17850 UNSPEC_FIST_FLOOR))
17851 (use (match_operand:HI 2 "memory_operand" "m,m"))
17852 (use (match_operand:HI 3 "memory_operand" "m,m"))
17853 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17854 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17855 "TARGET_USE_FANCY_MATH_387
17856 && flag_unsafe_math_optimizations"
17858 [(set_attr "type" "fistp")
17859 (set_attr "i387_cw" "floor")
17860 (set_attr "mode" "DI")])
17863 [(set (match_operand:DI 0 "register_operand" "")
17864 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17865 UNSPEC_FIST_FLOOR))
17866 (use (match_operand:HI 2 "memory_operand" ""))
17867 (use (match_operand:HI 3 "memory_operand" ""))
17868 (clobber (match_operand:DI 4 "memory_operand" ""))
17869 (clobber (match_scratch 5 ""))]
17871 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17872 (use (match_dup 2))
17873 (use (match_dup 3))
17874 (clobber (match_dup 5))])
17875 (set (match_dup 0) (match_dup 4))]
17879 [(set (match_operand:DI 0 "memory_operand" "")
17880 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17881 UNSPEC_FIST_FLOOR))
17882 (use (match_operand:HI 2 "memory_operand" ""))
17883 (use (match_operand:HI 3 "memory_operand" ""))
17884 (clobber (match_operand:DI 4 "memory_operand" ""))
17885 (clobber (match_scratch 5 ""))]
17887 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17888 (use (match_dup 2))
17889 (use (match_dup 3))
17890 (clobber (match_dup 5))])]
17893 (define_insn "fist<mode>2_floor"
17894 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17895 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17896 UNSPEC_FIST_FLOOR))
17897 (use (match_operand:HI 2 "memory_operand" "m"))
17898 (use (match_operand:HI 3 "memory_operand" "m"))]
17899 "TARGET_USE_FANCY_MATH_387
17900 && flag_unsafe_math_optimizations"
17901 "* return output_fix_trunc (insn, operands, 0);"
17902 [(set_attr "type" "fistp")
17903 (set_attr "i387_cw" "floor")
17904 (set_attr "mode" "<MODE>")])
17906 (define_insn "fist<mode>2_floor_with_temp"
17907 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17908 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17909 UNSPEC_FIST_FLOOR))
17910 (use (match_operand:HI 2 "memory_operand" "m,m"))
17911 (use (match_operand:HI 3 "memory_operand" "m,m"))
17912 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17913 "TARGET_USE_FANCY_MATH_387
17914 && flag_unsafe_math_optimizations"
17916 [(set_attr "type" "fistp")
17917 (set_attr "i387_cw" "floor")
17918 (set_attr "mode" "<MODE>")])
17921 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17922 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17923 UNSPEC_FIST_FLOOR))
17924 (use (match_operand:HI 2 "memory_operand" ""))
17925 (use (match_operand:HI 3 "memory_operand" ""))
17926 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17928 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17929 UNSPEC_FIST_FLOOR))
17930 (use (match_dup 2))
17931 (use (match_dup 3))])
17932 (set (match_dup 0) (match_dup 4))]
17936 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17937 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17938 UNSPEC_FIST_FLOOR))
17939 (use (match_operand:HI 2 "memory_operand" ""))
17940 (use (match_operand:HI 3 "memory_operand" ""))
17941 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17943 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17944 UNSPEC_FIST_FLOOR))
17945 (use (match_dup 2))
17946 (use (match_dup 3))])]
17949 (define_expand "lfloorxf<mode>2"
17950 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17951 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17952 UNSPEC_FIST_FLOOR))
17953 (clobber (reg:CC FLAGS_REG))])]
17954 "TARGET_USE_FANCY_MATH_387
17955 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17956 && flag_unsafe_math_optimizations"
17959 (define_expand "lfloor<mode>di2"
17960 [(match_operand:DI 0 "nonimmediate_operand" "")
17961 (match_operand:MODEF 1 "register_operand" "")]
17962 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17963 && !flag_trapping_math
17966 ix86_expand_lfloorceil (operand0, operand1, true);
17970 (define_expand "lfloor<mode>si2"
17971 [(match_operand:SI 0 "nonimmediate_operand" "")
17972 (match_operand:MODEF 1 "register_operand" "")]
17973 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17974 && !flag_trapping_math
17975 && (!optimize_size || !TARGET_64BIT)"
17977 ix86_expand_lfloorceil (operand0, operand1, true);
17981 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17982 (define_insn_and_split "frndintxf2_ceil"
17983 [(set (match_operand:XF 0 "register_operand" "")
17984 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17985 UNSPEC_FRNDINT_CEIL))
17986 (clobber (reg:CC FLAGS_REG))]
17987 "TARGET_USE_FANCY_MATH_387
17988 && flag_unsafe_math_optimizations
17989 && !(reload_completed || reload_in_progress)"
17994 ix86_optimize_mode_switching[I387_CEIL] = 1;
17996 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17997 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17999 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18000 operands[2], operands[3]));
18003 [(set_attr "type" "frndint")
18004 (set_attr "i387_cw" "ceil")
18005 (set_attr "mode" "XF")])
18007 (define_insn "frndintxf2_ceil_i387"
18008 [(set (match_operand:XF 0 "register_operand" "=f")
18009 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18010 UNSPEC_FRNDINT_CEIL))
18011 (use (match_operand:HI 2 "memory_operand" "m"))
18012 (use (match_operand:HI 3 "memory_operand" "m"))]
18013 "TARGET_USE_FANCY_MATH_387
18014 && flag_unsafe_math_optimizations"
18015 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18016 [(set_attr "type" "frndint")
18017 (set_attr "i387_cw" "ceil")
18018 (set_attr "mode" "XF")])
18020 (define_expand "ceilxf2"
18021 [(use (match_operand:XF 0 "register_operand" ""))
18022 (use (match_operand:XF 1 "register_operand" ""))]
18023 "TARGET_USE_FANCY_MATH_387
18024 && flag_unsafe_math_optimizations && !optimize_size"
18026 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18030 (define_expand "ceil<mode>2"
18031 [(use (match_operand:MODEF 0 "register_operand" ""))
18032 (use (match_operand:MODEF 1 "register_operand" ""))]
18033 "(TARGET_USE_FANCY_MATH_387
18034 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18035 || TARGET_MIX_SSE_I387)
18036 && flag_unsafe_math_optimizations && !optimize_size)
18037 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18038 && !flag_trapping_math
18039 && (TARGET_ROUND || !optimize_size))"
18041 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18042 && !flag_trapping_math
18043 && (TARGET_ROUND || !optimize_size))
18046 emit_insn (gen_sse4_1_round<mode>2
18047 (operands[0], operands[1], GEN_INT (0x02)));
18048 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18049 ix86_expand_floorceil (operand0, operand1, false);
18051 ix86_expand_floorceildf_32 (operand0, operand1, false);
18055 rtx op0 = gen_reg_rtx (XFmode);
18056 rtx op1 = gen_reg_rtx (XFmode);
18058 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18059 emit_insn (gen_frndintxf2_ceil (op0, op1));
18061 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18066 (define_insn_and_split "*fist<mode>2_ceil_1"
18067 [(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 && flag_unsafe_math_optimizations
18073 && !(reload_completed || reload_in_progress)"
18078 ix86_optimize_mode_switching[I387_CEIL] = 1;
18080 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18081 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18082 if (memory_operand (operands[0], VOIDmode))
18083 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18084 operands[2], operands[3]));
18087 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18088 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18089 operands[2], operands[3],
18094 [(set_attr "type" "fistp")
18095 (set_attr "i387_cw" "ceil")
18096 (set_attr "mode" "<MODE>")])
18098 (define_insn "fistdi2_ceil"
18099 [(set (match_operand:DI 0 "memory_operand" "=m")
18100 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18102 (use (match_operand:HI 2 "memory_operand" "m"))
18103 (use (match_operand:HI 3 "memory_operand" "m"))
18104 (clobber (match_scratch:XF 4 "=&1f"))]
18105 "TARGET_USE_FANCY_MATH_387
18106 && flag_unsafe_math_optimizations"
18107 "* return output_fix_trunc (insn, operands, 0);"
18108 [(set_attr "type" "fistp")
18109 (set_attr "i387_cw" "ceil")
18110 (set_attr "mode" "DI")])
18112 (define_insn "fistdi2_ceil_with_temp"
18113 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18114 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18116 (use (match_operand:HI 2 "memory_operand" "m,m"))
18117 (use (match_operand:HI 3 "memory_operand" "m,m"))
18118 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18119 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18120 "TARGET_USE_FANCY_MATH_387
18121 && flag_unsafe_math_optimizations"
18123 [(set_attr "type" "fistp")
18124 (set_attr "i387_cw" "ceil")
18125 (set_attr "mode" "DI")])
18128 [(set (match_operand:DI 0 "register_operand" "")
18129 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18131 (use (match_operand:HI 2 "memory_operand" ""))
18132 (use (match_operand:HI 3 "memory_operand" ""))
18133 (clobber (match_operand:DI 4 "memory_operand" ""))
18134 (clobber (match_scratch 5 ""))]
18136 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18137 (use (match_dup 2))
18138 (use (match_dup 3))
18139 (clobber (match_dup 5))])
18140 (set (match_dup 0) (match_dup 4))]
18144 [(set (match_operand:DI 0 "memory_operand" "")
18145 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18147 (use (match_operand:HI 2 "memory_operand" ""))
18148 (use (match_operand:HI 3 "memory_operand" ""))
18149 (clobber (match_operand:DI 4 "memory_operand" ""))
18150 (clobber (match_scratch 5 ""))]
18152 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18153 (use (match_dup 2))
18154 (use (match_dup 3))
18155 (clobber (match_dup 5))])]
18158 (define_insn "fist<mode>2_ceil"
18159 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18160 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18162 (use (match_operand:HI 2 "memory_operand" "m"))
18163 (use (match_operand:HI 3 "memory_operand" "m"))]
18164 "TARGET_USE_FANCY_MATH_387
18165 && flag_unsafe_math_optimizations"
18166 "* return output_fix_trunc (insn, operands, 0);"
18167 [(set_attr "type" "fistp")
18168 (set_attr "i387_cw" "ceil")
18169 (set_attr "mode" "<MODE>")])
18171 (define_insn "fist<mode>2_ceil_with_temp"
18172 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18173 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18175 (use (match_operand:HI 2 "memory_operand" "m,m"))
18176 (use (match_operand:HI 3 "memory_operand" "m,m"))
18177 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18178 "TARGET_USE_FANCY_MATH_387
18179 && flag_unsafe_math_optimizations"
18181 [(set_attr "type" "fistp")
18182 (set_attr "i387_cw" "ceil")
18183 (set_attr "mode" "<MODE>")])
18186 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18187 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18189 (use (match_operand:HI 2 "memory_operand" ""))
18190 (use (match_operand:HI 3 "memory_operand" ""))
18191 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18193 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18195 (use (match_dup 2))
18196 (use (match_dup 3))])
18197 (set (match_dup 0) (match_dup 4))]
18201 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18202 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18204 (use (match_operand:HI 2 "memory_operand" ""))
18205 (use (match_operand:HI 3 "memory_operand" ""))
18206 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18208 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18210 (use (match_dup 2))
18211 (use (match_dup 3))])]
18214 (define_expand "lceilxf<mode>2"
18215 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18216 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18218 (clobber (reg:CC FLAGS_REG))])]
18219 "TARGET_USE_FANCY_MATH_387
18220 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18221 && flag_unsafe_math_optimizations"
18224 (define_expand "lceil<mode>di2"
18225 [(match_operand:DI 0 "nonimmediate_operand" "")
18226 (match_operand:MODEF 1 "register_operand" "")]
18227 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18228 && !flag_trapping_math"
18230 ix86_expand_lfloorceil (operand0, operand1, false);
18234 (define_expand "lceil<mode>si2"
18235 [(match_operand:SI 0 "nonimmediate_operand" "")
18236 (match_operand:MODEF 1 "register_operand" "")]
18237 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18238 && !flag_trapping_math"
18240 ix86_expand_lfloorceil (operand0, operand1, false);
18244 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18245 (define_insn_and_split "frndintxf2_trunc"
18246 [(set (match_operand:XF 0 "register_operand" "")
18247 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18248 UNSPEC_FRNDINT_TRUNC))
18249 (clobber (reg:CC FLAGS_REG))]
18250 "TARGET_USE_FANCY_MATH_387
18251 && flag_unsafe_math_optimizations
18252 && !(reload_completed || reload_in_progress)"
18257 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18259 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18260 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18262 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18263 operands[2], operands[3]));
18266 [(set_attr "type" "frndint")
18267 (set_attr "i387_cw" "trunc")
18268 (set_attr "mode" "XF")])
18270 (define_insn "frndintxf2_trunc_i387"
18271 [(set (match_operand:XF 0 "register_operand" "=f")
18272 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18273 UNSPEC_FRNDINT_TRUNC))
18274 (use (match_operand:HI 2 "memory_operand" "m"))
18275 (use (match_operand:HI 3 "memory_operand" "m"))]
18276 "TARGET_USE_FANCY_MATH_387
18277 && flag_unsafe_math_optimizations"
18278 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18279 [(set_attr "type" "frndint")
18280 (set_attr "i387_cw" "trunc")
18281 (set_attr "mode" "XF")])
18283 (define_expand "btruncxf2"
18284 [(use (match_operand:XF 0 "register_operand" ""))
18285 (use (match_operand:XF 1 "register_operand" ""))]
18286 "TARGET_USE_FANCY_MATH_387
18287 && flag_unsafe_math_optimizations && !optimize_size"
18289 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18293 (define_expand "btrunc<mode>2"
18294 [(use (match_operand:MODEF 0 "register_operand" ""))
18295 (use (match_operand:MODEF 1 "register_operand" ""))]
18296 "(TARGET_USE_FANCY_MATH_387
18297 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18298 || TARGET_MIX_SSE_I387)
18299 && flag_unsafe_math_optimizations && !optimize_size)
18300 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18301 && !flag_trapping_math
18302 && (TARGET_ROUND || !optimize_size))"
18304 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18305 && !flag_trapping_math
18306 && (TARGET_ROUND || !optimize_size))
18309 emit_insn (gen_sse4_1_round<mode>2
18310 (operands[0], operands[1], GEN_INT (0x03)));
18311 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18312 ix86_expand_trunc (operand0, operand1);
18314 ix86_expand_truncdf_32 (operand0, operand1);
18318 rtx op0 = gen_reg_rtx (XFmode);
18319 rtx op1 = gen_reg_rtx (XFmode);
18321 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18322 emit_insn (gen_frndintxf2_trunc (op0, op1));
18324 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18329 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18330 (define_insn_and_split "frndintxf2_mask_pm"
18331 [(set (match_operand:XF 0 "register_operand" "")
18332 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18333 UNSPEC_FRNDINT_MASK_PM))
18334 (clobber (reg:CC FLAGS_REG))]
18335 "TARGET_USE_FANCY_MATH_387
18336 && flag_unsafe_math_optimizations
18337 && !(reload_completed || reload_in_progress)"
18342 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18344 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18345 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18347 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18348 operands[2], operands[3]));
18351 [(set_attr "type" "frndint")
18352 (set_attr "i387_cw" "mask_pm")
18353 (set_attr "mode" "XF")])
18355 (define_insn "frndintxf2_mask_pm_i387"
18356 [(set (match_operand:XF 0 "register_operand" "=f")
18357 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18358 UNSPEC_FRNDINT_MASK_PM))
18359 (use (match_operand:HI 2 "memory_operand" "m"))
18360 (use (match_operand:HI 3 "memory_operand" "m"))]
18361 "TARGET_USE_FANCY_MATH_387
18362 && flag_unsafe_math_optimizations"
18363 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18364 [(set_attr "type" "frndint")
18365 (set_attr "i387_cw" "mask_pm")
18366 (set_attr "mode" "XF")])
18368 (define_expand "nearbyintxf2"
18369 [(use (match_operand:XF 0 "register_operand" ""))
18370 (use (match_operand:XF 1 "register_operand" ""))]
18371 "TARGET_USE_FANCY_MATH_387
18372 && flag_unsafe_math_optimizations"
18374 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18379 (define_expand "nearbyint<mode>2"
18380 [(use (match_operand:MODEF 0 "register_operand" ""))
18381 (use (match_operand:MODEF 1 "register_operand" ""))]
18382 "TARGET_USE_FANCY_MATH_387
18383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18384 || TARGET_MIX_SSE_I387)
18385 && flag_unsafe_math_optimizations"
18387 rtx op0 = gen_reg_rtx (XFmode);
18388 rtx op1 = gen_reg_rtx (XFmode);
18390 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18391 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18393 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18397 (define_insn "fxam<mode>2_i387"
18398 [(set (match_operand:HI 0 "register_operand" "=a")
18400 [(match_operand:X87MODEF 1 "register_operand" "f")]
18402 "TARGET_USE_FANCY_MATH_387"
18403 "fxam\n\tfnstsw\t%0"
18404 [(set_attr "type" "multi")
18405 (set_attr "unit" "i387")
18406 (set_attr "mode" "<MODE>")])
18408 (define_expand "isinf<mode>2"
18409 [(use (match_operand:SI 0 "register_operand" ""))
18410 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18411 "TARGET_USE_FANCY_MATH_387
18412 && TARGET_C99_FUNCTIONS
18413 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18415 rtx mask = GEN_INT (0x45);
18416 rtx val = GEN_INT (0x05);
18420 rtx scratch = gen_reg_rtx (HImode);
18421 rtx res = gen_reg_rtx (QImode);
18423 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18424 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18425 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18426 cond = gen_rtx_fmt_ee (EQ, QImode,
18427 gen_rtx_REG (CCmode, FLAGS_REG),
18429 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18430 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18434 (define_expand "signbit<mode>2"
18435 [(use (match_operand:SI 0 "register_operand" ""))
18436 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18437 "TARGET_USE_FANCY_MATH_387
18438 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18440 rtx mask = GEN_INT (0x0200);
18442 rtx scratch = gen_reg_rtx (HImode);
18444 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18445 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18449 ;; Block operation instructions
18452 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18455 [(set_attr "length" "1")
18456 (set_attr "length_immediate" "0")
18457 (set_attr "modrm" "0")])
18459 (define_expand "movmemsi"
18460 [(use (match_operand:BLK 0 "memory_operand" ""))
18461 (use (match_operand:BLK 1 "memory_operand" ""))
18462 (use (match_operand:SI 2 "nonmemory_operand" ""))
18463 (use (match_operand:SI 3 "const_int_operand" ""))
18464 (use (match_operand:SI 4 "const_int_operand" ""))
18465 (use (match_operand:SI 5 "const_int_operand" ""))]
18468 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18469 operands[4], operands[5]))
18475 (define_expand "movmemdi"
18476 [(use (match_operand:BLK 0 "memory_operand" ""))
18477 (use (match_operand:BLK 1 "memory_operand" ""))
18478 (use (match_operand:DI 2 "nonmemory_operand" ""))
18479 (use (match_operand:DI 3 "const_int_operand" ""))
18480 (use (match_operand:SI 4 "const_int_operand" ""))
18481 (use (match_operand:SI 5 "const_int_operand" ""))]
18484 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18485 operands[4], operands[5]))
18491 ;; Most CPUs don't like single string operations
18492 ;; Handle this case here to simplify previous expander.
18494 (define_expand "strmov"
18495 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18496 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18497 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18498 (clobber (reg:CC FLAGS_REG))])
18499 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18500 (clobber (reg:CC FLAGS_REG))])]
18503 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18505 /* If .md ever supports :P for Pmode, these can be directly
18506 in the pattern above. */
18507 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18508 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18510 /* Can't use this if the user has appropriated esi or edi. */
18511 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18512 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18514 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18515 operands[2], operands[3],
18516 operands[5], operands[6]));
18520 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18523 (define_expand "strmov_singleop"
18524 [(parallel [(set (match_operand 1 "memory_operand" "")
18525 (match_operand 3 "memory_operand" ""))
18526 (set (match_operand 0 "register_operand" "")
18527 (match_operand 4 "" ""))
18528 (set (match_operand 2 "register_operand" "")
18529 (match_operand 5 "" ""))])]
18530 "TARGET_SINGLE_STRINGOP || optimize_size"
18531 "ix86_current_function_needs_cld = 1;")
18533 (define_insn "*strmovdi_rex_1"
18534 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18535 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18536 (set (match_operand:DI 0 "register_operand" "=D")
18537 (plus:DI (match_dup 2)
18539 (set (match_operand:DI 1 "register_operand" "=S")
18540 (plus:DI (match_dup 3)
18542 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18544 [(set_attr "type" "str")
18545 (set_attr "mode" "DI")
18546 (set_attr "memory" "both")])
18548 (define_insn "*strmovsi_1"
18549 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18550 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18551 (set (match_operand:SI 0 "register_operand" "=D")
18552 (plus:SI (match_dup 2)
18554 (set (match_operand:SI 1 "register_operand" "=S")
18555 (plus:SI (match_dup 3)
18557 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18559 [(set_attr "type" "str")
18560 (set_attr "mode" "SI")
18561 (set_attr "memory" "both")])
18563 (define_insn "*strmovsi_rex_1"
18564 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18565 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18566 (set (match_operand:DI 0 "register_operand" "=D")
18567 (plus:DI (match_dup 2)
18569 (set (match_operand:DI 1 "register_operand" "=S")
18570 (plus:DI (match_dup 3)
18572 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18574 [(set_attr "type" "str")
18575 (set_attr "mode" "SI")
18576 (set_attr "memory" "both")])
18578 (define_insn "*strmovhi_1"
18579 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18580 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18581 (set (match_operand:SI 0 "register_operand" "=D")
18582 (plus:SI (match_dup 2)
18584 (set (match_operand:SI 1 "register_operand" "=S")
18585 (plus:SI (match_dup 3)
18587 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18589 [(set_attr "type" "str")
18590 (set_attr "memory" "both")
18591 (set_attr "mode" "HI")])
18593 (define_insn "*strmovhi_rex_1"
18594 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18595 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18596 (set (match_operand:DI 0 "register_operand" "=D")
18597 (plus:DI (match_dup 2)
18599 (set (match_operand:DI 1 "register_operand" "=S")
18600 (plus:DI (match_dup 3)
18602 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18604 [(set_attr "type" "str")
18605 (set_attr "memory" "both")
18606 (set_attr "mode" "HI")])
18608 (define_insn "*strmovqi_1"
18609 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18610 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18611 (set (match_operand:SI 0 "register_operand" "=D")
18612 (plus:SI (match_dup 2)
18614 (set (match_operand:SI 1 "register_operand" "=S")
18615 (plus:SI (match_dup 3)
18617 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18619 [(set_attr "type" "str")
18620 (set_attr "memory" "both")
18621 (set_attr "mode" "QI")])
18623 (define_insn "*strmovqi_rex_1"
18624 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18625 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18626 (set (match_operand:DI 0 "register_operand" "=D")
18627 (plus:DI (match_dup 2)
18629 (set (match_operand:DI 1 "register_operand" "=S")
18630 (plus:DI (match_dup 3)
18632 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18634 [(set_attr "type" "str")
18635 (set_attr "memory" "both")
18636 (set_attr "mode" "QI")])
18638 (define_expand "rep_mov"
18639 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18640 (set (match_operand 0 "register_operand" "")
18641 (match_operand 5 "" ""))
18642 (set (match_operand 2 "register_operand" "")
18643 (match_operand 6 "" ""))
18644 (set (match_operand 1 "memory_operand" "")
18645 (match_operand 3 "memory_operand" ""))
18646 (use (match_dup 4))])]
18648 "ix86_current_function_needs_cld = 1;")
18650 (define_insn "*rep_movdi_rex64"
18651 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18652 (set (match_operand:DI 0 "register_operand" "=D")
18653 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18655 (match_operand:DI 3 "register_operand" "0")))
18656 (set (match_operand:DI 1 "register_operand" "=S")
18657 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18658 (match_operand:DI 4 "register_operand" "1")))
18659 (set (mem:BLK (match_dup 3))
18660 (mem:BLK (match_dup 4)))
18661 (use (match_dup 5))]
18664 [(set_attr "type" "str")
18665 (set_attr "prefix_rep" "1")
18666 (set_attr "memory" "both")
18667 (set_attr "mode" "DI")])
18669 (define_insn "*rep_movsi"
18670 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18671 (set (match_operand:SI 0 "register_operand" "=D")
18672 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18674 (match_operand:SI 3 "register_operand" "0")))
18675 (set (match_operand:SI 1 "register_operand" "=S")
18676 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18677 (match_operand:SI 4 "register_operand" "1")))
18678 (set (mem:BLK (match_dup 3))
18679 (mem:BLK (match_dup 4)))
18680 (use (match_dup 5))]
18683 [(set_attr "type" "str")
18684 (set_attr "prefix_rep" "1")
18685 (set_attr "memory" "both")
18686 (set_attr "mode" "SI")])
18688 (define_insn "*rep_movsi_rex64"
18689 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18690 (set (match_operand:DI 0 "register_operand" "=D")
18691 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18693 (match_operand:DI 3 "register_operand" "0")))
18694 (set (match_operand:DI 1 "register_operand" "=S")
18695 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18696 (match_operand:DI 4 "register_operand" "1")))
18697 (set (mem:BLK (match_dup 3))
18698 (mem:BLK (match_dup 4)))
18699 (use (match_dup 5))]
18702 [(set_attr "type" "str")
18703 (set_attr "prefix_rep" "1")
18704 (set_attr "memory" "both")
18705 (set_attr "mode" "SI")])
18707 (define_insn "*rep_movqi"
18708 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18709 (set (match_operand:SI 0 "register_operand" "=D")
18710 (plus:SI (match_operand:SI 3 "register_operand" "0")
18711 (match_operand:SI 5 "register_operand" "2")))
18712 (set (match_operand:SI 1 "register_operand" "=S")
18713 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18714 (set (mem:BLK (match_dup 3))
18715 (mem:BLK (match_dup 4)))
18716 (use (match_dup 5))]
18719 [(set_attr "type" "str")
18720 (set_attr "prefix_rep" "1")
18721 (set_attr "memory" "both")
18722 (set_attr "mode" "SI")])
18724 (define_insn "*rep_movqi_rex64"
18725 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18726 (set (match_operand:DI 0 "register_operand" "=D")
18727 (plus:DI (match_operand:DI 3 "register_operand" "0")
18728 (match_operand:DI 5 "register_operand" "2")))
18729 (set (match_operand:DI 1 "register_operand" "=S")
18730 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18731 (set (mem:BLK (match_dup 3))
18732 (mem:BLK (match_dup 4)))
18733 (use (match_dup 5))]
18736 [(set_attr "type" "str")
18737 (set_attr "prefix_rep" "1")
18738 (set_attr "memory" "both")
18739 (set_attr "mode" "SI")])
18741 (define_expand "setmemsi"
18742 [(use (match_operand:BLK 0 "memory_operand" ""))
18743 (use (match_operand:SI 1 "nonmemory_operand" ""))
18744 (use (match_operand 2 "const_int_operand" ""))
18745 (use (match_operand 3 "const_int_operand" ""))
18746 (use (match_operand:SI 4 "const_int_operand" ""))
18747 (use (match_operand:SI 5 "const_int_operand" ""))]
18750 if (ix86_expand_setmem (operands[0], operands[1],
18751 operands[2], operands[3],
18752 operands[4], operands[5]))
18758 (define_expand "setmemdi"
18759 [(use (match_operand:BLK 0 "memory_operand" ""))
18760 (use (match_operand:DI 1 "nonmemory_operand" ""))
18761 (use (match_operand 2 "const_int_operand" ""))
18762 (use (match_operand 3 "const_int_operand" ""))
18763 (use (match_operand 4 "const_int_operand" ""))
18764 (use (match_operand 5 "const_int_operand" ""))]
18767 if (ix86_expand_setmem (operands[0], operands[1],
18768 operands[2], operands[3],
18769 operands[4], operands[5]))
18775 ;; Most CPUs don't like single string operations
18776 ;; Handle this case here to simplify previous expander.
18778 (define_expand "strset"
18779 [(set (match_operand 1 "memory_operand" "")
18780 (match_operand 2 "register_operand" ""))
18781 (parallel [(set (match_operand 0 "register_operand" "")
18783 (clobber (reg:CC FLAGS_REG))])]
18786 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18787 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18789 /* If .md ever supports :P for Pmode, this can be directly
18790 in the pattern above. */
18791 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18792 GEN_INT (GET_MODE_SIZE (GET_MODE
18794 if (TARGET_SINGLE_STRINGOP || optimize_size)
18796 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18802 (define_expand "strset_singleop"
18803 [(parallel [(set (match_operand 1 "memory_operand" "")
18804 (match_operand 2 "register_operand" ""))
18805 (set (match_operand 0 "register_operand" "")
18806 (match_operand 3 "" ""))])]
18807 "TARGET_SINGLE_STRINGOP || optimize_size"
18808 "ix86_current_function_needs_cld = 1;")
18810 (define_insn "*strsetdi_rex_1"
18811 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18812 (match_operand:DI 2 "register_operand" "a"))
18813 (set (match_operand:DI 0 "register_operand" "=D")
18814 (plus:DI (match_dup 1)
18816 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18818 [(set_attr "type" "str")
18819 (set_attr "memory" "store")
18820 (set_attr "mode" "DI")])
18822 (define_insn "*strsetsi_1"
18823 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18824 (match_operand:SI 2 "register_operand" "a"))
18825 (set (match_operand:SI 0 "register_operand" "=D")
18826 (plus:SI (match_dup 1)
18828 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18830 [(set_attr "type" "str")
18831 (set_attr "memory" "store")
18832 (set_attr "mode" "SI")])
18834 (define_insn "*strsetsi_rex_1"
18835 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18836 (match_operand:SI 2 "register_operand" "a"))
18837 (set (match_operand:DI 0 "register_operand" "=D")
18838 (plus:DI (match_dup 1)
18840 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18842 [(set_attr "type" "str")
18843 (set_attr "memory" "store")
18844 (set_attr "mode" "SI")])
18846 (define_insn "*strsethi_1"
18847 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18848 (match_operand:HI 2 "register_operand" "a"))
18849 (set (match_operand:SI 0 "register_operand" "=D")
18850 (plus:SI (match_dup 1)
18852 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18854 [(set_attr "type" "str")
18855 (set_attr "memory" "store")
18856 (set_attr "mode" "HI")])
18858 (define_insn "*strsethi_rex_1"
18859 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18860 (match_operand:HI 2 "register_operand" "a"))
18861 (set (match_operand:DI 0 "register_operand" "=D")
18862 (plus:DI (match_dup 1)
18864 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18866 [(set_attr "type" "str")
18867 (set_attr "memory" "store")
18868 (set_attr "mode" "HI")])
18870 (define_insn "*strsetqi_1"
18871 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18872 (match_operand:QI 2 "register_operand" "a"))
18873 (set (match_operand:SI 0 "register_operand" "=D")
18874 (plus:SI (match_dup 1)
18876 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18878 [(set_attr "type" "str")
18879 (set_attr "memory" "store")
18880 (set_attr "mode" "QI")])
18882 (define_insn "*strsetqi_rex_1"
18883 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18884 (match_operand:QI 2 "register_operand" "a"))
18885 (set (match_operand:DI 0 "register_operand" "=D")
18886 (plus:DI (match_dup 1)
18888 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18890 [(set_attr "type" "str")
18891 (set_attr "memory" "store")
18892 (set_attr "mode" "QI")])
18894 (define_expand "rep_stos"
18895 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18896 (set (match_operand 0 "register_operand" "")
18897 (match_operand 4 "" ""))
18898 (set (match_operand 2 "memory_operand" "") (const_int 0))
18899 (use (match_operand 3 "register_operand" ""))
18900 (use (match_dup 1))])]
18902 "ix86_current_function_needs_cld = 1;")
18904 (define_insn "*rep_stosdi_rex64"
18905 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18906 (set (match_operand:DI 0 "register_operand" "=D")
18907 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18909 (match_operand:DI 3 "register_operand" "0")))
18910 (set (mem:BLK (match_dup 3))
18912 (use (match_operand:DI 2 "register_operand" "a"))
18913 (use (match_dup 4))]
18916 [(set_attr "type" "str")
18917 (set_attr "prefix_rep" "1")
18918 (set_attr "memory" "store")
18919 (set_attr "mode" "DI")])
18921 (define_insn "*rep_stossi"
18922 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18923 (set (match_operand:SI 0 "register_operand" "=D")
18924 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18926 (match_operand:SI 3 "register_operand" "0")))
18927 (set (mem:BLK (match_dup 3))
18929 (use (match_operand:SI 2 "register_operand" "a"))
18930 (use (match_dup 4))]
18933 [(set_attr "type" "str")
18934 (set_attr "prefix_rep" "1")
18935 (set_attr "memory" "store")
18936 (set_attr "mode" "SI")])
18938 (define_insn "*rep_stossi_rex64"
18939 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18940 (set (match_operand:DI 0 "register_operand" "=D")
18941 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18943 (match_operand:DI 3 "register_operand" "0")))
18944 (set (mem:BLK (match_dup 3))
18946 (use (match_operand:SI 2 "register_operand" "a"))
18947 (use (match_dup 4))]
18950 [(set_attr "type" "str")
18951 (set_attr "prefix_rep" "1")
18952 (set_attr "memory" "store")
18953 (set_attr "mode" "SI")])
18955 (define_insn "*rep_stosqi"
18956 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18957 (set (match_operand:SI 0 "register_operand" "=D")
18958 (plus:SI (match_operand:SI 3 "register_operand" "0")
18959 (match_operand:SI 4 "register_operand" "1")))
18960 (set (mem:BLK (match_dup 3))
18962 (use (match_operand:QI 2 "register_operand" "a"))
18963 (use (match_dup 4))]
18966 [(set_attr "type" "str")
18967 (set_attr "prefix_rep" "1")
18968 (set_attr "memory" "store")
18969 (set_attr "mode" "QI")])
18971 (define_insn "*rep_stosqi_rex64"
18972 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18973 (set (match_operand:DI 0 "register_operand" "=D")
18974 (plus:DI (match_operand:DI 3 "register_operand" "0")
18975 (match_operand:DI 4 "register_operand" "1")))
18976 (set (mem:BLK (match_dup 3))
18978 (use (match_operand:QI 2 "register_operand" "a"))
18979 (use (match_dup 4))]
18982 [(set_attr "type" "str")
18983 (set_attr "prefix_rep" "1")
18984 (set_attr "memory" "store")
18985 (set_attr "mode" "QI")])
18987 (define_expand "cmpstrnsi"
18988 [(set (match_operand:SI 0 "register_operand" "")
18989 (compare:SI (match_operand:BLK 1 "general_operand" "")
18990 (match_operand:BLK 2 "general_operand" "")))
18991 (use (match_operand 3 "general_operand" ""))
18992 (use (match_operand 4 "immediate_operand" ""))]
18993 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18995 rtx addr1, addr2, out, outlow, count, countreg, align;
18997 /* Can't use this if the user has appropriated esi or edi. */
18998 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19003 out = gen_reg_rtx (SImode);
19005 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19006 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19007 if (addr1 != XEXP (operands[1], 0))
19008 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19009 if (addr2 != XEXP (operands[2], 0))
19010 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19012 count = operands[3];
19013 countreg = ix86_zero_extend_to_Pmode (count);
19015 /* %%% Iff we are testing strict equality, we can use known alignment
19016 to good advantage. This may be possible with combine, particularly
19017 once cc0 is dead. */
19018 align = operands[4];
19020 if (CONST_INT_P (count))
19022 if (INTVAL (count) == 0)
19024 emit_move_insn (operands[0], const0_rtx);
19027 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19028 operands[1], operands[2]));
19033 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19035 emit_insn (gen_cmpsi_1 (countreg, countreg));
19036 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19037 operands[1], operands[2]));
19040 outlow = gen_lowpart (QImode, out);
19041 emit_insn (gen_cmpintqi (outlow));
19042 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19044 if (operands[0] != out)
19045 emit_move_insn (operands[0], out);
19050 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19052 (define_expand "cmpintqi"
19053 [(set (match_dup 1)
19054 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19056 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19057 (parallel [(set (match_operand:QI 0 "register_operand" "")
19058 (minus:QI (match_dup 1)
19060 (clobber (reg:CC FLAGS_REG))])]
19062 "operands[1] = gen_reg_rtx (QImode);
19063 operands[2] = gen_reg_rtx (QImode);")
19065 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19066 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19068 (define_expand "cmpstrnqi_nz_1"
19069 [(parallel [(set (reg:CC FLAGS_REG)
19070 (compare:CC (match_operand 4 "memory_operand" "")
19071 (match_operand 5 "memory_operand" "")))
19072 (use (match_operand 2 "register_operand" ""))
19073 (use (match_operand:SI 3 "immediate_operand" ""))
19074 (clobber (match_operand 0 "register_operand" ""))
19075 (clobber (match_operand 1 "register_operand" ""))
19076 (clobber (match_dup 2))])]
19078 "ix86_current_function_needs_cld = 1;")
19080 (define_insn "*cmpstrnqi_nz_1"
19081 [(set (reg:CC FLAGS_REG)
19082 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19083 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19084 (use (match_operand:SI 6 "register_operand" "2"))
19085 (use (match_operand:SI 3 "immediate_operand" "i"))
19086 (clobber (match_operand:SI 0 "register_operand" "=S"))
19087 (clobber (match_operand:SI 1 "register_operand" "=D"))
19088 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19091 [(set_attr "type" "str")
19092 (set_attr "mode" "QI")
19093 (set_attr "prefix_rep" "1")])
19095 (define_insn "*cmpstrnqi_nz_rex_1"
19096 [(set (reg:CC FLAGS_REG)
19097 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19098 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19099 (use (match_operand:DI 6 "register_operand" "2"))
19100 (use (match_operand:SI 3 "immediate_operand" "i"))
19101 (clobber (match_operand:DI 0 "register_operand" "=S"))
19102 (clobber (match_operand:DI 1 "register_operand" "=D"))
19103 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19106 [(set_attr "type" "str")
19107 (set_attr "mode" "QI")
19108 (set_attr "prefix_rep" "1")])
19110 ;; The same, but the count is not known to not be zero.
19112 (define_expand "cmpstrnqi_1"
19113 [(parallel [(set (reg:CC FLAGS_REG)
19114 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19116 (compare:CC (match_operand 4 "memory_operand" "")
19117 (match_operand 5 "memory_operand" ""))
19119 (use (match_operand:SI 3 "immediate_operand" ""))
19120 (use (reg:CC FLAGS_REG))
19121 (clobber (match_operand 0 "register_operand" ""))
19122 (clobber (match_operand 1 "register_operand" ""))
19123 (clobber (match_dup 2))])]
19125 "ix86_current_function_needs_cld = 1;")
19127 (define_insn "*cmpstrnqi_1"
19128 [(set (reg:CC FLAGS_REG)
19129 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19131 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19132 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19134 (use (match_operand:SI 3 "immediate_operand" "i"))
19135 (use (reg:CC FLAGS_REG))
19136 (clobber (match_operand:SI 0 "register_operand" "=S"))
19137 (clobber (match_operand:SI 1 "register_operand" "=D"))
19138 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19141 [(set_attr "type" "str")
19142 (set_attr "mode" "QI")
19143 (set_attr "prefix_rep" "1")])
19145 (define_insn "*cmpstrnqi_rex_1"
19146 [(set (reg:CC FLAGS_REG)
19147 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19149 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19150 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19152 (use (match_operand:SI 3 "immediate_operand" "i"))
19153 (use (reg:CC FLAGS_REG))
19154 (clobber (match_operand:DI 0 "register_operand" "=S"))
19155 (clobber (match_operand:DI 1 "register_operand" "=D"))
19156 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19159 [(set_attr "type" "str")
19160 (set_attr "mode" "QI")
19161 (set_attr "prefix_rep" "1")])
19163 (define_expand "strlensi"
19164 [(set (match_operand:SI 0 "register_operand" "")
19165 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19166 (match_operand:QI 2 "immediate_operand" "")
19167 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19170 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19176 (define_expand "strlendi"
19177 [(set (match_operand:DI 0 "register_operand" "")
19178 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19179 (match_operand:QI 2 "immediate_operand" "")
19180 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19183 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19189 (define_expand "strlenqi_1"
19190 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19191 (clobber (match_operand 1 "register_operand" ""))
19192 (clobber (reg:CC FLAGS_REG))])]
19194 "ix86_current_function_needs_cld = 1;")
19196 (define_insn "*strlenqi_1"
19197 [(set (match_operand:SI 0 "register_operand" "=&c")
19198 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19199 (match_operand:QI 2 "register_operand" "a")
19200 (match_operand:SI 3 "immediate_operand" "i")
19201 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19202 (clobber (match_operand:SI 1 "register_operand" "=D"))
19203 (clobber (reg:CC FLAGS_REG))]
19206 [(set_attr "type" "str")
19207 (set_attr "mode" "QI")
19208 (set_attr "prefix_rep" "1")])
19210 (define_insn "*strlenqi_rex_1"
19211 [(set (match_operand:DI 0 "register_operand" "=&c")
19212 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19213 (match_operand:QI 2 "register_operand" "a")
19214 (match_operand:DI 3 "immediate_operand" "i")
19215 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19216 (clobber (match_operand:DI 1 "register_operand" "=D"))
19217 (clobber (reg:CC FLAGS_REG))]
19220 [(set_attr "type" "str")
19221 (set_attr "mode" "QI")
19222 (set_attr "prefix_rep" "1")])
19224 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19225 ;; handled in combine, but it is not currently up to the task.
19226 ;; When used for their truth value, the cmpstrn* expanders generate
19235 ;; The intermediate three instructions are unnecessary.
19237 ;; This one handles cmpstrn*_nz_1...
19240 (set (reg:CC FLAGS_REG)
19241 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19242 (mem:BLK (match_operand 5 "register_operand" ""))))
19243 (use (match_operand 6 "register_operand" ""))
19244 (use (match_operand:SI 3 "immediate_operand" ""))
19245 (clobber (match_operand 0 "register_operand" ""))
19246 (clobber (match_operand 1 "register_operand" ""))
19247 (clobber (match_operand 2 "register_operand" ""))])
19248 (set (match_operand:QI 7 "register_operand" "")
19249 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19250 (set (match_operand:QI 8 "register_operand" "")
19251 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19252 (set (reg FLAGS_REG)
19253 (compare (match_dup 7) (match_dup 8)))
19255 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19257 (set (reg:CC FLAGS_REG)
19258 (compare:CC (mem:BLK (match_dup 4))
19259 (mem:BLK (match_dup 5))))
19260 (use (match_dup 6))
19261 (use (match_dup 3))
19262 (clobber (match_dup 0))
19263 (clobber (match_dup 1))
19264 (clobber (match_dup 2))])]
19267 ;; ...and this one handles cmpstrn*_1.
19270 (set (reg:CC FLAGS_REG)
19271 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19273 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19274 (mem:BLK (match_operand 5 "register_operand" "")))
19276 (use (match_operand:SI 3 "immediate_operand" ""))
19277 (use (reg:CC FLAGS_REG))
19278 (clobber (match_operand 0 "register_operand" ""))
19279 (clobber (match_operand 1 "register_operand" ""))
19280 (clobber (match_operand 2 "register_operand" ""))])
19281 (set (match_operand:QI 7 "register_operand" "")
19282 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19283 (set (match_operand:QI 8 "register_operand" "")
19284 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19285 (set (reg FLAGS_REG)
19286 (compare (match_dup 7) (match_dup 8)))
19288 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19290 (set (reg:CC FLAGS_REG)
19291 (if_then_else:CC (ne (match_dup 6)
19293 (compare:CC (mem:BLK (match_dup 4))
19294 (mem:BLK (match_dup 5)))
19296 (use (match_dup 3))
19297 (use (reg:CC FLAGS_REG))
19298 (clobber (match_dup 0))
19299 (clobber (match_dup 1))
19300 (clobber (match_dup 2))])]
19305 ;; Conditional move instructions.
19307 (define_expand "movdicc"
19308 [(set (match_operand:DI 0 "register_operand" "")
19309 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19310 (match_operand:DI 2 "general_operand" "")
19311 (match_operand:DI 3 "general_operand" "")))]
19313 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19315 (define_insn "x86_movdicc_0_m1_rex64"
19316 [(set (match_operand:DI 0 "register_operand" "=r")
19317 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19320 (clobber (reg:CC FLAGS_REG))]
19323 ; Since we don't have the proper number of operands for an alu insn,
19324 ; fill in all the blanks.
19325 [(set_attr "type" "alu")
19326 (set_attr "pent_pair" "pu")
19327 (set_attr "memory" "none")
19328 (set_attr "imm_disp" "false")
19329 (set_attr "mode" "DI")
19330 (set_attr "length_immediate" "0")])
19332 (define_insn "*x86_movdicc_0_m1_se"
19333 [(set (match_operand:DI 0 "register_operand" "=r")
19334 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19337 (clobber (reg:CC FLAGS_REG))]
19340 [(set_attr "type" "alu")
19341 (set_attr "pent_pair" "pu")
19342 (set_attr "memory" "none")
19343 (set_attr "imm_disp" "false")
19344 (set_attr "mode" "DI")
19345 (set_attr "length_immediate" "0")])
19347 (define_insn "*movdicc_c_rex64"
19348 [(set (match_operand:DI 0 "register_operand" "=r,r")
19349 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19350 [(reg FLAGS_REG) (const_int 0)])
19351 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19352 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19353 "TARGET_64BIT && TARGET_CMOVE
19354 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19356 cmov%O2%C1\t{%2, %0|%0, %2}
19357 cmov%O2%c1\t{%3, %0|%0, %3}"
19358 [(set_attr "type" "icmov")
19359 (set_attr "mode" "DI")])
19361 (define_expand "movsicc"
19362 [(set (match_operand:SI 0 "register_operand" "")
19363 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19364 (match_operand:SI 2 "general_operand" "")
19365 (match_operand:SI 3 "general_operand" "")))]
19367 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19369 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19370 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19371 ;; So just document what we're doing explicitly.
19373 (define_insn "x86_movsicc_0_m1"
19374 [(set (match_operand:SI 0 "register_operand" "=r")
19375 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19378 (clobber (reg:CC FLAGS_REG))]
19381 ; Since we don't have the proper number of operands for an alu insn,
19382 ; fill in all the blanks.
19383 [(set_attr "type" "alu")
19384 (set_attr "pent_pair" "pu")
19385 (set_attr "memory" "none")
19386 (set_attr "imm_disp" "false")
19387 (set_attr "mode" "SI")
19388 (set_attr "length_immediate" "0")])
19390 (define_insn "*x86_movsicc_0_m1_se"
19391 [(set (match_operand:SI 0 "register_operand" "=r")
19392 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19395 (clobber (reg:CC FLAGS_REG))]
19398 [(set_attr "type" "alu")
19399 (set_attr "pent_pair" "pu")
19400 (set_attr "memory" "none")
19401 (set_attr "imm_disp" "false")
19402 (set_attr "mode" "SI")
19403 (set_attr "length_immediate" "0")])
19405 (define_insn "*movsicc_noc"
19406 [(set (match_operand:SI 0 "register_operand" "=r,r")
19407 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19408 [(reg FLAGS_REG) (const_int 0)])
19409 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19410 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19412 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19414 cmov%O2%C1\t{%2, %0|%0, %2}
19415 cmov%O2%c1\t{%3, %0|%0, %3}"
19416 [(set_attr "type" "icmov")
19417 (set_attr "mode" "SI")])
19419 (define_expand "movhicc"
19420 [(set (match_operand:HI 0 "register_operand" "")
19421 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19422 (match_operand:HI 2 "general_operand" "")
19423 (match_operand:HI 3 "general_operand" "")))]
19424 "TARGET_HIMODE_MATH"
19425 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19427 (define_insn "*movhicc_noc"
19428 [(set (match_operand:HI 0 "register_operand" "=r,r")
19429 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19430 [(reg FLAGS_REG) (const_int 0)])
19431 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19432 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19434 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19436 cmov%O2%C1\t{%2, %0|%0, %2}
19437 cmov%O2%c1\t{%3, %0|%0, %3}"
19438 [(set_attr "type" "icmov")
19439 (set_attr "mode" "HI")])
19441 (define_expand "movqicc"
19442 [(set (match_operand:QI 0 "register_operand" "")
19443 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19444 (match_operand:QI 2 "general_operand" "")
19445 (match_operand:QI 3 "general_operand" "")))]
19446 "TARGET_QIMODE_MATH"
19447 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19449 (define_insn_and_split "*movqicc_noc"
19450 [(set (match_operand:QI 0 "register_operand" "=r,r")
19451 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19452 [(match_operand 4 "flags_reg_operand" "")
19454 (match_operand:QI 2 "register_operand" "r,0")
19455 (match_operand:QI 3 "register_operand" "0,r")))]
19456 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19458 "&& reload_completed"
19459 [(set (match_dup 0)
19460 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19463 "operands[0] = gen_lowpart (SImode, operands[0]);
19464 operands[2] = gen_lowpart (SImode, operands[2]);
19465 operands[3] = gen_lowpart (SImode, operands[3]);"
19466 [(set_attr "type" "icmov")
19467 (set_attr "mode" "SI")])
19469 (define_expand "mov<mode>cc"
19470 [(set (match_operand:X87MODEF 0 "register_operand" "")
19471 (if_then_else:X87MODEF
19472 (match_operand 1 "comparison_operator" "")
19473 (match_operand:X87MODEF 2 "register_operand" "")
19474 (match_operand:X87MODEF 3 "register_operand" "")))]
19475 "(TARGET_80387 && TARGET_CMOVE)
19476 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19477 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19479 (define_insn "*movsfcc_1_387"
19480 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19481 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19482 [(reg FLAGS_REG) (const_int 0)])
19483 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19484 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19485 "TARGET_80387 && TARGET_CMOVE
19486 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19488 fcmov%F1\t{%2, %0|%0, %2}
19489 fcmov%f1\t{%3, %0|%0, %3}
19490 cmov%O2%C1\t{%2, %0|%0, %2}
19491 cmov%O2%c1\t{%3, %0|%0, %3}"
19492 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19493 (set_attr "mode" "SF,SF,SI,SI")])
19495 (define_insn "*movdfcc_1"
19496 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19497 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19498 [(reg FLAGS_REG) (const_int 0)])
19499 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19500 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19501 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19502 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19504 fcmov%F1\t{%2, %0|%0, %2}
19505 fcmov%f1\t{%3, %0|%0, %3}
19508 [(set_attr "type" "fcmov,fcmov,multi,multi")
19509 (set_attr "mode" "DF")])
19511 (define_insn "*movdfcc_1_rex64"
19512 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19513 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19514 [(reg FLAGS_REG) (const_int 0)])
19515 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19516 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19517 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19518 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19520 fcmov%F1\t{%2, %0|%0, %2}
19521 fcmov%f1\t{%3, %0|%0, %3}
19522 cmov%O2%C1\t{%2, %0|%0, %2}
19523 cmov%O2%c1\t{%3, %0|%0, %3}"
19524 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19525 (set_attr "mode" "DF")])
19528 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19529 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19530 [(match_operand 4 "flags_reg_operand" "")
19532 (match_operand:DF 2 "nonimmediate_operand" "")
19533 (match_operand:DF 3 "nonimmediate_operand" "")))]
19534 "!TARGET_64BIT && reload_completed"
19535 [(set (match_dup 2)
19536 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19540 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19543 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19544 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19546 (define_insn "*movxfcc_1"
19547 [(set (match_operand:XF 0 "register_operand" "=f,f")
19548 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19549 [(reg FLAGS_REG) (const_int 0)])
19550 (match_operand:XF 2 "register_operand" "f,0")
19551 (match_operand:XF 3 "register_operand" "0,f")))]
19552 "TARGET_80387 && TARGET_CMOVE"
19554 fcmov%F1\t{%2, %0|%0, %2}
19555 fcmov%f1\t{%3, %0|%0, %3}"
19556 [(set_attr "type" "fcmov")
19557 (set_attr "mode" "XF")])
19559 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19560 ;; the scalar versions to have only XMM registers as operands.
19562 ;; SSE5 conditional move
19563 (define_insn "*sse5_pcmov_<mode>"
19564 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19565 (if_then_else:MODEF
19566 (match_operand:MODEF 1 "register_operand" "x,0")
19567 (match_operand:MODEF 2 "register_operand" "0,x")
19568 (match_operand:MODEF 3 "register_operand" "x,x")))]
19569 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19570 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19571 [(set_attr "type" "sse4arg")])
19573 ;; These versions of the min/max patterns are intentionally ignorant of
19574 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19575 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19576 ;; are undefined in this condition, we're certain this is correct.
19578 (define_insn "<code><mode>3"
19579 [(set (match_operand:MODEF 0 "register_operand" "=x")
19581 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19582 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19583 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19584 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19585 [(set_attr "type" "sseadd")
19586 (set_attr "mode" "<MODE>")])
19588 ;; These versions of the min/max patterns implement exactly the operations
19589 ;; min = (op1 < op2 ? op1 : op2)
19590 ;; max = (!(op1 < op2) ? op1 : op2)
19591 ;; Their operands are not commutative, and thus they may be used in the
19592 ;; presence of -0.0 and NaN.
19594 (define_insn "*ieee_smin<mode>3"
19595 [(set (match_operand:MODEF 0 "register_operand" "=x")
19597 [(match_operand:MODEF 1 "register_operand" "0")
19598 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19600 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19601 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19602 [(set_attr "type" "sseadd")
19603 (set_attr "mode" "<MODE>")])
19605 (define_insn "*ieee_smax<mode>3"
19606 [(set (match_operand:MODEF 0 "register_operand" "=x")
19608 [(match_operand:MODEF 1 "register_operand" "0")
19609 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19611 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19612 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19613 [(set_attr "type" "sseadd")
19614 (set_attr "mode" "<MODE>")])
19616 ;; Make two stack loads independent:
19618 ;; fld %st(0) -> fld bb
19619 ;; fmul bb fmul %st(1), %st
19621 ;; Actually we only match the last two instructions for simplicity.
19623 [(set (match_operand 0 "fp_register_operand" "")
19624 (match_operand 1 "fp_register_operand" ""))
19626 (match_operator 2 "binary_fp_operator"
19628 (match_operand 3 "memory_operand" "")]))]
19629 "REGNO (operands[0]) != REGNO (operands[1])"
19630 [(set (match_dup 0) (match_dup 3))
19631 (set (match_dup 0) (match_dup 4))]
19633 ;; The % modifier is not operational anymore in peephole2's, so we have to
19634 ;; swap the operands manually in the case of addition and multiplication.
19635 "if (COMMUTATIVE_ARITH_P (operands[2]))
19636 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19637 operands[0], operands[1]);
19639 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19640 operands[1], operands[0]);")
19642 ;; Conditional addition patterns
19643 (define_expand "add<mode>cc"
19644 [(match_operand:SWI 0 "register_operand" "")
19645 (match_operand 1 "comparison_operator" "")
19646 (match_operand:SWI 2 "register_operand" "")
19647 (match_operand:SWI 3 "const_int_operand" "")]
19649 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19652 ;; Misc patterns (?)
19654 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19655 ;; Otherwise there will be nothing to keep
19657 ;; [(set (reg ebp) (reg esp))]
19658 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19659 ;; (clobber (eflags)]
19660 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19662 ;; in proper program order.
19663 (define_insn "pro_epilogue_adjust_stack_1"
19664 [(set (match_operand:SI 0 "register_operand" "=r,r")
19665 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19666 (match_operand:SI 2 "immediate_operand" "i,i")))
19667 (clobber (reg:CC FLAGS_REG))
19668 (clobber (mem:BLK (scratch)))]
19671 switch (get_attr_type (insn))
19674 return "mov{l}\t{%1, %0|%0, %1}";
19677 if (CONST_INT_P (operands[2])
19678 && (INTVAL (operands[2]) == 128
19679 || (INTVAL (operands[2]) < 0
19680 && INTVAL (operands[2]) != -128)))
19682 operands[2] = GEN_INT (-INTVAL (operands[2]));
19683 return "sub{l}\t{%2, %0|%0, %2}";
19685 return "add{l}\t{%2, %0|%0, %2}";
19688 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19689 return "lea{l}\t{%a2, %0|%0, %a2}";
19692 gcc_unreachable ();
19695 [(set (attr "type")
19696 (cond [(eq_attr "alternative" "0")
19697 (const_string "alu")
19698 (match_operand:SI 2 "const0_operand" "")
19699 (const_string "imov")
19701 (const_string "lea")))
19702 (set_attr "mode" "SI")])
19704 (define_insn "pro_epilogue_adjust_stack_rex64"
19705 [(set (match_operand:DI 0 "register_operand" "=r,r")
19706 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19707 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19708 (clobber (reg:CC FLAGS_REG))
19709 (clobber (mem:BLK (scratch)))]
19712 switch (get_attr_type (insn))
19715 return "mov{q}\t{%1, %0|%0, %1}";
19718 if (CONST_INT_P (operands[2])
19719 /* Avoid overflows. */
19720 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19721 && (INTVAL (operands[2]) == 128
19722 || (INTVAL (operands[2]) < 0
19723 && INTVAL (operands[2]) != -128)))
19725 operands[2] = GEN_INT (-INTVAL (operands[2]));
19726 return "sub{q}\t{%2, %0|%0, %2}";
19728 return "add{q}\t{%2, %0|%0, %2}";
19731 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19732 return "lea{q}\t{%a2, %0|%0, %a2}";
19735 gcc_unreachable ();
19738 [(set (attr "type")
19739 (cond [(eq_attr "alternative" "0")
19740 (const_string "alu")
19741 (match_operand:DI 2 "const0_operand" "")
19742 (const_string "imov")
19744 (const_string "lea")))
19745 (set_attr "mode" "DI")])
19747 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19748 [(set (match_operand:DI 0 "register_operand" "=r,r")
19749 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19750 (match_operand:DI 3 "immediate_operand" "i,i")))
19751 (use (match_operand:DI 2 "register_operand" "r,r"))
19752 (clobber (reg:CC FLAGS_REG))
19753 (clobber (mem:BLK (scratch)))]
19756 switch (get_attr_type (insn))
19759 return "add{q}\t{%2, %0|%0, %2}";
19762 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19763 return "lea{q}\t{%a2, %0|%0, %a2}";
19766 gcc_unreachable ();
19769 [(set_attr "type" "alu,lea")
19770 (set_attr "mode" "DI")])
19772 (define_insn "allocate_stack_worker_32"
19773 [(set (match_operand:SI 0 "register_operand" "+a")
19774 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19775 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19776 (clobber (reg:CC FLAGS_REG))]
19777 "!TARGET_64BIT && TARGET_STACK_PROBE"
19779 [(set_attr "type" "multi")
19780 (set_attr "length" "5")])
19782 (define_insn "allocate_stack_worker_64"
19783 [(set (match_operand:DI 0 "register_operand" "+a")
19784 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19785 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19786 (clobber (reg:DI R10_REG))
19787 (clobber (reg:DI R11_REG))
19788 (clobber (reg:CC FLAGS_REG))]
19789 "TARGET_64BIT && TARGET_STACK_PROBE"
19791 [(set_attr "type" "multi")
19792 (set_attr "length" "5")])
19794 (define_expand "allocate_stack"
19795 [(match_operand 0 "register_operand" "")
19796 (match_operand 1 "general_operand" "")]
19797 "TARGET_STACK_PROBE"
19801 #ifndef CHECK_STACK_LIMIT
19802 #define CHECK_STACK_LIMIT 0
19805 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19806 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19808 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19809 stack_pointer_rtx, 0, OPTAB_DIRECT);
19810 if (x != stack_pointer_rtx)
19811 emit_move_insn (stack_pointer_rtx, x);
19815 x = copy_to_mode_reg (Pmode, operands[1]);
19817 x = gen_allocate_stack_worker_64 (x);
19819 x = gen_allocate_stack_worker_32 (x);
19823 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19827 (define_expand "builtin_setjmp_receiver"
19828 [(label_ref (match_operand 0 "" ""))]
19829 "!TARGET_64BIT && flag_pic"
19834 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19835 rtx label_rtx = gen_label_rtx ();
19836 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19837 xops[0] = xops[1] = picreg;
19838 xops[2] = gen_rtx_CONST (SImode,
19839 gen_rtx_MINUS (SImode,
19840 gen_rtx_LABEL_REF (SImode, label_rtx),
19841 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19842 ix86_expand_binary_operator (MINUS, SImode, xops);
19845 emit_insn (gen_set_got (pic_offset_table_rtx));
19849 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19852 [(set (match_operand 0 "register_operand" "")
19853 (match_operator 3 "promotable_binary_operator"
19854 [(match_operand 1 "register_operand" "")
19855 (match_operand 2 "aligned_operand" "")]))
19856 (clobber (reg:CC FLAGS_REG))]
19857 "! TARGET_PARTIAL_REG_STALL && reload_completed
19858 && ((GET_MODE (operands[0]) == HImode
19859 && ((!optimize_size && !TARGET_FAST_PREFIX)
19860 /* ??? next two lines just !satisfies_constraint_K (...) */
19861 || !CONST_INT_P (operands[2])
19862 || satisfies_constraint_K (operands[2])))
19863 || (GET_MODE (operands[0]) == QImode
19864 && (TARGET_PROMOTE_QImode || optimize_size)))"
19865 [(parallel [(set (match_dup 0)
19866 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19867 (clobber (reg:CC FLAGS_REG))])]
19868 "operands[0] = gen_lowpart (SImode, operands[0]);
19869 operands[1] = gen_lowpart (SImode, operands[1]);
19870 if (GET_CODE (operands[3]) != ASHIFT)
19871 operands[2] = gen_lowpart (SImode, operands[2]);
19872 PUT_MODE (operands[3], SImode);")
19874 ; Promote the QImode tests, as i386 has encoding of the AND
19875 ; instruction with 32-bit sign-extended immediate and thus the
19876 ; instruction size is unchanged, except in the %eax case for
19877 ; which it is increased by one byte, hence the ! optimize_size.
19879 [(set (match_operand 0 "flags_reg_operand" "")
19880 (match_operator 2 "compare_operator"
19881 [(and (match_operand 3 "aligned_operand" "")
19882 (match_operand 4 "const_int_operand" ""))
19884 (set (match_operand 1 "register_operand" "")
19885 (and (match_dup 3) (match_dup 4)))]
19886 "! TARGET_PARTIAL_REG_STALL && reload_completed
19888 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19889 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19890 /* Ensure that the operand will remain sign-extended immediate. */
19891 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19892 [(parallel [(set (match_dup 0)
19893 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19896 (and:SI (match_dup 3) (match_dup 4)))])]
19899 = gen_int_mode (INTVAL (operands[4])
19900 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19901 operands[1] = gen_lowpart (SImode, operands[1]);
19902 operands[3] = gen_lowpart (SImode, operands[3]);
19905 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19906 ; the TEST instruction with 32-bit sign-extended immediate and thus
19907 ; the instruction size would at least double, which is not what we
19908 ; want even with ! optimize_size.
19910 [(set (match_operand 0 "flags_reg_operand" "")
19911 (match_operator 1 "compare_operator"
19912 [(and (match_operand:HI 2 "aligned_operand" "")
19913 (match_operand:HI 3 "const_int_operand" ""))
19915 "! TARGET_PARTIAL_REG_STALL && reload_completed
19916 && ! TARGET_FAST_PREFIX
19918 /* Ensure that the operand will remain sign-extended immediate. */
19919 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19920 [(set (match_dup 0)
19921 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19925 = gen_int_mode (INTVAL (operands[3])
19926 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19927 operands[2] = gen_lowpart (SImode, operands[2]);
19931 [(set (match_operand 0 "register_operand" "")
19932 (neg (match_operand 1 "register_operand" "")))
19933 (clobber (reg:CC FLAGS_REG))]
19934 "! TARGET_PARTIAL_REG_STALL && reload_completed
19935 && (GET_MODE (operands[0]) == HImode
19936 || (GET_MODE (operands[0]) == QImode
19937 && (TARGET_PROMOTE_QImode || optimize_size)))"
19938 [(parallel [(set (match_dup 0)
19939 (neg:SI (match_dup 1)))
19940 (clobber (reg:CC FLAGS_REG))])]
19941 "operands[0] = gen_lowpart (SImode, operands[0]);
19942 operands[1] = gen_lowpart (SImode, operands[1]);")
19945 [(set (match_operand 0 "register_operand" "")
19946 (not (match_operand 1 "register_operand" "")))]
19947 "! TARGET_PARTIAL_REG_STALL && reload_completed
19948 && (GET_MODE (operands[0]) == HImode
19949 || (GET_MODE (operands[0]) == QImode
19950 && (TARGET_PROMOTE_QImode || optimize_size)))"
19951 [(set (match_dup 0)
19952 (not:SI (match_dup 1)))]
19953 "operands[0] = gen_lowpart (SImode, operands[0]);
19954 operands[1] = gen_lowpart (SImode, operands[1]);")
19957 [(set (match_operand 0 "register_operand" "")
19958 (if_then_else (match_operator 1 "comparison_operator"
19959 [(reg FLAGS_REG) (const_int 0)])
19960 (match_operand 2 "register_operand" "")
19961 (match_operand 3 "register_operand" "")))]
19962 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19963 && (GET_MODE (operands[0]) == HImode
19964 || (GET_MODE (operands[0]) == QImode
19965 && (TARGET_PROMOTE_QImode || optimize_size)))"
19966 [(set (match_dup 0)
19967 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19968 "operands[0] = gen_lowpart (SImode, operands[0]);
19969 operands[2] = gen_lowpart (SImode, operands[2]);
19970 operands[3] = gen_lowpart (SImode, operands[3]);")
19973 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19974 ;; transform a complex memory operation into two memory to register operations.
19976 ;; Don't push memory operands
19978 [(set (match_operand:SI 0 "push_operand" "")
19979 (match_operand:SI 1 "memory_operand" ""))
19980 (match_scratch:SI 2 "r")]
19981 "!optimize_size && !TARGET_PUSH_MEMORY
19982 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19983 [(set (match_dup 2) (match_dup 1))
19984 (set (match_dup 0) (match_dup 2))]
19988 [(set (match_operand:DI 0 "push_operand" "")
19989 (match_operand:DI 1 "memory_operand" ""))
19990 (match_scratch:DI 2 "r")]
19991 "!optimize_size && !TARGET_PUSH_MEMORY
19992 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19993 [(set (match_dup 2) (match_dup 1))
19994 (set (match_dup 0) (match_dup 2))]
19997 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20000 [(set (match_operand:SF 0 "push_operand" "")
20001 (match_operand:SF 1 "memory_operand" ""))
20002 (match_scratch:SF 2 "r")]
20003 "!optimize_size && !TARGET_PUSH_MEMORY
20004 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20005 [(set (match_dup 2) (match_dup 1))
20006 (set (match_dup 0) (match_dup 2))]
20010 [(set (match_operand:HI 0 "push_operand" "")
20011 (match_operand:HI 1 "memory_operand" ""))
20012 (match_scratch:HI 2 "r")]
20013 "!optimize_size && !TARGET_PUSH_MEMORY
20014 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20015 [(set (match_dup 2) (match_dup 1))
20016 (set (match_dup 0) (match_dup 2))]
20020 [(set (match_operand:QI 0 "push_operand" "")
20021 (match_operand:QI 1 "memory_operand" ""))
20022 (match_scratch:QI 2 "q")]
20023 "!optimize_size && !TARGET_PUSH_MEMORY
20024 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20025 [(set (match_dup 2) (match_dup 1))
20026 (set (match_dup 0) (match_dup 2))]
20029 ;; Don't move an immediate directly to memory when the instruction
20032 [(match_scratch:SI 1 "r")
20033 (set (match_operand:SI 0 "memory_operand" "")
20036 && ! TARGET_USE_MOV0
20037 && TARGET_SPLIT_LONG_MOVES
20038 && get_attr_length (insn) >= ix86_cost->large_insn
20039 && peep2_regno_dead_p (0, FLAGS_REG)"
20040 [(parallel [(set (match_dup 1) (const_int 0))
20041 (clobber (reg:CC FLAGS_REG))])
20042 (set (match_dup 0) (match_dup 1))]
20046 [(match_scratch:HI 1 "r")
20047 (set (match_operand:HI 0 "memory_operand" "")
20050 && ! TARGET_USE_MOV0
20051 && TARGET_SPLIT_LONG_MOVES
20052 && get_attr_length (insn) >= ix86_cost->large_insn
20053 && peep2_regno_dead_p (0, FLAGS_REG)"
20054 [(parallel [(set (match_dup 2) (const_int 0))
20055 (clobber (reg:CC FLAGS_REG))])
20056 (set (match_dup 0) (match_dup 1))]
20057 "operands[2] = gen_lowpart (SImode, operands[1]);")
20060 [(match_scratch:QI 1 "q")
20061 (set (match_operand:QI 0 "memory_operand" "")
20064 && ! TARGET_USE_MOV0
20065 && TARGET_SPLIT_LONG_MOVES
20066 && get_attr_length (insn) >= ix86_cost->large_insn
20067 && peep2_regno_dead_p (0, FLAGS_REG)"
20068 [(parallel [(set (match_dup 2) (const_int 0))
20069 (clobber (reg:CC FLAGS_REG))])
20070 (set (match_dup 0) (match_dup 1))]
20071 "operands[2] = gen_lowpart (SImode, operands[1]);")
20074 [(match_scratch:SI 2 "r")
20075 (set (match_operand:SI 0 "memory_operand" "")
20076 (match_operand:SI 1 "immediate_operand" ""))]
20078 && TARGET_SPLIT_LONG_MOVES
20079 && get_attr_length (insn) >= ix86_cost->large_insn"
20080 [(set (match_dup 2) (match_dup 1))
20081 (set (match_dup 0) (match_dup 2))]
20085 [(match_scratch:HI 2 "r")
20086 (set (match_operand:HI 0 "memory_operand" "")
20087 (match_operand:HI 1 "immediate_operand" ""))]
20089 && TARGET_SPLIT_LONG_MOVES
20090 && get_attr_length (insn) >= ix86_cost->large_insn"
20091 [(set (match_dup 2) (match_dup 1))
20092 (set (match_dup 0) (match_dup 2))]
20096 [(match_scratch:QI 2 "q")
20097 (set (match_operand:QI 0 "memory_operand" "")
20098 (match_operand:QI 1 "immediate_operand" ""))]
20100 && TARGET_SPLIT_LONG_MOVES
20101 && get_attr_length (insn) >= ix86_cost->large_insn"
20102 [(set (match_dup 2) (match_dup 1))
20103 (set (match_dup 0) (match_dup 2))]
20106 ;; Don't compare memory with zero, load and use a test instead.
20108 [(set (match_operand 0 "flags_reg_operand" "")
20109 (match_operator 1 "compare_operator"
20110 [(match_operand:SI 2 "memory_operand" "")
20112 (match_scratch:SI 3 "r")]
20113 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20114 [(set (match_dup 3) (match_dup 2))
20115 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20118 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20119 ;; Don't split NOTs with a displacement operand, because resulting XOR
20120 ;; will not be pairable anyway.
20122 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20123 ;; represented using a modRM byte. The XOR replacement is long decoded,
20124 ;; so this split helps here as well.
20126 ;; Note: Can't do this as a regular split because we can't get proper
20127 ;; lifetime information then.
20130 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20131 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20133 && ((TARGET_NOT_UNPAIRABLE
20134 && (!MEM_P (operands[0])
20135 || !memory_displacement_operand (operands[0], SImode)))
20136 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20137 && peep2_regno_dead_p (0, FLAGS_REG)"
20138 [(parallel [(set (match_dup 0)
20139 (xor:SI (match_dup 1) (const_int -1)))
20140 (clobber (reg:CC FLAGS_REG))])]
20144 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20145 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20147 && ((TARGET_NOT_UNPAIRABLE
20148 && (!MEM_P (operands[0])
20149 || !memory_displacement_operand (operands[0], HImode)))
20150 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20151 && peep2_regno_dead_p (0, FLAGS_REG)"
20152 [(parallel [(set (match_dup 0)
20153 (xor:HI (match_dup 1) (const_int -1)))
20154 (clobber (reg:CC FLAGS_REG))])]
20158 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20159 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20161 && ((TARGET_NOT_UNPAIRABLE
20162 && (!MEM_P (operands[0])
20163 || !memory_displacement_operand (operands[0], QImode)))
20164 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20165 && peep2_regno_dead_p (0, FLAGS_REG)"
20166 [(parallel [(set (match_dup 0)
20167 (xor:QI (match_dup 1) (const_int -1)))
20168 (clobber (reg:CC FLAGS_REG))])]
20171 ;; Non pairable "test imm, reg" instructions can be translated to
20172 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20173 ;; byte opcode instead of two, have a short form for byte operands),
20174 ;; so do it for other CPUs as well. Given that the value was dead,
20175 ;; this should not create any new dependencies. Pass on the sub-word
20176 ;; versions if we're concerned about partial register stalls.
20179 [(set (match_operand 0 "flags_reg_operand" "")
20180 (match_operator 1 "compare_operator"
20181 [(and:SI (match_operand:SI 2 "register_operand" "")
20182 (match_operand:SI 3 "immediate_operand" ""))
20184 "ix86_match_ccmode (insn, CCNOmode)
20185 && (true_regnum (operands[2]) != AX_REG
20186 || satisfies_constraint_K (operands[3]))
20187 && peep2_reg_dead_p (1, operands[2])"
20189 [(set (match_dup 0)
20190 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20193 (and:SI (match_dup 2) (match_dup 3)))])]
20196 ;; We don't need to handle HImode case, because it will be promoted to SImode
20197 ;; on ! TARGET_PARTIAL_REG_STALL
20200 [(set (match_operand 0 "flags_reg_operand" "")
20201 (match_operator 1 "compare_operator"
20202 [(and:QI (match_operand:QI 2 "register_operand" "")
20203 (match_operand:QI 3 "immediate_operand" ""))
20205 "! TARGET_PARTIAL_REG_STALL
20206 && ix86_match_ccmode (insn, CCNOmode)
20207 && true_regnum (operands[2]) != AX_REG
20208 && peep2_reg_dead_p (1, operands[2])"
20210 [(set (match_dup 0)
20211 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20214 (and:QI (match_dup 2) (match_dup 3)))])]
20218 [(set (match_operand 0 "flags_reg_operand" "")
20219 (match_operator 1 "compare_operator"
20222 (match_operand 2 "ext_register_operand" "")
20225 (match_operand 3 "const_int_operand" ""))
20227 "! TARGET_PARTIAL_REG_STALL
20228 && ix86_match_ccmode (insn, CCNOmode)
20229 && true_regnum (operands[2]) != AX_REG
20230 && peep2_reg_dead_p (1, operands[2])"
20231 [(parallel [(set (match_dup 0)
20240 (set (zero_extract:SI (match_dup 2)
20251 ;; Don't do logical operations with memory inputs.
20253 [(match_scratch:SI 2 "r")
20254 (parallel [(set (match_operand:SI 0 "register_operand" "")
20255 (match_operator:SI 3 "arith_or_logical_operator"
20257 (match_operand:SI 1 "memory_operand" "")]))
20258 (clobber (reg:CC FLAGS_REG))])]
20259 "! optimize_size && ! TARGET_READ_MODIFY"
20260 [(set (match_dup 2) (match_dup 1))
20261 (parallel [(set (match_dup 0)
20262 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20263 (clobber (reg:CC FLAGS_REG))])]
20267 [(match_scratch:SI 2 "r")
20268 (parallel [(set (match_operand:SI 0 "register_operand" "")
20269 (match_operator:SI 3 "arith_or_logical_operator"
20270 [(match_operand:SI 1 "memory_operand" "")
20272 (clobber (reg:CC FLAGS_REG))])]
20273 "! optimize_size && ! TARGET_READ_MODIFY"
20274 [(set (match_dup 2) (match_dup 1))
20275 (parallel [(set (match_dup 0)
20276 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20277 (clobber (reg:CC FLAGS_REG))])]
20280 ; Don't do logical operations with memory outputs
20282 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20283 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20284 ; the same decoder scheduling characteristics as the original.
20287 [(match_scratch:SI 2 "r")
20288 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20289 (match_operator:SI 3 "arith_or_logical_operator"
20291 (match_operand:SI 1 "nonmemory_operand" "")]))
20292 (clobber (reg:CC FLAGS_REG))])]
20293 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20294 [(set (match_dup 2) (match_dup 0))
20295 (parallel [(set (match_dup 2)
20296 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20297 (clobber (reg:CC FLAGS_REG))])
20298 (set (match_dup 0) (match_dup 2))]
20302 [(match_scratch:SI 2 "r")
20303 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20304 (match_operator:SI 3 "arith_or_logical_operator"
20305 [(match_operand:SI 1 "nonmemory_operand" "")
20307 (clobber (reg:CC FLAGS_REG))])]
20308 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20309 [(set (match_dup 2) (match_dup 0))
20310 (parallel [(set (match_dup 2)
20311 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20312 (clobber (reg:CC FLAGS_REG))])
20313 (set (match_dup 0) (match_dup 2))]
20316 ;; Attempt to always use XOR for zeroing registers.
20318 [(set (match_operand 0 "register_operand" "")
20319 (match_operand 1 "const0_operand" ""))]
20320 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20321 && (! TARGET_USE_MOV0 || optimize_size)
20322 && GENERAL_REG_P (operands[0])
20323 && peep2_regno_dead_p (0, FLAGS_REG)"
20324 [(parallel [(set (match_dup 0) (const_int 0))
20325 (clobber (reg:CC FLAGS_REG))])]
20327 operands[0] = gen_lowpart (word_mode, operands[0]);
20331 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20333 "(GET_MODE (operands[0]) == QImode
20334 || GET_MODE (operands[0]) == HImode)
20335 && (! TARGET_USE_MOV0 || optimize_size)
20336 && peep2_regno_dead_p (0, FLAGS_REG)"
20337 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20338 (clobber (reg:CC FLAGS_REG))])])
20340 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20342 [(set (match_operand 0 "register_operand" "")
20344 "(GET_MODE (operands[0]) == HImode
20345 || GET_MODE (operands[0]) == SImode
20346 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20347 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20348 && peep2_regno_dead_p (0, FLAGS_REG)"
20349 [(parallel [(set (match_dup 0) (const_int -1))
20350 (clobber (reg:CC FLAGS_REG))])]
20351 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20354 ;; Attempt to convert simple leas to adds. These can be created by
20357 [(set (match_operand:SI 0 "register_operand" "")
20358 (plus:SI (match_dup 0)
20359 (match_operand:SI 1 "nonmemory_operand" "")))]
20360 "peep2_regno_dead_p (0, FLAGS_REG)"
20361 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20362 (clobber (reg:CC FLAGS_REG))])]
20366 [(set (match_operand:SI 0 "register_operand" "")
20367 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20368 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20369 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20370 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20371 (clobber (reg:CC FLAGS_REG))])]
20372 "operands[2] = gen_lowpart (SImode, operands[2]);")
20375 [(set (match_operand:DI 0 "register_operand" "")
20376 (plus:DI (match_dup 0)
20377 (match_operand:DI 1 "x86_64_general_operand" "")))]
20378 "peep2_regno_dead_p (0, FLAGS_REG)"
20379 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20380 (clobber (reg:CC FLAGS_REG))])]
20384 [(set (match_operand:SI 0 "register_operand" "")
20385 (mult:SI (match_dup 0)
20386 (match_operand:SI 1 "const_int_operand" "")))]
20387 "exact_log2 (INTVAL (operands[1])) >= 0
20388 && peep2_regno_dead_p (0, FLAGS_REG)"
20389 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20390 (clobber (reg:CC FLAGS_REG))])]
20391 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20394 [(set (match_operand:DI 0 "register_operand" "")
20395 (mult:DI (match_dup 0)
20396 (match_operand:DI 1 "const_int_operand" "")))]
20397 "exact_log2 (INTVAL (operands[1])) >= 0
20398 && peep2_regno_dead_p (0, FLAGS_REG)"
20399 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20400 (clobber (reg:CC FLAGS_REG))])]
20401 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20404 [(set (match_operand:SI 0 "register_operand" "")
20405 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20406 (match_operand:DI 2 "const_int_operand" "")) 0))]
20407 "exact_log2 (INTVAL (operands[2])) >= 0
20408 && REGNO (operands[0]) == REGNO (operands[1])
20409 && peep2_regno_dead_p (0, FLAGS_REG)"
20410 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20411 (clobber (reg:CC FLAGS_REG))])]
20412 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20414 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20415 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20416 ;; many CPUs it is also faster, since special hardware to avoid esp
20417 ;; dependencies is present.
20419 ;; While some of these conversions may be done using splitters, we use peepholes
20420 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20422 ;; Convert prologue esp subtractions to push.
20423 ;; We need register to push. In order to keep verify_flow_info happy we have
20425 ;; - use scratch and clobber it in order to avoid dependencies
20426 ;; - use already live register
20427 ;; We can't use the second way right now, since there is no reliable way how to
20428 ;; verify that given register is live. First choice will also most likely in
20429 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20430 ;; call clobbered registers are dead. We may want to use base pointer as an
20431 ;; alternative when no register is available later.
20434 [(match_scratch:SI 0 "r")
20435 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20436 (clobber (reg:CC FLAGS_REG))
20437 (clobber (mem:BLK (scratch)))])]
20438 "optimize_size || !TARGET_SUB_ESP_4"
20439 [(clobber (match_dup 0))
20440 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20441 (clobber (mem:BLK (scratch)))])])
20444 [(match_scratch:SI 0 "r")
20445 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20446 (clobber (reg:CC FLAGS_REG))
20447 (clobber (mem:BLK (scratch)))])]
20448 "optimize_size || !TARGET_SUB_ESP_8"
20449 [(clobber (match_dup 0))
20450 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20451 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20452 (clobber (mem:BLK (scratch)))])])
20454 ;; Convert esp subtractions to push.
20456 [(match_scratch:SI 0 "r")
20457 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20458 (clobber (reg:CC FLAGS_REG))])]
20459 "optimize_size || !TARGET_SUB_ESP_4"
20460 [(clobber (match_dup 0))
20461 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20464 [(match_scratch:SI 0 "r")
20465 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20466 (clobber (reg:CC FLAGS_REG))])]
20467 "optimize_size || !TARGET_SUB_ESP_8"
20468 [(clobber (match_dup 0))
20469 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20470 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20472 ;; Convert epilogue deallocator to pop.
20474 [(match_scratch:SI 0 "r")
20475 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20476 (clobber (reg:CC FLAGS_REG))
20477 (clobber (mem:BLK (scratch)))])]
20478 "optimize_size || !TARGET_ADD_ESP_4"
20479 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20480 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20481 (clobber (mem:BLK (scratch)))])]
20484 ;; Two pops case is tricky, since pop causes dependency on destination register.
20485 ;; We use two registers if available.
20487 [(match_scratch:SI 0 "r")
20488 (match_scratch:SI 1 "r")
20489 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20490 (clobber (reg:CC FLAGS_REG))
20491 (clobber (mem:BLK (scratch)))])]
20492 "optimize_size || !TARGET_ADD_ESP_8"
20493 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20494 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20495 (clobber (mem:BLK (scratch)))])
20496 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20497 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20501 [(match_scratch:SI 0 "r")
20502 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20503 (clobber (reg:CC FLAGS_REG))
20504 (clobber (mem:BLK (scratch)))])]
20506 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20507 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20508 (clobber (mem:BLK (scratch)))])
20509 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20510 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20513 ;; Convert esp additions to pop.
20515 [(match_scratch:SI 0 "r")
20516 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20517 (clobber (reg:CC FLAGS_REG))])]
20519 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20520 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20523 ;; Two pops case is tricky, since pop causes dependency on destination register.
20524 ;; We use two registers if available.
20526 [(match_scratch:SI 0 "r")
20527 (match_scratch:SI 1 "r")
20528 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20529 (clobber (reg:CC FLAGS_REG))])]
20531 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20532 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20533 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20534 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20538 [(match_scratch:SI 0 "r")
20539 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20540 (clobber (reg:CC FLAGS_REG))])]
20542 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20543 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20544 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20545 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20548 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20549 ;; required and register dies. Similarly for 128 to plus -128.
20551 [(set (match_operand 0 "flags_reg_operand" "")
20552 (match_operator 1 "compare_operator"
20553 [(match_operand 2 "register_operand" "")
20554 (match_operand 3 "const_int_operand" "")]))]
20555 "(INTVAL (operands[3]) == -1
20556 || INTVAL (operands[3]) == 1
20557 || INTVAL (operands[3]) == 128)
20558 && ix86_match_ccmode (insn, CCGCmode)
20559 && peep2_reg_dead_p (1, operands[2])"
20560 [(parallel [(set (match_dup 0)
20561 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20562 (clobber (match_dup 2))])]
20566 [(match_scratch:DI 0 "r")
20567 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20568 (clobber (reg:CC FLAGS_REG))
20569 (clobber (mem:BLK (scratch)))])]
20570 "optimize_size || !TARGET_SUB_ESP_4"
20571 [(clobber (match_dup 0))
20572 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20573 (clobber (mem:BLK (scratch)))])])
20576 [(match_scratch:DI 0 "r")
20577 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20578 (clobber (reg:CC FLAGS_REG))
20579 (clobber (mem:BLK (scratch)))])]
20580 "optimize_size || !TARGET_SUB_ESP_8"
20581 [(clobber (match_dup 0))
20582 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20583 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20584 (clobber (mem:BLK (scratch)))])])
20586 ;; Convert esp subtractions to push.
20588 [(match_scratch:DI 0 "r")
20589 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20590 (clobber (reg:CC FLAGS_REG))])]
20591 "optimize_size || !TARGET_SUB_ESP_4"
20592 [(clobber (match_dup 0))
20593 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20596 [(match_scratch:DI 0 "r")
20597 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20598 (clobber (reg:CC FLAGS_REG))])]
20599 "optimize_size || !TARGET_SUB_ESP_8"
20600 [(clobber (match_dup 0))
20601 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20602 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20604 ;; Convert epilogue deallocator to pop.
20606 [(match_scratch:DI 0 "r")
20607 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20608 (clobber (reg:CC FLAGS_REG))
20609 (clobber (mem:BLK (scratch)))])]
20610 "optimize_size || !TARGET_ADD_ESP_4"
20611 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20612 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20613 (clobber (mem:BLK (scratch)))])]
20616 ;; Two pops case is tricky, since pop causes dependency on destination register.
20617 ;; We use two registers if available.
20619 [(match_scratch:DI 0 "r")
20620 (match_scratch:DI 1 "r")
20621 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20622 (clobber (reg:CC FLAGS_REG))
20623 (clobber (mem:BLK (scratch)))])]
20624 "optimize_size || !TARGET_ADD_ESP_8"
20625 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20626 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20627 (clobber (mem:BLK (scratch)))])
20628 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20629 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20633 [(match_scratch:DI 0 "r")
20634 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20635 (clobber (reg:CC FLAGS_REG))
20636 (clobber (mem:BLK (scratch)))])]
20638 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20639 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20640 (clobber (mem:BLK (scratch)))])
20641 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20642 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20645 ;; Convert esp additions to pop.
20647 [(match_scratch:DI 0 "r")
20648 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20649 (clobber (reg:CC FLAGS_REG))])]
20651 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20652 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20655 ;; Two pops case is tricky, since pop causes dependency on destination register.
20656 ;; We use two registers if available.
20658 [(match_scratch:DI 0 "r")
20659 (match_scratch:DI 1 "r")
20660 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20661 (clobber (reg:CC FLAGS_REG))])]
20663 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20664 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20665 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20666 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20670 [(match_scratch:DI 0 "r")
20671 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20672 (clobber (reg:CC FLAGS_REG))])]
20674 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20675 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20676 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20677 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20680 ;; Convert imul by three, five and nine into lea
20683 [(set (match_operand:SI 0 "register_operand" "")
20684 (mult:SI (match_operand:SI 1 "register_operand" "")
20685 (match_operand:SI 2 "const_int_operand" "")))
20686 (clobber (reg:CC FLAGS_REG))])]
20687 "INTVAL (operands[2]) == 3
20688 || INTVAL (operands[2]) == 5
20689 || INTVAL (operands[2]) == 9"
20690 [(set (match_dup 0)
20691 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20693 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20697 [(set (match_operand:SI 0 "register_operand" "")
20698 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20699 (match_operand:SI 2 "const_int_operand" "")))
20700 (clobber (reg:CC FLAGS_REG))])]
20702 && (INTVAL (operands[2]) == 3
20703 || INTVAL (operands[2]) == 5
20704 || INTVAL (operands[2]) == 9)"
20705 [(set (match_dup 0) (match_dup 1))
20707 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20709 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20713 [(set (match_operand:DI 0 "register_operand" "")
20714 (mult:DI (match_operand:DI 1 "register_operand" "")
20715 (match_operand:DI 2 "const_int_operand" "")))
20716 (clobber (reg:CC FLAGS_REG))])]
20718 && (INTVAL (operands[2]) == 3
20719 || INTVAL (operands[2]) == 5
20720 || INTVAL (operands[2]) == 9)"
20721 [(set (match_dup 0)
20722 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20724 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20728 [(set (match_operand:DI 0 "register_operand" "")
20729 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20730 (match_operand:DI 2 "const_int_operand" "")))
20731 (clobber (reg:CC FLAGS_REG))])]
20734 && (INTVAL (operands[2]) == 3
20735 || INTVAL (operands[2]) == 5
20736 || INTVAL (operands[2]) == 9)"
20737 [(set (match_dup 0) (match_dup 1))
20739 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20741 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20743 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20744 ;; imul $32bit_imm, reg, reg is direct decoded.
20746 [(match_scratch:DI 3 "r")
20747 (parallel [(set (match_operand:DI 0 "register_operand" "")
20748 (mult:DI (match_operand:DI 1 "memory_operand" "")
20749 (match_operand:DI 2 "immediate_operand" "")))
20750 (clobber (reg:CC FLAGS_REG))])]
20751 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20752 && !satisfies_constraint_K (operands[2])"
20753 [(set (match_dup 3) (match_dup 1))
20754 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20755 (clobber (reg:CC FLAGS_REG))])]
20759 [(match_scratch:SI 3 "r")
20760 (parallel [(set (match_operand:SI 0 "register_operand" "")
20761 (mult:SI (match_operand:SI 1 "memory_operand" "")
20762 (match_operand:SI 2 "immediate_operand" "")))
20763 (clobber (reg:CC FLAGS_REG))])]
20764 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20765 && !satisfies_constraint_K (operands[2])"
20766 [(set (match_dup 3) (match_dup 1))
20767 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20768 (clobber (reg:CC FLAGS_REG))])]
20772 [(match_scratch:SI 3 "r")
20773 (parallel [(set (match_operand:DI 0 "register_operand" "")
20775 (mult:SI (match_operand:SI 1 "memory_operand" "")
20776 (match_operand:SI 2 "immediate_operand" ""))))
20777 (clobber (reg:CC FLAGS_REG))])]
20778 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20779 && !satisfies_constraint_K (operands[2])"
20780 [(set (match_dup 3) (match_dup 1))
20781 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20782 (clobber (reg:CC FLAGS_REG))])]
20785 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20786 ;; Convert it into imul reg, reg
20787 ;; It would be better to force assembler to encode instruction using long
20788 ;; immediate, but there is apparently no way to do so.
20790 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20791 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20792 (match_operand:DI 2 "const_int_operand" "")))
20793 (clobber (reg:CC FLAGS_REG))])
20794 (match_scratch:DI 3 "r")]
20795 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20796 && satisfies_constraint_K (operands[2])"
20797 [(set (match_dup 3) (match_dup 2))
20798 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20799 (clobber (reg:CC FLAGS_REG))])]
20801 if (!rtx_equal_p (operands[0], operands[1]))
20802 emit_move_insn (operands[0], operands[1]);
20806 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20807 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20808 (match_operand:SI 2 "const_int_operand" "")))
20809 (clobber (reg:CC FLAGS_REG))])
20810 (match_scratch:SI 3 "r")]
20811 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20812 && satisfies_constraint_K (operands[2])"
20813 [(set (match_dup 3) (match_dup 2))
20814 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20815 (clobber (reg:CC FLAGS_REG))])]
20817 if (!rtx_equal_p (operands[0], operands[1]))
20818 emit_move_insn (operands[0], operands[1]);
20822 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20823 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20824 (match_operand:HI 2 "immediate_operand" "")))
20825 (clobber (reg:CC FLAGS_REG))])
20826 (match_scratch:HI 3 "r")]
20827 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20828 [(set (match_dup 3) (match_dup 2))
20829 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20830 (clobber (reg:CC FLAGS_REG))])]
20832 if (!rtx_equal_p (operands[0], operands[1]))
20833 emit_move_insn (operands[0], operands[1]);
20836 ;; After splitting up read-modify operations, array accesses with memory
20837 ;; operands might end up in form:
20839 ;; movl 4(%esp), %edx
20841 ;; instead of pre-splitting:
20843 ;; addl 4(%esp), %eax
20845 ;; movl 4(%esp), %edx
20846 ;; leal (%edx,%eax,4), %eax
20849 [(parallel [(set (match_operand 0 "register_operand" "")
20850 (ashift (match_operand 1 "register_operand" "")
20851 (match_operand 2 "const_int_operand" "")))
20852 (clobber (reg:CC FLAGS_REG))])
20853 (set (match_operand 3 "register_operand")
20854 (match_operand 4 "x86_64_general_operand" ""))
20855 (parallel [(set (match_operand 5 "register_operand" "")
20856 (plus (match_operand 6 "register_operand" "")
20857 (match_operand 7 "register_operand" "")))
20858 (clobber (reg:CC FLAGS_REG))])]
20859 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20860 /* Validate MODE for lea. */
20861 && ((!TARGET_PARTIAL_REG_STALL
20862 && (GET_MODE (operands[0]) == QImode
20863 || GET_MODE (operands[0]) == HImode))
20864 || GET_MODE (operands[0]) == SImode
20865 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20866 /* We reorder load and the shift. */
20867 && !rtx_equal_p (operands[1], operands[3])
20868 && !reg_overlap_mentioned_p (operands[0], operands[4])
20869 /* Last PLUS must consist of operand 0 and 3. */
20870 && !rtx_equal_p (operands[0], operands[3])
20871 && (rtx_equal_p (operands[3], operands[6])
20872 || rtx_equal_p (operands[3], operands[7]))
20873 && (rtx_equal_p (operands[0], operands[6])
20874 || rtx_equal_p (operands[0], operands[7]))
20875 /* The intermediate operand 0 must die or be same as output. */
20876 && (rtx_equal_p (operands[0], operands[5])
20877 || peep2_reg_dead_p (3, operands[0]))"
20878 [(set (match_dup 3) (match_dup 4))
20879 (set (match_dup 0) (match_dup 1))]
20881 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20882 int scale = 1 << INTVAL (operands[2]);
20883 rtx index = gen_lowpart (Pmode, operands[1]);
20884 rtx base = gen_lowpart (Pmode, operands[3]);
20885 rtx dest = gen_lowpart (mode, operands[5]);
20887 operands[1] = gen_rtx_PLUS (Pmode, base,
20888 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20890 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20891 operands[0] = dest;
20894 ;; Call-value patterns last so that the wildcard operand does not
20895 ;; disrupt insn-recog's switch tables.
20897 (define_insn "*call_value_pop_0"
20898 [(set (match_operand 0 "" "")
20899 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20900 (match_operand:SI 2 "" "")))
20901 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20902 (match_operand:SI 3 "immediate_operand" "")))]
20905 if (SIBLING_CALL_P (insn))
20908 return "call\t%P1";
20910 [(set_attr "type" "callv")])
20912 (define_insn "*call_value_pop_1"
20913 [(set (match_operand 0 "" "")
20914 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20915 (match_operand:SI 2 "" "")))
20916 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20917 (match_operand:SI 3 "immediate_operand" "i")))]
20920 if (constant_call_address_operand (operands[1], Pmode))
20922 if (SIBLING_CALL_P (insn))
20925 return "call\t%P1";
20927 if (SIBLING_CALL_P (insn))
20930 return "call\t%A1";
20932 [(set_attr "type" "callv")])
20934 (define_insn "*call_value_0"
20935 [(set (match_operand 0 "" "")
20936 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20937 (match_operand:SI 2 "" "")))]
20940 if (SIBLING_CALL_P (insn))
20943 return "call\t%P1";
20945 [(set_attr "type" "callv")])
20947 (define_insn "*call_value_0_rex64"
20948 [(set (match_operand 0 "" "")
20949 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20950 (match_operand:DI 2 "const_int_operand" "")))]
20953 if (SIBLING_CALL_P (insn))
20956 return "call\t%P1";
20958 [(set_attr "type" "callv")])
20960 (define_insn "*call_value_1"
20961 [(set (match_operand 0 "" "")
20962 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20963 (match_operand:SI 2 "" "")))]
20964 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20966 if (constant_call_address_operand (operands[1], Pmode))
20967 return "call\t%P1";
20968 return "call\t%A1";
20970 [(set_attr "type" "callv")])
20972 (define_insn "*sibcall_value_1"
20973 [(set (match_operand 0 "" "")
20974 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20975 (match_operand:SI 2 "" "")))]
20976 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20978 if (constant_call_address_operand (operands[1], Pmode))
20982 [(set_attr "type" "callv")])
20984 (define_insn "*call_value_1_rex64"
20985 [(set (match_operand 0 "" "")
20986 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20987 (match_operand:DI 2 "" "")))]
20988 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20989 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20991 if (constant_call_address_operand (operands[1], Pmode))
20992 return "call\t%P1";
20993 return "call\t%A1";
20995 [(set_attr "type" "callv")])
20997 (define_insn "*call_value_1_rex64_large"
20998 [(set (match_operand 0 "" "")
20999 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21000 (match_operand:DI 2 "" "")))]
21001 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21003 [(set_attr "type" "callv")])
21005 (define_insn "*sibcall_value_1_rex64"
21006 [(set (match_operand 0 "" "")
21007 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21008 (match_operand:DI 2 "" "")))]
21009 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21011 [(set_attr "type" "callv")])
21013 (define_insn "*sibcall_value_1_rex64_v"
21014 [(set (match_operand 0 "" "")
21015 (call (mem:QI (reg:DI R11_REG))
21016 (match_operand:DI 1 "" "")))]
21017 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21019 [(set_attr "type" "callv")])
21021 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21022 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21023 ;; caught for use by garbage collectors and the like. Using an insn that
21024 ;; maps to SIGILL makes it more likely the program will rightfully die.
21025 ;; Keeping with tradition, "6" is in honor of #UD.
21026 (define_insn "trap"
21027 [(trap_if (const_int 1) (const_int 6))]
21029 { return ASM_SHORT "0x0b0f"; }
21030 [(set_attr "length" "2")])
21032 (define_expand "sse_prologue_save"
21033 [(parallel [(set (match_operand:BLK 0 "" "")
21034 (unspec:BLK [(reg:DI 21)
21041 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21042 (use (match_operand:DI 1 "register_operand" ""))
21043 (use (match_operand:DI 2 "immediate_operand" ""))
21044 (use (label_ref:DI (match_operand 3 "" "")))])]
21048 (define_insn "*sse_prologue_save_insn"
21049 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21050 (match_operand:DI 4 "const_int_operand" "n")))
21051 (unspec:BLK [(reg:DI 21)
21058 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21059 (use (match_operand:DI 1 "register_operand" "r"))
21060 (use (match_operand:DI 2 "const_int_operand" "i"))
21061 (use (label_ref:DI (match_operand 3 "" "X")))]
21063 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21064 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21067 operands[0] = gen_rtx_MEM (Pmode,
21068 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21069 output_asm_insn ("jmp\t%A1", operands);
21070 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21072 operands[4] = adjust_address (operands[0], DImode, i*16);
21073 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21074 PUT_MODE (operands[4], TImode);
21075 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21076 output_asm_insn ("rex", operands);
21077 output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
21079 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21080 CODE_LABEL_NUMBER (operands[3]));
21083 [(set_attr "type" "other")
21084 (set_attr "length_immediate" "0")
21085 (set_attr "length_address" "0")
21086 (set_attr "length" "34")
21087 (set_attr "memory" "store")
21088 (set_attr "modrm" "0")
21089 (set_attr "mode" "DI")])
21091 (define_expand "prefetch"
21092 [(prefetch (match_operand 0 "address_operand" "")
21093 (match_operand:SI 1 "const_int_operand" "")
21094 (match_operand:SI 2 "const_int_operand" ""))]
21095 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21097 int rw = INTVAL (operands[1]);
21098 int locality = INTVAL (operands[2]);
21100 gcc_assert (rw == 0 || rw == 1);
21101 gcc_assert (locality >= 0 && locality <= 3);
21102 gcc_assert (GET_MODE (operands[0]) == Pmode
21103 || GET_MODE (operands[0]) == VOIDmode);
21105 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21106 supported by SSE counterpart or the SSE prefetch is not available
21107 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21109 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21110 operands[2] = GEN_INT (3);
21112 operands[1] = const0_rtx;
21115 (define_insn "*prefetch_sse"
21116 [(prefetch (match_operand:SI 0 "address_operand" "p")
21118 (match_operand:SI 1 "const_int_operand" ""))]
21119 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21121 static const char * const patterns[4] = {
21122 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21125 int locality = INTVAL (operands[1]);
21126 gcc_assert (locality >= 0 && locality <= 3);
21128 return patterns[locality];
21130 [(set_attr "type" "sse")
21131 (set_attr "memory" "none")])
21133 (define_insn "*prefetch_sse_rex"
21134 [(prefetch (match_operand:DI 0 "address_operand" "p")
21136 (match_operand:SI 1 "const_int_operand" ""))]
21137 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21139 static const char * const patterns[4] = {
21140 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21143 int locality = INTVAL (operands[1]);
21144 gcc_assert (locality >= 0 && locality <= 3);
21146 return patterns[locality];
21148 [(set_attr "type" "sse")
21149 (set_attr "memory" "none")])
21151 (define_insn "*prefetch_3dnow"
21152 [(prefetch (match_operand:SI 0 "address_operand" "p")
21153 (match_operand:SI 1 "const_int_operand" "n")
21155 "TARGET_3DNOW && !TARGET_64BIT"
21157 if (INTVAL (operands[1]) == 0)
21158 return "prefetch\t%a0";
21160 return "prefetchw\t%a0";
21162 [(set_attr "type" "mmx")
21163 (set_attr "memory" "none")])
21165 (define_insn "*prefetch_3dnow_rex"
21166 [(prefetch (match_operand:DI 0 "address_operand" "p")
21167 (match_operand:SI 1 "const_int_operand" "n")
21169 "TARGET_3DNOW && TARGET_64BIT"
21171 if (INTVAL (operands[1]) == 0)
21172 return "prefetch\t%a0";
21174 return "prefetchw\t%a0";
21176 [(set_attr "type" "mmx")
21177 (set_attr "memory" "none")])
21179 (define_expand "stack_protect_set"
21180 [(match_operand 0 "memory_operand" "")
21181 (match_operand 1 "memory_operand" "")]
21184 #ifdef TARGET_THREAD_SSP_OFFSET
21186 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21187 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21189 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21190 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21193 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21195 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21200 (define_insn "stack_protect_set_si"
21201 [(set (match_operand:SI 0 "memory_operand" "=m")
21202 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21203 (set (match_scratch:SI 2 "=&r") (const_int 0))
21204 (clobber (reg:CC FLAGS_REG))]
21206 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21207 [(set_attr "type" "multi")])
21209 (define_insn "stack_protect_set_di"
21210 [(set (match_operand:DI 0 "memory_operand" "=m")
21211 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21212 (set (match_scratch:DI 2 "=&r") (const_int 0))
21213 (clobber (reg:CC FLAGS_REG))]
21215 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21216 [(set_attr "type" "multi")])
21218 (define_insn "stack_tls_protect_set_si"
21219 [(set (match_operand:SI 0 "memory_operand" "=m")
21220 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21221 (set (match_scratch:SI 2 "=&r") (const_int 0))
21222 (clobber (reg:CC FLAGS_REG))]
21224 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21225 [(set_attr "type" "multi")])
21227 (define_insn "stack_tls_protect_set_di"
21228 [(set (match_operand:DI 0 "memory_operand" "=m")
21229 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21230 (set (match_scratch:DI 2 "=&r") (const_int 0))
21231 (clobber (reg:CC FLAGS_REG))]
21234 /* The kernel uses a different segment register for performance reasons; a
21235 system call would not have to trash the userspace segment register,
21236 which would be expensive */
21237 if (ix86_cmodel != CM_KERNEL)
21238 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21240 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21242 [(set_attr "type" "multi")])
21244 (define_expand "stack_protect_test"
21245 [(match_operand 0 "memory_operand" "")
21246 (match_operand 1 "memory_operand" "")
21247 (match_operand 2 "" "")]
21250 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21251 ix86_compare_op0 = operands[0];
21252 ix86_compare_op1 = operands[1];
21253 ix86_compare_emitted = flags;
21255 #ifdef TARGET_THREAD_SSP_OFFSET
21257 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21258 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21260 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21261 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21264 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21266 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21268 emit_jump_insn (gen_beq (operands[2]));
21272 (define_insn "stack_protect_test_si"
21273 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21274 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21275 (match_operand:SI 2 "memory_operand" "m")]
21277 (clobber (match_scratch:SI 3 "=&r"))]
21279 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21280 [(set_attr "type" "multi")])
21282 (define_insn "stack_protect_test_di"
21283 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21284 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21285 (match_operand:DI 2 "memory_operand" "m")]
21287 (clobber (match_scratch:DI 3 "=&r"))]
21289 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21290 [(set_attr "type" "multi")])
21292 (define_insn "stack_tls_protect_test_si"
21293 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21294 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21295 (match_operand:SI 2 "const_int_operand" "i")]
21296 UNSPEC_SP_TLS_TEST))
21297 (clobber (match_scratch:SI 3 "=r"))]
21299 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21300 [(set_attr "type" "multi")])
21302 (define_insn "stack_tls_protect_test_di"
21303 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21304 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21305 (match_operand:DI 2 "const_int_operand" "i")]
21306 UNSPEC_SP_TLS_TEST))
21307 (clobber (match_scratch:DI 3 "=r"))]
21310 /* The kernel uses a different segment register for performance reasons; a
21311 system call would not have to trash the userspace segment register,
21312 which would be expensive */
21313 if (ix86_cmodel != CM_KERNEL)
21314 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21316 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21318 [(set_attr "type" "multi")])
21320 (define_mode_iterator CRC32MODE [QI HI SI])
21321 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21322 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21324 (define_insn "sse4_2_crc32<mode>"
21325 [(set (match_operand:SI 0 "register_operand" "=r")
21327 [(match_operand:SI 1 "register_operand" "0")
21328 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21331 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21332 [(set_attr "type" "sselog1")
21333 (set_attr "prefix_rep" "1")
21334 (set_attr "prefix_extra" "1")
21335 (set_attr "mode" "SI")])
21337 (define_insn "sse4_2_crc32di"
21338 [(set (match_operand:DI 0 "register_operand" "=r")
21340 [(match_operand:DI 1 "register_operand" "0")
21341 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21343 "TARGET_SSE4_2 && TARGET_64BIT"
21344 "crc32q\t{%2, %0|%0, %2}"
21345 [(set_attr "type" "sselog1")
21346 (set_attr "prefix_rep" "1")
21347 (set_attr "prefix_extra" "1")
21348 (set_attr "mode" "DI")])
21352 (include "sync.md")