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)
184 (UNSPEC_SSE5_ASHIFT 154)
185 (UNSPEC_SSE5_LSHIFT 155)
187 (UNSPEC_CVTPH2PS 157)
188 (UNSPEC_CVTPS2PH 158)
192 [(UNSPECV_BLOCKAGE 0)
193 (UNSPECV_STACK_PROBE 1)
202 (UNSPECV_CMPXCHG_1 10)
203 (UNSPECV_CMPXCHG_2 11)
206 (UNSPECV_PROLOGUE_USE 14)
209 ;; Constants to represent pcomtrue/pcomfalse variants
219 ;; Registers by name.
235 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
238 ;; In C guard expressions, put expressions which may be compile-time
239 ;; constants first. This allows for better optimization. For
240 ;; example, write "TARGET_64BIT && reload_completed", not
241 ;; "reload_completed && TARGET_64BIT".
244 ;; Processor type. This attribute must exactly match the processor_type
245 ;; enumeration in i386.h.
246 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
247 nocona,core2,generic32,generic64,amdfam10"
248 (const (symbol_ref "ix86_tune")))
250 ;; A basic instruction type. Refinements due to arguments to be
251 ;; provided in other attributes.
254 alu,alu1,negnot,imov,imovx,lea,
255 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
256 icmp,test,ibr,setcc,icmov,
257 push,pop,call,callv,leave,
259 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
260 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
261 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
263 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
264 (const_string "other"))
266 ;; Main data type used by the insn
268 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
269 (const_string "unknown"))
271 ;; The CPU unit operations uses.
272 (define_attr "unit" "integer,i387,sse,mmx,unknown"
273 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
274 (const_string "i387")
275 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
276 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
277 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
279 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
281 (eq_attr "type" "other")
282 (const_string "unknown")]
283 (const_string "integer")))
285 ;; The (bounding maximum) length of an instruction immediate.
286 (define_attr "length_immediate" ""
287 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
290 (eq_attr "unit" "i387,sse,mmx")
292 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
294 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
295 (eq_attr "type" "imov,test")
296 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
297 (eq_attr "type" "call")
298 (if_then_else (match_operand 0 "constant_call_address_operand" "")
301 (eq_attr "type" "callv")
302 (if_then_else (match_operand 1 "constant_call_address_operand" "")
305 ;; We don't know the size before shorten_branches. Expect
306 ;; the instruction to fit for better scheduling.
307 (eq_attr "type" "ibr")
310 (symbol_ref "/* Update immediate_length and other attributes! */
311 gcc_unreachable (),1")))
313 ;; The (bounding maximum) length of an instruction address.
314 (define_attr "length_address" ""
315 (cond [(eq_attr "type" "str,other,multi,fxch")
317 (and (eq_attr "type" "call")
318 (match_operand 0 "constant_call_address_operand" ""))
320 (and (eq_attr "type" "callv")
321 (match_operand 1 "constant_call_address_operand" ""))
324 (symbol_ref "ix86_attr_length_address_default (insn)")))
326 ;; Set when length prefix is used.
327 (define_attr "prefix_data16" ""
328 (if_then_else (ior (eq_attr "mode" "HI")
329 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
333 ;; Set when string REP prefix is used.
334 (define_attr "prefix_rep" ""
335 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
339 ;; Set when 0f opcode prefix is used.
340 (define_attr "prefix_0f" ""
342 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
343 (eq_attr "unit" "sse,mmx"))
347 ;; Set when REX opcode prefix is used.
348 (define_attr "prefix_rex" ""
349 (cond [(and (eq_attr "mode" "DI")
350 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
352 (and (eq_attr "mode" "QI")
353 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
356 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
362 ;; There are also additional prefixes in SSSE3.
363 (define_attr "prefix_extra" "" (const_int 0))
365 ;; Set when modrm byte is used.
366 (define_attr "modrm" ""
367 (cond [(eq_attr "type" "str,leave")
369 (eq_attr "unit" "i387")
371 (and (eq_attr "type" "incdec")
372 (ior (match_operand:SI 1 "register_operand" "")
373 (match_operand:HI 1 "register_operand" "")))
375 (and (eq_attr "type" "push")
376 (not (match_operand 1 "memory_operand" "")))
378 (and (eq_attr "type" "pop")
379 (not (match_operand 0 "memory_operand" "")))
381 (and (eq_attr "type" "imov")
382 (ior (and (match_operand 0 "register_operand" "")
383 (match_operand 1 "immediate_operand" ""))
384 (ior (and (match_operand 0 "ax_reg_operand" "")
385 (match_operand 1 "memory_displacement_only_operand" ""))
386 (and (match_operand 0 "memory_displacement_only_operand" "")
387 (match_operand 1 "ax_reg_operand" "")))))
389 (and (eq_attr "type" "call")
390 (match_operand 0 "constant_call_address_operand" ""))
392 (and (eq_attr "type" "callv")
393 (match_operand 1 "constant_call_address_operand" ""))
398 ;; The (bounding maximum) length of an instruction in bytes.
399 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
400 ;; Later we may want to split them and compute proper length as for
402 (define_attr "length" ""
403 (cond [(eq_attr "type" "other,multi,fistp,frndint")
405 (eq_attr "type" "fcmp")
407 (eq_attr "unit" "i387")
409 (plus (attr "prefix_data16")
410 (attr "length_address")))]
411 (plus (plus (attr "modrm")
412 (plus (attr "prefix_0f")
413 (plus (attr "prefix_rex")
414 (plus (attr "prefix_extra")
416 (plus (attr "prefix_rep")
417 (plus (attr "prefix_data16")
418 (plus (attr "length_immediate")
419 (attr "length_address")))))))
421 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
422 ;; `store' if there is a simple memory reference therein, or `unknown'
423 ;; if the instruction is complex.
425 (define_attr "memory" "none,load,store,both,unknown"
426 (cond [(eq_attr "type" "other,multi,str")
427 (const_string "unknown")
428 (eq_attr "type" "lea,fcmov,fpspc")
429 (const_string "none")
430 (eq_attr "type" "fistp,leave")
431 (const_string "both")
432 (eq_attr "type" "frndint")
433 (const_string "load")
434 (eq_attr "type" "push")
435 (if_then_else (match_operand 1 "memory_operand" "")
436 (const_string "both")
437 (const_string "store"))
438 (eq_attr "type" "pop")
439 (if_then_else (match_operand 0 "memory_operand" "")
440 (const_string "both")
441 (const_string "load"))
442 (eq_attr "type" "setcc")
443 (if_then_else (match_operand 0 "memory_operand" "")
444 (const_string "store")
445 (const_string "none"))
446 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
447 (if_then_else (ior (match_operand 0 "memory_operand" "")
448 (match_operand 1 "memory_operand" ""))
449 (const_string "load")
450 (const_string "none"))
451 (eq_attr "type" "ibr")
452 (if_then_else (match_operand 0 "memory_operand" "")
453 (const_string "load")
454 (const_string "none"))
455 (eq_attr "type" "call")
456 (if_then_else (match_operand 0 "constant_call_address_operand" "")
457 (const_string "none")
458 (const_string "load"))
459 (eq_attr "type" "callv")
460 (if_then_else (match_operand 1 "constant_call_address_operand" "")
461 (const_string "none")
462 (const_string "load"))
463 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
464 (match_operand 1 "memory_operand" ""))
465 (const_string "both")
466 (and (match_operand 0 "memory_operand" "")
467 (match_operand 1 "memory_operand" ""))
468 (const_string "both")
469 (match_operand 0 "memory_operand" "")
470 (const_string "store")
471 (match_operand 1 "memory_operand" "")
472 (const_string "load")
474 "!alu1,negnot,ishift1,
475 imov,imovx,icmp,test,bitmanip,
477 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
478 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
479 (match_operand 2 "memory_operand" ""))
480 (const_string "load")
481 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
482 (match_operand 3 "memory_operand" ""))
483 (const_string "load")
485 (const_string "none")))
487 ;; Indicates if an instruction has both an immediate and a displacement.
489 (define_attr "imm_disp" "false,true,unknown"
490 (cond [(eq_attr "type" "other,multi")
491 (const_string "unknown")
492 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
493 (and (match_operand 0 "memory_displacement_operand" "")
494 (match_operand 1 "immediate_operand" "")))
495 (const_string "true")
496 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
497 (and (match_operand 0 "memory_displacement_operand" "")
498 (match_operand 2 "immediate_operand" "")))
499 (const_string "true")
501 (const_string "false")))
503 ;; Indicates if an FP operation has an integer source.
505 (define_attr "fp_int_src" "false,true"
506 (const_string "false"))
508 ;; Defines rounding mode of an FP operation.
510 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
511 (const_string "any"))
513 ;; Describe a user's asm statement.
514 (define_asm_attributes
515 [(set_attr "length" "128")
516 (set_attr "type" "multi")])
518 (define_code_iterator plusminus [plus minus])
520 ;; Base name for define_insn and insn mnemonic.
521 (define_code_attr addsub [(plus "add") (minus "sub")])
523 ;; Mark commutative operators as such in constraints.
524 (define_code_attr comm [(plus "%") (minus "")])
526 ;; All single word integer modes.
527 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
529 ;; Instruction suffix for integer modes.
530 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
532 ;; Register class for integer modes.
533 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
535 ;; Immediate operand constraint for integer modes.
536 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
538 ;; General operand predicate for integer modes.
539 (define_mode_attr general_operand
540 [(QI "general_operand")
541 (HI "general_operand")
542 (SI "general_operand")
543 (DI "x86_64_general_operand")])
545 ;; SSE and x87 SFmode and DFmode floating point modes
546 (define_mode_iterator MODEF [SF DF])
548 ;; All x87 floating point modes
549 (define_mode_iterator X87MODEF [SF DF XF])
551 ;; All integer modes handled by x87 fisttp operator.
552 (define_mode_iterator X87MODEI [HI SI DI])
554 ;; All integer modes handled by integer x87 operators.
555 (define_mode_iterator X87MODEI12 [HI SI])
557 ;; All integer modes handled by SSE cvtts?2si* operators.
558 (define_mode_iterator SSEMODEI24 [SI DI])
560 ;; SSE asm suffix for floating point modes
561 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
563 ;; SSE vector mode corresponding to a scalar mode
564 (define_mode_attr ssevecmode
565 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
567 ;; Scheduling descriptions
569 (include "pentium.md")
572 (include "athlon.md")
576 ;; Operand and operator predicates and constraints
578 (include "predicates.md")
579 (include "constraints.md")
582 ;; Compare instructions.
584 ;; All compare insns have expanders that save the operands away without
585 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
586 ;; after the cmp) will actually emit the cmpM.
588 (define_expand "cmpti"
589 [(set (reg:CC FLAGS_REG)
590 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
591 (match_operand:TI 1 "x86_64_general_operand" "")))]
594 if (MEM_P (operands[0]) && MEM_P (operands[1]))
595 operands[0] = force_reg (TImode, operands[0]);
596 ix86_compare_op0 = operands[0];
597 ix86_compare_op1 = operands[1];
601 (define_expand "cmpdi"
602 [(set (reg:CC FLAGS_REG)
603 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
604 (match_operand:DI 1 "x86_64_general_operand" "")))]
607 if (MEM_P (operands[0]) && MEM_P (operands[1]))
608 operands[0] = force_reg (DImode, operands[0]);
609 ix86_compare_op0 = operands[0];
610 ix86_compare_op1 = operands[1];
614 (define_expand "cmpsi"
615 [(set (reg:CC FLAGS_REG)
616 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
617 (match_operand:SI 1 "general_operand" "")))]
620 if (MEM_P (operands[0]) && MEM_P (operands[1]))
621 operands[0] = force_reg (SImode, operands[0]);
622 ix86_compare_op0 = operands[0];
623 ix86_compare_op1 = operands[1];
627 (define_expand "cmphi"
628 [(set (reg:CC FLAGS_REG)
629 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
630 (match_operand:HI 1 "general_operand" "")))]
633 if (MEM_P (operands[0]) && MEM_P (operands[1]))
634 operands[0] = force_reg (HImode, operands[0]);
635 ix86_compare_op0 = operands[0];
636 ix86_compare_op1 = operands[1];
640 (define_expand "cmpqi"
641 [(set (reg:CC FLAGS_REG)
642 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
643 (match_operand:QI 1 "general_operand" "")))]
646 if (MEM_P (operands[0]) && MEM_P (operands[1]))
647 operands[0] = force_reg (QImode, operands[0]);
648 ix86_compare_op0 = operands[0];
649 ix86_compare_op1 = operands[1];
653 (define_insn "cmpdi_ccno_1_rex64"
654 [(set (reg FLAGS_REG)
655 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
656 (match_operand:DI 1 "const0_operand" "n,n")))]
657 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
660 cmp{q}\t{%1, %0|%0, %1}"
661 [(set_attr "type" "test,icmp")
662 (set_attr "length_immediate" "0,1")
663 (set_attr "mode" "DI")])
665 (define_insn "*cmpdi_minus_1_rex64"
666 [(set (reg FLAGS_REG)
667 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
668 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
670 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
671 "cmp{q}\t{%1, %0|%0, %1}"
672 [(set_attr "type" "icmp")
673 (set_attr "mode" "DI")])
675 (define_expand "cmpdi_1_rex64"
676 [(set (reg:CC FLAGS_REG)
677 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
678 (match_operand:DI 1 "general_operand" "")))]
682 (define_insn "cmpdi_1_insn_rex64"
683 [(set (reg FLAGS_REG)
684 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
685 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
686 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
687 "cmp{q}\t{%1, %0|%0, %1}"
688 [(set_attr "type" "icmp")
689 (set_attr "mode" "DI")])
692 (define_insn "*cmpsi_ccno_1"
693 [(set (reg FLAGS_REG)
694 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
695 (match_operand:SI 1 "const0_operand" "n,n")))]
696 "ix86_match_ccmode (insn, CCNOmode)"
699 cmp{l}\t{%1, %0|%0, %1}"
700 [(set_attr "type" "test,icmp")
701 (set_attr "length_immediate" "0,1")
702 (set_attr "mode" "SI")])
704 (define_insn "*cmpsi_minus_1"
705 [(set (reg FLAGS_REG)
706 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
707 (match_operand:SI 1 "general_operand" "ri,mr"))
709 "ix86_match_ccmode (insn, CCGOCmode)"
710 "cmp{l}\t{%1, %0|%0, %1}"
711 [(set_attr "type" "icmp")
712 (set_attr "mode" "SI")])
714 (define_expand "cmpsi_1"
715 [(set (reg:CC FLAGS_REG)
716 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
717 (match_operand:SI 1 "general_operand" "")))]
721 (define_insn "*cmpsi_1_insn"
722 [(set (reg FLAGS_REG)
723 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
724 (match_operand:SI 1 "general_operand" "ri,mr")))]
725 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
726 && ix86_match_ccmode (insn, CCmode)"
727 "cmp{l}\t{%1, %0|%0, %1}"
728 [(set_attr "type" "icmp")
729 (set_attr "mode" "SI")])
731 (define_insn "*cmphi_ccno_1"
732 [(set (reg FLAGS_REG)
733 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
734 (match_operand:HI 1 "const0_operand" "n,n")))]
735 "ix86_match_ccmode (insn, CCNOmode)"
738 cmp{w}\t{%1, %0|%0, %1}"
739 [(set_attr "type" "test,icmp")
740 (set_attr "length_immediate" "0,1")
741 (set_attr "mode" "HI")])
743 (define_insn "*cmphi_minus_1"
744 [(set (reg FLAGS_REG)
745 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
746 (match_operand:HI 1 "general_operand" "ri,mr"))
748 "ix86_match_ccmode (insn, CCGOCmode)"
749 "cmp{w}\t{%1, %0|%0, %1}"
750 [(set_attr "type" "icmp")
751 (set_attr "mode" "HI")])
753 (define_insn "*cmphi_1"
754 [(set (reg FLAGS_REG)
755 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
756 (match_operand:HI 1 "general_operand" "ri,mr")))]
757 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
758 && ix86_match_ccmode (insn, CCmode)"
759 "cmp{w}\t{%1, %0|%0, %1}"
760 [(set_attr "type" "icmp")
761 (set_attr "mode" "HI")])
763 (define_insn "*cmpqi_ccno_1"
764 [(set (reg FLAGS_REG)
765 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
766 (match_operand:QI 1 "const0_operand" "n,n")))]
767 "ix86_match_ccmode (insn, CCNOmode)"
770 cmp{b}\t{$0, %0|%0, 0}"
771 [(set_attr "type" "test,icmp")
772 (set_attr "length_immediate" "0,1")
773 (set_attr "mode" "QI")])
775 (define_insn "*cmpqi_1"
776 [(set (reg FLAGS_REG)
777 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
778 (match_operand:QI 1 "general_operand" "qi,mq")))]
779 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
780 && ix86_match_ccmode (insn, CCmode)"
781 "cmp{b}\t{%1, %0|%0, %1}"
782 [(set_attr "type" "icmp")
783 (set_attr "mode" "QI")])
785 (define_insn "*cmpqi_minus_1"
786 [(set (reg FLAGS_REG)
787 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
788 (match_operand:QI 1 "general_operand" "qi,mq"))
790 "ix86_match_ccmode (insn, CCGOCmode)"
791 "cmp{b}\t{%1, %0|%0, %1}"
792 [(set_attr "type" "icmp")
793 (set_attr "mode" "QI")])
795 (define_insn "*cmpqi_ext_1"
796 [(set (reg FLAGS_REG)
798 (match_operand:QI 0 "general_operand" "Qm")
801 (match_operand 1 "ext_register_operand" "Q")
804 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
805 "cmp{b}\t{%h1, %0|%0, %h1}"
806 [(set_attr "type" "icmp")
807 (set_attr "mode" "QI")])
809 (define_insn "*cmpqi_ext_1_rex64"
810 [(set (reg FLAGS_REG)
812 (match_operand:QI 0 "register_operand" "Q")
815 (match_operand 1 "ext_register_operand" "Q")
818 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
819 "cmp{b}\t{%h1, %0|%0, %h1}"
820 [(set_attr "type" "icmp")
821 (set_attr "mode" "QI")])
823 (define_insn "*cmpqi_ext_2"
824 [(set (reg FLAGS_REG)
828 (match_operand 0 "ext_register_operand" "Q")
831 (match_operand:QI 1 "const0_operand" "n")))]
832 "ix86_match_ccmode (insn, CCNOmode)"
834 [(set_attr "type" "test")
835 (set_attr "length_immediate" "0")
836 (set_attr "mode" "QI")])
838 (define_expand "cmpqi_ext_3"
839 [(set (reg:CC FLAGS_REG)
843 (match_operand 0 "ext_register_operand" "")
846 (match_operand:QI 1 "general_operand" "")))]
850 (define_insn "cmpqi_ext_3_insn"
851 [(set (reg FLAGS_REG)
855 (match_operand 0 "ext_register_operand" "Q")
858 (match_operand:QI 1 "general_operand" "Qmn")))]
859 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
860 "cmp{b}\t{%1, %h0|%h0, %1}"
861 [(set_attr "type" "icmp")
862 (set_attr "mode" "QI")])
864 (define_insn "cmpqi_ext_3_insn_rex64"
865 [(set (reg FLAGS_REG)
869 (match_operand 0 "ext_register_operand" "Q")
872 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
873 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
874 "cmp{b}\t{%1, %h0|%h0, %1}"
875 [(set_attr "type" "icmp")
876 (set_attr "mode" "QI")])
878 (define_insn "*cmpqi_ext_4"
879 [(set (reg FLAGS_REG)
883 (match_operand 0 "ext_register_operand" "Q")
888 (match_operand 1 "ext_register_operand" "Q")
891 "ix86_match_ccmode (insn, CCmode)"
892 "cmp{b}\t{%h1, %h0|%h0, %h1}"
893 [(set_attr "type" "icmp")
894 (set_attr "mode" "QI")])
896 ;; These implement float point compares.
897 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
898 ;; which would allow mix and match FP modes on the compares. Which is what
899 ;; the old patterns did, but with many more of them.
901 (define_expand "cmpxf"
902 [(set (reg:CC FLAGS_REG)
903 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
904 (match_operand:XF 1 "nonmemory_operand" "")))]
907 ix86_compare_op0 = operands[0];
908 ix86_compare_op1 = operands[1];
912 (define_expand "cmp<mode>"
913 [(set (reg:CC FLAGS_REG)
914 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
915 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
916 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
918 ix86_compare_op0 = operands[0];
919 ix86_compare_op1 = operands[1];
923 ;; FP compares, step 1:
924 ;; Set the FP condition codes.
926 ;; CCFPmode compare with exceptions
927 ;; CCFPUmode compare with no exceptions
929 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
930 ;; used to manage the reg stack popping would not be preserved.
932 (define_insn "*cmpfp_0"
933 [(set (match_operand:HI 0 "register_operand" "=a")
936 (match_operand 1 "register_operand" "f")
937 (match_operand 2 "const0_operand" "X"))]
939 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
940 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
941 "* return output_fp_compare (insn, operands, 0, 0);"
942 [(set_attr "type" "multi")
943 (set_attr "unit" "i387")
945 (cond [(match_operand:SF 1 "" "")
947 (match_operand:DF 1 "" "")
950 (const_string "XF")))])
952 (define_insn_and_split "*cmpfp_0_cc"
953 [(set (reg:CCFP FLAGS_REG)
955 (match_operand 1 "register_operand" "f")
956 (match_operand 2 "const0_operand" "X")))
957 (clobber (match_operand:HI 0 "register_operand" "=a"))]
958 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
959 && TARGET_SAHF && !TARGET_CMOVE
960 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
962 "&& reload_completed"
965 [(compare:CCFP (match_dup 1)(match_dup 2))]
967 (set (reg:CC FLAGS_REG)
968 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
970 [(set_attr "type" "multi")
971 (set_attr "unit" "i387")
973 (cond [(match_operand:SF 1 "" "")
975 (match_operand:DF 1 "" "")
978 (const_string "XF")))])
980 (define_insn "*cmpfp_xf"
981 [(set (match_operand:HI 0 "register_operand" "=a")
984 (match_operand:XF 1 "register_operand" "f")
985 (match_operand:XF 2 "register_operand" "f"))]
988 "* return output_fp_compare (insn, operands, 0, 0);"
989 [(set_attr "type" "multi")
990 (set_attr "unit" "i387")
991 (set_attr "mode" "XF")])
993 (define_insn_and_split "*cmpfp_xf_cc"
994 [(set (reg:CCFP FLAGS_REG)
996 (match_operand:XF 1 "register_operand" "f")
997 (match_operand:XF 2 "register_operand" "f")))
998 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1000 && TARGET_SAHF && !TARGET_CMOVE"
1002 "&& reload_completed"
1005 [(compare:CCFP (match_dup 1)(match_dup 2))]
1007 (set (reg:CC FLAGS_REG)
1008 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1010 [(set_attr "type" "multi")
1011 (set_attr "unit" "i387")
1012 (set_attr "mode" "XF")])
1014 (define_insn "*cmpfp_<mode>"
1015 [(set (match_operand:HI 0 "register_operand" "=a")
1018 (match_operand:MODEF 1 "register_operand" "f")
1019 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1022 "* return output_fp_compare (insn, operands, 0, 0);"
1023 [(set_attr "type" "multi")
1024 (set_attr "unit" "i387")
1025 (set_attr "mode" "<MODE>")])
1027 (define_insn_and_split "*cmpfp_<mode>_cc"
1028 [(set (reg:CCFP FLAGS_REG)
1030 (match_operand:MODEF 1 "register_operand" "f")
1031 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1032 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1034 && TARGET_SAHF && !TARGET_CMOVE"
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")
1046 (set_attr "mode" "<MODE>")])
1048 (define_insn "*cmpfp_u"
1049 [(set (match_operand:HI 0 "register_operand" "=a")
1052 (match_operand 1 "register_operand" "f")
1053 (match_operand 2 "register_operand" "f"))]
1055 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1056 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1057 "* return output_fp_compare (insn, operands, 0, 1);"
1058 [(set_attr "type" "multi")
1059 (set_attr "unit" "i387")
1061 (cond [(match_operand:SF 1 "" "")
1063 (match_operand:DF 1 "" "")
1066 (const_string "XF")))])
1068 (define_insn_and_split "*cmpfp_u_cc"
1069 [(set (reg:CCFPU FLAGS_REG)
1071 (match_operand 1 "register_operand" "f")
1072 (match_operand 2 "register_operand" "f")))
1073 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1074 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1075 && TARGET_SAHF && !TARGET_CMOVE
1076 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1078 "&& reload_completed"
1081 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1083 (set (reg:CC FLAGS_REG)
1084 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1086 [(set_attr "type" "multi")
1087 (set_attr "unit" "i387")
1089 (cond [(match_operand:SF 1 "" "")
1091 (match_operand:DF 1 "" "")
1094 (const_string "XF")))])
1096 (define_insn "*cmpfp_<mode>"
1097 [(set (match_operand:HI 0 "register_operand" "=a")
1100 (match_operand 1 "register_operand" "f")
1101 (match_operator 3 "float_operator"
1102 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1104 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1105 && TARGET_USE_<MODE>MODE_FIOP
1106 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1107 "* return output_fp_compare (insn, operands, 0, 0);"
1108 [(set_attr "type" "multi")
1109 (set_attr "unit" "i387")
1110 (set_attr "fp_int_src" "true")
1111 (set_attr "mode" "<MODE>")])
1113 (define_insn_and_split "*cmpfp_<mode>_cc"
1114 [(set (reg:CCFP FLAGS_REG)
1116 (match_operand 1 "register_operand" "f")
1117 (match_operator 3 "float_operator"
1118 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1119 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1120 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1121 && TARGET_SAHF && !TARGET_CMOVE
1122 && TARGET_USE_<MODE>MODE_FIOP
1123 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1125 "&& reload_completed"
1130 (match_op_dup 3 [(match_dup 2)]))]
1132 (set (reg:CC FLAGS_REG)
1133 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1135 [(set_attr "type" "multi")
1136 (set_attr "unit" "i387")
1137 (set_attr "fp_int_src" "true")
1138 (set_attr "mode" "<MODE>")])
1140 ;; FP compares, step 2
1141 ;; Move the fpsw to ax.
1143 (define_insn "x86_fnstsw_1"
1144 [(set (match_operand:HI 0 "register_operand" "=a")
1145 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1148 [(set_attr "length" "2")
1149 (set_attr "mode" "SI")
1150 (set_attr "unit" "i387")])
1152 ;; FP compares, step 3
1153 ;; Get ax into flags, general case.
1155 (define_insn "x86_sahf_1"
1156 [(set (reg:CC FLAGS_REG)
1157 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1161 #ifdef HAVE_AS_IX86_SAHF
1164 return ".byte\t0x9e";
1167 [(set_attr "length" "1")
1168 (set_attr "athlon_decode" "vector")
1169 (set_attr "amdfam10_decode" "direct")
1170 (set_attr "mode" "SI")])
1172 ;; Pentium Pro can do steps 1 through 3 in one go.
1173 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1174 (define_insn "*cmpfp_i_mixed"
1175 [(set (reg:CCFP FLAGS_REG)
1176 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1177 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1178 "TARGET_MIX_SSE_I387
1179 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1180 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1181 "* return output_fp_compare (insn, operands, 1, 0);"
1182 [(set_attr "type" "fcmp,ssecomi")
1184 (if_then_else (match_operand:SF 1 "" "")
1186 (const_string "DF")))
1187 (set_attr "athlon_decode" "vector")
1188 (set_attr "amdfam10_decode" "direct")])
1190 (define_insn "*cmpfp_i_sse"
1191 [(set (reg:CCFP FLAGS_REG)
1192 (compare:CCFP (match_operand 0 "register_operand" "x")
1193 (match_operand 1 "nonimmediate_operand" "xm")))]
1195 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1196 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1197 "* return output_fp_compare (insn, operands, 1, 0);"
1198 [(set_attr "type" "ssecomi")
1200 (if_then_else (match_operand:SF 1 "" "")
1202 (const_string "DF")))
1203 (set_attr "athlon_decode" "vector")
1204 (set_attr "amdfam10_decode" "direct")])
1206 (define_insn "*cmpfp_i_i387"
1207 [(set (reg:CCFP FLAGS_REG)
1208 (compare:CCFP (match_operand 0 "register_operand" "f")
1209 (match_operand 1 "register_operand" "f")))]
1210 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1212 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1213 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1214 "* return output_fp_compare (insn, operands, 1, 0);"
1215 [(set_attr "type" "fcmp")
1217 (cond [(match_operand:SF 1 "" "")
1219 (match_operand:DF 1 "" "")
1222 (const_string "XF")))
1223 (set_attr "athlon_decode" "vector")
1224 (set_attr "amdfam10_decode" "direct")])
1226 (define_insn "*cmpfp_iu_mixed"
1227 [(set (reg:CCFPU FLAGS_REG)
1228 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1229 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1230 "TARGET_MIX_SSE_I387
1231 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1232 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1233 "* return output_fp_compare (insn, operands, 1, 1);"
1234 [(set_attr "type" "fcmp,ssecomi")
1236 (if_then_else (match_operand:SF 1 "" "")
1238 (const_string "DF")))
1239 (set_attr "athlon_decode" "vector")
1240 (set_attr "amdfam10_decode" "direct")])
1242 (define_insn "*cmpfp_iu_sse"
1243 [(set (reg:CCFPU FLAGS_REG)
1244 (compare:CCFPU (match_operand 0 "register_operand" "x")
1245 (match_operand 1 "nonimmediate_operand" "xm")))]
1247 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1248 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1249 "* return output_fp_compare (insn, operands, 1, 1);"
1250 [(set_attr "type" "ssecomi")
1252 (if_then_else (match_operand:SF 1 "" "")
1254 (const_string "DF")))
1255 (set_attr "athlon_decode" "vector")
1256 (set_attr "amdfam10_decode" "direct")])
1258 (define_insn "*cmpfp_iu_387"
1259 [(set (reg:CCFPU FLAGS_REG)
1260 (compare:CCFPU (match_operand 0 "register_operand" "f")
1261 (match_operand 1 "register_operand" "f")))]
1262 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1264 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1265 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1266 "* return output_fp_compare (insn, operands, 1, 1);"
1267 [(set_attr "type" "fcmp")
1269 (cond [(match_operand:SF 1 "" "")
1271 (match_operand:DF 1 "" "")
1274 (const_string "XF")))
1275 (set_attr "athlon_decode" "vector")
1276 (set_attr "amdfam10_decode" "direct")])
1278 ;; Move instructions.
1280 ;; General case of fullword move.
1282 (define_expand "movsi"
1283 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1284 (match_operand:SI 1 "general_operand" ""))]
1286 "ix86_expand_move (SImode, operands); DONE;")
1288 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1291 ;; %%% We don't use a post-inc memory reference because x86 is not a
1292 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1293 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1294 ;; targets without our curiosities, and it is just as easy to represent
1295 ;; this differently.
1297 (define_insn "*pushsi2"
1298 [(set (match_operand:SI 0 "push_operand" "=<")
1299 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1302 [(set_attr "type" "push")
1303 (set_attr "mode" "SI")])
1305 ;; For 64BIT abi we always round up to 8 bytes.
1306 (define_insn "*pushsi2_rex64"
1307 [(set (match_operand:SI 0 "push_operand" "=X")
1308 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1311 [(set_attr "type" "push")
1312 (set_attr "mode" "SI")])
1314 (define_insn "*pushsi2_prologue"
1315 [(set (match_operand:SI 0 "push_operand" "=<")
1316 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1317 (clobber (mem:BLK (scratch)))]
1320 [(set_attr "type" "push")
1321 (set_attr "mode" "SI")])
1323 (define_insn "*popsi1_epilogue"
1324 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1325 (mem:SI (reg:SI SP_REG)))
1326 (set (reg:SI SP_REG)
1327 (plus:SI (reg:SI SP_REG) (const_int 4)))
1328 (clobber (mem:BLK (scratch)))]
1331 [(set_attr "type" "pop")
1332 (set_attr "mode" "SI")])
1334 (define_insn "popsi1"
1335 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1336 (mem:SI (reg:SI SP_REG)))
1337 (set (reg:SI SP_REG)
1338 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1341 [(set_attr "type" "pop")
1342 (set_attr "mode" "SI")])
1344 (define_insn "*movsi_xor"
1345 [(set (match_operand:SI 0 "register_operand" "=r")
1346 (match_operand:SI 1 "const0_operand" "i"))
1347 (clobber (reg:CC FLAGS_REG))]
1348 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1350 [(set_attr "type" "alu1")
1351 (set_attr "mode" "SI")
1352 (set_attr "length_immediate" "0")])
1354 (define_insn "*movsi_or"
1355 [(set (match_operand:SI 0 "register_operand" "=r")
1356 (match_operand:SI 1 "immediate_operand" "i"))
1357 (clobber (reg:CC FLAGS_REG))]
1359 && operands[1] == constm1_rtx
1360 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1362 operands[1] = constm1_rtx;
1363 return "or{l}\t{%1, %0|%0, %1}";
1365 [(set_attr "type" "alu1")
1366 (set_attr "mode" "SI")
1367 (set_attr "length_immediate" "1")])
1369 (define_insn "*movsi_1"
1370 [(set (match_operand:SI 0 "nonimmediate_operand"
1371 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1372 (match_operand:SI 1 "general_operand"
1373 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1374 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1376 switch (get_attr_type (insn))
1379 if (get_attr_mode (insn) == MODE_TI)
1380 return "pxor\t%0, %0";
1381 return "xorps\t%0, %0";
1384 switch (get_attr_mode (insn))
1387 return "movdqa\t{%1, %0|%0, %1}";
1389 return "movaps\t{%1, %0|%0, %1}";
1391 return "movd\t{%1, %0|%0, %1}";
1393 return "movss\t{%1, %0|%0, %1}";
1399 return "pxor\t%0, %0";
1402 if (get_attr_mode (insn) == MODE_DI)
1403 return "movq\t{%1, %0|%0, %1}";
1404 return "movd\t{%1, %0|%0, %1}";
1407 return "lea{l}\t{%1, %0|%0, %1}";
1410 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1411 return "mov{l}\t{%1, %0|%0, %1}";
1415 (cond [(eq_attr "alternative" "2")
1416 (const_string "mmxadd")
1417 (eq_attr "alternative" "3,4,5")
1418 (const_string "mmxmov")
1419 (eq_attr "alternative" "6")
1420 (const_string "sselog1")
1421 (eq_attr "alternative" "7,8,9,10,11")
1422 (const_string "ssemov")
1423 (match_operand:DI 1 "pic_32bit_operand" "")
1424 (const_string "lea")
1426 (const_string "imov")))
1428 (cond [(eq_attr "alternative" "2,3")
1430 (eq_attr "alternative" "6,7")
1432 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1433 (const_string "V4SF")
1434 (const_string "TI"))
1435 (and (eq_attr "alternative" "8,9,10,11")
1436 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1439 (const_string "SI")))])
1441 ;; Stores and loads of ax to arbitrary constant address.
1442 ;; We fake an second form of instruction to force reload to load address
1443 ;; into register when rax is not available
1444 (define_insn "*movabssi_1_rex64"
1445 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1446 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1447 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1449 movabs{l}\t{%1, %P0|%P0, %1}
1450 mov{l}\t{%1, %a0|%a0, %1}"
1451 [(set_attr "type" "imov")
1452 (set_attr "modrm" "0,*")
1453 (set_attr "length_address" "8,0")
1454 (set_attr "length_immediate" "0,*")
1455 (set_attr "memory" "store")
1456 (set_attr "mode" "SI")])
1458 (define_insn "*movabssi_2_rex64"
1459 [(set (match_operand:SI 0 "register_operand" "=a,r")
1460 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1461 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1463 movabs{l}\t{%P1, %0|%0, %P1}
1464 mov{l}\t{%a1, %0|%0, %a1}"
1465 [(set_attr "type" "imov")
1466 (set_attr "modrm" "0,*")
1467 (set_attr "length_address" "8,0")
1468 (set_attr "length_immediate" "0")
1469 (set_attr "memory" "load")
1470 (set_attr "mode" "SI")])
1472 (define_insn "*swapsi"
1473 [(set (match_operand:SI 0 "register_operand" "+r")
1474 (match_operand:SI 1 "register_operand" "+r"))
1479 [(set_attr "type" "imov")
1480 (set_attr "mode" "SI")
1481 (set_attr "pent_pair" "np")
1482 (set_attr "athlon_decode" "vector")
1483 (set_attr "amdfam10_decode" "double")])
1485 (define_expand "movhi"
1486 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1487 (match_operand:HI 1 "general_operand" ""))]
1489 "ix86_expand_move (HImode, operands); DONE;")
1491 (define_insn "*pushhi2"
1492 [(set (match_operand:HI 0 "push_operand" "=X")
1493 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1496 [(set_attr "type" "push")
1497 (set_attr "mode" "SI")])
1499 ;; For 64BIT abi we always round up to 8 bytes.
1500 (define_insn "*pushhi2_rex64"
1501 [(set (match_operand:HI 0 "push_operand" "=X")
1502 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1505 [(set_attr "type" "push")
1506 (set_attr "mode" "DI")])
1508 (define_insn "*movhi_1"
1509 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1510 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1511 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1513 switch (get_attr_type (insn))
1516 /* movzwl is faster than movw on p2 due to partial word stalls,
1517 though not as fast as an aligned movl. */
1518 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1520 if (get_attr_mode (insn) == MODE_SI)
1521 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1523 return "mov{w}\t{%1, %0|%0, %1}";
1527 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1528 (const_string "imov")
1529 (and (eq_attr "alternative" "0")
1530 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1532 (eq (symbol_ref "TARGET_HIMODE_MATH")
1534 (const_string "imov")
1535 (and (eq_attr "alternative" "1,2")
1536 (match_operand:HI 1 "aligned_operand" ""))
1537 (const_string "imov")
1538 (and (ne (symbol_ref "TARGET_MOVX")
1540 (eq_attr "alternative" "0,2"))
1541 (const_string "imovx")
1543 (const_string "imov")))
1545 (cond [(eq_attr "type" "imovx")
1547 (and (eq_attr "alternative" "1,2")
1548 (match_operand:HI 1 "aligned_operand" ""))
1550 (and (eq_attr "alternative" "0")
1551 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553 (eq (symbol_ref "TARGET_HIMODE_MATH")
1557 (const_string "HI")))])
1559 ;; Stores and loads of ax to arbitrary constant address.
1560 ;; We fake an second form of instruction to force reload to load address
1561 ;; into register when rax is not available
1562 (define_insn "*movabshi_1_rex64"
1563 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1564 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1565 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1567 movabs{w}\t{%1, %P0|%P0, %1}
1568 mov{w}\t{%1, %a0|%a0, %1}"
1569 [(set_attr "type" "imov")
1570 (set_attr "modrm" "0,*")
1571 (set_attr "length_address" "8,0")
1572 (set_attr "length_immediate" "0,*")
1573 (set_attr "memory" "store")
1574 (set_attr "mode" "HI")])
1576 (define_insn "*movabshi_2_rex64"
1577 [(set (match_operand:HI 0 "register_operand" "=a,r")
1578 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1579 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1581 movabs{w}\t{%P1, %0|%0, %P1}
1582 mov{w}\t{%a1, %0|%0, %a1}"
1583 [(set_attr "type" "imov")
1584 (set_attr "modrm" "0,*")
1585 (set_attr "length_address" "8,0")
1586 (set_attr "length_immediate" "0")
1587 (set_attr "memory" "load")
1588 (set_attr "mode" "HI")])
1590 (define_insn "*swaphi_1"
1591 [(set (match_operand:HI 0 "register_operand" "+r")
1592 (match_operand:HI 1 "register_operand" "+r"))
1595 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1597 [(set_attr "type" "imov")
1598 (set_attr "mode" "SI")
1599 (set_attr "pent_pair" "np")
1600 (set_attr "athlon_decode" "vector")
1601 (set_attr "amdfam10_decode" "double")])
1603 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1604 (define_insn "*swaphi_2"
1605 [(set (match_operand:HI 0 "register_operand" "+r")
1606 (match_operand:HI 1 "register_operand" "+r"))
1609 "TARGET_PARTIAL_REG_STALL"
1611 [(set_attr "type" "imov")
1612 (set_attr "mode" "HI")
1613 (set_attr "pent_pair" "np")
1614 (set_attr "athlon_decode" "vector")])
1616 (define_expand "movstricthi"
1617 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1618 (match_operand:HI 1 "general_operand" ""))]
1619 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1621 /* Don't generate memory->memory moves, go through a register */
1622 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1623 operands[1] = force_reg (HImode, operands[1]);
1626 (define_insn "*movstricthi_1"
1627 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1628 (match_operand:HI 1 "general_operand" "rn,m"))]
1629 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1630 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1631 "mov{w}\t{%1, %0|%0, %1}"
1632 [(set_attr "type" "imov")
1633 (set_attr "mode" "HI")])
1635 (define_insn "*movstricthi_xor"
1636 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1637 (match_operand:HI 1 "const0_operand" "i"))
1638 (clobber (reg:CC FLAGS_REG))]
1640 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1642 [(set_attr "type" "alu1")
1643 (set_attr "mode" "HI")
1644 (set_attr "length_immediate" "0")])
1646 (define_expand "movqi"
1647 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1648 (match_operand:QI 1 "general_operand" ""))]
1650 "ix86_expand_move (QImode, operands); DONE;")
1652 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1653 ;; "push a byte". But actually we use pushl, which has the effect
1654 ;; of rounding the amount pushed up to a word.
1656 (define_insn "*pushqi2"
1657 [(set (match_operand:QI 0 "push_operand" "=X")
1658 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1661 [(set_attr "type" "push")
1662 (set_attr "mode" "SI")])
1664 ;; For 64BIT abi we always round up to 8 bytes.
1665 (define_insn "*pushqi2_rex64"
1666 [(set (match_operand:QI 0 "push_operand" "=X")
1667 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1670 [(set_attr "type" "push")
1671 (set_attr "mode" "DI")])
1673 ;; Situation is quite tricky about when to choose full sized (SImode) move
1674 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1675 ;; partial register dependency machines (such as AMD Athlon), where QImode
1676 ;; moves issue extra dependency and for partial register stalls machines
1677 ;; that don't use QImode patterns (and QImode move cause stall on the next
1680 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1681 ;; register stall machines with, where we use QImode instructions, since
1682 ;; partial register stall can be caused there. Then we use movzx.
1683 (define_insn "*movqi_1"
1684 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1685 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1686 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1688 switch (get_attr_type (insn))
1691 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1692 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1694 if (get_attr_mode (insn) == MODE_SI)
1695 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1697 return "mov{b}\t{%1, %0|%0, %1}";
1701 (cond [(and (eq_attr "alternative" "5")
1702 (not (match_operand:QI 1 "aligned_operand" "")))
1703 (const_string "imovx")
1704 (ne (symbol_ref "optimize_size") (const_int 0))
1705 (const_string "imov")
1706 (and (eq_attr "alternative" "3")
1707 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1709 (eq (symbol_ref "TARGET_QIMODE_MATH")
1711 (const_string "imov")
1712 (eq_attr "alternative" "3,5")
1713 (const_string "imovx")
1714 (and (ne (symbol_ref "TARGET_MOVX")
1716 (eq_attr "alternative" "2"))
1717 (const_string "imovx")
1719 (const_string "imov")))
1721 (cond [(eq_attr "alternative" "3,4,5")
1723 (eq_attr "alternative" "6")
1725 (eq_attr "type" "imovx")
1727 (and (eq_attr "type" "imov")
1728 (and (eq_attr "alternative" "0,1")
1729 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1731 (and (eq (symbol_ref "optimize_size")
1733 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1736 ;; Avoid partial register stalls when not using QImode arithmetic
1737 (and (eq_attr "type" "imov")
1738 (and (eq_attr "alternative" "0,1")
1739 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1741 (eq (symbol_ref "TARGET_QIMODE_MATH")
1745 (const_string "QI")))])
1747 (define_expand "reload_outqi"
1748 [(parallel [(match_operand:QI 0 "" "=m")
1749 (match_operand:QI 1 "register_operand" "r")
1750 (match_operand:QI 2 "register_operand" "=&q")])]
1754 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1756 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1757 if (! q_regs_operand (op1, QImode))
1759 emit_insn (gen_movqi (op2, op1));
1762 emit_insn (gen_movqi (op0, op1));
1766 (define_insn "*swapqi_1"
1767 [(set (match_operand:QI 0 "register_operand" "+r")
1768 (match_operand:QI 1 "register_operand" "+r"))
1771 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1773 [(set_attr "type" "imov")
1774 (set_attr "mode" "SI")
1775 (set_attr "pent_pair" "np")
1776 (set_attr "athlon_decode" "vector")
1777 (set_attr "amdfam10_decode" "vector")])
1779 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1780 (define_insn "*swapqi_2"
1781 [(set (match_operand:QI 0 "register_operand" "+q")
1782 (match_operand:QI 1 "register_operand" "+q"))
1785 "TARGET_PARTIAL_REG_STALL"
1787 [(set_attr "type" "imov")
1788 (set_attr "mode" "QI")
1789 (set_attr "pent_pair" "np")
1790 (set_attr "athlon_decode" "vector")])
1792 (define_expand "movstrictqi"
1793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1794 (match_operand:QI 1 "general_operand" ""))]
1795 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1797 /* Don't generate memory->memory moves, go through a register. */
1798 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1799 operands[1] = force_reg (QImode, operands[1]);
1802 (define_insn "*movstrictqi_1"
1803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1804 (match_operand:QI 1 "general_operand" "*qn,m"))]
1805 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1806 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1807 "mov{b}\t{%1, %0|%0, %1}"
1808 [(set_attr "type" "imov")
1809 (set_attr "mode" "QI")])
1811 (define_insn "*movstrictqi_xor"
1812 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1813 (match_operand:QI 1 "const0_operand" "i"))
1814 (clobber (reg:CC FLAGS_REG))]
1815 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1817 [(set_attr "type" "alu1")
1818 (set_attr "mode" "QI")
1819 (set_attr "length_immediate" "0")])
1821 (define_insn "*movsi_extv_1"
1822 [(set (match_operand:SI 0 "register_operand" "=R")
1823 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1827 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1828 [(set_attr "type" "imovx")
1829 (set_attr "mode" "SI")])
1831 (define_insn "*movhi_extv_1"
1832 [(set (match_operand:HI 0 "register_operand" "=R")
1833 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1837 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1838 [(set_attr "type" "imovx")
1839 (set_attr "mode" "SI")])
1841 (define_insn "*movqi_extv_1"
1842 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1843 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1848 switch (get_attr_type (insn))
1851 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1853 return "mov{b}\t{%h1, %0|%0, %h1}";
1857 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1858 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1859 (ne (symbol_ref "TARGET_MOVX")
1861 (const_string "imovx")
1862 (const_string "imov")))
1864 (if_then_else (eq_attr "type" "imovx")
1866 (const_string "QI")))])
1868 (define_insn "*movqi_extv_1_rex64"
1869 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1870 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1875 switch (get_attr_type (insn))
1878 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1880 return "mov{b}\t{%h1, %0|%0, %h1}";
1884 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1885 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1886 (ne (symbol_ref "TARGET_MOVX")
1888 (const_string "imovx")
1889 (const_string "imov")))
1891 (if_then_else (eq_attr "type" "imovx")
1893 (const_string "QI")))])
1895 ;; Stores and loads of ax to arbitrary constant address.
1896 ;; We fake an second form of instruction to force reload to load address
1897 ;; into register when rax is not available
1898 (define_insn "*movabsqi_1_rex64"
1899 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1900 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1901 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1903 movabs{b}\t{%1, %P0|%P0, %1}
1904 mov{b}\t{%1, %a0|%a0, %1}"
1905 [(set_attr "type" "imov")
1906 (set_attr "modrm" "0,*")
1907 (set_attr "length_address" "8,0")
1908 (set_attr "length_immediate" "0,*")
1909 (set_attr "memory" "store")
1910 (set_attr "mode" "QI")])
1912 (define_insn "*movabsqi_2_rex64"
1913 [(set (match_operand:QI 0 "register_operand" "=a,r")
1914 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1915 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1917 movabs{b}\t{%P1, %0|%0, %P1}
1918 mov{b}\t{%a1, %0|%0, %a1}"
1919 [(set_attr "type" "imov")
1920 (set_attr "modrm" "0,*")
1921 (set_attr "length_address" "8,0")
1922 (set_attr "length_immediate" "0")
1923 (set_attr "memory" "load")
1924 (set_attr "mode" "QI")])
1926 (define_insn "*movdi_extzv_1"
1927 [(set (match_operand:DI 0 "register_operand" "=R")
1928 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1932 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1933 [(set_attr "type" "imovx")
1934 (set_attr "mode" "DI")])
1936 (define_insn "*movsi_extzv_1"
1937 [(set (match_operand:SI 0 "register_operand" "=R")
1938 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1942 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1943 [(set_attr "type" "imovx")
1944 (set_attr "mode" "SI")])
1946 (define_insn "*movqi_extzv_2"
1947 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1948 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1953 switch (get_attr_type (insn))
1956 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1958 return "mov{b}\t{%h1, %0|%0, %h1}";
1962 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1963 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1964 (ne (symbol_ref "TARGET_MOVX")
1966 (const_string "imovx")
1967 (const_string "imov")))
1969 (if_then_else (eq_attr "type" "imovx")
1971 (const_string "QI")))])
1973 (define_insn "*movqi_extzv_2_rex64"
1974 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1975 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1980 switch (get_attr_type (insn))
1983 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1985 return "mov{b}\t{%h1, %0|%0, %h1}";
1989 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1990 (ne (symbol_ref "TARGET_MOVX")
1992 (const_string "imovx")
1993 (const_string "imov")))
1995 (if_then_else (eq_attr "type" "imovx")
1997 (const_string "QI")))])
1999 (define_insn "movsi_insv_1"
2000 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2003 (match_operand:SI 1 "general_operand" "Qmn"))]
2005 "mov{b}\t{%b1, %h0|%h0, %b1}"
2006 [(set_attr "type" "imov")
2007 (set_attr "mode" "QI")])
2009 (define_insn "*movsi_insv_1_rex64"
2010 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2013 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2015 "mov{b}\t{%b1, %h0|%h0, %b1}"
2016 [(set_attr "type" "imov")
2017 (set_attr "mode" "QI")])
2019 (define_insn "movdi_insv_1_rex64"
2020 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2023 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2025 "mov{b}\t{%b1, %h0|%h0, %b1}"
2026 [(set_attr "type" "imov")
2027 (set_attr "mode" "QI")])
2029 (define_insn "*movqi_insv_2"
2030 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2033 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2036 "mov{b}\t{%h1, %h0|%h0, %h1}"
2037 [(set_attr "type" "imov")
2038 (set_attr "mode" "QI")])
2040 (define_expand "movdi"
2041 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2042 (match_operand:DI 1 "general_operand" ""))]
2044 "ix86_expand_move (DImode, operands); DONE;")
2046 (define_insn "*pushdi"
2047 [(set (match_operand:DI 0 "push_operand" "=<")
2048 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2052 (define_insn "*pushdi2_rex64"
2053 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2054 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2059 [(set_attr "type" "push,multi")
2060 (set_attr "mode" "DI")])
2062 ;; Convert impossible pushes of immediate to existing instructions.
2063 ;; First try to get scratch register and go through it. In case this
2064 ;; fails, push sign extended lower part first and then overwrite
2065 ;; upper part by 32bit move.
2067 [(match_scratch:DI 2 "r")
2068 (set (match_operand:DI 0 "push_operand" "")
2069 (match_operand:DI 1 "immediate_operand" ""))]
2070 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2071 && !x86_64_immediate_operand (operands[1], DImode)"
2072 [(set (match_dup 2) (match_dup 1))
2073 (set (match_dup 0) (match_dup 2))]
2076 ;; We need to define this as both peepholer and splitter for case
2077 ;; peephole2 pass is not run.
2078 ;; "&& 1" is needed to keep it from matching the previous pattern.
2080 [(set (match_operand:DI 0 "push_operand" "")
2081 (match_operand:DI 1 "immediate_operand" ""))]
2082 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2083 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2084 [(set (match_dup 0) (match_dup 1))
2085 (set (match_dup 2) (match_dup 3))]
2086 "split_di (operands + 1, 1, operands + 2, operands + 3);
2087 operands[1] = gen_lowpart (DImode, operands[2]);
2088 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2093 [(set (match_operand:DI 0 "push_operand" "")
2094 (match_operand:DI 1 "immediate_operand" ""))]
2095 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2096 ? epilogue_completed : reload_completed)
2097 && !symbolic_operand (operands[1], DImode)
2098 && !x86_64_immediate_operand (operands[1], DImode)"
2099 [(set (match_dup 0) (match_dup 1))
2100 (set (match_dup 2) (match_dup 3))]
2101 "split_di (operands + 1, 1, operands + 2, operands + 3);
2102 operands[1] = gen_lowpart (DImode, operands[2]);
2103 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2107 (define_insn "*pushdi2_prologue_rex64"
2108 [(set (match_operand:DI 0 "push_operand" "=<")
2109 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2110 (clobber (mem:BLK (scratch)))]
2113 [(set_attr "type" "push")
2114 (set_attr "mode" "DI")])
2116 (define_insn "*popdi1_epilogue_rex64"
2117 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2118 (mem:DI (reg:DI SP_REG)))
2119 (set (reg:DI SP_REG)
2120 (plus:DI (reg:DI SP_REG) (const_int 8)))
2121 (clobber (mem:BLK (scratch)))]
2124 [(set_attr "type" "pop")
2125 (set_attr "mode" "DI")])
2127 (define_insn "popdi1"
2128 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2129 (mem:DI (reg:DI SP_REG)))
2130 (set (reg:DI SP_REG)
2131 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2134 [(set_attr "type" "pop")
2135 (set_attr "mode" "DI")])
2137 (define_insn "*movdi_xor_rex64"
2138 [(set (match_operand:DI 0 "register_operand" "=r")
2139 (match_operand:DI 1 "const0_operand" "i"))
2140 (clobber (reg:CC FLAGS_REG))]
2141 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2142 && reload_completed"
2144 [(set_attr "type" "alu1")
2145 (set_attr "mode" "SI")
2146 (set_attr "length_immediate" "0")])
2148 (define_insn "*movdi_or_rex64"
2149 [(set (match_operand:DI 0 "register_operand" "=r")
2150 (match_operand:DI 1 "const_int_operand" "i"))
2151 (clobber (reg:CC FLAGS_REG))]
2152 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2154 && operands[1] == constm1_rtx"
2156 operands[1] = constm1_rtx;
2157 return "or{q}\t{%1, %0|%0, %1}";
2159 [(set_attr "type" "alu1")
2160 (set_attr "mode" "DI")
2161 (set_attr "length_immediate" "1")])
2163 (define_insn "*movdi_2"
2164 [(set (match_operand:DI 0 "nonimmediate_operand"
2165 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2166 (match_operand:DI 1 "general_operand"
2167 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2168 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2173 movq\t{%1, %0|%0, %1}
2174 movq\t{%1, %0|%0, %1}
2176 movq\t{%1, %0|%0, %1}
2177 movdqa\t{%1, %0|%0, %1}
2178 movq\t{%1, %0|%0, %1}
2180 movlps\t{%1, %0|%0, %1}
2181 movaps\t{%1, %0|%0, %1}
2182 movlps\t{%1, %0|%0, %1}"
2183 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2184 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2187 [(set (match_operand:DI 0 "push_operand" "")
2188 (match_operand:DI 1 "general_operand" ""))]
2189 "!TARGET_64BIT && reload_completed
2190 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2192 "ix86_split_long_move (operands); DONE;")
2194 ;; %%% This multiword shite has got to go.
2196 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2197 (match_operand:DI 1 "general_operand" ""))]
2198 "!TARGET_64BIT && reload_completed
2199 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2200 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2202 "ix86_split_long_move (operands); DONE;")
2204 (define_insn "*movdi_1_rex64"
2205 [(set (match_operand:DI 0 "nonimmediate_operand"
2206 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2207 (match_operand:DI 1 "general_operand"
2208 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2209 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2211 switch (get_attr_type (insn))
2214 if (SSE_REG_P (operands[0]))
2215 return "movq2dq\t{%1, %0|%0, %1}";
2217 return "movdq2q\t{%1, %0|%0, %1}";
2220 if (get_attr_mode (insn) == MODE_TI)
2221 return "movdqa\t{%1, %0|%0, %1}";
2225 /* Moves from and into integer register is done using movd
2226 opcode with REX prefix. */
2227 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2228 return "movd\t{%1, %0|%0, %1}";
2229 return "movq\t{%1, %0|%0, %1}";
2233 return "pxor\t%0, %0";
2239 return "lea{q}\t{%a1, %0|%0, %a1}";
2242 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2243 if (get_attr_mode (insn) == MODE_SI)
2244 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2245 else if (which_alternative == 2)
2246 return "movabs{q}\t{%1, %0|%0, %1}";
2248 return "mov{q}\t{%1, %0|%0, %1}";
2252 (cond [(eq_attr "alternative" "5")
2253 (const_string "mmxadd")
2254 (eq_attr "alternative" "6,7,8,9,10")
2255 (const_string "mmxmov")
2256 (eq_attr "alternative" "11")
2257 (const_string "sselog1")
2258 (eq_attr "alternative" "12,13,14,15,16")
2259 (const_string "ssemov")
2260 (eq_attr "alternative" "17,18")
2261 (const_string "ssecvt")
2262 (eq_attr "alternative" "4")
2263 (const_string "multi")
2264 (match_operand:DI 1 "pic_32bit_operand" "")
2265 (const_string "lea")
2267 (const_string "imov")))
2268 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2269 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2270 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2272 ;; Stores and loads of ax to arbitrary constant address.
2273 ;; We fake an second form of instruction to force reload to load address
2274 ;; into register when rax is not available
2275 (define_insn "*movabsdi_1_rex64"
2276 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2277 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2278 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2280 movabs{q}\t{%1, %P0|%P0, %1}
2281 mov{q}\t{%1, %a0|%a0, %1}"
2282 [(set_attr "type" "imov")
2283 (set_attr "modrm" "0,*")
2284 (set_attr "length_address" "8,0")
2285 (set_attr "length_immediate" "0,*")
2286 (set_attr "memory" "store")
2287 (set_attr "mode" "DI")])
2289 (define_insn "*movabsdi_2_rex64"
2290 [(set (match_operand:DI 0 "register_operand" "=a,r")
2291 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2292 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2294 movabs{q}\t{%P1, %0|%0, %P1}
2295 mov{q}\t{%a1, %0|%0, %a1}"
2296 [(set_attr "type" "imov")
2297 (set_attr "modrm" "0,*")
2298 (set_attr "length_address" "8,0")
2299 (set_attr "length_immediate" "0")
2300 (set_attr "memory" "load")
2301 (set_attr "mode" "DI")])
2303 ;; Convert impossible stores of immediate to existing instructions.
2304 ;; First try to get scratch register and go through it. In case this
2305 ;; fails, move by 32bit parts.
2307 [(match_scratch:DI 2 "r")
2308 (set (match_operand:DI 0 "memory_operand" "")
2309 (match_operand:DI 1 "immediate_operand" ""))]
2310 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2311 && !x86_64_immediate_operand (operands[1], DImode)"
2312 [(set (match_dup 2) (match_dup 1))
2313 (set (match_dup 0) (match_dup 2))]
2316 ;; We need to define this as both peepholer and splitter for case
2317 ;; peephole2 pass is not run.
2318 ;; "&& 1" is needed to keep it from matching the previous pattern.
2320 [(set (match_operand:DI 0 "memory_operand" "")
2321 (match_operand:DI 1 "immediate_operand" ""))]
2322 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2323 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2324 [(set (match_dup 2) (match_dup 3))
2325 (set (match_dup 4) (match_dup 5))]
2326 "split_di (operands, 2, operands + 2, operands + 4);")
2329 [(set (match_operand:DI 0 "memory_operand" "")
2330 (match_operand:DI 1 "immediate_operand" ""))]
2331 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2332 ? epilogue_completed : reload_completed)
2333 && !symbolic_operand (operands[1], DImode)
2334 && !x86_64_immediate_operand (operands[1], DImode)"
2335 [(set (match_dup 2) (match_dup 3))
2336 (set (match_dup 4) (match_dup 5))]
2337 "split_di (operands, 2, operands + 2, operands + 4);")
2339 (define_insn "*swapdi_rex64"
2340 [(set (match_operand:DI 0 "register_operand" "+r")
2341 (match_operand:DI 1 "register_operand" "+r"))
2346 [(set_attr "type" "imov")
2347 (set_attr "mode" "DI")
2348 (set_attr "pent_pair" "np")
2349 (set_attr "athlon_decode" "vector")
2350 (set_attr "amdfam10_decode" "double")])
2352 (define_expand "movti"
2353 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2354 (match_operand:TI 1 "nonimmediate_operand" ""))]
2355 "TARGET_SSE || TARGET_64BIT"
2358 ix86_expand_move (TImode, operands);
2359 else if (push_operand (operands[0], TImode))
2360 ix86_expand_push (TImode, operands[1]);
2362 ix86_expand_vector_move (TImode, operands);
2366 (define_insn "*movti_internal"
2367 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2368 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2369 "TARGET_SSE && !TARGET_64BIT
2370 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2372 switch (which_alternative)
2375 if (get_attr_mode (insn) == MODE_V4SF)
2376 return "xorps\t%0, %0";
2378 return "pxor\t%0, %0";
2381 if (get_attr_mode (insn) == MODE_V4SF)
2382 return "movaps\t{%1, %0|%0, %1}";
2384 return "movdqa\t{%1, %0|%0, %1}";
2389 [(set_attr "type" "sselog1,ssemov,ssemov")
2391 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2392 (ne (symbol_ref "optimize_size") (const_int 0)))
2393 (const_string "V4SF")
2394 (and (eq_attr "alternative" "2")
2395 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2397 (const_string "V4SF")]
2398 (const_string "TI")))])
2400 (define_insn "*movti_rex64"
2401 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2402 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2404 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2406 switch (which_alternative)
2412 if (get_attr_mode (insn) == MODE_V4SF)
2413 return "xorps\t%0, %0";
2415 return "pxor\t%0, %0";
2418 if (get_attr_mode (insn) == MODE_V4SF)
2419 return "movaps\t{%1, %0|%0, %1}";
2421 return "movdqa\t{%1, %0|%0, %1}";
2426 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2428 (cond [(eq_attr "alternative" "2,3")
2430 (ne (symbol_ref "optimize_size")
2432 (const_string "V4SF")
2433 (const_string "TI"))
2434 (eq_attr "alternative" "4")
2436 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2438 (ne (symbol_ref "optimize_size")
2440 (const_string "V4SF")
2441 (const_string "TI"))]
2442 (const_string "DI")))])
2445 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2446 (match_operand:TI 1 "general_operand" ""))]
2447 "reload_completed && !SSE_REG_P (operands[0])
2448 && !SSE_REG_P (operands[1])"
2450 "ix86_split_long_move (operands); DONE;")
2452 ;; This expands to what emit_move_complex would generate if we didn't
2453 ;; have a movti pattern. Having this avoids problems with reload on
2454 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2455 ;; to have around all the time.
2456 (define_expand "movcdi"
2457 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2458 (match_operand:CDI 1 "general_operand" ""))]
2461 if (push_operand (operands[0], CDImode))
2462 emit_move_complex_push (CDImode, operands[0], operands[1]);
2464 emit_move_complex_parts (operands[0], operands[1]);
2468 (define_expand "movsf"
2469 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2470 (match_operand:SF 1 "general_operand" ""))]
2472 "ix86_expand_move (SFmode, operands); DONE;")
2474 (define_insn "*pushsf"
2475 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2476 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2479 /* Anything else should be already split before reg-stack. */
2480 gcc_assert (which_alternative == 1);
2481 return "push{l}\t%1";
2483 [(set_attr "type" "multi,push,multi")
2484 (set_attr "unit" "i387,*,*")
2485 (set_attr "mode" "SF,SI,SF")])
2487 (define_insn "*pushsf_rex64"
2488 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2489 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2492 /* Anything else should be already split before reg-stack. */
2493 gcc_assert (which_alternative == 1);
2494 return "push{q}\t%q1";
2496 [(set_attr "type" "multi,push,multi")
2497 (set_attr "unit" "i387,*,*")
2498 (set_attr "mode" "SF,DI,SF")])
2501 [(set (match_operand:SF 0 "push_operand" "")
2502 (match_operand:SF 1 "memory_operand" ""))]
2504 && MEM_P (operands[1])
2505 && (operands[2] = find_constant_src (insn))"
2510 ;; %%% Kill this when call knows how to work this out.
2512 [(set (match_operand:SF 0 "push_operand" "")
2513 (match_operand:SF 1 "any_fp_register_operand" ""))]
2515 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2516 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2519 [(set (match_operand:SF 0 "push_operand" "")
2520 (match_operand:SF 1 "any_fp_register_operand" ""))]
2522 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2523 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2525 (define_insn "*movsf_1"
2526 [(set (match_operand:SF 0 "nonimmediate_operand"
2527 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2528 (match_operand:SF 1 "general_operand"
2529 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2530 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2531 && (reload_in_progress || reload_completed
2532 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2533 || (!TARGET_SSE_MATH && optimize_size
2534 && standard_80387_constant_p (operands[1]))
2535 || GET_CODE (operands[1]) != CONST_DOUBLE
2536 || memory_operand (operands[0], SFmode))"
2538 switch (which_alternative)
2542 return output_387_reg_move (insn, operands);
2545 return standard_80387_constant_opcode (operands[1]);
2549 return "mov{l}\t{%1, %0|%0, %1}";
2551 if (get_attr_mode (insn) == MODE_TI)
2552 return "pxor\t%0, %0";
2554 return "xorps\t%0, %0";
2556 if (get_attr_mode (insn) == MODE_V4SF)
2557 return "movaps\t{%1, %0|%0, %1}";
2559 return "movss\t{%1, %0|%0, %1}";
2561 return "movss\t{%1, %0|%0, %1}";
2564 case 12: case 13: case 14: case 15:
2565 return "movd\t{%1, %0|%0, %1}";
2568 return "movq\t{%1, %0|%0, %1}";
2574 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2576 (cond [(eq_attr "alternative" "3,4,9,10")
2578 (eq_attr "alternative" "5")
2580 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2582 (ne (symbol_ref "TARGET_SSE2")
2584 (eq (symbol_ref "optimize_size")
2587 (const_string "V4SF"))
2588 /* For architectures resolving dependencies on
2589 whole SSE registers use APS move to break dependency
2590 chains, otherwise use short move to avoid extra work.
2592 Do the same for architectures resolving dependencies on
2593 the parts. While in DF mode it is better to always handle
2594 just register parts, the SF mode is different due to lack
2595 of instructions to load just part of the register. It is
2596 better to maintain the whole registers in single format
2597 to avoid problems on using packed logical operations. */
2598 (eq_attr "alternative" "6")
2600 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2602 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2604 (const_string "V4SF")
2605 (const_string "SF"))
2606 (eq_attr "alternative" "11")
2607 (const_string "DI")]
2608 (const_string "SF")))])
2610 (define_insn "*swapsf"
2611 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2612 (match_operand:SF 1 "fp_register_operand" "+f"))
2615 "reload_completed || TARGET_80387"
2617 if (STACK_TOP_P (operands[0]))
2622 [(set_attr "type" "fxch")
2623 (set_attr "mode" "SF")])
2625 (define_expand "movdf"
2626 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2627 (match_operand:DF 1 "general_operand" ""))]
2629 "ix86_expand_move (DFmode, operands); DONE;")
2631 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2632 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2633 ;; On the average, pushdf using integers can be still shorter. Allow this
2634 ;; pattern for optimize_size too.
2636 (define_insn "*pushdf_nointeger"
2637 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2638 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2639 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2641 /* This insn should be already split before reg-stack. */
2644 [(set_attr "type" "multi")
2645 (set_attr "unit" "i387,*,*,*")
2646 (set_attr "mode" "DF,SI,SI,DF")])
2648 (define_insn "*pushdf_integer"
2649 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2650 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2651 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2653 /* This insn should be already split before reg-stack. */
2656 [(set_attr "type" "multi")
2657 (set_attr "unit" "i387,*,*")
2658 (set_attr "mode" "DF,SI,DF")])
2660 ;; %%% Kill this when call knows how to work this out.
2662 [(set (match_operand:DF 0 "push_operand" "")
2663 (match_operand:DF 1 "any_fp_register_operand" ""))]
2664 "!TARGET_64BIT && reload_completed"
2665 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2666 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2670 [(set (match_operand:DF 0 "push_operand" "")
2671 (match_operand:DF 1 "any_fp_register_operand" ""))]
2672 "TARGET_64BIT && reload_completed"
2673 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2674 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2678 [(set (match_operand:DF 0 "push_operand" "")
2679 (match_operand:DF 1 "general_operand" ""))]
2682 "ix86_split_long_move (operands); DONE;")
2684 ;; Moving is usually shorter when only FP registers are used. This separate
2685 ;; movdf pattern avoids the use of integer registers for FP operations
2686 ;; when optimizing for size.
2688 (define_insn "*movdf_nointeger"
2689 [(set (match_operand:DF 0 "nonimmediate_operand"
2690 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2691 (match_operand:DF 1 "general_operand"
2692 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2693 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2694 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2695 && (reload_in_progress || reload_completed
2696 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2697 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2698 && !memory_operand (operands[0], DFmode)
2699 && standard_80387_constant_p (operands[1]))
2700 || GET_CODE (operands[1]) != CONST_DOUBLE
2702 || !TARGET_MEMORY_MISMATCH_STALL
2703 || reload_in_progress || reload_completed)
2704 && memory_operand (operands[0], DFmode)))"
2706 switch (which_alternative)
2710 return output_387_reg_move (insn, operands);
2713 return standard_80387_constant_opcode (operands[1]);
2719 switch (get_attr_mode (insn))
2722 return "xorps\t%0, %0";
2724 return "xorpd\t%0, %0";
2726 return "pxor\t%0, %0";
2733 switch (get_attr_mode (insn))
2736 return "movaps\t{%1, %0|%0, %1}";
2738 return "movapd\t{%1, %0|%0, %1}";
2740 return "movdqa\t{%1, %0|%0, %1}";
2742 return "movq\t{%1, %0|%0, %1}";
2744 return "movsd\t{%1, %0|%0, %1}";
2746 return "movlpd\t{%1, %0|%0, %1}";
2748 return "movlps\t{%1, %0|%0, %1}";
2757 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2759 (cond [(eq_attr "alternative" "0,1,2")
2761 (eq_attr "alternative" "3,4")
2764 /* For SSE1, we have many fewer alternatives. */
2765 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2766 (cond [(eq_attr "alternative" "5,6")
2767 (const_string "V4SF")
2769 (const_string "V2SF"))
2771 /* xorps is one byte shorter. */
2772 (eq_attr "alternative" "5")
2773 (cond [(ne (symbol_ref "optimize_size")
2775 (const_string "V4SF")
2776 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2780 (const_string "V2DF"))
2782 /* For architectures resolving dependencies on
2783 whole SSE registers use APD move to break dependency
2784 chains, otherwise use short move to avoid extra work.
2786 movaps encodes one byte shorter. */
2787 (eq_attr "alternative" "6")
2789 [(ne (symbol_ref "optimize_size")
2791 (const_string "V4SF")
2792 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2794 (const_string "V2DF")
2796 (const_string "DF"))
2797 /* For architectures resolving dependencies on register
2798 parts we may avoid extra work to zero out upper part
2800 (eq_attr "alternative" "7")
2802 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2804 (const_string "V1DF")
2805 (const_string "DF"))
2807 (const_string "DF")))])
2809 (define_insn "*movdf_integer_rex64"
2810 [(set (match_operand:DF 0 "nonimmediate_operand"
2811 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2812 (match_operand:DF 1 "general_operand"
2813 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2814 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2815 && (reload_in_progress || reload_completed
2816 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2817 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2818 && standard_80387_constant_p (operands[1]))
2819 || GET_CODE (operands[1]) != CONST_DOUBLE
2820 || memory_operand (operands[0], DFmode))"
2822 switch (which_alternative)
2826 return output_387_reg_move (insn, operands);
2829 return standard_80387_constant_opcode (operands[1]);
2836 switch (get_attr_mode (insn))
2839 return "xorps\t%0, %0";
2841 return "xorpd\t%0, %0";
2843 return "pxor\t%0, %0";
2850 switch (get_attr_mode (insn))
2853 return "movaps\t{%1, %0|%0, %1}";
2855 return "movapd\t{%1, %0|%0, %1}";
2857 return "movdqa\t{%1, %0|%0, %1}";
2859 return "movq\t{%1, %0|%0, %1}";
2861 return "movsd\t{%1, %0|%0, %1}";
2863 return "movlpd\t{%1, %0|%0, %1}";
2865 return "movlps\t{%1, %0|%0, %1}";
2872 return "movd\t{%1, %0|%0, %1}";
2878 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2880 (cond [(eq_attr "alternative" "0,1,2")
2882 (eq_attr "alternative" "3,4,9,10")
2885 /* For SSE1, we have many fewer alternatives. */
2886 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2887 (cond [(eq_attr "alternative" "5,6")
2888 (const_string "V4SF")
2890 (const_string "V2SF"))
2892 /* xorps is one byte shorter. */
2893 (eq_attr "alternative" "5")
2894 (cond [(ne (symbol_ref "optimize_size")
2896 (const_string "V4SF")
2897 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2901 (const_string "V2DF"))
2903 /* For architectures resolving dependencies on
2904 whole SSE registers use APD move to break dependency
2905 chains, otherwise use short move to avoid extra work.
2907 movaps encodes one byte shorter. */
2908 (eq_attr "alternative" "6")
2910 [(ne (symbol_ref "optimize_size")
2912 (const_string "V4SF")
2913 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2915 (const_string "V2DF")
2917 (const_string "DF"))
2918 /* For architectures resolving dependencies on register
2919 parts we may avoid extra work to zero out upper part
2921 (eq_attr "alternative" "7")
2923 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2925 (const_string "V1DF")
2926 (const_string "DF"))
2928 (const_string "DF")))])
2930 (define_insn "*movdf_integer"
2931 [(set (match_operand:DF 0 "nonimmediate_operand"
2932 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2933 (match_operand:DF 1 "general_operand"
2934 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2935 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2936 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2937 && (reload_in_progress || reload_completed
2938 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2939 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2940 && standard_80387_constant_p (operands[1]))
2941 || GET_CODE (operands[1]) != CONST_DOUBLE
2942 || memory_operand (operands[0], DFmode))"
2944 switch (which_alternative)
2948 return output_387_reg_move (insn, operands);
2951 return standard_80387_constant_opcode (operands[1]);
2958 switch (get_attr_mode (insn))
2961 return "xorps\t%0, %0";
2963 return "xorpd\t%0, %0";
2965 return "pxor\t%0, %0";
2972 switch (get_attr_mode (insn))
2975 return "movaps\t{%1, %0|%0, %1}";
2977 return "movapd\t{%1, %0|%0, %1}";
2979 return "movdqa\t{%1, %0|%0, %1}";
2981 return "movq\t{%1, %0|%0, %1}";
2983 return "movsd\t{%1, %0|%0, %1}";
2985 return "movlpd\t{%1, %0|%0, %1}";
2987 return "movlps\t{%1, %0|%0, %1}";
2996 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2998 (cond [(eq_attr "alternative" "0,1,2")
3000 (eq_attr "alternative" "3,4")
3003 /* For SSE1, we have many fewer alternatives. */
3004 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3005 (cond [(eq_attr "alternative" "5,6")
3006 (const_string "V4SF")
3008 (const_string "V2SF"))
3010 /* xorps is one byte shorter. */
3011 (eq_attr "alternative" "5")
3012 (cond [(ne (symbol_ref "optimize_size")
3014 (const_string "V4SF")
3015 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3019 (const_string "V2DF"))
3021 /* For architectures resolving dependencies on
3022 whole SSE registers use APD move to break dependency
3023 chains, otherwise use short move to avoid extra work.
3025 movaps encodes one byte shorter. */
3026 (eq_attr "alternative" "6")
3028 [(ne (symbol_ref "optimize_size")
3030 (const_string "V4SF")
3031 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3033 (const_string "V2DF")
3035 (const_string "DF"))
3036 /* For architectures resolving dependencies on register
3037 parts we may avoid extra work to zero out upper part
3039 (eq_attr "alternative" "7")
3041 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3043 (const_string "V1DF")
3044 (const_string "DF"))
3046 (const_string "DF")))])
3049 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3050 (match_operand:DF 1 "general_operand" ""))]
3052 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3053 && ! (ANY_FP_REG_P (operands[0]) ||
3054 (GET_CODE (operands[0]) == SUBREG
3055 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3056 && ! (ANY_FP_REG_P (operands[1]) ||
3057 (GET_CODE (operands[1]) == SUBREG
3058 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3060 "ix86_split_long_move (operands); DONE;")
3062 (define_insn "*swapdf"
3063 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3064 (match_operand:DF 1 "fp_register_operand" "+f"))
3067 "reload_completed || TARGET_80387"
3069 if (STACK_TOP_P (operands[0]))
3074 [(set_attr "type" "fxch")
3075 (set_attr "mode" "DF")])
3077 (define_expand "movxf"
3078 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3079 (match_operand:XF 1 "general_operand" ""))]
3081 "ix86_expand_move (XFmode, operands); DONE;")
3083 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3084 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3085 ;; Pushing using integer instructions is longer except for constants
3086 ;; and direct memory references.
3087 ;; (assuming that any given constant is pushed only once, but this ought to be
3088 ;; handled elsewhere).
3090 (define_insn "*pushxf_nointeger"
3091 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3092 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3095 /* This insn should be already split before reg-stack. */
3098 [(set_attr "type" "multi")
3099 (set_attr "unit" "i387,*,*")
3100 (set_attr "mode" "XF,SI,SI")])
3102 (define_insn "*pushxf_integer"
3103 [(set (match_operand:XF 0 "push_operand" "=<,<")
3104 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3107 /* This insn should be already split before reg-stack. */
3110 [(set_attr "type" "multi")
3111 (set_attr "unit" "i387,*")
3112 (set_attr "mode" "XF,SI")])
3115 [(set (match_operand 0 "push_operand" "")
3116 (match_operand 1 "general_operand" ""))]
3118 && (GET_MODE (operands[0]) == XFmode
3119 || GET_MODE (operands[0]) == DFmode)
3120 && !ANY_FP_REG_P (operands[1])"
3122 "ix86_split_long_move (operands); DONE;")
3125 [(set (match_operand:XF 0 "push_operand" "")
3126 (match_operand:XF 1 "any_fp_register_operand" ""))]
3128 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3129 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3130 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3133 [(set (match_operand:XF 0 "push_operand" "")
3134 (match_operand:XF 1 "any_fp_register_operand" ""))]
3136 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3137 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3138 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3140 ;; Do not use integer registers when optimizing for size
3141 (define_insn "*movxf_nointeger"
3142 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3143 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3145 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3146 && (reload_in_progress || reload_completed
3147 || (optimize_size && standard_80387_constant_p (operands[1]))
3148 || GET_CODE (operands[1]) != CONST_DOUBLE
3149 || memory_operand (operands[0], XFmode))"
3151 switch (which_alternative)
3155 return output_387_reg_move (insn, operands);
3158 return standard_80387_constant_opcode (operands[1]);
3166 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3167 (set_attr "mode" "XF,XF,XF,SI,SI")])
3169 (define_insn "*movxf_integer"
3170 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3171 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3173 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3174 && (reload_in_progress || reload_completed
3175 || (optimize_size && standard_80387_constant_p (operands[1]))
3176 || GET_CODE (operands[1]) != CONST_DOUBLE
3177 || memory_operand (operands[0], XFmode))"
3179 switch (which_alternative)
3183 return output_387_reg_move (insn, operands);
3186 return standard_80387_constant_opcode (operands[1]);
3195 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3196 (set_attr "mode" "XF,XF,XF,SI,SI")])
3198 (define_expand "movtf"
3199 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3200 (match_operand:TF 1 "nonimmediate_operand" ""))]
3203 ix86_expand_move (TFmode, operands);
3207 (define_insn "*movtf_internal"
3208 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3209 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3211 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3213 switch (which_alternative)
3217 if (get_attr_mode (insn) == MODE_V4SF)
3218 return "movaps\t{%1, %0|%0, %1}";
3220 return "movdqa\t{%1, %0|%0, %1}";
3222 if (get_attr_mode (insn) == MODE_V4SF)
3223 return "xorps\t%0, %0";
3225 return "pxor\t%0, %0";
3233 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3235 (cond [(eq_attr "alternative" "0,2")
3237 (ne (symbol_ref "optimize_size")
3239 (const_string "V4SF")
3240 (const_string "TI"))
3241 (eq_attr "alternative" "1")
3243 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3245 (ne (symbol_ref "optimize_size")
3247 (const_string "V4SF")
3248 (const_string "TI"))]
3249 (const_string "DI")))])
3252 [(set (match_operand 0 "nonimmediate_operand" "")
3253 (match_operand 1 "general_operand" ""))]
3255 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3256 && GET_MODE (operands[0]) == XFmode
3257 && ! (ANY_FP_REG_P (operands[0]) ||
3258 (GET_CODE (operands[0]) == SUBREG
3259 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3260 && ! (ANY_FP_REG_P (operands[1]) ||
3261 (GET_CODE (operands[1]) == SUBREG
3262 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3264 "ix86_split_long_move (operands); DONE;")
3267 [(set (match_operand 0 "register_operand" "")
3268 (match_operand 1 "memory_operand" ""))]
3270 && MEM_P (operands[1])
3271 && (GET_MODE (operands[0]) == TFmode
3272 || GET_MODE (operands[0]) == XFmode
3273 || GET_MODE (operands[0]) == SFmode
3274 || GET_MODE (operands[0]) == DFmode)
3275 && (operands[2] = find_constant_src (insn))"
3276 [(set (match_dup 0) (match_dup 2))]
3278 rtx c = operands[2];
3279 rtx r = operands[0];
3281 if (GET_CODE (r) == SUBREG)
3286 if (!standard_sse_constant_p (c))
3289 else if (FP_REG_P (r))
3291 if (!standard_80387_constant_p (c))
3294 else if (MMX_REG_P (r))
3299 [(set (match_operand 0 "register_operand" "")
3300 (float_extend (match_operand 1 "memory_operand" "")))]
3302 && MEM_P (operands[1])
3303 && (GET_MODE (operands[0]) == TFmode
3304 || GET_MODE (operands[0]) == XFmode
3305 || GET_MODE (operands[0]) == SFmode
3306 || GET_MODE (operands[0]) == DFmode)
3307 && (operands[2] = find_constant_src (insn))"
3308 [(set (match_dup 0) (match_dup 2))]
3310 rtx c = operands[2];
3311 rtx r = operands[0];
3313 if (GET_CODE (r) == SUBREG)
3318 if (!standard_sse_constant_p (c))
3321 else if (FP_REG_P (r))
3323 if (!standard_80387_constant_p (c))
3326 else if (MMX_REG_P (r))
3330 (define_insn "swapxf"
3331 [(set (match_operand:XF 0 "register_operand" "+f")
3332 (match_operand:XF 1 "register_operand" "+f"))
3337 if (STACK_TOP_P (operands[0]))
3342 [(set_attr "type" "fxch")
3343 (set_attr "mode" "XF")])
3345 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3347 [(set (match_operand:X87MODEF 0 "register_operand" "")
3348 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3349 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3350 && (standard_80387_constant_p (operands[1]) == 8
3351 || standard_80387_constant_p (operands[1]) == 9)"
3352 [(set (match_dup 0)(match_dup 1))
3354 (neg:X87MODEF (match_dup 0)))]
3358 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3359 if (real_isnegzero (&r))
3360 operands[1] = CONST0_RTX (<MODE>mode);
3362 operands[1] = CONST1_RTX (<MODE>mode);
3366 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3367 (match_operand:TF 1 "general_operand" ""))]
3369 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3371 "ix86_split_long_move (operands); DONE;")
3373 ;; Zero extension instructions
3375 (define_expand "zero_extendhisi2"
3376 [(set (match_operand:SI 0 "register_operand" "")
3377 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3380 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3382 operands[1] = force_reg (HImode, operands[1]);
3383 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3388 (define_insn "zero_extendhisi2_and"
3389 [(set (match_operand:SI 0 "register_operand" "=r")
3390 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3391 (clobber (reg:CC FLAGS_REG))]
3392 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3394 [(set_attr "type" "alu1")
3395 (set_attr "mode" "SI")])
3398 [(set (match_operand:SI 0 "register_operand" "")
3399 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3400 (clobber (reg:CC FLAGS_REG))]
3401 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3402 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3403 (clobber (reg:CC FLAGS_REG))])]
3406 (define_insn "*zero_extendhisi2_movzwl"
3407 [(set (match_operand:SI 0 "register_operand" "=r")
3408 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3409 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3410 "movz{wl|x}\t{%1, %0|%0, %1}"
3411 [(set_attr "type" "imovx")
3412 (set_attr "mode" "SI")])
3414 (define_expand "zero_extendqihi2"
3416 [(set (match_operand:HI 0 "register_operand" "")
3417 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3418 (clobber (reg:CC FLAGS_REG))])]
3422 (define_insn "*zero_extendqihi2_and"
3423 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3424 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3425 (clobber (reg:CC FLAGS_REG))]
3426 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3428 [(set_attr "type" "alu1")
3429 (set_attr "mode" "HI")])
3431 (define_insn "*zero_extendqihi2_movzbw_and"
3432 [(set (match_operand:HI 0 "register_operand" "=r,r")
3433 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3434 (clobber (reg:CC FLAGS_REG))]
3435 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3437 [(set_attr "type" "imovx,alu1")
3438 (set_attr "mode" "HI")])
3440 ; zero extend to SImode here to avoid partial register stalls
3441 (define_insn "*zero_extendqihi2_movzbl"
3442 [(set (match_operand:HI 0 "register_operand" "=r")
3443 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3444 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3445 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3446 [(set_attr "type" "imovx")
3447 (set_attr "mode" "SI")])
3449 ;; For the movzbw case strip only the clobber
3451 [(set (match_operand:HI 0 "register_operand" "")
3452 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3453 (clobber (reg:CC FLAGS_REG))]
3455 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3456 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3457 [(set (match_operand:HI 0 "register_operand" "")
3458 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3460 ;; When source and destination does not overlap, clear destination
3461 ;; first and then do the movb
3463 [(set (match_operand:HI 0 "register_operand" "")
3464 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3465 (clobber (reg:CC FLAGS_REG))]
3467 && ANY_QI_REG_P (operands[0])
3468 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3469 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3470 [(set (match_dup 0) (const_int 0))
3471 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3472 "operands[2] = gen_lowpart (QImode, operands[0]);")
3474 ;; Rest is handled by single and.
3476 [(set (match_operand:HI 0 "register_operand" "")
3477 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3478 (clobber (reg:CC FLAGS_REG))]
3480 && true_regnum (operands[0]) == true_regnum (operands[1])"
3481 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3482 (clobber (reg:CC FLAGS_REG))])]
3485 (define_expand "zero_extendqisi2"
3487 [(set (match_operand:SI 0 "register_operand" "")
3488 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3489 (clobber (reg:CC FLAGS_REG))])]
3493 (define_insn "*zero_extendqisi2_and"
3494 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3495 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3496 (clobber (reg:CC FLAGS_REG))]
3497 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3499 [(set_attr "type" "alu1")
3500 (set_attr "mode" "SI")])
3502 (define_insn "*zero_extendqisi2_movzbw_and"
3503 [(set (match_operand:SI 0 "register_operand" "=r,r")
3504 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3505 (clobber (reg:CC FLAGS_REG))]
3506 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3508 [(set_attr "type" "imovx,alu1")
3509 (set_attr "mode" "SI")])
3511 (define_insn "*zero_extendqisi2_movzbw"
3512 [(set (match_operand:SI 0 "register_operand" "=r")
3513 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3514 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3515 "movz{bl|x}\t{%1, %0|%0, %1}"
3516 [(set_attr "type" "imovx")
3517 (set_attr "mode" "SI")])
3519 ;; For the movzbl case strip only the clobber
3521 [(set (match_operand:SI 0 "register_operand" "")
3522 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3523 (clobber (reg:CC FLAGS_REG))]
3525 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3526 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3528 (zero_extend:SI (match_dup 1)))])
3530 ;; When source and destination does not overlap, clear destination
3531 ;; first and then do the movb
3533 [(set (match_operand:SI 0 "register_operand" "")
3534 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3535 (clobber (reg:CC FLAGS_REG))]
3537 && ANY_QI_REG_P (operands[0])
3538 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3539 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3540 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3541 [(set (match_dup 0) (const_int 0))
3542 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3543 "operands[2] = gen_lowpart (QImode, operands[0]);")
3545 ;; Rest is handled by single and.
3547 [(set (match_operand:SI 0 "register_operand" "")
3548 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3549 (clobber (reg:CC FLAGS_REG))]
3551 && true_regnum (operands[0]) == true_regnum (operands[1])"
3552 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3553 (clobber (reg:CC FLAGS_REG))])]
3556 ;; %%% Kill me once multi-word ops are sane.
3557 (define_expand "zero_extendsidi2"
3558 [(set (match_operand:DI 0 "register_operand" "")
3559 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3564 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3569 (define_insn "zero_extendsidi2_32"
3570 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3572 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3573 (clobber (reg:CC FLAGS_REG))]
3579 movd\t{%1, %0|%0, %1}
3580 movd\t{%1, %0|%0, %1}
3581 movd\t{%1, %0|%0, %1}
3582 movd\t{%1, %0|%0, %1}"
3583 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3584 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3586 (define_insn "zero_extendsidi2_rex64"
3587 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3589 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3592 mov\t{%k1, %k0|%k0, %k1}
3594 movd\t{%1, %0|%0, %1}
3595 movd\t{%1, %0|%0, %1}
3596 movd\t{%1, %0|%0, %1}
3597 movd\t{%1, %0|%0, %1}"
3598 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3599 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3602 [(set (match_operand:DI 0 "memory_operand" "")
3603 (zero_extend:DI (match_dup 0)))]
3605 [(set (match_dup 4) (const_int 0))]
3606 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3609 [(set (match_operand:DI 0 "register_operand" "")
3610 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3611 (clobber (reg:CC FLAGS_REG))]
3612 "!TARGET_64BIT && reload_completed
3613 && true_regnum (operands[0]) == true_regnum (operands[1])"
3614 [(set (match_dup 4) (const_int 0))]
3615 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3618 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3619 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3620 (clobber (reg:CC FLAGS_REG))]
3621 "!TARGET_64BIT && reload_completed
3622 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3623 [(set (match_dup 3) (match_dup 1))
3624 (set (match_dup 4) (const_int 0))]
3625 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3627 (define_insn "zero_extendhidi2"
3628 [(set (match_operand:DI 0 "register_operand" "=r")
3629 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3631 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3632 [(set_attr "type" "imovx")
3633 (set_attr "mode" "DI")])
3635 (define_insn "zero_extendqidi2"
3636 [(set (match_operand:DI 0 "register_operand" "=r")
3637 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3639 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3640 [(set_attr "type" "imovx")
3641 (set_attr "mode" "DI")])
3643 ;; Sign extension instructions
3645 (define_expand "extendsidi2"
3646 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3647 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3648 (clobber (reg:CC FLAGS_REG))
3649 (clobber (match_scratch:SI 2 ""))])]
3654 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3659 (define_insn "*extendsidi2_1"
3660 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3661 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3662 (clobber (reg:CC FLAGS_REG))
3663 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3667 (define_insn "extendsidi2_rex64"
3668 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3669 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3673 movs{lq|x}\t{%1,%0|%0, %1}"
3674 [(set_attr "type" "imovx")
3675 (set_attr "mode" "DI")
3676 (set_attr "prefix_0f" "0")
3677 (set_attr "modrm" "0,1")])
3679 (define_insn "extendhidi2"
3680 [(set (match_operand:DI 0 "register_operand" "=r")
3681 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3683 "movs{wq|x}\t{%1,%0|%0, %1}"
3684 [(set_attr "type" "imovx")
3685 (set_attr "mode" "DI")])
3687 (define_insn "extendqidi2"
3688 [(set (match_operand:DI 0 "register_operand" "=r")
3689 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3691 "movs{bq|x}\t{%1,%0|%0, %1}"
3692 [(set_attr "type" "imovx")
3693 (set_attr "mode" "DI")])
3695 ;; Extend to memory case when source register does die.
3697 [(set (match_operand:DI 0 "memory_operand" "")
3698 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3699 (clobber (reg:CC FLAGS_REG))
3700 (clobber (match_operand:SI 2 "register_operand" ""))]
3702 && dead_or_set_p (insn, operands[1])
3703 && !reg_mentioned_p (operands[1], operands[0]))"
3704 [(set (match_dup 3) (match_dup 1))
3705 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3706 (clobber (reg:CC FLAGS_REG))])
3707 (set (match_dup 4) (match_dup 1))]
3708 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3710 ;; Extend to memory case when source register does not die.
3712 [(set (match_operand:DI 0 "memory_operand" "")
3713 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3714 (clobber (reg:CC FLAGS_REG))
3715 (clobber (match_operand:SI 2 "register_operand" ""))]
3719 split_di (&operands[0], 1, &operands[3], &operands[4]);
3721 emit_move_insn (operands[3], operands[1]);
3723 /* Generate a cltd if possible and doing so it profitable. */
3724 if ((optimize_size || TARGET_USE_CLTD)
3725 && true_regnum (operands[1]) == AX_REG
3726 && true_regnum (operands[2]) == DX_REG)
3728 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3732 emit_move_insn (operands[2], operands[1]);
3733 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3735 emit_move_insn (operands[4], operands[2]);
3739 ;; Extend to register case. Optimize case where source and destination
3740 ;; registers match and cases where we can use cltd.
3742 [(set (match_operand:DI 0 "register_operand" "")
3743 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3744 (clobber (reg:CC FLAGS_REG))
3745 (clobber (match_scratch:SI 2 ""))]
3749 split_di (&operands[0], 1, &operands[3], &operands[4]);
3751 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3752 emit_move_insn (operands[3], operands[1]);
3754 /* Generate a cltd if possible and doing so it profitable. */
3755 if ((optimize_size || TARGET_USE_CLTD)
3756 && true_regnum (operands[3]) == AX_REG)
3758 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3762 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3763 emit_move_insn (operands[4], operands[1]);
3765 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3769 (define_insn "extendhisi2"
3770 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3771 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3774 switch (get_attr_prefix_0f (insn))
3777 return "{cwtl|cwde}";
3779 return "movs{wl|x}\t{%1,%0|%0, %1}";
3782 [(set_attr "type" "imovx")
3783 (set_attr "mode" "SI")
3784 (set (attr "prefix_0f")
3785 ;; movsx is short decodable while cwtl is vector decoded.
3786 (if_then_else (and (eq_attr "cpu" "!k6")
3787 (eq_attr "alternative" "0"))
3789 (const_string "1")))
3791 (if_then_else (eq_attr "prefix_0f" "0")
3793 (const_string "1")))])
3795 (define_insn "*extendhisi2_zext"
3796 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3798 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3801 switch (get_attr_prefix_0f (insn))
3804 return "{cwtl|cwde}";
3806 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3809 [(set_attr "type" "imovx")
3810 (set_attr "mode" "SI")
3811 (set (attr "prefix_0f")
3812 ;; movsx is short decodable while cwtl is vector decoded.
3813 (if_then_else (and (eq_attr "cpu" "!k6")
3814 (eq_attr "alternative" "0"))
3816 (const_string "1")))
3818 (if_then_else (eq_attr "prefix_0f" "0")
3820 (const_string "1")))])
3822 (define_insn "extendqihi2"
3823 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3824 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3827 switch (get_attr_prefix_0f (insn))
3830 return "{cbtw|cbw}";
3832 return "movs{bw|x}\t{%1,%0|%0, %1}";
3835 [(set_attr "type" "imovx")
3836 (set_attr "mode" "HI")
3837 (set (attr "prefix_0f")
3838 ;; movsx is short decodable while cwtl is vector decoded.
3839 (if_then_else (and (eq_attr "cpu" "!k6")
3840 (eq_attr "alternative" "0"))
3842 (const_string "1")))
3844 (if_then_else (eq_attr "prefix_0f" "0")
3846 (const_string "1")))])
3848 (define_insn "extendqisi2"
3849 [(set (match_operand:SI 0 "register_operand" "=r")
3850 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3852 "movs{bl|x}\t{%1,%0|%0, %1}"
3853 [(set_attr "type" "imovx")
3854 (set_attr "mode" "SI")])
3856 (define_insn "*extendqisi2_zext"
3857 [(set (match_operand:DI 0 "register_operand" "=r")
3859 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3861 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3862 [(set_attr "type" "imovx")
3863 (set_attr "mode" "SI")])
3865 ;; Conversions between float and double.
3867 ;; These are all no-ops in the model used for the 80387. So just
3870 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3871 (define_insn "*dummy_extendsfdf2"
3872 [(set (match_operand:DF 0 "push_operand" "=<")
3873 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3878 [(set (match_operand:DF 0 "push_operand" "")
3879 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3881 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3882 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3885 [(set (match_operand:DF 0 "push_operand" "")
3886 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3888 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3889 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3891 (define_insn "*dummy_extendsfxf2"
3892 [(set (match_operand:XF 0 "push_operand" "=<")
3893 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3898 [(set (match_operand:XF 0 "push_operand" "")
3899 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3901 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3902 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3903 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3906 [(set (match_operand:XF 0 "push_operand" "")
3907 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3909 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3910 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3911 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3914 [(set (match_operand:XF 0 "push_operand" "")
3915 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3917 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3918 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3919 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3922 [(set (match_operand:XF 0 "push_operand" "")
3923 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3925 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3926 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3927 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3929 (define_expand "extendsfdf2"
3930 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3931 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3932 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3934 /* ??? Needed for compress_float_constant since all fp constants
3935 are LEGITIMATE_CONSTANT_P. */
3936 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3938 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3939 && standard_80387_constant_p (operands[1]) > 0)
3941 operands[1] = simplify_const_unary_operation
3942 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3943 emit_move_insn_1 (operands[0], operands[1]);
3946 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3950 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3952 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3954 We do the conversion post reload to avoid producing of 128bit spills
3955 that might lead to ICE on 32bit target. The sequence unlikely combine
3958 [(set (match_operand:DF 0 "register_operand" "")
3960 (match_operand:SF 1 "nonimmediate_operand" "")))]
3961 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3962 && reload_completed && SSE_REG_P (operands[0])"
3967 (parallel [(const_int 0) (const_int 1)]))))]
3969 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3970 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3971 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3972 Try to avoid move when unpacking can be done in source. */
3973 if (REG_P (operands[1]))
3975 /* If it is unsafe to overwrite upper half of source, we need
3976 to move to destination and unpack there. */
3977 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3978 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3979 && true_regnum (operands[0]) != true_regnum (operands[1]))
3981 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3982 emit_move_insn (tmp, operands[1]);
3985 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3986 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3989 emit_insn (gen_vec_setv4sf_0 (operands[3],
3990 CONST0_RTX (V4SFmode), operands[1]));
3993 (define_insn "*extendsfdf2_mixed"
3994 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3996 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3997 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3999 switch (which_alternative)
4003 return output_387_reg_move (insn, operands);
4006 return "cvtss2sd\t{%1, %0|%0, %1}";
4012 [(set_attr "type" "fmov,fmov,ssecvt")
4013 (set_attr "mode" "SF,XF,DF")])
4015 (define_insn "*extendsfdf2_sse"
4016 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4017 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4018 "TARGET_SSE2 && TARGET_SSE_MATH"
4019 "cvtss2sd\t{%1, %0|%0, %1}"
4020 [(set_attr "type" "ssecvt")
4021 (set_attr "mode" "DF")])
4023 (define_insn "*extendsfdf2_i387"
4024 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4025 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4027 "* return output_387_reg_move (insn, operands);"
4028 [(set_attr "type" "fmov")
4029 (set_attr "mode" "SF,XF")])
4031 (define_expand "extend<mode>xf2"
4032 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4033 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4036 /* ??? Needed for compress_float_constant since all fp constants
4037 are LEGITIMATE_CONSTANT_P. */
4038 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4040 if (standard_80387_constant_p (operands[1]) > 0)
4042 operands[1] = simplify_const_unary_operation
4043 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4044 emit_move_insn_1 (operands[0], operands[1]);
4047 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4051 (define_insn "*extend<mode>xf2_i387"
4052 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4054 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4056 "* return output_387_reg_move (insn, operands);"
4057 [(set_attr "type" "fmov")
4058 (set_attr "mode" "<MODE>,XF")])
4060 ;; %%% This seems bad bad news.
4061 ;; This cannot output into an f-reg because there is no way to be sure
4062 ;; of truncating in that case. Otherwise this is just like a simple move
4063 ;; insn. So we pretend we can output to a reg in order to get better
4064 ;; register preferencing, but we really use a stack slot.
4066 ;; Conversion from DFmode to SFmode.
4068 (define_expand "truncdfsf2"
4069 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4071 (match_operand:DF 1 "nonimmediate_operand" "")))]
4072 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4074 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4076 else if (flag_unsafe_math_optimizations)
4080 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4081 rtx temp = assign_386_stack_local (SFmode, slot);
4082 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4087 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4089 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4091 We do the conversion post reload to avoid producing of 128bit spills
4092 that might lead to ICE on 32bit target. The sequence unlikely combine
4095 [(set (match_operand:SF 0 "register_operand" "")
4097 (match_operand:DF 1 "nonimmediate_operand" "")))]
4098 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4099 && reload_completed && SSE_REG_P (operands[0])"
4102 (float_truncate:V2SF
4106 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4107 operands[3] = CONST0_RTX (V2SFmode);
4108 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4109 /* Use movsd for loading from memory, unpcklpd for registers.
4110 Try to avoid move when unpacking can be done in source, or SSE3
4111 movddup is available. */
4112 if (REG_P (operands[1]))
4115 && true_regnum (operands[0]) != true_regnum (operands[1])
4116 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4117 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4119 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4120 emit_move_insn (tmp, operands[1]);
4123 else if (!TARGET_SSE3)
4124 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4125 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4128 emit_insn (gen_sse2_loadlpd (operands[4],
4129 CONST0_RTX (V2DFmode), operands[1]));
4132 (define_expand "truncdfsf2_with_temp"
4133 [(parallel [(set (match_operand:SF 0 "" "")
4134 (float_truncate:SF (match_operand:DF 1 "" "")))
4135 (clobber (match_operand:SF 2 "" ""))])]
4138 (define_insn "*truncdfsf_fast_mixed"
4139 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4141 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4142 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4144 switch (which_alternative)
4148 return output_387_reg_move (insn, operands);
4150 return "cvtsd2ss\t{%1, %0|%0, %1}";
4155 [(set_attr "type" "fmov,fmov,ssecvt")
4156 (set_attr "mode" "SF")])
4158 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4159 ;; because nothing we do here is unsafe.
4160 (define_insn "*truncdfsf_fast_sse"
4161 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4163 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4164 "TARGET_SSE2 && TARGET_SSE_MATH"
4165 "cvtsd2ss\t{%1, %0|%0, %1}"
4166 [(set_attr "type" "ssecvt")
4167 (set_attr "mode" "SF")])
4169 (define_insn "*truncdfsf_fast_i387"
4170 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4172 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4173 "TARGET_80387 && flag_unsafe_math_optimizations"
4174 "* return output_387_reg_move (insn, operands);"
4175 [(set_attr "type" "fmov")
4176 (set_attr "mode" "SF")])
4178 (define_insn "*truncdfsf_mixed"
4179 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4181 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4182 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4183 "TARGET_MIX_SSE_I387"
4185 switch (which_alternative)
4188 return output_387_reg_move (insn, operands);
4193 return "cvtsd2ss\t{%1, %0|%0, %1}";
4198 [(set_attr "type" "fmov,multi,ssecvt")
4199 (set_attr "unit" "*,i387,*")
4200 (set_attr "mode" "SF")])
4202 (define_insn "*truncdfsf_i387"
4203 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4205 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4206 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4209 switch (which_alternative)
4212 return output_387_reg_move (insn, operands);
4220 [(set_attr "type" "fmov,multi")
4221 (set_attr "unit" "*,i387")
4222 (set_attr "mode" "SF")])
4224 (define_insn "*truncdfsf2_i387_1"
4225 [(set (match_operand:SF 0 "memory_operand" "=m")
4227 (match_operand:DF 1 "register_operand" "f")))]
4229 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4230 && !TARGET_MIX_SSE_I387"
4231 "* return output_387_reg_move (insn, operands);"
4232 [(set_attr "type" "fmov")
4233 (set_attr "mode" "SF")])
4236 [(set (match_operand:SF 0 "register_operand" "")
4238 (match_operand:DF 1 "fp_register_operand" "")))
4239 (clobber (match_operand 2 "" ""))]
4241 [(set (match_dup 2) (match_dup 1))
4242 (set (match_dup 0) (match_dup 2))]
4244 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4247 ;; Conversion from XFmode to {SF,DF}mode
4249 (define_expand "truncxf<mode>2"
4250 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4251 (float_truncate:MODEF
4252 (match_operand:XF 1 "register_operand" "")))
4253 (clobber (match_dup 2))])]
4256 if (flag_unsafe_math_optimizations)
4258 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4259 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4260 if (reg != operands[0])
4261 emit_move_insn (operands[0], reg);
4266 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4267 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4271 (define_insn "*truncxfsf2_mixed"
4272 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4274 (match_operand:XF 1 "register_operand" "f,f")))
4275 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4278 gcc_assert (!which_alternative);
4279 return output_387_reg_move (insn, operands);
4281 [(set_attr "type" "fmov,multi")
4282 (set_attr "unit" "*,i387")
4283 (set_attr "mode" "SF")])
4285 (define_insn "*truncxfdf2_mixed"
4286 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4288 (match_operand:XF 1 "register_operand" "f,f")))
4289 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4292 gcc_assert (!which_alternative);
4293 return output_387_reg_move (insn, operands);
4295 [(set_attr "type" "fmov,multi")
4296 (set_attr "unit" "*,i387")
4297 (set_attr "mode" "DF")])
4299 (define_insn "truncxf<mode>2_i387_noop"
4300 [(set (match_operand:MODEF 0 "register_operand" "=f")
4301 (float_truncate:MODEF
4302 (match_operand:XF 1 "register_operand" "f")))]
4303 "TARGET_80387 && flag_unsafe_math_optimizations"
4304 "* return output_387_reg_move (insn, operands);"
4305 [(set_attr "type" "fmov")
4306 (set_attr "mode" "<MODE>")])
4308 (define_insn "*truncxf<mode>2_i387"
4309 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4310 (float_truncate:MODEF
4311 (match_operand:XF 1 "register_operand" "f")))]
4313 "* return output_387_reg_move (insn, operands);"
4314 [(set_attr "type" "fmov")
4315 (set_attr "mode" "<MODE>")])
4318 [(set (match_operand:MODEF 0 "register_operand" "")
4319 (float_truncate:MODEF
4320 (match_operand:XF 1 "register_operand" "")))
4321 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4322 "TARGET_80387 && reload_completed"
4323 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4324 (set (match_dup 0) (match_dup 2))]
4328 [(set (match_operand:MODEF 0 "memory_operand" "")
4329 (float_truncate:MODEF
4330 (match_operand:XF 1 "register_operand" "")))
4331 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4333 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4336 ;; Signed conversion to DImode.
4338 (define_expand "fix_truncxfdi2"
4339 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4340 (fix:DI (match_operand:XF 1 "register_operand" "")))
4341 (clobber (reg:CC FLAGS_REG))])]
4346 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4351 (define_expand "fix_trunc<mode>di2"
4352 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4353 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4354 (clobber (reg:CC FLAGS_REG))])]
4355 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4358 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4360 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4363 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4365 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4366 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4367 if (out != operands[0])
4368 emit_move_insn (operands[0], out);
4373 ;; Signed conversion to SImode.
4375 (define_expand "fix_truncxfsi2"
4376 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4377 (fix:SI (match_operand:XF 1 "register_operand" "")))
4378 (clobber (reg:CC FLAGS_REG))])]
4383 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4388 (define_expand "fix_trunc<mode>si2"
4389 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4390 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4391 (clobber (reg:CC FLAGS_REG))])]
4392 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4395 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4397 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4400 if (SSE_FLOAT_MODE_P (<MODE>mode))
4402 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4403 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4404 if (out != operands[0])
4405 emit_move_insn (operands[0], out);
4410 ;; Signed conversion to HImode.
4412 (define_expand "fix_trunc<mode>hi2"
4413 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4414 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4415 (clobber (reg:CC FLAGS_REG))])]
4417 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4421 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4426 ;; Unsigned conversion to SImode.
4428 (define_expand "fixuns_trunc<mode>si2"
4430 [(set (match_operand:SI 0 "register_operand" "")
4432 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4434 (clobber (match_scratch:<ssevecmode> 3 ""))
4435 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4436 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4438 enum machine_mode mode = <MODE>mode;
4439 enum machine_mode vecmode = <ssevecmode>mode;
4440 REAL_VALUE_TYPE TWO31r;
4443 real_ldexp (&TWO31r, &dconst1, 31);
4444 two31 = const_double_from_real_value (TWO31r, mode);
4445 two31 = ix86_build_const_vector (mode, true, two31);
4446 operands[2] = force_reg (vecmode, two31);
4449 (define_insn_and_split "*fixuns_trunc<mode>_1"
4450 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4452 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4453 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4454 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4455 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4456 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4458 "&& reload_completed"
4461 ix86_split_convert_uns_si_sse (operands);
4465 ;; Unsigned conversion to HImode.
4466 ;; Without these patterns, we'll try the unsigned SI conversion which
4467 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4469 (define_expand "fixuns_trunc<mode>hi2"
4471 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4472 (set (match_operand:HI 0 "nonimmediate_operand" "")
4473 (subreg:HI (match_dup 2) 0))]
4474 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4475 "operands[2] = gen_reg_rtx (SImode);")
4477 ;; When SSE is available, it is always faster to use it!
4478 (define_insn "fix_trunc<mode>di_sse"
4479 [(set (match_operand:DI 0 "register_operand" "=r,r")
4480 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4481 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4482 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4483 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4484 [(set_attr "type" "sseicvt")
4485 (set_attr "mode" "<MODE>")
4486 (set_attr "athlon_decode" "double,vector")
4487 (set_attr "amdfam10_decode" "double,double")])
4489 (define_insn "fix_trunc<mode>si_sse"
4490 [(set (match_operand:SI 0 "register_operand" "=r,r")
4491 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4492 "SSE_FLOAT_MODE_P (<MODE>mode)
4493 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4494 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4495 [(set_attr "type" "sseicvt")
4496 (set_attr "mode" "<MODE>")
4497 (set_attr "athlon_decode" "double,vector")
4498 (set_attr "amdfam10_decode" "double,double")])
4500 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4502 [(set (match_operand:MODEF 0 "register_operand" "")
4503 (match_operand:MODEF 1 "memory_operand" ""))
4504 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4505 (fix:SSEMODEI24 (match_dup 0)))]
4506 "TARGET_SHORTEN_X87_SSE
4507 && peep2_reg_dead_p (2, operands[0])"
4508 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4511 ;; Avoid vector decoded forms of the instruction.
4513 [(match_scratch:DF 2 "Y2")
4514 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4515 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4516 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4517 [(set (match_dup 2) (match_dup 1))
4518 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4522 [(match_scratch:SF 2 "x")
4523 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4524 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4525 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4526 [(set (match_dup 2) (match_dup 1))
4527 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4530 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4531 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4532 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4533 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4535 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4536 && (TARGET_64BIT || <MODE>mode != DImode))
4538 && !(reload_completed || reload_in_progress)"
4543 if (memory_operand (operands[0], VOIDmode))
4544 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4547 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4548 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4554 [(set_attr "type" "fisttp")
4555 (set_attr "mode" "<MODE>")])
4557 (define_insn "fix_trunc<mode>_i387_fisttp"
4558 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4559 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4560 (clobber (match_scratch:XF 2 "=&1f"))]
4561 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4563 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && (TARGET_64BIT || <MODE>mode != DImode))
4565 && TARGET_SSE_MATH)"
4566 "* return output_fix_trunc (insn, operands, 1);"
4567 [(set_attr "type" "fisttp")
4568 (set_attr "mode" "<MODE>")])
4570 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4571 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4572 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4573 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4574 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4575 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4577 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4578 && (TARGET_64BIT || <MODE>mode != DImode))
4579 && TARGET_SSE_MATH)"
4581 [(set_attr "type" "fisttp")
4582 (set_attr "mode" "<MODE>")])
4585 [(set (match_operand:X87MODEI 0 "register_operand" "")
4586 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4587 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4588 (clobber (match_scratch 3 ""))]
4590 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4591 (clobber (match_dup 3))])
4592 (set (match_dup 0) (match_dup 2))]
4596 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4597 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4598 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4599 (clobber (match_scratch 3 ""))]
4601 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4602 (clobber (match_dup 3))])]
4605 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4606 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4607 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4608 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4609 ;; function in i386.c.
4610 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4611 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4612 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4613 (clobber (reg:CC FLAGS_REG))]
4614 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4617 && (TARGET_64BIT || <MODE>mode != DImode))
4618 && !(reload_completed || reload_in_progress)"
4623 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4625 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4626 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4627 if (memory_operand (operands[0], VOIDmode))
4628 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4629 operands[2], operands[3]));
4632 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4633 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4634 operands[2], operands[3],
4639 [(set_attr "type" "fistp")
4640 (set_attr "i387_cw" "trunc")
4641 (set_attr "mode" "<MODE>")])
4643 (define_insn "fix_truncdi_i387"
4644 [(set (match_operand:DI 0 "memory_operand" "=m")
4645 (fix:DI (match_operand 1 "register_operand" "f")))
4646 (use (match_operand:HI 2 "memory_operand" "m"))
4647 (use (match_operand:HI 3 "memory_operand" "m"))
4648 (clobber (match_scratch:XF 4 "=&1f"))]
4649 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4651 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4652 "* return output_fix_trunc (insn, operands, 0);"
4653 [(set_attr "type" "fistp")
4654 (set_attr "i387_cw" "trunc")
4655 (set_attr "mode" "DI")])
4657 (define_insn "fix_truncdi_i387_with_temp"
4658 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4659 (fix:DI (match_operand 1 "register_operand" "f,f")))
4660 (use (match_operand:HI 2 "memory_operand" "m,m"))
4661 (use (match_operand:HI 3 "memory_operand" "m,m"))
4662 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4663 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4664 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4666 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4668 [(set_attr "type" "fistp")
4669 (set_attr "i387_cw" "trunc")
4670 (set_attr "mode" "DI")])
4673 [(set (match_operand:DI 0 "register_operand" "")
4674 (fix:DI (match_operand 1 "register_operand" "")))
4675 (use (match_operand:HI 2 "memory_operand" ""))
4676 (use (match_operand:HI 3 "memory_operand" ""))
4677 (clobber (match_operand:DI 4 "memory_operand" ""))
4678 (clobber (match_scratch 5 ""))]
4680 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4683 (clobber (match_dup 5))])
4684 (set (match_dup 0) (match_dup 4))]
4688 [(set (match_operand:DI 0 "memory_operand" "")
4689 (fix:DI (match_operand 1 "register_operand" "")))
4690 (use (match_operand:HI 2 "memory_operand" ""))
4691 (use (match_operand:HI 3 "memory_operand" ""))
4692 (clobber (match_operand:DI 4 "memory_operand" ""))
4693 (clobber (match_scratch 5 ""))]
4695 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4698 (clobber (match_dup 5))])]
4701 (define_insn "fix_trunc<mode>_i387"
4702 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4703 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4704 (use (match_operand:HI 2 "memory_operand" "m"))
4705 (use (match_operand:HI 3 "memory_operand" "m"))]
4706 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4708 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4709 "* return output_fix_trunc (insn, operands, 0);"
4710 [(set_attr "type" "fistp")
4711 (set_attr "i387_cw" "trunc")
4712 (set_attr "mode" "<MODE>")])
4714 (define_insn "fix_trunc<mode>_i387_with_temp"
4715 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4716 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4717 (use (match_operand:HI 2 "memory_operand" "m,m"))
4718 (use (match_operand:HI 3 "memory_operand" "m,m"))
4719 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4720 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4722 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4724 [(set_attr "type" "fistp")
4725 (set_attr "i387_cw" "trunc")
4726 (set_attr "mode" "<MODE>")])
4729 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4730 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4731 (use (match_operand:HI 2 "memory_operand" ""))
4732 (use (match_operand:HI 3 "memory_operand" ""))
4733 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4735 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4737 (use (match_dup 3))])
4738 (set (match_dup 0) (match_dup 4))]
4742 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4743 (fix:X87MODEI12 (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:X87MODEI12 4 "memory_operand" ""))]
4748 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4750 (use (match_dup 3))])]
4753 (define_insn "x86_fnstcw_1"
4754 [(set (match_operand:HI 0 "memory_operand" "=m")
4755 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4758 [(set_attr "length" "2")
4759 (set_attr "mode" "HI")
4760 (set_attr "unit" "i387")])
4762 (define_insn "x86_fldcw_1"
4763 [(set (reg:HI FPCR_REG)
4764 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4767 [(set_attr "length" "2")
4768 (set_attr "mode" "HI")
4769 (set_attr "unit" "i387")
4770 (set_attr "athlon_decode" "vector")
4771 (set_attr "amdfam10_decode" "vector")])
4773 ;; Conversion between fixed point and floating point.
4775 ;; Even though we only accept memory inputs, the backend _really_
4776 ;; wants to be able to do this between registers.
4778 (define_expand "floathi<mode>2"
4779 [(set (match_operand:MODEF 0 "register_operand" "")
4780 (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4781 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4783 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4786 (gen_floatsi<mode>2 (operands[0],
4787 convert_to_mode (SImode, operands[1], 0)));
4792 (define_insn "*floathi<mode>2_i387"
4793 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4795 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4798 || TARGET_MIX_SSE_I387)"
4802 [(set_attr "type" "fmov,multi")
4803 (set_attr "mode" "<MODE>")
4804 (set_attr "unit" "*,i387")
4805 (set_attr "fp_int_src" "true")])
4807 (define_expand "floatsi<mode>2"
4808 [(set (match_operand:MODEF 0 "register_operand" "")
4809 (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4810 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4812 /* When we use vector converts, we can't have input in memory. */
4813 if (GET_MODE (operands[0]) == DFmode
4814 && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4815 && SSE_FLOAT_MODE_P (DFmode))
4816 operands[1] = force_reg (SImode, operands[1]);
4817 else if (GET_MODE (operands[0]) == SFmode
4818 && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4819 && SSE_FLOAT_MODE_P (SFmode))
4821 /* When !flag_trapping_math, we handle SImode->SFmode vector
4822 conversions same way as SImode->DFmode.
4824 For flat_trapping_math we can't safely use vector conversion without
4825 clearing upper half, otherwise precision exception might occur.
4826 However we can still generate the common sequence converting value
4827 from general register to XMM register as:
4833 because we know that movd clears the upper half.
4835 Sadly in this case we can't rely on reload moving the value to XMM
4836 register, since we need to know if upper half is OK, so we need
4837 to do reloading by hand. We force operand to memory unless target
4838 supports inter unit moves. */
4839 if (!flag_trapping_math)
4840 operands[1] = force_reg (SImode, operands[1]);
4841 else if (!MEM_P (operands[1]))
4843 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4844 rtx tmp = assign_386_stack_local (SImode, slot);
4845 emit_move_insn (tmp, operands[1]);
4849 /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4850 !TARGET_INTER_UNIT_CONVERSIONS
4851 It is necessary for the patterns to not accept nonmemory operands
4852 as we would optimize out later. */
4853 else if (!TARGET_INTER_UNIT_CONVERSIONS
4854 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4856 && !MEM_P (operands[1]))
4858 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4859 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
4860 emit_move_insn (tmp, operands[1]);
4865 (define_insn "*floatsisf2_mixed_vector"
4866 [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4867 (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4868 "TARGET_MIX_SSE_I387 && !flag_trapping_math
4869 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4871 cvtdq2ps\t{%1, %0|%0, %1}
4874 [(set_attr "type" "sseicvt,fmov,multi")
4875 (set_attr "mode" "SF")
4876 (set_attr "unit" "*,i387,*")
4877 (set_attr "athlon_decode" "double,*,*")
4878 (set_attr "amdfam10_decode" "double,*,*")
4879 (set_attr "fp_int_src" "false,true,true")])
4881 (define_insn "*floatsisf2_mixed"
4882 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4883 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4884 "TARGET_MIX_SSE_I387
4885 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4890 cvtsi2ss\t{%1, %0|%0, %1}
4891 cvtsi2ss\t{%1, %0|%0, %1}"
4892 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4893 (set_attr "mode" "SF")
4894 (set_attr "unit" "*,i387,*,*")
4895 (set_attr "athlon_decode" "*,*,vector,double")
4896 (set_attr "amdfam10_decode" "*,*,vector,double")
4897 (set_attr "fp_int_src" "true")])
4899 (define_insn "*floatsisf2_mixed_memory"
4900 [(set (match_operand:SF 0 "register_operand" "=f,x")
4901 (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4902 "TARGET_MIX_SSE_I387
4903 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4906 cvtsi2ss\t{%1, %0|%0, %1}"
4907 [(set_attr "type" "fmov,sseicvt")
4908 (set_attr "mode" "SF")
4909 (set_attr "athlon_decode" "*,double")
4910 (set_attr "amdfam10_decode" "*,double")
4911 (set_attr "fp_int_src" "true")])
4913 (define_insn "*floatsisf2_sse_vector_nointernunit"
4914 [(set (match_operand:SF 0 "register_operand" "=x")
4915 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4916 "TARGET_SSE_MATH && flag_trapping_math
4917 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4918 && !TARGET_INTER_UNIT_MOVES"
4920 [(set_attr "type" "multi")])
4922 (define_insn "*floatsisf2_sse_vector_internunit"
4923 [(set (match_operand:SF 0 "register_operand" "=x,x")
4924 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4925 "TARGET_SSE_MATH && flag_trapping_math
4926 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4927 && TARGET_INTER_UNIT_MOVES"
4929 [(set_attr "type" "multi")])
4932 [(set (match_operand:SF 0 "register_operand" "")
4933 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4935 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4936 && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4937 && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4939 (float:V4SF (match_dup 2)))]
4941 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4942 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4943 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4947 [(set (match_operand:SF 0 "register_operand" "")
4948 (float:SF (match_operand:SI 1 "register_operand" "")))]
4950 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4951 && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4952 [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4954 (float:V4SF (match_dup 2)))]
4956 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4957 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4960 (define_insn "*floatsisf2_sse_vector"
4961 [(set (match_operand:SF 0 "register_operand" "=x")
4962 (float:SF (match_operand:SI 1 "register_operand" "x")))]
4963 "TARGET_SSE_MATH && !flag_trapping_math
4964 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4965 && !TARGET_INTER_UNIT_MOVES"
4966 "cvtdq2ps\t{%1, %0|%0, %1}"
4967 [(set_attr "type" "sseicvt")
4968 (set_attr "mode" "SF")
4969 (set_attr "athlon_decode" "double")
4970 (set_attr "amdfam10_decode" "double")
4971 (set_attr "fp_int_src" "true")])
4973 (define_insn "*floatsisf2_sse"
4974 [(set (match_operand:SF 0 "register_operand" "=x,x")
4975 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4977 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4979 "cvtsi2ss\t{%1, %0|%0, %1}"
4980 [(set_attr "type" "sseicvt")
4981 (set_attr "mode" "SF")
4982 (set_attr "athlon_decode" "vector,double")
4983 (set_attr "amdfam10_decode" "vector,double")
4984 (set_attr "fp_int_src" "true")])
4986 (define_insn "*floatsisf2_sse_memory"
4987 [(set (match_operand:SF 0 "register_operand" "=x")
4988 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4990 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4991 "cvtsi2ss\t{%1, %0|%0, %1}"
4992 [(set_attr "type" "sseicvt")
4993 (set_attr "mode" "SF")
4994 (set_attr "athlon_decode" "double")
4995 (set_attr "amdfam10_decode" "double")
4996 (set_attr "fp_int_src" "true")])
4998 (define_insn "*floatsidf2_mixed_vector"
4999 [(set (match_operand:DF 0 "register_operand" "=x,f,f")
5000 (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
5001 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5002 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5004 cvtdq2pd\t{%1, %0|%0, %1}
5007 [(set_attr "type" "sseicvt,fmov,multi")
5008 (set_attr "mode" "V2DF,DF,DF")
5009 (set_attr "unit" "*,*,i387")
5010 (set_attr "athlon_decode" "double,*,*")
5011 (set_attr "amdfam10_decode" "double,*,*")
5012 (set_attr "fp_int_src" "false,true,true")])
5014 (define_insn "*floatsidf2_mixed"
5015 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5016 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5017 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5018 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5023 cvtsi2sd\t{%1, %0|%0, %1}
5024 cvtsi2sd\t{%1, %0|%0, %1}
5025 cvtdq2pd\t{%1, %0|%0, %1}"
5026 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5027 (set_attr "mode" "DF,DF,DF,DF,V2DF")
5028 (set_attr "unit" "*,i387,*,*,*")
5029 (set_attr "athlon_decode" "*,*,double,direct,double")
5030 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5031 (set_attr "fp_int_src" "true,true,true,true,false")])
5033 (define_insn "*floatsidf2_mixed_memory"
5034 [(set (match_operand:DF 0 "register_operand" "=f,x")
5035 (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5036 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5037 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5040 cvtsi2sd\t{%1, %0|%0, %1}"
5041 [(set_attr "type" "fmov,sseicvt")
5042 (set_attr "mode" "DF")
5043 (set_attr "athlon_decode" "*,direct")
5044 (set_attr "amdfam10_decode" "*,double")
5045 (set_attr "fp_int_src" "true")])
5047 (define_insn "*floatsidf2_sse_vector"
5048 [(set (match_operand:DF 0 "register_operand" "=x")
5049 (float:DF (match_operand:SI 1 "register_operand" "x")))]
5050 "TARGET_SSE2 && TARGET_SSE_MATH
5051 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5052 "cvtdq2pd\t{%1, %0|%0, %1}"
5053 [(set_attr "type" "sseicvt")
5054 (set_attr "mode" "V2DF")
5055 (set_attr "athlon_decode" "double")
5056 (set_attr "amdfam10_decode" "double")
5057 (set_attr "fp_int_src" "true")])
5060 [(set (match_operand:DF 0 "register_operand" "")
5061 (float:DF (match_operand:SI 1 "memory_operand" "")))]
5062 "TARGET_USE_VECTOR_CONVERTS && reload_completed
5063 && SSE_REG_P (operands[0])"
5068 (parallel [(const_int 0) (const_int 1)]))))]
5070 operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5071 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5072 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5075 (define_insn "*floatsidf2_sse"
5076 [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5077 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5078 "TARGET_SSE2 && TARGET_SSE_MATH
5079 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5082 cvtsi2sd\t{%1, %0|%0, %1}
5083 cvtsi2sd\t{%1, %0|%0, %1}
5084 cvtdq2pd\t{%1, %0|%0, %1}"
5085 [(set_attr "type" "sseicvt")
5086 (set_attr "mode" "DF,DF,V2DF")
5087 (set_attr "athlon_decode" "double,direct,double")
5088 (set_attr "amdfam10_decode" "vector,double,double")
5089 (set_attr "fp_int_src" "true")])
5091 (define_insn "*floatsidf2_memory"
5092 [(set (match_operand:DF 0 "register_operand" "=x")
5093 (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5094 "TARGET_SSE2 && TARGET_SSE_MATH
5095 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5097 "cvtsi2sd\t{%1, %0|%0, %1}"
5098 [(set_attr "type" "sseicvt")
5099 (set_attr "mode" "DF")
5100 (set_attr "athlon_decode" "direct")
5101 (set_attr "amdfam10_decode" "double")
5102 (set_attr "fp_int_src" "true")])
5104 (define_insn "*floatsi<mode>2_i387"
5105 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5107 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5109 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5113 [(set_attr "type" "fmov,multi")
5114 (set_attr "mode" "<MODE>")
5115 (set_attr "unit" "*,i387")
5116 (set_attr "fp_int_src" "true")])
5118 (define_expand "floatdisf2"
5119 [(set (match_operand:SF 0 "register_operand" "")
5120 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5121 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5123 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5124 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5126 && !MEM_P (operands[1]))
5128 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5129 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5130 emit_move_insn (tmp, operands[1]);
5135 (define_insn "*floatdisf2_mixed"
5136 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5137 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5138 "TARGET_64BIT && TARGET_MIX_SSE_I387
5139 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5143 cvtsi2ss{q}\t{%1, %0|%0, %1}
5144 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5145 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5146 (set_attr "mode" "SF")
5147 (set_attr "unit" "*,i387,*,*")
5148 (set_attr "athlon_decode" "*,*,vector,double")
5149 (set_attr "amdfam10_decode" "*,*,vector,double")
5150 (set_attr "fp_int_src" "true")])
5152 (define_insn "*floatdisf2_mixed"
5153 [(set (match_operand:SF 0 "register_operand" "=f,x")
5154 (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5155 "TARGET_64BIT && TARGET_MIX_SSE_I387
5156 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5159 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5160 [(set_attr "type" "fmov,sseicvt")
5161 (set_attr "mode" "SF")
5162 (set_attr "athlon_decode" "*,double")
5163 (set_attr "amdfam10_decode" "*,double")
5164 (set_attr "fp_int_src" "true")])
5166 (define_insn "*floatdisf2_sse"
5167 [(set (match_operand:SF 0 "register_operand" "=x,x")
5168 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5169 "TARGET_64BIT && TARGET_SSE_MATH
5170 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5171 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5172 [(set_attr "type" "sseicvt")
5173 (set_attr "mode" "SF")
5174 (set_attr "athlon_decode" "vector,double")
5175 (set_attr "amdfam10_decode" "vector,double")
5176 (set_attr "fp_int_src" "true")])
5178 (define_insn "*floatdisf2_memory"
5179 [(set (match_operand:SF 0 "register_operand" "=x")
5180 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5181 "TARGET_64BIT && TARGET_SSE_MATH
5182 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5183 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5184 [(set_attr "type" "sseicvt")
5185 (set_attr "mode" "SF")
5186 (set_attr "athlon_decode" "double")
5187 (set_attr "amdfam10_decode" "double")
5188 (set_attr "fp_int_src" "true")])
5190 (define_expand "floatdidf2"
5191 [(set (match_operand:DF 0 "register_operand" "")
5192 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5193 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5195 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5197 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5200 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5201 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5203 && !MEM_P (operands[1]))
5205 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5206 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5207 emit_move_insn (tmp, operands[1]);
5212 (define_insn "*floatdidf2_mixed"
5213 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5214 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5215 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5216 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5220 cvtsi2sd{q}\t{%1, %0|%0, %1}
5221 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5222 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5223 (set_attr "mode" "DF")
5224 (set_attr "unit" "*,i387,*,*")
5225 (set_attr "athlon_decode" "*,*,double,direct")
5226 (set_attr "amdfam10_decode" "*,*,vector,double")
5227 (set_attr "fp_int_src" "true")])
5229 (define_insn "*floatdidf2_mixed_memory"
5230 [(set (match_operand:DF 0 "register_operand" "=f,x")
5231 (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5232 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5233 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5236 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5237 [(set_attr "type" "fmov,sseicvt")
5238 (set_attr "mode" "DF")
5239 (set_attr "athlon_decode" "*,direct")
5240 (set_attr "amdfam10_decode" "*,double")
5241 (set_attr "fp_int_src" "true")])
5243 (define_insn "*floatdidf2_sse"
5244 [(set (match_operand:DF 0 "register_operand" "=x,x")
5245 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5246 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5247 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5248 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5249 [(set_attr "type" "sseicvt")
5250 (set_attr "mode" "DF")
5251 (set_attr "athlon_decode" "double,direct")
5252 (set_attr "amdfam10_decode" "vector,double")
5253 (set_attr "fp_int_src" "true")])
5255 (define_insn "*floatdidf2_sse_memory"
5256 [(set (match_operand:DF 0 "register_operand" "=x")
5257 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5258 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5259 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5260 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5261 [(set_attr "type" "sseicvt")
5262 (set_attr "mode" "DF")
5263 (set_attr "athlon_decode" "direct")
5264 (set_attr "amdfam10_decode" "double")
5265 (set_attr "fp_int_src" "true")])
5267 (define_insn "*floatdi<mode>2_i387"
5268 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5270 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5272 && (!TARGET_SSE_MATH || !TARGET_64BIT
5273 || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5277 [(set_attr "type" "fmov,multi")
5278 (set_attr "mode" "<MODE>")
5279 (set_attr "unit" "*,i387")
5280 (set_attr "fp_int_src" "true")])
5282 (define_insn "float<mode>xf2"
5283 [(set (match_operand:XF 0 "register_operand" "=f,f")
5284 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5289 [(set_attr "type" "fmov,multi")
5290 (set_attr "mode" "XF")
5291 (set_attr "unit" "*,i387")
5292 (set_attr "fp_int_src" "true")])
5294 ;; %%% Kill these when reload knows how to do it.
5296 [(set (match_operand 0 "fp_register_operand" "")
5297 (float (match_operand 1 "register_operand" "")))]
5299 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5302 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5303 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5304 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5305 ix86_free_from_memory (GET_MODE (operands[1]));
5309 (define_expand "floatunssi<mode>2"
5310 [(use (match_operand:MODEF 0 "register_operand" ""))
5311 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5312 "!TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5314 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5318 (define_expand "floatunsdisf2"
5319 [(use (match_operand:SF 0 "register_operand" ""))
5320 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5321 "TARGET_64BIT && TARGET_SSE_MATH"
5322 "x86_emit_floatuns (operands); DONE;")
5324 (define_expand "floatunsdidf2"
5325 [(use (match_operand:DF 0 "register_operand" ""))
5326 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5327 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5328 && TARGET_SSE2 && TARGET_SSE_MATH"
5331 x86_emit_floatuns (operands);
5333 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5339 ;; %%% splits for addditi3
5341 (define_expand "addti3"
5342 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5343 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5344 (match_operand:TI 2 "x86_64_general_operand" "")))
5345 (clobber (reg:CC FLAGS_REG))]
5347 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5349 (define_insn "*addti3_1"
5350 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5351 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5352 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5353 (clobber (reg:CC FLAGS_REG))]
5354 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5358 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5359 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5360 (match_operand:TI 2 "x86_64_general_operand" "")))
5361 (clobber (reg:CC FLAGS_REG))]
5362 "TARGET_64BIT && reload_completed"
5363 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5365 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5366 (parallel [(set (match_dup 3)
5367 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5370 (clobber (reg:CC FLAGS_REG))])]
5371 "split_ti (operands+0, 1, operands+0, operands+3);
5372 split_ti (operands+1, 1, operands+1, operands+4);
5373 split_ti (operands+2, 1, operands+2, operands+5);")
5375 ;; %%% splits for addsidi3
5376 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5377 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5378 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5380 (define_expand "adddi3"
5381 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5382 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5383 (match_operand:DI 2 "x86_64_general_operand" "")))
5384 (clobber (reg:CC FLAGS_REG))]
5386 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5388 (define_insn "*adddi3_1"
5389 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5390 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5391 (match_operand:DI 2 "general_operand" "roiF,riF")))
5392 (clobber (reg:CC FLAGS_REG))]
5393 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5397 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5398 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5399 (match_operand:DI 2 "general_operand" "")))
5400 (clobber (reg:CC FLAGS_REG))]
5401 "!TARGET_64BIT && reload_completed"
5402 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5404 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5405 (parallel [(set (match_dup 3)
5406 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5409 (clobber (reg:CC FLAGS_REG))])]
5410 "split_di (operands+0, 1, operands+0, operands+3);
5411 split_di (operands+1, 1, operands+1, operands+4);
5412 split_di (operands+2, 1, operands+2, operands+5);")
5414 (define_insn "adddi3_carry_rex64"
5415 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5416 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5417 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5418 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5419 (clobber (reg:CC FLAGS_REG))]
5420 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5421 "adc{q}\t{%2, %0|%0, %2}"
5422 [(set_attr "type" "alu")
5423 (set_attr "pent_pair" "pu")
5424 (set_attr "mode" "DI")])
5426 (define_insn "*adddi3_cc_rex64"
5427 [(set (reg:CC FLAGS_REG)
5428 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5429 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5431 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5432 (plus:DI (match_dup 1) (match_dup 2)))]
5433 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5434 "add{q}\t{%2, %0|%0, %2}"
5435 [(set_attr "type" "alu")
5436 (set_attr "mode" "DI")])
5438 (define_insn "*<addsub><mode>3_cc_overflow"
5439 [(set (reg:CCC FLAGS_REG)
5442 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5443 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5445 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5446 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5447 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5448 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5449 [(set_attr "type" "alu")
5450 (set_attr "mode" "<MODE>")])
5452 (define_insn "*add<mode>3_cconly_overflow"
5453 [(set (reg:CCC FLAGS_REG)
5455 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5456 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5458 (clobber (match_scratch:SWI 0 "=<r>"))]
5459 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5460 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5461 [(set_attr "type" "alu")
5462 (set_attr "mode" "<MODE>")])
5464 (define_insn "*sub<mode>3_cconly_overflow"
5465 [(set (reg:CCC FLAGS_REG)
5467 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5468 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5471 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5472 [(set_attr "type" "icmp")
5473 (set_attr "mode" "<MODE>")])
5475 (define_insn "*<addsub>si3_zext_cc_overflow"
5476 [(set (reg:CCC FLAGS_REG)
5478 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5479 (match_operand:SI 2 "general_operand" "g"))
5481 (set (match_operand:DI 0 "register_operand" "=r")
5482 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5483 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5484 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5485 [(set_attr "type" "alu")
5486 (set_attr "mode" "SI")])
5488 (define_insn "addqi3_carry"
5489 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5490 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5491 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5492 (match_operand:QI 2 "general_operand" "qi,qm")))
5493 (clobber (reg:CC FLAGS_REG))]
5494 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5495 "adc{b}\t{%2, %0|%0, %2}"
5496 [(set_attr "type" "alu")
5497 (set_attr "pent_pair" "pu")
5498 (set_attr "mode" "QI")])
5500 (define_insn "addhi3_carry"
5501 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5502 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5503 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5504 (match_operand:HI 2 "general_operand" "ri,rm")))
5505 (clobber (reg:CC FLAGS_REG))]
5506 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5507 "adc{w}\t{%2, %0|%0, %2}"
5508 [(set_attr "type" "alu")
5509 (set_attr "pent_pair" "pu")
5510 (set_attr "mode" "HI")])
5512 (define_insn "addsi3_carry"
5513 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5514 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5515 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5516 (match_operand:SI 2 "general_operand" "ri,rm")))
5517 (clobber (reg:CC FLAGS_REG))]
5518 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5519 "adc{l}\t{%2, %0|%0, %2}"
5520 [(set_attr "type" "alu")
5521 (set_attr "pent_pair" "pu")
5522 (set_attr "mode" "SI")])
5524 (define_insn "*addsi3_carry_zext"
5525 [(set (match_operand:DI 0 "register_operand" "=r")
5527 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5528 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5529 (match_operand:SI 2 "general_operand" "g"))))
5530 (clobber (reg:CC FLAGS_REG))]
5531 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5532 "adc{l}\t{%2, %k0|%k0, %2}"
5533 [(set_attr "type" "alu")
5534 (set_attr "pent_pair" "pu")
5535 (set_attr "mode" "SI")])
5537 (define_insn "*addsi3_cc"
5538 [(set (reg:CC FLAGS_REG)
5539 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5540 (match_operand:SI 2 "general_operand" "ri,rm")]
5542 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5543 (plus:SI (match_dup 1) (match_dup 2)))]
5544 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5545 "add{l}\t{%2, %0|%0, %2}"
5546 [(set_attr "type" "alu")
5547 (set_attr "mode" "SI")])
5549 (define_insn "addqi3_cc"
5550 [(set (reg:CC FLAGS_REG)
5551 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5552 (match_operand:QI 2 "general_operand" "qi,qm")]
5554 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5555 (plus:QI (match_dup 1) (match_dup 2)))]
5556 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5557 "add{b}\t{%2, %0|%0, %2}"
5558 [(set_attr "type" "alu")
5559 (set_attr "mode" "QI")])
5561 (define_expand "addsi3"
5562 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5563 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5564 (match_operand:SI 2 "general_operand" "")))
5565 (clobber (reg:CC FLAGS_REG))])]
5567 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5569 (define_insn "*lea_1"
5570 [(set (match_operand:SI 0 "register_operand" "=r")
5571 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5573 "lea{l}\t{%a1, %0|%0, %a1}"
5574 [(set_attr "type" "lea")
5575 (set_attr "mode" "SI")])
5577 (define_insn "*lea_1_rex64"
5578 [(set (match_operand:SI 0 "register_operand" "=r")
5579 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5581 "lea{l}\t{%a1, %0|%0, %a1}"
5582 [(set_attr "type" "lea")
5583 (set_attr "mode" "SI")])
5585 (define_insn "*lea_1_zext"
5586 [(set (match_operand:DI 0 "register_operand" "=r")
5588 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5590 "lea{l}\t{%a1, %k0|%k0, %a1}"
5591 [(set_attr "type" "lea")
5592 (set_attr "mode" "SI")])
5594 (define_insn "*lea_2_rex64"
5595 [(set (match_operand:DI 0 "register_operand" "=r")
5596 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5598 "lea{q}\t{%a1, %0|%0, %a1}"
5599 [(set_attr "type" "lea")
5600 (set_attr "mode" "DI")])
5602 ;; The lea patterns for non-Pmodes needs to be matched by several
5603 ;; insns converted to real lea by splitters.
5605 (define_insn_and_split "*lea_general_1"
5606 [(set (match_operand 0 "register_operand" "=r")
5607 (plus (plus (match_operand 1 "index_register_operand" "l")
5608 (match_operand 2 "register_operand" "r"))
5609 (match_operand 3 "immediate_operand" "i")))]
5610 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5611 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5612 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5613 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5614 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5615 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5616 || GET_MODE (operands[3]) == VOIDmode)"
5618 "&& reload_completed"
5622 operands[0] = gen_lowpart (SImode, operands[0]);
5623 operands[1] = gen_lowpart (Pmode, operands[1]);
5624 operands[2] = gen_lowpart (Pmode, operands[2]);
5625 operands[3] = gen_lowpart (Pmode, operands[3]);
5626 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5628 if (Pmode != SImode)
5629 pat = gen_rtx_SUBREG (SImode, pat, 0);
5630 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5633 [(set_attr "type" "lea")
5634 (set_attr "mode" "SI")])
5636 (define_insn_and_split "*lea_general_1_zext"
5637 [(set (match_operand:DI 0 "register_operand" "=r")
5639 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5640 (match_operand:SI 2 "register_operand" "r"))
5641 (match_operand:SI 3 "immediate_operand" "i"))))]
5644 "&& reload_completed"
5646 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5648 (match_dup 3)) 0)))]
5650 operands[1] = gen_lowpart (Pmode, operands[1]);
5651 operands[2] = gen_lowpart (Pmode, operands[2]);
5652 operands[3] = gen_lowpart (Pmode, operands[3]);
5654 [(set_attr "type" "lea")
5655 (set_attr "mode" "SI")])
5657 (define_insn_and_split "*lea_general_2"
5658 [(set (match_operand 0 "register_operand" "=r")
5659 (plus (mult (match_operand 1 "index_register_operand" "l")
5660 (match_operand 2 "const248_operand" "i"))
5661 (match_operand 3 "nonmemory_operand" "ri")))]
5662 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5663 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5664 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5665 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5666 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5667 || GET_MODE (operands[3]) == VOIDmode)"
5669 "&& reload_completed"
5673 operands[0] = gen_lowpart (SImode, operands[0]);
5674 operands[1] = gen_lowpart (Pmode, operands[1]);
5675 operands[3] = gen_lowpart (Pmode, operands[3]);
5676 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5678 if (Pmode != SImode)
5679 pat = gen_rtx_SUBREG (SImode, pat, 0);
5680 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5683 [(set_attr "type" "lea")
5684 (set_attr "mode" "SI")])
5686 (define_insn_and_split "*lea_general_2_zext"
5687 [(set (match_operand:DI 0 "register_operand" "=r")
5689 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5690 (match_operand:SI 2 "const248_operand" "n"))
5691 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5694 "&& reload_completed"
5696 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5698 (match_dup 3)) 0)))]
5700 operands[1] = gen_lowpart (Pmode, operands[1]);
5701 operands[3] = gen_lowpart (Pmode, operands[3]);
5703 [(set_attr "type" "lea")
5704 (set_attr "mode" "SI")])
5706 (define_insn_and_split "*lea_general_3"
5707 [(set (match_operand 0 "register_operand" "=r")
5708 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5709 (match_operand 2 "const248_operand" "i"))
5710 (match_operand 3 "register_operand" "r"))
5711 (match_operand 4 "immediate_operand" "i")))]
5712 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5713 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5714 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5715 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5716 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5718 "&& reload_completed"
5722 operands[0] = gen_lowpart (SImode, operands[0]);
5723 operands[1] = gen_lowpart (Pmode, operands[1]);
5724 operands[3] = gen_lowpart (Pmode, operands[3]);
5725 operands[4] = gen_lowpart (Pmode, operands[4]);
5726 pat = gen_rtx_PLUS (Pmode,
5727 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5731 if (Pmode != SImode)
5732 pat = gen_rtx_SUBREG (SImode, pat, 0);
5733 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5736 [(set_attr "type" "lea")
5737 (set_attr "mode" "SI")])
5739 (define_insn_and_split "*lea_general_3_zext"
5740 [(set (match_operand:DI 0 "register_operand" "=r")
5742 (plus:SI (plus:SI (mult:SI
5743 (match_operand:SI 1 "index_register_operand" "l")
5744 (match_operand:SI 2 "const248_operand" "n"))
5745 (match_operand:SI 3 "register_operand" "r"))
5746 (match_operand:SI 4 "immediate_operand" "i"))))]
5749 "&& reload_completed"
5751 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5754 (match_dup 4)) 0)))]
5756 operands[1] = gen_lowpart (Pmode, operands[1]);
5757 operands[3] = gen_lowpart (Pmode, operands[3]);
5758 operands[4] = gen_lowpart (Pmode, operands[4]);
5760 [(set_attr "type" "lea")
5761 (set_attr "mode" "SI")])
5763 (define_insn "*adddi_1_rex64"
5764 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5765 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5766 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5770 switch (get_attr_type (insn))
5773 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5774 return "lea{q}\t{%a2, %0|%0, %a2}";
5777 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5778 if (operands[2] == const1_rtx)
5779 return "inc{q}\t%0";
5782 gcc_assert (operands[2] == constm1_rtx);
5783 return "dec{q}\t%0";
5787 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5789 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5790 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5791 if (CONST_INT_P (operands[2])
5792 /* Avoid overflows. */
5793 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5794 && (INTVAL (operands[2]) == 128
5795 || (INTVAL (operands[2]) < 0
5796 && INTVAL (operands[2]) != -128)))
5798 operands[2] = GEN_INT (-INTVAL (operands[2]));
5799 return "sub{q}\t{%2, %0|%0, %2}";
5801 return "add{q}\t{%2, %0|%0, %2}";
5805 (cond [(eq_attr "alternative" "2")
5806 (const_string "lea")
5807 ; Current assemblers are broken and do not allow @GOTOFF in
5808 ; ought but a memory context.
5809 (match_operand:DI 2 "pic_symbolic_operand" "")
5810 (const_string "lea")
5811 (match_operand:DI 2 "incdec_operand" "")
5812 (const_string "incdec")
5814 (const_string "alu")))
5815 (set_attr "mode" "DI")])
5817 ;; Convert lea to the lea pattern to avoid flags dependency.
5819 [(set (match_operand:DI 0 "register_operand" "")
5820 (plus:DI (match_operand:DI 1 "register_operand" "")
5821 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5822 (clobber (reg:CC FLAGS_REG))]
5823 "TARGET_64BIT && reload_completed
5824 && true_regnum (operands[0]) != true_regnum (operands[1])"
5826 (plus:DI (match_dup 1)
5830 (define_insn "*adddi_2_rex64"
5831 [(set (reg FLAGS_REG)
5833 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5834 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5836 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5837 (plus:DI (match_dup 1) (match_dup 2)))]
5838 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5839 && ix86_binary_operator_ok (PLUS, DImode, operands)
5840 /* Current assemblers are broken and do not allow @GOTOFF in
5841 ought but a memory context. */
5842 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5844 switch (get_attr_type (insn))
5847 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5848 if (operands[2] == const1_rtx)
5849 return "inc{q}\t%0";
5852 gcc_assert (operands[2] == constm1_rtx);
5853 return "dec{q}\t%0";
5857 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5858 /* ???? We ought to handle there the 32bit case too
5859 - do we need new constraint? */
5860 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5861 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5862 if (CONST_INT_P (operands[2])
5863 /* Avoid overflows. */
5864 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5865 && (INTVAL (operands[2]) == 128
5866 || (INTVAL (operands[2]) < 0
5867 && INTVAL (operands[2]) != -128)))
5869 operands[2] = GEN_INT (-INTVAL (operands[2]));
5870 return "sub{q}\t{%2, %0|%0, %2}";
5872 return "add{q}\t{%2, %0|%0, %2}";
5876 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5877 (const_string "incdec")
5878 (const_string "alu")))
5879 (set_attr "mode" "DI")])
5881 (define_insn "*adddi_3_rex64"
5882 [(set (reg FLAGS_REG)
5883 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5884 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5885 (clobber (match_scratch:DI 0 "=r"))]
5887 && ix86_match_ccmode (insn, CCZmode)
5888 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5889 /* Current assemblers are broken and do not allow @GOTOFF in
5890 ought but a memory context. */
5891 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5893 switch (get_attr_type (insn))
5896 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5897 if (operands[2] == const1_rtx)
5898 return "inc{q}\t%0";
5901 gcc_assert (operands[2] == constm1_rtx);
5902 return "dec{q}\t%0";
5906 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5907 /* ???? We ought to handle there the 32bit case too
5908 - do we need new constraint? */
5909 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5910 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5911 if (CONST_INT_P (operands[2])
5912 /* Avoid overflows. */
5913 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5914 && (INTVAL (operands[2]) == 128
5915 || (INTVAL (operands[2]) < 0
5916 && INTVAL (operands[2]) != -128)))
5918 operands[2] = GEN_INT (-INTVAL (operands[2]));
5919 return "sub{q}\t{%2, %0|%0, %2}";
5921 return "add{q}\t{%2, %0|%0, %2}";
5925 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5926 (const_string "incdec")
5927 (const_string "alu")))
5928 (set_attr "mode" "DI")])
5930 ; For comparisons against 1, -1 and 128, we may generate better code
5931 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5932 ; is matched then. We can't accept general immediate, because for
5933 ; case of overflows, the result is messed up.
5934 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5936 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5937 ; only for comparisons not depending on it.
5938 (define_insn "*adddi_4_rex64"
5939 [(set (reg FLAGS_REG)
5940 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5941 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5942 (clobber (match_scratch:DI 0 "=rm"))]
5944 && ix86_match_ccmode (insn, CCGCmode)"
5946 switch (get_attr_type (insn))
5949 if (operands[2] == constm1_rtx)
5950 return "inc{q}\t%0";
5953 gcc_assert (operands[2] == const1_rtx);
5954 return "dec{q}\t%0";
5958 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5959 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5960 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5961 if ((INTVAL (operands[2]) == -128
5962 || (INTVAL (operands[2]) > 0
5963 && INTVAL (operands[2]) != 128))
5964 /* Avoid overflows. */
5965 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5966 return "sub{q}\t{%2, %0|%0, %2}";
5967 operands[2] = GEN_INT (-INTVAL (operands[2]));
5968 return "add{q}\t{%2, %0|%0, %2}";
5972 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5973 (const_string "incdec")
5974 (const_string "alu")))
5975 (set_attr "mode" "DI")])
5977 (define_insn "*adddi_5_rex64"
5978 [(set (reg FLAGS_REG)
5980 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5981 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5983 (clobber (match_scratch:DI 0 "=r"))]
5985 && ix86_match_ccmode (insn, CCGOCmode)
5986 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5987 /* Current assemblers are broken and do not allow @GOTOFF in
5988 ought but a memory context. */
5989 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5991 switch (get_attr_type (insn))
5994 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5995 if (operands[2] == const1_rtx)
5996 return "inc{q}\t%0";
5999 gcc_assert (operands[2] == constm1_rtx);
6000 return "dec{q}\t%0";
6004 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6005 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6007 if (CONST_INT_P (operands[2])
6008 /* Avoid overflows. */
6009 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6010 && (INTVAL (operands[2]) == 128
6011 || (INTVAL (operands[2]) < 0
6012 && INTVAL (operands[2]) != -128)))
6014 operands[2] = GEN_INT (-INTVAL (operands[2]));
6015 return "sub{q}\t{%2, %0|%0, %2}";
6017 return "add{q}\t{%2, %0|%0, %2}";
6021 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6022 (const_string "incdec")
6023 (const_string "alu")))
6024 (set_attr "mode" "DI")])
6027 (define_insn "*addsi_1"
6028 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6029 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6030 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6031 (clobber (reg:CC FLAGS_REG))]
6032 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6034 switch (get_attr_type (insn))
6037 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6038 return "lea{l}\t{%a2, %0|%0, %a2}";
6041 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6042 if (operands[2] == const1_rtx)
6043 return "inc{l}\t%0";
6046 gcc_assert (operands[2] == constm1_rtx);
6047 return "dec{l}\t%0";
6051 gcc_assert (rtx_equal_p (operands[0], operands[1]));
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 && (INTVAL (operands[2]) == 128
6057 || (INTVAL (operands[2]) < 0
6058 && INTVAL (operands[2]) != -128)))
6060 operands[2] = GEN_INT (-INTVAL (operands[2]));
6061 return "sub{l}\t{%2, %0|%0, %2}";
6063 return "add{l}\t{%2, %0|%0, %2}";
6067 (cond [(eq_attr "alternative" "2")
6068 (const_string "lea")
6069 ; Current assemblers are broken and do not allow @GOTOFF in
6070 ; ought but a memory context.
6071 (match_operand:SI 2 "pic_symbolic_operand" "")
6072 (const_string "lea")
6073 (match_operand:SI 2 "incdec_operand" "")
6074 (const_string "incdec")
6076 (const_string "alu")))
6077 (set_attr "mode" "SI")])
6079 ;; Convert lea to the lea pattern to avoid flags dependency.
6081 [(set (match_operand 0 "register_operand" "")
6082 (plus (match_operand 1 "register_operand" "")
6083 (match_operand 2 "nonmemory_operand" "")))
6084 (clobber (reg:CC FLAGS_REG))]
6086 && true_regnum (operands[0]) != true_regnum (operands[1])"
6090 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6091 may confuse gen_lowpart. */
6092 if (GET_MODE (operands[0]) != Pmode)
6094 operands[1] = gen_lowpart (Pmode, operands[1]);
6095 operands[2] = gen_lowpart (Pmode, operands[2]);
6097 operands[0] = gen_lowpart (SImode, operands[0]);
6098 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6099 if (Pmode != SImode)
6100 pat = gen_rtx_SUBREG (SImode, pat, 0);
6101 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6105 ;; It may seem that nonimmediate operand is proper one for operand 1.
6106 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6107 ;; we take care in ix86_binary_operator_ok to not allow two memory
6108 ;; operands so proper swapping will be done in reload. This allow
6109 ;; patterns constructed from addsi_1 to match.
6110 (define_insn "addsi_1_zext"
6111 [(set (match_operand:DI 0 "register_operand" "=r,r")
6113 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6114 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6115 (clobber (reg:CC FLAGS_REG))]
6116 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6118 switch (get_attr_type (insn))
6121 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6122 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6125 if (operands[2] == const1_rtx)
6126 return "inc{l}\t%k0";
6129 gcc_assert (operands[2] == constm1_rtx);
6130 return "dec{l}\t%k0";
6134 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6135 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6136 if (CONST_INT_P (operands[2])
6137 && (INTVAL (operands[2]) == 128
6138 || (INTVAL (operands[2]) < 0
6139 && INTVAL (operands[2]) != -128)))
6141 operands[2] = GEN_INT (-INTVAL (operands[2]));
6142 return "sub{l}\t{%2, %k0|%k0, %2}";
6144 return "add{l}\t{%2, %k0|%k0, %2}";
6148 (cond [(eq_attr "alternative" "1")
6149 (const_string "lea")
6150 ; Current assemblers are broken and do not allow @GOTOFF in
6151 ; ought but a memory context.
6152 (match_operand:SI 2 "pic_symbolic_operand" "")
6153 (const_string "lea")
6154 (match_operand:SI 2 "incdec_operand" "")
6155 (const_string "incdec")
6157 (const_string "alu")))
6158 (set_attr "mode" "SI")])
6160 ;; Convert lea to the lea pattern to avoid flags dependency.
6162 [(set (match_operand:DI 0 "register_operand" "")
6164 (plus:SI (match_operand:SI 1 "register_operand" "")
6165 (match_operand:SI 2 "nonmemory_operand" ""))))
6166 (clobber (reg:CC FLAGS_REG))]
6167 "TARGET_64BIT && reload_completed
6168 && true_regnum (operands[0]) != true_regnum (operands[1])"
6170 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6172 operands[1] = gen_lowpart (Pmode, operands[1]);
6173 operands[2] = gen_lowpart (Pmode, operands[2]);
6176 (define_insn "*addsi_2"
6177 [(set (reg FLAGS_REG)
6179 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6180 (match_operand:SI 2 "general_operand" "rmni,rni"))
6182 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6183 (plus:SI (match_dup 1) (match_dup 2)))]
6184 "ix86_match_ccmode (insn, CCGOCmode)
6185 && ix86_binary_operator_ok (PLUS, SImode, operands)
6186 /* Current assemblers are broken and do not allow @GOTOFF in
6187 ought but a memory context. */
6188 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6190 switch (get_attr_type (insn))
6193 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6194 if (operands[2] == const1_rtx)
6195 return "inc{l}\t%0";
6198 gcc_assert (operands[2] == constm1_rtx);
6199 return "dec{l}\t%0";
6203 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6204 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6205 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6206 if (CONST_INT_P (operands[2])
6207 && (INTVAL (operands[2]) == 128
6208 || (INTVAL (operands[2]) < 0
6209 && INTVAL (operands[2]) != -128)))
6211 operands[2] = GEN_INT (-INTVAL (operands[2]));
6212 return "sub{l}\t{%2, %0|%0, %2}";
6214 return "add{l}\t{%2, %0|%0, %2}";
6218 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6219 (const_string "incdec")
6220 (const_string "alu")))
6221 (set_attr "mode" "SI")])
6223 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6224 (define_insn "*addsi_2_zext"
6225 [(set (reg FLAGS_REG)
6227 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6228 (match_operand:SI 2 "general_operand" "rmni"))
6230 (set (match_operand:DI 0 "register_operand" "=r")
6231 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6232 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6233 && ix86_binary_operator_ok (PLUS, SImode, operands)
6234 /* Current assemblers are broken and do not allow @GOTOFF in
6235 ought but a memory context. */
6236 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6238 switch (get_attr_type (insn))
6241 if (operands[2] == const1_rtx)
6242 return "inc{l}\t%k0";
6245 gcc_assert (operands[2] == constm1_rtx);
6246 return "dec{l}\t%k0";
6250 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6251 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6252 if (CONST_INT_P (operands[2])
6253 && (INTVAL (operands[2]) == 128
6254 || (INTVAL (operands[2]) < 0
6255 && INTVAL (operands[2]) != -128)))
6257 operands[2] = GEN_INT (-INTVAL (operands[2]));
6258 return "sub{l}\t{%2, %k0|%k0, %2}";
6260 return "add{l}\t{%2, %k0|%k0, %2}";
6264 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6265 (const_string "incdec")
6266 (const_string "alu")))
6267 (set_attr "mode" "SI")])
6269 (define_insn "*addsi_3"
6270 [(set (reg FLAGS_REG)
6271 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6272 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6273 (clobber (match_scratch:SI 0 "=r"))]
6274 "ix86_match_ccmode (insn, CCZmode)
6275 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6276 /* Current assemblers are broken and do not allow @GOTOFF in
6277 ought but a memory context. */
6278 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6280 switch (get_attr_type (insn))
6283 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6284 if (operands[2] == const1_rtx)
6285 return "inc{l}\t%0";
6288 gcc_assert (operands[2] == constm1_rtx);
6289 return "dec{l}\t%0";
6293 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6294 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6295 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6296 if (CONST_INT_P (operands[2])
6297 && (INTVAL (operands[2]) == 128
6298 || (INTVAL (operands[2]) < 0
6299 && INTVAL (operands[2]) != -128)))
6301 operands[2] = GEN_INT (-INTVAL (operands[2]));
6302 return "sub{l}\t{%2, %0|%0, %2}";
6304 return "add{l}\t{%2, %0|%0, %2}";
6308 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6309 (const_string "incdec")
6310 (const_string "alu")))
6311 (set_attr "mode" "SI")])
6313 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6314 (define_insn "*addsi_3_zext"
6315 [(set (reg FLAGS_REG)
6316 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6317 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6318 (set (match_operand:DI 0 "register_operand" "=r")
6319 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6320 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6321 && ix86_binary_operator_ok (PLUS, SImode, operands)
6322 /* Current assemblers are broken and do not allow @GOTOFF in
6323 ought but a memory context. */
6324 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6326 switch (get_attr_type (insn))
6329 if (operands[2] == const1_rtx)
6330 return "inc{l}\t%k0";
6333 gcc_assert (operands[2] == constm1_rtx);
6334 return "dec{l}\t%k0";
6338 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6339 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6340 if (CONST_INT_P (operands[2])
6341 && (INTVAL (operands[2]) == 128
6342 || (INTVAL (operands[2]) < 0
6343 && INTVAL (operands[2]) != -128)))
6345 operands[2] = GEN_INT (-INTVAL (operands[2]));
6346 return "sub{l}\t{%2, %k0|%k0, %2}";
6348 return "add{l}\t{%2, %k0|%k0, %2}";
6352 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6353 (const_string "incdec")
6354 (const_string "alu")))
6355 (set_attr "mode" "SI")])
6357 ; For comparisons against 1, -1 and 128, we may generate better code
6358 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6359 ; is matched then. We can't accept general immediate, because for
6360 ; case of overflows, the result is messed up.
6361 ; This pattern also don't hold of 0x80000000, since the value overflows
6363 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6364 ; only for comparisons not depending on it.
6365 (define_insn "*addsi_4"
6366 [(set (reg FLAGS_REG)
6367 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6368 (match_operand:SI 2 "const_int_operand" "n")))
6369 (clobber (match_scratch:SI 0 "=rm"))]
6370 "ix86_match_ccmode (insn, CCGCmode)
6371 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6373 switch (get_attr_type (insn))
6376 if (operands[2] == constm1_rtx)
6377 return "inc{l}\t%0";
6380 gcc_assert (operands[2] == const1_rtx);
6381 return "dec{l}\t%0";
6385 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6386 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6387 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6388 if ((INTVAL (operands[2]) == -128
6389 || (INTVAL (operands[2]) > 0
6390 && INTVAL (operands[2]) != 128)))
6391 return "sub{l}\t{%2, %0|%0, %2}";
6392 operands[2] = GEN_INT (-INTVAL (operands[2]));
6393 return "add{l}\t{%2, %0|%0, %2}";
6397 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6398 (const_string "incdec")
6399 (const_string "alu")))
6400 (set_attr "mode" "SI")])
6402 (define_insn "*addsi_5"
6403 [(set (reg FLAGS_REG)
6405 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6406 (match_operand:SI 2 "general_operand" "rmni"))
6408 (clobber (match_scratch:SI 0 "=r"))]
6409 "ix86_match_ccmode (insn, CCGOCmode)
6410 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6411 /* Current assemblers are broken and do not allow @GOTOFF in
6412 ought but a memory context. */
6413 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6415 switch (get_attr_type (insn))
6418 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6419 if (operands[2] == const1_rtx)
6420 return "inc{l}\t%0";
6423 gcc_assert (operands[2] == constm1_rtx);
6424 return "dec{l}\t%0";
6428 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6429 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6430 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6431 if (CONST_INT_P (operands[2])
6432 && (INTVAL (operands[2]) == 128
6433 || (INTVAL (operands[2]) < 0
6434 && INTVAL (operands[2]) != -128)))
6436 operands[2] = GEN_INT (-INTVAL (operands[2]));
6437 return "sub{l}\t{%2, %0|%0, %2}";
6439 return "add{l}\t{%2, %0|%0, %2}";
6443 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6444 (const_string "incdec")
6445 (const_string "alu")))
6446 (set_attr "mode" "SI")])
6448 (define_expand "addhi3"
6449 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6450 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6451 (match_operand:HI 2 "general_operand" "")))
6452 (clobber (reg:CC FLAGS_REG))])]
6453 "TARGET_HIMODE_MATH"
6454 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6456 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6457 ;; type optimizations enabled by define-splits. This is not important
6458 ;; for PII, and in fact harmful because of partial register stalls.
6460 (define_insn "*addhi_1_lea"
6461 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6462 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6463 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6464 (clobber (reg:CC FLAGS_REG))]
6465 "!TARGET_PARTIAL_REG_STALL
6466 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6468 switch (get_attr_type (insn))
6473 if (operands[2] == const1_rtx)
6474 return "inc{w}\t%0";
6477 gcc_assert (operands[2] == constm1_rtx);
6478 return "dec{w}\t%0";
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{w}\t{%2, %0|%0, %2}";
6492 return "add{w}\t{%2, %0|%0, %2}";
6496 (if_then_else (eq_attr "alternative" "2")
6497 (const_string "lea")
6498 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6499 (const_string "incdec")
6500 (const_string "alu"))))
6501 (set_attr "mode" "HI,HI,SI")])
6503 (define_insn "*addhi_1"
6504 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6505 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6506 (match_operand:HI 2 "general_operand" "ri,rm")))
6507 (clobber (reg:CC FLAGS_REG))]
6508 "TARGET_PARTIAL_REG_STALL
6509 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6511 switch (get_attr_type (insn))
6514 if (operands[2] == const1_rtx)
6515 return "inc{w}\t%0";
6518 gcc_assert (operands[2] == constm1_rtx);
6519 return "dec{w}\t%0";
6523 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6524 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6525 if (CONST_INT_P (operands[2])
6526 && (INTVAL (operands[2]) == 128
6527 || (INTVAL (operands[2]) < 0
6528 && INTVAL (operands[2]) != -128)))
6530 operands[2] = GEN_INT (-INTVAL (operands[2]));
6531 return "sub{w}\t{%2, %0|%0, %2}";
6533 return "add{w}\t{%2, %0|%0, %2}";
6537 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6538 (const_string "incdec")
6539 (const_string "alu")))
6540 (set_attr "mode" "HI")])
6542 (define_insn "*addhi_2"
6543 [(set (reg FLAGS_REG)
6545 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6546 (match_operand:HI 2 "general_operand" "rmni,rni"))
6548 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6549 (plus:HI (match_dup 1) (match_dup 2)))]
6550 "ix86_match_ccmode (insn, CCGOCmode)
6551 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6553 switch (get_attr_type (insn))
6556 if (operands[2] == const1_rtx)
6557 return "inc{w}\t%0";
6560 gcc_assert (operands[2] == constm1_rtx);
6561 return "dec{w}\t%0";
6565 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6566 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6567 if (CONST_INT_P (operands[2])
6568 && (INTVAL (operands[2]) == 128
6569 || (INTVAL (operands[2]) < 0
6570 && INTVAL (operands[2]) != -128)))
6572 operands[2] = GEN_INT (-INTVAL (operands[2]));
6573 return "sub{w}\t{%2, %0|%0, %2}";
6575 return "add{w}\t{%2, %0|%0, %2}";
6579 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6580 (const_string "incdec")
6581 (const_string "alu")))
6582 (set_attr "mode" "HI")])
6584 (define_insn "*addhi_3"
6585 [(set (reg FLAGS_REG)
6586 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6587 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6588 (clobber (match_scratch:HI 0 "=r"))]
6589 "ix86_match_ccmode (insn, CCZmode)
6590 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6592 switch (get_attr_type (insn))
6595 if (operands[2] == const1_rtx)
6596 return "inc{w}\t%0";
6599 gcc_assert (operands[2] == constm1_rtx);
6600 return "dec{w}\t%0";
6604 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6605 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6606 if (CONST_INT_P (operands[2])
6607 && (INTVAL (operands[2]) == 128
6608 || (INTVAL (operands[2]) < 0
6609 && INTVAL (operands[2]) != -128)))
6611 operands[2] = GEN_INT (-INTVAL (operands[2]));
6612 return "sub{w}\t{%2, %0|%0, %2}";
6614 return "add{w}\t{%2, %0|%0, %2}";
6618 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6619 (const_string "incdec")
6620 (const_string "alu")))
6621 (set_attr "mode" "HI")])
6623 ; See comments above addsi_4 for details.
6624 (define_insn "*addhi_4"
6625 [(set (reg FLAGS_REG)
6626 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6627 (match_operand:HI 2 "const_int_operand" "n")))
6628 (clobber (match_scratch:HI 0 "=rm"))]
6629 "ix86_match_ccmode (insn, CCGCmode)
6630 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6632 switch (get_attr_type (insn))
6635 if (operands[2] == constm1_rtx)
6636 return "inc{w}\t%0";
6639 gcc_assert (operands[2] == const1_rtx);
6640 return "dec{w}\t%0";
6644 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6645 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6646 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6647 if ((INTVAL (operands[2]) == -128
6648 || (INTVAL (operands[2]) > 0
6649 && INTVAL (operands[2]) != 128)))
6650 return "sub{w}\t{%2, %0|%0, %2}";
6651 operands[2] = GEN_INT (-INTVAL (operands[2]));
6652 return "add{w}\t{%2, %0|%0, %2}";
6656 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6657 (const_string "incdec")
6658 (const_string "alu")))
6659 (set_attr "mode" "SI")])
6662 (define_insn "*addhi_5"
6663 [(set (reg FLAGS_REG)
6665 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6666 (match_operand:HI 2 "general_operand" "rmni"))
6668 (clobber (match_scratch:HI 0 "=r"))]
6669 "ix86_match_ccmode (insn, CCGOCmode)
6670 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6672 switch (get_attr_type (insn))
6675 if (operands[2] == const1_rtx)
6676 return "inc{w}\t%0";
6679 gcc_assert (operands[2] == constm1_rtx);
6680 return "dec{w}\t%0";
6684 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6685 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6686 if (CONST_INT_P (operands[2])
6687 && (INTVAL (operands[2]) == 128
6688 || (INTVAL (operands[2]) < 0
6689 && INTVAL (operands[2]) != -128)))
6691 operands[2] = GEN_INT (-INTVAL (operands[2]));
6692 return "sub{w}\t{%2, %0|%0, %2}";
6694 return "add{w}\t{%2, %0|%0, %2}";
6698 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6699 (const_string "incdec")
6700 (const_string "alu")))
6701 (set_attr "mode" "HI")])
6703 (define_expand "addqi3"
6704 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6705 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6706 (match_operand:QI 2 "general_operand" "")))
6707 (clobber (reg:CC FLAGS_REG))])]
6708 "TARGET_QIMODE_MATH"
6709 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6711 ;; %%% Potential partial reg stall on alternative 2. What to do?
6712 (define_insn "*addqi_1_lea"
6713 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6714 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6715 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6716 (clobber (reg:CC FLAGS_REG))]
6717 "!TARGET_PARTIAL_REG_STALL
6718 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6720 int widen = (which_alternative == 2);
6721 switch (get_attr_type (insn))
6726 if (operands[2] == const1_rtx)
6727 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6730 gcc_assert (operands[2] == constm1_rtx);
6731 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6735 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6736 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6737 if (CONST_INT_P (operands[2])
6738 && (INTVAL (operands[2]) == 128
6739 || (INTVAL (operands[2]) < 0
6740 && INTVAL (operands[2]) != -128)))
6742 operands[2] = GEN_INT (-INTVAL (operands[2]));
6744 return "sub{l}\t{%2, %k0|%k0, %2}";
6746 return "sub{b}\t{%2, %0|%0, %2}";
6749 return "add{l}\t{%k2, %k0|%k0, %k2}";
6751 return "add{b}\t{%2, %0|%0, %2}";
6755 (if_then_else (eq_attr "alternative" "3")
6756 (const_string "lea")
6757 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6758 (const_string "incdec")
6759 (const_string "alu"))))
6760 (set_attr "mode" "QI,QI,SI,SI")])
6762 (define_insn "*addqi_1"
6763 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6764 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6765 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6766 (clobber (reg:CC FLAGS_REG))]
6767 "TARGET_PARTIAL_REG_STALL
6768 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6770 int widen = (which_alternative == 2);
6771 switch (get_attr_type (insn))
6774 if (operands[2] == const1_rtx)
6775 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6778 gcc_assert (operands[2] == constm1_rtx);
6779 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6783 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6784 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6785 if (CONST_INT_P (operands[2])
6786 && (INTVAL (operands[2]) == 128
6787 || (INTVAL (operands[2]) < 0
6788 && INTVAL (operands[2]) != -128)))
6790 operands[2] = GEN_INT (-INTVAL (operands[2]));
6792 return "sub{l}\t{%2, %k0|%k0, %2}";
6794 return "sub{b}\t{%2, %0|%0, %2}";
6797 return "add{l}\t{%k2, %k0|%k0, %k2}";
6799 return "add{b}\t{%2, %0|%0, %2}";
6803 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6804 (const_string "incdec")
6805 (const_string "alu")))
6806 (set_attr "mode" "QI,QI,SI")])
6808 (define_insn "*addqi_1_slp"
6809 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6810 (plus:QI (match_dup 0)
6811 (match_operand:QI 1 "general_operand" "qn,qnm")))
6812 (clobber (reg:CC FLAGS_REG))]
6813 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6816 switch (get_attr_type (insn))
6819 if (operands[1] == const1_rtx)
6820 return "inc{b}\t%0";
6823 gcc_assert (operands[1] == constm1_rtx);
6824 return "dec{b}\t%0";
6828 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6829 if (CONST_INT_P (operands[1])
6830 && INTVAL (operands[1]) < 0)
6832 operands[1] = GEN_INT (-INTVAL (operands[1]));
6833 return "sub{b}\t{%1, %0|%0, %1}";
6835 return "add{b}\t{%1, %0|%0, %1}";
6839 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6840 (const_string "incdec")
6841 (const_string "alu1")))
6842 (set (attr "memory")
6843 (if_then_else (match_operand 1 "memory_operand" "")
6844 (const_string "load")
6845 (const_string "none")))
6846 (set_attr "mode" "QI")])
6848 (define_insn "*addqi_2"
6849 [(set (reg FLAGS_REG)
6851 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6852 (match_operand:QI 2 "general_operand" "qmni,qni"))
6854 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6855 (plus:QI (match_dup 1) (match_dup 2)))]
6856 "ix86_match_ccmode (insn, CCGOCmode)
6857 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6859 switch (get_attr_type (insn))
6862 if (operands[2] == const1_rtx)
6863 return "inc{b}\t%0";
6866 gcc_assert (operands[2] == constm1_rtx
6867 || (CONST_INT_P (operands[2])
6868 && INTVAL (operands[2]) == 255));
6869 return "dec{b}\t%0";
6873 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6874 if (CONST_INT_P (operands[2])
6875 && INTVAL (operands[2]) < 0)
6877 operands[2] = GEN_INT (-INTVAL (operands[2]));
6878 return "sub{b}\t{%2, %0|%0, %2}";
6880 return "add{b}\t{%2, %0|%0, %2}";
6884 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6885 (const_string "incdec")
6886 (const_string "alu")))
6887 (set_attr "mode" "QI")])
6889 (define_insn "*addqi_3"
6890 [(set (reg FLAGS_REG)
6891 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6892 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6893 (clobber (match_scratch:QI 0 "=q"))]
6894 "ix86_match_ccmode (insn, CCZmode)
6895 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6897 switch (get_attr_type (insn))
6900 if (operands[2] == const1_rtx)
6901 return "inc{b}\t%0";
6904 gcc_assert (operands[2] == constm1_rtx
6905 || (CONST_INT_P (operands[2])
6906 && INTVAL (operands[2]) == 255));
6907 return "dec{b}\t%0";
6911 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6912 if (CONST_INT_P (operands[2])
6913 && INTVAL (operands[2]) < 0)
6915 operands[2] = GEN_INT (-INTVAL (operands[2]));
6916 return "sub{b}\t{%2, %0|%0, %2}";
6918 return "add{b}\t{%2, %0|%0, %2}";
6922 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6923 (const_string "incdec")
6924 (const_string "alu")))
6925 (set_attr "mode" "QI")])
6927 ; See comments above addsi_4 for details.
6928 (define_insn "*addqi_4"
6929 [(set (reg FLAGS_REG)
6930 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6931 (match_operand:QI 2 "const_int_operand" "n")))
6932 (clobber (match_scratch:QI 0 "=qm"))]
6933 "ix86_match_ccmode (insn, CCGCmode)
6934 && (INTVAL (operands[2]) & 0xff) != 0x80"
6936 switch (get_attr_type (insn))
6939 if (operands[2] == constm1_rtx
6940 || (CONST_INT_P (operands[2])
6941 && INTVAL (operands[2]) == 255))
6942 return "inc{b}\t%0";
6945 gcc_assert (operands[2] == const1_rtx);
6946 return "dec{b}\t%0";
6950 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6951 if (INTVAL (operands[2]) < 0)
6953 operands[2] = GEN_INT (-INTVAL (operands[2]));
6954 return "add{b}\t{%2, %0|%0, %2}";
6956 return "sub{b}\t{%2, %0|%0, %2}";
6960 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6961 (const_string "incdec")
6962 (const_string "alu")))
6963 (set_attr "mode" "QI")])
6966 (define_insn "*addqi_5"
6967 [(set (reg FLAGS_REG)
6969 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6970 (match_operand:QI 2 "general_operand" "qmni"))
6972 (clobber (match_scratch:QI 0 "=q"))]
6973 "ix86_match_ccmode (insn, CCGOCmode)
6974 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6976 switch (get_attr_type (insn))
6979 if (operands[2] == const1_rtx)
6980 return "inc{b}\t%0";
6983 gcc_assert (operands[2] == constm1_rtx
6984 || (CONST_INT_P (operands[2])
6985 && INTVAL (operands[2]) == 255));
6986 return "dec{b}\t%0";
6990 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6991 if (CONST_INT_P (operands[2])
6992 && INTVAL (operands[2]) < 0)
6994 operands[2] = GEN_INT (-INTVAL (operands[2]));
6995 return "sub{b}\t{%2, %0|%0, %2}";
6997 return "add{b}\t{%2, %0|%0, %2}";
7001 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7002 (const_string "incdec")
7003 (const_string "alu")))
7004 (set_attr "mode" "QI")])
7007 (define_insn "addqi_ext_1"
7008 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7013 (match_operand 1 "ext_register_operand" "0")
7016 (match_operand:QI 2 "general_operand" "Qmn")))
7017 (clobber (reg:CC FLAGS_REG))]
7020 switch (get_attr_type (insn))
7023 if (operands[2] == const1_rtx)
7024 return "inc{b}\t%h0";
7027 gcc_assert (operands[2] == constm1_rtx
7028 || (CONST_INT_P (operands[2])
7029 && INTVAL (operands[2]) == 255));
7030 return "dec{b}\t%h0";
7034 return "add{b}\t{%2, %h0|%h0, %2}";
7038 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7039 (const_string "incdec")
7040 (const_string "alu")))
7041 (set_attr "mode" "QI")])
7043 (define_insn "*addqi_ext_1_rex64"
7044 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7049 (match_operand 1 "ext_register_operand" "0")
7052 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7053 (clobber (reg:CC FLAGS_REG))]
7056 switch (get_attr_type (insn))
7059 if (operands[2] == const1_rtx)
7060 return "inc{b}\t%h0";
7063 gcc_assert (operands[2] == constm1_rtx
7064 || (CONST_INT_P (operands[2])
7065 && INTVAL (operands[2]) == 255));
7066 return "dec{b}\t%h0";
7070 return "add{b}\t{%2, %h0|%h0, %2}";
7074 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7075 (const_string "incdec")
7076 (const_string "alu")))
7077 (set_attr "mode" "QI")])
7079 (define_insn "*addqi_ext_2"
7080 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7085 (match_operand 1 "ext_register_operand" "%0")
7089 (match_operand 2 "ext_register_operand" "Q")
7092 (clobber (reg:CC FLAGS_REG))]
7094 "add{b}\t{%h2, %h0|%h0, %h2}"
7095 [(set_attr "type" "alu")
7096 (set_attr "mode" "QI")])
7098 ;; The patterns that match these are at the end of this file.
7100 (define_expand "addxf3"
7101 [(set (match_operand:XF 0 "register_operand" "")
7102 (plus:XF (match_operand:XF 1 "register_operand" "")
7103 (match_operand:XF 2 "register_operand" "")))]
7107 (define_expand "add<mode>3"
7108 [(set (match_operand:MODEF 0 "register_operand" "")
7109 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7110 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7111 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7114 ;; Subtract instructions
7116 ;; %%% splits for subditi3
7118 (define_expand "subti3"
7119 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7120 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7121 (match_operand:TI 2 "x86_64_general_operand" "")))
7122 (clobber (reg:CC FLAGS_REG))])]
7124 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7126 (define_insn "*subti3_1"
7127 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7128 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7129 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7130 (clobber (reg:CC FLAGS_REG))]
7131 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7135 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7136 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7137 (match_operand:TI 2 "x86_64_general_operand" "")))
7138 (clobber (reg:CC FLAGS_REG))]
7139 "TARGET_64BIT && reload_completed"
7140 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7141 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7142 (parallel [(set (match_dup 3)
7143 (minus:DI (match_dup 4)
7144 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7146 (clobber (reg:CC FLAGS_REG))])]
7147 "split_ti (operands+0, 1, operands+0, operands+3);
7148 split_ti (operands+1, 1, operands+1, operands+4);
7149 split_ti (operands+2, 1, operands+2, operands+5);")
7151 ;; %%% splits for subsidi3
7153 (define_expand "subdi3"
7154 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7155 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7156 (match_operand:DI 2 "x86_64_general_operand" "")))
7157 (clobber (reg:CC FLAGS_REG))])]
7159 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7161 (define_insn "*subdi3_1"
7162 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7163 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7164 (match_operand:DI 2 "general_operand" "roiF,riF")))
7165 (clobber (reg:CC FLAGS_REG))]
7166 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7170 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7171 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7172 (match_operand:DI 2 "general_operand" "")))
7173 (clobber (reg:CC FLAGS_REG))]
7174 "!TARGET_64BIT && reload_completed"
7175 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7176 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7177 (parallel [(set (match_dup 3)
7178 (minus:SI (match_dup 4)
7179 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7181 (clobber (reg:CC FLAGS_REG))])]
7182 "split_di (operands+0, 1, operands+0, operands+3);
7183 split_di (operands+1, 1, operands+1, operands+4);
7184 split_di (operands+2, 1, operands+2, operands+5);")
7186 (define_insn "subdi3_carry_rex64"
7187 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7188 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7189 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7190 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7191 (clobber (reg:CC FLAGS_REG))]
7192 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7193 "sbb{q}\t{%2, %0|%0, %2}"
7194 [(set_attr "type" "alu")
7195 (set_attr "pent_pair" "pu")
7196 (set_attr "mode" "DI")])
7198 (define_insn "*subdi_1_rex64"
7199 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7200 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7201 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7202 (clobber (reg:CC FLAGS_REG))]
7203 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7204 "sub{q}\t{%2, %0|%0, %2}"
7205 [(set_attr "type" "alu")
7206 (set_attr "mode" "DI")])
7208 (define_insn "*subdi_2_rex64"
7209 [(set (reg FLAGS_REG)
7211 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7212 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7214 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7215 (minus:DI (match_dup 1) (match_dup 2)))]
7216 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7217 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7218 "sub{q}\t{%2, %0|%0, %2}"
7219 [(set_attr "type" "alu")
7220 (set_attr "mode" "DI")])
7222 (define_insn "*subdi_3_rex63"
7223 [(set (reg FLAGS_REG)
7224 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7225 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7226 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7227 (minus:DI (match_dup 1) (match_dup 2)))]
7228 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7229 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7230 "sub{q}\t{%2, %0|%0, %2}"
7231 [(set_attr "type" "alu")
7232 (set_attr "mode" "DI")])
7234 (define_insn "subqi3_carry"
7235 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7236 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7237 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7238 (match_operand:QI 2 "general_operand" "qi,qm"))))
7239 (clobber (reg:CC FLAGS_REG))]
7240 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7241 "sbb{b}\t{%2, %0|%0, %2}"
7242 [(set_attr "type" "alu")
7243 (set_attr "pent_pair" "pu")
7244 (set_attr "mode" "QI")])
7246 (define_insn "subhi3_carry"
7247 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7248 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7249 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7250 (match_operand:HI 2 "general_operand" "ri,rm"))))
7251 (clobber (reg:CC FLAGS_REG))]
7252 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7253 "sbb{w}\t{%2, %0|%0, %2}"
7254 [(set_attr "type" "alu")
7255 (set_attr "pent_pair" "pu")
7256 (set_attr "mode" "HI")])
7258 (define_insn "subsi3_carry"
7259 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7260 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7261 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7262 (match_operand:SI 2 "general_operand" "ri,rm"))))
7263 (clobber (reg:CC FLAGS_REG))]
7264 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7265 "sbb{l}\t{%2, %0|%0, %2}"
7266 [(set_attr "type" "alu")
7267 (set_attr "pent_pair" "pu")
7268 (set_attr "mode" "SI")])
7270 (define_insn "subsi3_carry_zext"
7271 [(set (match_operand:DI 0 "register_operand" "=r")
7273 (minus:SI (match_operand:SI 1 "register_operand" "0")
7274 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7275 (match_operand:SI 2 "general_operand" "g")))))
7276 (clobber (reg:CC FLAGS_REG))]
7277 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7278 "sbb{l}\t{%2, %k0|%k0, %2}"
7279 [(set_attr "type" "alu")
7280 (set_attr "pent_pair" "pu")
7281 (set_attr "mode" "SI")])
7283 (define_expand "subsi3"
7284 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7285 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7286 (match_operand:SI 2 "general_operand" "")))
7287 (clobber (reg:CC FLAGS_REG))])]
7289 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7291 (define_insn "*subsi_1"
7292 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7293 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7294 (match_operand:SI 2 "general_operand" "ri,rm")))
7295 (clobber (reg:CC FLAGS_REG))]
7296 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7297 "sub{l}\t{%2, %0|%0, %2}"
7298 [(set_attr "type" "alu")
7299 (set_attr "mode" "SI")])
7301 (define_insn "*subsi_1_zext"
7302 [(set (match_operand:DI 0 "register_operand" "=r")
7304 (minus:SI (match_operand:SI 1 "register_operand" "0")
7305 (match_operand:SI 2 "general_operand" "g"))))
7306 (clobber (reg:CC FLAGS_REG))]
7307 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7308 "sub{l}\t{%2, %k0|%k0, %2}"
7309 [(set_attr "type" "alu")
7310 (set_attr "mode" "SI")])
7312 (define_insn "*subsi_2"
7313 [(set (reg FLAGS_REG)
7315 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7316 (match_operand:SI 2 "general_operand" "ri,rm"))
7318 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7319 (minus:SI (match_dup 1) (match_dup 2)))]
7320 "ix86_match_ccmode (insn, CCGOCmode)
7321 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7322 "sub{l}\t{%2, %0|%0, %2}"
7323 [(set_attr "type" "alu")
7324 (set_attr "mode" "SI")])
7326 (define_insn "*subsi_2_zext"
7327 [(set (reg FLAGS_REG)
7329 (minus:SI (match_operand:SI 1 "register_operand" "0")
7330 (match_operand:SI 2 "general_operand" "g"))
7332 (set (match_operand:DI 0 "register_operand" "=r")
7334 (minus:SI (match_dup 1)
7336 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7337 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7338 "sub{l}\t{%2, %k0|%k0, %2}"
7339 [(set_attr "type" "alu")
7340 (set_attr "mode" "SI")])
7342 (define_insn "*subsi_3"
7343 [(set (reg FLAGS_REG)
7344 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7345 (match_operand:SI 2 "general_operand" "ri,rm")))
7346 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7347 (minus:SI (match_dup 1) (match_dup 2)))]
7348 "ix86_match_ccmode (insn, CCmode)
7349 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7350 "sub{l}\t{%2, %0|%0, %2}"
7351 [(set_attr "type" "alu")
7352 (set_attr "mode" "SI")])
7354 (define_insn "*subsi_3_zext"
7355 [(set (reg FLAGS_REG)
7356 (compare (match_operand:SI 1 "register_operand" "0")
7357 (match_operand:SI 2 "general_operand" "g")))
7358 (set (match_operand:DI 0 "register_operand" "=r")
7360 (minus:SI (match_dup 1)
7362 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7363 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7364 "sub{l}\t{%2, %1|%1, %2}"
7365 [(set_attr "type" "alu")
7366 (set_attr "mode" "DI")])
7368 (define_expand "subhi3"
7369 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7370 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7371 (match_operand:HI 2 "general_operand" "")))
7372 (clobber (reg:CC FLAGS_REG))])]
7373 "TARGET_HIMODE_MATH"
7374 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7376 (define_insn "*subhi_1"
7377 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7378 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7379 (match_operand:HI 2 "general_operand" "ri,rm")))
7380 (clobber (reg:CC FLAGS_REG))]
7381 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7382 "sub{w}\t{%2, %0|%0, %2}"
7383 [(set_attr "type" "alu")
7384 (set_attr "mode" "HI")])
7386 (define_insn "*subhi_2"
7387 [(set (reg FLAGS_REG)
7389 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7390 (match_operand:HI 2 "general_operand" "ri,rm"))
7392 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7393 (minus:HI (match_dup 1) (match_dup 2)))]
7394 "ix86_match_ccmode (insn, CCGOCmode)
7395 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7396 "sub{w}\t{%2, %0|%0, %2}"
7397 [(set_attr "type" "alu")
7398 (set_attr "mode" "HI")])
7400 (define_insn "*subhi_3"
7401 [(set (reg FLAGS_REG)
7402 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7403 (match_operand:HI 2 "general_operand" "ri,rm")))
7404 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7405 (minus:HI (match_dup 1) (match_dup 2)))]
7406 "ix86_match_ccmode (insn, CCmode)
7407 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7408 "sub{w}\t{%2, %0|%0, %2}"
7409 [(set_attr "type" "alu")
7410 (set_attr "mode" "HI")])
7412 (define_expand "subqi3"
7413 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7414 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7415 (match_operand:QI 2 "general_operand" "")))
7416 (clobber (reg:CC FLAGS_REG))])]
7417 "TARGET_QIMODE_MATH"
7418 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7420 (define_insn "*subqi_1"
7421 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7422 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7423 (match_operand:QI 2 "general_operand" "qn,qmn")))
7424 (clobber (reg:CC FLAGS_REG))]
7425 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7426 "sub{b}\t{%2, %0|%0, %2}"
7427 [(set_attr "type" "alu")
7428 (set_attr "mode" "QI")])
7430 (define_insn "*subqi_1_slp"
7431 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7432 (minus:QI (match_dup 0)
7433 (match_operand:QI 1 "general_operand" "qn,qmn")))
7434 (clobber (reg:CC FLAGS_REG))]
7435 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7436 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7437 "sub{b}\t{%1, %0|%0, %1}"
7438 [(set_attr "type" "alu1")
7439 (set_attr "mode" "QI")])
7441 (define_insn "*subqi_2"
7442 [(set (reg FLAGS_REG)
7444 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7445 (match_operand:QI 2 "general_operand" "qi,qm"))
7447 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7448 (minus:HI (match_dup 1) (match_dup 2)))]
7449 "ix86_match_ccmode (insn, CCGOCmode)
7450 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7451 "sub{b}\t{%2, %0|%0, %2}"
7452 [(set_attr "type" "alu")
7453 (set_attr "mode" "QI")])
7455 (define_insn "*subqi_3"
7456 [(set (reg FLAGS_REG)
7457 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7458 (match_operand:QI 2 "general_operand" "qi,qm")))
7459 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7460 (minus:HI (match_dup 1) (match_dup 2)))]
7461 "ix86_match_ccmode (insn, CCmode)
7462 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7463 "sub{b}\t{%2, %0|%0, %2}"
7464 [(set_attr "type" "alu")
7465 (set_attr "mode" "QI")])
7467 ;; The patterns that match these are at the end of this file.
7469 (define_expand "subxf3"
7470 [(set (match_operand:XF 0 "register_operand" "")
7471 (minus:XF (match_operand:XF 1 "register_operand" "")
7472 (match_operand:XF 2 "register_operand" "")))]
7476 (define_expand "sub<mode>3"
7477 [(set (match_operand:MODEF 0 "register_operand" "")
7478 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7479 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7480 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7483 ;; Multiply instructions
7485 (define_expand "muldi3"
7486 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7487 (mult:DI (match_operand:DI 1 "register_operand" "")
7488 (match_operand:DI 2 "x86_64_general_operand" "")))
7489 (clobber (reg:CC FLAGS_REG))])]
7494 ;; IMUL reg64, reg64, imm8 Direct
7495 ;; IMUL reg64, mem64, imm8 VectorPath
7496 ;; IMUL reg64, reg64, imm32 Direct
7497 ;; IMUL reg64, mem64, imm32 VectorPath
7498 ;; IMUL reg64, reg64 Direct
7499 ;; IMUL reg64, mem64 Direct
7501 (define_insn "*muldi3_1_rex64"
7502 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7503 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7504 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7505 (clobber (reg:CC FLAGS_REG))]
7507 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7509 imul{q}\t{%2, %1, %0|%0, %1, %2}
7510 imul{q}\t{%2, %1, %0|%0, %1, %2}
7511 imul{q}\t{%2, %0|%0, %2}"
7512 [(set_attr "type" "imul")
7513 (set_attr "prefix_0f" "0,0,1")
7514 (set (attr "athlon_decode")
7515 (cond [(eq_attr "cpu" "athlon")
7516 (const_string "vector")
7517 (eq_attr "alternative" "1")
7518 (const_string "vector")
7519 (and (eq_attr "alternative" "2")
7520 (match_operand 1 "memory_operand" ""))
7521 (const_string "vector")]
7522 (const_string "direct")))
7523 (set (attr "amdfam10_decode")
7524 (cond [(and (eq_attr "alternative" "0,1")
7525 (match_operand 1 "memory_operand" ""))
7526 (const_string "vector")]
7527 (const_string "direct")))
7528 (set_attr "mode" "DI")])
7530 (define_expand "mulsi3"
7531 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7532 (mult:SI (match_operand:SI 1 "register_operand" "")
7533 (match_operand:SI 2 "general_operand" "")))
7534 (clobber (reg:CC FLAGS_REG))])]
7539 ;; IMUL reg32, reg32, imm8 Direct
7540 ;; IMUL reg32, mem32, imm8 VectorPath
7541 ;; IMUL reg32, reg32, imm32 Direct
7542 ;; IMUL reg32, mem32, imm32 VectorPath
7543 ;; IMUL reg32, reg32 Direct
7544 ;; IMUL reg32, mem32 Direct
7546 (define_insn "*mulsi3_1"
7547 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7548 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7549 (match_operand:SI 2 "general_operand" "K,i,mr")))
7550 (clobber (reg:CC FLAGS_REG))]
7551 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7553 imul{l}\t{%2, %1, %0|%0, %1, %2}
7554 imul{l}\t{%2, %1, %0|%0, %1, %2}
7555 imul{l}\t{%2, %0|%0, %2}"
7556 [(set_attr "type" "imul")
7557 (set_attr "prefix_0f" "0,0,1")
7558 (set (attr "athlon_decode")
7559 (cond [(eq_attr "cpu" "athlon")
7560 (const_string "vector")
7561 (eq_attr "alternative" "1")
7562 (const_string "vector")
7563 (and (eq_attr "alternative" "2")
7564 (match_operand 1 "memory_operand" ""))
7565 (const_string "vector")]
7566 (const_string "direct")))
7567 (set (attr "amdfam10_decode")
7568 (cond [(and (eq_attr "alternative" "0,1")
7569 (match_operand 1 "memory_operand" ""))
7570 (const_string "vector")]
7571 (const_string "direct")))
7572 (set_attr "mode" "SI")])
7574 (define_insn "*mulsi3_1_zext"
7575 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7577 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7578 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7579 (clobber (reg:CC FLAGS_REG))]
7581 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7583 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7584 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7585 imul{l}\t{%2, %k0|%k0, %2}"
7586 [(set_attr "type" "imul")
7587 (set_attr "prefix_0f" "0,0,1")
7588 (set (attr "athlon_decode")
7589 (cond [(eq_attr "cpu" "athlon")
7590 (const_string "vector")
7591 (eq_attr "alternative" "1")
7592 (const_string "vector")
7593 (and (eq_attr "alternative" "2")
7594 (match_operand 1 "memory_operand" ""))
7595 (const_string "vector")]
7596 (const_string "direct")))
7597 (set (attr "amdfam10_decode")
7598 (cond [(and (eq_attr "alternative" "0,1")
7599 (match_operand 1 "memory_operand" ""))
7600 (const_string "vector")]
7601 (const_string "direct")))
7602 (set_attr "mode" "SI")])
7604 (define_expand "mulhi3"
7605 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7606 (mult:HI (match_operand:HI 1 "register_operand" "")
7607 (match_operand:HI 2 "general_operand" "")))
7608 (clobber (reg:CC FLAGS_REG))])]
7609 "TARGET_HIMODE_MATH"
7613 ;; IMUL reg16, reg16, imm8 VectorPath
7614 ;; IMUL reg16, mem16, imm8 VectorPath
7615 ;; IMUL reg16, reg16, imm16 VectorPath
7616 ;; IMUL reg16, mem16, imm16 VectorPath
7617 ;; IMUL reg16, reg16 Direct
7618 ;; IMUL reg16, mem16 Direct
7619 (define_insn "*mulhi3_1"
7620 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7621 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7622 (match_operand:HI 2 "general_operand" "K,i,mr")))
7623 (clobber (reg:CC FLAGS_REG))]
7624 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7626 imul{w}\t{%2, %1, %0|%0, %1, %2}
7627 imul{w}\t{%2, %1, %0|%0, %1, %2}
7628 imul{w}\t{%2, %0|%0, %2}"
7629 [(set_attr "type" "imul")
7630 (set_attr "prefix_0f" "0,0,1")
7631 (set (attr "athlon_decode")
7632 (cond [(eq_attr "cpu" "athlon")
7633 (const_string "vector")
7634 (eq_attr "alternative" "1,2")
7635 (const_string "vector")]
7636 (const_string "direct")))
7637 (set (attr "amdfam10_decode")
7638 (cond [(eq_attr "alternative" "0,1")
7639 (const_string "vector")]
7640 (const_string "direct")))
7641 (set_attr "mode" "HI")])
7643 (define_expand "mulqi3"
7644 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7645 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7646 (match_operand:QI 2 "register_operand" "")))
7647 (clobber (reg:CC FLAGS_REG))])]
7648 "TARGET_QIMODE_MATH"
7655 (define_insn "*mulqi3_1"
7656 [(set (match_operand:QI 0 "register_operand" "=a")
7657 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7658 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7659 (clobber (reg:CC FLAGS_REG))]
7661 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7663 [(set_attr "type" "imul")
7664 (set_attr "length_immediate" "0")
7665 (set (attr "athlon_decode")
7666 (if_then_else (eq_attr "cpu" "athlon")
7667 (const_string "vector")
7668 (const_string "direct")))
7669 (set_attr "amdfam10_decode" "direct")
7670 (set_attr "mode" "QI")])
7672 (define_expand "umulqihi3"
7673 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7674 (mult:HI (zero_extend:HI
7675 (match_operand:QI 1 "nonimmediate_operand" ""))
7677 (match_operand:QI 2 "register_operand" ""))))
7678 (clobber (reg:CC FLAGS_REG))])]
7679 "TARGET_QIMODE_MATH"
7682 (define_insn "*umulqihi3_1"
7683 [(set (match_operand:HI 0 "register_operand" "=a")
7684 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7685 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7686 (clobber (reg:CC FLAGS_REG))]
7688 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7690 [(set_attr "type" "imul")
7691 (set_attr "length_immediate" "0")
7692 (set (attr "athlon_decode")
7693 (if_then_else (eq_attr "cpu" "athlon")
7694 (const_string "vector")
7695 (const_string "direct")))
7696 (set_attr "amdfam10_decode" "direct")
7697 (set_attr "mode" "QI")])
7699 (define_expand "mulqihi3"
7700 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7701 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7702 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7703 (clobber (reg:CC FLAGS_REG))])]
7704 "TARGET_QIMODE_MATH"
7707 (define_insn "*mulqihi3_insn"
7708 [(set (match_operand:HI 0 "register_operand" "=a")
7709 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7710 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7711 (clobber (reg:CC FLAGS_REG))]
7713 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7715 [(set_attr "type" "imul")
7716 (set_attr "length_immediate" "0")
7717 (set (attr "athlon_decode")
7718 (if_then_else (eq_attr "cpu" "athlon")
7719 (const_string "vector")
7720 (const_string "direct")))
7721 (set_attr "amdfam10_decode" "direct")
7722 (set_attr "mode" "QI")])
7724 (define_expand "umulditi3"
7725 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7726 (mult:TI (zero_extend:TI
7727 (match_operand:DI 1 "nonimmediate_operand" ""))
7729 (match_operand:DI 2 "register_operand" ""))))
7730 (clobber (reg:CC FLAGS_REG))])]
7734 (define_insn "*umulditi3_insn"
7735 [(set (match_operand:TI 0 "register_operand" "=A")
7736 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7737 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7738 (clobber (reg:CC FLAGS_REG))]
7740 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7742 [(set_attr "type" "imul")
7743 (set_attr "length_immediate" "0")
7744 (set (attr "athlon_decode")
7745 (if_then_else (eq_attr "cpu" "athlon")
7746 (const_string "vector")
7747 (const_string "double")))
7748 (set_attr "amdfam10_decode" "double")
7749 (set_attr "mode" "DI")])
7751 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7752 (define_expand "umulsidi3"
7753 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7754 (mult:DI (zero_extend:DI
7755 (match_operand:SI 1 "nonimmediate_operand" ""))
7757 (match_operand:SI 2 "register_operand" ""))))
7758 (clobber (reg:CC FLAGS_REG))])]
7762 (define_insn "*umulsidi3_insn"
7763 [(set (match_operand:DI 0 "register_operand" "=A")
7764 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7765 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7766 (clobber (reg:CC FLAGS_REG))]
7768 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7770 [(set_attr "type" "imul")
7771 (set_attr "length_immediate" "0")
7772 (set (attr "athlon_decode")
7773 (if_then_else (eq_attr "cpu" "athlon")
7774 (const_string "vector")
7775 (const_string "double")))
7776 (set_attr "amdfam10_decode" "double")
7777 (set_attr "mode" "SI")])
7779 (define_expand "mulditi3"
7780 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7781 (mult:TI (sign_extend:TI
7782 (match_operand:DI 1 "nonimmediate_operand" ""))
7784 (match_operand:DI 2 "register_operand" ""))))
7785 (clobber (reg:CC FLAGS_REG))])]
7789 (define_insn "*mulditi3_insn"
7790 [(set (match_operand:TI 0 "register_operand" "=A")
7791 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7792 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7793 (clobber (reg:CC FLAGS_REG))]
7795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7797 [(set_attr "type" "imul")
7798 (set_attr "length_immediate" "0")
7799 (set (attr "athlon_decode")
7800 (if_then_else (eq_attr "cpu" "athlon")
7801 (const_string "vector")
7802 (const_string "double")))
7803 (set_attr "amdfam10_decode" "double")
7804 (set_attr "mode" "DI")])
7806 (define_expand "mulsidi3"
7807 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7808 (mult:DI (sign_extend:DI
7809 (match_operand:SI 1 "nonimmediate_operand" ""))
7811 (match_operand:SI 2 "register_operand" ""))))
7812 (clobber (reg:CC FLAGS_REG))])]
7816 (define_insn "*mulsidi3_insn"
7817 [(set (match_operand:DI 0 "register_operand" "=A")
7818 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7819 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7820 (clobber (reg:CC FLAGS_REG))]
7822 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7824 [(set_attr "type" "imul")
7825 (set_attr "length_immediate" "0")
7826 (set (attr "athlon_decode")
7827 (if_then_else (eq_attr "cpu" "athlon")
7828 (const_string "vector")
7829 (const_string "double")))
7830 (set_attr "amdfam10_decode" "double")
7831 (set_attr "mode" "SI")])
7833 (define_expand "umuldi3_highpart"
7834 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7837 (mult:TI (zero_extend:TI
7838 (match_operand:DI 1 "nonimmediate_operand" ""))
7840 (match_operand:DI 2 "register_operand" "")))
7842 (clobber (match_scratch:DI 3 ""))
7843 (clobber (reg:CC FLAGS_REG))])]
7847 (define_insn "*umuldi3_highpart_rex64"
7848 [(set (match_operand:DI 0 "register_operand" "=d")
7851 (mult:TI (zero_extend:TI
7852 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7854 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7856 (clobber (match_scratch:DI 3 "=1"))
7857 (clobber (reg:CC FLAGS_REG))]
7859 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7861 [(set_attr "type" "imul")
7862 (set_attr "length_immediate" "0")
7863 (set (attr "athlon_decode")
7864 (if_then_else (eq_attr "cpu" "athlon")
7865 (const_string "vector")
7866 (const_string "double")))
7867 (set_attr "amdfam10_decode" "double")
7868 (set_attr "mode" "DI")])
7870 (define_expand "umulsi3_highpart"
7871 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7874 (mult:DI (zero_extend:DI
7875 (match_operand:SI 1 "nonimmediate_operand" ""))
7877 (match_operand:SI 2 "register_operand" "")))
7879 (clobber (match_scratch:SI 3 ""))
7880 (clobber (reg:CC FLAGS_REG))])]
7884 (define_insn "*umulsi3_highpart_insn"
7885 [(set (match_operand:SI 0 "register_operand" "=d")
7888 (mult:DI (zero_extend:DI
7889 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7891 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7893 (clobber (match_scratch:SI 3 "=1"))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7897 [(set_attr "type" "imul")
7898 (set_attr "length_immediate" "0")
7899 (set (attr "athlon_decode")
7900 (if_then_else (eq_attr "cpu" "athlon")
7901 (const_string "vector")
7902 (const_string "double")))
7903 (set_attr "amdfam10_decode" "double")
7904 (set_attr "mode" "SI")])
7906 (define_insn "*umulsi3_highpart_zext"
7907 [(set (match_operand:DI 0 "register_operand" "=d")
7908 (zero_extend:DI (truncate:SI
7910 (mult:DI (zero_extend:DI
7911 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7913 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7915 (clobber (match_scratch:SI 3 "=1"))
7916 (clobber (reg:CC FLAGS_REG))]
7918 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7920 [(set_attr "type" "imul")
7921 (set_attr "length_immediate" "0")
7922 (set (attr "athlon_decode")
7923 (if_then_else (eq_attr "cpu" "athlon")
7924 (const_string "vector")
7925 (const_string "double")))
7926 (set_attr "amdfam10_decode" "double")
7927 (set_attr "mode" "SI")])
7929 (define_expand "smuldi3_highpart"
7930 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7933 (mult:TI (sign_extend:TI
7934 (match_operand:DI 1 "nonimmediate_operand" ""))
7936 (match_operand:DI 2 "register_operand" "")))
7938 (clobber (match_scratch:DI 3 ""))
7939 (clobber (reg:CC FLAGS_REG))])]
7943 (define_insn "*smuldi3_highpart_rex64"
7944 [(set (match_operand:DI 0 "register_operand" "=d")
7947 (mult:TI (sign_extend:TI
7948 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7950 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7952 (clobber (match_scratch:DI 3 "=1"))
7953 (clobber (reg:CC FLAGS_REG))]
7955 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7957 [(set_attr "type" "imul")
7958 (set (attr "athlon_decode")
7959 (if_then_else (eq_attr "cpu" "athlon")
7960 (const_string "vector")
7961 (const_string "double")))
7962 (set_attr "amdfam10_decode" "double")
7963 (set_attr "mode" "DI")])
7965 (define_expand "smulsi3_highpart"
7966 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7969 (mult:DI (sign_extend:DI
7970 (match_operand:SI 1 "nonimmediate_operand" ""))
7972 (match_operand:SI 2 "register_operand" "")))
7974 (clobber (match_scratch:SI 3 ""))
7975 (clobber (reg:CC FLAGS_REG))])]
7979 (define_insn "*smulsi3_highpart_insn"
7980 [(set (match_operand:SI 0 "register_operand" "=d")
7983 (mult:DI (sign_extend:DI
7984 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7986 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7988 (clobber (match_scratch:SI 3 "=1"))
7989 (clobber (reg:CC FLAGS_REG))]
7990 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7992 [(set_attr "type" "imul")
7993 (set (attr "athlon_decode")
7994 (if_then_else (eq_attr "cpu" "athlon")
7995 (const_string "vector")
7996 (const_string "double")))
7997 (set_attr "amdfam10_decode" "double")
7998 (set_attr "mode" "SI")])
8000 (define_insn "*smulsi3_highpart_zext"
8001 [(set (match_operand:DI 0 "register_operand" "=d")
8002 (zero_extend:DI (truncate:SI
8004 (mult:DI (sign_extend:DI
8005 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8007 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8009 (clobber (match_scratch:SI 3 "=1"))
8010 (clobber (reg:CC FLAGS_REG))]
8012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8014 [(set_attr "type" "imul")
8015 (set (attr "athlon_decode")
8016 (if_then_else (eq_attr "cpu" "athlon")
8017 (const_string "vector")
8018 (const_string "double")))
8019 (set_attr "amdfam10_decode" "double")
8020 (set_attr "mode" "SI")])
8022 ;; The patterns that match these are at the end of this file.
8024 (define_expand "mulxf3"
8025 [(set (match_operand:XF 0 "register_operand" "")
8026 (mult:XF (match_operand:XF 1 "register_operand" "")
8027 (match_operand:XF 2 "register_operand" "")))]
8031 (define_expand "mul<mode>3"
8032 [(set (match_operand:MODEF 0 "register_operand" "")
8033 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8034 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8035 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8038 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8041 ;; Divide instructions
8043 (define_insn "divqi3"
8044 [(set (match_operand:QI 0 "register_operand" "=a")
8045 (div:QI (match_operand:HI 1 "register_operand" "0")
8046 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8047 (clobber (reg:CC FLAGS_REG))]
8048 "TARGET_QIMODE_MATH"
8050 [(set_attr "type" "idiv")
8051 (set_attr "mode" "QI")])
8053 (define_insn "udivqi3"
8054 [(set (match_operand:QI 0 "register_operand" "=a")
8055 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8056 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8057 (clobber (reg:CC FLAGS_REG))]
8058 "TARGET_QIMODE_MATH"
8060 [(set_attr "type" "idiv")
8061 (set_attr "mode" "QI")])
8063 ;; The patterns that match these are at the end of this file.
8065 (define_expand "divxf3"
8066 [(set (match_operand:XF 0 "register_operand" "")
8067 (div:XF (match_operand:XF 1 "register_operand" "")
8068 (match_operand:XF 2 "register_operand" "")))]
8072 (define_expand "divdf3"
8073 [(set (match_operand:DF 0 "register_operand" "")
8074 (div:DF (match_operand:DF 1 "register_operand" "")
8075 (match_operand:DF 2 "nonimmediate_operand" "")))]
8076 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8079 (define_expand "divsf3"
8080 [(set (match_operand:SF 0 "register_operand" "")
8081 (div:SF (match_operand:SF 1 "register_operand" "")
8082 (match_operand:SF 2 "nonimmediate_operand" "")))]
8083 "TARGET_80387 || TARGET_SSE_MATH"
8085 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8086 && flag_finite_math_only && !flag_trapping_math
8087 && flag_unsafe_math_optimizations)
8089 ix86_emit_swdivsf (operands[0], operands[1],
8090 operands[2], SFmode);
8095 ;; Remainder instructions.
8097 (define_expand "divmoddi4"
8098 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8099 (div:DI (match_operand:DI 1 "register_operand" "")
8100 (match_operand:DI 2 "nonimmediate_operand" "")))
8101 (set (match_operand:DI 3 "register_operand" "")
8102 (mod:DI (match_dup 1) (match_dup 2)))
8103 (clobber (reg:CC FLAGS_REG))])]
8107 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8108 ;; Penalize eax case slightly because it results in worse scheduling
8110 (define_insn "*divmoddi4_nocltd_rex64"
8111 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8112 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8113 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8114 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8115 (mod:DI (match_dup 2) (match_dup 3)))
8116 (clobber (reg:CC FLAGS_REG))]
8117 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8119 [(set_attr "type" "multi")])
8121 (define_insn "*divmoddi4_cltd_rex64"
8122 [(set (match_operand:DI 0 "register_operand" "=a")
8123 (div:DI (match_operand:DI 2 "register_operand" "a")
8124 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8125 (set (match_operand:DI 1 "register_operand" "=&d")
8126 (mod:DI (match_dup 2) (match_dup 3)))
8127 (clobber (reg:CC FLAGS_REG))]
8128 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8130 [(set_attr "type" "multi")])
8132 (define_insn "*divmoddi_noext_rex64"
8133 [(set (match_operand:DI 0 "register_operand" "=a")
8134 (div:DI (match_operand:DI 1 "register_operand" "0")
8135 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8136 (set (match_operand:DI 3 "register_operand" "=d")
8137 (mod:DI (match_dup 1) (match_dup 2)))
8138 (use (match_operand:DI 4 "register_operand" "3"))
8139 (clobber (reg:CC FLAGS_REG))]
8142 [(set_attr "type" "idiv")
8143 (set_attr "mode" "DI")])
8146 [(set (match_operand:DI 0 "register_operand" "")
8147 (div:DI (match_operand:DI 1 "register_operand" "")
8148 (match_operand:DI 2 "nonimmediate_operand" "")))
8149 (set (match_operand:DI 3 "register_operand" "")
8150 (mod:DI (match_dup 1) (match_dup 2)))
8151 (clobber (reg:CC FLAGS_REG))]
8152 "TARGET_64BIT && reload_completed"
8153 [(parallel [(set (match_dup 3)
8154 (ashiftrt:DI (match_dup 4) (const_int 63)))
8155 (clobber (reg:CC FLAGS_REG))])
8156 (parallel [(set (match_dup 0)
8157 (div:DI (reg:DI 0) (match_dup 2)))
8159 (mod:DI (reg:DI 0) (match_dup 2)))
8161 (clobber (reg:CC FLAGS_REG))])]
8163 /* Avoid use of cltd in favor of a mov+shift. */
8164 if (!TARGET_USE_CLTD && !optimize_size)
8166 if (true_regnum (operands[1]))
8167 emit_move_insn (operands[0], operands[1]);
8169 emit_move_insn (operands[3], operands[1]);
8170 operands[4] = operands[3];
8174 gcc_assert (!true_regnum (operands[1]));
8175 operands[4] = operands[1];
8180 (define_expand "divmodsi4"
8181 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8182 (div:SI (match_operand:SI 1 "register_operand" "")
8183 (match_operand:SI 2 "nonimmediate_operand" "")))
8184 (set (match_operand:SI 3 "register_operand" "")
8185 (mod:SI (match_dup 1) (match_dup 2)))
8186 (clobber (reg:CC FLAGS_REG))])]
8190 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8191 ;; Penalize eax case slightly because it results in worse scheduling
8193 (define_insn "*divmodsi4_nocltd"
8194 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8195 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8196 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8197 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8198 (mod:SI (match_dup 2) (match_dup 3)))
8199 (clobber (reg:CC FLAGS_REG))]
8200 "!optimize_size && !TARGET_USE_CLTD"
8202 [(set_attr "type" "multi")])
8204 (define_insn "*divmodsi4_cltd"
8205 [(set (match_operand:SI 0 "register_operand" "=a")
8206 (div:SI (match_operand:SI 2 "register_operand" "a")
8207 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8208 (set (match_operand:SI 1 "register_operand" "=&d")
8209 (mod:SI (match_dup 2) (match_dup 3)))
8210 (clobber (reg:CC FLAGS_REG))]
8211 "optimize_size || TARGET_USE_CLTD"
8213 [(set_attr "type" "multi")])
8215 (define_insn "*divmodsi_noext"
8216 [(set (match_operand:SI 0 "register_operand" "=a")
8217 (div:SI (match_operand:SI 1 "register_operand" "0")
8218 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8219 (set (match_operand:SI 3 "register_operand" "=d")
8220 (mod:SI (match_dup 1) (match_dup 2)))
8221 (use (match_operand:SI 4 "register_operand" "3"))
8222 (clobber (reg:CC FLAGS_REG))]
8225 [(set_attr "type" "idiv")
8226 (set_attr "mode" "SI")])
8229 [(set (match_operand:SI 0 "register_operand" "")
8230 (div:SI (match_operand:SI 1 "register_operand" "")
8231 (match_operand:SI 2 "nonimmediate_operand" "")))
8232 (set (match_operand:SI 3 "register_operand" "")
8233 (mod:SI (match_dup 1) (match_dup 2)))
8234 (clobber (reg:CC FLAGS_REG))]
8236 [(parallel [(set (match_dup 3)
8237 (ashiftrt:SI (match_dup 4) (const_int 31)))
8238 (clobber (reg:CC FLAGS_REG))])
8239 (parallel [(set (match_dup 0)
8240 (div:SI (reg:SI 0) (match_dup 2)))
8242 (mod:SI (reg:SI 0) (match_dup 2)))
8244 (clobber (reg:CC FLAGS_REG))])]
8246 /* Avoid use of cltd in favor of a mov+shift. */
8247 if (!TARGET_USE_CLTD && !optimize_size)
8249 if (true_regnum (operands[1]))
8250 emit_move_insn (operands[0], operands[1]);
8252 emit_move_insn (operands[3], operands[1]);
8253 operands[4] = operands[3];
8257 gcc_assert (!true_regnum (operands[1]));
8258 operands[4] = operands[1];
8262 (define_insn "divmodhi4"
8263 [(set (match_operand:HI 0 "register_operand" "=a")
8264 (div:HI (match_operand:HI 1 "register_operand" "0")
8265 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8266 (set (match_operand:HI 3 "register_operand" "=&d")
8267 (mod:HI (match_dup 1) (match_dup 2)))
8268 (clobber (reg:CC FLAGS_REG))]
8269 "TARGET_HIMODE_MATH"
8271 [(set_attr "type" "multi")
8272 (set_attr "length_immediate" "0")
8273 (set_attr "mode" "SI")])
8275 (define_insn "udivmoddi4"
8276 [(set (match_operand:DI 0 "register_operand" "=a")
8277 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8278 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8279 (set (match_operand:DI 3 "register_operand" "=&d")
8280 (umod:DI (match_dup 1) (match_dup 2)))
8281 (clobber (reg:CC FLAGS_REG))]
8283 "xor{q}\t%3, %3\;div{q}\t%2"
8284 [(set_attr "type" "multi")
8285 (set_attr "length_immediate" "0")
8286 (set_attr "mode" "DI")])
8288 (define_insn "*udivmoddi4_noext"
8289 [(set (match_operand:DI 0 "register_operand" "=a")
8290 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8291 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8292 (set (match_operand:DI 3 "register_operand" "=d")
8293 (umod:DI (match_dup 1) (match_dup 2)))
8295 (clobber (reg:CC FLAGS_REG))]
8298 [(set_attr "type" "idiv")
8299 (set_attr "mode" "DI")])
8302 [(set (match_operand:DI 0 "register_operand" "")
8303 (udiv:DI (match_operand:DI 1 "register_operand" "")
8304 (match_operand:DI 2 "nonimmediate_operand" "")))
8305 (set (match_operand:DI 3 "register_operand" "")
8306 (umod:DI (match_dup 1) (match_dup 2)))
8307 (clobber (reg:CC FLAGS_REG))]
8308 "TARGET_64BIT && reload_completed"
8309 [(set (match_dup 3) (const_int 0))
8310 (parallel [(set (match_dup 0)
8311 (udiv:DI (match_dup 1) (match_dup 2)))
8313 (umod:DI (match_dup 1) (match_dup 2)))
8315 (clobber (reg:CC FLAGS_REG))])]
8318 (define_insn "udivmodsi4"
8319 [(set (match_operand:SI 0 "register_operand" "=a")
8320 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8321 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8322 (set (match_operand:SI 3 "register_operand" "=&d")
8323 (umod:SI (match_dup 1) (match_dup 2)))
8324 (clobber (reg:CC FLAGS_REG))]
8326 "xor{l}\t%3, %3\;div{l}\t%2"
8327 [(set_attr "type" "multi")
8328 (set_attr "length_immediate" "0")
8329 (set_attr "mode" "SI")])
8331 (define_insn "*udivmodsi4_noext"
8332 [(set (match_operand:SI 0 "register_operand" "=a")
8333 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8334 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8335 (set (match_operand:SI 3 "register_operand" "=d")
8336 (umod:SI (match_dup 1) (match_dup 2)))
8338 (clobber (reg:CC FLAGS_REG))]
8341 [(set_attr "type" "idiv")
8342 (set_attr "mode" "SI")])
8345 [(set (match_operand:SI 0 "register_operand" "")
8346 (udiv:SI (match_operand:SI 1 "register_operand" "")
8347 (match_operand:SI 2 "nonimmediate_operand" "")))
8348 (set (match_operand:SI 3 "register_operand" "")
8349 (umod:SI (match_dup 1) (match_dup 2)))
8350 (clobber (reg:CC FLAGS_REG))]
8352 [(set (match_dup 3) (const_int 0))
8353 (parallel [(set (match_dup 0)
8354 (udiv:SI (match_dup 1) (match_dup 2)))
8356 (umod:SI (match_dup 1) (match_dup 2)))
8358 (clobber (reg:CC FLAGS_REG))])]
8361 (define_expand "udivmodhi4"
8362 [(set (match_dup 4) (const_int 0))
8363 (parallel [(set (match_operand:HI 0 "register_operand" "")
8364 (udiv:HI (match_operand:HI 1 "register_operand" "")
8365 (match_operand:HI 2 "nonimmediate_operand" "")))
8366 (set (match_operand:HI 3 "register_operand" "")
8367 (umod:HI (match_dup 1) (match_dup 2)))
8369 (clobber (reg:CC FLAGS_REG))])]
8370 "TARGET_HIMODE_MATH"
8371 "operands[4] = gen_reg_rtx (HImode);")
8373 (define_insn "*udivmodhi_noext"
8374 [(set (match_operand:HI 0 "register_operand" "=a")
8375 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8376 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8377 (set (match_operand:HI 3 "register_operand" "=d")
8378 (umod:HI (match_dup 1) (match_dup 2)))
8379 (use (match_operand:HI 4 "register_operand" "3"))
8380 (clobber (reg:CC FLAGS_REG))]
8383 [(set_attr "type" "idiv")
8384 (set_attr "mode" "HI")])
8386 ;; We cannot use div/idiv for double division, because it causes
8387 ;; "division by zero" on the overflow and that's not what we expect
8388 ;; from truncate. Because true (non truncating) double division is
8389 ;; never generated, we can't create this insn anyway.
8392 ; [(set (match_operand:SI 0 "register_operand" "=a")
8394 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8396 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8397 ; (set (match_operand:SI 3 "register_operand" "=d")
8399 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8400 ; (clobber (reg:CC FLAGS_REG))]
8402 ; "div{l}\t{%2, %0|%0, %2}"
8403 ; [(set_attr "type" "idiv")])
8405 ;;- Logical AND instructions
8407 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8408 ;; Note that this excludes ah.
8410 (define_insn "*testdi_1_rex64"
8411 [(set (reg FLAGS_REG)
8413 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8414 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8416 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8417 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8419 test{l}\t{%k1, %k0|%k0, %k1}
8420 test{l}\t{%k1, %k0|%k0, %k1}
8421 test{q}\t{%1, %0|%0, %1}
8422 test{q}\t{%1, %0|%0, %1}
8423 test{q}\t{%1, %0|%0, %1}"
8424 [(set_attr "type" "test")
8425 (set_attr "modrm" "0,1,0,1,1")
8426 (set_attr "mode" "SI,SI,DI,DI,DI")
8427 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8429 (define_insn "testsi_1"
8430 [(set (reg FLAGS_REG)
8432 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8433 (match_operand:SI 1 "general_operand" "in,in,rin"))
8435 "ix86_match_ccmode (insn, CCNOmode)
8436 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8437 "test{l}\t{%1, %0|%0, %1}"
8438 [(set_attr "type" "test")
8439 (set_attr "modrm" "0,1,1")
8440 (set_attr "mode" "SI")
8441 (set_attr "pent_pair" "uv,np,uv")])
8443 (define_expand "testsi_ccno_1"
8444 [(set (reg:CCNO FLAGS_REG)
8446 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8447 (match_operand:SI 1 "nonmemory_operand" ""))
8452 (define_insn "*testhi_1"
8453 [(set (reg FLAGS_REG)
8454 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8455 (match_operand:HI 1 "general_operand" "n,n,rn"))
8457 "ix86_match_ccmode (insn, CCNOmode)
8458 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8459 "test{w}\t{%1, %0|%0, %1}"
8460 [(set_attr "type" "test")
8461 (set_attr "modrm" "0,1,1")
8462 (set_attr "mode" "HI")
8463 (set_attr "pent_pair" "uv,np,uv")])
8465 (define_expand "testqi_ccz_1"
8466 [(set (reg:CCZ FLAGS_REG)
8467 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8468 (match_operand:QI 1 "nonmemory_operand" ""))
8473 (define_insn "*testqi_1_maybe_si"
8474 [(set (reg FLAGS_REG)
8477 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8478 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8480 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8481 && ix86_match_ccmode (insn,
8482 CONST_INT_P (operands[1])
8483 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8485 if (which_alternative == 3)
8487 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8488 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8489 return "test{l}\t{%1, %k0|%k0, %1}";
8491 return "test{b}\t{%1, %0|%0, %1}";
8493 [(set_attr "type" "test")
8494 (set_attr "modrm" "0,1,1,1")
8495 (set_attr "mode" "QI,QI,QI,SI")
8496 (set_attr "pent_pair" "uv,np,uv,np")])
8498 (define_insn "*testqi_1"
8499 [(set (reg FLAGS_REG)
8502 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8503 (match_operand:QI 1 "general_operand" "n,n,qn"))
8505 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8506 && ix86_match_ccmode (insn, CCNOmode)"
8507 "test{b}\t{%1, %0|%0, %1}"
8508 [(set_attr "type" "test")
8509 (set_attr "modrm" "0,1,1")
8510 (set_attr "mode" "QI")
8511 (set_attr "pent_pair" "uv,np,uv")])
8513 (define_expand "testqi_ext_ccno_0"
8514 [(set (reg:CCNO FLAGS_REG)
8518 (match_operand 0 "ext_register_operand" "")
8521 (match_operand 1 "const_int_operand" ""))
8526 (define_insn "*testqi_ext_0"
8527 [(set (reg FLAGS_REG)
8531 (match_operand 0 "ext_register_operand" "Q")
8534 (match_operand 1 "const_int_operand" "n"))
8536 "ix86_match_ccmode (insn, CCNOmode)"
8537 "test{b}\t{%1, %h0|%h0, %1}"
8538 [(set_attr "type" "test")
8539 (set_attr "mode" "QI")
8540 (set_attr "length_immediate" "1")
8541 (set_attr "pent_pair" "np")])
8543 (define_insn "*testqi_ext_1"
8544 [(set (reg FLAGS_REG)
8548 (match_operand 0 "ext_register_operand" "Q")
8552 (match_operand:QI 1 "general_operand" "Qm")))
8554 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8555 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8556 "test{b}\t{%1, %h0|%h0, %1}"
8557 [(set_attr "type" "test")
8558 (set_attr "mode" "QI")])
8560 (define_insn "*testqi_ext_1_rex64"
8561 [(set (reg FLAGS_REG)
8565 (match_operand 0 "ext_register_operand" "Q")
8569 (match_operand:QI 1 "register_operand" "Q")))
8571 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8572 "test{b}\t{%1, %h0|%h0, %1}"
8573 [(set_attr "type" "test")
8574 (set_attr "mode" "QI")])
8576 (define_insn "*testqi_ext_2"
8577 [(set (reg FLAGS_REG)
8581 (match_operand 0 "ext_register_operand" "Q")
8585 (match_operand 1 "ext_register_operand" "Q")
8589 "ix86_match_ccmode (insn, CCNOmode)"
8590 "test{b}\t{%h1, %h0|%h0, %h1}"
8591 [(set_attr "type" "test")
8592 (set_attr "mode" "QI")])
8594 ;; Combine likes to form bit extractions for some tests. Humor it.
8595 (define_insn "*testqi_ext_3"
8596 [(set (reg FLAGS_REG)
8597 (compare (zero_extract:SI
8598 (match_operand 0 "nonimmediate_operand" "rm")
8599 (match_operand:SI 1 "const_int_operand" "")
8600 (match_operand:SI 2 "const_int_operand" ""))
8602 "ix86_match_ccmode (insn, CCNOmode)
8603 && INTVAL (operands[1]) > 0
8604 && INTVAL (operands[2]) >= 0
8605 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8606 && (GET_MODE (operands[0]) == SImode
8607 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8608 || GET_MODE (operands[0]) == HImode
8609 || GET_MODE (operands[0]) == QImode)"
8612 (define_insn "*testqi_ext_3_rex64"
8613 [(set (reg FLAGS_REG)
8614 (compare (zero_extract:DI
8615 (match_operand 0 "nonimmediate_operand" "rm")
8616 (match_operand:DI 1 "const_int_operand" "")
8617 (match_operand:DI 2 "const_int_operand" ""))
8620 && ix86_match_ccmode (insn, CCNOmode)
8621 && INTVAL (operands[1]) > 0
8622 && INTVAL (operands[2]) >= 0
8623 /* Ensure that resulting mask is zero or sign extended operand. */
8624 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8625 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8626 && INTVAL (operands[1]) > 32))
8627 && (GET_MODE (operands[0]) == SImode
8628 || GET_MODE (operands[0]) == DImode
8629 || GET_MODE (operands[0]) == HImode
8630 || GET_MODE (operands[0]) == QImode)"
8634 [(set (match_operand 0 "flags_reg_operand" "")
8635 (match_operator 1 "compare_operator"
8637 (match_operand 2 "nonimmediate_operand" "")
8638 (match_operand 3 "const_int_operand" "")
8639 (match_operand 4 "const_int_operand" ""))
8641 "ix86_match_ccmode (insn, CCNOmode)"
8642 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8644 rtx val = operands[2];
8645 HOST_WIDE_INT len = INTVAL (operands[3]);
8646 HOST_WIDE_INT pos = INTVAL (operands[4]);
8648 enum machine_mode mode, submode;
8650 mode = GET_MODE (val);
8653 /* ??? Combine likes to put non-volatile mem extractions in QImode
8654 no matter the size of the test. So find a mode that works. */
8655 if (! MEM_VOLATILE_P (val))
8657 mode = smallest_mode_for_size (pos + len, MODE_INT);
8658 val = adjust_address (val, mode, 0);
8661 else if (GET_CODE (val) == SUBREG
8662 && (submode = GET_MODE (SUBREG_REG (val)),
8663 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8664 && pos + len <= GET_MODE_BITSIZE (submode))
8666 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8668 val = SUBREG_REG (val);
8670 else if (mode == HImode && pos + len <= 8)
8672 /* Small HImode tests can be converted to QImode. */
8674 val = gen_lowpart (QImode, val);
8677 if (len == HOST_BITS_PER_WIDE_INT)
8680 mask = ((HOST_WIDE_INT)1 << len) - 1;
8683 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8686 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8687 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8688 ;; this is relatively important trick.
8689 ;; Do the conversion only post-reload to avoid limiting of the register class
8692 [(set (match_operand 0 "flags_reg_operand" "")
8693 (match_operator 1 "compare_operator"
8694 [(and (match_operand 2 "register_operand" "")
8695 (match_operand 3 "const_int_operand" ""))
8698 && QI_REG_P (operands[2])
8699 && GET_MODE (operands[2]) != QImode
8700 && ((ix86_match_ccmode (insn, CCZmode)
8701 && !(INTVAL (operands[3]) & ~(255 << 8)))
8702 || (ix86_match_ccmode (insn, CCNOmode)
8703 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8706 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8709 "operands[2] = gen_lowpart (SImode, operands[2]);
8710 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8713 [(set (match_operand 0 "flags_reg_operand" "")
8714 (match_operator 1 "compare_operator"
8715 [(and (match_operand 2 "nonimmediate_operand" "")
8716 (match_operand 3 "const_int_operand" ""))
8719 && GET_MODE (operands[2]) != QImode
8720 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8721 && ((ix86_match_ccmode (insn, CCZmode)
8722 && !(INTVAL (operands[3]) & ~255))
8723 || (ix86_match_ccmode (insn, CCNOmode)
8724 && !(INTVAL (operands[3]) & ~127)))"
8726 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8728 "operands[2] = gen_lowpart (QImode, operands[2]);
8729 operands[3] = gen_lowpart (QImode, operands[3]);")
8732 ;; %%% This used to optimize known byte-wide and operations to memory,
8733 ;; and sometimes to QImode registers. If this is considered useful,
8734 ;; it should be done with splitters.
8736 (define_expand "anddi3"
8737 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8738 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8739 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8740 (clobber (reg:CC FLAGS_REG))]
8742 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8744 (define_insn "*anddi_1_rex64"
8745 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8746 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8747 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8748 (clobber (reg:CC FLAGS_REG))]
8749 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8751 switch (get_attr_type (insn))
8755 enum machine_mode mode;
8757 gcc_assert (CONST_INT_P (operands[2]));
8758 if (INTVAL (operands[2]) == 0xff)
8762 gcc_assert (INTVAL (operands[2]) == 0xffff);
8766 operands[1] = gen_lowpart (mode, operands[1]);
8768 return "movz{bq|x}\t{%1,%0|%0, %1}";
8770 return "movz{wq|x}\t{%1,%0|%0, %1}";
8774 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8775 if (get_attr_mode (insn) == MODE_SI)
8776 return "and{l}\t{%k2, %k0|%k0, %k2}";
8778 return "and{q}\t{%2, %0|%0, %2}";
8781 [(set_attr "type" "alu,alu,alu,imovx")
8782 (set_attr "length_immediate" "*,*,*,0")
8783 (set_attr "mode" "SI,DI,DI,DI")])
8785 (define_insn "*anddi_2"
8786 [(set (reg FLAGS_REG)
8787 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8788 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8790 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8791 (and:DI (match_dup 1) (match_dup 2)))]
8792 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8793 && ix86_binary_operator_ok (AND, DImode, operands)"
8795 and{l}\t{%k2, %k0|%k0, %k2}
8796 and{q}\t{%2, %0|%0, %2}
8797 and{q}\t{%2, %0|%0, %2}"
8798 [(set_attr "type" "alu")
8799 (set_attr "mode" "SI,DI,DI")])
8801 (define_expand "andsi3"
8802 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8803 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8804 (match_operand:SI 2 "general_operand" "")))
8805 (clobber (reg:CC FLAGS_REG))]
8807 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8809 (define_insn "*andsi_1"
8810 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8811 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8812 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8813 (clobber (reg:CC FLAGS_REG))]
8814 "ix86_binary_operator_ok (AND, SImode, operands)"
8816 switch (get_attr_type (insn))
8820 enum machine_mode mode;
8822 gcc_assert (CONST_INT_P (operands[2]));
8823 if (INTVAL (operands[2]) == 0xff)
8827 gcc_assert (INTVAL (operands[2]) == 0xffff);
8831 operands[1] = gen_lowpart (mode, operands[1]);
8833 return "movz{bl|x}\t{%1,%0|%0, %1}";
8835 return "movz{wl|x}\t{%1,%0|%0, %1}";
8839 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8840 return "and{l}\t{%2, %0|%0, %2}";
8843 [(set_attr "type" "alu,alu,imovx")
8844 (set_attr "length_immediate" "*,*,0")
8845 (set_attr "mode" "SI")])
8848 [(set (match_operand 0 "register_operand" "")
8850 (const_int -65536)))
8851 (clobber (reg:CC FLAGS_REG))]
8852 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8853 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8854 "operands[1] = gen_lowpart (HImode, operands[0]);")
8857 [(set (match_operand 0 "ext_register_operand" "")
8860 (clobber (reg:CC FLAGS_REG))]
8861 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8862 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8863 "operands[1] = gen_lowpart (QImode, operands[0]);")
8866 [(set (match_operand 0 "ext_register_operand" "")
8868 (const_int -65281)))
8869 (clobber (reg:CC FLAGS_REG))]
8870 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8871 [(parallel [(set (zero_extract:SI (match_dup 0)
8875 (zero_extract:SI (match_dup 0)
8878 (zero_extract:SI (match_dup 0)
8881 (clobber (reg:CC FLAGS_REG))])]
8882 "operands[0] = gen_lowpart (SImode, operands[0]);")
8884 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8885 (define_insn "*andsi_1_zext"
8886 [(set (match_operand:DI 0 "register_operand" "=r")
8888 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8889 (match_operand:SI 2 "general_operand" "g"))))
8890 (clobber (reg:CC FLAGS_REG))]
8891 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8892 "and{l}\t{%2, %k0|%k0, %2}"
8893 [(set_attr "type" "alu")
8894 (set_attr "mode" "SI")])
8896 (define_insn "*andsi_2"
8897 [(set (reg FLAGS_REG)
8898 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8899 (match_operand:SI 2 "general_operand" "g,ri"))
8901 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8902 (and:SI (match_dup 1) (match_dup 2)))]
8903 "ix86_match_ccmode (insn, CCNOmode)
8904 && ix86_binary_operator_ok (AND, SImode, operands)"
8905 "and{l}\t{%2, %0|%0, %2}"
8906 [(set_attr "type" "alu")
8907 (set_attr "mode" "SI")])
8909 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8910 (define_insn "*andsi_2_zext"
8911 [(set (reg FLAGS_REG)
8912 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8913 (match_operand:SI 2 "general_operand" "g"))
8915 (set (match_operand:DI 0 "register_operand" "=r")
8916 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8917 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8918 && ix86_binary_operator_ok (AND, SImode, operands)"
8919 "and{l}\t{%2, %k0|%k0, %2}"
8920 [(set_attr "type" "alu")
8921 (set_attr "mode" "SI")])
8923 (define_expand "andhi3"
8924 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8925 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8926 (match_operand:HI 2 "general_operand" "")))
8927 (clobber (reg:CC FLAGS_REG))]
8928 "TARGET_HIMODE_MATH"
8929 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8931 (define_insn "*andhi_1"
8932 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8933 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8934 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8935 (clobber (reg:CC FLAGS_REG))]
8936 "ix86_binary_operator_ok (AND, HImode, operands)"
8938 switch (get_attr_type (insn))
8941 gcc_assert (CONST_INT_P (operands[2]));
8942 gcc_assert (INTVAL (operands[2]) == 0xff);
8943 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8946 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8948 return "and{w}\t{%2, %0|%0, %2}";
8951 [(set_attr "type" "alu,alu,imovx")
8952 (set_attr "length_immediate" "*,*,0")
8953 (set_attr "mode" "HI,HI,SI")])
8955 (define_insn "*andhi_2"
8956 [(set (reg FLAGS_REG)
8957 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8958 (match_operand:HI 2 "general_operand" "g,ri"))
8960 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8961 (and:HI (match_dup 1) (match_dup 2)))]
8962 "ix86_match_ccmode (insn, CCNOmode)
8963 && ix86_binary_operator_ok (AND, HImode, operands)"
8964 "and{w}\t{%2, %0|%0, %2}"
8965 [(set_attr "type" "alu")
8966 (set_attr "mode" "HI")])
8968 (define_expand "andqi3"
8969 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8970 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8971 (match_operand:QI 2 "general_operand" "")))
8972 (clobber (reg:CC FLAGS_REG))]
8973 "TARGET_QIMODE_MATH"
8974 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8976 ;; %%% Potential partial reg stall on alternative 2. What to do?
8977 (define_insn "*andqi_1"
8978 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8979 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8980 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8981 (clobber (reg:CC FLAGS_REG))]
8982 "ix86_binary_operator_ok (AND, QImode, operands)"
8984 and{b}\t{%2, %0|%0, %2}
8985 and{b}\t{%2, %0|%0, %2}
8986 and{l}\t{%k2, %k0|%k0, %k2}"
8987 [(set_attr "type" "alu")
8988 (set_attr "mode" "QI,QI,SI")])
8990 (define_insn "*andqi_1_slp"
8991 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8992 (and:QI (match_dup 0)
8993 (match_operand:QI 1 "general_operand" "qi,qmi")))
8994 (clobber (reg:CC FLAGS_REG))]
8995 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8996 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8997 "and{b}\t{%1, %0|%0, %1}"
8998 [(set_attr "type" "alu1")
8999 (set_attr "mode" "QI")])
9001 (define_insn "*andqi_2_maybe_si"
9002 [(set (reg FLAGS_REG)
9004 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9005 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9007 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9008 (and:QI (match_dup 1) (match_dup 2)))]
9009 "ix86_binary_operator_ok (AND, QImode, operands)
9010 && ix86_match_ccmode (insn,
9011 CONST_INT_P (operands[2])
9012 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9014 if (which_alternative == 2)
9016 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9017 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9018 return "and{l}\t{%2, %k0|%k0, %2}";
9020 return "and{b}\t{%2, %0|%0, %2}";
9022 [(set_attr "type" "alu")
9023 (set_attr "mode" "QI,QI,SI")])
9025 (define_insn "*andqi_2"
9026 [(set (reg FLAGS_REG)
9028 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9029 (match_operand:QI 2 "general_operand" "qim,qi"))
9031 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9032 (and:QI (match_dup 1) (match_dup 2)))]
9033 "ix86_match_ccmode (insn, CCNOmode)
9034 && ix86_binary_operator_ok (AND, QImode, operands)"
9035 "and{b}\t{%2, %0|%0, %2}"
9036 [(set_attr "type" "alu")
9037 (set_attr "mode" "QI")])
9039 (define_insn "*andqi_2_slp"
9040 [(set (reg FLAGS_REG)
9042 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9043 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9045 (set (strict_low_part (match_dup 0))
9046 (and:QI (match_dup 0) (match_dup 1)))]
9047 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9048 && ix86_match_ccmode (insn, CCNOmode)
9049 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9050 "and{b}\t{%1, %0|%0, %1}"
9051 [(set_attr "type" "alu1")
9052 (set_attr "mode" "QI")])
9054 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9055 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9056 ;; for a QImode operand, which of course failed.
9058 (define_insn "andqi_ext_0"
9059 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9064 (match_operand 1 "ext_register_operand" "0")
9067 (match_operand 2 "const_int_operand" "n")))
9068 (clobber (reg:CC FLAGS_REG))]
9070 "and{b}\t{%2, %h0|%h0, %2}"
9071 [(set_attr "type" "alu")
9072 (set_attr "length_immediate" "1")
9073 (set_attr "mode" "QI")])
9075 ;; Generated by peephole translating test to and. This shows up
9076 ;; often in fp comparisons.
9078 (define_insn "*andqi_ext_0_cc"
9079 [(set (reg FLAGS_REG)
9083 (match_operand 1 "ext_register_operand" "0")
9086 (match_operand 2 "const_int_operand" "n"))
9088 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9097 "ix86_match_ccmode (insn, CCNOmode)"
9098 "and{b}\t{%2, %h0|%h0, %2}"
9099 [(set_attr "type" "alu")
9100 (set_attr "length_immediate" "1")
9101 (set_attr "mode" "QI")])
9103 (define_insn "*andqi_ext_1"
9104 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9109 (match_operand 1 "ext_register_operand" "0")
9113 (match_operand:QI 2 "general_operand" "Qm"))))
9114 (clobber (reg:CC FLAGS_REG))]
9116 "and{b}\t{%2, %h0|%h0, %2}"
9117 [(set_attr "type" "alu")
9118 (set_attr "length_immediate" "0")
9119 (set_attr "mode" "QI")])
9121 (define_insn "*andqi_ext_1_rex64"
9122 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9127 (match_operand 1 "ext_register_operand" "0")
9131 (match_operand 2 "ext_register_operand" "Q"))))
9132 (clobber (reg:CC FLAGS_REG))]
9134 "and{b}\t{%2, %h0|%h0, %2}"
9135 [(set_attr "type" "alu")
9136 (set_attr "length_immediate" "0")
9137 (set_attr "mode" "QI")])
9139 (define_insn "*andqi_ext_2"
9140 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9145 (match_operand 1 "ext_register_operand" "%0")
9149 (match_operand 2 "ext_register_operand" "Q")
9152 (clobber (reg:CC FLAGS_REG))]
9154 "and{b}\t{%h2, %h0|%h0, %h2}"
9155 [(set_attr "type" "alu")
9156 (set_attr "length_immediate" "0")
9157 (set_attr "mode" "QI")])
9159 ;; Convert wide AND instructions with immediate operand to shorter QImode
9160 ;; equivalents when possible.
9161 ;; Don't do the splitting with memory operands, since it introduces risk
9162 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9163 ;; for size, but that can (should?) be handled by generic code instead.
9165 [(set (match_operand 0 "register_operand" "")
9166 (and (match_operand 1 "register_operand" "")
9167 (match_operand 2 "const_int_operand" "")))
9168 (clobber (reg:CC FLAGS_REG))]
9170 && QI_REG_P (operands[0])
9171 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9172 && !(~INTVAL (operands[2]) & ~(255 << 8))
9173 && GET_MODE (operands[0]) != QImode"
9174 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9175 (and:SI (zero_extract:SI (match_dup 1)
9176 (const_int 8) (const_int 8))
9178 (clobber (reg:CC FLAGS_REG))])]
9179 "operands[0] = gen_lowpart (SImode, operands[0]);
9180 operands[1] = gen_lowpart (SImode, operands[1]);
9181 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9183 ;; Since AND can be encoded with sign extended immediate, this is only
9184 ;; profitable when 7th bit is not set.
9186 [(set (match_operand 0 "register_operand" "")
9187 (and (match_operand 1 "general_operand" "")
9188 (match_operand 2 "const_int_operand" "")))
9189 (clobber (reg:CC FLAGS_REG))]
9191 && ANY_QI_REG_P (operands[0])
9192 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9193 && !(~INTVAL (operands[2]) & ~255)
9194 && !(INTVAL (operands[2]) & 128)
9195 && GET_MODE (operands[0]) != QImode"
9196 [(parallel [(set (strict_low_part (match_dup 0))
9197 (and:QI (match_dup 1)
9199 (clobber (reg:CC FLAGS_REG))])]
9200 "operands[0] = gen_lowpart (QImode, operands[0]);
9201 operands[1] = gen_lowpart (QImode, operands[1]);
9202 operands[2] = gen_lowpart (QImode, operands[2]);")
9204 ;; Logical inclusive OR instructions
9206 ;; %%% This used to optimize known byte-wide and operations to memory.
9207 ;; If this is considered useful, it should be done with splitters.
9209 (define_expand "iordi3"
9210 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9211 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9212 (match_operand:DI 2 "x86_64_general_operand" "")))
9213 (clobber (reg:CC FLAGS_REG))]
9215 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9217 (define_insn "*iordi_1_rex64"
9218 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9219 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9220 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9221 (clobber (reg:CC FLAGS_REG))]
9223 && ix86_binary_operator_ok (IOR, DImode, operands)"
9224 "or{q}\t{%2, %0|%0, %2}"
9225 [(set_attr "type" "alu")
9226 (set_attr "mode" "DI")])
9228 (define_insn "*iordi_2_rex64"
9229 [(set (reg FLAGS_REG)
9230 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9231 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9233 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9234 (ior:DI (match_dup 1) (match_dup 2)))]
9236 && ix86_match_ccmode (insn, CCNOmode)
9237 && ix86_binary_operator_ok (IOR, DImode, operands)"
9238 "or{q}\t{%2, %0|%0, %2}"
9239 [(set_attr "type" "alu")
9240 (set_attr "mode" "DI")])
9242 (define_insn "*iordi_3_rex64"
9243 [(set (reg FLAGS_REG)
9244 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9245 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9247 (clobber (match_scratch:DI 0 "=r"))]
9249 && ix86_match_ccmode (insn, CCNOmode)
9250 && ix86_binary_operator_ok (IOR, DImode, operands)"
9251 "or{q}\t{%2, %0|%0, %2}"
9252 [(set_attr "type" "alu")
9253 (set_attr "mode" "DI")])
9256 (define_expand "iorsi3"
9257 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9258 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9259 (match_operand:SI 2 "general_operand" "")))
9260 (clobber (reg:CC FLAGS_REG))]
9262 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9264 (define_insn "*iorsi_1"
9265 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9266 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9267 (match_operand:SI 2 "general_operand" "ri,g")))
9268 (clobber (reg:CC FLAGS_REG))]
9269 "ix86_binary_operator_ok (IOR, SImode, operands)"
9270 "or{l}\t{%2, %0|%0, %2}"
9271 [(set_attr "type" "alu")
9272 (set_attr "mode" "SI")])
9274 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9275 (define_insn "*iorsi_1_zext"
9276 [(set (match_operand:DI 0 "register_operand" "=r")
9278 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9279 (match_operand:SI 2 "general_operand" "g"))))
9280 (clobber (reg:CC FLAGS_REG))]
9281 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9282 "or{l}\t{%2, %k0|%k0, %2}"
9283 [(set_attr "type" "alu")
9284 (set_attr "mode" "SI")])
9286 (define_insn "*iorsi_1_zext_imm"
9287 [(set (match_operand:DI 0 "register_operand" "=r")
9288 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9289 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9290 (clobber (reg:CC FLAGS_REG))]
9292 "or{l}\t{%2, %k0|%k0, %2}"
9293 [(set_attr "type" "alu")
9294 (set_attr "mode" "SI")])
9296 (define_insn "*iorsi_2"
9297 [(set (reg FLAGS_REG)
9298 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9299 (match_operand:SI 2 "general_operand" "g,ri"))
9301 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9302 (ior:SI (match_dup 1) (match_dup 2)))]
9303 "ix86_match_ccmode (insn, CCNOmode)
9304 && ix86_binary_operator_ok (IOR, SImode, operands)"
9305 "or{l}\t{%2, %0|%0, %2}"
9306 [(set_attr "type" "alu")
9307 (set_attr "mode" "SI")])
9309 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9310 ;; ??? Special case for immediate operand is missing - it is tricky.
9311 (define_insn "*iorsi_2_zext"
9312 [(set (reg FLAGS_REG)
9313 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9314 (match_operand:SI 2 "general_operand" "g"))
9316 (set (match_operand:DI 0 "register_operand" "=r")
9317 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9318 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9319 && ix86_binary_operator_ok (IOR, SImode, operands)"
9320 "or{l}\t{%2, %k0|%k0, %2}"
9321 [(set_attr "type" "alu")
9322 (set_attr "mode" "SI")])
9324 (define_insn "*iorsi_2_zext_imm"
9325 [(set (reg FLAGS_REG)
9326 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9327 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9329 (set (match_operand:DI 0 "register_operand" "=r")
9330 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9331 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9332 && ix86_binary_operator_ok (IOR, SImode, operands)"
9333 "or{l}\t{%2, %k0|%k0, %2}"
9334 [(set_attr "type" "alu")
9335 (set_attr "mode" "SI")])
9337 (define_insn "*iorsi_3"
9338 [(set (reg FLAGS_REG)
9339 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9340 (match_operand:SI 2 "general_operand" "g"))
9342 (clobber (match_scratch:SI 0 "=r"))]
9343 "ix86_match_ccmode (insn, CCNOmode)
9344 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9345 "or{l}\t{%2, %0|%0, %2}"
9346 [(set_attr "type" "alu")
9347 (set_attr "mode" "SI")])
9349 (define_expand "iorhi3"
9350 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9351 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9352 (match_operand:HI 2 "general_operand" "")))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "TARGET_HIMODE_MATH"
9355 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9357 (define_insn "*iorhi_1"
9358 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9359 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9360 (match_operand:HI 2 "general_operand" "g,ri")))
9361 (clobber (reg:CC FLAGS_REG))]
9362 "ix86_binary_operator_ok (IOR, HImode, operands)"
9363 "or{w}\t{%2, %0|%0, %2}"
9364 [(set_attr "type" "alu")
9365 (set_attr "mode" "HI")])
9367 (define_insn "*iorhi_2"
9368 [(set (reg FLAGS_REG)
9369 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9370 (match_operand:HI 2 "general_operand" "g,ri"))
9372 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9373 (ior:HI (match_dup 1) (match_dup 2)))]
9374 "ix86_match_ccmode (insn, CCNOmode)
9375 && ix86_binary_operator_ok (IOR, HImode, operands)"
9376 "or{w}\t{%2, %0|%0, %2}"
9377 [(set_attr "type" "alu")
9378 (set_attr "mode" "HI")])
9380 (define_insn "*iorhi_3"
9381 [(set (reg FLAGS_REG)
9382 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9383 (match_operand:HI 2 "general_operand" "g"))
9385 (clobber (match_scratch:HI 0 "=r"))]
9386 "ix86_match_ccmode (insn, CCNOmode)
9387 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9388 "or{w}\t{%2, %0|%0, %2}"
9389 [(set_attr "type" "alu")
9390 (set_attr "mode" "HI")])
9392 (define_expand "iorqi3"
9393 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9394 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9395 (match_operand:QI 2 "general_operand" "")))
9396 (clobber (reg:CC FLAGS_REG))]
9397 "TARGET_QIMODE_MATH"
9398 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9400 ;; %%% Potential partial reg stall on alternative 2. What to do?
9401 (define_insn "*iorqi_1"
9402 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9403 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9404 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9405 (clobber (reg:CC FLAGS_REG))]
9406 "ix86_binary_operator_ok (IOR, QImode, operands)"
9408 or{b}\t{%2, %0|%0, %2}
9409 or{b}\t{%2, %0|%0, %2}
9410 or{l}\t{%k2, %k0|%k0, %k2}"
9411 [(set_attr "type" "alu")
9412 (set_attr "mode" "QI,QI,SI")])
9414 (define_insn "*iorqi_1_slp"
9415 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9416 (ior:QI (match_dup 0)
9417 (match_operand:QI 1 "general_operand" "qmi,qi")))
9418 (clobber (reg:CC FLAGS_REG))]
9419 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9420 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9421 "or{b}\t{%1, %0|%0, %1}"
9422 [(set_attr "type" "alu1")
9423 (set_attr "mode" "QI")])
9425 (define_insn "*iorqi_2"
9426 [(set (reg FLAGS_REG)
9427 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9428 (match_operand:QI 2 "general_operand" "qim,qi"))
9430 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9431 (ior:QI (match_dup 1) (match_dup 2)))]
9432 "ix86_match_ccmode (insn, CCNOmode)
9433 && ix86_binary_operator_ok (IOR, QImode, operands)"
9434 "or{b}\t{%2, %0|%0, %2}"
9435 [(set_attr "type" "alu")
9436 (set_attr "mode" "QI")])
9438 (define_insn "*iorqi_2_slp"
9439 [(set (reg FLAGS_REG)
9440 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9441 (match_operand:QI 1 "general_operand" "qim,qi"))
9443 (set (strict_low_part (match_dup 0))
9444 (ior:QI (match_dup 0) (match_dup 1)))]
9445 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9446 && ix86_match_ccmode (insn, CCNOmode)
9447 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9448 "or{b}\t{%1, %0|%0, %1}"
9449 [(set_attr "type" "alu1")
9450 (set_attr "mode" "QI")])
9452 (define_insn "*iorqi_3"
9453 [(set (reg FLAGS_REG)
9454 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9455 (match_operand:QI 2 "general_operand" "qim"))
9457 (clobber (match_scratch:QI 0 "=q"))]
9458 "ix86_match_ccmode (insn, CCNOmode)
9459 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9460 "or{b}\t{%2, %0|%0, %2}"
9461 [(set_attr "type" "alu")
9462 (set_attr "mode" "QI")])
9464 (define_insn "iorqi_ext_0"
9465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9470 (match_operand 1 "ext_register_operand" "0")
9473 (match_operand 2 "const_int_operand" "n")))
9474 (clobber (reg:CC FLAGS_REG))]
9475 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9476 "or{b}\t{%2, %h0|%h0, %2}"
9477 [(set_attr "type" "alu")
9478 (set_attr "length_immediate" "1")
9479 (set_attr "mode" "QI")])
9481 (define_insn "*iorqi_ext_1"
9482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9487 (match_operand 1 "ext_register_operand" "0")
9491 (match_operand:QI 2 "general_operand" "Qm"))))
9492 (clobber (reg:CC FLAGS_REG))]
9494 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9495 "or{b}\t{%2, %h0|%h0, %2}"
9496 [(set_attr "type" "alu")
9497 (set_attr "length_immediate" "0")
9498 (set_attr "mode" "QI")])
9500 (define_insn "*iorqi_ext_1_rex64"
9501 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9506 (match_operand 1 "ext_register_operand" "0")
9510 (match_operand 2 "ext_register_operand" "Q"))))
9511 (clobber (reg:CC FLAGS_REG))]
9513 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9514 "or{b}\t{%2, %h0|%h0, %2}"
9515 [(set_attr "type" "alu")
9516 (set_attr "length_immediate" "0")
9517 (set_attr "mode" "QI")])
9519 (define_insn "*iorqi_ext_2"
9520 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9524 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9527 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9530 (clobber (reg:CC FLAGS_REG))]
9531 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9532 "ior{b}\t{%h2, %h0|%h0, %h2}"
9533 [(set_attr "type" "alu")
9534 (set_attr "length_immediate" "0")
9535 (set_attr "mode" "QI")])
9538 [(set (match_operand 0 "register_operand" "")
9539 (ior (match_operand 1 "register_operand" "")
9540 (match_operand 2 "const_int_operand" "")))
9541 (clobber (reg:CC FLAGS_REG))]
9543 && QI_REG_P (operands[0])
9544 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9545 && !(INTVAL (operands[2]) & ~(255 << 8))
9546 && GET_MODE (operands[0]) != QImode"
9547 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9548 (ior:SI (zero_extract:SI (match_dup 1)
9549 (const_int 8) (const_int 8))
9551 (clobber (reg:CC FLAGS_REG))])]
9552 "operands[0] = gen_lowpart (SImode, operands[0]);
9553 operands[1] = gen_lowpart (SImode, operands[1]);
9554 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9556 ;; Since OR can be encoded with sign extended immediate, this is only
9557 ;; profitable when 7th bit is set.
9559 [(set (match_operand 0 "register_operand" "")
9560 (ior (match_operand 1 "general_operand" "")
9561 (match_operand 2 "const_int_operand" "")))
9562 (clobber (reg:CC FLAGS_REG))]
9564 && ANY_QI_REG_P (operands[0])
9565 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9566 && !(INTVAL (operands[2]) & ~255)
9567 && (INTVAL (operands[2]) & 128)
9568 && GET_MODE (operands[0]) != QImode"
9569 [(parallel [(set (strict_low_part (match_dup 0))
9570 (ior:QI (match_dup 1)
9572 (clobber (reg:CC FLAGS_REG))])]
9573 "operands[0] = gen_lowpart (QImode, operands[0]);
9574 operands[1] = gen_lowpart (QImode, operands[1]);
9575 operands[2] = gen_lowpart (QImode, operands[2]);")
9577 ;; Logical XOR instructions
9579 ;; %%% This used to optimize known byte-wide and operations to memory.
9580 ;; If this is considered useful, it should be done with splitters.
9582 (define_expand "xordi3"
9583 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9584 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9585 (match_operand:DI 2 "x86_64_general_operand" "")))
9586 (clobber (reg:CC FLAGS_REG))]
9588 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9590 (define_insn "*xordi_1_rex64"
9591 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9592 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9593 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9594 (clobber (reg:CC FLAGS_REG))]
9596 && ix86_binary_operator_ok (XOR, DImode, operands)"
9598 xor{q}\t{%2, %0|%0, %2}
9599 xor{q}\t{%2, %0|%0, %2}"
9600 [(set_attr "type" "alu")
9601 (set_attr "mode" "DI,DI")])
9603 (define_insn "*xordi_2_rex64"
9604 [(set (reg FLAGS_REG)
9605 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9606 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9608 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9609 (xor:DI (match_dup 1) (match_dup 2)))]
9611 && ix86_match_ccmode (insn, CCNOmode)
9612 && ix86_binary_operator_ok (XOR, DImode, operands)"
9614 xor{q}\t{%2, %0|%0, %2}
9615 xor{q}\t{%2, %0|%0, %2}"
9616 [(set_attr "type" "alu")
9617 (set_attr "mode" "DI,DI")])
9619 (define_insn "*xordi_3_rex64"
9620 [(set (reg FLAGS_REG)
9621 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9622 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9624 (clobber (match_scratch:DI 0 "=r"))]
9626 && ix86_match_ccmode (insn, CCNOmode)
9627 && ix86_binary_operator_ok (XOR, DImode, operands)"
9628 "xor{q}\t{%2, %0|%0, %2}"
9629 [(set_attr "type" "alu")
9630 (set_attr "mode" "DI")])
9632 (define_expand "xorsi3"
9633 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9634 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9635 (match_operand:SI 2 "general_operand" "")))
9636 (clobber (reg:CC FLAGS_REG))]
9638 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9640 (define_insn "*xorsi_1"
9641 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9642 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9643 (match_operand:SI 2 "general_operand" "ri,rm")))
9644 (clobber (reg:CC FLAGS_REG))]
9645 "ix86_binary_operator_ok (XOR, SImode, operands)"
9646 "xor{l}\t{%2, %0|%0, %2}"
9647 [(set_attr "type" "alu")
9648 (set_attr "mode" "SI")])
9650 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9651 ;; Add speccase for immediates
9652 (define_insn "*xorsi_1_zext"
9653 [(set (match_operand:DI 0 "register_operand" "=r")
9655 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9656 (match_operand:SI 2 "general_operand" "g"))))
9657 (clobber (reg:CC FLAGS_REG))]
9658 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9659 "xor{l}\t{%2, %k0|%k0, %2}"
9660 [(set_attr "type" "alu")
9661 (set_attr "mode" "SI")])
9663 (define_insn "*xorsi_1_zext_imm"
9664 [(set (match_operand:DI 0 "register_operand" "=r")
9665 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9666 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9667 (clobber (reg:CC FLAGS_REG))]
9668 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9669 "xor{l}\t{%2, %k0|%k0, %2}"
9670 [(set_attr "type" "alu")
9671 (set_attr "mode" "SI")])
9673 (define_insn "*xorsi_2"
9674 [(set (reg FLAGS_REG)
9675 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9676 (match_operand:SI 2 "general_operand" "g,ri"))
9678 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9679 (xor:SI (match_dup 1) (match_dup 2)))]
9680 "ix86_match_ccmode (insn, CCNOmode)
9681 && ix86_binary_operator_ok (XOR, SImode, operands)"
9682 "xor{l}\t{%2, %0|%0, %2}"
9683 [(set_attr "type" "alu")
9684 (set_attr "mode" "SI")])
9686 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9687 ;; ??? Special case for immediate operand is missing - it is tricky.
9688 (define_insn "*xorsi_2_zext"
9689 [(set (reg FLAGS_REG)
9690 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9691 (match_operand:SI 2 "general_operand" "g"))
9693 (set (match_operand:DI 0 "register_operand" "=r")
9694 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9695 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9696 && ix86_binary_operator_ok (XOR, SImode, operands)"
9697 "xor{l}\t{%2, %k0|%k0, %2}"
9698 [(set_attr "type" "alu")
9699 (set_attr "mode" "SI")])
9701 (define_insn "*xorsi_2_zext_imm"
9702 [(set (reg FLAGS_REG)
9703 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9704 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9706 (set (match_operand:DI 0 "register_operand" "=r")
9707 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9708 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9709 && ix86_binary_operator_ok (XOR, SImode, operands)"
9710 "xor{l}\t{%2, %k0|%k0, %2}"
9711 [(set_attr "type" "alu")
9712 (set_attr "mode" "SI")])
9714 (define_insn "*xorsi_3"
9715 [(set (reg FLAGS_REG)
9716 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9717 (match_operand:SI 2 "general_operand" "g"))
9719 (clobber (match_scratch:SI 0 "=r"))]
9720 "ix86_match_ccmode (insn, CCNOmode)
9721 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9722 "xor{l}\t{%2, %0|%0, %2}"
9723 [(set_attr "type" "alu")
9724 (set_attr "mode" "SI")])
9726 (define_expand "xorhi3"
9727 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9728 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9729 (match_operand:HI 2 "general_operand" "")))
9730 (clobber (reg:CC FLAGS_REG))]
9731 "TARGET_HIMODE_MATH"
9732 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9734 (define_insn "*xorhi_1"
9735 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9736 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9737 (match_operand:HI 2 "general_operand" "g,ri")))
9738 (clobber (reg:CC FLAGS_REG))]
9739 "ix86_binary_operator_ok (XOR, HImode, operands)"
9740 "xor{w}\t{%2, %0|%0, %2}"
9741 [(set_attr "type" "alu")
9742 (set_attr "mode" "HI")])
9744 (define_insn "*xorhi_2"
9745 [(set (reg FLAGS_REG)
9746 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9747 (match_operand:HI 2 "general_operand" "g,ri"))
9749 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9750 (xor:HI (match_dup 1) (match_dup 2)))]
9751 "ix86_match_ccmode (insn, CCNOmode)
9752 && ix86_binary_operator_ok (XOR, HImode, operands)"
9753 "xor{w}\t{%2, %0|%0, %2}"
9754 [(set_attr "type" "alu")
9755 (set_attr "mode" "HI")])
9757 (define_insn "*xorhi_3"
9758 [(set (reg FLAGS_REG)
9759 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9760 (match_operand:HI 2 "general_operand" "g"))
9762 (clobber (match_scratch:HI 0 "=r"))]
9763 "ix86_match_ccmode (insn, CCNOmode)
9764 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9765 "xor{w}\t{%2, %0|%0, %2}"
9766 [(set_attr "type" "alu")
9767 (set_attr "mode" "HI")])
9769 (define_expand "xorqi3"
9770 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9771 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9772 (match_operand:QI 2 "general_operand" "")))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "TARGET_QIMODE_MATH"
9775 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9777 ;; %%% Potential partial reg stall on alternative 2. What to do?
9778 (define_insn "*xorqi_1"
9779 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9780 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9781 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9782 (clobber (reg:CC FLAGS_REG))]
9783 "ix86_binary_operator_ok (XOR, QImode, operands)"
9785 xor{b}\t{%2, %0|%0, %2}
9786 xor{b}\t{%2, %0|%0, %2}
9787 xor{l}\t{%k2, %k0|%k0, %k2}"
9788 [(set_attr "type" "alu")
9789 (set_attr "mode" "QI,QI,SI")])
9791 (define_insn "*xorqi_1_slp"
9792 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9793 (xor:QI (match_dup 0)
9794 (match_operand:QI 1 "general_operand" "qi,qmi")))
9795 (clobber (reg:CC FLAGS_REG))]
9796 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9797 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9798 "xor{b}\t{%1, %0|%0, %1}"
9799 [(set_attr "type" "alu1")
9800 (set_attr "mode" "QI")])
9802 (define_insn "xorqi_ext_0"
9803 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9808 (match_operand 1 "ext_register_operand" "0")
9811 (match_operand 2 "const_int_operand" "n")))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9814 "xor{b}\t{%2, %h0|%h0, %2}"
9815 [(set_attr "type" "alu")
9816 (set_attr "length_immediate" "1")
9817 (set_attr "mode" "QI")])
9819 (define_insn "*xorqi_ext_1"
9820 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9825 (match_operand 1 "ext_register_operand" "0")
9829 (match_operand:QI 2 "general_operand" "Qm"))))
9830 (clobber (reg:CC FLAGS_REG))]
9832 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9833 "xor{b}\t{%2, %h0|%h0, %2}"
9834 [(set_attr "type" "alu")
9835 (set_attr "length_immediate" "0")
9836 (set_attr "mode" "QI")])
9838 (define_insn "*xorqi_ext_1_rex64"
9839 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9844 (match_operand 1 "ext_register_operand" "0")
9848 (match_operand 2 "ext_register_operand" "Q"))))
9849 (clobber (reg:CC FLAGS_REG))]
9851 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9852 "xor{b}\t{%2, %h0|%h0, %2}"
9853 [(set_attr "type" "alu")
9854 (set_attr "length_immediate" "0")
9855 (set_attr "mode" "QI")])
9857 (define_insn "*xorqi_ext_2"
9858 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9862 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9865 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9868 (clobber (reg:CC FLAGS_REG))]
9869 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9870 "xor{b}\t{%h2, %h0|%h0, %h2}"
9871 [(set_attr "type" "alu")
9872 (set_attr "length_immediate" "0")
9873 (set_attr "mode" "QI")])
9875 (define_insn "*xorqi_cc_1"
9876 [(set (reg FLAGS_REG)
9878 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9879 (match_operand:QI 2 "general_operand" "qim,qi"))
9881 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9882 (xor:QI (match_dup 1) (match_dup 2)))]
9883 "ix86_match_ccmode (insn, CCNOmode)
9884 && ix86_binary_operator_ok (XOR, QImode, operands)"
9885 "xor{b}\t{%2, %0|%0, %2}"
9886 [(set_attr "type" "alu")
9887 (set_attr "mode" "QI")])
9889 (define_insn "*xorqi_2_slp"
9890 [(set (reg FLAGS_REG)
9891 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9892 (match_operand:QI 1 "general_operand" "qim,qi"))
9894 (set (strict_low_part (match_dup 0))
9895 (xor:QI (match_dup 0) (match_dup 1)))]
9896 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9897 && ix86_match_ccmode (insn, CCNOmode)
9898 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9899 "xor{b}\t{%1, %0|%0, %1}"
9900 [(set_attr "type" "alu1")
9901 (set_attr "mode" "QI")])
9903 (define_insn "*xorqi_cc_2"
9904 [(set (reg FLAGS_REG)
9906 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9907 (match_operand:QI 2 "general_operand" "qim"))
9909 (clobber (match_scratch:QI 0 "=q"))]
9910 "ix86_match_ccmode (insn, CCNOmode)
9911 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9912 "xor{b}\t{%2, %0|%0, %2}"
9913 [(set_attr "type" "alu")
9914 (set_attr "mode" "QI")])
9916 (define_insn "*xorqi_cc_ext_1"
9917 [(set (reg FLAGS_REG)
9921 (match_operand 1 "ext_register_operand" "0")
9924 (match_operand:QI 2 "general_operand" "qmn"))
9926 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9930 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9932 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9933 "xor{b}\t{%2, %h0|%h0, %2}"
9934 [(set_attr "type" "alu")
9935 (set_attr "mode" "QI")])
9937 (define_insn "*xorqi_cc_ext_1_rex64"
9938 [(set (reg FLAGS_REG)
9942 (match_operand 1 "ext_register_operand" "0")
9945 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9947 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9951 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9953 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9954 "xor{b}\t{%2, %h0|%h0, %2}"
9955 [(set_attr "type" "alu")
9956 (set_attr "mode" "QI")])
9958 (define_expand "xorqi_cc_ext_1"
9960 (set (reg:CCNO FLAGS_REG)
9964 (match_operand 1 "ext_register_operand" "")
9967 (match_operand:QI 2 "general_operand" ""))
9969 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9973 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9979 [(set (match_operand 0 "register_operand" "")
9980 (xor (match_operand 1 "register_operand" "")
9981 (match_operand 2 "const_int_operand" "")))
9982 (clobber (reg:CC FLAGS_REG))]
9984 && QI_REG_P (operands[0])
9985 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9986 && !(INTVAL (operands[2]) & ~(255 << 8))
9987 && GET_MODE (operands[0]) != QImode"
9988 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9989 (xor:SI (zero_extract:SI (match_dup 1)
9990 (const_int 8) (const_int 8))
9992 (clobber (reg:CC FLAGS_REG))])]
9993 "operands[0] = gen_lowpart (SImode, operands[0]);
9994 operands[1] = gen_lowpart (SImode, operands[1]);
9995 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9997 ;; Since XOR can be encoded with sign extended immediate, this is only
9998 ;; profitable when 7th bit is set.
10000 [(set (match_operand 0 "register_operand" "")
10001 (xor (match_operand 1 "general_operand" "")
10002 (match_operand 2 "const_int_operand" "")))
10003 (clobber (reg:CC FLAGS_REG))]
10005 && ANY_QI_REG_P (operands[0])
10006 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10007 && !(INTVAL (operands[2]) & ~255)
10008 && (INTVAL (operands[2]) & 128)
10009 && GET_MODE (operands[0]) != QImode"
10010 [(parallel [(set (strict_low_part (match_dup 0))
10011 (xor:QI (match_dup 1)
10013 (clobber (reg:CC FLAGS_REG))])]
10014 "operands[0] = gen_lowpart (QImode, operands[0]);
10015 operands[1] = gen_lowpart (QImode, operands[1]);
10016 operands[2] = gen_lowpart (QImode, operands[2]);")
10018 ;; Negation instructions
10020 (define_expand "negti2"
10021 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10022 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10023 (clobber (reg:CC FLAGS_REG))])]
10025 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10027 (define_insn "*negti2_1"
10028 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10029 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10030 (clobber (reg:CC FLAGS_REG))]
10032 && ix86_unary_operator_ok (NEG, TImode, operands)"
10036 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10037 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10038 (clobber (reg:CC FLAGS_REG))]
10039 "TARGET_64BIT && reload_completed"
10041 [(set (reg:CCZ FLAGS_REG)
10042 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10043 (set (match_dup 0) (neg:DI (match_dup 2)))])
10045 [(set (match_dup 1)
10046 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10049 (clobber (reg:CC FLAGS_REG))])
10051 [(set (match_dup 1)
10052 (neg:DI (match_dup 1)))
10053 (clobber (reg:CC FLAGS_REG))])]
10054 "split_ti (operands+1, 1, operands+2, operands+3);
10055 split_ti (operands+0, 1, operands+0, operands+1);")
10057 (define_expand "negdi2"
10058 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10059 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10060 (clobber (reg:CC FLAGS_REG))])]
10062 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10064 (define_insn "*negdi2_1"
10065 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10066 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10067 (clobber (reg:CC FLAGS_REG))]
10069 && ix86_unary_operator_ok (NEG, DImode, operands)"
10073 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10074 (neg:DI (match_operand:DI 1 "general_operand" "")))
10075 (clobber (reg:CC FLAGS_REG))]
10076 "!TARGET_64BIT && reload_completed"
10078 [(set (reg:CCZ FLAGS_REG)
10079 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10080 (set (match_dup 0) (neg:SI (match_dup 2)))])
10082 [(set (match_dup 1)
10083 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10086 (clobber (reg:CC FLAGS_REG))])
10088 [(set (match_dup 1)
10089 (neg:SI (match_dup 1)))
10090 (clobber (reg:CC FLAGS_REG))])]
10091 "split_di (operands+1, 1, operands+2, operands+3);
10092 split_di (operands+0, 1, operands+0, operands+1);")
10094 (define_insn "*negdi2_1_rex64"
10095 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10096 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10097 (clobber (reg:CC FLAGS_REG))]
10098 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10100 [(set_attr "type" "negnot")
10101 (set_attr "mode" "DI")])
10103 ;; The problem with neg is that it does not perform (compare x 0),
10104 ;; it really performs (compare 0 x), which leaves us with the zero
10105 ;; flag being the only useful item.
10107 (define_insn "*negdi2_cmpz_rex64"
10108 [(set (reg:CCZ FLAGS_REG)
10109 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10111 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10112 (neg:DI (match_dup 1)))]
10113 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10115 [(set_attr "type" "negnot")
10116 (set_attr "mode" "DI")])
10119 (define_expand "negsi2"
10120 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10121 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10122 (clobber (reg:CC FLAGS_REG))])]
10124 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10126 (define_insn "*negsi2_1"
10127 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10128 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10129 (clobber (reg:CC FLAGS_REG))]
10130 "ix86_unary_operator_ok (NEG, SImode, operands)"
10132 [(set_attr "type" "negnot")
10133 (set_attr "mode" "SI")])
10135 ;; Combine is quite creative about this pattern.
10136 (define_insn "*negsi2_1_zext"
10137 [(set (match_operand:DI 0 "register_operand" "=r")
10138 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10141 (clobber (reg:CC FLAGS_REG))]
10142 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10144 [(set_attr "type" "negnot")
10145 (set_attr "mode" "SI")])
10147 ;; The problem with neg is that it does not perform (compare x 0),
10148 ;; it really performs (compare 0 x), which leaves us with the zero
10149 ;; flag being the only useful item.
10151 (define_insn "*negsi2_cmpz"
10152 [(set (reg:CCZ FLAGS_REG)
10153 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10155 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10156 (neg:SI (match_dup 1)))]
10157 "ix86_unary_operator_ok (NEG, SImode, operands)"
10159 [(set_attr "type" "negnot")
10160 (set_attr "mode" "SI")])
10162 (define_insn "*negsi2_cmpz_zext"
10163 [(set (reg:CCZ FLAGS_REG)
10164 (compare:CCZ (lshiftrt:DI
10166 (match_operand:DI 1 "register_operand" "0")
10170 (set (match_operand:DI 0 "register_operand" "=r")
10171 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10174 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10176 [(set_attr "type" "negnot")
10177 (set_attr "mode" "SI")])
10179 (define_expand "neghi2"
10180 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10181 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10182 (clobber (reg:CC FLAGS_REG))])]
10183 "TARGET_HIMODE_MATH"
10184 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10186 (define_insn "*neghi2_1"
10187 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10188 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10189 (clobber (reg:CC FLAGS_REG))]
10190 "ix86_unary_operator_ok (NEG, HImode, operands)"
10192 [(set_attr "type" "negnot")
10193 (set_attr "mode" "HI")])
10195 (define_insn "*neghi2_cmpz"
10196 [(set (reg:CCZ FLAGS_REG)
10197 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10199 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10200 (neg:HI (match_dup 1)))]
10201 "ix86_unary_operator_ok (NEG, HImode, operands)"
10203 [(set_attr "type" "negnot")
10204 (set_attr "mode" "HI")])
10206 (define_expand "negqi2"
10207 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10208 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10209 (clobber (reg:CC FLAGS_REG))])]
10210 "TARGET_QIMODE_MATH"
10211 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10213 (define_insn "*negqi2_1"
10214 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10215 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10216 (clobber (reg:CC FLAGS_REG))]
10217 "ix86_unary_operator_ok (NEG, QImode, operands)"
10219 [(set_attr "type" "negnot")
10220 (set_attr "mode" "QI")])
10222 (define_insn "*negqi2_cmpz"
10223 [(set (reg:CCZ FLAGS_REG)
10224 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10226 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10227 (neg:QI (match_dup 1)))]
10228 "ix86_unary_operator_ok (NEG, QImode, operands)"
10230 [(set_attr "type" "negnot")
10231 (set_attr "mode" "QI")])
10233 ;; Changing of sign for FP values is doable using integer unit too.
10235 (define_expand "neg<mode>2"
10236 [(set (match_operand:X87MODEF 0 "register_operand" "")
10237 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10238 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10239 "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10241 (define_expand "abs<mode>2"
10242 [(set (match_operand:X87MODEF 0 "register_operand" "")
10243 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10244 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10245 "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10247 (define_insn "*absneg<mode>2_mixed"
10248 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10249 (match_operator:MODEF 3 "absneg_operator"
10250 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10251 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10252 (clobber (reg:CC FLAGS_REG))]
10253 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10256 (define_insn "*absneg<mode>2_sse"
10257 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10258 (match_operator:MODEF 3 "absneg_operator"
10259 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10260 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10261 (clobber (reg:CC FLAGS_REG))]
10262 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10265 (define_insn "*absneg<mode>2_i387"
10266 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10267 (match_operator:X87MODEF 3 "absneg_operator"
10268 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10269 (use (match_operand 2 "" ""))
10270 (clobber (reg:CC FLAGS_REG))]
10271 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10274 (define_expand "negtf2"
10275 [(set (match_operand:TF 0 "register_operand" "")
10276 (neg:TF (match_operand:TF 1 "register_operand" "")))]
10278 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10280 (define_expand "abstf2"
10281 [(set (match_operand:TF 0 "register_operand" "")
10282 (abs:TF (match_operand:TF 1 "register_operand" "")))]
10284 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10286 (define_insn "*absnegtf2_sse"
10287 [(set (match_operand:TF 0 "register_operand" "=x,x")
10288 (match_operator:TF 3 "absneg_operator"
10289 [(match_operand:TF 1 "register_operand" "0,x")]))
10290 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10291 (clobber (reg:CC FLAGS_REG))]
10295 ;; Splitters for fp abs and neg.
10298 [(set (match_operand 0 "fp_register_operand" "")
10299 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10300 (use (match_operand 2 "" ""))
10301 (clobber (reg:CC FLAGS_REG))]
10303 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10306 [(set (match_operand 0 "register_operand" "")
10307 (match_operator 3 "absneg_operator"
10308 [(match_operand 1 "register_operand" "")]))
10309 (use (match_operand 2 "nonimmediate_operand" ""))
10310 (clobber (reg:CC FLAGS_REG))]
10311 "reload_completed && SSE_REG_P (operands[0])"
10312 [(set (match_dup 0) (match_dup 3))]
10314 enum machine_mode mode = GET_MODE (operands[0]);
10315 enum machine_mode vmode = GET_MODE (operands[2]);
10318 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10319 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10320 if (operands_match_p (operands[0], operands[2]))
10323 operands[1] = operands[2];
10326 if (GET_CODE (operands[3]) == ABS)
10327 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10329 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10334 [(set (match_operand:SF 0 "register_operand" "")
10335 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10336 (use (match_operand:V4SF 2 "" ""))
10337 (clobber (reg:CC FLAGS_REG))]
10339 [(parallel [(set (match_dup 0) (match_dup 1))
10340 (clobber (reg:CC FLAGS_REG))])]
10343 operands[0] = gen_lowpart (SImode, operands[0]);
10344 if (GET_CODE (operands[1]) == ABS)
10346 tmp = gen_int_mode (0x7fffffff, SImode);
10347 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10351 tmp = gen_int_mode (0x80000000, SImode);
10352 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10358 [(set (match_operand:DF 0 "register_operand" "")
10359 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10360 (use (match_operand 2 "" ""))
10361 (clobber (reg:CC FLAGS_REG))]
10363 [(parallel [(set (match_dup 0) (match_dup 1))
10364 (clobber (reg:CC FLAGS_REG))])]
10369 tmp = gen_lowpart (DImode, operands[0]);
10370 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10373 if (GET_CODE (operands[1]) == ABS)
10376 tmp = gen_rtx_NOT (DImode, tmp);
10380 operands[0] = gen_highpart (SImode, operands[0]);
10381 if (GET_CODE (operands[1]) == ABS)
10383 tmp = gen_int_mode (0x7fffffff, SImode);
10384 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10388 tmp = gen_int_mode (0x80000000, SImode);
10389 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10396 [(set (match_operand:XF 0 "register_operand" "")
10397 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10398 (use (match_operand 2 "" ""))
10399 (clobber (reg:CC FLAGS_REG))]
10401 [(parallel [(set (match_dup 0) (match_dup 1))
10402 (clobber (reg:CC FLAGS_REG))])]
10405 operands[0] = gen_rtx_REG (SImode,
10406 true_regnum (operands[0])
10407 + (TARGET_64BIT ? 1 : 2));
10408 if (GET_CODE (operands[1]) == ABS)
10410 tmp = GEN_INT (0x7fff);
10411 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10415 tmp = GEN_INT (0x8000);
10416 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10421 ;; Conditionalize these after reload. If they match before reload, we
10422 ;; lose the clobber and ability to use integer instructions.
10424 (define_insn "*neg<mode>2_1"
10425 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10426 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10428 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10430 [(set_attr "type" "fsgn")
10431 (set_attr "mode" "<MODE>")])
10433 (define_insn "*abs<mode>2_1"
10434 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10435 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10437 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10439 [(set_attr "type" "fsgn")
10440 (set_attr "mode" "<MODE>")])
10442 (define_insn "*negextendsfdf2"
10443 [(set (match_operand:DF 0 "register_operand" "=f")
10444 (neg:DF (float_extend:DF
10445 (match_operand:SF 1 "register_operand" "0"))))]
10446 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10448 [(set_attr "type" "fsgn")
10449 (set_attr "mode" "DF")])
10451 (define_insn "*negextenddfxf2"
10452 [(set (match_operand:XF 0 "register_operand" "=f")
10453 (neg:XF (float_extend:XF
10454 (match_operand:DF 1 "register_operand" "0"))))]
10457 [(set_attr "type" "fsgn")
10458 (set_attr "mode" "XF")])
10460 (define_insn "*negextendsfxf2"
10461 [(set (match_operand:XF 0 "register_operand" "=f")
10462 (neg:XF (float_extend:XF
10463 (match_operand:SF 1 "register_operand" "0"))))]
10466 [(set_attr "type" "fsgn")
10467 (set_attr "mode" "XF")])
10469 (define_insn "*absextendsfdf2"
10470 [(set (match_operand:DF 0 "register_operand" "=f")
10471 (abs:DF (float_extend:DF
10472 (match_operand:SF 1 "register_operand" "0"))))]
10473 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10475 [(set_attr "type" "fsgn")
10476 (set_attr "mode" "DF")])
10478 (define_insn "*absextenddfxf2"
10479 [(set (match_operand:XF 0 "register_operand" "=f")
10480 (abs:XF (float_extend:XF
10481 (match_operand:DF 1 "register_operand" "0"))))]
10484 [(set_attr "type" "fsgn")
10485 (set_attr "mode" "XF")])
10487 (define_insn "*absextendsfxf2"
10488 [(set (match_operand:XF 0 "register_operand" "=f")
10489 (abs:XF (float_extend:XF
10490 (match_operand:SF 1 "register_operand" "0"))))]
10493 [(set_attr "type" "fsgn")
10494 (set_attr "mode" "XF")])
10496 ;; Copysign instructions
10498 (define_mode_iterator CSGNMODE [SF DF TF])
10499 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10501 (define_expand "copysign<mode>3"
10502 [(match_operand:CSGNMODE 0 "register_operand" "")
10503 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10504 (match_operand:CSGNMODE 2 "register_operand" "")]
10505 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10506 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10508 ix86_expand_copysign (operands);
10512 (define_insn_and_split "copysign<mode>3_const"
10513 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10515 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10516 (match_operand:CSGNMODE 2 "register_operand" "0")
10517 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10519 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10520 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10522 "&& reload_completed"
10525 ix86_split_copysign_const (operands);
10529 (define_insn "copysign<mode>3_var"
10530 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10532 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10533 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10534 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10535 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10537 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10538 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10539 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10543 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10545 [(match_operand:CSGNMODE 2 "register_operand" "")
10546 (match_operand:CSGNMODE 3 "register_operand" "")
10547 (match_operand:<CSGNVMODE> 4 "" "")
10548 (match_operand:<CSGNVMODE> 5 "" "")]
10550 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10551 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10552 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10553 && reload_completed"
10556 ix86_split_copysign_var (operands);
10560 ;; One complement instructions
10562 (define_expand "one_cmpldi2"
10563 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10564 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10566 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10568 (define_insn "*one_cmpldi2_1_rex64"
10569 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10570 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10571 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10573 [(set_attr "type" "negnot")
10574 (set_attr "mode" "DI")])
10576 (define_insn "*one_cmpldi2_2_rex64"
10577 [(set (reg FLAGS_REG)
10578 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10580 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10581 (not:DI (match_dup 1)))]
10582 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10583 && ix86_unary_operator_ok (NOT, DImode, operands)"
10585 [(set_attr "type" "alu1")
10586 (set_attr "mode" "DI")])
10589 [(set (match_operand 0 "flags_reg_operand" "")
10590 (match_operator 2 "compare_operator"
10591 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10593 (set (match_operand:DI 1 "nonimmediate_operand" "")
10594 (not:DI (match_dup 3)))]
10595 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10596 [(parallel [(set (match_dup 0)
10598 [(xor:DI (match_dup 3) (const_int -1))
10601 (xor:DI (match_dup 3) (const_int -1)))])]
10604 (define_expand "one_cmplsi2"
10605 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10606 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10608 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10610 (define_insn "*one_cmplsi2_1"
10611 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10612 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10613 "ix86_unary_operator_ok (NOT, SImode, operands)"
10615 [(set_attr "type" "negnot")
10616 (set_attr "mode" "SI")])
10618 ;; ??? Currently never generated - xor is used instead.
10619 (define_insn "*one_cmplsi2_1_zext"
10620 [(set (match_operand:DI 0 "register_operand" "=r")
10621 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10622 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10624 [(set_attr "type" "negnot")
10625 (set_attr "mode" "SI")])
10627 (define_insn "*one_cmplsi2_2"
10628 [(set (reg FLAGS_REG)
10629 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10631 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10632 (not:SI (match_dup 1)))]
10633 "ix86_match_ccmode (insn, CCNOmode)
10634 && ix86_unary_operator_ok (NOT, SImode, operands)"
10636 [(set_attr "type" "alu1")
10637 (set_attr "mode" "SI")])
10640 [(set (match_operand 0 "flags_reg_operand" "")
10641 (match_operator 2 "compare_operator"
10642 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10644 (set (match_operand:SI 1 "nonimmediate_operand" "")
10645 (not:SI (match_dup 3)))]
10646 "ix86_match_ccmode (insn, CCNOmode)"
10647 [(parallel [(set (match_dup 0)
10648 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10651 (xor:SI (match_dup 3) (const_int -1)))])]
10654 ;; ??? Currently never generated - xor is used instead.
10655 (define_insn "*one_cmplsi2_2_zext"
10656 [(set (reg FLAGS_REG)
10657 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10659 (set (match_operand:DI 0 "register_operand" "=r")
10660 (zero_extend:DI (not:SI (match_dup 1))))]
10661 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10662 && ix86_unary_operator_ok (NOT, SImode, operands)"
10664 [(set_attr "type" "alu1")
10665 (set_attr "mode" "SI")])
10668 [(set (match_operand 0 "flags_reg_operand" "")
10669 (match_operator 2 "compare_operator"
10670 [(not:SI (match_operand:SI 3 "register_operand" ""))
10672 (set (match_operand:DI 1 "register_operand" "")
10673 (zero_extend:DI (not:SI (match_dup 3))))]
10674 "ix86_match_ccmode (insn, CCNOmode)"
10675 [(parallel [(set (match_dup 0)
10676 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10679 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10682 (define_expand "one_cmplhi2"
10683 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10684 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10685 "TARGET_HIMODE_MATH"
10686 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10688 (define_insn "*one_cmplhi2_1"
10689 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10690 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10691 "ix86_unary_operator_ok (NOT, HImode, operands)"
10693 [(set_attr "type" "negnot")
10694 (set_attr "mode" "HI")])
10696 (define_insn "*one_cmplhi2_2"
10697 [(set (reg FLAGS_REG)
10698 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10700 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10701 (not:HI (match_dup 1)))]
10702 "ix86_match_ccmode (insn, CCNOmode)
10703 && ix86_unary_operator_ok (NEG, HImode, operands)"
10705 [(set_attr "type" "alu1")
10706 (set_attr "mode" "HI")])
10709 [(set (match_operand 0 "flags_reg_operand" "")
10710 (match_operator 2 "compare_operator"
10711 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10713 (set (match_operand:HI 1 "nonimmediate_operand" "")
10714 (not:HI (match_dup 3)))]
10715 "ix86_match_ccmode (insn, CCNOmode)"
10716 [(parallel [(set (match_dup 0)
10717 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10720 (xor:HI (match_dup 3) (const_int -1)))])]
10723 ;; %%% Potential partial reg stall on alternative 1. What to do?
10724 (define_expand "one_cmplqi2"
10725 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10726 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10727 "TARGET_QIMODE_MATH"
10728 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10730 (define_insn "*one_cmplqi2_1"
10731 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10732 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10733 "ix86_unary_operator_ok (NOT, QImode, operands)"
10737 [(set_attr "type" "negnot")
10738 (set_attr "mode" "QI,SI")])
10740 (define_insn "*one_cmplqi2_2"
10741 [(set (reg FLAGS_REG)
10742 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10744 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10745 (not:QI (match_dup 1)))]
10746 "ix86_match_ccmode (insn, CCNOmode)
10747 && ix86_unary_operator_ok (NOT, QImode, operands)"
10749 [(set_attr "type" "alu1")
10750 (set_attr "mode" "QI")])
10753 [(set (match_operand 0 "flags_reg_operand" "")
10754 (match_operator 2 "compare_operator"
10755 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10757 (set (match_operand:QI 1 "nonimmediate_operand" "")
10758 (not:QI (match_dup 3)))]
10759 "ix86_match_ccmode (insn, CCNOmode)"
10760 [(parallel [(set (match_dup 0)
10761 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10764 (xor:QI (match_dup 3) (const_int -1)))])]
10767 ;; Arithmetic shift instructions
10769 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10770 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10771 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10772 ;; from the assembler input.
10774 ;; This instruction shifts the target reg/mem as usual, but instead of
10775 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10776 ;; is a left shift double, bits are taken from the high order bits of
10777 ;; reg, else if the insn is a shift right double, bits are taken from the
10778 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10779 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10781 ;; Since sh[lr]d does not change the `reg' operand, that is done
10782 ;; separately, making all shifts emit pairs of shift double and normal
10783 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10784 ;; support a 63 bit shift, each shift where the count is in a reg expands
10785 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10787 ;; If the shift count is a constant, we need never emit more than one
10788 ;; shift pair, instead using moves and sign extension for counts greater
10791 (define_expand "ashlti3"
10792 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10793 (ashift:TI (match_operand:TI 1 "register_operand" "")
10794 (match_operand:QI 2 "nonmemory_operand" "")))
10795 (clobber (reg:CC FLAGS_REG))])]
10798 if (! immediate_operand (operands[2], QImode))
10800 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10803 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10807 (define_insn "ashlti3_1"
10808 [(set (match_operand:TI 0 "register_operand" "=r")
10809 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10810 (match_operand:QI 2 "register_operand" "c")))
10811 (clobber (match_scratch:DI 3 "=&r"))
10812 (clobber (reg:CC FLAGS_REG))]
10815 [(set_attr "type" "multi")])
10817 ;; This pattern must be defined before *ashlti3_2 to prevent
10818 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10820 (define_insn "sse2_ashlti3"
10821 [(set (match_operand:TI 0 "register_operand" "=x")
10822 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10823 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10826 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10827 return "pslldq\t{%2, %0|%0, %2}";
10829 [(set_attr "type" "sseishft")
10830 (set_attr "prefix_data16" "1")
10831 (set_attr "mode" "TI")])
10833 (define_insn "*ashlti3_2"
10834 [(set (match_operand:TI 0 "register_operand" "=r")
10835 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10836 (match_operand:QI 2 "immediate_operand" "O")))
10837 (clobber (reg:CC FLAGS_REG))]
10840 [(set_attr "type" "multi")])
10843 [(set (match_operand:TI 0 "register_operand" "")
10844 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10845 (match_operand:QI 2 "register_operand" "")))
10846 (clobber (match_scratch:DI 3 ""))
10847 (clobber (reg:CC FLAGS_REG))]
10848 "TARGET_64BIT && reload_completed"
10850 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10853 [(set (match_operand:TI 0 "register_operand" "")
10854 (ashift:TI (match_operand:TI 1 "register_operand" "")
10855 (match_operand:QI 2 "immediate_operand" "")))
10856 (clobber (reg:CC FLAGS_REG))]
10857 "TARGET_64BIT && reload_completed"
10859 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10861 (define_insn "x86_64_shld"
10862 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10863 (ior:DI (ashift:DI (match_dup 0)
10864 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10865 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10866 (minus:QI (const_int 64) (match_dup 2)))))
10867 (clobber (reg:CC FLAGS_REG))]
10870 shld{q}\t{%2, %1, %0|%0, %1, %2}
10871 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10872 [(set_attr "type" "ishift")
10873 (set_attr "prefix_0f" "1")
10874 (set_attr "mode" "DI")
10875 (set_attr "athlon_decode" "vector")
10876 (set_attr "amdfam10_decode" "vector")])
10878 (define_expand "x86_64_shift_adj"
10879 [(set (reg:CCZ FLAGS_REG)
10880 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10883 (set (match_operand:DI 0 "register_operand" "")
10884 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10885 (match_operand:DI 1 "register_operand" "")
10888 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10889 (match_operand:DI 3 "register_operand" "r")
10894 (define_expand "ashldi3"
10895 [(set (match_operand:DI 0 "shiftdi_operand" "")
10896 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10897 (match_operand:QI 2 "nonmemory_operand" "")))]
10899 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10901 (define_insn "*ashldi3_1_rex64"
10902 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10903 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10904 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10905 (clobber (reg:CC FLAGS_REG))]
10906 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10908 switch (get_attr_type (insn))
10911 gcc_assert (operands[2] == const1_rtx);
10912 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10913 return "add{q}\t%0, %0";
10916 gcc_assert (CONST_INT_P (operands[2]));
10917 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10918 operands[1] = gen_rtx_MULT (DImode, operands[1],
10919 GEN_INT (1 << INTVAL (operands[2])));
10920 return "lea{q}\t{%a1, %0|%0, %a1}";
10923 if (REG_P (operands[2]))
10924 return "sal{q}\t{%b2, %0|%0, %b2}";
10925 else if (operands[2] == const1_rtx
10926 && (TARGET_SHIFT1 || optimize_size))
10927 return "sal{q}\t%0";
10929 return "sal{q}\t{%2, %0|%0, %2}";
10932 [(set (attr "type")
10933 (cond [(eq_attr "alternative" "1")
10934 (const_string "lea")
10935 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10937 (match_operand 0 "register_operand" ""))
10938 (match_operand 2 "const1_operand" ""))
10939 (const_string "alu")
10941 (const_string "ishift")))
10942 (set_attr "mode" "DI")])
10944 ;; Convert lea to the lea pattern to avoid flags dependency.
10946 [(set (match_operand:DI 0 "register_operand" "")
10947 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10948 (match_operand:QI 2 "immediate_operand" "")))
10949 (clobber (reg:CC FLAGS_REG))]
10950 "TARGET_64BIT && reload_completed
10951 && true_regnum (operands[0]) != true_regnum (operands[1])"
10952 [(set (match_dup 0)
10953 (mult:DI (match_dup 1)
10955 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10957 ;; This pattern can't accept a variable shift count, since shifts by
10958 ;; zero don't affect the flags. We assume that shifts by constant
10959 ;; zero are optimized away.
10960 (define_insn "*ashldi3_cmp_rex64"
10961 [(set (reg FLAGS_REG)
10963 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10964 (match_operand:QI 2 "immediate_operand" "e"))
10966 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10967 (ashift:DI (match_dup 1) (match_dup 2)))]
10970 || !TARGET_PARTIAL_FLAG_REG_STALL
10971 || (operands[2] == const1_rtx
10973 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10974 && ix86_match_ccmode (insn, CCGOCmode)
10975 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10977 switch (get_attr_type (insn))
10980 gcc_assert (operands[2] == const1_rtx);
10981 return "add{q}\t%0, %0";
10984 if (REG_P (operands[2]))
10985 return "sal{q}\t{%b2, %0|%0, %b2}";
10986 else if (operands[2] == const1_rtx
10987 && (TARGET_SHIFT1 || optimize_size))
10988 return "sal{q}\t%0";
10990 return "sal{q}\t{%2, %0|%0, %2}";
10993 [(set (attr "type")
10994 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10996 (match_operand 0 "register_operand" ""))
10997 (match_operand 2 "const1_operand" ""))
10998 (const_string "alu")
11000 (const_string "ishift")))
11001 (set_attr "mode" "DI")])
11003 (define_insn "*ashldi3_cconly_rex64"
11004 [(set (reg FLAGS_REG)
11006 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11007 (match_operand:QI 2 "immediate_operand" "e"))
11009 (clobber (match_scratch:DI 0 "=r"))]
11012 || !TARGET_PARTIAL_FLAG_REG_STALL
11013 || (operands[2] == const1_rtx
11015 || TARGET_DOUBLE_WITH_ADD)))
11016 && ix86_match_ccmode (insn, CCGOCmode)
11017 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11019 switch (get_attr_type (insn))
11022 gcc_assert (operands[2] == const1_rtx);
11023 return "add{q}\t%0, %0";
11026 if (REG_P (operands[2]))
11027 return "sal{q}\t{%b2, %0|%0, %b2}";
11028 else if (operands[2] == const1_rtx
11029 && (TARGET_SHIFT1 || optimize_size))
11030 return "sal{q}\t%0";
11032 return "sal{q}\t{%2, %0|%0, %2}";
11035 [(set (attr "type")
11036 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11038 (match_operand 0 "register_operand" ""))
11039 (match_operand 2 "const1_operand" ""))
11040 (const_string "alu")
11042 (const_string "ishift")))
11043 (set_attr "mode" "DI")])
11045 (define_insn "*ashldi3_1"
11046 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11047 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11048 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11049 (clobber (reg:CC FLAGS_REG))]
11052 [(set_attr "type" "multi")])
11054 ;; By default we don't ask for a scratch register, because when DImode
11055 ;; values are manipulated, registers are already at a premium. But if
11056 ;; we have one handy, we won't turn it away.
11058 [(match_scratch:SI 3 "r")
11059 (parallel [(set (match_operand:DI 0 "register_operand" "")
11060 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11061 (match_operand:QI 2 "nonmemory_operand" "")))
11062 (clobber (reg:CC FLAGS_REG))])
11064 "!TARGET_64BIT && TARGET_CMOVE"
11066 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11069 [(set (match_operand:DI 0 "register_operand" "")
11070 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11071 (match_operand:QI 2 "nonmemory_operand" "")))
11072 (clobber (reg:CC FLAGS_REG))]
11073 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11074 ? epilogue_completed : reload_completed)"
11076 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11078 (define_insn "x86_shld_1"
11079 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11080 (ior:SI (ashift:SI (match_dup 0)
11081 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11082 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11083 (minus:QI (const_int 32) (match_dup 2)))))
11084 (clobber (reg:CC FLAGS_REG))]
11087 shld{l}\t{%2, %1, %0|%0, %1, %2}
11088 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11089 [(set_attr "type" "ishift")
11090 (set_attr "prefix_0f" "1")
11091 (set_attr "mode" "SI")
11092 (set_attr "pent_pair" "np")
11093 (set_attr "athlon_decode" "vector")
11094 (set_attr "amdfam10_decode" "vector")])
11096 (define_expand "x86_shift_adj_1"
11097 [(set (reg:CCZ FLAGS_REG)
11098 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11101 (set (match_operand:SI 0 "register_operand" "")
11102 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11103 (match_operand:SI 1 "register_operand" "")
11106 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11107 (match_operand:SI 3 "register_operand" "r")
11112 (define_expand "x86_shift_adj_2"
11113 [(use (match_operand:SI 0 "register_operand" ""))
11114 (use (match_operand:SI 1 "register_operand" ""))
11115 (use (match_operand:QI 2 "register_operand" ""))]
11118 rtx label = gen_label_rtx ();
11121 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11123 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11124 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11125 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11126 gen_rtx_LABEL_REF (VOIDmode, label),
11128 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11129 JUMP_LABEL (tmp) = label;
11131 emit_move_insn (operands[0], operands[1]);
11132 ix86_expand_clear (operands[1]);
11134 emit_label (label);
11135 LABEL_NUSES (label) = 1;
11140 (define_expand "ashlsi3"
11141 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11142 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11143 (match_operand:QI 2 "nonmemory_operand" "")))
11144 (clobber (reg:CC FLAGS_REG))]
11146 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11148 (define_insn "*ashlsi3_1"
11149 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11150 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11151 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11152 (clobber (reg:CC FLAGS_REG))]
11153 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11155 switch (get_attr_type (insn))
11158 gcc_assert (operands[2] == const1_rtx);
11159 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11160 return "add{l}\t%0, %0";
11166 if (REG_P (operands[2]))
11167 return "sal{l}\t{%b2, %0|%0, %b2}";
11168 else if (operands[2] == const1_rtx
11169 && (TARGET_SHIFT1 || optimize_size))
11170 return "sal{l}\t%0";
11172 return "sal{l}\t{%2, %0|%0, %2}";
11175 [(set (attr "type")
11176 (cond [(eq_attr "alternative" "1")
11177 (const_string "lea")
11178 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11180 (match_operand 0 "register_operand" ""))
11181 (match_operand 2 "const1_operand" ""))
11182 (const_string "alu")
11184 (const_string "ishift")))
11185 (set_attr "mode" "SI")])
11187 ;; Convert lea to the lea pattern to avoid flags dependency.
11189 [(set (match_operand 0 "register_operand" "")
11190 (ashift (match_operand 1 "index_register_operand" "")
11191 (match_operand:QI 2 "const_int_operand" "")))
11192 (clobber (reg:CC FLAGS_REG))]
11194 && true_regnum (operands[0]) != true_regnum (operands[1])
11195 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11199 enum machine_mode mode = GET_MODE (operands[0]);
11201 if (GET_MODE_SIZE (mode) < 4)
11202 operands[0] = gen_lowpart (SImode, operands[0]);
11204 operands[1] = gen_lowpart (Pmode, operands[1]);
11205 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11207 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11208 if (Pmode != SImode)
11209 pat = gen_rtx_SUBREG (SImode, pat, 0);
11210 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11214 ;; Rare case of shifting RSP is handled by generating move and shift
11216 [(set (match_operand 0 "register_operand" "")
11217 (ashift (match_operand 1 "register_operand" "")
11218 (match_operand:QI 2 "const_int_operand" "")))
11219 (clobber (reg:CC FLAGS_REG))]
11221 && true_regnum (operands[0]) != true_regnum (operands[1])"
11225 emit_move_insn (operands[0], operands[1]);
11226 pat = gen_rtx_SET (VOIDmode, operands[0],
11227 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11228 operands[0], operands[2]));
11229 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11230 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11234 (define_insn "*ashlsi3_1_zext"
11235 [(set (match_operand:DI 0 "register_operand" "=r,r")
11236 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11237 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11238 (clobber (reg:CC FLAGS_REG))]
11239 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11241 switch (get_attr_type (insn))
11244 gcc_assert (operands[2] == const1_rtx);
11245 return "add{l}\t%k0, %k0";
11251 if (REG_P (operands[2]))
11252 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11253 else if (operands[2] == const1_rtx
11254 && (TARGET_SHIFT1 || optimize_size))
11255 return "sal{l}\t%k0";
11257 return "sal{l}\t{%2, %k0|%k0, %2}";
11260 [(set (attr "type")
11261 (cond [(eq_attr "alternative" "1")
11262 (const_string "lea")
11263 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11265 (match_operand 2 "const1_operand" ""))
11266 (const_string "alu")
11268 (const_string "ishift")))
11269 (set_attr "mode" "SI")])
11271 ;; Convert lea to the lea pattern to avoid flags dependency.
11273 [(set (match_operand:DI 0 "register_operand" "")
11274 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11275 (match_operand:QI 2 "const_int_operand" ""))))
11276 (clobber (reg:CC FLAGS_REG))]
11277 "TARGET_64BIT && reload_completed
11278 && true_regnum (operands[0]) != true_regnum (operands[1])"
11279 [(set (match_dup 0) (zero_extend:DI
11280 (subreg:SI (mult:SI (match_dup 1)
11281 (match_dup 2)) 0)))]
11283 operands[1] = gen_lowpart (Pmode, operands[1]);
11284 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11287 ;; This pattern can't accept a variable shift count, since shifts by
11288 ;; zero don't affect the flags. We assume that shifts by constant
11289 ;; zero are optimized away.
11290 (define_insn "*ashlsi3_cmp"
11291 [(set (reg FLAGS_REG)
11293 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11294 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11296 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11297 (ashift:SI (match_dup 1) (match_dup 2)))]
11299 || !TARGET_PARTIAL_FLAG_REG_STALL
11300 || (operands[2] == const1_rtx
11302 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11303 && ix86_match_ccmode (insn, CCGOCmode)
11304 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11306 switch (get_attr_type (insn))
11309 gcc_assert (operands[2] == const1_rtx);
11310 return "add{l}\t%0, %0";
11313 if (REG_P (operands[2]))
11314 return "sal{l}\t{%b2, %0|%0, %b2}";
11315 else if (operands[2] == const1_rtx
11316 && (TARGET_SHIFT1 || optimize_size))
11317 return "sal{l}\t%0";
11319 return "sal{l}\t{%2, %0|%0, %2}";
11322 [(set (attr "type")
11323 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11325 (match_operand 0 "register_operand" ""))
11326 (match_operand 2 "const1_operand" ""))
11327 (const_string "alu")
11329 (const_string "ishift")))
11330 (set_attr "mode" "SI")])
11332 (define_insn "*ashlsi3_cconly"
11333 [(set (reg FLAGS_REG)
11335 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11336 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11338 (clobber (match_scratch:SI 0 "=r"))]
11340 || !TARGET_PARTIAL_FLAG_REG_STALL
11341 || (operands[2] == const1_rtx
11343 || TARGET_DOUBLE_WITH_ADD)))
11344 && ix86_match_ccmode (insn, CCGOCmode)
11345 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11347 switch (get_attr_type (insn))
11350 gcc_assert (operands[2] == const1_rtx);
11351 return "add{l}\t%0, %0";
11354 if (REG_P (operands[2]))
11355 return "sal{l}\t{%b2, %0|%0, %b2}";
11356 else if (operands[2] == const1_rtx
11357 && (TARGET_SHIFT1 || optimize_size))
11358 return "sal{l}\t%0";
11360 return "sal{l}\t{%2, %0|%0, %2}";
11363 [(set (attr "type")
11364 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11366 (match_operand 0 "register_operand" ""))
11367 (match_operand 2 "const1_operand" ""))
11368 (const_string "alu")
11370 (const_string "ishift")))
11371 (set_attr "mode" "SI")])
11373 (define_insn "*ashlsi3_cmp_zext"
11374 [(set (reg FLAGS_REG)
11376 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11377 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11379 (set (match_operand:DI 0 "register_operand" "=r")
11380 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11383 || !TARGET_PARTIAL_FLAG_REG_STALL
11384 || (operands[2] == const1_rtx
11386 || TARGET_DOUBLE_WITH_ADD)))
11387 && ix86_match_ccmode (insn, CCGOCmode)
11388 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11390 switch (get_attr_type (insn))
11393 gcc_assert (operands[2] == const1_rtx);
11394 return "add{l}\t%k0, %k0";
11397 if (REG_P (operands[2]))
11398 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11399 else if (operands[2] == const1_rtx
11400 && (TARGET_SHIFT1 || optimize_size))
11401 return "sal{l}\t%k0";
11403 return "sal{l}\t{%2, %k0|%k0, %2}";
11406 [(set (attr "type")
11407 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11409 (match_operand 2 "const1_operand" ""))
11410 (const_string "alu")
11412 (const_string "ishift")))
11413 (set_attr "mode" "SI")])
11415 (define_expand "ashlhi3"
11416 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11417 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11418 (match_operand:QI 2 "nonmemory_operand" "")))
11419 (clobber (reg:CC FLAGS_REG))]
11420 "TARGET_HIMODE_MATH"
11421 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11423 (define_insn "*ashlhi3_1_lea"
11424 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11425 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11426 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11427 (clobber (reg:CC FLAGS_REG))]
11428 "!TARGET_PARTIAL_REG_STALL
11429 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11431 switch (get_attr_type (insn))
11436 gcc_assert (operands[2] == const1_rtx);
11437 return "add{w}\t%0, %0";
11440 if (REG_P (operands[2]))
11441 return "sal{w}\t{%b2, %0|%0, %b2}";
11442 else if (operands[2] == const1_rtx
11443 && (TARGET_SHIFT1 || optimize_size))
11444 return "sal{w}\t%0";
11446 return "sal{w}\t{%2, %0|%0, %2}";
11449 [(set (attr "type")
11450 (cond [(eq_attr "alternative" "1")
11451 (const_string "lea")
11452 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11454 (match_operand 0 "register_operand" ""))
11455 (match_operand 2 "const1_operand" ""))
11456 (const_string "alu")
11458 (const_string "ishift")))
11459 (set_attr "mode" "HI,SI")])
11461 (define_insn "*ashlhi3_1"
11462 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11463 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11464 (match_operand:QI 2 "nonmemory_operand" "cI")))
11465 (clobber (reg:CC FLAGS_REG))]
11466 "TARGET_PARTIAL_REG_STALL
11467 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11469 switch (get_attr_type (insn))
11472 gcc_assert (operands[2] == const1_rtx);
11473 return "add{w}\t%0, %0";
11476 if (REG_P (operands[2]))
11477 return "sal{w}\t{%b2, %0|%0, %b2}";
11478 else if (operands[2] == const1_rtx
11479 && (TARGET_SHIFT1 || optimize_size))
11480 return "sal{w}\t%0";
11482 return "sal{w}\t{%2, %0|%0, %2}";
11485 [(set (attr "type")
11486 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11488 (match_operand 0 "register_operand" ""))
11489 (match_operand 2 "const1_operand" ""))
11490 (const_string "alu")
11492 (const_string "ishift")))
11493 (set_attr "mode" "HI")])
11495 ;; This pattern can't accept a variable shift count, since shifts by
11496 ;; zero don't affect the flags. We assume that shifts by constant
11497 ;; zero are optimized away.
11498 (define_insn "*ashlhi3_cmp"
11499 [(set (reg FLAGS_REG)
11501 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11502 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11504 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11505 (ashift:HI (match_dup 1) (match_dup 2)))]
11507 || !TARGET_PARTIAL_FLAG_REG_STALL
11508 || (operands[2] == const1_rtx
11510 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11511 && ix86_match_ccmode (insn, CCGOCmode)
11512 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11514 switch (get_attr_type (insn))
11517 gcc_assert (operands[2] == const1_rtx);
11518 return "add{w}\t%0, %0";
11521 if (REG_P (operands[2]))
11522 return "sal{w}\t{%b2, %0|%0, %b2}";
11523 else if (operands[2] == const1_rtx
11524 && (TARGET_SHIFT1 || optimize_size))
11525 return "sal{w}\t%0";
11527 return "sal{w}\t{%2, %0|%0, %2}";
11530 [(set (attr "type")
11531 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11533 (match_operand 0 "register_operand" ""))
11534 (match_operand 2 "const1_operand" ""))
11535 (const_string "alu")
11537 (const_string "ishift")))
11538 (set_attr "mode" "HI")])
11540 (define_insn "*ashlhi3_cconly"
11541 [(set (reg FLAGS_REG)
11543 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11544 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11546 (clobber (match_scratch:HI 0 "=r"))]
11548 || !TARGET_PARTIAL_FLAG_REG_STALL
11549 || (operands[2] == const1_rtx
11551 || TARGET_DOUBLE_WITH_ADD)))
11552 && ix86_match_ccmode (insn, CCGOCmode)
11553 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11555 switch (get_attr_type (insn))
11558 gcc_assert (operands[2] == const1_rtx);
11559 return "add{w}\t%0, %0";
11562 if (REG_P (operands[2]))
11563 return "sal{w}\t{%b2, %0|%0, %b2}";
11564 else if (operands[2] == const1_rtx
11565 && (TARGET_SHIFT1 || optimize_size))
11566 return "sal{w}\t%0";
11568 return "sal{w}\t{%2, %0|%0, %2}";
11571 [(set (attr "type")
11572 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11574 (match_operand 0 "register_operand" ""))
11575 (match_operand 2 "const1_operand" ""))
11576 (const_string "alu")
11578 (const_string "ishift")))
11579 (set_attr "mode" "HI")])
11581 (define_expand "ashlqi3"
11582 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11583 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11584 (match_operand:QI 2 "nonmemory_operand" "")))
11585 (clobber (reg:CC FLAGS_REG))]
11586 "TARGET_QIMODE_MATH"
11587 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11589 ;; %%% Potential partial reg stall on alternative 2. What to do?
11591 (define_insn "*ashlqi3_1_lea"
11592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11593 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11594 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11595 (clobber (reg:CC FLAGS_REG))]
11596 "!TARGET_PARTIAL_REG_STALL
11597 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11599 switch (get_attr_type (insn))
11604 gcc_assert (operands[2] == const1_rtx);
11605 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11606 return "add{l}\t%k0, %k0";
11608 return "add{b}\t%0, %0";
11611 if (REG_P (operands[2]))
11613 if (get_attr_mode (insn) == MODE_SI)
11614 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11616 return "sal{b}\t{%b2, %0|%0, %b2}";
11618 else if (operands[2] == const1_rtx
11619 && (TARGET_SHIFT1 || optimize_size))
11621 if (get_attr_mode (insn) == MODE_SI)
11622 return "sal{l}\t%0";
11624 return "sal{b}\t%0";
11628 if (get_attr_mode (insn) == MODE_SI)
11629 return "sal{l}\t{%2, %k0|%k0, %2}";
11631 return "sal{b}\t{%2, %0|%0, %2}";
11635 [(set (attr "type")
11636 (cond [(eq_attr "alternative" "2")
11637 (const_string "lea")
11638 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11640 (match_operand 0 "register_operand" ""))
11641 (match_operand 2 "const1_operand" ""))
11642 (const_string "alu")
11644 (const_string "ishift")))
11645 (set_attr "mode" "QI,SI,SI")])
11647 (define_insn "*ashlqi3_1"
11648 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11649 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11650 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11651 (clobber (reg:CC FLAGS_REG))]
11652 "TARGET_PARTIAL_REG_STALL
11653 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11655 switch (get_attr_type (insn))
11658 gcc_assert (operands[2] == const1_rtx);
11659 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11660 return "add{l}\t%k0, %k0";
11662 return "add{b}\t%0, %0";
11665 if (REG_P (operands[2]))
11667 if (get_attr_mode (insn) == MODE_SI)
11668 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11670 return "sal{b}\t{%b2, %0|%0, %b2}";
11672 else if (operands[2] == const1_rtx
11673 && (TARGET_SHIFT1 || optimize_size))
11675 if (get_attr_mode (insn) == MODE_SI)
11676 return "sal{l}\t%0";
11678 return "sal{b}\t%0";
11682 if (get_attr_mode (insn) == MODE_SI)
11683 return "sal{l}\t{%2, %k0|%k0, %2}";
11685 return "sal{b}\t{%2, %0|%0, %2}";
11689 [(set (attr "type")
11690 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11692 (match_operand 0 "register_operand" ""))
11693 (match_operand 2 "const1_operand" ""))
11694 (const_string "alu")
11696 (const_string "ishift")))
11697 (set_attr "mode" "QI,SI")])
11699 ;; This pattern can't accept a variable shift count, since shifts by
11700 ;; zero don't affect the flags. We assume that shifts by constant
11701 ;; zero are optimized away.
11702 (define_insn "*ashlqi3_cmp"
11703 [(set (reg FLAGS_REG)
11705 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11706 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11708 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11709 (ashift:QI (match_dup 1) (match_dup 2)))]
11711 || !TARGET_PARTIAL_FLAG_REG_STALL
11712 || (operands[2] == const1_rtx
11714 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11715 && ix86_match_ccmode (insn, CCGOCmode)
11716 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11718 switch (get_attr_type (insn))
11721 gcc_assert (operands[2] == const1_rtx);
11722 return "add{b}\t%0, %0";
11725 if (REG_P (operands[2]))
11726 return "sal{b}\t{%b2, %0|%0, %b2}";
11727 else if (operands[2] == const1_rtx
11728 && (TARGET_SHIFT1 || optimize_size))
11729 return "sal{b}\t%0";
11731 return "sal{b}\t{%2, %0|%0, %2}";
11734 [(set (attr "type")
11735 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11737 (match_operand 0 "register_operand" ""))
11738 (match_operand 2 "const1_operand" ""))
11739 (const_string "alu")
11741 (const_string "ishift")))
11742 (set_attr "mode" "QI")])
11744 (define_insn "*ashlqi3_cconly"
11745 [(set (reg FLAGS_REG)
11747 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11748 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11750 (clobber (match_scratch:QI 0 "=q"))]
11752 || !TARGET_PARTIAL_FLAG_REG_STALL
11753 || (operands[2] == const1_rtx
11755 || TARGET_DOUBLE_WITH_ADD)))
11756 && ix86_match_ccmode (insn, CCGOCmode)
11757 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11759 switch (get_attr_type (insn))
11762 gcc_assert (operands[2] == const1_rtx);
11763 return "add{b}\t%0, %0";
11766 if (REG_P (operands[2]))
11767 return "sal{b}\t{%b2, %0|%0, %b2}";
11768 else if (operands[2] == const1_rtx
11769 && (TARGET_SHIFT1 || optimize_size))
11770 return "sal{b}\t%0";
11772 return "sal{b}\t{%2, %0|%0, %2}";
11775 [(set (attr "type")
11776 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11778 (match_operand 0 "register_operand" ""))
11779 (match_operand 2 "const1_operand" ""))
11780 (const_string "alu")
11782 (const_string "ishift")))
11783 (set_attr "mode" "QI")])
11785 ;; See comment above `ashldi3' about how this works.
11787 (define_expand "ashrti3"
11788 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11789 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11790 (match_operand:QI 2 "nonmemory_operand" "")))
11791 (clobber (reg:CC FLAGS_REG))])]
11794 if (! immediate_operand (operands[2], QImode))
11796 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11799 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11803 (define_insn "ashrti3_1"
11804 [(set (match_operand:TI 0 "register_operand" "=r")
11805 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11806 (match_operand:QI 2 "register_operand" "c")))
11807 (clobber (match_scratch:DI 3 "=&r"))
11808 (clobber (reg:CC FLAGS_REG))]
11811 [(set_attr "type" "multi")])
11813 (define_insn "*ashrti3_2"
11814 [(set (match_operand:TI 0 "register_operand" "=r")
11815 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11816 (match_operand:QI 2 "immediate_operand" "O")))
11817 (clobber (reg:CC FLAGS_REG))]
11820 [(set_attr "type" "multi")])
11823 [(set (match_operand:TI 0 "register_operand" "")
11824 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11825 (match_operand:QI 2 "register_operand" "")))
11826 (clobber (match_scratch:DI 3 ""))
11827 (clobber (reg:CC FLAGS_REG))]
11828 "TARGET_64BIT && reload_completed"
11830 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11833 [(set (match_operand:TI 0 "register_operand" "")
11834 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11835 (match_operand:QI 2 "immediate_operand" "")))
11836 (clobber (reg:CC FLAGS_REG))]
11837 "TARGET_64BIT && reload_completed"
11839 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11841 (define_insn "x86_64_shrd"
11842 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11843 (ior:DI (ashiftrt:DI (match_dup 0)
11844 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11845 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11846 (minus:QI (const_int 64) (match_dup 2)))))
11847 (clobber (reg:CC FLAGS_REG))]
11850 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11851 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11852 [(set_attr "type" "ishift")
11853 (set_attr "prefix_0f" "1")
11854 (set_attr "mode" "DI")
11855 (set_attr "athlon_decode" "vector")
11856 (set_attr "amdfam10_decode" "vector")])
11858 (define_expand "ashrdi3"
11859 [(set (match_operand:DI 0 "shiftdi_operand" "")
11860 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11861 (match_operand:QI 2 "nonmemory_operand" "")))]
11863 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11865 (define_insn "*ashrdi3_63_rex64"
11866 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11867 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11868 (match_operand:DI 2 "const_int_operand" "i,i")))
11869 (clobber (reg:CC FLAGS_REG))]
11870 "TARGET_64BIT && INTVAL (operands[2]) == 63
11871 && (TARGET_USE_CLTD || optimize_size)
11872 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11875 sar{q}\t{%2, %0|%0, %2}"
11876 [(set_attr "type" "imovx,ishift")
11877 (set_attr "prefix_0f" "0,*")
11878 (set_attr "length_immediate" "0,*")
11879 (set_attr "modrm" "0,1")
11880 (set_attr "mode" "DI")])
11882 (define_insn "*ashrdi3_1_one_bit_rex64"
11883 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11884 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11885 (match_operand:QI 2 "const1_operand" "")))
11886 (clobber (reg:CC FLAGS_REG))]
11888 && (TARGET_SHIFT1 || optimize_size)
11889 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11891 [(set_attr "type" "ishift")
11892 (set (attr "length")
11893 (if_then_else (match_operand:DI 0 "register_operand" "")
11895 (const_string "*")))])
11897 (define_insn "*ashrdi3_1_rex64"
11898 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11899 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11900 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11901 (clobber (reg:CC FLAGS_REG))]
11902 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11904 sar{q}\t{%2, %0|%0, %2}
11905 sar{q}\t{%b2, %0|%0, %b2}"
11906 [(set_attr "type" "ishift")
11907 (set_attr "mode" "DI")])
11909 ;; This pattern can't accept a variable shift count, since shifts by
11910 ;; zero don't affect the flags. We assume that shifts by constant
11911 ;; zero are optimized away.
11912 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11913 [(set (reg FLAGS_REG)
11915 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11916 (match_operand:QI 2 "const1_operand" ""))
11918 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11919 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11921 && (TARGET_SHIFT1 || optimize_size)
11922 && ix86_match_ccmode (insn, CCGOCmode)
11923 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11925 [(set_attr "type" "ishift")
11926 (set (attr "length")
11927 (if_then_else (match_operand:DI 0 "register_operand" "")
11929 (const_string "*")))])
11931 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11932 [(set (reg FLAGS_REG)
11934 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11935 (match_operand:QI 2 "const1_operand" ""))
11937 (clobber (match_scratch:DI 0 "=r"))]
11939 && (TARGET_SHIFT1 || optimize_size)
11940 && ix86_match_ccmode (insn, CCGOCmode)
11941 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11943 [(set_attr "type" "ishift")
11944 (set_attr "length" "2")])
11946 ;; This pattern can't accept a variable shift count, since shifts by
11947 ;; zero don't affect the flags. We assume that shifts by constant
11948 ;; zero are optimized away.
11949 (define_insn "*ashrdi3_cmp_rex64"
11950 [(set (reg FLAGS_REG)
11952 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11953 (match_operand:QI 2 "const_int_operand" "n"))
11955 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11956 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11958 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11959 && ix86_match_ccmode (insn, CCGOCmode)
11960 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11961 "sar{q}\t{%2, %0|%0, %2}"
11962 [(set_attr "type" "ishift")
11963 (set_attr "mode" "DI")])
11965 (define_insn "*ashrdi3_cconly_rex64"
11966 [(set (reg FLAGS_REG)
11968 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11969 (match_operand:QI 2 "const_int_operand" "n"))
11971 (clobber (match_scratch:DI 0 "=r"))]
11973 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11974 && ix86_match_ccmode (insn, CCGOCmode)
11975 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11976 "sar{q}\t{%2, %0|%0, %2}"
11977 [(set_attr "type" "ishift")
11978 (set_attr "mode" "DI")])
11980 (define_insn "*ashrdi3_1"
11981 [(set (match_operand:DI 0 "register_operand" "=r")
11982 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11983 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11984 (clobber (reg:CC FLAGS_REG))]
11987 [(set_attr "type" "multi")])
11989 ;; By default we don't ask for a scratch register, because when DImode
11990 ;; values are manipulated, registers are already at a premium. But if
11991 ;; we have one handy, we won't turn it away.
11993 [(match_scratch:SI 3 "r")
11994 (parallel [(set (match_operand:DI 0 "register_operand" "")
11995 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11996 (match_operand:QI 2 "nonmemory_operand" "")))
11997 (clobber (reg:CC FLAGS_REG))])
11999 "!TARGET_64BIT && TARGET_CMOVE"
12001 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12004 [(set (match_operand:DI 0 "register_operand" "")
12005 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12006 (match_operand:QI 2 "nonmemory_operand" "")))
12007 (clobber (reg:CC FLAGS_REG))]
12008 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12009 ? epilogue_completed : reload_completed)"
12011 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12013 (define_insn "x86_shrd_1"
12014 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12015 (ior:SI (ashiftrt:SI (match_dup 0)
12016 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12017 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12018 (minus:QI (const_int 32) (match_dup 2)))))
12019 (clobber (reg:CC FLAGS_REG))]
12022 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12023 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12024 [(set_attr "type" "ishift")
12025 (set_attr "prefix_0f" "1")
12026 (set_attr "pent_pair" "np")
12027 (set_attr "mode" "SI")])
12029 (define_expand "x86_shift_adj_3"
12030 [(use (match_operand:SI 0 "register_operand" ""))
12031 (use (match_operand:SI 1 "register_operand" ""))
12032 (use (match_operand:QI 2 "register_operand" ""))]
12035 rtx label = gen_label_rtx ();
12038 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12040 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12041 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12042 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12043 gen_rtx_LABEL_REF (VOIDmode, label),
12045 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12046 JUMP_LABEL (tmp) = label;
12048 emit_move_insn (operands[0], operands[1]);
12049 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12051 emit_label (label);
12052 LABEL_NUSES (label) = 1;
12057 (define_insn "ashrsi3_31"
12058 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12059 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12060 (match_operand:SI 2 "const_int_operand" "i,i")))
12061 (clobber (reg:CC FLAGS_REG))]
12062 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12063 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12066 sar{l}\t{%2, %0|%0, %2}"
12067 [(set_attr "type" "imovx,ishift")
12068 (set_attr "prefix_0f" "0,*")
12069 (set_attr "length_immediate" "0,*")
12070 (set_attr "modrm" "0,1")
12071 (set_attr "mode" "SI")])
12073 (define_insn "*ashrsi3_31_zext"
12074 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12075 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12076 (match_operand:SI 2 "const_int_operand" "i,i"))))
12077 (clobber (reg:CC FLAGS_REG))]
12078 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12079 && INTVAL (operands[2]) == 31
12080 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12083 sar{l}\t{%2, %k0|%k0, %2}"
12084 [(set_attr "type" "imovx,ishift")
12085 (set_attr "prefix_0f" "0,*")
12086 (set_attr "length_immediate" "0,*")
12087 (set_attr "modrm" "0,1")
12088 (set_attr "mode" "SI")])
12090 (define_expand "ashrsi3"
12091 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12092 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12093 (match_operand:QI 2 "nonmemory_operand" "")))
12094 (clobber (reg:CC FLAGS_REG))]
12096 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12098 (define_insn "*ashrsi3_1_one_bit"
12099 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12100 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12101 (match_operand:QI 2 "const1_operand" "")))
12102 (clobber (reg:CC FLAGS_REG))]
12103 "(TARGET_SHIFT1 || optimize_size)
12104 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12106 [(set_attr "type" "ishift")
12107 (set (attr "length")
12108 (if_then_else (match_operand:SI 0 "register_operand" "")
12110 (const_string "*")))])
12112 (define_insn "*ashrsi3_1_one_bit_zext"
12113 [(set (match_operand:DI 0 "register_operand" "=r")
12114 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12115 (match_operand:QI 2 "const1_operand" ""))))
12116 (clobber (reg:CC FLAGS_REG))]
12118 && (TARGET_SHIFT1 || optimize_size)
12119 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12121 [(set_attr "type" "ishift")
12122 (set_attr "length" "2")])
12124 (define_insn "*ashrsi3_1"
12125 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12126 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12127 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12128 (clobber (reg:CC FLAGS_REG))]
12129 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12131 sar{l}\t{%2, %0|%0, %2}
12132 sar{l}\t{%b2, %0|%0, %b2}"
12133 [(set_attr "type" "ishift")
12134 (set_attr "mode" "SI")])
12136 (define_insn "*ashrsi3_1_zext"
12137 [(set (match_operand:DI 0 "register_operand" "=r,r")
12138 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12139 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12140 (clobber (reg:CC FLAGS_REG))]
12141 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12143 sar{l}\t{%2, %k0|%k0, %2}
12144 sar{l}\t{%b2, %k0|%k0, %b2}"
12145 [(set_attr "type" "ishift")
12146 (set_attr "mode" "SI")])
12148 ;; This pattern can't accept a variable shift count, since shifts by
12149 ;; zero don't affect the flags. We assume that shifts by constant
12150 ;; zero are optimized away.
12151 (define_insn "*ashrsi3_one_bit_cmp"
12152 [(set (reg FLAGS_REG)
12154 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12155 (match_operand:QI 2 "const1_operand" ""))
12157 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12158 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12159 "(TARGET_SHIFT1 || optimize_size)
12160 && ix86_match_ccmode (insn, CCGOCmode)
12161 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12163 [(set_attr "type" "ishift")
12164 (set (attr "length")
12165 (if_then_else (match_operand:SI 0 "register_operand" "")
12167 (const_string "*")))])
12169 (define_insn "*ashrsi3_one_bit_cconly"
12170 [(set (reg FLAGS_REG)
12172 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12173 (match_operand:QI 2 "const1_operand" ""))
12175 (clobber (match_scratch:SI 0 "=r"))]
12176 "(TARGET_SHIFT1 || optimize_size)
12177 && ix86_match_ccmode (insn, CCGOCmode)
12178 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12180 [(set_attr "type" "ishift")
12181 (set_attr "length" "2")])
12183 (define_insn "*ashrsi3_one_bit_cmp_zext"
12184 [(set (reg FLAGS_REG)
12186 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12187 (match_operand:QI 2 "const1_operand" ""))
12189 (set (match_operand:DI 0 "register_operand" "=r")
12190 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12192 && (TARGET_SHIFT1 || optimize_size)
12193 && ix86_match_ccmode (insn, CCmode)
12194 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12196 [(set_attr "type" "ishift")
12197 (set_attr "length" "2")])
12199 ;; This pattern can't accept a variable shift count, since shifts by
12200 ;; zero don't affect the flags. We assume that shifts by constant
12201 ;; zero are optimized away.
12202 (define_insn "*ashrsi3_cmp"
12203 [(set (reg FLAGS_REG)
12205 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12206 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12208 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12209 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12210 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12211 && ix86_match_ccmode (insn, CCGOCmode)
12212 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12213 "sar{l}\t{%2, %0|%0, %2}"
12214 [(set_attr "type" "ishift")
12215 (set_attr "mode" "SI")])
12217 (define_insn "*ashrsi3_cconly"
12218 [(set (reg FLAGS_REG)
12220 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12221 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12223 (clobber (match_scratch:SI 0 "=r"))]
12224 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12225 && ix86_match_ccmode (insn, CCGOCmode)
12226 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12227 "sar{l}\t{%2, %0|%0, %2}"
12228 [(set_attr "type" "ishift")
12229 (set_attr "mode" "SI")])
12231 (define_insn "*ashrsi3_cmp_zext"
12232 [(set (reg FLAGS_REG)
12234 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12235 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12237 (set (match_operand:DI 0 "register_operand" "=r")
12238 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12240 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12241 && ix86_match_ccmode (insn, CCGOCmode)
12242 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12243 "sar{l}\t{%2, %k0|%k0, %2}"
12244 [(set_attr "type" "ishift")
12245 (set_attr "mode" "SI")])
12247 (define_expand "ashrhi3"
12248 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12249 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12250 (match_operand:QI 2 "nonmemory_operand" "")))
12251 (clobber (reg:CC FLAGS_REG))]
12252 "TARGET_HIMODE_MATH"
12253 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12255 (define_insn "*ashrhi3_1_one_bit"
12256 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12257 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12258 (match_operand:QI 2 "const1_operand" "")))
12259 (clobber (reg:CC FLAGS_REG))]
12260 "(TARGET_SHIFT1 || optimize_size)
12261 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12263 [(set_attr "type" "ishift")
12264 (set (attr "length")
12265 (if_then_else (match_operand 0 "register_operand" "")
12267 (const_string "*")))])
12269 (define_insn "*ashrhi3_1"
12270 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12271 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12272 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12273 (clobber (reg:CC FLAGS_REG))]
12274 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12276 sar{w}\t{%2, %0|%0, %2}
12277 sar{w}\t{%b2, %0|%0, %b2}"
12278 [(set_attr "type" "ishift")
12279 (set_attr "mode" "HI")])
12281 ;; This pattern can't accept a variable shift count, since shifts by
12282 ;; zero don't affect the flags. We assume that shifts by constant
12283 ;; zero are optimized away.
12284 (define_insn "*ashrhi3_one_bit_cmp"
12285 [(set (reg FLAGS_REG)
12287 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12288 (match_operand:QI 2 "const1_operand" ""))
12290 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12291 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12292 "(TARGET_SHIFT1 || optimize_size)
12293 && ix86_match_ccmode (insn, CCGOCmode)
12294 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12296 [(set_attr "type" "ishift")
12297 (set (attr "length")
12298 (if_then_else (match_operand 0 "register_operand" "")
12300 (const_string "*")))])
12302 (define_insn "*ashrhi3_one_bit_cconly"
12303 [(set (reg FLAGS_REG)
12305 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12306 (match_operand:QI 2 "const1_operand" ""))
12308 (clobber (match_scratch:HI 0 "=r"))]
12309 "(TARGET_SHIFT1 || optimize_size)
12310 && ix86_match_ccmode (insn, CCGOCmode)
12311 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12313 [(set_attr "type" "ishift")
12314 (set_attr "length" "2")])
12316 ;; This pattern can't accept a variable shift count, since shifts by
12317 ;; zero don't affect the flags. We assume that shifts by constant
12318 ;; zero are optimized away.
12319 (define_insn "*ashrhi3_cmp"
12320 [(set (reg FLAGS_REG)
12322 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12323 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12325 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12326 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12327 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12328 && ix86_match_ccmode (insn, CCGOCmode)
12329 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12330 "sar{w}\t{%2, %0|%0, %2}"
12331 [(set_attr "type" "ishift")
12332 (set_attr "mode" "HI")])
12334 (define_insn "*ashrhi3_cconly"
12335 [(set (reg FLAGS_REG)
12337 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12338 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12340 (clobber (match_scratch:HI 0 "=r"))]
12341 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12342 && ix86_match_ccmode (insn, CCGOCmode)
12343 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12344 "sar{w}\t{%2, %0|%0, %2}"
12345 [(set_attr "type" "ishift")
12346 (set_attr "mode" "HI")])
12348 (define_expand "ashrqi3"
12349 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12350 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12351 (match_operand:QI 2 "nonmemory_operand" "")))
12352 (clobber (reg:CC FLAGS_REG))]
12353 "TARGET_QIMODE_MATH"
12354 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12356 (define_insn "*ashrqi3_1_one_bit"
12357 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12358 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12359 (match_operand:QI 2 "const1_operand" "")))
12360 (clobber (reg:CC FLAGS_REG))]
12361 "(TARGET_SHIFT1 || optimize_size)
12362 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12364 [(set_attr "type" "ishift")
12365 (set (attr "length")
12366 (if_then_else (match_operand 0 "register_operand" "")
12368 (const_string "*")))])
12370 (define_insn "*ashrqi3_1_one_bit_slp"
12371 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12372 (ashiftrt:QI (match_dup 0)
12373 (match_operand:QI 1 "const1_operand" "")))
12374 (clobber (reg:CC FLAGS_REG))]
12375 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12376 && (TARGET_SHIFT1 || optimize_size)
12377 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12379 [(set_attr "type" "ishift1")
12380 (set (attr "length")
12381 (if_then_else (match_operand 0 "register_operand" "")
12383 (const_string "*")))])
12385 (define_insn "*ashrqi3_1"
12386 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12387 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12388 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12389 (clobber (reg:CC FLAGS_REG))]
12390 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12392 sar{b}\t{%2, %0|%0, %2}
12393 sar{b}\t{%b2, %0|%0, %b2}"
12394 [(set_attr "type" "ishift")
12395 (set_attr "mode" "QI")])
12397 (define_insn "*ashrqi3_1_slp"
12398 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12399 (ashiftrt:QI (match_dup 0)
12400 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12401 (clobber (reg:CC FLAGS_REG))]
12402 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12403 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12405 sar{b}\t{%1, %0|%0, %1}
12406 sar{b}\t{%b1, %0|%0, %b1}"
12407 [(set_attr "type" "ishift1")
12408 (set_attr "mode" "QI")])
12410 ;; This pattern can't accept a variable shift count, since shifts by
12411 ;; zero don't affect the flags. We assume that shifts by constant
12412 ;; zero are optimized away.
12413 (define_insn "*ashrqi3_one_bit_cmp"
12414 [(set (reg FLAGS_REG)
12416 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12417 (match_operand:QI 2 "const1_operand" "I"))
12419 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12420 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12421 "(TARGET_SHIFT1 || optimize_size)
12422 && ix86_match_ccmode (insn, CCGOCmode)
12423 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12425 [(set_attr "type" "ishift")
12426 (set (attr "length")
12427 (if_then_else (match_operand 0 "register_operand" "")
12429 (const_string "*")))])
12431 (define_insn "*ashrqi3_one_bit_cconly"
12432 [(set (reg FLAGS_REG)
12434 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12435 (match_operand:QI 2 "const1_operand" "I"))
12437 (clobber (match_scratch:QI 0 "=q"))]
12438 "(TARGET_SHIFT1 || optimize_size)
12439 && ix86_match_ccmode (insn, CCGOCmode)
12440 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12442 [(set_attr "type" "ishift")
12443 (set_attr "length" "2")])
12445 ;; This pattern can't accept a variable shift count, since shifts by
12446 ;; zero don't affect the flags. We assume that shifts by constant
12447 ;; zero are optimized away.
12448 (define_insn "*ashrqi3_cmp"
12449 [(set (reg FLAGS_REG)
12451 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12452 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12454 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12455 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12456 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12457 && ix86_match_ccmode (insn, CCGOCmode)
12458 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12459 "sar{b}\t{%2, %0|%0, %2}"
12460 [(set_attr "type" "ishift")
12461 (set_attr "mode" "QI")])
12463 (define_insn "*ashrqi3_cconly"
12464 [(set (reg FLAGS_REG)
12466 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12467 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12469 (clobber (match_scratch:QI 0 "=q"))]
12470 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12471 && ix86_match_ccmode (insn, CCGOCmode)
12472 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12473 "sar{b}\t{%2, %0|%0, %2}"
12474 [(set_attr "type" "ishift")
12475 (set_attr "mode" "QI")])
12478 ;; Logical shift instructions
12480 ;; See comment above `ashldi3' about how this works.
12482 (define_expand "lshrti3"
12483 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12484 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12485 (match_operand:QI 2 "nonmemory_operand" "")))
12486 (clobber (reg:CC FLAGS_REG))])]
12489 if (! immediate_operand (operands[2], QImode))
12491 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12494 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12498 (define_insn "lshrti3_1"
12499 [(set (match_operand:TI 0 "register_operand" "=r")
12500 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12501 (match_operand:QI 2 "register_operand" "c")))
12502 (clobber (match_scratch:DI 3 "=&r"))
12503 (clobber (reg:CC FLAGS_REG))]
12506 [(set_attr "type" "multi")])
12508 ;; This pattern must be defined before *lshrti3_2 to prevent
12509 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12511 (define_insn "sse2_lshrti3"
12512 [(set (match_operand:TI 0 "register_operand" "=x")
12513 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12514 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12517 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12518 return "psrldq\t{%2, %0|%0, %2}";
12520 [(set_attr "type" "sseishft")
12521 (set_attr "prefix_data16" "1")
12522 (set_attr "mode" "TI")])
12524 (define_insn "*lshrti3_2"
12525 [(set (match_operand:TI 0 "register_operand" "=r")
12526 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12527 (match_operand:QI 2 "immediate_operand" "O")))
12528 (clobber (reg:CC FLAGS_REG))]
12531 [(set_attr "type" "multi")])
12534 [(set (match_operand:TI 0 "register_operand" "")
12535 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12536 (match_operand:QI 2 "register_operand" "")))
12537 (clobber (match_scratch:DI 3 ""))
12538 (clobber (reg:CC FLAGS_REG))]
12539 "TARGET_64BIT && reload_completed"
12541 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12544 [(set (match_operand:TI 0 "register_operand" "")
12545 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12546 (match_operand:QI 2 "immediate_operand" "")))
12547 (clobber (reg:CC FLAGS_REG))]
12548 "TARGET_64BIT && reload_completed"
12550 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12552 (define_expand "lshrdi3"
12553 [(set (match_operand:DI 0 "shiftdi_operand" "")
12554 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12555 (match_operand:QI 2 "nonmemory_operand" "")))]
12557 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12559 (define_insn "*lshrdi3_1_one_bit_rex64"
12560 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12561 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12562 (match_operand:QI 2 "const1_operand" "")))
12563 (clobber (reg:CC FLAGS_REG))]
12565 && (TARGET_SHIFT1 || optimize_size)
12566 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12568 [(set_attr "type" "ishift")
12569 (set (attr "length")
12570 (if_then_else (match_operand:DI 0 "register_operand" "")
12572 (const_string "*")))])
12574 (define_insn "*lshrdi3_1_rex64"
12575 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12576 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12577 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12578 (clobber (reg:CC FLAGS_REG))]
12579 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12581 shr{q}\t{%2, %0|%0, %2}
12582 shr{q}\t{%b2, %0|%0, %b2}"
12583 [(set_attr "type" "ishift")
12584 (set_attr "mode" "DI")])
12586 ;; This pattern can't accept a variable shift count, since shifts by
12587 ;; zero don't affect the flags. We assume that shifts by constant
12588 ;; zero are optimized away.
12589 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12590 [(set (reg FLAGS_REG)
12592 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12593 (match_operand:QI 2 "const1_operand" ""))
12595 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12596 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12598 && (TARGET_SHIFT1 || optimize_size)
12599 && ix86_match_ccmode (insn, CCGOCmode)
12600 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12602 [(set_attr "type" "ishift")
12603 (set (attr "length")
12604 (if_then_else (match_operand:DI 0 "register_operand" "")
12606 (const_string "*")))])
12608 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12609 [(set (reg FLAGS_REG)
12611 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12612 (match_operand:QI 2 "const1_operand" ""))
12614 (clobber (match_scratch:DI 0 "=r"))]
12616 && (TARGET_SHIFT1 || optimize_size)
12617 && ix86_match_ccmode (insn, CCGOCmode)
12618 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12620 [(set_attr "type" "ishift")
12621 (set_attr "length" "2")])
12623 ;; This pattern can't accept a variable shift count, since shifts by
12624 ;; zero don't affect the flags. We assume that shifts by constant
12625 ;; zero are optimized away.
12626 (define_insn "*lshrdi3_cmp_rex64"
12627 [(set (reg FLAGS_REG)
12629 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12630 (match_operand:QI 2 "const_int_operand" "e"))
12632 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12633 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12635 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12636 && ix86_match_ccmode (insn, CCGOCmode)
12637 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12638 "shr{q}\t{%2, %0|%0, %2}"
12639 [(set_attr "type" "ishift")
12640 (set_attr "mode" "DI")])
12642 (define_insn "*lshrdi3_cconly_rex64"
12643 [(set (reg FLAGS_REG)
12645 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12646 (match_operand:QI 2 "const_int_operand" "e"))
12648 (clobber (match_scratch:DI 0 "=r"))]
12650 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12651 && ix86_match_ccmode (insn, CCGOCmode)
12652 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12653 "shr{q}\t{%2, %0|%0, %2}"
12654 [(set_attr "type" "ishift")
12655 (set_attr "mode" "DI")])
12657 (define_insn "*lshrdi3_1"
12658 [(set (match_operand:DI 0 "register_operand" "=r")
12659 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12660 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12661 (clobber (reg:CC FLAGS_REG))]
12664 [(set_attr "type" "multi")])
12666 ;; By default we don't ask for a scratch register, because when DImode
12667 ;; values are manipulated, registers are already at a premium. But if
12668 ;; we have one handy, we won't turn it away.
12670 [(match_scratch:SI 3 "r")
12671 (parallel [(set (match_operand:DI 0 "register_operand" "")
12672 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12673 (match_operand:QI 2 "nonmemory_operand" "")))
12674 (clobber (reg:CC FLAGS_REG))])
12676 "!TARGET_64BIT && TARGET_CMOVE"
12678 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12681 [(set (match_operand:DI 0 "register_operand" "")
12682 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12683 (match_operand:QI 2 "nonmemory_operand" "")))
12684 (clobber (reg:CC FLAGS_REG))]
12685 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12686 ? epilogue_completed : reload_completed)"
12688 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12690 (define_expand "lshrsi3"
12691 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12692 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12693 (match_operand:QI 2 "nonmemory_operand" "")))
12694 (clobber (reg:CC FLAGS_REG))]
12696 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12698 (define_insn "*lshrsi3_1_one_bit"
12699 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12700 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12701 (match_operand:QI 2 "const1_operand" "")))
12702 (clobber (reg:CC FLAGS_REG))]
12703 "(TARGET_SHIFT1 || optimize_size)
12704 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12706 [(set_attr "type" "ishift")
12707 (set (attr "length")
12708 (if_then_else (match_operand:SI 0 "register_operand" "")
12710 (const_string "*")))])
12712 (define_insn "*lshrsi3_1_one_bit_zext"
12713 [(set (match_operand:DI 0 "register_operand" "=r")
12714 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12715 (match_operand:QI 2 "const1_operand" "")))
12716 (clobber (reg:CC FLAGS_REG))]
12718 && (TARGET_SHIFT1 || optimize_size)
12719 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12721 [(set_attr "type" "ishift")
12722 (set_attr "length" "2")])
12724 (define_insn "*lshrsi3_1"
12725 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12726 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12727 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12728 (clobber (reg:CC FLAGS_REG))]
12729 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12731 shr{l}\t{%2, %0|%0, %2}
12732 shr{l}\t{%b2, %0|%0, %b2}"
12733 [(set_attr "type" "ishift")
12734 (set_attr "mode" "SI")])
12736 (define_insn "*lshrsi3_1_zext"
12737 [(set (match_operand:DI 0 "register_operand" "=r,r")
12739 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12740 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12741 (clobber (reg:CC FLAGS_REG))]
12742 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12744 shr{l}\t{%2, %k0|%k0, %2}
12745 shr{l}\t{%b2, %k0|%k0, %b2}"
12746 [(set_attr "type" "ishift")
12747 (set_attr "mode" "SI")])
12749 ;; This pattern can't accept a variable shift count, since shifts by
12750 ;; zero don't affect the flags. We assume that shifts by constant
12751 ;; zero are optimized away.
12752 (define_insn "*lshrsi3_one_bit_cmp"
12753 [(set (reg FLAGS_REG)
12755 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12756 (match_operand:QI 2 "const1_operand" ""))
12758 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12759 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12760 "(TARGET_SHIFT1 || optimize_size)
12761 && ix86_match_ccmode (insn, CCGOCmode)
12762 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12764 [(set_attr "type" "ishift")
12765 (set (attr "length")
12766 (if_then_else (match_operand:SI 0 "register_operand" "")
12768 (const_string "*")))])
12770 (define_insn "*lshrsi3_one_bit_cconly"
12771 [(set (reg FLAGS_REG)
12773 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12774 (match_operand:QI 2 "const1_operand" ""))
12776 (clobber (match_scratch:SI 0 "=r"))]
12777 "(TARGET_SHIFT1 || optimize_size)
12778 && ix86_match_ccmode (insn, CCGOCmode)
12779 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12781 [(set_attr "type" "ishift")
12782 (set_attr "length" "2")])
12784 (define_insn "*lshrsi3_cmp_one_bit_zext"
12785 [(set (reg FLAGS_REG)
12787 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12788 (match_operand:QI 2 "const1_operand" ""))
12790 (set (match_operand:DI 0 "register_operand" "=r")
12791 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12793 && (TARGET_SHIFT1 || optimize_size)
12794 && ix86_match_ccmode (insn, CCGOCmode)
12795 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12797 [(set_attr "type" "ishift")
12798 (set_attr "length" "2")])
12800 ;; This pattern can't accept a variable shift count, since shifts by
12801 ;; zero don't affect the flags. We assume that shifts by constant
12802 ;; zero are optimized away.
12803 (define_insn "*lshrsi3_cmp"
12804 [(set (reg FLAGS_REG)
12806 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12807 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12809 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12810 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12811 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12812 && ix86_match_ccmode (insn, CCGOCmode)
12813 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12814 "shr{l}\t{%2, %0|%0, %2}"
12815 [(set_attr "type" "ishift")
12816 (set_attr "mode" "SI")])
12818 (define_insn "*lshrsi3_cconly"
12819 [(set (reg FLAGS_REG)
12821 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12822 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12824 (clobber (match_scratch:SI 0 "=r"))]
12825 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12826 && ix86_match_ccmode (insn, CCGOCmode)
12827 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12828 "shr{l}\t{%2, %0|%0, %2}"
12829 [(set_attr "type" "ishift")
12830 (set_attr "mode" "SI")])
12832 (define_insn "*lshrsi3_cmp_zext"
12833 [(set (reg FLAGS_REG)
12835 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12836 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12838 (set (match_operand:DI 0 "register_operand" "=r")
12839 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12841 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12842 && ix86_match_ccmode (insn, CCGOCmode)
12843 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12844 "shr{l}\t{%2, %k0|%k0, %2}"
12845 [(set_attr "type" "ishift")
12846 (set_attr "mode" "SI")])
12848 (define_expand "lshrhi3"
12849 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12850 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12851 (match_operand:QI 2 "nonmemory_operand" "")))
12852 (clobber (reg:CC FLAGS_REG))]
12853 "TARGET_HIMODE_MATH"
12854 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12856 (define_insn "*lshrhi3_1_one_bit"
12857 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12858 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12859 (match_operand:QI 2 "const1_operand" "")))
12860 (clobber (reg:CC FLAGS_REG))]
12861 "(TARGET_SHIFT1 || optimize_size)
12862 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12864 [(set_attr "type" "ishift")
12865 (set (attr "length")
12866 (if_then_else (match_operand 0 "register_operand" "")
12868 (const_string "*")))])
12870 (define_insn "*lshrhi3_1"
12871 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12872 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12873 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12874 (clobber (reg:CC FLAGS_REG))]
12875 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12877 shr{w}\t{%2, %0|%0, %2}
12878 shr{w}\t{%b2, %0|%0, %b2}"
12879 [(set_attr "type" "ishift")
12880 (set_attr "mode" "HI")])
12882 ;; This pattern can't accept a variable shift count, since shifts by
12883 ;; zero don't affect the flags. We assume that shifts by constant
12884 ;; zero are optimized away.
12885 (define_insn "*lshrhi3_one_bit_cmp"
12886 [(set (reg FLAGS_REG)
12888 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12889 (match_operand:QI 2 "const1_operand" ""))
12891 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12892 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12893 "(TARGET_SHIFT1 || optimize_size)
12894 && ix86_match_ccmode (insn, CCGOCmode)
12895 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12897 [(set_attr "type" "ishift")
12898 (set (attr "length")
12899 (if_then_else (match_operand:SI 0 "register_operand" "")
12901 (const_string "*")))])
12903 (define_insn "*lshrhi3_one_bit_cconly"
12904 [(set (reg FLAGS_REG)
12906 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12907 (match_operand:QI 2 "const1_operand" ""))
12909 (clobber (match_scratch:HI 0 "=r"))]
12910 "(TARGET_SHIFT1 || optimize_size)
12911 && ix86_match_ccmode (insn, CCGOCmode)
12912 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12914 [(set_attr "type" "ishift")
12915 (set_attr "length" "2")])
12917 ;; This pattern can't accept a variable shift count, since shifts by
12918 ;; zero don't affect the flags. We assume that shifts by constant
12919 ;; zero are optimized away.
12920 (define_insn "*lshrhi3_cmp"
12921 [(set (reg FLAGS_REG)
12923 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12924 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12926 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12927 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12928 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12929 && ix86_match_ccmode (insn, CCGOCmode)
12930 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12931 "shr{w}\t{%2, %0|%0, %2}"
12932 [(set_attr "type" "ishift")
12933 (set_attr "mode" "HI")])
12935 (define_insn "*lshrhi3_cconly"
12936 [(set (reg FLAGS_REG)
12938 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12939 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12941 (clobber (match_scratch:HI 0 "=r"))]
12942 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12943 && ix86_match_ccmode (insn, CCGOCmode)
12944 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12945 "shr{w}\t{%2, %0|%0, %2}"
12946 [(set_attr "type" "ishift")
12947 (set_attr "mode" "HI")])
12949 (define_expand "lshrqi3"
12950 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12951 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12952 (match_operand:QI 2 "nonmemory_operand" "")))
12953 (clobber (reg:CC FLAGS_REG))]
12954 "TARGET_QIMODE_MATH"
12955 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12957 (define_insn "*lshrqi3_1_one_bit"
12958 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12959 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12960 (match_operand:QI 2 "const1_operand" "")))
12961 (clobber (reg:CC FLAGS_REG))]
12962 "(TARGET_SHIFT1 || optimize_size)
12963 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12965 [(set_attr "type" "ishift")
12966 (set (attr "length")
12967 (if_then_else (match_operand 0 "register_operand" "")
12969 (const_string "*")))])
12971 (define_insn "*lshrqi3_1_one_bit_slp"
12972 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12973 (lshiftrt:QI (match_dup 0)
12974 (match_operand:QI 1 "const1_operand" "")))
12975 (clobber (reg:CC FLAGS_REG))]
12976 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12977 && (TARGET_SHIFT1 || optimize_size)"
12979 [(set_attr "type" "ishift1")
12980 (set (attr "length")
12981 (if_then_else (match_operand 0 "register_operand" "")
12983 (const_string "*")))])
12985 (define_insn "*lshrqi3_1"
12986 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12987 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12988 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12989 (clobber (reg:CC FLAGS_REG))]
12990 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12992 shr{b}\t{%2, %0|%0, %2}
12993 shr{b}\t{%b2, %0|%0, %b2}"
12994 [(set_attr "type" "ishift")
12995 (set_attr "mode" "QI")])
12997 (define_insn "*lshrqi3_1_slp"
12998 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12999 (lshiftrt:QI (match_dup 0)
13000 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13001 (clobber (reg:CC FLAGS_REG))]
13002 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13003 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13005 shr{b}\t{%1, %0|%0, %1}
13006 shr{b}\t{%b1, %0|%0, %b1}"
13007 [(set_attr "type" "ishift1")
13008 (set_attr "mode" "QI")])
13010 ;; This pattern can't accept a variable shift count, since shifts by
13011 ;; zero don't affect the flags. We assume that shifts by constant
13012 ;; zero are optimized away.
13013 (define_insn "*lshrqi2_one_bit_cmp"
13014 [(set (reg FLAGS_REG)
13016 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13017 (match_operand:QI 2 "const1_operand" ""))
13019 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13020 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13021 "(TARGET_SHIFT1 || optimize_size)
13022 && ix86_match_ccmode (insn, CCGOCmode)
13023 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13025 [(set_attr "type" "ishift")
13026 (set (attr "length")
13027 (if_then_else (match_operand:SI 0 "register_operand" "")
13029 (const_string "*")))])
13031 (define_insn "*lshrqi2_one_bit_cconly"
13032 [(set (reg FLAGS_REG)
13034 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13035 (match_operand:QI 2 "const1_operand" ""))
13037 (clobber (match_scratch:QI 0 "=q"))]
13038 "(TARGET_SHIFT1 || optimize_size)
13039 && ix86_match_ccmode (insn, CCGOCmode)
13040 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13042 [(set_attr "type" "ishift")
13043 (set_attr "length" "2")])
13045 ;; This pattern can't accept a variable shift count, since shifts by
13046 ;; zero don't affect the flags. We assume that shifts by constant
13047 ;; zero are optimized away.
13048 (define_insn "*lshrqi2_cmp"
13049 [(set (reg FLAGS_REG)
13051 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13052 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13054 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13055 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13056 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13057 && ix86_match_ccmode (insn, CCGOCmode)
13058 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13059 "shr{b}\t{%2, %0|%0, %2}"
13060 [(set_attr "type" "ishift")
13061 (set_attr "mode" "QI")])
13063 (define_insn "*lshrqi2_cconly"
13064 [(set (reg FLAGS_REG)
13066 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13067 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13069 (clobber (match_scratch:QI 0 "=q"))]
13070 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13071 && ix86_match_ccmode (insn, CCGOCmode)
13072 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13073 "shr{b}\t{%2, %0|%0, %2}"
13074 [(set_attr "type" "ishift")
13075 (set_attr "mode" "QI")])
13077 ;; Rotate instructions
13079 (define_expand "rotldi3"
13080 [(set (match_operand:DI 0 "shiftdi_operand" "")
13081 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13082 (match_operand:QI 2 "nonmemory_operand" "")))
13083 (clobber (reg:CC FLAGS_REG))]
13088 ix86_expand_binary_operator (ROTATE, DImode, operands);
13091 if (!const_1_to_31_operand (operands[2], VOIDmode))
13093 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13097 ;; Implement rotation using two double-precision shift instructions
13098 ;; and a scratch register.
13099 (define_insn_and_split "ix86_rotldi3"
13100 [(set (match_operand:DI 0 "register_operand" "=r")
13101 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13102 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13103 (clobber (reg:CC FLAGS_REG))
13104 (clobber (match_scratch:SI 3 "=&r"))]
13107 "&& reload_completed"
13108 [(set (match_dup 3) (match_dup 4))
13110 [(set (match_dup 4)
13111 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13112 (lshiftrt:SI (match_dup 5)
13113 (minus:QI (const_int 32) (match_dup 2)))))
13114 (clobber (reg:CC FLAGS_REG))])
13116 [(set (match_dup 5)
13117 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13118 (lshiftrt:SI (match_dup 3)
13119 (minus:QI (const_int 32) (match_dup 2)))))
13120 (clobber (reg:CC FLAGS_REG))])]
13121 "split_di (operands, 1, operands + 4, operands + 5);")
13123 (define_insn "*rotlsi3_1_one_bit_rex64"
13124 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13125 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13126 (match_operand:QI 2 "const1_operand" "")))
13127 (clobber (reg:CC FLAGS_REG))]
13129 && (TARGET_SHIFT1 || optimize_size)
13130 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13132 [(set_attr "type" "rotate")
13133 (set (attr "length")
13134 (if_then_else (match_operand:DI 0 "register_operand" "")
13136 (const_string "*")))])
13138 (define_insn "*rotldi3_1_rex64"
13139 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13140 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13141 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13142 (clobber (reg:CC FLAGS_REG))]
13143 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13145 rol{q}\t{%2, %0|%0, %2}
13146 rol{q}\t{%b2, %0|%0, %b2}"
13147 [(set_attr "type" "rotate")
13148 (set_attr "mode" "DI")])
13150 (define_expand "rotlsi3"
13151 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13152 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13153 (match_operand:QI 2 "nonmemory_operand" "")))
13154 (clobber (reg:CC FLAGS_REG))]
13156 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13158 (define_insn "*rotlsi3_1_one_bit"
13159 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13160 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13161 (match_operand:QI 2 "const1_operand" "")))
13162 (clobber (reg:CC FLAGS_REG))]
13163 "(TARGET_SHIFT1 || optimize_size)
13164 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13166 [(set_attr "type" "rotate")
13167 (set (attr "length")
13168 (if_then_else (match_operand:SI 0 "register_operand" "")
13170 (const_string "*")))])
13172 (define_insn "*rotlsi3_1_one_bit_zext"
13173 [(set (match_operand:DI 0 "register_operand" "=r")
13175 (rotate:SI (match_operand:SI 1 "register_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, SImode, operands)"
13182 [(set_attr "type" "rotate")
13183 (set_attr "length" "2")])
13185 (define_insn "*rotlsi3_1"
13186 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13187 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13188 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13189 (clobber (reg:CC FLAGS_REG))]
13190 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13192 rol{l}\t{%2, %0|%0, %2}
13193 rol{l}\t{%b2, %0|%0, %b2}"
13194 [(set_attr "type" "rotate")
13195 (set_attr "mode" "SI")])
13197 (define_insn "*rotlsi3_1_zext"
13198 [(set (match_operand:DI 0 "register_operand" "=r,r")
13200 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13201 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13202 (clobber (reg:CC FLAGS_REG))]
13203 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13205 rol{l}\t{%2, %k0|%k0, %2}
13206 rol{l}\t{%b2, %k0|%k0, %b2}"
13207 [(set_attr "type" "rotate")
13208 (set_attr "mode" "SI")])
13210 (define_expand "rotlhi3"
13211 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13212 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13213 (match_operand:QI 2 "nonmemory_operand" "")))
13214 (clobber (reg:CC FLAGS_REG))]
13215 "TARGET_HIMODE_MATH"
13216 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13218 (define_insn "*rotlhi3_1_one_bit"
13219 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13220 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13221 (match_operand:QI 2 "const1_operand" "")))
13222 (clobber (reg:CC FLAGS_REG))]
13223 "(TARGET_SHIFT1 || optimize_size)
13224 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13226 [(set_attr "type" "rotate")
13227 (set (attr "length")
13228 (if_then_else (match_operand 0 "register_operand" "")
13230 (const_string "*")))])
13232 (define_insn "*rotlhi3_1"
13233 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13234 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13235 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13236 (clobber (reg:CC FLAGS_REG))]
13237 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13239 rol{w}\t{%2, %0|%0, %2}
13240 rol{w}\t{%b2, %0|%0, %b2}"
13241 [(set_attr "type" "rotate")
13242 (set_attr "mode" "HI")])
13245 [(set (match_operand:HI 0 "register_operand" "")
13246 (rotate:HI (match_dup 0) (const_int 8)))
13247 (clobber (reg:CC FLAGS_REG))]
13249 [(parallel [(set (strict_low_part (match_dup 0))
13250 (bswap:HI (match_dup 0)))
13251 (clobber (reg:CC FLAGS_REG))])]
13254 (define_expand "rotlqi3"
13255 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13256 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13257 (match_operand:QI 2 "nonmemory_operand" "")))
13258 (clobber (reg:CC FLAGS_REG))]
13259 "TARGET_QIMODE_MATH"
13260 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13262 (define_insn "*rotlqi3_1_one_bit_slp"
13263 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13264 (rotate:QI (match_dup 0)
13265 (match_operand:QI 1 "const1_operand" "")))
13266 (clobber (reg:CC FLAGS_REG))]
13267 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13268 && (TARGET_SHIFT1 || optimize_size)"
13270 [(set_attr "type" "rotate1")
13271 (set (attr "length")
13272 (if_then_else (match_operand 0 "register_operand" "")
13274 (const_string "*")))])
13276 (define_insn "*rotlqi3_1_one_bit"
13277 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13278 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13279 (match_operand:QI 2 "const1_operand" "")))
13280 (clobber (reg:CC FLAGS_REG))]
13281 "(TARGET_SHIFT1 || optimize_size)
13282 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13284 [(set_attr "type" "rotate")
13285 (set (attr "length")
13286 (if_then_else (match_operand 0 "register_operand" "")
13288 (const_string "*")))])
13290 (define_insn "*rotlqi3_1_slp"
13291 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13292 (rotate:QI (match_dup 0)
13293 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13294 (clobber (reg:CC FLAGS_REG))]
13295 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13296 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13298 rol{b}\t{%1, %0|%0, %1}
13299 rol{b}\t{%b1, %0|%0, %b1}"
13300 [(set_attr "type" "rotate1")
13301 (set_attr "mode" "QI")])
13303 (define_insn "*rotlqi3_1"
13304 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13305 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13306 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13307 (clobber (reg:CC FLAGS_REG))]
13308 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13310 rol{b}\t{%2, %0|%0, %2}
13311 rol{b}\t{%b2, %0|%0, %b2}"
13312 [(set_attr "type" "rotate")
13313 (set_attr "mode" "QI")])
13315 (define_expand "rotrdi3"
13316 [(set (match_operand:DI 0 "shiftdi_operand" "")
13317 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13318 (match_operand:QI 2 "nonmemory_operand" "")))
13319 (clobber (reg:CC FLAGS_REG))]
13324 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13327 if (!const_1_to_31_operand (operands[2], VOIDmode))
13329 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13333 ;; Implement rotation using two double-precision shift instructions
13334 ;; and a scratch register.
13335 (define_insn_and_split "ix86_rotrdi3"
13336 [(set (match_operand:DI 0 "register_operand" "=r")
13337 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13338 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13339 (clobber (reg:CC FLAGS_REG))
13340 (clobber (match_scratch:SI 3 "=&r"))]
13343 "&& reload_completed"
13344 [(set (match_dup 3) (match_dup 4))
13346 [(set (match_dup 4)
13347 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13348 (ashift:SI (match_dup 5)
13349 (minus:QI (const_int 32) (match_dup 2)))))
13350 (clobber (reg:CC FLAGS_REG))])
13352 [(set (match_dup 5)
13353 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13354 (ashift:SI (match_dup 3)
13355 (minus:QI (const_int 32) (match_dup 2)))))
13356 (clobber (reg:CC FLAGS_REG))])]
13357 "split_di (operands, 1, operands + 4, operands + 5);")
13359 (define_insn "*rotrdi3_1_one_bit_rex64"
13360 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13361 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13362 (match_operand:QI 2 "const1_operand" "")))
13363 (clobber (reg:CC FLAGS_REG))]
13365 && (TARGET_SHIFT1 || optimize_size)
13366 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13368 [(set_attr "type" "rotate")
13369 (set (attr "length")
13370 (if_then_else (match_operand:DI 0 "register_operand" "")
13372 (const_string "*")))])
13374 (define_insn "*rotrdi3_1_rex64"
13375 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13376 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13377 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13378 (clobber (reg:CC FLAGS_REG))]
13379 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13381 ror{q}\t{%2, %0|%0, %2}
13382 ror{q}\t{%b2, %0|%0, %b2}"
13383 [(set_attr "type" "rotate")
13384 (set_attr "mode" "DI")])
13386 (define_expand "rotrsi3"
13387 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13388 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13389 (match_operand:QI 2 "nonmemory_operand" "")))
13390 (clobber (reg:CC FLAGS_REG))]
13392 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13394 (define_insn "*rotrsi3_1_one_bit"
13395 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13396 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13397 (match_operand:QI 2 "const1_operand" "")))
13398 (clobber (reg:CC FLAGS_REG))]
13399 "(TARGET_SHIFT1 || optimize_size)
13400 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13402 [(set_attr "type" "rotate")
13403 (set (attr "length")
13404 (if_then_else (match_operand:SI 0 "register_operand" "")
13406 (const_string "*")))])
13408 (define_insn "*rotrsi3_1_one_bit_zext"
13409 [(set (match_operand:DI 0 "register_operand" "=r")
13411 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13412 (match_operand:QI 2 "const1_operand" ""))))
13413 (clobber (reg:CC FLAGS_REG))]
13415 && (TARGET_SHIFT1 || optimize_size)
13416 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13418 [(set_attr "type" "rotate")
13419 (set (attr "length")
13420 (if_then_else (match_operand:SI 0 "register_operand" "")
13422 (const_string "*")))])
13424 (define_insn "*rotrsi3_1"
13425 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13426 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13427 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13428 (clobber (reg:CC FLAGS_REG))]
13429 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13431 ror{l}\t{%2, %0|%0, %2}
13432 ror{l}\t{%b2, %0|%0, %b2}"
13433 [(set_attr "type" "rotate")
13434 (set_attr "mode" "SI")])
13436 (define_insn "*rotrsi3_1_zext"
13437 [(set (match_operand:DI 0 "register_operand" "=r,r")
13439 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13440 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13441 (clobber (reg:CC FLAGS_REG))]
13442 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13444 ror{l}\t{%2, %k0|%k0, %2}
13445 ror{l}\t{%b2, %k0|%k0, %b2}"
13446 [(set_attr "type" "rotate")
13447 (set_attr "mode" "SI")])
13449 (define_expand "rotrhi3"
13450 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13451 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13452 (match_operand:QI 2 "nonmemory_operand" "")))
13453 (clobber (reg:CC FLAGS_REG))]
13454 "TARGET_HIMODE_MATH"
13455 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13457 (define_insn "*rotrhi3_one_bit"
13458 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13459 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13460 (match_operand:QI 2 "const1_operand" "")))
13461 (clobber (reg:CC FLAGS_REG))]
13462 "(TARGET_SHIFT1 || optimize_size)
13463 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13465 [(set_attr "type" "rotate")
13466 (set (attr "length")
13467 (if_then_else (match_operand 0 "register_operand" "")
13469 (const_string "*")))])
13471 (define_insn "*rotrhi3_1"
13472 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13473 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13474 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13475 (clobber (reg:CC FLAGS_REG))]
13476 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13478 ror{w}\t{%2, %0|%0, %2}
13479 ror{w}\t{%b2, %0|%0, %b2}"
13480 [(set_attr "type" "rotate")
13481 (set_attr "mode" "HI")])
13484 [(set (match_operand:HI 0 "register_operand" "")
13485 (rotatert:HI (match_dup 0) (const_int 8)))
13486 (clobber (reg:CC FLAGS_REG))]
13488 [(parallel [(set (strict_low_part (match_dup 0))
13489 (bswap:HI (match_dup 0)))
13490 (clobber (reg:CC FLAGS_REG))])]
13493 (define_expand "rotrqi3"
13494 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13495 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13496 (match_operand:QI 2 "nonmemory_operand" "")))
13497 (clobber (reg:CC FLAGS_REG))]
13498 "TARGET_QIMODE_MATH"
13499 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13501 (define_insn "*rotrqi3_1_one_bit"
13502 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13503 (rotatert:QI (match_operand:QI 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, QImode, 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 "*rotrqi3_1_one_bit_slp"
13516 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13517 (rotatert:QI (match_dup 0)
13518 (match_operand:QI 1 "const1_operand" "")))
13519 (clobber (reg:CC FLAGS_REG))]
13520 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13521 && (TARGET_SHIFT1 || optimize_size)"
13523 [(set_attr "type" "rotate1")
13524 (set (attr "length")
13525 (if_then_else (match_operand 0 "register_operand" "")
13527 (const_string "*")))])
13529 (define_insn "*rotrqi3_1"
13530 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13531 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13532 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13533 (clobber (reg:CC FLAGS_REG))]
13534 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13536 ror{b}\t{%2, %0|%0, %2}
13537 ror{b}\t{%b2, %0|%0, %b2}"
13538 [(set_attr "type" "rotate")
13539 (set_attr "mode" "QI")])
13541 (define_insn "*rotrqi3_1_slp"
13542 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13543 (rotatert:QI (match_dup 0)
13544 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13545 (clobber (reg:CC FLAGS_REG))]
13546 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13547 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13549 ror{b}\t{%1, %0|%0, %1}
13550 ror{b}\t{%b1, %0|%0, %b1}"
13551 [(set_attr "type" "rotate1")
13552 (set_attr "mode" "QI")])
13554 ;; Bit set / bit test instructions
13556 (define_expand "extv"
13557 [(set (match_operand:SI 0 "register_operand" "")
13558 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13559 (match_operand:SI 2 "const8_operand" "")
13560 (match_operand:SI 3 "const8_operand" "")))]
13563 /* Handle extractions from %ah et al. */
13564 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13567 /* From mips.md: extract_bit_field doesn't verify that our source
13568 matches the predicate, so check it again here. */
13569 if (! ext_register_operand (operands[1], VOIDmode))
13573 (define_expand "extzv"
13574 [(set (match_operand:SI 0 "register_operand" "")
13575 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13576 (match_operand:SI 2 "const8_operand" "")
13577 (match_operand:SI 3 "const8_operand" "")))]
13580 /* Handle extractions from %ah et al. */
13581 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13584 /* From mips.md: extract_bit_field doesn't verify that our source
13585 matches the predicate, so check it again here. */
13586 if (! ext_register_operand (operands[1], VOIDmode))
13590 (define_expand "insv"
13591 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13592 (match_operand 1 "const8_operand" "")
13593 (match_operand 2 "const8_operand" ""))
13594 (match_operand 3 "register_operand" ""))]
13597 /* Handle insertions to %ah et al. */
13598 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13601 /* From mips.md: insert_bit_field doesn't verify that our source
13602 matches the predicate, so check it again here. */
13603 if (! ext_register_operand (operands[0], VOIDmode))
13607 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13609 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13614 ;; %%% bts, btr, btc, bt.
13615 ;; In general these instructions are *slow* when applied to memory,
13616 ;; since they enforce atomic operation. When applied to registers,
13617 ;; it depends on the cpu implementation. They're never faster than
13618 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13619 ;; no point. But in 64-bit, we can't hold the relevant immediates
13620 ;; within the instruction itself, so operating on bits in the high
13621 ;; 32-bits of a register becomes easier.
13623 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13624 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13625 ;; negdf respectively, so they can never be disabled entirely.
13627 (define_insn "*btsq"
13628 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13630 (match_operand:DI 1 "const_0_to_63_operand" ""))
13632 (clobber (reg:CC FLAGS_REG))]
13633 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13635 [(set_attr "type" "alu1")])
13637 (define_insn "*btrq"
13638 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13640 (match_operand:DI 1 "const_0_to_63_operand" ""))
13642 (clobber (reg:CC FLAGS_REG))]
13643 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13645 [(set_attr "type" "alu1")])
13647 (define_insn "*btcq"
13648 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13650 (match_operand:DI 1 "const_0_to_63_operand" ""))
13651 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13652 (clobber (reg:CC FLAGS_REG))]
13653 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13655 [(set_attr "type" "alu1")])
13657 ;; Allow Nocona to avoid these instructions if a register is available.
13660 [(match_scratch:DI 2 "r")
13661 (parallel [(set (zero_extract:DI
13662 (match_operand:DI 0 "register_operand" "")
13664 (match_operand:DI 1 "const_0_to_63_operand" ""))
13666 (clobber (reg:CC FLAGS_REG))])]
13667 "TARGET_64BIT && !TARGET_USE_BT"
13670 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13673 if (HOST_BITS_PER_WIDE_INT >= 64)
13674 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13675 else if (i < HOST_BITS_PER_WIDE_INT)
13676 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13678 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13680 op1 = immed_double_const (lo, hi, DImode);
13683 emit_move_insn (operands[2], op1);
13687 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13692 [(match_scratch:DI 2 "r")
13693 (parallel [(set (zero_extract:DI
13694 (match_operand:DI 0 "register_operand" "")
13696 (match_operand:DI 1 "const_0_to_63_operand" ""))
13698 (clobber (reg:CC FLAGS_REG))])]
13699 "TARGET_64BIT && !TARGET_USE_BT"
13702 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13705 if (HOST_BITS_PER_WIDE_INT >= 64)
13706 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13707 else if (i < HOST_BITS_PER_WIDE_INT)
13708 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13710 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13712 op1 = immed_double_const (~lo, ~hi, DImode);
13715 emit_move_insn (operands[2], op1);
13719 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13724 [(match_scratch:DI 2 "r")
13725 (parallel [(set (zero_extract:DI
13726 (match_operand:DI 0 "register_operand" "")
13728 (match_operand:DI 1 "const_0_to_63_operand" ""))
13729 (not:DI (zero_extract:DI
13730 (match_dup 0) (const_int 1) (match_dup 1))))
13731 (clobber (reg:CC FLAGS_REG))])]
13732 "TARGET_64BIT && !TARGET_USE_BT"
13735 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13738 if (HOST_BITS_PER_WIDE_INT >= 64)
13739 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13740 else if (i < HOST_BITS_PER_WIDE_INT)
13741 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13743 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13745 op1 = immed_double_const (lo, hi, DImode);
13748 emit_move_insn (operands[2], op1);
13752 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13756 ;; Store-flag instructions.
13758 ;; For all sCOND expanders, also expand the compare or test insn that
13759 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13761 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13762 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13763 ;; way, which can later delete the movzx if only QImode is needed.
13765 (define_expand "seq"
13766 [(set (match_operand:QI 0 "register_operand" "")
13767 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13769 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13771 (define_expand "sne"
13772 [(set (match_operand:QI 0 "register_operand" "")
13773 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13775 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13777 (define_expand "sgt"
13778 [(set (match_operand:QI 0 "register_operand" "")
13779 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13781 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13783 (define_expand "sgtu"
13784 [(set (match_operand:QI 0 "register_operand" "")
13785 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13787 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13789 (define_expand "slt"
13790 [(set (match_operand:QI 0 "register_operand" "")
13791 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13793 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13795 (define_expand "sltu"
13796 [(set (match_operand:QI 0 "register_operand" "")
13797 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13799 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13801 (define_expand "sge"
13802 [(set (match_operand:QI 0 "register_operand" "")
13803 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13805 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13807 (define_expand "sgeu"
13808 [(set (match_operand:QI 0 "register_operand" "")
13809 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13811 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13813 (define_expand "sle"
13814 [(set (match_operand:QI 0 "register_operand" "")
13815 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13817 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13819 (define_expand "sleu"
13820 [(set (match_operand:QI 0 "register_operand" "")
13821 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13823 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13825 (define_expand "sunordered"
13826 [(set (match_operand:QI 0 "register_operand" "")
13827 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13828 "TARGET_80387 || TARGET_SSE"
13829 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13831 (define_expand "sordered"
13832 [(set (match_operand:QI 0 "register_operand" "")
13833 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13835 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13837 (define_expand "suneq"
13838 [(set (match_operand:QI 0 "register_operand" "")
13839 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13840 "TARGET_80387 || TARGET_SSE"
13841 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13843 (define_expand "sunge"
13844 [(set (match_operand:QI 0 "register_operand" "")
13845 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13846 "TARGET_80387 || TARGET_SSE"
13847 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13849 (define_expand "sungt"
13850 [(set (match_operand:QI 0 "register_operand" "")
13851 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13852 "TARGET_80387 || TARGET_SSE"
13853 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13855 (define_expand "sunle"
13856 [(set (match_operand:QI 0 "register_operand" "")
13857 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13858 "TARGET_80387 || TARGET_SSE"
13859 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13861 (define_expand "sunlt"
13862 [(set (match_operand:QI 0 "register_operand" "")
13863 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13864 "TARGET_80387 || TARGET_SSE"
13865 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13867 (define_expand "sltgt"
13868 [(set (match_operand:QI 0 "register_operand" "")
13869 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13870 "TARGET_80387 || TARGET_SSE"
13871 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13873 (define_insn "*setcc_1"
13874 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13875 (match_operator:QI 1 "ix86_comparison_operator"
13876 [(reg FLAGS_REG) (const_int 0)]))]
13879 [(set_attr "type" "setcc")
13880 (set_attr "mode" "QI")])
13882 (define_insn "*setcc_2"
13883 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13884 (match_operator:QI 1 "ix86_comparison_operator"
13885 [(reg FLAGS_REG) (const_int 0)]))]
13888 [(set_attr "type" "setcc")
13889 (set_attr "mode" "QI")])
13891 ;; In general it is not safe to assume too much about CCmode registers,
13892 ;; so simplify-rtx stops when it sees a second one. Under certain
13893 ;; conditions this is safe on x86, so help combine not create
13900 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13901 (ne:QI (match_operator 1 "ix86_comparison_operator"
13902 [(reg FLAGS_REG) (const_int 0)])
13905 [(set (match_dup 0) (match_dup 1))]
13907 PUT_MODE (operands[1], QImode);
13911 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13912 (ne:QI (match_operator 1 "ix86_comparison_operator"
13913 [(reg FLAGS_REG) (const_int 0)])
13916 [(set (match_dup 0) (match_dup 1))]
13918 PUT_MODE (operands[1], QImode);
13922 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13923 (eq:QI (match_operator 1 "ix86_comparison_operator"
13924 [(reg FLAGS_REG) (const_int 0)])
13927 [(set (match_dup 0) (match_dup 1))]
13929 rtx new_op1 = copy_rtx (operands[1]);
13930 operands[1] = new_op1;
13931 PUT_MODE (new_op1, QImode);
13932 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13933 GET_MODE (XEXP (new_op1, 0))));
13935 /* Make sure that (a) the CCmode we have for the flags is strong
13936 enough for the reversed compare or (b) we have a valid FP compare. */
13937 if (! ix86_comparison_operator (new_op1, VOIDmode))
13942 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13943 (eq:QI (match_operator 1 "ix86_comparison_operator"
13944 [(reg FLAGS_REG) (const_int 0)])
13947 [(set (match_dup 0) (match_dup 1))]
13949 rtx new_op1 = copy_rtx (operands[1]);
13950 operands[1] = new_op1;
13951 PUT_MODE (new_op1, QImode);
13952 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13953 GET_MODE (XEXP (new_op1, 0))));
13955 /* Make sure that (a) the CCmode we have for the flags is strong
13956 enough for the reversed compare or (b) we have a valid FP compare. */
13957 if (! ix86_comparison_operator (new_op1, VOIDmode))
13961 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13962 ;; subsequent logical operations are used to imitate conditional moves.
13963 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13966 (define_insn "*sse_setcc<mode>"
13967 [(set (match_operand:MODEF 0 "register_operand" "=x")
13968 (match_operator:MODEF 1 "sse_comparison_operator"
13969 [(match_operand:MODEF 2 "register_operand" "0")
13970 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13971 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13972 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13973 [(set_attr "type" "ssecmp")
13974 (set_attr "mode" "<MODE>")])
13976 (define_insn "*sse5_setcc<mode>"
13977 [(set (match_operand:MODEF 0 "register_operand" "=x")
13978 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13979 [(match_operand:MODEF 2 "register_operand" "x")
13980 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13982 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13983 [(set_attr "type" "sse4arg")
13984 (set_attr "mode" "<MODE>")])
13987 ;; Basic conditional jump instructions.
13988 ;; We ignore the overflow flag for signed branch instructions.
13990 ;; For all bCOND expanders, also expand the compare or test insn that
13991 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13993 (define_expand "beq"
13995 (if_then_else (match_dup 1)
13996 (label_ref (match_operand 0 "" ""))
13999 "ix86_expand_branch (EQ, operands[0]); DONE;")
14001 (define_expand "bne"
14003 (if_then_else (match_dup 1)
14004 (label_ref (match_operand 0 "" ""))
14007 "ix86_expand_branch (NE, operands[0]); DONE;")
14009 (define_expand "bgt"
14011 (if_then_else (match_dup 1)
14012 (label_ref (match_operand 0 "" ""))
14015 "ix86_expand_branch (GT, operands[0]); DONE;")
14017 (define_expand "bgtu"
14019 (if_then_else (match_dup 1)
14020 (label_ref (match_operand 0 "" ""))
14023 "ix86_expand_branch (GTU, operands[0]); DONE;")
14025 (define_expand "blt"
14027 (if_then_else (match_dup 1)
14028 (label_ref (match_operand 0 "" ""))
14031 "ix86_expand_branch (LT, operands[0]); DONE;")
14033 (define_expand "bltu"
14035 (if_then_else (match_dup 1)
14036 (label_ref (match_operand 0 "" ""))
14039 "ix86_expand_branch (LTU, operands[0]); DONE;")
14041 (define_expand "bge"
14043 (if_then_else (match_dup 1)
14044 (label_ref (match_operand 0 "" ""))
14047 "ix86_expand_branch (GE, operands[0]); DONE;")
14049 (define_expand "bgeu"
14051 (if_then_else (match_dup 1)
14052 (label_ref (match_operand 0 "" ""))
14055 "ix86_expand_branch (GEU, operands[0]); DONE;")
14057 (define_expand "ble"
14059 (if_then_else (match_dup 1)
14060 (label_ref (match_operand 0 "" ""))
14063 "ix86_expand_branch (LE, operands[0]); DONE;")
14065 (define_expand "bleu"
14067 (if_then_else (match_dup 1)
14068 (label_ref (match_operand 0 "" ""))
14071 "ix86_expand_branch (LEU, operands[0]); DONE;")
14073 (define_expand "bunordered"
14075 (if_then_else (match_dup 1)
14076 (label_ref (match_operand 0 "" ""))
14078 "TARGET_80387 || TARGET_SSE_MATH"
14079 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14081 (define_expand "bordered"
14083 (if_then_else (match_dup 1)
14084 (label_ref (match_operand 0 "" ""))
14086 "TARGET_80387 || TARGET_SSE_MATH"
14087 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14089 (define_expand "buneq"
14091 (if_then_else (match_dup 1)
14092 (label_ref (match_operand 0 "" ""))
14094 "TARGET_80387 || TARGET_SSE_MATH"
14095 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14097 (define_expand "bunge"
14099 (if_then_else (match_dup 1)
14100 (label_ref (match_operand 0 "" ""))
14102 "TARGET_80387 || TARGET_SSE_MATH"
14103 "ix86_expand_branch (UNGE, operands[0]); DONE;")
14105 (define_expand "bungt"
14107 (if_then_else (match_dup 1)
14108 (label_ref (match_operand 0 "" ""))
14110 "TARGET_80387 || TARGET_SSE_MATH"
14111 "ix86_expand_branch (UNGT, operands[0]); DONE;")
14113 (define_expand "bunle"
14115 (if_then_else (match_dup 1)
14116 (label_ref (match_operand 0 "" ""))
14118 "TARGET_80387 || TARGET_SSE_MATH"
14119 "ix86_expand_branch (UNLE, operands[0]); DONE;")
14121 (define_expand "bunlt"
14123 (if_then_else (match_dup 1)
14124 (label_ref (match_operand 0 "" ""))
14126 "TARGET_80387 || TARGET_SSE_MATH"
14127 "ix86_expand_branch (UNLT, operands[0]); DONE;")
14129 (define_expand "bltgt"
14131 (if_then_else (match_dup 1)
14132 (label_ref (match_operand 0 "" ""))
14134 "TARGET_80387 || TARGET_SSE_MATH"
14135 "ix86_expand_branch (LTGT, operands[0]); DONE;")
14137 (define_insn "*jcc_1"
14139 (if_then_else (match_operator 1 "ix86_comparison_operator"
14140 [(reg FLAGS_REG) (const_int 0)])
14141 (label_ref (match_operand 0 "" ""))
14145 [(set_attr "type" "ibr")
14146 (set_attr "modrm" "0")
14147 (set (attr "length")
14148 (if_then_else (and (ge (minus (match_dup 0) (pc))
14150 (lt (minus (match_dup 0) (pc))
14155 (define_insn "*jcc_2"
14157 (if_then_else (match_operator 1 "ix86_comparison_operator"
14158 [(reg FLAGS_REG) (const_int 0)])
14160 (label_ref (match_operand 0 "" ""))))]
14163 [(set_attr "type" "ibr")
14164 (set_attr "modrm" "0")
14165 (set (attr "length")
14166 (if_then_else (and (ge (minus (match_dup 0) (pc))
14168 (lt (minus (match_dup 0) (pc))
14173 ;; In general it is not safe to assume too much about CCmode registers,
14174 ;; so simplify-rtx stops when it sees a second one. Under certain
14175 ;; conditions this is safe on x86, so help combine not create
14183 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14184 [(reg FLAGS_REG) (const_int 0)])
14186 (label_ref (match_operand 1 "" ""))
14190 (if_then_else (match_dup 0)
14191 (label_ref (match_dup 1))
14194 PUT_MODE (operands[0], VOIDmode);
14199 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14200 [(reg FLAGS_REG) (const_int 0)])
14202 (label_ref (match_operand 1 "" ""))
14206 (if_then_else (match_dup 0)
14207 (label_ref (match_dup 1))
14210 rtx new_op0 = copy_rtx (operands[0]);
14211 operands[0] = new_op0;
14212 PUT_MODE (new_op0, VOIDmode);
14213 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14214 GET_MODE (XEXP (new_op0, 0))));
14216 /* Make sure that (a) the CCmode we have for the flags is strong
14217 enough for the reversed compare or (b) we have a valid FP compare. */
14218 if (! ix86_comparison_operator (new_op0, VOIDmode))
14222 ;; Define combination compare-and-branch fp compare instructions to use
14223 ;; during early optimization. Splitting the operation apart early makes
14224 ;; for bad code when we want to reverse the operation.
14226 (define_insn "*fp_jcc_1_mixed"
14228 (if_then_else (match_operator 0 "comparison_operator"
14229 [(match_operand 1 "register_operand" "f,x")
14230 (match_operand 2 "nonimmediate_operand" "f,xm")])
14231 (label_ref (match_operand 3 "" ""))
14233 (clobber (reg:CCFP FPSR_REG))
14234 (clobber (reg:CCFP FLAGS_REG))]
14235 "TARGET_MIX_SSE_I387
14236 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14237 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14238 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14241 (define_insn "*fp_jcc_1_sse"
14243 (if_then_else (match_operator 0 "comparison_operator"
14244 [(match_operand 1 "register_operand" "x")
14245 (match_operand 2 "nonimmediate_operand" "xm")])
14246 (label_ref (match_operand 3 "" ""))
14248 (clobber (reg:CCFP FPSR_REG))
14249 (clobber (reg:CCFP FLAGS_REG))]
14251 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14252 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14253 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14256 (define_insn "*fp_jcc_1_387"
14258 (if_then_else (match_operator 0 "comparison_operator"
14259 [(match_operand 1 "register_operand" "f")
14260 (match_operand 2 "register_operand" "f")])
14261 (label_ref (match_operand 3 "" ""))
14263 (clobber (reg:CCFP FPSR_REG))
14264 (clobber (reg:CCFP FLAGS_REG))]
14265 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14267 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14268 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14271 (define_insn "*fp_jcc_2_mixed"
14273 (if_then_else (match_operator 0 "comparison_operator"
14274 [(match_operand 1 "register_operand" "f,x")
14275 (match_operand 2 "nonimmediate_operand" "f,xm")])
14277 (label_ref (match_operand 3 "" ""))))
14278 (clobber (reg:CCFP FPSR_REG))
14279 (clobber (reg:CCFP FLAGS_REG))]
14280 "TARGET_MIX_SSE_I387
14281 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14282 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14283 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14286 (define_insn "*fp_jcc_2_sse"
14288 (if_then_else (match_operator 0 "comparison_operator"
14289 [(match_operand 1 "register_operand" "x")
14290 (match_operand 2 "nonimmediate_operand" "xm")])
14292 (label_ref (match_operand 3 "" ""))))
14293 (clobber (reg:CCFP FPSR_REG))
14294 (clobber (reg:CCFP FLAGS_REG))]
14296 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14297 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14298 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14301 (define_insn "*fp_jcc_2_387"
14303 (if_then_else (match_operator 0 "comparison_operator"
14304 [(match_operand 1 "register_operand" "f")
14305 (match_operand 2 "register_operand" "f")])
14307 (label_ref (match_operand 3 "" ""))))
14308 (clobber (reg:CCFP FPSR_REG))
14309 (clobber (reg:CCFP FLAGS_REG))]
14310 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14312 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14313 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14316 (define_insn "*fp_jcc_3_387"
14318 (if_then_else (match_operator 0 "comparison_operator"
14319 [(match_operand 1 "register_operand" "f")
14320 (match_operand 2 "nonimmediate_operand" "fm")])
14321 (label_ref (match_operand 3 "" ""))
14323 (clobber (reg:CCFP FPSR_REG))
14324 (clobber (reg:CCFP FLAGS_REG))
14325 (clobber (match_scratch:HI 4 "=a"))]
14327 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14328 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14329 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14330 && SELECT_CC_MODE (GET_CODE (operands[0]),
14331 operands[1], operands[2]) == CCFPmode
14332 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14335 (define_insn "*fp_jcc_4_387"
14337 (if_then_else (match_operator 0 "comparison_operator"
14338 [(match_operand 1 "register_operand" "f")
14339 (match_operand 2 "nonimmediate_operand" "fm")])
14341 (label_ref (match_operand 3 "" ""))))
14342 (clobber (reg:CCFP FPSR_REG))
14343 (clobber (reg:CCFP FLAGS_REG))
14344 (clobber (match_scratch:HI 4 "=a"))]
14346 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14347 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14348 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14349 && SELECT_CC_MODE (GET_CODE (operands[0]),
14350 operands[1], operands[2]) == CCFPmode
14351 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14354 (define_insn "*fp_jcc_5_387"
14356 (if_then_else (match_operator 0 "comparison_operator"
14357 [(match_operand 1 "register_operand" "f")
14358 (match_operand 2 "register_operand" "f")])
14359 (label_ref (match_operand 3 "" ""))
14361 (clobber (reg:CCFP FPSR_REG))
14362 (clobber (reg:CCFP FLAGS_REG))
14363 (clobber (match_scratch:HI 4 "=a"))]
14364 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14365 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14366 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14369 (define_insn "*fp_jcc_6_387"
14371 (if_then_else (match_operator 0 "comparison_operator"
14372 [(match_operand 1 "register_operand" "f")
14373 (match_operand 2 "register_operand" "f")])
14375 (label_ref (match_operand 3 "" ""))))
14376 (clobber (reg:CCFP FPSR_REG))
14377 (clobber (reg:CCFP FLAGS_REG))
14378 (clobber (match_scratch:HI 4 "=a"))]
14379 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14380 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14381 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14384 (define_insn "*fp_jcc_7_387"
14386 (if_then_else (match_operator 0 "comparison_operator"
14387 [(match_operand 1 "register_operand" "f")
14388 (match_operand 2 "const0_operand" "X")])
14389 (label_ref (match_operand 3 "" ""))
14391 (clobber (reg:CCFP FPSR_REG))
14392 (clobber (reg:CCFP FLAGS_REG))
14393 (clobber (match_scratch:HI 4 "=a"))]
14394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14395 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14396 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14397 && SELECT_CC_MODE (GET_CODE (operands[0]),
14398 operands[1], operands[2]) == CCFPmode
14399 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14402 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14403 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14404 ;; with a precedence over other operators and is always put in the first
14405 ;; place. Swap condition and operands to match ficom instruction.
14407 (define_insn "*fp_jcc_8<mode>_387"
14409 (if_then_else (match_operator 0 "comparison_operator"
14410 [(match_operator 1 "float_operator"
14411 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14412 (match_operand 3 "register_operand" "f,f")])
14413 (label_ref (match_operand 4 "" ""))
14415 (clobber (reg:CCFP FPSR_REG))
14416 (clobber (reg:CCFP FLAGS_REG))
14417 (clobber (match_scratch:HI 5 "=a,a"))]
14418 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14419 && TARGET_USE_<MODE>MODE_FIOP
14420 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14421 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14422 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14423 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14428 (if_then_else (match_operator 0 "comparison_operator"
14429 [(match_operand 1 "register_operand" "")
14430 (match_operand 2 "nonimmediate_operand" "")])
14431 (match_operand 3 "" "")
14432 (match_operand 4 "" "")))
14433 (clobber (reg:CCFP FPSR_REG))
14434 (clobber (reg:CCFP FLAGS_REG))]
14438 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14439 operands[3], operands[4], NULL_RTX, NULL_RTX);
14445 (if_then_else (match_operator 0 "comparison_operator"
14446 [(match_operand 1 "register_operand" "")
14447 (match_operand 2 "general_operand" "")])
14448 (match_operand 3 "" "")
14449 (match_operand 4 "" "")))
14450 (clobber (reg:CCFP FPSR_REG))
14451 (clobber (reg:CCFP FLAGS_REG))
14452 (clobber (match_scratch:HI 5 "=a"))]
14456 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14457 operands[3], operands[4], operands[5], NULL_RTX);
14463 (if_then_else (match_operator 0 "comparison_operator"
14464 [(match_operator 1 "float_operator"
14465 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14466 (match_operand 3 "register_operand" "")])
14467 (match_operand 4 "" "")
14468 (match_operand 5 "" "")))
14469 (clobber (reg:CCFP FPSR_REG))
14470 (clobber (reg:CCFP FLAGS_REG))
14471 (clobber (match_scratch:HI 6 "=a"))]
14475 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14476 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14477 operands[3], operands[7],
14478 operands[4], operands[5], operands[6], NULL_RTX);
14482 ;; %%% Kill this when reload knows how to do it.
14485 (if_then_else (match_operator 0 "comparison_operator"
14486 [(match_operator 1 "float_operator"
14487 [(match_operand:X87MODEI12 2 "register_operand" "")])
14488 (match_operand 3 "register_operand" "")])
14489 (match_operand 4 "" "")
14490 (match_operand 5 "" "")))
14491 (clobber (reg:CCFP FPSR_REG))
14492 (clobber (reg:CCFP FLAGS_REG))
14493 (clobber (match_scratch:HI 6 "=a"))]
14497 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14498 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14499 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14500 operands[3], operands[7],
14501 operands[4], operands[5], operands[6], operands[2]);
14505 ;; Unconditional and other jump instructions
14507 (define_insn "jump"
14509 (label_ref (match_operand 0 "" "")))]
14512 [(set_attr "type" "ibr")
14513 (set (attr "length")
14514 (if_then_else (and (ge (minus (match_dup 0) (pc))
14516 (lt (minus (match_dup 0) (pc))
14520 (set_attr "modrm" "0")])
14522 (define_expand "indirect_jump"
14523 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14527 (define_insn "*indirect_jump"
14528 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14531 [(set_attr "type" "ibr")
14532 (set_attr "length_immediate" "0")])
14534 (define_insn "*indirect_jump_rtx64"
14535 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14538 [(set_attr "type" "ibr")
14539 (set_attr "length_immediate" "0")])
14541 (define_expand "tablejump"
14542 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14543 (use (label_ref (match_operand 1 "" "")))])]
14546 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14547 relative. Convert the relative address to an absolute address. */
14551 enum rtx_code code;
14553 /* We can't use @GOTOFF for text labels on VxWorks;
14554 see gotoff_operand. */
14555 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14559 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14561 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14565 op1 = pic_offset_table_rtx;
14570 op0 = pic_offset_table_rtx;
14574 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14579 (define_insn "*tablejump_1"
14580 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14581 (use (label_ref (match_operand 1 "" "")))]
14584 [(set_attr "type" "ibr")
14585 (set_attr "length_immediate" "0")])
14587 (define_insn "*tablejump_1_rtx64"
14588 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14589 (use (label_ref (match_operand 1 "" "")))]
14592 [(set_attr "type" "ibr")
14593 (set_attr "length_immediate" "0")])
14595 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14598 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14599 (set (match_operand:QI 1 "register_operand" "")
14600 (match_operator:QI 2 "ix86_comparison_operator"
14601 [(reg FLAGS_REG) (const_int 0)]))
14602 (set (match_operand 3 "q_regs_operand" "")
14603 (zero_extend (match_dup 1)))]
14604 "(peep2_reg_dead_p (3, operands[1])
14605 || operands_match_p (operands[1], operands[3]))
14606 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14607 [(set (match_dup 4) (match_dup 0))
14608 (set (strict_low_part (match_dup 5))
14611 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14612 operands[5] = gen_lowpart (QImode, operands[3]);
14613 ix86_expand_clear (operands[3]);
14616 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14619 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14620 (set (match_operand:QI 1 "register_operand" "")
14621 (match_operator:QI 2 "ix86_comparison_operator"
14622 [(reg FLAGS_REG) (const_int 0)]))
14623 (parallel [(set (match_operand 3 "q_regs_operand" "")
14624 (zero_extend (match_dup 1)))
14625 (clobber (reg:CC FLAGS_REG))])]
14626 "(peep2_reg_dead_p (3, operands[1])
14627 || operands_match_p (operands[1], operands[3]))
14628 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14629 [(set (match_dup 4) (match_dup 0))
14630 (set (strict_low_part (match_dup 5))
14633 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14634 operands[5] = gen_lowpart (QImode, operands[3]);
14635 ix86_expand_clear (operands[3]);
14638 ;; Call instructions.
14640 ;; The predicates normally associated with named expanders are not properly
14641 ;; checked for calls. This is a bug in the generic code, but it isn't that
14642 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14644 ;; Call subroutine returning no value.
14646 (define_expand "call_pop"
14647 [(parallel [(call (match_operand:QI 0 "" "")
14648 (match_operand:SI 1 "" ""))
14649 (set (reg:SI SP_REG)
14650 (plus:SI (reg:SI SP_REG)
14651 (match_operand:SI 3 "" "")))])]
14654 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14658 (define_insn "*call_pop_0"
14659 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14660 (match_operand:SI 1 "" ""))
14661 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14662 (match_operand:SI 2 "immediate_operand" "")))]
14665 if (SIBLING_CALL_P (insn))
14668 return "call\t%P0";
14670 [(set_attr "type" "call")])
14672 (define_insn "*call_pop_1"
14673 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14674 (match_operand:SI 1 "" ""))
14675 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14676 (match_operand:SI 2 "immediate_operand" "i")))]
14679 if (constant_call_address_operand (operands[0], Pmode))
14681 if (SIBLING_CALL_P (insn))
14684 return "call\t%P0";
14686 if (SIBLING_CALL_P (insn))
14689 return "call\t%A0";
14691 [(set_attr "type" "call")])
14693 (define_expand "call"
14694 [(call (match_operand:QI 0 "" "")
14695 (match_operand 1 "" ""))
14696 (use (match_operand 2 "" ""))]
14699 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14703 (define_expand "sibcall"
14704 [(call (match_operand:QI 0 "" "")
14705 (match_operand 1 "" ""))
14706 (use (match_operand 2 "" ""))]
14709 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14713 (define_insn "*call_0"
14714 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14715 (match_operand 1 "" ""))]
14718 if (SIBLING_CALL_P (insn))
14721 return "call\t%P0";
14723 [(set_attr "type" "call")])
14725 (define_insn "*call_1"
14726 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14727 (match_operand 1 "" ""))]
14728 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14730 if (constant_call_address_operand (operands[0], Pmode))
14731 return "call\t%P0";
14732 return "call\t%A0";
14734 [(set_attr "type" "call")])
14736 (define_insn "*sibcall_1"
14737 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14738 (match_operand 1 "" ""))]
14739 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14741 if (constant_call_address_operand (operands[0], Pmode))
14745 [(set_attr "type" "call")])
14747 (define_insn "*call_1_rex64"
14748 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14749 (match_operand 1 "" ""))]
14750 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14751 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14753 if (constant_call_address_operand (operands[0], Pmode))
14754 return "call\t%P0";
14755 return "call\t%A0";
14757 [(set_attr "type" "call")])
14759 (define_insn "*call_1_rex64_large"
14760 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14761 (match_operand 1 "" ""))]
14762 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14764 [(set_attr "type" "call")])
14766 (define_insn "*sibcall_1_rex64"
14767 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14768 (match_operand 1 "" ""))]
14769 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14771 [(set_attr "type" "call")])
14773 (define_insn "*sibcall_1_rex64_v"
14774 [(call (mem:QI (reg:DI R11_REG))
14775 (match_operand 0 "" ""))]
14776 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14778 [(set_attr "type" "call")])
14781 ;; Call subroutine, returning value in operand 0
14783 (define_expand "call_value_pop"
14784 [(parallel [(set (match_operand 0 "" "")
14785 (call (match_operand:QI 1 "" "")
14786 (match_operand:SI 2 "" "")))
14787 (set (reg:SI SP_REG)
14788 (plus:SI (reg:SI SP_REG)
14789 (match_operand:SI 4 "" "")))])]
14792 ix86_expand_call (operands[0], operands[1], operands[2],
14793 operands[3], operands[4], 0);
14797 (define_expand "call_value"
14798 [(set (match_operand 0 "" "")
14799 (call (match_operand:QI 1 "" "")
14800 (match_operand:SI 2 "" "")))
14801 (use (match_operand:SI 3 "" ""))]
14802 ;; Operand 2 not used on the i386.
14805 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14809 (define_expand "sibcall_value"
14810 [(set (match_operand 0 "" "")
14811 (call (match_operand:QI 1 "" "")
14812 (match_operand:SI 2 "" "")))
14813 (use (match_operand:SI 3 "" ""))]
14814 ;; Operand 2 not used on the i386.
14817 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14821 ;; Call subroutine returning any type.
14823 (define_expand "untyped_call"
14824 [(parallel [(call (match_operand 0 "" "")
14826 (match_operand 1 "" "")
14827 (match_operand 2 "" "")])]
14832 /* In order to give reg-stack an easier job in validating two
14833 coprocessor registers as containing a possible return value,
14834 simply pretend the untyped call returns a complex long double
14837 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14838 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14839 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14842 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14844 rtx set = XVECEXP (operands[2], 0, i);
14845 emit_move_insn (SET_DEST (set), SET_SRC (set));
14848 /* The optimizer does not know that the call sets the function value
14849 registers we stored in the result block. We avoid problems by
14850 claiming that all hard registers are used and clobbered at this
14852 emit_insn (gen_blockage ());
14857 ;; Prologue and epilogue instructions
14859 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14860 ;; all of memory. This blocks insns from being moved across this point.
14862 (define_insn "blockage"
14863 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14866 [(set_attr "length" "0")])
14868 ;; As USE insns aren't meaningful after reload, this is used instead
14869 ;; to prevent deleting instructions setting registers for PIC code
14870 (define_insn "prologue_use"
14871 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14874 [(set_attr "length" "0")])
14876 ;; Insn emitted into the body of a function to return from a function.
14877 ;; This is only done if the function's epilogue is known to be simple.
14878 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14880 (define_expand "return"
14882 "ix86_can_use_return_insn_p ()"
14884 if (current_function_pops_args)
14886 rtx popc = GEN_INT (current_function_pops_args);
14887 emit_jump_insn (gen_return_pop_internal (popc));
14892 (define_insn "return_internal"
14896 [(set_attr "length" "1")
14897 (set_attr "length_immediate" "0")
14898 (set_attr "modrm" "0")])
14900 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14901 ;; instruction Athlon and K8 have.
14903 (define_insn "return_internal_long"
14905 (unspec [(const_int 0)] UNSPEC_REP)]
14908 [(set_attr "length" "1")
14909 (set_attr "length_immediate" "0")
14910 (set_attr "prefix_rep" "1")
14911 (set_attr "modrm" "0")])
14913 (define_insn "return_pop_internal"
14915 (use (match_operand:SI 0 "const_int_operand" ""))]
14918 [(set_attr "length" "3")
14919 (set_attr "length_immediate" "2")
14920 (set_attr "modrm" "0")])
14922 (define_insn "return_indirect_internal"
14924 (use (match_operand:SI 0 "register_operand" "r"))]
14927 [(set_attr "type" "ibr")
14928 (set_attr "length_immediate" "0")])
14934 [(set_attr "length" "1")
14935 (set_attr "length_immediate" "0")
14936 (set_attr "modrm" "0")])
14938 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14939 ;; branch prediction penalty for the third jump in a 16-byte
14942 (define_insn "align"
14943 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14946 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14947 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14949 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14950 The align insn is used to avoid 3 jump instructions in the row to improve
14951 branch prediction and the benefits hardly outweigh the cost of extra 8
14952 nops on the average inserted by full alignment pseudo operation. */
14956 [(set_attr "length" "16")])
14958 (define_expand "prologue"
14961 "ix86_expand_prologue (); DONE;")
14963 (define_insn "set_got"
14964 [(set (match_operand:SI 0 "register_operand" "=r")
14965 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14966 (clobber (reg:CC FLAGS_REG))]
14968 { return output_set_got (operands[0], NULL_RTX); }
14969 [(set_attr "type" "multi")
14970 (set_attr "length" "12")])
14972 (define_insn "set_got_labelled"
14973 [(set (match_operand:SI 0 "register_operand" "=r")
14974 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14976 (clobber (reg:CC FLAGS_REG))]
14978 { return output_set_got (operands[0], operands[1]); }
14979 [(set_attr "type" "multi")
14980 (set_attr "length" "12")])
14982 (define_insn "set_got_rex64"
14983 [(set (match_operand:DI 0 "register_operand" "=r")
14984 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14986 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14987 [(set_attr "type" "lea")
14988 (set_attr "length" "6")])
14990 (define_insn "set_rip_rex64"
14991 [(set (match_operand:DI 0 "register_operand" "=r")
14992 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14994 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14995 [(set_attr "type" "lea")
14996 (set_attr "length" "6")])
14998 (define_insn "set_got_offset_rex64"
14999 [(set (match_operand:DI 0 "register_operand" "=r")
15000 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15002 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15003 [(set_attr "type" "imov")
15004 (set_attr "length" "11")])
15006 (define_expand "epilogue"
15009 "ix86_expand_epilogue (1); DONE;")
15011 (define_expand "sibcall_epilogue"
15014 "ix86_expand_epilogue (0); DONE;")
15016 (define_expand "eh_return"
15017 [(use (match_operand 0 "register_operand" ""))]
15020 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15022 /* Tricky bit: we write the address of the handler to which we will
15023 be returning into someone else's stack frame, one word below the
15024 stack address we wish to restore. */
15025 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15026 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15027 tmp = gen_rtx_MEM (Pmode, tmp);
15028 emit_move_insn (tmp, ra);
15030 if (Pmode == SImode)
15031 emit_jump_insn (gen_eh_return_si (sa));
15033 emit_jump_insn (gen_eh_return_di (sa));
15038 (define_insn_and_split "eh_return_si"
15040 (unspec [(match_operand:SI 0 "register_operand" "c")]
15041 UNSPEC_EH_RETURN))]
15046 "ix86_expand_epilogue (2); DONE;")
15048 (define_insn_and_split "eh_return_di"
15050 (unspec [(match_operand:DI 0 "register_operand" "c")]
15051 UNSPEC_EH_RETURN))]
15056 "ix86_expand_epilogue (2); DONE;")
15058 (define_insn "leave"
15059 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15060 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15061 (clobber (mem:BLK (scratch)))]
15064 [(set_attr "type" "leave")])
15066 (define_insn "leave_rex64"
15067 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15068 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15069 (clobber (mem:BLK (scratch)))]
15072 [(set_attr "type" "leave")])
15074 (define_expand "ffssi2"
15076 [(set (match_operand:SI 0 "register_operand" "")
15077 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15078 (clobber (match_scratch:SI 2 ""))
15079 (clobber (reg:CC FLAGS_REG))])]
15084 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15089 (define_expand "ffs_cmove"
15090 [(set (match_dup 2) (const_int -1))
15091 (parallel [(set (reg:CCZ FLAGS_REG)
15092 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15094 (set (match_operand:SI 0 "nonimmediate_operand" "")
15095 (ctz:SI (match_dup 1)))])
15096 (set (match_dup 0) (if_then_else:SI
15097 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15100 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15101 (clobber (reg:CC FLAGS_REG))])]
15103 "operands[2] = gen_reg_rtx (SImode);")
15105 (define_insn_and_split "*ffs_no_cmove"
15106 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15107 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15108 (clobber (match_scratch:SI 2 "=&q"))
15109 (clobber (reg:CC FLAGS_REG))]
15112 "&& reload_completed"
15113 [(parallel [(set (reg:CCZ FLAGS_REG)
15114 (compare:CCZ (match_dup 1) (const_int 0)))
15115 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15116 (set (strict_low_part (match_dup 3))
15117 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15118 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15119 (clobber (reg:CC FLAGS_REG))])
15120 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15121 (clobber (reg:CC FLAGS_REG))])
15122 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15123 (clobber (reg:CC FLAGS_REG))])]
15125 operands[3] = gen_lowpart (QImode, operands[2]);
15126 ix86_expand_clear (operands[2]);
15129 (define_insn "*ffssi_1"
15130 [(set (reg:CCZ FLAGS_REG)
15131 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15133 (set (match_operand:SI 0 "register_operand" "=r")
15134 (ctz:SI (match_dup 1)))]
15136 "bsf{l}\t{%1, %0|%0, %1}"
15137 [(set_attr "prefix_0f" "1")])
15139 (define_expand "ffsdi2"
15140 [(set (match_dup 2) (const_int -1))
15141 (parallel [(set (reg:CCZ FLAGS_REG)
15142 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15144 (set (match_operand:DI 0 "nonimmediate_operand" "")
15145 (ctz:DI (match_dup 1)))])
15146 (set (match_dup 0) (if_then_else:DI
15147 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15150 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15151 (clobber (reg:CC FLAGS_REG))])]
15153 "operands[2] = gen_reg_rtx (DImode);")
15155 (define_insn "*ffsdi_1"
15156 [(set (reg:CCZ FLAGS_REG)
15157 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15159 (set (match_operand:DI 0 "register_operand" "=r")
15160 (ctz:DI (match_dup 1)))]
15162 "bsf{q}\t{%1, %0|%0, %1}"
15163 [(set_attr "prefix_0f" "1")])
15165 (define_insn "ctzsi2"
15166 [(set (match_operand:SI 0 "register_operand" "=r")
15167 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15168 (clobber (reg:CC FLAGS_REG))]
15170 "bsf{l}\t{%1, %0|%0, %1}"
15171 [(set_attr "prefix_0f" "1")])
15173 (define_insn "ctzdi2"
15174 [(set (match_operand:DI 0 "register_operand" "=r")
15175 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15176 (clobber (reg:CC FLAGS_REG))]
15178 "bsf{q}\t{%1, %0|%0, %1}"
15179 [(set_attr "prefix_0f" "1")])
15181 (define_expand "clzsi2"
15183 [(set (match_operand:SI 0 "register_operand" "")
15184 (minus:SI (const_int 31)
15185 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15186 (clobber (reg:CC FLAGS_REG))])
15188 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15189 (clobber (reg:CC FLAGS_REG))])]
15194 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15199 (define_insn "clzsi2_abm"
15200 [(set (match_operand:SI 0 "register_operand" "=r")
15201 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15202 (clobber (reg:CC FLAGS_REG))]
15204 "lzcnt{l}\t{%1, %0|%0, %1}"
15205 [(set_attr "prefix_rep" "1")
15206 (set_attr "type" "bitmanip")
15207 (set_attr "mode" "SI")])
15209 (define_insn "*bsr"
15210 [(set (match_operand:SI 0 "register_operand" "=r")
15211 (minus:SI (const_int 31)
15212 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15213 (clobber (reg:CC FLAGS_REG))]
15215 "bsr{l}\t{%1, %0|%0, %1}"
15216 [(set_attr "prefix_0f" "1")
15217 (set_attr "mode" "SI")])
15219 (define_insn "popcountsi2"
15220 [(set (match_operand:SI 0 "register_operand" "=r")
15221 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15222 (clobber (reg:CC FLAGS_REG))]
15224 "popcnt{l}\t{%1, %0|%0, %1}"
15225 [(set_attr "prefix_rep" "1")
15226 (set_attr "type" "bitmanip")
15227 (set_attr "mode" "SI")])
15229 (define_insn "*popcountsi2_cmp"
15230 [(set (reg FLAGS_REG)
15232 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15234 (set (match_operand:SI 0 "register_operand" "=r")
15235 (popcount:SI (match_dup 1)))]
15236 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15237 "popcnt{l}\t{%1, %0|%0, %1}"
15238 [(set_attr "prefix_rep" "1")
15239 (set_attr "type" "bitmanip")
15240 (set_attr "mode" "SI")])
15242 (define_insn "*popcountsi2_cmp_zext"
15243 [(set (reg FLAGS_REG)
15245 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15247 (set (match_operand:DI 0 "register_operand" "=r")
15248 (zero_extend:DI(popcount:SI (match_dup 1))))]
15249 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15250 "popcnt{l}\t{%1, %0|%0, %1}"
15251 [(set_attr "prefix_rep" "1")
15252 (set_attr "type" "bitmanip")
15253 (set_attr "mode" "SI")])
15255 (define_expand "bswapsi2"
15256 [(set (match_operand:SI 0 "register_operand" "")
15257 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15262 rtx x = operands[0];
15264 emit_move_insn (x, operands[1]);
15265 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15266 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15267 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15272 (define_insn "*bswapsi_1"
15273 [(set (match_operand:SI 0 "register_operand" "=r")
15274 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15277 [(set_attr "prefix_0f" "1")
15278 (set_attr "length" "2")])
15280 (define_insn "*bswaphi_lowpart_1"
15281 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15282 (bswap:HI (match_dup 0)))
15283 (clobber (reg:CC FLAGS_REG))]
15284 "TARGET_USE_XCHGB || optimize_size"
15286 xchg{b}\t{%h0, %b0|%b0, %h0}
15287 rol{w}\t{$8, %0|%0, 8}"
15288 [(set_attr "length" "2,4")
15289 (set_attr "mode" "QI,HI")])
15291 (define_insn "bswaphi_lowpart"
15292 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15293 (bswap:HI (match_dup 0)))
15294 (clobber (reg:CC FLAGS_REG))]
15296 "rol{w}\t{$8, %0|%0, 8}"
15297 [(set_attr "length" "4")
15298 (set_attr "mode" "HI")])
15300 (define_insn "bswapdi2"
15301 [(set (match_operand:DI 0 "register_operand" "=r")
15302 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15305 [(set_attr "prefix_0f" "1")
15306 (set_attr "length" "3")])
15308 (define_expand "clzdi2"
15310 [(set (match_operand:DI 0 "register_operand" "")
15311 (minus:DI (const_int 63)
15312 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15313 (clobber (reg:CC FLAGS_REG))])
15315 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15316 (clobber (reg:CC FLAGS_REG))])]
15321 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15326 (define_insn "clzdi2_abm"
15327 [(set (match_operand:DI 0 "register_operand" "=r")
15328 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15329 (clobber (reg:CC FLAGS_REG))]
15330 "TARGET_64BIT && TARGET_ABM"
15331 "lzcnt{q}\t{%1, %0|%0, %1}"
15332 [(set_attr "prefix_rep" "1")
15333 (set_attr "type" "bitmanip")
15334 (set_attr "mode" "DI")])
15336 (define_insn "*bsr_rex64"
15337 [(set (match_operand:DI 0 "register_operand" "=r")
15338 (minus:DI (const_int 63)
15339 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15340 (clobber (reg:CC FLAGS_REG))]
15342 "bsr{q}\t{%1, %0|%0, %1}"
15343 [(set_attr "prefix_0f" "1")
15344 (set_attr "mode" "DI")])
15346 (define_insn "popcountdi2"
15347 [(set (match_operand:DI 0 "register_operand" "=r")
15348 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15349 (clobber (reg:CC FLAGS_REG))]
15350 "TARGET_64BIT && TARGET_POPCNT"
15351 "popcnt{q}\t{%1, %0|%0, %1}"
15352 [(set_attr "prefix_rep" "1")
15353 (set_attr "type" "bitmanip")
15354 (set_attr "mode" "DI")])
15356 (define_insn "*popcountdi2_cmp"
15357 [(set (reg FLAGS_REG)
15359 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15361 (set (match_operand:DI 0 "register_operand" "=r")
15362 (popcount:DI (match_dup 1)))]
15363 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15364 "popcnt{q}\t{%1, %0|%0, %1}"
15365 [(set_attr "prefix_rep" "1")
15366 (set_attr "type" "bitmanip")
15367 (set_attr "mode" "DI")])
15369 (define_expand "clzhi2"
15371 [(set (match_operand:HI 0 "register_operand" "")
15372 (minus:HI (const_int 15)
15373 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15374 (clobber (reg:CC FLAGS_REG))])
15376 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15377 (clobber (reg:CC FLAGS_REG))])]
15382 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15387 (define_insn "clzhi2_abm"
15388 [(set (match_operand:HI 0 "register_operand" "=r")
15389 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15390 (clobber (reg:CC FLAGS_REG))]
15392 "lzcnt{w}\t{%1, %0|%0, %1}"
15393 [(set_attr "prefix_rep" "1")
15394 (set_attr "type" "bitmanip")
15395 (set_attr "mode" "HI")])
15397 (define_insn "*bsrhi"
15398 [(set (match_operand:HI 0 "register_operand" "=r")
15399 (minus:HI (const_int 15)
15400 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15401 (clobber (reg:CC FLAGS_REG))]
15403 "bsr{w}\t{%1, %0|%0, %1}"
15404 [(set_attr "prefix_0f" "1")
15405 (set_attr "mode" "HI")])
15407 (define_insn "popcounthi2"
15408 [(set (match_operand:HI 0 "register_operand" "=r")
15409 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15410 (clobber (reg:CC FLAGS_REG))]
15412 "popcnt{w}\t{%1, %0|%0, %1}"
15413 [(set_attr "prefix_rep" "1")
15414 (set_attr "type" "bitmanip")
15415 (set_attr "mode" "HI")])
15417 (define_insn "*popcounthi2_cmp"
15418 [(set (reg FLAGS_REG)
15420 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15422 (set (match_operand:HI 0 "register_operand" "=r")
15423 (popcount:HI (match_dup 1)))]
15424 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15425 "popcnt{w}\t{%1, %0|%0, %1}"
15426 [(set_attr "prefix_rep" "1")
15427 (set_attr "type" "bitmanip")
15428 (set_attr "mode" "HI")])
15430 (define_expand "paritydi2"
15431 [(set (match_operand:DI 0 "register_operand" "")
15432 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15435 rtx scratch = gen_reg_rtx (QImode);
15438 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15439 NULL_RTX, operands[1]));
15441 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15442 gen_rtx_REG (CCmode, FLAGS_REG),
15444 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15447 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15450 rtx tmp = gen_reg_rtx (SImode);
15452 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15453 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15458 (define_insn_and_split "paritydi2_cmp"
15459 [(set (reg:CC FLAGS_REG)
15460 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15461 (clobber (match_scratch:DI 0 "=r"))
15462 (clobber (match_scratch:SI 1 "=&r"))
15463 (clobber (match_scratch:HI 2 "=Q"))]
15466 "&& reload_completed"
15468 [(set (match_dup 1)
15469 (xor:SI (match_dup 1) (match_dup 4)))
15470 (clobber (reg:CC FLAGS_REG))])
15472 [(set (reg:CC FLAGS_REG)
15473 (parity:CC (match_dup 1)))
15474 (clobber (match_dup 1))
15475 (clobber (match_dup 2))])]
15477 operands[4] = gen_lowpart (SImode, operands[3]);
15481 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15482 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15485 operands[1] = gen_highpart (SImode, operands[3]);
15488 (define_expand "paritysi2"
15489 [(set (match_operand:SI 0 "register_operand" "")
15490 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15493 rtx scratch = gen_reg_rtx (QImode);
15496 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15498 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15499 gen_rtx_REG (CCmode, FLAGS_REG),
15501 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15503 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15507 (define_insn_and_split "paritysi2_cmp"
15508 [(set (reg:CC FLAGS_REG)
15509 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15510 (clobber (match_scratch:SI 0 "=r"))
15511 (clobber (match_scratch:HI 1 "=&Q"))]
15514 "&& reload_completed"
15516 [(set (match_dup 1)
15517 (xor:HI (match_dup 1) (match_dup 3)))
15518 (clobber (reg:CC FLAGS_REG))])
15520 [(set (reg:CC FLAGS_REG)
15521 (parity:CC (match_dup 1)))
15522 (clobber (match_dup 1))])]
15524 operands[3] = gen_lowpart (HImode, operands[2]);
15526 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15527 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15530 (define_insn "*parityhi2_cmp"
15531 [(set (reg:CC FLAGS_REG)
15532 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15533 (clobber (match_scratch:HI 0 "=Q"))]
15535 "xor{b}\t{%h0, %b0|%b0, %h0}"
15536 [(set_attr "length" "2")
15537 (set_attr "mode" "HI")])
15539 (define_insn "*parityqi2_cmp"
15540 [(set (reg:CC FLAGS_REG)
15541 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15544 [(set_attr "length" "2")
15545 (set_attr "mode" "QI")])
15547 ;; Thread-local storage patterns for ELF.
15549 ;; Note that these code sequences must appear exactly as shown
15550 ;; in order to allow linker relaxation.
15552 (define_insn "*tls_global_dynamic_32_gnu"
15553 [(set (match_operand:SI 0 "register_operand" "=a")
15554 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15555 (match_operand:SI 2 "tls_symbolic_operand" "")
15556 (match_operand:SI 3 "call_insn_operand" "")]
15558 (clobber (match_scratch:SI 4 "=d"))
15559 (clobber (match_scratch:SI 5 "=c"))
15560 (clobber (reg:CC FLAGS_REG))]
15561 "!TARGET_64BIT && TARGET_GNU_TLS"
15562 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15563 [(set_attr "type" "multi")
15564 (set_attr "length" "12")])
15566 (define_insn "*tls_global_dynamic_32_sun"
15567 [(set (match_operand:SI 0 "register_operand" "=a")
15568 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15569 (match_operand:SI 2 "tls_symbolic_operand" "")
15570 (match_operand:SI 3 "call_insn_operand" "")]
15572 (clobber (match_scratch:SI 4 "=d"))
15573 (clobber (match_scratch:SI 5 "=c"))
15574 (clobber (reg:CC FLAGS_REG))]
15575 "!TARGET_64BIT && TARGET_SUN_TLS"
15576 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15577 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15578 [(set_attr "type" "multi")
15579 (set_attr "length" "14")])
15581 (define_expand "tls_global_dynamic_32"
15582 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15585 (match_operand:SI 1 "tls_symbolic_operand" "")
15588 (clobber (match_scratch:SI 4 ""))
15589 (clobber (match_scratch:SI 5 ""))
15590 (clobber (reg:CC FLAGS_REG))])]
15594 operands[2] = pic_offset_table_rtx;
15597 operands[2] = gen_reg_rtx (Pmode);
15598 emit_insn (gen_set_got (operands[2]));
15600 if (TARGET_GNU2_TLS)
15602 emit_insn (gen_tls_dynamic_gnu2_32
15603 (operands[0], operands[1], operands[2]));
15606 operands[3] = ix86_tls_get_addr ();
15609 (define_insn "*tls_global_dynamic_64"
15610 [(set (match_operand:DI 0 "register_operand" "=a")
15611 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15612 (match_operand:DI 3 "" "")))
15613 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15616 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15617 [(set_attr "type" "multi")
15618 (set_attr "length" "16")])
15620 (define_expand "tls_global_dynamic_64"
15621 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15622 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15623 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15627 if (TARGET_GNU2_TLS)
15629 emit_insn (gen_tls_dynamic_gnu2_64
15630 (operands[0], operands[1]));
15633 operands[2] = ix86_tls_get_addr ();
15636 (define_insn "*tls_local_dynamic_base_32_gnu"
15637 [(set (match_operand:SI 0 "register_operand" "=a")
15638 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15639 (match_operand:SI 2 "call_insn_operand" "")]
15640 UNSPEC_TLS_LD_BASE))
15641 (clobber (match_scratch:SI 3 "=d"))
15642 (clobber (match_scratch:SI 4 "=c"))
15643 (clobber (reg:CC FLAGS_REG))]
15644 "!TARGET_64BIT && TARGET_GNU_TLS"
15645 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15646 [(set_attr "type" "multi")
15647 (set_attr "length" "11")])
15649 (define_insn "*tls_local_dynamic_base_32_sun"
15650 [(set (match_operand:SI 0 "register_operand" "=a")
15651 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15652 (match_operand:SI 2 "call_insn_operand" "")]
15653 UNSPEC_TLS_LD_BASE))
15654 (clobber (match_scratch:SI 3 "=d"))
15655 (clobber (match_scratch:SI 4 "=c"))
15656 (clobber (reg:CC FLAGS_REG))]
15657 "!TARGET_64BIT && TARGET_SUN_TLS"
15658 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15659 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15660 [(set_attr "type" "multi")
15661 (set_attr "length" "13")])
15663 (define_expand "tls_local_dynamic_base_32"
15664 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15665 (unspec:SI [(match_dup 1) (match_dup 2)]
15666 UNSPEC_TLS_LD_BASE))
15667 (clobber (match_scratch:SI 3 ""))
15668 (clobber (match_scratch:SI 4 ""))
15669 (clobber (reg:CC FLAGS_REG))])]
15673 operands[1] = pic_offset_table_rtx;
15676 operands[1] = gen_reg_rtx (Pmode);
15677 emit_insn (gen_set_got (operands[1]));
15679 if (TARGET_GNU2_TLS)
15681 emit_insn (gen_tls_dynamic_gnu2_32
15682 (operands[0], ix86_tls_module_base (), operands[1]));
15685 operands[2] = ix86_tls_get_addr ();
15688 (define_insn "*tls_local_dynamic_base_64"
15689 [(set (match_operand:DI 0 "register_operand" "=a")
15690 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15691 (match_operand:DI 2 "" "")))
15692 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15694 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15695 [(set_attr "type" "multi")
15696 (set_attr "length" "12")])
15698 (define_expand "tls_local_dynamic_base_64"
15699 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15700 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15701 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15704 if (TARGET_GNU2_TLS)
15706 emit_insn (gen_tls_dynamic_gnu2_64
15707 (operands[0], ix86_tls_module_base ()));
15710 operands[1] = ix86_tls_get_addr ();
15713 ;; Local dynamic of a single variable is a lose. Show combine how
15714 ;; to convert that back to global dynamic.
15716 (define_insn_and_split "*tls_local_dynamic_32_once"
15717 [(set (match_operand:SI 0 "register_operand" "=a")
15718 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15719 (match_operand:SI 2 "call_insn_operand" "")]
15720 UNSPEC_TLS_LD_BASE)
15721 (const:SI (unspec:SI
15722 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15724 (clobber (match_scratch:SI 4 "=d"))
15725 (clobber (match_scratch:SI 5 "=c"))
15726 (clobber (reg:CC FLAGS_REG))]
15730 [(parallel [(set (match_dup 0)
15731 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15733 (clobber (match_dup 4))
15734 (clobber (match_dup 5))
15735 (clobber (reg:CC FLAGS_REG))])]
15738 ;; Load and add the thread base pointer from %gs:0.
15740 (define_insn "*load_tp_si"
15741 [(set (match_operand:SI 0 "register_operand" "=r")
15742 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15744 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15745 [(set_attr "type" "imov")
15746 (set_attr "modrm" "0")
15747 (set_attr "length" "7")
15748 (set_attr "memory" "load")
15749 (set_attr "imm_disp" "false")])
15751 (define_insn "*add_tp_si"
15752 [(set (match_operand:SI 0 "register_operand" "=r")
15753 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15754 (match_operand:SI 1 "register_operand" "0")))
15755 (clobber (reg:CC FLAGS_REG))]
15757 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15758 [(set_attr "type" "alu")
15759 (set_attr "modrm" "0")
15760 (set_attr "length" "7")
15761 (set_attr "memory" "load")
15762 (set_attr "imm_disp" "false")])
15764 (define_insn "*load_tp_di"
15765 [(set (match_operand:DI 0 "register_operand" "=r")
15766 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15768 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15769 [(set_attr "type" "imov")
15770 (set_attr "modrm" "0")
15771 (set_attr "length" "7")
15772 (set_attr "memory" "load")
15773 (set_attr "imm_disp" "false")])
15775 (define_insn "*add_tp_di"
15776 [(set (match_operand:DI 0 "register_operand" "=r")
15777 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15778 (match_operand:DI 1 "register_operand" "0")))
15779 (clobber (reg:CC FLAGS_REG))]
15781 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15782 [(set_attr "type" "alu")
15783 (set_attr "modrm" "0")
15784 (set_attr "length" "7")
15785 (set_attr "memory" "load")
15786 (set_attr "imm_disp" "false")])
15788 ;; GNU2 TLS patterns can be split.
15790 (define_expand "tls_dynamic_gnu2_32"
15791 [(set (match_dup 3)
15792 (plus:SI (match_operand:SI 2 "register_operand" "")
15794 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15797 [(set (match_operand:SI 0 "register_operand" "")
15798 (unspec:SI [(match_dup 1) (match_dup 3)
15799 (match_dup 2) (reg:SI SP_REG)]
15801 (clobber (reg:CC FLAGS_REG))])]
15802 "!TARGET_64BIT && TARGET_GNU2_TLS"
15804 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15805 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15808 (define_insn "*tls_dynamic_lea_32"
15809 [(set (match_operand:SI 0 "register_operand" "=r")
15810 (plus:SI (match_operand:SI 1 "register_operand" "b")
15812 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15813 UNSPEC_TLSDESC))))]
15814 "!TARGET_64BIT && TARGET_GNU2_TLS"
15815 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15816 [(set_attr "type" "lea")
15817 (set_attr "mode" "SI")
15818 (set_attr "length" "6")
15819 (set_attr "length_address" "4")])
15821 (define_insn "*tls_dynamic_call_32"
15822 [(set (match_operand:SI 0 "register_operand" "=a")
15823 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15824 (match_operand:SI 2 "register_operand" "0")
15825 ;; we have to make sure %ebx still points to the GOT
15826 (match_operand:SI 3 "register_operand" "b")
15829 (clobber (reg:CC FLAGS_REG))]
15830 "!TARGET_64BIT && TARGET_GNU2_TLS"
15831 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15832 [(set_attr "type" "call")
15833 (set_attr "length" "2")
15834 (set_attr "length_address" "0")])
15836 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15837 [(set (match_operand:SI 0 "register_operand" "=&a")
15839 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15840 (match_operand:SI 4 "" "")
15841 (match_operand:SI 2 "register_operand" "b")
15844 (const:SI (unspec:SI
15845 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15847 (clobber (reg:CC FLAGS_REG))]
15848 "!TARGET_64BIT && TARGET_GNU2_TLS"
15851 [(set (match_dup 0) (match_dup 5))]
15853 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15854 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15857 (define_expand "tls_dynamic_gnu2_64"
15858 [(set (match_dup 2)
15859 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15862 [(set (match_operand:DI 0 "register_operand" "")
15863 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15865 (clobber (reg:CC FLAGS_REG))])]
15866 "TARGET_64BIT && TARGET_GNU2_TLS"
15868 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15869 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15872 (define_insn "*tls_dynamic_lea_64"
15873 [(set (match_operand:DI 0 "register_operand" "=r")
15874 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15876 "TARGET_64BIT && TARGET_GNU2_TLS"
15877 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15878 [(set_attr "type" "lea")
15879 (set_attr "mode" "DI")
15880 (set_attr "length" "7")
15881 (set_attr "length_address" "4")])
15883 (define_insn "*tls_dynamic_call_64"
15884 [(set (match_operand:DI 0 "register_operand" "=a")
15885 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15886 (match_operand:DI 2 "register_operand" "0")
15889 (clobber (reg:CC FLAGS_REG))]
15890 "TARGET_64BIT && TARGET_GNU2_TLS"
15891 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15892 [(set_attr "type" "call")
15893 (set_attr "length" "2")
15894 (set_attr "length_address" "0")])
15896 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15897 [(set (match_operand:DI 0 "register_operand" "=&a")
15899 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15900 (match_operand:DI 3 "" "")
15903 (const:DI (unspec:DI
15904 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15906 (clobber (reg:CC FLAGS_REG))]
15907 "TARGET_64BIT && TARGET_GNU2_TLS"
15910 [(set (match_dup 0) (match_dup 4))]
15912 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15913 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15918 ;; These patterns match the binary 387 instructions for addM3, subM3,
15919 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15920 ;; SFmode. The first is the normal insn, the second the same insn but
15921 ;; with one operand a conversion, and the third the same insn but with
15922 ;; the other operand a conversion. The conversion may be SFmode or
15923 ;; SImode if the target mode DFmode, but only SImode if the target mode
15926 ;; Gcc is slightly more smart about handling normal two address instructions
15927 ;; so use special patterns for add and mull.
15929 (define_insn "*fop_sf_comm_mixed"
15930 [(set (match_operand:SF 0 "register_operand" "=f,x")
15931 (match_operator:SF 3 "binary_fp_operator"
15932 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15933 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15934 "TARGET_MIX_SSE_I387
15935 && COMMUTATIVE_ARITH_P (operands[3])
15936 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15937 "* return output_387_binary_op (insn, operands);"
15938 [(set (attr "type")
15939 (if_then_else (eq_attr "alternative" "1")
15940 (if_then_else (match_operand:SF 3 "mult_operator" "")
15941 (const_string "ssemul")
15942 (const_string "sseadd"))
15943 (if_then_else (match_operand:SF 3 "mult_operator" "")
15944 (const_string "fmul")
15945 (const_string "fop"))))
15946 (set_attr "mode" "SF")])
15948 (define_insn "*fop_sf_comm_sse"
15949 [(set (match_operand:SF 0 "register_operand" "=x")
15950 (match_operator:SF 3 "binary_fp_operator"
15951 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15952 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15954 && COMMUTATIVE_ARITH_P (operands[3])
15955 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15956 "* return output_387_binary_op (insn, operands);"
15957 [(set (attr "type")
15958 (if_then_else (match_operand:SF 3 "mult_operator" "")
15959 (const_string "ssemul")
15960 (const_string "sseadd")))
15961 (set_attr "mode" "SF")])
15963 (define_insn "*fop_sf_comm_i387"
15964 [(set (match_operand:SF 0 "register_operand" "=f")
15965 (match_operator:SF 3 "binary_fp_operator"
15966 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15967 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15969 && COMMUTATIVE_ARITH_P (operands[3])
15970 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15971 "* return output_387_binary_op (insn, operands);"
15972 [(set (attr "type")
15973 (if_then_else (match_operand:SF 3 "mult_operator" "")
15974 (const_string "fmul")
15975 (const_string "fop")))
15976 (set_attr "mode" "SF")])
15978 (define_insn "*fop_sf_1_mixed"
15979 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15980 (match_operator:SF 3 "binary_fp_operator"
15981 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15982 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15983 "TARGET_MIX_SSE_I387
15984 && !COMMUTATIVE_ARITH_P (operands[3])
15985 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15986 "* return output_387_binary_op (insn, operands);"
15987 [(set (attr "type")
15988 (cond [(and (eq_attr "alternative" "2")
15989 (match_operand:SF 3 "mult_operator" ""))
15990 (const_string "ssemul")
15991 (and (eq_attr "alternative" "2")
15992 (match_operand:SF 3 "div_operator" ""))
15993 (const_string "ssediv")
15994 (eq_attr "alternative" "2")
15995 (const_string "sseadd")
15996 (match_operand:SF 3 "mult_operator" "")
15997 (const_string "fmul")
15998 (match_operand:SF 3 "div_operator" "")
15999 (const_string "fdiv")
16001 (const_string "fop")))
16002 (set_attr "mode" "SF")])
16004 (define_insn "*rcpsf2_sse"
16005 [(set (match_operand:SF 0 "register_operand" "=x")
16006 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16009 "rcpss\t{%1, %0|%0, %1}"
16010 [(set_attr "type" "sse")
16011 (set_attr "mode" "SF")])
16013 (define_insn "*fop_sf_1_sse"
16014 [(set (match_operand:SF 0 "register_operand" "=x")
16015 (match_operator:SF 3 "binary_fp_operator"
16016 [(match_operand:SF 1 "register_operand" "0")
16017 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16019 && !COMMUTATIVE_ARITH_P (operands[3])"
16020 "* return output_387_binary_op (insn, operands);"
16021 [(set (attr "type")
16022 (cond [(match_operand:SF 3 "mult_operator" "")
16023 (const_string "ssemul")
16024 (match_operand:SF 3 "div_operator" "")
16025 (const_string "ssediv")
16027 (const_string "sseadd")))
16028 (set_attr "mode" "SF")])
16030 ;; This pattern is not fully shadowed by the pattern above.
16031 (define_insn "*fop_sf_1_i387"
16032 [(set (match_operand:SF 0 "register_operand" "=f,f")
16033 (match_operator:SF 3 "binary_fp_operator"
16034 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16035 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16036 "TARGET_80387 && !TARGET_SSE_MATH
16037 && !COMMUTATIVE_ARITH_P (operands[3])
16038 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16039 "* return output_387_binary_op (insn, operands);"
16040 [(set (attr "type")
16041 (cond [(match_operand:SF 3 "mult_operator" "")
16042 (const_string "fmul")
16043 (match_operand:SF 3 "div_operator" "")
16044 (const_string "fdiv")
16046 (const_string "fop")))
16047 (set_attr "mode" "SF")])
16049 ;; ??? Add SSE splitters for these!
16050 (define_insn "*fop_sf_2<mode>_i387"
16051 [(set (match_operand:SF 0 "register_operand" "=f,f")
16052 (match_operator:SF 3 "binary_fp_operator"
16053 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16054 (match_operand:SF 2 "register_operand" "0,0")]))]
16055 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16056 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16057 [(set (attr "type")
16058 (cond [(match_operand:SF 3 "mult_operator" "")
16059 (const_string "fmul")
16060 (match_operand:SF 3 "div_operator" "")
16061 (const_string "fdiv")
16063 (const_string "fop")))
16064 (set_attr "fp_int_src" "true")
16065 (set_attr "mode" "<MODE>")])
16067 (define_insn "*fop_sf_3<mode>_i387"
16068 [(set (match_operand:SF 0 "register_operand" "=f,f")
16069 (match_operator:SF 3 "binary_fp_operator"
16070 [(match_operand:SF 1 "register_operand" "0,0")
16071 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16072 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16073 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16074 [(set (attr "type")
16075 (cond [(match_operand:SF 3 "mult_operator" "")
16076 (const_string "fmul")
16077 (match_operand:SF 3 "div_operator" "")
16078 (const_string "fdiv")
16080 (const_string "fop")))
16081 (set_attr "fp_int_src" "true")
16082 (set_attr "mode" "<MODE>")])
16084 (define_insn "*fop_df_comm_mixed"
16085 [(set (match_operand:DF 0 "register_operand" "=f,x")
16086 (match_operator:DF 3 "binary_fp_operator"
16087 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16088 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16089 "TARGET_SSE2 && TARGET_MIX_SSE_I387
16090 && COMMUTATIVE_ARITH_P (operands[3])
16091 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16092 "* return output_387_binary_op (insn, operands);"
16093 [(set (attr "type")
16094 (if_then_else (eq_attr "alternative" "1")
16095 (if_then_else (match_operand:DF 3 "mult_operator" "")
16096 (const_string "ssemul")
16097 (const_string "sseadd"))
16098 (if_then_else (match_operand:DF 3 "mult_operator" "")
16099 (const_string "fmul")
16100 (const_string "fop"))))
16101 (set_attr "mode" "DF")])
16103 (define_insn "*fop_df_comm_sse"
16104 [(set (match_operand:DF 0 "register_operand" "=x")
16105 (match_operator:DF 3 "binary_fp_operator"
16106 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16107 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16108 "TARGET_SSE2 && TARGET_SSE_MATH
16109 && COMMUTATIVE_ARITH_P (operands[3])
16110 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16111 "* return output_387_binary_op (insn, operands);"
16112 [(set (attr "type")
16113 (if_then_else (match_operand:DF 3 "mult_operator" "")
16114 (const_string "ssemul")
16115 (const_string "sseadd")))
16116 (set_attr "mode" "DF")])
16118 (define_insn "*fop_df_comm_i387"
16119 [(set (match_operand:DF 0 "register_operand" "=f")
16120 (match_operator:DF 3 "binary_fp_operator"
16121 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16122 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16124 && COMMUTATIVE_ARITH_P (operands[3])
16125 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16126 "* return output_387_binary_op (insn, operands);"
16127 [(set (attr "type")
16128 (if_then_else (match_operand:DF 3 "mult_operator" "")
16129 (const_string "fmul")
16130 (const_string "fop")))
16131 (set_attr "mode" "DF")])
16133 (define_insn "*fop_df_1_mixed"
16134 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16135 (match_operator:DF 3 "binary_fp_operator"
16136 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16137 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16138 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16139 && !COMMUTATIVE_ARITH_P (operands[3])
16140 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16141 "* return output_387_binary_op (insn, operands);"
16142 [(set (attr "type")
16143 (cond [(and (eq_attr "alternative" "2")
16144 (match_operand:DF 3 "mult_operator" ""))
16145 (const_string "ssemul")
16146 (and (eq_attr "alternative" "2")
16147 (match_operand:DF 3 "div_operator" ""))
16148 (const_string "ssediv")
16149 (eq_attr "alternative" "2")
16150 (const_string "sseadd")
16151 (match_operand:DF 3 "mult_operator" "")
16152 (const_string "fmul")
16153 (match_operand:DF 3 "div_operator" "")
16154 (const_string "fdiv")
16156 (const_string "fop")))
16157 (set_attr "mode" "DF")])
16159 (define_insn "*fop_df_1_sse"
16160 [(set (match_operand:DF 0 "register_operand" "=x")
16161 (match_operator:DF 3 "binary_fp_operator"
16162 [(match_operand:DF 1 "register_operand" "0")
16163 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16164 "TARGET_SSE2 && TARGET_SSE_MATH
16165 && !COMMUTATIVE_ARITH_P (operands[3])"
16166 "* return output_387_binary_op (insn, operands);"
16167 [(set_attr "mode" "DF")
16169 (cond [(match_operand:DF 3 "mult_operator" "")
16170 (const_string "ssemul")
16171 (match_operand:DF 3 "div_operator" "")
16172 (const_string "ssediv")
16174 (const_string "sseadd")))])
16176 ;; This pattern is not fully shadowed by the pattern above.
16177 (define_insn "*fop_df_1_i387"
16178 [(set (match_operand:DF 0 "register_operand" "=f,f")
16179 (match_operator:DF 3 "binary_fp_operator"
16180 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16181 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16182 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16183 && !COMMUTATIVE_ARITH_P (operands[3])
16184 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16185 "* return output_387_binary_op (insn, operands);"
16186 [(set (attr "type")
16187 (cond [(match_operand:DF 3 "mult_operator" "")
16188 (const_string "fmul")
16189 (match_operand:DF 3 "div_operator" "")
16190 (const_string "fdiv")
16192 (const_string "fop")))
16193 (set_attr "mode" "DF")])
16195 ;; ??? Add SSE splitters for these!
16196 (define_insn "*fop_df_2<mode>_i387"
16197 [(set (match_operand:DF 0 "register_operand" "=f,f")
16198 (match_operator:DF 3 "binary_fp_operator"
16199 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16200 (match_operand:DF 2 "register_operand" "0,0")]))]
16201 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16202 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16203 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16204 [(set (attr "type")
16205 (cond [(match_operand:DF 3 "mult_operator" "")
16206 (const_string "fmul")
16207 (match_operand:DF 3 "div_operator" "")
16208 (const_string "fdiv")
16210 (const_string "fop")))
16211 (set_attr "fp_int_src" "true")
16212 (set_attr "mode" "<MODE>")])
16214 (define_insn "*fop_df_3<mode>_i387"
16215 [(set (match_operand:DF 0 "register_operand" "=f,f")
16216 (match_operator:DF 3 "binary_fp_operator"
16217 [(match_operand:DF 1 "register_operand" "0,0")
16218 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16219 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16220 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16221 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16222 [(set (attr "type")
16223 (cond [(match_operand:DF 3 "mult_operator" "")
16224 (const_string "fmul")
16225 (match_operand:DF 3 "div_operator" "")
16226 (const_string "fdiv")
16228 (const_string "fop")))
16229 (set_attr "fp_int_src" "true")
16230 (set_attr "mode" "<MODE>")])
16232 (define_insn "*fop_df_4_i387"
16233 [(set (match_operand:DF 0 "register_operand" "=f,f")
16234 (match_operator:DF 3 "binary_fp_operator"
16235 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16236 (match_operand:DF 2 "register_operand" "0,f")]))]
16237 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16238 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16239 "* return output_387_binary_op (insn, operands);"
16240 [(set (attr "type")
16241 (cond [(match_operand:DF 3 "mult_operator" "")
16242 (const_string "fmul")
16243 (match_operand:DF 3 "div_operator" "")
16244 (const_string "fdiv")
16246 (const_string "fop")))
16247 (set_attr "mode" "SF")])
16249 (define_insn "*fop_df_5_i387"
16250 [(set (match_operand:DF 0 "register_operand" "=f,f")
16251 (match_operator:DF 3 "binary_fp_operator"
16252 [(match_operand:DF 1 "register_operand" "0,f")
16254 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16255 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16256 "* return output_387_binary_op (insn, operands);"
16257 [(set (attr "type")
16258 (cond [(match_operand:DF 3 "mult_operator" "")
16259 (const_string "fmul")
16260 (match_operand:DF 3 "div_operator" "")
16261 (const_string "fdiv")
16263 (const_string "fop")))
16264 (set_attr "mode" "SF")])
16266 (define_insn "*fop_df_6_i387"
16267 [(set (match_operand:DF 0 "register_operand" "=f,f")
16268 (match_operator:DF 3 "binary_fp_operator"
16270 (match_operand:SF 1 "register_operand" "0,f"))
16272 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16273 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16274 "* return output_387_binary_op (insn, operands);"
16275 [(set (attr "type")
16276 (cond [(match_operand:DF 3 "mult_operator" "")
16277 (const_string "fmul")
16278 (match_operand:DF 3 "div_operator" "")
16279 (const_string "fdiv")
16281 (const_string "fop")))
16282 (set_attr "mode" "SF")])
16284 (define_insn "*fop_xf_comm_i387"
16285 [(set (match_operand:XF 0 "register_operand" "=f")
16286 (match_operator:XF 3 "binary_fp_operator"
16287 [(match_operand:XF 1 "register_operand" "%0")
16288 (match_operand:XF 2 "register_operand" "f")]))]
16290 && COMMUTATIVE_ARITH_P (operands[3])"
16291 "* return output_387_binary_op (insn, operands);"
16292 [(set (attr "type")
16293 (if_then_else (match_operand:XF 3 "mult_operator" "")
16294 (const_string "fmul")
16295 (const_string "fop")))
16296 (set_attr "mode" "XF")])
16298 (define_insn "*fop_xf_1_i387"
16299 [(set (match_operand:XF 0 "register_operand" "=f,f")
16300 (match_operator:XF 3 "binary_fp_operator"
16301 [(match_operand:XF 1 "register_operand" "0,f")
16302 (match_operand:XF 2 "register_operand" "f,0")]))]
16304 && !COMMUTATIVE_ARITH_P (operands[3])"
16305 "* return output_387_binary_op (insn, operands);"
16306 [(set (attr "type")
16307 (cond [(match_operand:XF 3 "mult_operator" "")
16308 (const_string "fmul")
16309 (match_operand:XF 3 "div_operator" "")
16310 (const_string "fdiv")
16312 (const_string "fop")))
16313 (set_attr "mode" "XF")])
16315 (define_insn "*fop_xf_2<mode>_i387"
16316 [(set (match_operand:XF 0 "register_operand" "=f,f")
16317 (match_operator:XF 3 "binary_fp_operator"
16318 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16319 (match_operand:XF 2 "register_operand" "0,0")]))]
16320 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16321 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16322 [(set (attr "type")
16323 (cond [(match_operand:XF 3 "mult_operator" "")
16324 (const_string "fmul")
16325 (match_operand:XF 3 "div_operator" "")
16326 (const_string "fdiv")
16328 (const_string "fop")))
16329 (set_attr "fp_int_src" "true")
16330 (set_attr "mode" "<MODE>")])
16332 (define_insn "*fop_xf_3<mode>_i387"
16333 [(set (match_operand:XF 0 "register_operand" "=f,f")
16334 (match_operator:XF 3 "binary_fp_operator"
16335 [(match_operand:XF 1 "register_operand" "0,0")
16336 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16337 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16338 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16339 [(set (attr "type")
16340 (cond [(match_operand:XF 3 "mult_operator" "")
16341 (const_string "fmul")
16342 (match_operand:XF 3 "div_operator" "")
16343 (const_string "fdiv")
16345 (const_string "fop")))
16346 (set_attr "fp_int_src" "true")
16347 (set_attr "mode" "<MODE>")])
16349 (define_insn "*fop_xf_4_i387"
16350 [(set (match_operand:XF 0 "register_operand" "=f,f")
16351 (match_operator:XF 3 "binary_fp_operator"
16353 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16354 (match_operand:XF 2 "register_operand" "0,f")]))]
16356 "* return output_387_binary_op (insn, operands);"
16357 [(set (attr "type")
16358 (cond [(match_operand:XF 3 "mult_operator" "")
16359 (const_string "fmul")
16360 (match_operand:XF 3 "div_operator" "")
16361 (const_string "fdiv")
16363 (const_string "fop")))
16364 (set_attr "mode" "SF")])
16366 (define_insn "*fop_xf_5_i387"
16367 [(set (match_operand:XF 0 "register_operand" "=f,f")
16368 (match_operator:XF 3 "binary_fp_operator"
16369 [(match_operand:XF 1 "register_operand" "0,f")
16371 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16373 "* return output_387_binary_op (insn, operands);"
16374 [(set (attr "type")
16375 (cond [(match_operand:XF 3 "mult_operator" "")
16376 (const_string "fmul")
16377 (match_operand:XF 3 "div_operator" "")
16378 (const_string "fdiv")
16380 (const_string "fop")))
16381 (set_attr "mode" "SF")])
16383 (define_insn "*fop_xf_6_i387"
16384 [(set (match_operand:XF 0 "register_operand" "=f,f")
16385 (match_operator:XF 3 "binary_fp_operator"
16387 (match_operand:MODEF 1 "register_operand" "0,f"))
16389 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16391 "* return output_387_binary_op (insn, operands);"
16392 [(set (attr "type")
16393 (cond [(match_operand:XF 3 "mult_operator" "")
16394 (const_string "fmul")
16395 (match_operand:XF 3 "div_operator" "")
16396 (const_string "fdiv")
16398 (const_string "fop")))
16399 (set_attr "mode" "SF")])
16402 [(set (match_operand 0 "register_operand" "")
16403 (match_operator 3 "binary_fp_operator"
16404 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16405 (match_operand 2 "register_operand" "")]))]
16407 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16410 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16411 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16412 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16413 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16414 GET_MODE (operands[3]),
16417 ix86_free_from_memory (GET_MODE (operands[1]));
16422 [(set (match_operand 0 "register_operand" "")
16423 (match_operator 3 "binary_fp_operator"
16424 [(match_operand 1 "register_operand" "")
16425 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16427 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16430 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16431 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16432 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16433 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16434 GET_MODE (operands[3]),
16437 ix86_free_from_memory (GET_MODE (operands[2]));
16441 ;; FPU special functions.
16443 ;; This pattern implements a no-op XFmode truncation for
16444 ;; all fancy i386 XFmode math functions.
16446 (define_insn "truncxf<mode>2_i387_noop_unspec"
16447 [(set (match_operand:MODEF 0 "register_operand" "=f")
16448 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16449 UNSPEC_TRUNC_NOOP))]
16450 "TARGET_USE_FANCY_MATH_387"
16451 "* return output_387_reg_move (insn, operands);"
16452 [(set_attr "type" "fmov")
16453 (set_attr "mode" "<MODE>")])
16455 (define_insn "sqrtxf2"
16456 [(set (match_operand:XF 0 "register_operand" "=f")
16457 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16458 "TARGET_USE_FANCY_MATH_387"
16460 [(set_attr "type" "fpspc")
16461 (set_attr "mode" "XF")
16462 (set_attr "athlon_decode" "direct")
16463 (set_attr "amdfam10_decode" "direct")])
16465 (define_insn "sqrt_extend<mode>xf2_i387"
16466 [(set (match_operand:XF 0 "register_operand" "=f")
16469 (match_operand:MODEF 1 "register_operand" "0"))))]
16470 "TARGET_USE_FANCY_MATH_387"
16472 [(set_attr "type" "fpspc")
16473 (set_attr "mode" "XF")
16474 (set_attr "athlon_decode" "direct")
16475 (set_attr "amdfam10_decode" "direct")])
16477 (define_insn "*rsqrtsf2_sse"
16478 [(set (match_operand:SF 0 "register_operand" "=x")
16479 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16482 "rsqrtss\t{%1, %0|%0, %1}"
16483 [(set_attr "type" "sse")
16484 (set_attr "mode" "SF")])
16486 (define_expand "rsqrtsf2"
16487 [(set (match_operand:SF 0 "register_operand" "")
16488 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16492 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16496 (define_insn "*sqrt<mode>2_sse"
16497 [(set (match_operand:MODEF 0 "register_operand" "=x")
16499 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16500 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16501 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16502 [(set_attr "type" "sse")
16503 (set_attr "mode" "<MODE>")
16504 (set_attr "athlon_decode" "*")
16505 (set_attr "amdfam10_decode" "*")])
16507 (define_expand "sqrt<mode>2"
16508 [(set (match_operand:MODEF 0 "register_operand" "")
16510 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16511 "TARGET_USE_FANCY_MATH_387
16512 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16514 if (<MODE>mode == SFmode
16515 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16516 && flag_finite_math_only && !flag_trapping_math
16517 && flag_unsafe_math_optimizations)
16519 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16523 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16525 rtx op0 = gen_reg_rtx (XFmode);
16526 rtx op1 = force_reg (<MODE>mode, operands[1]);
16528 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16529 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16534 (define_insn "fpremxf4_i387"
16535 [(set (match_operand:XF 0 "register_operand" "=f")
16536 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16537 (match_operand:XF 3 "register_operand" "1")]
16539 (set (match_operand:XF 1 "register_operand" "=u")
16540 (unspec:XF [(match_dup 2) (match_dup 3)]
16542 (set (reg:CCFP FPSR_REG)
16543 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16545 "TARGET_USE_FANCY_MATH_387"
16547 [(set_attr "type" "fpspc")
16548 (set_attr "mode" "XF")])
16550 (define_expand "fmodxf3"
16551 [(use (match_operand:XF 0 "register_operand" ""))
16552 (use (match_operand:XF 1 "register_operand" ""))
16553 (use (match_operand:XF 2 "register_operand" ""))]
16554 "TARGET_USE_FANCY_MATH_387"
16556 rtx label = gen_label_rtx ();
16560 if (rtx_equal_p (operands[1], operands[2]))
16562 op2 = gen_reg_rtx (XFmode);
16563 emit_move_insn (op2, operands[2]);
16568 emit_label (label);
16569 emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16570 ix86_emit_fp_unordered_jump (label);
16571 LABEL_NUSES (label) = 1;
16573 emit_move_insn (operands[0], operands[1]);
16577 (define_expand "fmod<mode>3"
16578 [(use (match_operand:MODEF 0 "register_operand" ""))
16579 (use (match_operand:MODEF 1 "general_operand" ""))
16580 (use (match_operand:MODEF 2 "general_operand" ""))]
16581 "TARGET_USE_FANCY_MATH_387"
16583 rtx label = gen_label_rtx ();
16585 rtx op1 = gen_reg_rtx (XFmode);
16586 rtx op2 = gen_reg_rtx (XFmode);
16588 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16589 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16591 emit_label (label);
16592 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16593 ix86_emit_fp_unordered_jump (label);
16594 LABEL_NUSES (label) = 1;
16596 /* Truncate the result properly for strict SSE math. */
16597 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16598 && !TARGET_MIX_SSE_I387)
16599 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16601 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16606 (define_insn "fprem1xf4_i387"
16607 [(set (match_operand:XF 0 "register_operand" "=f")
16608 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16609 (match_operand:XF 3 "register_operand" "1")]
16611 (set (match_operand:XF 1 "register_operand" "=u")
16612 (unspec:XF [(match_dup 2) (match_dup 3)]
16614 (set (reg:CCFP FPSR_REG)
16615 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16617 "TARGET_USE_FANCY_MATH_387"
16619 [(set_attr "type" "fpspc")
16620 (set_attr "mode" "XF")])
16622 (define_expand "remainderxf3"
16623 [(use (match_operand:XF 0 "register_operand" ""))
16624 (use (match_operand:XF 1 "register_operand" ""))
16625 (use (match_operand:XF 2 "register_operand" ""))]
16626 "TARGET_USE_FANCY_MATH_387"
16628 rtx label = gen_label_rtx ();
16632 if (rtx_equal_p (operands[1], operands[2]))
16634 op2 = gen_reg_rtx (XFmode);
16635 emit_move_insn (op2, operands[2]);
16640 emit_label (label);
16641 emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16642 ix86_emit_fp_unordered_jump (label);
16643 LABEL_NUSES (label) = 1;
16645 emit_move_insn (operands[0], operands[1]);
16649 (define_expand "remainder<mode>3"
16650 [(use (match_operand:MODEF 0 "register_operand" ""))
16651 (use (match_operand:MODEF 1 "general_operand" ""))
16652 (use (match_operand:MODEF 2 "general_operand" ""))]
16653 "TARGET_USE_FANCY_MATH_387"
16655 rtx label = gen_label_rtx ();
16657 rtx op1 = gen_reg_rtx (XFmode);
16658 rtx op2 = gen_reg_rtx (XFmode);
16660 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16661 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16663 emit_label (label);
16665 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16666 ix86_emit_fp_unordered_jump (label);
16667 LABEL_NUSES (label) = 1;
16669 /* Truncate the result properly for strict SSE math. */
16670 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16671 && !TARGET_MIX_SSE_I387)
16672 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16674 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16679 (define_insn "*sinxf2_i387"
16680 [(set (match_operand:XF 0 "register_operand" "=f")
16681 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16682 "TARGET_USE_FANCY_MATH_387
16683 && flag_unsafe_math_optimizations"
16685 [(set_attr "type" "fpspc")
16686 (set_attr "mode" "XF")])
16688 (define_insn "*sin_extend<mode>xf2_i387"
16689 [(set (match_operand:XF 0 "register_operand" "=f")
16690 (unspec:XF [(float_extend:XF
16691 (match_operand:MODEF 1 "register_operand" "0"))]
16693 "TARGET_USE_FANCY_MATH_387
16694 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16695 || TARGET_MIX_SSE_I387)
16696 && flag_unsafe_math_optimizations"
16698 [(set_attr "type" "fpspc")
16699 (set_attr "mode" "XF")])
16701 (define_insn "*cosxf2_i387"
16702 [(set (match_operand:XF 0 "register_operand" "=f")
16703 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16704 "TARGET_USE_FANCY_MATH_387
16705 && flag_unsafe_math_optimizations"
16707 [(set_attr "type" "fpspc")
16708 (set_attr "mode" "XF")])
16710 (define_insn "*cos_extend<mode>xf2_i387"
16711 [(set (match_operand:XF 0 "register_operand" "=f")
16712 (unspec:XF [(float_extend:XF
16713 (match_operand:MODEF 1 "register_operand" "0"))]
16715 "TARGET_USE_FANCY_MATH_387
16716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16717 || TARGET_MIX_SSE_I387)
16718 && flag_unsafe_math_optimizations"
16720 [(set_attr "type" "fpspc")
16721 (set_attr "mode" "XF")])
16723 ;; When sincos pattern is defined, sin and cos builtin functions will be
16724 ;; expanded to sincos pattern with one of its outputs left unused.
16725 ;; CSE pass will figure out if two sincos patterns can be combined,
16726 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16727 ;; depending on the unused output.
16729 (define_insn "sincosxf3"
16730 [(set (match_operand:XF 0 "register_operand" "=f")
16731 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16732 UNSPEC_SINCOS_COS))
16733 (set (match_operand:XF 1 "register_operand" "=u")
16734 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16735 "TARGET_USE_FANCY_MATH_387
16736 && flag_unsafe_math_optimizations"
16738 [(set_attr "type" "fpspc")
16739 (set_attr "mode" "XF")])
16742 [(set (match_operand:XF 0 "register_operand" "")
16743 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16744 UNSPEC_SINCOS_COS))
16745 (set (match_operand:XF 1 "register_operand" "")
16746 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16747 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16748 && !(reload_completed || reload_in_progress)"
16749 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16753 [(set (match_operand:XF 0 "register_operand" "")
16754 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16755 UNSPEC_SINCOS_COS))
16756 (set (match_operand:XF 1 "register_operand" "")
16757 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16758 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16759 && !(reload_completed || reload_in_progress)"
16760 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16763 (define_insn "sincos_extend<mode>xf3_i387"
16764 [(set (match_operand:XF 0 "register_operand" "=f")
16765 (unspec:XF [(float_extend:XF
16766 (match_operand:MODEF 2 "register_operand" "0"))]
16767 UNSPEC_SINCOS_COS))
16768 (set (match_operand:XF 1 "register_operand" "=u")
16769 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16770 "TARGET_USE_FANCY_MATH_387
16771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16772 || TARGET_MIX_SSE_I387)
16773 && flag_unsafe_math_optimizations"
16775 [(set_attr "type" "fpspc")
16776 (set_attr "mode" "XF")])
16779 [(set (match_operand:XF 0 "register_operand" "")
16780 (unspec:XF [(float_extend:XF
16781 (match_operand:MODEF 2 "register_operand" ""))]
16782 UNSPEC_SINCOS_COS))
16783 (set (match_operand:XF 1 "register_operand" "")
16784 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16785 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16786 && !(reload_completed || reload_in_progress)"
16787 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16791 [(set (match_operand:XF 0 "register_operand" "")
16792 (unspec:XF [(float_extend:XF
16793 (match_operand:MODEF 2 "register_operand" ""))]
16794 UNSPEC_SINCOS_COS))
16795 (set (match_operand:XF 1 "register_operand" "")
16796 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16797 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16798 && !(reload_completed || reload_in_progress)"
16799 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16802 (define_expand "sincos<mode>3"
16803 [(use (match_operand:MODEF 0 "register_operand" ""))
16804 (use (match_operand:MODEF 1 "register_operand" ""))
16805 (use (match_operand:MODEF 2 "register_operand" ""))]
16806 "TARGET_USE_FANCY_MATH_387
16807 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16808 || TARGET_MIX_SSE_I387)
16809 && flag_unsafe_math_optimizations"
16811 rtx op0 = gen_reg_rtx (XFmode);
16812 rtx op1 = gen_reg_rtx (XFmode);
16814 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16815 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16816 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16820 (define_insn "fptanxf4_i387"
16821 [(set (match_operand:XF 0 "register_operand" "=f")
16822 (match_operand:XF 3 "const_double_operand" "F"))
16823 (set (match_operand:XF 1 "register_operand" "=u")
16824 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16826 "TARGET_USE_FANCY_MATH_387
16827 && flag_unsafe_math_optimizations
16828 && standard_80387_constant_p (operands[3]) == 2"
16830 [(set_attr "type" "fpspc")
16831 (set_attr "mode" "XF")])
16833 (define_insn "fptan_extend<mode>xf4_i387"
16834 [(set (match_operand:MODEF 0 "register_operand" "=f")
16835 (match_operand:MODEF 3 "const_double_operand" "F"))
16836 (set (match_operand:XF 1 "register_operand" "=u")
16837 (unspec:XF [(float_extend:XF
16838 (match_operand:MODEF 2 "register_operand" "0"))]
16840 "TARGET_USE_FANCY_MATH_387
16841 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16842 || TARGET_MIX_SSE_I387)
16843 && flag_unsafe_math_optimizations
16844 && standard_80387_constant_p (operands[3]) == 2"
16846 [(set_attr "type" "fpspc")
16847 (set_attr "mode" "XF")])
16849 (define_expand "tanxf2"
16850 [(use (match_operand:XF 0 "register_operand" ""))
16851 (use (match_operand:XF 1 "register_operand" ""))]
16852 "TARGET_USE_FANCY_MATH_387
16853 && flag_unsafe_math_optimizations"
16855 rtx one = gen_reg_rtx (XFmode);
16856 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16858 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16862 (define_expand "tan<mode>2"
16863 [(use (match_operand:MODEF 0 "register_operand" ""))
16864 (use (match_operand:MODEF 1 "register_operand" ""))]
16865 "TARGET_USE_FANCY_MATH_387
16866 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16867 || TARGET_MIX_SSE_I387)
16868 && flag_unsafe_math_optimizations"
16870 rtx op0 = gen_reg_rtx (XFmode);
16872 rtx one = gen_reg_rtx (<MODE>mode);
16873 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16875 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16876 operands[1], op2));
16877 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16881 (define_insn "*fpatanxf3_i387"
16882 [(set (match_operand:XF 0 "register_operand" "=f")
16883 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16884 (match_operand:XF 2 "register_operand" "u")]
16886 (clobber (match_scratch:XF 3 "=2"))]
16887 "TARGET_USE_FANCY_MATH_387
16888 && flag_unsafe_math_optimizations"
16890 [(set_attr "type" "fpspc")
16891 (set_attr "mode" "XF")])
16893 (define_insn "fpatan_extend<mode>xf3_i387"
16894 [(set (match_operand:XF 0 "register_operand" "=f")
16895 (unspec:XF [(float_extend:XF
16896 (match_operand:MODEF 1 "register_operand" "0"))
16898 (match_operand:MODEF 2 "register_operand" "u"))]
16900 (clobber (match_scratch:XF 3 "=2"))]
16901 "TARGET_USE_FANCY_MATH_387
16902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16903 || TARGET_MIX_SSE_I387)
16904 && flag_unsafe_math_optimizations"
16906 [(set_attr "type" "fpspc")
16907 (set_attr "mode" "XF")])
16909 (define_expand "atan2xf3"
16910 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16911 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16912 (match_operand:XF 1 "register_operand" "")]
16914 (clobber (match_scratch:XF 3 ""))])]
16915 "TARGET_USE_FANCY_MATH_387
16916 && flag_unsafe_math_optimizations"
16919 (define_expand "atan2<mode>3"
16920 [(use (match_operand:MODEF 0 "register_operand" ""))
16921 (use (match_operand:MODEF 1 "register_operand" ""))
16922 (use (match_operand:MODEF 2 "register_operand" ""))]
16923 "TARGET_USE_FANCY_MATH_387
16924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16925 || TARGET_MIX_SSE_I387)
16926 && flag_unsafe_math_optimizations"
16928 rtx op0 = gen_reg_rtx (XFmode);
16930 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16931 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16935 (define_expand "atanxf2"
16936 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16937 (unspec:XF [(match_dup 2)
16938 (match_operand:XF 1 "register_operand" "")]
16940 (clobber (match_scratch:XF 3 ""))])]
16941 "TARGET_USE_FANCY_MATH_387
16942 && flag_unsafe_math_optimizations"
16944 operands[2] = gen_reg_rtx (XFmode);
16945 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16948 (define_expand "atan<mode>2"
16949 [(use (match_operand:MODEF 0 "register_operand" ""))
16950 (use (match_operand:MODEF 1 "register_operand" ""))]
16951 "TARGET_USE_FANCY_MATH_387
16952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16953 || TARGET_MIX_SSE_I387)
16954 && flag_unsafe_math_optimizations"
16956 rtx op0 = gen_reg_rtx (XFmode);
16958 rtx op2 = gen_reg_rtx (<MODE>mode);
16959 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16961 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16962 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16966 (define_expand "asinxf2"
16967 [(set (match_dup 2)
16968 (mult:XF (match_operand:XF 1 "register_operand" "")
16970 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16971 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16972 (parallel [(set (match_operand:XF 0 "register_operand" "")
16973 (unspec:XF [(match_dup 5) (match_dup 1)]
16975 (clobber (match_scratch:XF 6 ""))])]
16976 "TARGET_USE_FANCY_MATH_387
16977 && flag_unsafe_math_optimizations && !optimize_size"
16981 for (i = 2; i < 6; i++)
16982 operands[i] = gen_reg_rtx (XFmode);
16984 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16987 (define_expand "asin<mode>2"
16988 [(use (match_operand:MODEF 0 "register_operand" ""))
16989 (use (match_operand:MODEF 1 "general_operand" ""))]
16990 "TARGET_USE_FANCY_MATH_387
16991 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16992 || TARGET_MIX_SSE_I387)
16993 && flag_unsafe_math_optimizations && !optimize_size"
16995 rtx op0 = gen_reg_rtx (XFmode);
16996 rtx op1 = gen_reg_rtx (XFmode);
16998 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16999 emit_insn (gen_asinxf2 (op0, op1));
17000 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17004 (define_expand "acosxf2"
17005 [(set (match_dup 2)
17006 (mult:XF (match_operand:XF 1 "register_operand" "")
17008 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17009 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17010 (parallel [(set (match_operand:XF 0 "register_operand" "")
17011 (unspec:XF [(match_dup 1) (match_dup 5)]
17013 (clobber (match_scratch:XF 6 ""))])]
17014 "TARGET_USE_FANCY_MATH_387
17015 && flag_unsafe_math_optimizations && !optimize_size"
17019 for (i = 2; i < 6; i++)
17020 operands[i] = gen_reg_rtx (XFmode);
17022 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17025 (define_expand "acos<mode>2"
17026 [(use (match_operand:MODEF 0 "register_operand" ""))
17027 (use (match_operand:MODEF 1 "general_operand" ""))]
17028 "TARGET_USE_FANCY_MATH_387
17029 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17030 || TARGET_MIX_SSE_I387)
17031 && flag_unsafe_math_optimizations && !optimize_size"
17033 rtx op0 = gen_reg_rtx (XFmode);
17034 rtx op1 = gen_reg_rtx (XFmode);
17036 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17037 emit_insn (gen_acosxf2 (op0, op1));
17038 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17042 (define_insn "fyl2xxf3_i387"
17043 [(set (match_operand:XF 0 "register_operand" "=f")
17044 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17045 (match_operand:XF 2 "register_operand" "u")]
17047 (clobber (match_scratch:XF 3 "=2"))]
17048 "TARGET_USE_FANCY_MATH_387
17049 && flag_unsafe_math_optimizations"
17051 [(set_attr "type" "fpspc")
17052 (set_attr "mode" "XF")])
17054 (define_insn "fyl2x_extend<mode>xf3_i387"
17055 [(set (match_operand:XF 0 "register_operand" "=f")
17056 (unspec:XF [(float_extend:XF
17057 (match_operand:MODEF 1 "register_operand" "0"))
17058 (match_operand:XF 2 "register_operand" "u")]
17060 (clobber (match_scratch:XF 3 "=2"))]
17061 "TARGET_USE_FANCY_MATH_387
17062 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17063 || TARGET_MIX_SSE_I387)
17064 && flag_unsafe_math_optimizations"
17066 [(set_attr "type" "fpspc")
17067 (set_attr "mode" "XF")])
17069 (define_expand "logxf2"
17070 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17071 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17072 (match_dup 2)] UNSPEC_FYL2X))
17073 (clobber (match_scratch:XF 3 ""))])]
17074 "TARGET_USE_FANCY_MATH_387
17075 && flag_unsafe_math_optimizations"
17077 operands[2] = gen_reg_rtx (XFmode);
17078 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17081 (define_expand "log<mode>2"
17082 [(use (match_operand:MODEF 0 "register_operand" ""))
17083 (use (match_operand:MODEF 1 "register_operand" ""))]
17084 "TARGET_USE_FANCY_MATH_387
17085 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17086 || TARGET_MIX_SSE_I387)
17087 && flag_unsafe_math_optimizations"
17089 rtx op0 = gen_reg_rtx (XFmode);
17091 rtx op2 = gen_reg_rtx (XFmode);
17092 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17094 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17095 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17099 (define_expand "log10xf2"
17100 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17101 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17102 (match_dup 2)] UNSPEC_FYL2X))
17103 (clobber (match_scratch:XF 3 ""))])]
17104 "TARGET_USE_FANCY_MATH_387
17105 && flag_unsafe_math_optimizations"
17107 operands[2] = gen_reg_rtx (XFmode);
17108 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17111 (define_expand "log10<mode>2"
17112 [(use (match_operand:MODEF 0 "register_operand" ""))
17113 (use (match_operand:MODEF 1 "register_operand" ""))]
17114 "TARGET_USE_FANCY_MATH_387
17115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17116 || TARGET_MIX_SSE_I387)
17117 && flag_unsafe_math_optimizations"
17119 rtx op0 = gen_reg_rtx (XFmode);
17121 rtx op2 = gen_reg_rtx (XFmode);
17122 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17124 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17125 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17129 (define_expand "log2xf2"
17130 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17131 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17132 (match_dup 2)] UNSPEC_FYL2X))
17133 (clobber (match_scratch:XF 3 ""))])]
17134 "TARGET_USE_FANCY_MATH_387
17135 && flag_unsafe_math_optimizations"
17137 operands[2] = gen_reg_rtx (XFmode);
17138 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17141 (define_expand "log2<mode>2"
17142 [(use (match_operand:MODEF 0 "register_operand" ""))
17143 (use (match_operand:MODEF 1 "register_operand" ""))]
17144 "TARGET_USE_FANCY_MATH_387
17145 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17146 || TARGET_MIX_SSE_I387)
17147 && flag_unsafe_math_optimizations"
17149 rtx op0 = gen_reg_rtx (XFmode);
17151 rtx op2 = gen_reg_rtx (XFmode);
17152 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17154 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17155 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17159 (define_insn "fyl2xp1xf3_i387"
17160 [(set (match_operand:XF 0 "register_operand" "=f")
17161 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17162 (match_operand:XF 2 "register_operand" "u")]
17164 (clobber (match_scratch:XF 3 "=2"))]
17165 "TARGET_USE_FANCY_MATH_387
17166 && flag_unsafe_math_optimizations"
17168 [(set_attr "type" "fpspc")
17169 (set_attr "mode" "XF")])
17171 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17172 [(set (match_operand:XF 0 "register_operand" "=f")
17173 (unspec:XF [(float_extend:XF
17174 (match_operand:MODEF 1 "register_operand" "0"))
17175 (match_operand:XF 2 "register_operand" "u")]
17177 (clobber (match_scratch:XF 3 "=2"))]
17178 "TARGET_USE_FANCY_MATH_387
17179 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17180 || TARGET_MIX_SSE_I387)
17181 && flag_unsafe_math_optimizations"
17183 [(set_attr "type" "fpspc")
17184 (set_attr "mode" "XF")])
17186 (define_expand "log1pxf2"
17187 [(use (match_operand:XF 0 "register_operand" ""))
17188 (use (match_operand:XF 1 "register_operand" ""))]
17189 "TARGET_USE_FANCY_MATH_387
17190 && flag_unsafe_math_optimizations && !optimize_size"
17192 ix86_emit_i387_log1p (operands[0], operands[1]);
17196 (define_expand "log1p<mode>2"
17197 [(use (match_operand:MODEF 0 "register_operand" ""))
17198 (use (match_operand:MODEF 1 "register_operand" ""))]
17199 "TARGET_USE_FANCY_MATH_387
17200 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17201 || TARGET_MIX_SSE_I387)
17202 && flag_unsafe_math_optimizations && !optimize_size"
17204 rtx op0 = gen_reg_rtx (XFmode);
17206 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17208 ix86_emit_i387_log1p (op0, operands[1]);
17209 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17213 (define_insn "fxtractxf3_i387"
17214 [(set (match_operand:XF 0 "register_operand" "=f")
17215 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17216 UNSPEC_XTRACT_FRACT))
17217 (set (match_operand:XF 1 "register_operand" "=u")
17218 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17219 "TARGET_USE_FANCY_MATH_387
17220 && flag_unsafe_math_optimizations"
17222 [(set_attr "type" "fpspc")
17223 (set_attr "mode" "XF")])
17225 (define_insn "fxtract_extend<mode>xf3_i387"
17226 [(set (match_operand:XF 0 "register_operand" "=f")
17227 (unspec:XF [(float_extend:XF
17228 (match_operand:MODEF 2 "register_operand" "0"))]
17229 UNSPEC_XTRACT_FRACT))
17230 (set (match_operand:XF 1 "register_operand" "=u")
17231 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17232 "TARGET_USE_FANCY_MATH_387
17233 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17234 || TARGET_MIX_SSE_I387)
17235 && flag_unsafe_math_optimizations"
17237 [(set_attr "type" "fpspc")
17238 (set_attr "mode" "XF")])
17240 (define_expand "logbxf2"
17241 [(parallel [(set (match_dup 2)
17242 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17243 UNSPEC_XTRACT_FRACT))
17244 (set (match_operand:XF 0 "register_operand" "")
17245 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17246 "TARGET_USE_FANCY_MATH_387
17247 && flag_unsafe_math_optimizations"
17249 operands[2] = gen_reg_rtx (XFmode);
17252 (define_expand "logb<mode>2"
17253 [(use (match_operand:MODEF 0 "register_operand" ""))
17254 (use (match_operand:MODEF 1 "register_operand" ""))]
17255 "TARGET_USE_FANCY_MATH_387
17256 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17257 || TARGET_MIX_SSE_I387)
17258 && flag_unsafe_math_optimizations"
17260 rtx op0 = gen_reg_rtx (XFmode);
17261 rtx op1 = gen_reg_rtx (XFmode);
17263 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17264 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17268 (define_expand "ilogbxf2"
17269 [(use (match_operand:SI 0 "register_operand" ""))
17270 (use (match_operand:XF 1 "register_operand" ""))]
17271 "TARGET_USE_FANCY_MATH_387
17272 && flag_unsafe_math_optimizations && !optimize_size"
17274 rtx op0 = gen_reg_rtx (XFmode);
17275 rtx op1 = gen_reg_rtx (XFmode);
17277 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17278 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17282 (define_expand "ilogb<mode>2"
17283 [(use (match_operand:SI 0 "register_operand" ""))
17284 (use (match_operand:MODEF 1 "register_operand" ""))]
17285 "TARGET_USE_FANCY_MATH_387
17286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17287 || TARGET_MIX_SSE_I387)
17288 && flag_unsafe_math_optimizations && !optimize_size"
17290 rtx op0 = gen_reg_rtx (XFmode);
17291 rtx op1 = gen_reg_rtx (XFmode);
17293 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17294 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17298 (define_insn "*f2xm1xf2_i387"
17299 [(set (match_operand:XF 0 "register_operand" "=f")
17300 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17302 "TARGET_USE_FANCY_MATH_387
17303 && flag_unsafe_math_optimizations"
17305 [(set_attr "type" "fpspc")
17306 (set_attr "mode" "XF")])
17308 (define_insn "*fscalexf4_i387"
17309 [(set (match_operand:XF 0 "register_operand" "=f")
17310 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17311 (match_operand:XF 3 "register_operand" "1")]
17312 UNSPEC_FSCALE_FRACT))
17313 (set (match_operand:XF 1 "register_operand" "=u")
17314 (unspec:XF [(match_dup 2) (match_dup 3)]
17315 UNSPEC_FSCALE_EXP))]
17316 "TARGET_USE_FANCY_MATH_387
17317 && flag_unsafe_math_optimizations"
17319 [(set_attr "type" "fpspc")
17320 (set_attr "mode" "XF")])
17322 (define_expand "expNcorexf3"
17323 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17324 (match_operand:XF 2 "register_operand" "")))
17325 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17326 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17327 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17328 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17329 (parallel [(set (match_operand:XF 0 "register_operand" "")
17330 (unspec:XF [(match_dup 8) (match_dup 4)]
17331 UNSPEC_FSCALE_FRACT))
17333 (unspec:XF [(match_dup 8) (match_dup 4)]
17334 UNSPEC_FSCALE_EXP))])]
17335 "TARGET_USE_FANCY_MATH_387
17336 && flag_unsafe_math_optimizations && !optimize_size"
17340 for (i = 3; i < 10; i++)
17341 operands[i] = gen_reg_rtx (XFmode);
17343 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17346 (define_expand "expxf2"
17347 [(use (match_operand:XF 0 "register_operand" ""))
17348 (use (match_operand:XF 1 "register_operand" ""))]
17349 "TARGET_USE_FANCY_MATH_387
17350 && flag_unsafe_math_optimizations && !optimize_size"
17352 rtx op2 = gen_reg_rtx (XFmode);
17353 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17355 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17359 (define_expand "exp<mode>2"
17360 [(use (match_operand:MODEF 0 "register_operand" ""))
17361 (use (match_operand:MODEF 1 "general_operand" ""))]
17362 "TARGET_USE_FANCY_MATH_387
17363 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17364 || TARGET_MIX_SSE_I387)
17365 && flag_unsafe_math_optimizations && !optimize_size"
17367 rtx op0 = gen_reg_rtx (XFmode);
17368 rtx op1 = gen_reg_rtx (XFmode);
17370 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17371 emit_insn (gen_expxf2 (op0, op1));
17372 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17376 (define_expand "exp10xf2"
17377 [(use (match_operand:XF 0 "register_operand" ""))
17378 (use (match_operand:XF 1 "register_operand" ""))]
17379 "TARGET_USE_FANCY_MATH_387
17380 && flag_unsafe_math_optimizations && !optimize_size"
17382 rtx op2 = gen_reg_rtx (XFmode);
17383 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17385 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17389 (define_expand "exp10<mode>2"
17390 [(use (match_operand:MODEF 0 "register_operand" ""))
17391 (use (match_operand:MODEF 1 "general_operand" ""))]
17392 "TARGET_USE_FANCY_MATH_387
17393 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17394 || TARGET_MIX_SSE_I387)
17395 && flag_unsafe_math_optimizations && !optimize_size"
17397 rtx op0 = gen_reg_rtx (XFmode);
17398 rtx op1 = gen_reg_rtx (XFmode);
17400 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17401 emit_insn (gen_exp10xf2 (op0, op1));
17402 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17406 (define_expand "exp2xf2"
17407 [(use (match_operand:XF 0 "register_operand" ""))
17408 (use (match_operand:XF 1 "register_operand" ""))]
17409 "TARGET_USE_FANCY_MATH_387
17410 && flag_unsafe_math_optimizations && !optimize_size"
17412 rtx op2 = gen_reg_rtx (XFmode);
17413 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17415 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17419 (define_expand "exp2<mode>2"
17420 [(use (match_operand:MODEF 0 "register_operand" ""))
17421 (use (match_operand:MODEF 1 "general_operand" ""))]
17422 "TARGET_USE_FANCY_MATH_387
17423 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17424 || TARGET_MIX_SSE_I387)
17425 && flag_unsafe_math_optimizations && !optimize_size"
17427 rtx op0 = gen_reg_rtx (XFmode);
17428 rtx op1 = gen_reg_rtx (XFmode);
17430 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17431 emit_insn (gen_exp2xf2 (op0, op1));
17432 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17436 (define_expand "expm1xf2"
17437 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17439 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17440 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17441 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17442 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17443 (parallel [(set (match_dup 7)
17444 (unspec:XF [(match_dup 6) (match_dup 4)]
17445 UNSPEC_FSCALE_FRACT))
17447 (unspec:XF [(match_dup 6) (match_dup 4)]
17448 UNSPEC_FSCALE_EXP))])
17449 (parallel [(set (match_dup 10)
17450 (unspec:XF [(match_dup 9) (match_dup 8)]
17451 UNSPEC_FSCALE_FRACT))
17452 (set (match_dup 11)
17453 (unspec:XF [(match_dup 9) (match_dup 8)]
17454 UNSPEC_FSCALE_EXP))])
17455 (set (match_dup 12) (minus:XF (match_dup 10)
17456 (float_extend:XF (match_dup 13))))
17457 (set (match_operand:XF 0 "register_operand" "")
17458 (plus:XF (match_dup 12) (match_dup 7)))]
17459 "TARGET_USE_FANCY_MATH_387
17460 && flag_unsafe_math_optimizations && !optimize_size"
17464 for (i = 2; i < 13; i++)
17465 operands[i] = gen_reg_rtx (XFmode);
17468 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17470 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17473 (define_expand "expm1<mode>2"
17474 [(use (match_operand:MODEF 0 "register_operand" ""))
17475 (use (match_operand:MODEF 1 "general_operand" ""))]
17476 "TARGET_USE_FANCY_MATH_387
17477 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17478 || TARGET_MIX_SSE_I387)
17479 && flag_unsafe_math_optimizations && !optimize_size"
17481 rtx op0 = gen_reg_rtx (XFmode);
17482 rtx op1 = gen_reg_rtx (XFmode);
17484 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17485 emit_insn (gen_expm1xf2 (op0, op1));
17486 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17490 (define_expand "ldexpxf3"
17491 [(set (match_dup 3)
17492 (float:XF (match_operand:SI 2 "register_operand" "")))
17493 (parallel [(set (match_operand:XF 0 " register_operand" "")
17494 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17496 UNSPEC_FSCALE_FRACT))
17498 (unspec:XF [(match_dup 1) (match_dup 3)]
17499 UNSPEC_FSCALE_EXP))])]
17500 "TARGET_USE_FANCY_MATH_387
17501 && flag_unsafe_math_optimizations && !optimize_size"
17503 operands[3] = gen_reg_rtx (XFmode);
17504 operands[4] = gen_reg_rtx (XFmode);
17507 (define_expand "ldexp<mode>3"
17508 [(use (match_operand:MODEF 0 "register_operand" ""))
17509 (use (match_operand:MODEF 1 "general_operand" ""))
17510 (use (match_operand:SI 2 "register_operand" ""))]
17511 "TARGET_USE_FANCY_MATH_387
17512 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17513 || TARGET_MIX_SSE_I387)
17514 && flag_unsafe_math_optimizations && !optimize_size"
17516 rtx op0 = gen_reg_rtx (XFmode);
17517 rtx op1 = gen_reg_rtx (XFmode);
17519 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17520 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17521 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17525 (define_expand "scalbxf3"
17526 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17527 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17528 (match_operand:XF 2 "register_operand" "")]
17529 UNSPEC_FSCALE_FRACT))
17531 (unspec:XF [(match_dup 1) (match_dup 2)]
17532 UNSPEC_FSCALE_EXP))])]
17533 "TARGET_USE_FANCY_MATH_387
17534 && flag_unsafe_math_optimizations && !optimize_size"
17536 operands[3] = gen_reg_rtx (XFmode);
17539 (define_expand "scalb<mode>3"
17540 [(use (match_operand:MODEF 0 "register_operand" ""))
17541 (use (match_operand:MODEF 1 "general_operand" ""))
17542 (use (match_operand:MODEF 2 "register_operand" ""))]
17543 "TARGET_USE_FANCY_MATH_387
17544 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17545 || TARGET_MIX_SSE_I387)
17546 && flag_unsafe_math_optimizations && !optimize_size"
17548 rtx op0 = gen_reg_rtx (XFmode);
17549 rtx op1 = gen_reg_rtx (XFmode);
17550 rtx op2 = gen_reg_rtx (XFmode);
17552 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17553 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17554 emit_insn (gen_scalbxf3 (op0, op1, op2));
17555 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17560 (define_insn "sse4_1_round<mode>2"
17561 [(set (match_operand:MODEF 0 "register_operand" "=x")
17562 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17563 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17566 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17567 [(set_attr "type" "ssecvt")
17568 (set_attr "prefix_extra" "1")
17569 (set_attr "mode" "<MODE>")])
17571 (define_insn "rintxf2"
17572 [(set (match_operand:XF 0 "register_operand" "=f")
17573 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17575 "TARGET_USE_FANCY_MATH_387
17576 && flag_unsafe_math_optimizations"
17578 [(set_attr "type" "fpspc")
17579 (set_attr "mode" "XF")])
17581 (define_expand "rint<mode>2"
17582 [(use (match_operand:MODEF 0 "register_operand" ""))
17583 (use (match_operand:MODEF 1 "register_operand" ""))]
17584 "(TARGET_USE_FANCY_MATH_387
17585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17586 || TARGET_MIX_SSE_I387)
17587 && flag_unsafe_math_optimizations)
17588 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17589 && !flag_trapping_math
17590 && (TARGET_ROUND || !optimize_size))"
17592 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17593 && !flag_trapping_math
17594 && (TARGET_ROUND || !optimize_size))
17597 emit_insn (gen_sse4_1_round<mode>2
17598 (operands[0], operands[1], GEN_INT (0x04)));
17600 ix86_expand_rint (operand0, operand1);
17604 rtx op0 = gen_reg_rtx (XFmode);
17605 rtx op1 = gen_reg_rtx (XFmode);
17607 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17608 emit_insn (gen_rintxf2 (op0, op1));
17610 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17615 (define_expand "round<mode>2"
17616 [(match_operand:MODEF 0 "register_operand" "")
17617 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17618 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17619 && !flag_trapping_math && !flag_rounding_math
17622 if (TARGET_64BIT || (<MODE>mode != DFmode))
17623 ix86_expand_round (operand0, operand1);
17625 ix86_expand_rounddf_32 (operand0, operand1);
17629 (define_insn_and_split "*fistdi2_1"
17630 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17631 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17633 "TARGET_USE_FANCY_MATH_387
17634 && !(reload_completed || reload_in_progress)"
17639 if (memory_operand (operands[0], VOIDmode))
17640 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17643 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17644 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17649 [(set_attr "type" "fpspc")
17650 (set_attr "mode" "DI")])
17652 (define_insn "fistdi2"
17653 [(set (match_operand:DI 0 "memory_operand" "=m")
17654 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17656 (clobber (match_scratch:XF 2 "=&1f"))]
17657 "TARGET_USE_FANCY_MATH_387"
17658 "* return output_fix_trunc (insn, operands, 0);"
17659 [(set_attr "type" "fpspc")
17660 (set_attr "mode" "DI")])
17662 (define_insn "fistdi2_with_temp"
17663 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17664 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17666 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17667 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17668 "TARGET_USE_FANCY_MATH_387"
17670 [(set_attr "type" "fpspc")
17671 (set_attr "mode" "DI")])
17674 [(set (match_operand:DI 0 "register_operand" "")
17675 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17677 (clobber (match_operand:DI 2 "memory_operand" ""))
17678 (clobber (match_scratch 3 ""))]
17680 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17681 (clobber (match_dup 3))])
17682 (set (match_dup 0) (match_dup 2))]
17686 [(set (match_operand:DI 0 "memory_operand" "")
17687 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17689 (clobber (match_operand:DI 2 "memory_operand" ""))
17690 (clobber (match_scratch 3 ""))]
17692 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17693 (clobber (match_dup 3))])]
17696 (define_insn_and_split "*fist<mode>2_1"
17697 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17698 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17700 "TARGET_USE_FANCY_MATH_387
17701 && !(reload_completed || reload_in_progress)"
17706 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17707 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17711 [(set_attr "type" "fpspc")
17712 (set_attr "mode" "<MODE>")])
17714 (define_insn "fist<mode>2"
17715 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17716 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17718 "TARGET_USE_FANCY_MATH_387"
17719 "* return output_fix_trunc (insn, operands, 0);"
17720 [(set_attr "type" "fpspc")
17721 (set_attr "mode" "<MODE>")])
17723 (define_insn "fist<mode>2_with_temp"
17724 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17725 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17727 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17728 "TARGET_USE_FANCY_MATH_387"
17730 [(set_attr "type" "fpspc")
17731 (set_attr "mode" "<MODE>")])
17734 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17735 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17737 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17739 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17740 (set (match_dup 0) (match_dup 2))]
17744 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17745 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17747 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17749 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17752 (define_expand "lrintxf<mode>2"
17753 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17754 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17756 "TARGET_USE_FANCY_MATH_387"
17759 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17760 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17761 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17762 UNSPEC_FIX_NOTRUNC))]
17763 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17764 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17767 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17768 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17769 (match_operand:MODEF 1 "register_operand" "")]
17770 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17771 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17772 && !flag_trapping_math && !flag_rounding_math
17775 ix86_expand_lround (operand0, operand1);
17779 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17780 (define_insn_and_split "frndintxf2_floor"
17781 [(set (match_operand:XF 0 "register_operand" "")
17782 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17783 UNSPEC_FRNDINT_FLOOR))
17784 (clobber (reg:CC FLAGS_REG))]
17785 "TARGET_USE_FANCY_MATH_387
17786 && flag_unsafe_math_optimizations
17787 && !(reload_completed || reload_in_progress)"
17792 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17794 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17795 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17797 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17798 operands[2], operands[3]));
17801 [(set_attr "type" "frndint")
17802 (set_attr "i387_cw" "floor")
17803 (set_attr "mode" "XF")])
17805 (define_insn "frndintxf2_floor_i387"
17806 [(set (match_operand:XF 0 "register_operand" "=f")
17807 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17808 UNSPEC_FRNDINT_FLOOR))
17809 (use (match_operand:HI 2 "memory_operand" "m"))
17810 (use (match_operand:HI 3 "memory_operand" "m"))]
17811 "TARGET_USE_FANCY_MATH_387
17812 && flag_unsafe_math_optimizations"
17813 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17814 [(set_attr "type" "frndint")
17815 (set_attr "i387_cw" "floor")
17816 (set_attr "mode" "XF")])
17818 (define_expand "floorxf2"
17819 [(use (match_operand:XF 0 "register_operand" ""))
17820 (use (match_operand:XF 1 "register_operand" ""))]
17821 "TARGET_USE_FANCY_MATH_387
17822 && flag_unsafe_math_optimizations && !optimize_size"
17824 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17828 (define_expand "floor<mode>2"
17829 [(use (match_operand:MODEF 0 "register_operand" ""))
17830 (use (match_operand:MODEF 1 "register_operand" ""))]
17831 "(TARGET_USE_FANCY_MATH_387
17832 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17833 || TARGET_MIX_SSE_I387)
17834 && flag_unsafe_math_optimizations && !optimize_size)
17835 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17836 && !flag_trapping_math
17837 && (TARGET_ROUND || !optimize_size))"
17839 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17840 && !flag_trapping_math
17841 && (TARGET_ROUND || !optimize_size))
17844 emit_insn (gen_sse4_1_round<mode>2
17845 (operands[0], operands[1], GEN_INT (0x01)));
17846 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17847 ix86_expand_floorceil (operand0, operand1, true);
17849 ix86_expand_floorceildf_32 (operand0, operand1, true);
17853 rtx op0 = gen_reg_rtx (XFmode);
17854 rtx op1 = gen_reg_rtx (XFmode);
17856 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17857 emit_insn (gen_frndintxf2_floor (op0, op1));
17859 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17864 (define_insn_and_split "*fist<mode>2_floor_1"
17865 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17866 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17867 UNSPEC_FIST_FLOOR))
17868 (clobber (reg:CC FLAGS_REG))]
17869 "TARGET_USE_FANCY_MATH_387
17870 && flag_unsafe_math_optimizations
17871 && !(reload_completed || reload_in_progress)"
17876 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17878 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17879 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17880 if (memory_operand (operands[0], VOIDmode))
17881 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17882 operands[2], operands[3]));
17885 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17886 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17887 operands[2], operands[3],
17892 [(set_attr "type" "fistp")
17893 (set_attr "i387_cw" "floor")
17894 (set_attr "mode" "<MODE>")])
17896 (define_insn "fistdi2_floor"
17897 [(set (match_operand:DI 0 "memory_operand" "=m")
17898 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17899 UNSPEC_FIST_FLOOR))
17900 (use (match_operand:HI 2 "memory_operand" "m"))
17901 (use (match_operand:HI 3 "memory_operand" "m"))
17902 (clobber (match_scratch:XF 4 "=&1f"))]
17903 "TARGET_USE_FANCY_MATH_387
17904 && flag_unsafe_math_optimizations"
17905 "* return output_fix_trunc (insn, operands, 0);"
17906 [(set_attr "type" "fistp")
17907 (set_attr "i387_cw" "floor")
17908 (set_attr "mode" "DI")])
17910 (define_insn "fistdi2_floor_with_temp"
17911 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17912 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17913 UNSPEC_FIST_FLOOR))
17914 (use (match_operand:HI 2 "memory_operand" "m,m"))
17915 (use (match_operand:HI 3 "memory_operand" "m,m"))
17916 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17917 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17918 "TARGET_USE_FANCY_MATH_387
17919 && flag_unsafe_math_optimizations"
17921 [(set_attr "type" "fistp")
17922 (set_attr "i387_cw" "floor")
17923 (set_attr "mode" "DI")])
17926 [(set (match_operand:DI 0 "register_operand" "")
17927 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17928 UNSPEC_FIST_FLOOR))
17929 (use (match_operand:HI 2 "memory_operand" ""))
17930 (use (match_operand:HI 3 "memory_operand" ""))
17931 (clobber (match_operand:DI 4 "memory_operand" ""))
17932 (clobber (match_scratch 5 ""))]
17934 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17935 (use (match_dup 2))
17936 (use (match_dup 3))
17937 (clobber (match_dup 5))])
17938 (set (match_dup 0) (match_dup 4))]
17942 [(set (match_operand:DI 0 "memory_operand" "")
17943 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17944 UNSPEC_FIST_FLOOR))
17945 (use (match_operand:HI 2 "memory_operand" ""))
17946 (use (match_operand:HI 3 "memory_operand" ""))
17947 (clobber (match_operand:DI 4 "memory_operand" ""))
17948 (clobber (match_scratch 5 ""))]
17950 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17951 (use (match_dup 2))
17952 (use (match_dup 3))
17953 (clobber (match_dup 5))])]
17956 (define_insn "fist<mode>2_floor"
17957 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17958 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17959 UNSPEC_FIST_FLOOR))
17960 (use (match_operand:HI 2 "memory_operand" "m"))
17961 (use (match_operand:HI 3 "memory_operand" "m"))]
17962 "TARGET_USE_FANCY_MATH_387
17963 && flag_unsafe_math_optimizations"
17964 "* return output_fix_trunc (insn, operands, 0);"
17965 [(set_attr "type" "fistp")
17966 (set_attr "i387_cw" "floor")
17967 (set_attr "mode" "<MODE>")])
17969 (define_insn "fist<mode>2_floor_with_temp"
17970 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17971 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17972 UNSPEC_FIST_FLOOR))
17973 (use (match_operand:HI 2 "memory_operand" "m,m"))
17974 (use (match_operand:HI 3 "memory_operand" "m,m"))
17975 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17976 "TARGET_USE_FANCY_MATH_387
17977 && flag_unsafe_math_optimizations"
17979 [(set_attr "type" "fistp")
17980 (set_attr "i387_cw" "floor")
17981 (set_attr "mode" "<MODE>")])
17984 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17985 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17986 UNSPEC_FIST_FLOOR))
17987 (use (match_operand:HI 2 "memory_operand" ""))
17988 (use (match_operand:HI 3 "memory_operand" ""))
17989 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17991 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17992 UNSPEC_FIST_FLOOR))
17993 (use (match_dup 2))
17994 (use (match_dup 3))])
17995 (set (match_dup 0) (match_dup 4))]
17999 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18000 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18001 UNSPEC_FIST_FLOOR))
18002 (use (match_operand:HI 2 "memory_operand" ""))
18003 (use (match_operand:HI 3 "memory_operand" ""))
18004 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18006 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18007 UNSPEC_FIST_FLOOR))
18008 (use (match_dup 2))
18009 (use (match_dup 3))])]
18012 (define_expand "lfloorxf<mode>2"
18013 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18014 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18015 UNSPEC_FIST_FLOOR))
18016 (clobber (reg:CC FLAGS_REG))])]
18017 "TARGET_USE_FANCY_MATH_387
18018 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18019 && flag_unsafe_math_optimizations"
18022 (define_expand "lfloor<mode>di2"
18023 [(match_operand:DI 0 "nonimmediate_operand" "")
18024 (match_operand:MODEF 1 "register_operand" "")]
18025 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18026 && !flag_trapping_math
18029 ix86_expand_lfloorceil (operand0, operand1, true);
18033 (define_expand "lfloor<mode>si2"
18034 [(match_operand:SI 0 "nonimmediate_operand" "")
18035 (match_operand:MODEF 1 "register_operand" "")]
18036 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18037 && !flag_trapping_math
18038 && (!optimize_size || !TARGET_64BIT)"
18040 ix86_expand_lfloorceil (operand0, operand1, true);
18044 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18045 (define_insn_and_split "frndintxf2_ceil"
18046 [(set (match_operand:XF 0 "register_operand" "")
18047 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18048 UNSPEC_FRNDINT_CEIL))
18049 (clobber (reg:CC FLAGS_REG))]
18050 "TARGET_USE_FANCY_MATH_387
18051 && flag_unsafe_math_optimizations
18052 && !(reload_completed || reload_in_progress)"
18057 ix86_optimize_mode_switching[I387_CEIL] = 1;
18059 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18060 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18062 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18063 operands[2], operands[3]));
18066 [(set_attr "type" "frndint")
18067 (set_attr "i387_cw" "ceil")
18068 (set_attr "mode" "XF")])
18070 (define_insn "frndintxf2_ceil_i387"
18071 [(set (match_operand:XF 0 "register_operand" "=f")
18072 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18073 UNSPEC_FRNDINT_CEIL))
18074 (use (match_operand:HI 2 "memory_operand" "m"))
18075 (use (match_operand:HI 3 "memory_operand" "m"))]
18076 "TARGET_USE_FANCY_MATH_387
18077 && flag_unsafe_math_optimizations"
18078 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18079 [(set_attr "type" "frndint")
18080 (set_attr "i387_cw" "ceil")
18081 (set_attr "mode" "XF")])
18083 (define_expand "ceilxf2"
18084 [(use (match_operand:XF 0 "register_operand" ""))
18085 (use (match_operand:XF 1 "register_operand" ""))]
18086 "TARGET_USE_FANCY_MATH_387
18087 && flag_unsafe_math_optimizations && !optimize_size"
18089 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18093 (define_expand "ceil<mode>2"
18094 [(use (match_operand:MODEF 0 "register_operand" ""))
18095 (use (match_operand:MODEF 1 "register_operand" ""))]
18096 "(TARGET_USE_FANCY_MATH_387
18097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18098 || TARGET_MIX_SSE_I387)
18099 && flag_unsafe_math_optimizations && !optimize_size)
18100 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18101 && !flag_trapping_math
18102 && (TARGET_ROUND || !optimize_size))"
18104 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18105 && !flag_trapping_math
18106 && (TARGET_ROUND || !optimize_size))
18109 emit_insn (gen_sse4_1_round<mode>2
18110 (operands[0], operands[1], GEN_INT (0x02)));
18111 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18112 ix86_expand_floorceil (operand0, operand1, false);
18114 ix86_expand_floorceildf_32 (operand0, operand1, false);
18118 rtx op0 = gen_reg_rtx (XFmode);
18119 rtx op1 = gen_reg_rtx (XFmode);
18121 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18122 emit_insn (gen_frndintxf2_ceil (op0, op1));
18124 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18129 (define_insn_and_split "*fist<mode>2_ceil_1"
18130 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18131 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18133 (clobber (reg:CC FLAGS_REG))]
18134 "TARGET_USE_FANCY_MATH_387
18135 && flag_unsafe_math_optimizations
18136 && !(reload_completed || reload_in_progress)"
18141 ix86_optimize_mode_switching[I387_CEIL] = 1;
18143 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18144 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18145 if (memory_operand (operands[0], VOIDmode))
18146 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18147 operands[2], operands[3]));
18150 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18151 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18152 operands[2], operands[3],
18157 [(set_attr "type" "fistp")
18158 (set_attr "i387_cw" "ceil")
18159 (set_attr "mode" "<MODE>")])
18161 (define_insn "fistdi2_ceil"
18162 [(set (match_operand:DI 0 "memory_operand" "=m")
18163 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18165 (use (match_operand:HI 2 "memory_operand" "m"))
18166 (use (match_operand:HI 3 "memory_operand" "m"))
18167 (clobber (match_scratch:XF 4 "=&1f"))]
18168 "TARGET_USE_FANCY_MATH_387
18169 && flag_unsafe_math_optimizations"
18170 "* return output_fix_trunc (insn, operands, 0);"
18171 [(set_attr "type" "fistp")
18172 (set_attr "i387_cw" "ceil")
18173 (set_attr "mode" "DI")])
18175 (define_insn "fistdi2_ceil_with_temp"
18176 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18177 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18179 (use (match_operand:HI 2 "memory_operand" "m,m"))
18180 (use (match_operand:HI 3 "memory_operand" "m,m"))
18181 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18182 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18183 "TARGET_USE_FANCY_MATH_387
18184 && flag_unsafe_math_optimizations"
18186 [(set_attr "type" "fistp")
18187 (set_attr "i387_cw" "ceil")
18188 (set_attr "mode" "DI")])
18191 [(set (match_operand:DI 0 "register_operand" "")
18192 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18194 (use (match_operand:HI 2 "memory_operand" ""))
18195 (use (match_operand:HI 3 "memory_operand" ""))
18196 (clobber (match_operand:DI 4 "memory_operand" ""))
18197 (clobber (match_scratch 5 ""))]
18199 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18200 (use (match_dup 2))
18201 (use (match_dup 3))
18202 (clobber (match_dup 5))])
18203 (set (match_dup 0) (match_dup 4))]
18207 [(set (match_operand:DI 0 "memory_operand" "")
18208 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18210 (use (match_operand:HI 2 "memory_operand" ""))
18211 (use (match_operand:HI 3 "memory_operand" ""))
18212 (clobber (match_operand:DI 4 "memory_operand" ""))
18213 (clobber (match_scratch 5 ""))]
18215 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18216 (use (match_dup 2))
18217 (use (match_dup 3))
18218 (clobber (match_dup 5))])]
18221 (define_insn "fist<mode>2_ceil"
18222 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18223 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18225 (use (match_operand:HI 2 "memory_operand" "m"))
18226 (use (match_operand:HI 3 "memory_operand" "m"))]
18227 "TARGET_USE_FANCY_MATH_387
18228 && flag_unsafe_math_optimizations"
18229 "* return output_fix_trunc (insn, operands, 0);"
18230 [(set_attr "type" "fistp")
18231 (set_attr "i387_cw" "ceil")
18232 (set_attr "mode" "<MODE>")])
18234 (define_insn "fist<mode>2_ceil_with_temp"
18235 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18236 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18238 (use (match_operand:HI 2 "memory_operand" "m,m"))
18239 (use (match_operand:HI 3 "memory_operand" "m,m"))
18240 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18241 "TARGET_USE_FANCY_MATH_387
18242 && flag_unsafe_math_optimizations"
18244 [(set_attr "type" "fistp")
18245 (set_attr "i387_cw" "ceil")
18246 (set_attr "mode" "<MODE>")])
18249 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18250 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18252 (use (match_operand:HI 2 "memory_operand" ""))
18253 (use (match_operand:HI 3 "memory_operand" ""))
18254 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18256 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18258 (use (match_dup 2))
18259 (use (match_dup 3))])
18260 (set (match_dup 0) (match_dup 4))]
18264 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18265 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18267 (use (match_operand:HI 2 "memory_operand" ""))
18268 (use (match_operand:HI 3 "memory_operand" ""))
18269 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18271 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18273 (use (match_dup 2))
18274 (use (match_dup 3))])]
18277 (define_expand "lceilxf<mode>2"
18278 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18279 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18281 (clobber (reg:CC FLAGS_REG))])]
18282 "TARGET_USE_FANCY_MATH_387
18283 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18284 && flag_unsafe_math_optimizations"
18287 (define_expand "lceil<mode>di2"
18288 [(match_operand:DI 0 "nonimmediate_operand" "")
18289 (match_operand:MODEF 1 "register_operand" "")]
18290 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18291 && !flag_trapping_math"
18293 ix86_expand_lfloorceil (operand0, operand1, false);
18297 (define_expand "lceil<mode>si2"
18298 [(match_operand:SI 0 "nonimmediate_operand" "")
18299 (match_operand:MODEF 1 "register_operand" "")]
18300 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18301 && !flag_trapping_math"
18303 ix86_expand_lfloorceil (operand0, operand1, false);
18307 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18308 (define_insn_and_split "frndintxf2_trunc"
18309 [(set (match_operand:XF 0 "register_operand" "")
18310 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18311 UNSPEC_FRNDINT_TRUNC))
18312 (clobber (reg:CC FLAGS_REG))]
18313 "TARGET_USE_FANCY_MATH_387
18314 && flag_unsafe_math_optimizations
18315 && !(reload_completed || reload_in_progress)"
18320 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18322 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18323 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18325 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18326 operands[2], operands[3]));
18329 [(set_attr "type" "frndint")
18330 (set_attr "i387_cw" "trunc")
18331 (set_attr "mode" "XF")])
18333 (define_insn "frndintxf2_trunc_i387"
18334 [(set (match_operand:XF 0 "register_operand" "=f")
18335 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18336 UNSPEC_FRNDINT_TRUNC))
18337 (use (match_operand:HI 2 "memory_operand" "m"))
18338 (use (match_operand:HI 3 "memory_operand" "m"))]
18339 "TARGET_USE_FANCY_MATH_387
18340 && flag_unsafe_math_optimizations"
18341 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18342 [(set_attr "type" "frndint")
18343 (set_attr "i387_cw" "trunc")
18344 (set_attr "mode" "XF")])
18346 (define_expand "btruncxf2"
18347 [(use (match_operand:XF 0 "register_operand" ""))
18348 (use (match_operand:XF 1 "register_operand" ""))]
18349 "TARGET_USE_FANCY_MATH_387
18350 && flag_unsafe_math_optimizations && !optimize_size"
18352 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18356 (define_expand "btrunc<mode>2"
18357 [(use (match_operand:MODEF 0 "register_operand" ""))
18358 (use (match_operand:MODEF 1 "register_operand" ""))]
18359 "(TARGET_USE_FANCY_MATH_387
18360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18361 || TARGET_MIX_SSE_I387)
18362 && flag_unsafe_math_optimizations && !optimize_size)
18363 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18364 && !flag_trapping_math
18365 && (TARGET_ROUND || !optimize_size))"
18367 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18368 && !flag_trapping_math
18369 && (TARGET_ROUND || !optimize_size))
18372 emit_insn (gen_sse4_1_round<mode>2
18373 (operands[0], operands[1], GEN_INT (0x03)));
18374 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18375 ix86_expand_trunc (operand0, operand1);
18377 ix86_expand_truncdf_32 (operand0, operand1);
18381 rtx op0 = gen_reg_rtx (XFmode);
18382 rtx op1 = gen_reg_rtx (XFmode);
18384 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18385 emit_insn (gen_frndintxf2_trunc (op0, op1));
18387 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18392 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18393 (define_insn_and_split "frndintxf2_mask_pm"
18394 [(set (match_operand:XF 0 "register_operand" "")
18395 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18396 UNSPEC_FRNDINT_MASK_PM))
18397 (clobber (reg:CC FLAGS_REG))]
18398 "TARGET_USE_FANCY_MATH_387
18399 && flag_unsafe_math_optimizations
18400 && !(reload_completed || reload_in_progress)"
18405 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18407 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18408 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18410 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18411 operands[2], operands[3]));
18414 [(set_attr "type" "frndint")
18415 (set_attr "i387_cw" "mask_pm")
18416 (set_attr "mode" "XF")])
18418 (define_insn "frndintxf2_mask_pm_i387"
18419 [(set (match_operand:XF 0 "register_operand" "=f")
18420 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18421 UNSPEC_FRNDINT_MASK_PM))
18422 (use (match_operand:HI 2 "memory_operand" "m"))
18423 (use (match_operand:HI 3 "memory_operand" "m"))]
18424 "TARGET_USE_FANCY_MATH_387
18425 && flag_unsafe_math_optimizations"
18426 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18427 [(set_attr "type" "frndint")
18428 (set_attr "i387_cw" "mask_pm")
18429 (set_attr "mode" "XF")])
18431 (define_expand "nearbyintxf2"
18432 [(use (match_operand:XF 0 "register_operand" ""))
18433 (use (match_operand:XF 1 "register_operand" ""))]
18434 "TARGET_USE_FANCY_MATH_387
18435 && flag_unsafe_math_optimizations"
18437 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18442 (define_expand "nearbyint<mode>2"
18443 [(use (match_operand:MODEF 0 "register_operand" ""))
18444 (use (match_operand:MODEF 1 "register_operand" ""))]
18445 "TARGET_USE_FANCY_MATH_387
18446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18447 || TARGET_MIX_SSE_I387)
18448 && flag_unsafe_math_optimizations"
18450 rtx op0 = gen_reg_rtx (XFmode);
18451 rtx op1 = gen_reg_rtx (XFmode);
18453 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18454 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18456 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18460 (define_insn "fxam<mode>2_i387"
18461 [(set (match_operand:HI 0 "register_operand" "=a")
18463 [(match_operand:X87MODEF 1 "register_operand" "f")]
18465 "TARGET_USE_FANCY_MATH_387"
18466 "fxam\n\tfnstsw\t%0"
18467 [(set_attr "type" "multi")
18468 (set_attr "unit" "i387")
18469 (set_attr "mode" "<MODE>")])
18471 (define_expand "isinf<mode>2"
18472 [(use (match_operand:SI 0 "register_operand" ""))
18473 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18474 "TARGET_USE_FANCY_MATH_387
18475 && TARGET_C99_FUNCTIONS
18476 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18478 rtx mask = GEN_INT (0x45);
18479 rtx val = GEN_INT (0x05);
18483 rtx scratch = gen_reg_rtx (HImode);
18484 rtx res = gen_reg_rtx (QImode);
18486 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18487 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18488 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18489 cond = gen_rtx_fmt_ee (EQ, QImode,
18490 gen_rtx_REG (CCmode, FLAGS_REG),
18492 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18493 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18497 (define_expand "signbit<mode>2"
18498 [(use (match_operand:SI 0 "register_operand" ""))
18499 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18500 "TARGET_USE_FANCY_MATH_387
18501 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18503 rtx mask = GEN_INT (0x0200);
18505 rtx scratch = gen_reg_rtx (HImode);
18507 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18508 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18512 ;; Block operation instructions
18514 (define_expand "movmemsi"
18515 [(use (match_operand:BLK 0 "memory_operand" ""))
18516 (use (match_operand:BLK 1 "memory_operand" ""))
18517 (use (match_operand:SI 2 "nonmemory_operand" ""))
18518 (use (match_operand:SI 3 "const_int_operand" ""))
18519 (use (match_operand:SI 4 "const_int_operand" ""))
18520 (use (match_operand:SI 5 "const_int_operand" ""))]
18523 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18524 operands[4], operands[5]))
18530 (define_expand "movmemdi"
18531 [(use (match_operand:BLK 0 "memory_operand" ""))
18532 (use (match_operand:BLK 1 "memory_operand" ""))
18533 (use (match_operand:DI 2 "nonmemory_operand" ""))
18534 (use (match_operand:DI 3 "const_int_operand" ""))
18535 (use (match_operand:SI 4 "const_int_operand" ""))
18536 (use (match_operand:SI 5 "const_int_operand" ""))]
18539 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18540 operands[4], operands[5]))
18546 ;; Most CPUs don't like single string operations
18547 ;; Handle this case here to simplify previous expander.
18549 (define_expand "strmov"
18550 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18551 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18552 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18553 (clobber (reg:CC FLAGS_REG))])
18554 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18555 (clobber (reg:CC FLAGS_REG))])]
18558 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18560 /* If .md ever supports :P for Pmode, these can be directly
18561 in the pattern above. */
18562 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18563 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18565 /* Can't use this if the user has appropriated esi or edi. */
18566 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18567 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18569 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18570 operands[2], operands[3],
18571 operands[5], operands[6]));
18575 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18578 (define_expand "strmov_singleop"
18579 [(parallel [(set (match_operand 1 "memory_operand" "")
18580 (match_operand 3 "memory_operand" ""))
18581 (set (match_operand 0 "register_operand" "")
18582 (match_operand 4 "" ""))
18583 (set (match_operand 2 "register_operand" "")
18584 (match_operand 5 "" ""))])]
18585 "TARGET_SINGLE_STRINGOP || optimize_size"
18588 (define_insn "*strmovdi_rex_1"
18589 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18590 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18591 (set (match_operand:DI 0 "register_operand" "=D")
18592 (plus:DI (match_dup 2)
18594 (set (match_operand:DI 1 "register_operand" "=S")
18595 (plus:DI (match_dup 3)
18597 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18599 [(set_attr "type" "str")
18600 (set_attr "mode" "DI")
18601 (set_attr "memory" "both")])
18603 (define_insn "*strmovsi_1"
18604 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18605 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18606 (set (match_operand:SI 0 "register_operand" "=D")
18607 (plus:SI (match_dup 2)
18609 (set (match_operand:SI 1 "register_operand" "=S")
18610 (plus:SI (match_dup 3)
18612 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18614 [(set_attr "type" "str")
18615 (set_attr "mode" "SI")
18616 (set_attr "memory" "both")])
18618 (define_insn "*strmovsi_rex_1"
18619 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18620 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18621 (set (match_operand:DI 0 "register_operand" "=D")
18622 (plus:DI (match_dup 2)
18624 (set (match_operand:DI 1 "register_operand" "=S")
18625 (plus:DI (match_dup 3)
18627 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18629 [(set_attr "type" "str")
18630 (set_attr "mode" "SI")
18631 (set_attr "memory" "both")])
18633 (define_insn "*strmovhi_1"
18634 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18635 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18636 (set (match_operand:SI 0 "register_operand" "=D")
18637 (plus:SI (match_dup 2)
18639 (set (match_operand:SI 1 "register_operand" "=S")
18640 (plus:SI (match_dup 3)
18642 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18644 [(set_attr "type" "str")
18645 (set_attr "memory" "both")
18646 (set_attr "mode" "HI")])
18648 (define_insn "*strmovhi_rex_1"
18649 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18650 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18651 (set (match_operand:DI 0 "register_operand" "=D")
18652 (plus:DI (match_dup 2)
18654 (set (match_operand:DI 1 "register_operand" "=S")
18655 (plus:DI (match_dup 3)
18657 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18659 [(set_attr "type" "str")
18660 (set_attr "memory" "both")
18661 (set_attr "mode" "HI")])
18663 (define_insn "*strmovqi_1"
18664 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18665 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18666 (set (match_operand:SI 0 "register_operand" "=D")
18667 (plus:SI (match_dup 2)
18669 (set (match_operand:SI 1 "register_operand" "=S")
18670 (plus:SI (match_dup 3)
18672 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18674 [(set_attr "type" "str")
18675 (set_attr "memory" "both")
18676 (set_attr "mode" "QI")])
18678 (define_insn "*strmovqi_rex_1"
18679 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18680 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18681 (set (match_operand:DI 0 "register_operand" "=D")
18682 (plus:DI (match_dup 2)
18684 (set (match_operand:DI 1 "register_operand" "=S")
18685 (plus:DI (match_dup 3)
18687 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18689 [(set_attr "type" "str")
18690 (set_attr "memory" "both")
18691 (set_attr "mode" "QI")])
18693 (define_expand "rep_mov"
18694 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18695 (set (match_operand 0 "register_operand" "")
18696 (match_operand 5 "" ""))
18697 (set (match_operand 2 "register_operand" "")
18698 (match_operand 6 "" ""))
18699 (set (match_operand 1 "memory_operand" "")
18700 (match_operand 3 "memory_operand" ""))
18701 (use (match_dup 4))])]
18705 (define_insn "*rep_movdi_rex64"
18706 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18707 (set (match_operand:DI 0 "register_operand" "=D")
18708 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18710 (match_operand:DI 3 "register_operand" "0")))
18711 (set (match_operand:DI 1 "register_operand" "=S")
18712 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18713 (match_operand:DI 4 "register_operand" "1")))
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" "DI")])
18724 (define_insn "*rep_movsi"
18725 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18726 (set (match_operand:SI 0 "register_operand" "=D")
18727 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18729 (match_operand:SI 3 "register_operand" "0")))
18730 (set (match_operand:SI 1 "register_operand" "=S")
18731 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18732 (match_operand:SI 4 "register_operand" "1")))
18733 (set (mem:BLK (match_dup 3))
18734 (mem:BLK (match_dup 4)))
18735 (use (match_dup 5))]
18738 [(set_attr "type" "str")
18739 (set_attr "prefix_rep" "1")
18740 (set_attr "memory" "both")
18741 (set_attr "mode" "SI")])
18743 (define_insn "*rep_movsi_rex64"
18744 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18745 (set (match_operand:DI 0 "register_operand" "=D")
18746 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18748 (match_operand:DI 3 "register_operand" "0")))
18749 (set (match_operand:DI 1 "register_operand" "=S")
18750 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18751 (match_operand:DI 4 "register_operand" "1")))
18752 (set (mem:BLK (match_dup 3))
18753 (mem:BLK (match_dup 4)))
18754 (use (match_dup 5))]
18757 [(set_attr "type" "str")
18758 (set_attr "prefix_rep" "1")
18759 (set_attr "memory" "both")
18760 (set_attr "mode" "SI")])
18762 (define_insn "*rep_movqi"
18763 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18764 (set (match_operand:SI 0 "register_operand" "=D")
18765 (plus:SI (match_operand:SI 3 "register_operand" "0")
18766 (match_operand:SI 5 "register_operand" "2")))
18767 (set (match_operand:SI 1 "register_operand" "=S")
18768 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18769 (set (mem:BLK (match_dup 3))
18770 (mem:BLK (match_dup 4)))
18771 (use (match_dup 5))]
18774 [(set_attr "type" "str")
18775 (set_attr "prefix_rep" "1")
18776 (set_attr "memory" "both")
18777 (set_attr "mode" "SI")])
18779 (define_insn "*rep_movqi_rex64"
18780 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18781 (set (match_operand:DI 0 "register_operand" "=D")
18782 (plus:DI (match_operand:DI 3 "register_operand" "0")
18783 (match_operand:DI 5 "register_operand" "2")))
18784 (set (match_operand:DI 1 "register_operand" "=S")
18785 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18786 (set (mem:BLK (match_dup 3))
18787 (mem:BLK (match_dup 4)))
18788 (use (match_dup 5))]
18791 [(set_attr "type" "str")
18792 (set_attr "prefix_rep" "1")
18793 (set_attr "memory" "both")
18794 (set_attr "mode" "SI")])
18796 (define_expand "setmemsi"
18797 [(use (match_operand:BLK 0 "memory_operand" ""))
18798 (use (match_operand:SI 1 "nonmemory_operand" ""))
18799 (use (match_operand 2 "const_int_operand" ""))
18800 (use (match_operand 3 "const_int_operand" ""))
18801 (use (match_operand:SI 4 "const_int_operand" ""))
18802 (use (match_operand:SI 5 "const_int_operand" ""))]
18805 if (ix86_expand_setmem (operands[0], operands[1],
18806 operands[2], operands[3],
18807 operands[4], operands[5]))
18813 (define_expand "setmemdi"
18814 [(use (match_operand:BLK 0 "memory_operand" ""))
18815 (use (match_operand:DI 1 "nonmemory_operand" ""))
18816 (use (match_operand 2 "const_int_operand" ""))
18817 (use (match_operand 3 "const_int_operand" ""))
18818 (use (match_operand 4 "const_int_operand" ""))
18819 (use (match_operand 5 "const_int_operand" ""))]
18822 if (ix86_expand_setmem (operands[0], operands[1],
18823 operands[2], operands[3],
18824 operands[4], operands[5]))
18830 ;; Most CPUs don't like single string operations
18831 ;; Handle this case here to simplify previous expander.
18833 (define_expand "strset"
18834 [(set (match_operand 1 "memory_operand" "")
18835 (match_operand 2 "register_operand" ""))
18836 (parallel [(set (match_operand 0 "register_operand" "")
18838 (clobber (reg:CC FLAGS_REG))])]
18841 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18842 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18844 /* If .md ever supports :P for Pmode, this can be directly
18845 in the pattern above. */
18846 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18847 GEN_INT (GET_MODE_SIZE (GET_MODE
18849 if (TARGET_SINGLE_STRINGOP || optimize_size)
18851 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18857 (define_expand "strset_singleop"
18858 [(parallel [(set (match_operand 1 "memory_operand" "")
18859 (match_operand 2 "register_operand" ""))
18860 (set (match_operand 0 "register_operand" "")
18861 (match_operand 3 "" ""))])]
18862 "TARGET_SINGLE_STRINGOP || optimize_size"
18865 (define_insn "*strsetdi_rex_1"
18866 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18867 (match_operand:DI 2 "register_operand" "a"))
18868 (set (match_operand:DI 0 "register_operand" "=D")
18869 (plus:DI (match_dup 1)
18871 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18873 [(set_attr "type" "str")
18874 (set_attr "memory" "store")
18875 (set_attr "mode" "DI")])
18877 (define_insn "*strsetsi_1"
18878 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18879 (match_operand:SI 2 "register_operand" "a"))
18880 (set (match_operand:SI 0 "register_operand" "=D")
18881 (plus:SI (match_dup 1)
18883 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18885 [(set_attr "type" "str")
18886 (set_attr "memory" "store")
18887 (set_attr "mode" "SI")])
18889 (define_insn "*strsetsi_rex_1"
18890 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18891 (match_operand:SI 2 "register_operand" "a"))
18892 (set (match_operand:DI 0 "register_operand" "=D")
18893 (plus:DI (match_dup 1)
18895 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18897 [(set_attr "type" "str")
18898 (set_attr "memory" "store")
18899 (set_attr "mode" "SI")])
18901 (define_insn "*strsethi_1"
18902 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18903 (match_operand:HI 2 "register_operand" "a"))
18904 (set (match_operand:SI 0 "register_operand" "=D")
18905 (plus:SI (match_dup 1)
18907 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18909 [(set_attr "type" "str")
18910 (set_attr "memory" "store")
18911 (set_attr "mode" "HI")])
18913 (define_insn "*strsethi_rex_1"
18914 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18915 (match_operand:HI 2 "register_operand" "a"))
18916 (set (match_operand:DI 0 "register_operand" "=D")
18917 (plus:DI (match_dup 1)
18919 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18921 [(set_attr "type" "str")
18922 (set_attr "memory" "store")
18923 (set_attr "mode" "HI")])
18925 (define_insn "*strsetqi_1"
18926 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18927 (match_operand:QI 2 "register_operand" "a"))
18928 (set (match_operand:SI 0 "register_operand" "=D")
18929 (plus:SI (match_dup 1)
18931 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18933 [(set_attr "type" "str")
18934 (set_attr "memory" "store")
18935 (set_attr "mode" "QI")])
18937 (define_insn "*strsetqi_rex_1"
18938 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18939 (match_operand:QI 2 "register_operand" "a"))
18940 (set (match_operand:DI 0 "register_operand" "=D")
18941 (plus:DI (match_dup 1)
18943 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18945 [(set_attr "type" "str")
18946 (set_attr "memory" "store")
18947 (set_attr "mode" "QI")])
18949 (define_expand "rep_stos"
18950 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18951 (set (match_operand 0 "register_operand" "")
18952 (match_operand 4 "" ""))
18953 (set (match_operand 2 "memory_operand" "") (const_int 0))
18954 (use (match_operand 3 "register_operand" ""))
18955 (use (match_dup 1))])]
18959 (define_insn "*rep_stosdi_rex64"
18960 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18961 (set (match_operand:DI 0 "register_operand" "=D")
18962 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18964 (match_operand:DI 3 "register_operand" "0")))
18965 (set (mem:BLK (match_dup 3))
18967 (use (match_operand:DI 2 "register_operand" "a"))
18968 (use (match_dup 4))]
18971 [(set_attr "type" "str")
18972 (set_attr "prefix_rep" "1")
18973 (set_attr "memory" "store")
18974 (set_attr "mode" "DI")])
18976 (define_insn "*rep_stossi"
18977 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18978 (set (match_operand:SI 0 "register_operand" "=D")
18979 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18981 (match_operand:SI 3 "register_operand" "0")))
18982 (set (mem:BLK (match_dup 3))
18984 (use (match_operand:SI 2 "register_operand" "a"))
18985 (use (match_dup 4))]
18988 [(set_attr "type" "str")
18989 (set_attr "prefix_rep" "1")
18990 (set_attr "memory" "store")
18991 (set_attr "mode" "SI")])
18993 (define_insn "*rep_stossi_rex64"
18994 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18995 (set (match_operand:DI 0 "register_operand" "=D")
18996 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18998 (match_operand:DI 3 "register_operand" "0")))
18999 (set (mem:BLK (match_dup 3))
19001 (use (match_operand:SI 2 "register_operand" "a"))
19002 (use (match_dup 4))]
19005 [(set_attr "type" "str")
19006 (set_attr "prefix_rep" "1")
19007 (set_attr "memory" "store")
19008 (set_attr "mode" "SI")])
19010 (define_insn "*rep_stosqi"
19011 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19012 (set (match_operand:SI 0 "register_operand" "=D")
19013 (plus:SI (match_operand:SI 3 "register_operand" "0")
19014 (match_operand:SI 4 "register_operand" "1")))
19015 (set (mem:BLK (match_dup 3))
19017 (use (match_operand:QI 2 "register_operand" "a"))
19018 (use (match_dup 4))]
19021 [(set_attr "type" "str")
19022 (set_attr "prefix_rep" "1")
19023 (set_attr "memory" "store")
19024 (set_attr "mode" "QI")])
19026 (define_insn "*rep_stosqi_rex64"
19027 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19028 (set (match_operand:DI 0 "register_operand" "=D")
19029 (plus:DI (match_operand:DI 3 "register_operand" "0")
19030 (match_operand:DI 4 "register_operand" "1")))
19031 (set (mem:BLK (match_dup 3))
19033 (use (match_operand:QI 2 "register_operand" "a"))
19034 (use (match_dup 4))]
19037 [(set_attr "type" "str")
19038 (set_attr "prefix_rep" "1")
19039 (set_attr "memory" "store")
19040 (set_attr "mode" "QI")])
19042 (define_expand "cmpstrnsi"
19043 [(set (match_operand:SI 0 "register_operand" "")
19044 (compare:SI (match_operand:BLK 1 "general_operand" "")
19045 (match_operand:BLK 2 "general_operand" "")))
19046 (use (match_operand 3 "general_operand" ""))
19047 (use (match_operand 4 "immediate_operand" ""))]
19048 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19050 rtx addr1, addr2, out, outlow, count, countreg, align;
19052 /* Can't use this if the user has appropriated esi or edi. */
19053 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19058 out = gen_reg_rtx (SImode);
19060 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19061 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19062 if (addr1 != XEXP (operands[1], 0))
19063 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19064 if (addr2 != XEXP (operands[2], 0))
19065 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19067 count = operands[3];
19068 countreg = ix86_zero_extend_to_Pmode (count);
19070 /* %%% Iff we are testing strict equality, we can use known alignment
19071 to good advantage. This may be possible with combine, particularly
19072 once cc0 is dead. */
19073 align = operands[4];
19075 if (CONST_INT_P (count))
19077 if (INTVAL (count) == 0)
19079 emit_move_insn (operands[0], const0_rtx);
19082 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19083 operands[1], operands[2]));
19088 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19090 emit_insn (gen_cmpsi_1 (countreg, countreg));
19091 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19092 operands[1], operands[2]));
19095 outlow = gen_lowpart (QImode, out);
19096 emit_insn (gen_cmpintqi (outlow));
19097 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19099 if (operands[0] != out)
19100 emit_move_insn (operands[0], out);
19105 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19107 (define_expand "cmpintqi"
19108 [(set (match_dup 1)
19109 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19111 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19112 (parallel [(set (match_operand:QI 0 "register_operand" "")
19113 (minus:QI (match_dup 1)
19115 (clobber (reg:CC FLAGS_REG))])]
19117 "operands[1] = gen_reg_rtx (QImode);
19118 operands[2] = gen_reg_rtx (QImode);")
19120 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19121 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19123 (define_expand "cmpstrnqi_nz_1"
19124 [(parallel [(set (reg:CC FLAGS_REG)
19125 (compare:CC (match_operand 4 "memory_operand" "")
19126 (match_operand 5 "memory_operand" "")))
19127 (use (match_operand 2 "register_operand" ""))
19128 (use (match_operand:SI 3 "immediate_operand" ""))
19129 (clobber (match_operand 0 "register_operand" ""))
19130 (clobber (match_operand 1 "register_operand" ""))
19131 (clobber (match_dup 2))])]
19135 (define_insn "*cmpstrnqi_nz_1"
19136 [(set (reg:CC FLAGS_REG)
19137 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19138 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19139 (use (match_operand:SI 6 "register_operand" "2"))
19140 (use (match_operand:SI 3 "immediate_operand" "i"))
19141 (clobber (match_operand:SI 0 "register_operand" "=S"))
19142 (clobber (match_operand:SI 1 "register_operand" "=D"))
19143 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19146 [(set_attr "type" "str")
19147 (set_attr "mode" "QI")
19148 (set_attr "prefix_rep" "1")])
19150 (define_insn "*cmpstrnqi_nz_rex_1"
19151 [(set (reg:CC FLAGS_REG)
19152 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19153 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19154 (use (match_operand:DI 6 "register_operand" "2"))
19155 (use (match_operand:SI 3 "immediate_operand" "i"))
19156 (clobber (match_operand:DI 0 "register_operand" "=S"))
19157 (clobber (match_operand:DI 1 "register_operand" "=D"))
19158 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19161 [(set_attr "type" "str")
19162 (set_attr "mode" "QI")
19163 (set_attr "prefix_rep" "1")])
19165 ;; The same, but the count is not known to not be zero.
19167 (define_expand "cmpstrnqi_1"
19168 [(parallel [(set (reg:CC FLAGS_REG)
19169 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19171 (compare:CC (match_operand 4 "memory_operand" "")
19172 (match_operand 5 "memory_operand" ""))
19174 (use (match_operand:SI 3 "immediate_operand" ""))
19175 (use (reg:CC FLAGS_REG))
19176 (clobber (match_operand 0 "register_operand" ""))
19177 (clobber (match_operand 1 "register_operand" ""))
19178 (clobber (match_dup 2))])]
19182 (define_insn "*cmpstrnqi_1"
19183 [(set (reg:CC FLAGS_REG)
19184 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19186 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19187 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19189 (use (match_operand:SI 3 "immediate_operand" "i"))
19190 (use (reg:CC FLAGS_REG))
19191 (clobber (match_operand:SI 0 "register_operand" "=S"))
19192 (clobber (match_operand:SI 1 "register_operand" "=D"))
19193 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19196 [(set_attr "type" "str")
19197 (set_attr "mode" "QI")
19198 (set_attr "prefix_rep" "1")])
19200 (define_insn "*cmpstrnqi_rex_1"
19201 [(set (reg:CC FLAGS_REG)
19202 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19204 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19205 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19207 (use (match_operand:SI 3 "immediate_operand" "i"))
19208 (use (reg:CC FLAGS_REG))
19209 (clobber (match_operand:DI 0 "register_operand" "=S"))
19210 (clobber (match_operand:DI 1 "register_operand" "=D"))
19211 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19214 [(set_attr "type" "str")
19215 (set_attr "mode" "QI")
19216 (set_attr "prefix_rep" "1")])
19218 (define_expand "strlensi"
19219 [(set (match_operand:SI 0 "register_operand" "")
19220 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19221 (match_operand:QI 2 "immediate_operand" "")
19222 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19225 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19231 (define_expand "strlendi"
19232 [(set (match_operand:DI 0 "register_operand" "")
19233 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19234 (match_operand:QI 2 "immediate_operand" "")
19235 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19238 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19244 (define_expand "strlenqi_1"
19245 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19246 (clobber (match_operand 1 "register_operand" ""))
19247 (clobber (reg:CC FLAGS_REG))])]
19251 (define_insn "*strlenqi_1"
19252 [(set (match_operand:SI 0 "register_operand" "=&c")
19253 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19254 (match_operand:QI 2 "register_operand" "a")
19255 (match_operand:SI 3 "immediate_operand" "i")
19256 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19257 (clobber (match_operand:SI 1 "register_operand" "=D"))
19258 (clobber (reg:CC FLAGS_REG))]
19261 [(set_attr "type" "str")
19262 (set_attr "mode" "QI")
19263 (set_attr "prefix_rep" "1")])
19265 (define_insn "*strlenqi_rex_1"
19266 [(set (match_operand:DI 0 "register_operand" "=&c")
19267 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19268 (match_operand:QI 2 "register_operand" "a")
19269 (match_operand:DI 3 "immediate_operand" "i")
19270 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19271 (clobber (match_operand:DI 1 "register_operand" "=D"))
19272 (clobber (reg:CC FLAGS_REG))]
19275 [(set_attr "type" "str")
19276 (set_attr "mode" "QI")
19277 (set_attr "prefix_rep" "1")])
19279 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19280 ;; handled in combine, but it is not currently up to the task.
19281 ;; When used for their truth value, the cmpstrn* expanders generate
19290 ;; The intermediate three instructions are unnecessary.
19292 ;; This one handles cmpstrn*_nz_1...
19295 (set (reg:CC FLAGS_REG)
19296 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19297 (mem:BLK (match_operand 5 "register_operand" ""))))
19298 (use (match_operand 6 "register_operand" ""))
19299 (use (match_operand:SI 3 "immediate_operand" ""))
19300 (clobber (match_operand 0 "register_operand" ""))
19301 (clobber (match_operand 1 "register_operand" ""))
19302 (clobber (match_operand 2 "register_operand" ""))])
19303 (set (match_operand:QI 7 "register_operand" "")
19304 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19305 (set (match_operand:QI 8 "register_operand" "")
19306 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19307 (set (reg FLAGS_REG)
19308 (compare (match_dup 7) (match_dup 8)))
19310 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19312 (set (reg:CC FLAGS_REG)
19313 (compare:CC (mem:BLK (match_dup 4))
19314 (mem:BLK (match_dup 5))))
19315 (use (match_dup 6))
19316 (use (match_dup 3))
19317 (clobber (match_dup 0))
19318 (clobber (match_dup 1))
19319 (clobber (match_dup 2))])]
19322 ;; ...and this one handles cmpstrn*_1.
19325 (set (reg:CC FLAGS_REG)
19326 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19328 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19329 (mem:BLK (match_operand 5 "register_operand" "")))
19331 (use (match_operand:SI 3 "immediate_operand" ""))
19332 (use (reg:CC FLAGS_REG))
19333 (clobber (match_operand 0 "register_operand" ""))
19334 (clobber (match_operand 1 "register_operand" ""))
19335 (clobber (match_operand 2 "register_operand" ""))])
19336 (set (match_operand:QI 7 "register_operand" "")
19337 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19338 (set (match_operand:QI 8 "register_operand" "")
19339 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19340 (set (reg FLAGS_REG)
19341 (compare (match_dup 7) (match_dup 8)))
19343 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19345 (set (reg:CC FLAGS_REG)
19346 (if_then_else:CC (ne (match_dup 6)
19348 (compare:CC (mem:BLK (match_dup 4))
19349 (mem:BLK (match_dup 5)))
19351 (use (match_dup 3))
19352 (use (reg:CC FLAGS_REG))
19353 (clobber (match_dup 0))
19354 (clobber (match_dup 1))
19355 (clobber (match_dup 2))])]
19360 ;; Conditional move instructions.
19362 (define_expand "movdicc"
19363 [(set (match_operand:DI 0 "register_operand" "")
19364 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19365 (match_operand:DI 2 "general_operand" "")
19366 (match_operand:DI 3 "general_operand" "")))]
19368 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19370 (define_insn "x86_movdicc_0_m1_rex64"
19371 [(set (match_operand:DI 0 "register_operand" "=r")
19372 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19375 (clobber (reg:CC FLAGS_REG))]
19378 ; Since we don't have the proper number of operands for an alu insn,
19379 ; fill in all the blanks.
19380 [(set_attr "type" "alu")
19381 (set_attr "pent_pair" "pu")
19382 (set_attr "memory" "none")
19383 (set_attr "imm_disp" "false")
19384 (set_attr "mode" "DI")
19385 (set_attr "length_immediate" "0")])
19387 (define_insn "*x86_movdicc_0_m1_se"
19388 [(set (match_operand:DI 0 "register_operand" "=r")
19389 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19392 (clobber (reg:CC FLAGS_REG))]
19395 [(set_attr "type" "alu")
19396 (set_attr "pent_pair" "pu")
19397 (set_attr "memory" "none")
19398 (set_attr "imm_disp" "false")
19399 (set_attr "mode" "DI")
19400 (set_attr "length_immediate" "0")])
19402 (define_insn "*movdicc_c_rex64"
19403 [(set (match_operand:DI 0 "register_operand" "=r,r")
19404 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19405 [(reg FLAGS_REG) (const_int 0)])
19406 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19407 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19408 "TARGET_64BIT && TARGET_CMOVE
19409 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19411 cmov%O2%C1\t{%2, %0|%0, %2}
19412 cmov%O2%c1\t{%3, %0|%0, %3}"
19413 [(set_attr "type" "icmov")
19414 (set_attr "mode" "DI")])
19416 (define_expand "movsicc"
19417 [(set (match_operand:SI 0 "register_operand" "")
19418 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19419 (match_operand:SI 2 "general_operand" "")
19420 (match_operand:SI 3 "general_operand" "")))]
19422 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19424 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19425 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19426 ;; So just document what we're doing explicitly.
19428 (define_insn "x86_movsicc_0_m1"
19429 [(set (match_operand:SI 0 "register_operand" "=r")
19430 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19433 (clobber (reg:CC FLAGS_REG))]
19436 ; Since we don't have the proper number of operands for an alu insn,
19437 ; fill in all the blanks.
19438 [(set_attr "type" "alu")
19439 (set_attr "pent_pair" "pu")
19440 (set_attr "memory" "none")
19441 (set_attr "imm_disp" "false")
19442 (set_attr "mode" "SI")
19443 (set_attr "length_immediate" "0")])
19445 (define_insn "*x86_movsicc_0_m1_se"
19446 [(set (match_operand:SI 0 "register_operand" "=r")
19447 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19450 (clobber (reg:CC FLAGS_REG))]
19453 [(set_attr "type" "alu")
19454 (set_attr "pent_pair" "pu")
19455 (set_attr "memory" "none")
19456 (set_attr "imm_disp" "false")
19457 (set_attr "mode" "SI")
19458 (set_attr "length_immediate" "0")])
19460 (define_insn "*movsicc_noc"
19461 [(set (match_operand:SI 0 "register_operand" "=r,r")
19462 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19463 [(reg FLAGS_REG) (const_int 0)])
19464 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19465 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19467 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19469 cmov%O2%C1\t{%2, %0|%0, %2}
19470 cmov%O2%c1\t{%3, %0|%0, %3}"
19471 [(set_attr "type" "icmov")
19472 (set_attr "mode" "SI")])
19474 (define_expand "movhicc"
19475 [(set (match_operand:HI 0 "register_operand" "")
19476 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19477 (match_operand:HI 2 "general_operand" "")
19478 (match_operand:HI 3 "general_operand" "")))]
19479 "TARGET_HIMODE_MATH"
19480 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19482 (define_insn "*movhicc_noc"
19483 [(set (match_operand:HI 0 "register_operand" "=r,r")
19484 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19485 [(reg FLAGS_REG) (const_int 0)])
19486 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19487 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19489 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19491 cmov%O2%C1\t{%2, %0|%0, %2}
19492 cmov%O2%c1\t{%3, %0|%0, %3}"
19493 [(set_attr "type" "icmov")
19494 (set_attr "mode" "HI")])
19496 (define_expand "movqicc"
19497 [(set (match_operand:QI 0 "register_operand" "")
19498 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19499 (match_operand:QI 2 "general_operand" "")
19500 (match_operand:QI 3 "general_operand" "")))]
19501 "TARGET_QIMODE_MATH"
19502 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19504 (define_insn_and_split "*movqicc_noc"
19505 [(set (match_operand:QI 0 "register_operand" "=r,r")
19506 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19507 [(match_operand 4 "flags_reg_operand" "")
19509 (match_operand:QI 2 "register_operand" "r,0")
19510 (match_operand:QI 3 "register_operand" "0,r")))]
19511 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19513 "&& reload_completed"
19514 [(set (match_dup 0)
19515 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19518 "operands[0] = gen_lowpart (SImode, operands[0]);
19519 operands[2] = gen_lowpart (SImode, operands[2]);
19520 operands[3] = gen_lowpart (SImode, operands[3]);"
19521 [(set_attr "type" "icmov")
19522 (set_attr "mode" "SI")])
19524 (define_expand "mov<mode>cc"
19525 [(set (match_operand:X87MODEF 0 "register_operand" "")
19526 (if_then_else:X87MODEF
19527 (match_operand 1 "comparison_operator" "")
19528 (match_operand:X87MODEF 2 "register_operand" "")
19529 (match_operand:X87MODEF 3 "register_operand" "")))]
19530 "(TARGET_80387 && TARGET_CMOVE)
19531 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19532 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19534 (define_insn "*movsfcc_1_387"
19535 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19536 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19537 [(reg FLAGS_REG) (const_int 0)])
19538 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19539 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19540 "TARGET_80387 && TARGET_CMOVE
19541 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19543 fcmov%F1\t{%2, %0|%0, %2}
19544 fcmov%f1\t{%3, %0|%0, %3}
19545 cmov%O2%C1\t{%2, %0|%0, %2}
19546 cmov%O2%c1\t{%3, %0|%0, %3}"
19547 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19548 (set_attr "mode" "SF,SF,SI,SI")])
19550 (define_insn "*movdfcc_1"
19551 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19552 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19553 [(reg FLAGS_REG) (const_int 0)])
19554 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19555 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19556 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19557 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19559 fcmov%F1\t{%2, %0|%0, %2}
19560 fcmov%f1\t{%3, %0|%0, %3}
19563 [(set_attr "type" "fcmov,fcmov,multi,multi")
19564 (set_attr "mode" "DF")])
19566 (define_insn "*movdfcc_1_rex64"
19567 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19568 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19569 [(reg FLAGS_REG) (const_int 0)])
19570 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19571 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19572 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19573 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19575 fcmov%F1\t{%2, %0|%0, %2}
19576 fcmov%f1\t{%3, %0|%0, %3}
19577 cmov%O2%C1\t{%2, %0|%0, %2}
19578 cmov%O2%c1\t{%3, %0|%0, %3}"
19579 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19580 (set_attr "mode" "DF")])
19583 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19584 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19585 [(match_operand 4 "flags_reg_operand" "")
19587 (match_operand:DF 2 "nonimmediate_operand" "")
19588 (match_operand:DF 3 "nonimmediate_operand" "")))]
19589 "!TARGET_64BIT && reload_completed"
19590 [(set (match_dup 2)
19591 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19595 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19598 "split_di (operands+2, 1, operands+5, operands+6);
19599 split_di (operands+3, 1, operands+7, operands+8);
19600 split_di (operands, 1, operands+2, operands+3);")
19602 (define_insn "*movxfcc_1"
19603 [(set (match_operand:XF 0 "register_operand" "=f,f")
19604 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19605 [(reg FLAGS_REG) (const_int 0)])
19606 (match_operand:XF 2 "register_operand" "f,0")
19607 (match_operand:XF 3 "register_operand" "0,f")))]
19608 "TARGET_80387 && TARGET_CMOVE"
19610 fcmov%F1\t{%2, %0|%0, %2}
19611 fcmov%f1\t{%3, %0|%0, %3}"
19612 [(set_attr "type" "fcmov")
19613 (set_attr "mode" "XF")])
19615 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19616 ;; the scalar versions to have only XMM registers as operands.
19618 ;; SSE5 conditional move
19619 (define_insn "*sse5_pcmov_<mode>"
19620 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19621 (if_then_else:MODEF
19622 (match_operand:MODEF 1 "register_operand" "x,0")
19623 (match_operand:MODEF 2 "register_operand" "0,x")
19624 (match_operand:MODEF 3 "register_operand" "x,x")))]
19625 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19626 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19627 [(set_attr "type" "sse4arg")])
19629 ;; These versions of the min/max patterns are intentionally ignorant of
19630 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19631 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19632 ;; are undefined in this condition, we're certain this is correct.
19634 (define_insn "smin<mode>3"
19635 [(set (match_operand:MODEF 0 "register_operand" "=x")
19637 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19638 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19639 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19640 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19641 [(set_attr "type" "sseadd")
19642 (set_attr "mode" "<MODE>")])
19644 (define_insn "smax<mode>3"
19645 [(set (match_operand:MODEF 0 "register_operand" "=x")
19647 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19648 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19649 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19650 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19651 [(set_attr "type" "sseadd")
19652 (set_attr "mode" "<MODE>")])
19654 ;; These versions of the min/max patterns implement exactly the operations
19655 ;; min = (op1 < op2 ? op1 : op2)
19656 ;; max = (!(op1 < op2) ? op1 : op2)
19657 ;; Their operands are not commutative, and thus they may be used in the
19658 ;; presence of -0.0 and NaN.
19660 (define_insn "*ieee_smin<mode>3"
19661 [(set (match_operand:MODEF 0 "register_operand" "=x")
19663 [(match_operand:MODEF 1 "register_operand" "0")
19664 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19666 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19667 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19668 [(set_attr "type" "sseadd")
19669 (set_attr "mode" "<MODE>")])
19671 (define_insn "*ieee_smax<mode>3"
19672 [(set (match_operand:MODEF 0 "register_operand" "=x")
19674 [(match_operand:MODEF 1 "register_operand" "0")
19675 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19677 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19678 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19679 [(set_attr "type" "sseadd")
19680 (set_attr "mode" "<MODE>")])
19682 ;; Make two stack loads independent:
19684 ;; fld %st(0) -> fld bb
19685 ;; fmul bb fmul %st(1), %st
19687 ;; Actually we only match the last two instructions for simplicity.
19689 [(set (match_operand 0 "fp_register_operand" "")
19690 (match_operand 1 "fp_register_operand" ""))
19692 (match_operator 2 "binary_fp_operator"
19694 (match_operand 3 "memory_operand" "")]))]
19695 "REGNO (operands[0]) != REGNO (operands[1])"
19696 [(set (match_dup 0) (match_dup 3))
19697 (set (match_dup 0) (match_dup 4))]
19699 ;; The % modifier is not operational anymore in peephole2's, so we have to
19700 ;; swap the operands manually in the case of addition and multiplication.
19701 "if (COMMUTATIVE_ARITH_P (operands[2]))
19702 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19703 operands[0], operands[1]);
19705 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19706 operands[1], operands[0]);")
19708 ;; Conditional addition patterns
19709 (define_expand "addqicc"
19710 [(match_operand:QI 0 "register_operand" "")
19711 (match_operand 1 "comparison_operator" "")
19712 (match_operand:QI 2 "register_operand" "")
19713 (match_operand:QI 3 "const_int_operand" "")]
19715 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19717 (define_expand "addhicc"
19718 [(match_operand:HI 0 "register_operand" "")
19719 (match_operand 1 "comparison_operator" "")
19720 (match_operand:HI 2 "register_operand" "")
19721 (match_operand:HI 3 "const_int_operand" "")]
19723 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19725 (define_expand "addsicc"
19726 [(match_operand:SI 0 "register_operand" "")
19727 (match_operand 1 "comparison_operator" "")
19728 (match_operand:SI 2 "register_operand" "")
19729 (match_operand:SI 3 "const_int_operand" "")]
19731 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19733 (define_expand "adddicc"
19734 [(match_operand:DI 0 "register_operand" "")
19735 (match_operand 1 "comparison_operator" "")
19736 (match_operand:DI 2 "register_operand" "")
19737 (match_operand:DI 3 "const_int_operand" "")]
19739 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19742 ;; Misc patterns (?)
19744 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19745 ;; Otherwise there will be nothing to keep
19747 ;; [(set (reg ebp) (reg esp))]
19748 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19749 ;; (clobber (eflags)]
19750 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19752 ;; in proper program order.
19753 (define_insn "pro_epilogue_adjust_stack_1"
19754 [(set (match_operand:SI 0 "register_operand" "=r,r")
19755 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19756 (match_operand:SI 2 "immediate_operand" "i,i")))
19757 (clobber (reg:CC FLAGS_REG))
19758 (clobber (mem:BLK (scratch)))]
19761 switch (get_attr_type (insn))
19764 return "mov{l}\t{%1, %0|%0, %1}";
19767 if (CONST_INT_P (operands[2])
19768 && (INTVAL (operands[2]) == 128
19769 || (INTVAL (operands[2]) < 0
19770 && INTVAL (operands[2]) != -128)))
19772 operands[2] = GEN_INT (-INTVAL (operands[2]));
19773 return "sub{l}\t{%2, %0|%0, %2}";
19775 return "add{l}\t{%2, %0|%0, %2}";
19778 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19779 return "lea{l}\t{%a2, %0|%0, %a2}";
19782 gcc_unreachable ();
19785 [(set (attr "type")
19786 (cond [(eq_attr "alternative" "0")
19787 (const_string "alu")
19788 (match_operand:SI 2 "const0_operand" "")
19789 (const_string "imov")
19791 (const_string "lea")))
19792 (set_attr "mode" "SI")])
19794 (define_insn "pro_epilogue_adjust_stack_rex64"
19795 [(set (match_operand:DI 0 "register_operand" "=r,r")
19796 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19797 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19798 (clobber (reg:CC FLAGS_REG))
19799 (clobber (mem:BLK (scratch)))]
19802 switch (get_attr_type (insn))
19805 return "mov{q}\t{%1, %0|%0, %1}";
19808 if (CONST_INT_P (operands[2])
19809 /* Avoid overflows. */
19810 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19811 && (INTVAL (operands[2]) == 128
19812 || (INTVAL (operands[2]) < 0
19813 && INTVAL (operands[2]) != -128)))
19815 operands[2] = GEN_INT (-INTVAL (operands[2]));
19816 return "sub{q}\t{%2, %0|%0, %2}";
19818 return "add{q}\t{%2, %0|%0, %2}";
19821 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19822 return "lea{q}\t{%a2, %0|%0, %a2}";
19825 gcc_unreachable ();
19828 [(set (attr "type")
19829 (cond [(eq_attr "alternative" "0")
19830 (const_string "alu")
19831 (match_operand:DI 2 "const0_operand" "")
19832 (const_string "imov")
19834 (const_string "lea")))
19835 (set_attr "mode" "DI")])
19837 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19838 [(set (match_operand:DI 0 "register_operand" "=r,r")
19839 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19840 (match_operand:DI 3 "immediate_operand" "i,i")))
19841 (use (match_operand:DI 2 "register_operand" "r,r"))
19842 (clobber (reg:CC FLAGS_REG))
19843 (clobber (mem:BLK (scratch)))]
19846 switch (get_attr_type (insn))
19849 return "add{q}\t{%2, %0|%0, %2}";
19852 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19853 return "lea{q}\t{%a2, %0|%0, %a2}";
19856 gcc_unreachable ();
19859 [(set_attr "type" "alu,lea")
19860 (set_attr "mode" "DI")])
19862 (define_insn "allocate_stack_worker_32"
19863 [(set (match_operand:SI 0 "register_operand" "+a")
19864 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19865 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19866 (clobber (reg:CC FLAGS_REG))]
19867 "!TARGET_64BIT && TARGET_STACK_PROBE"
19869 [(set_attr "type" "multi")
19870 (set_attr "length" "5")])
19872 (define_insn "allocate_stack_worker_64"
19873 [(set (match_operand:DI 0 "register_operand" "=a")
19874 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19875 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19876 (clobber (reg:DI R10_REG))
19877 (clobber (reg:DI R11_REG))
19878 (clobber (reg:CC FLAGS_REG))]
19879 "TARGET_64BIT && TARGET_STACK_PROBE"
19881 [(set_attr "type" "multi")
19882 (set_attr "length" "5")])
19884 (define_expand "allocate_stack"
19885 [(match_operand 0 "register_operand" "")
19886 (match_operand 1 "general_operand" "")]
19887 "TARGET_STACK_PROBE"
19891 #ifndef CHECK_STACK_LIMIT
19892 #define CHECK_STACK_LIMIT 0
19895 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19896 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19898 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19899 stack_pointer_rtx, 0, OPTAB_DIRECT);
19900 if (x != stack_pointer_rtx)
19901 emit_move_insn (stack_pointer_rtx, x);
19905 x = copy_to_mode_reg (Pmode, operands[1]);
19907 x = gen_allocate_stack_worker_64 (x);
19909 x = gen_allocate_stack_worker_32 (x);
19913 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19917 (define_expand "builtin_setjmp_receiver"
19918 [(label_ref (match_operand 0 "" ""))]
19919 "!TARGET_64BIT && flag_pic"
19924 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19925 rtx label_rtx = gen_label_rtx ();
19926 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19927 xops[0] = xops[1] = picreg;
19928 xops[2] = gen_rtx_CONST (SImode,
19929 gen_rtx_MINUS (SImode,
19930 gen_rtx_LABEL_REF (SImode, label_rtx),
19931 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19932 ix86_expand_binary_operator (MINUS, SImode, xops);
19935 emit_insn (gen_set_got (pic_offset_table_rtx));
19939 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19942 [(set (match_operand 0 "register_operand" "")
19943 (match_operator 3 "promotable_binary_operator"
19944 [(match_operand 1 "register_operand" "")
19945 (match_operand 2 "aligned_operand" "")]))
19946 (clobber (reg:CC FLAGS_REG))]
19947 "! TARGET_PARTIAL_REG_STALL && reload_completed
19948 && ((GET_MODE (operands[0]) == HImode
19949 && ((!optimize_size && !TARGET_FAST_PREFIX)
19950 /* ??? next two lines just !satisfies_constraint_K (...) */
19951 || !CONST_INT_P (operands[2])
19952 || satisfies_constraint_K (operands[2])))
19953 || (GET_MODE (operands[0]) == QImode
19954 && (TARGET_PROMOTE_QImode || optimize_size)))"
19955 [(parallel [(set (match_dup 0)
19956 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19957 (clobber (reg:CC FLAGS_REG))])]
19958 "operands[0] = gen_lowpart (SImode, operands[0]);
19959 operands[1] = gen_lowpart (SImode, operands[1]);
19960 if (GET_CODE (operands[3]) != ASHIFT)
19961 operands[2] = gen_lowpart (SImode, operands[2]);
19962 PUT_MODE (operands[3], SImode);")
19964 ; Promote the QImode tests, as i386 has encoding of the AND
19965 ; instruction with 32-bit sign-extended immediate and thus the
19966 ; instruction size is unchanged, except in the %eax case for
19967 ; which it is increased by one byte, hence the ! optimize_size.
19969 [(set (match_operand 0 "flags_reg_operand" "")
19970 (match_operator 2 "compare_operator"
19971 [(and (match_operand 3 "aligned_operand" "")
19972 (match_operand 4 "const_int_operand" ""))
19974 (set (match_operand 1 "register_operand" "")
19975 (and (match_dup 3) (match_dup 4)))]
19976 "! TARGET_PARTIAL_REG_STALL && reload_completed
19978 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19979 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19980 /* Ensure that the operand will remain sign-extended immediate. */
19981 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19982 [(parallel [(set (match_dup 0)
19983 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19986 (and:SI (match_dup 3) (match_dup 4)))])]
19989 = gen_int_mode (INTVAL (operands[4])
19990 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19991 operands[1] = gen_lowpart (SImode, operands[1]);
19992 operands[3] = gen_lowpart (SImode, operands[3]);
19995 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19996 ; the TEST instruction with 32-bit sign-extended immediate and thus
19997 ; the instruction size would at least double, which is not what we
19998 ; want even with ! optimize_size.
20000 [(set (match_operand 0 "flags_reg_operand" "")
20001 (match_operator 1 "compare_operator"
20002 [(and (match_operand:HI 2 "aligned_operand" "")
20003 (match_operand:HI 3 "const_int_operand" ""))
20005 "! TARGET_PARTIAL_REG_STALL && reload_completed
20006 && ! TARGET_FAST_PREFIX
20008 /* Ensure that the operand will remain sign-extended immediate. */
20009 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20010 [(set (match_dup 0)
20011 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20015 = gen_int_mode (INTVAL (operands[3])
20016 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20017 operands[2] = gen_lowpart (SImode, operands[2]);
20021 [(set (match_operand 0 "register_operand" "")
20022 (neg (match_operand 1 "register_operand" "")))
20023 (clobber (reg:CC FLAGS_REG))]
20024 "! TARGET_PARTIAL_REG_STALL && reload_completed
20025 && (GET_MODE (operands[0]) == HImode
20026 || (GET_MODE (operands[0]) == QImode
20027 && (TARGET_PROMOTE_QImode || optimize_size)))"
20028 [(parallel [(set (match_dup 0)
20029 (neg:SI (match_dup 1)))
20030 (clobber (reg:CC FLAGS_REG))])]
20031 "operands[0] = gen_lowpart (SImode, operands[0]);
20032 operands[1] = gen_lowpart (SImode, operands[1]);")
20035 [(set (match_operand 0 "register_operand" "")
20036 (not (match_operand 1 "register_operand" "")))]
20037 "! TARGET_PARTIAL_REG_STALL && reload_completed
20038 && (GET_MODE (operands[0]) == HImode
20039 || (GET_MODE (operands[0]) == QImode
20040 && (TARGET_PROMOTE_QImode || optimize_size)))"
20041 [(set (match_dup 0)
20042 (not:SI (match_dup 1)))]
20043 "operands[0] = gen_lowpart (SImode, operands[0]);
20044 operands[1] = gen_lowpart (SImode, operands[1]);")
20047 [(set (match_operand 0 "register_operand" "")
20048 (if_then_else (match_operator 1 "comparison_operator"
20049 [(reg FLAGS_REG) (const_int 0)])
20050 (match_operand 2 "register_operand" "")
20051 (match_operand 3 "register_operand" "")))]
20052 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20053 && (GET_MODE (operands[0]) == HImode
20054 || (GET_MODE (operands[0]) == QImode
20055 && (TARGET_PROMOTE_QImode || optimize_size)))"
20056 [(set (match_dup 0)
20057 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20058 "operands[0] = gen_lowpart (SImode, operands[0]);
20059 operands[2] = gen_lowpart (SImode, operands[2]);
20060 operands[3] = gen_lowpart (SImode, operands[3]);")
20063 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20064 ;; transform a complex memory operation into two memory to register operations.
20066 ;; Don't push memory operands
20068 [(set (match_operand:SI 0 "push_operand" "")
20069 (match_operand:SI 1 "memory_operand" ""))
20070 (match_scratch:SI 2 "r")]
20071 "!optimize_size && !TARGET_PUSH_MEMORY
20072 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20073 [(set (match_dup 2) (match_dup 1))
20074 (set (match_dup 0) (match_dup 2))]
20078 [(set (match_operand:DI 0 "push_operand" "")
20079 (match_operand:DI 1 "memory_operand" ""))
20080 (match_scratch:DI 2 "r")]
20081 "!optimize_size && !TARGET_PUSH_MEMORY
20082 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20083 [(set (match_dup 2) (match_dup 1))
20084 (set (match_dup 0) (match_dup 2))]
20087 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20090 [(set (match_operand:SF 0 "push_operand" "")
20091 (match_operand:SF 1 "memory_operand" ""))
20092 (match_scratch:SF 2 "r")]
20093 "!optimize_size && !TARGET_PUSH_MEMORY
20094 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20095 [(set (match_dup 2) (match_dup 1))
20096 (set (match_dup 0) (match_dup 2))]
20100 [(set (match_operand:HI 0 "push_operand" "")
20101 (match_operand:HI 1 "memory_operand" ""))
20102 (match_scratch:HI 2 "r")]
20103 "!optimize_size && !TARGET_PUSH_MEMORY
20104 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20105 [(set (match_dup 2) (match_dup 1))
20106 (set (match_dup 0) (match_dup 2))]
20110 [(set (match_operand:QI 0 "push_operand" "")
20111 (match_operand:QI 1 "memory_operand" ""))
20112 (match_scratch:QI 2 "q")]
20113 "!optimize_size && !TARGET_PUSH_MEMORY
20114 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20115 [(set (match_dup 2) (match_dup 1))
20116 (set (match_dup 0) (match_dup 2))]
20119 ;; Don't move an immediate directly to memory when the instruction
20122 [(match_scratch:SI 1 "r")
20123 (set (match_operand:SI 0 "memory_operand" "")
20126 && ! TARGET_USE_MOV0
20127 && TARGET_SPLIT_LONG_MOVES
20128 && get_attr_length (insn) >= ix86_cost->large_insn
20129 && peep2_regno_dead_p (0, FLAGS_REG)"
20130 [(parallel [(set (match_dup 1) (const_int 0))
20131 (clobber (reg:CC FLAGS_REG))])
20132 (set (match_dup 0) (match_dup 1))]
20136 [(match_scratch:HI 1 "r")
20137 (set (match_operand:HI 0 "memory_operand" "")
20140 && ! TARGET_USE_MOV0
20141 && TARGET_SPLIT_LONG_MOVES
20142 && get_attr_length (insn) >= ix86_cost->large_insn
20143 && peep2_regno_dead_p (0, FLAGS_REG)"
20144 [(parallel [(set (match_dup 2) (const_int 0))
20145 (clobber (reg:CC FLAGS_REG))])
20146 (set (match_dup 0) (match_dup 1))]
20147 "operands[2] = gen_lowpart (SImode, operands[1]);")
20150 [(match_scratch:QI 1 "q")
20151 (set (match_operand:QI 0 "memory_operand" "")
20154 && ! TARGET_USE_MOV0
20155 && TARGET_SPLIT_LONG_MOVES
20156 && get_attr_length (insn) >= ix86_cost->large_insn
20157 && peep2_regno_dead_p (0, FLAGS_REG)"
20158 [(parallel [(set (match_dup 2) (const_int 0))
20159 (clobber (reg:CC FLAGS_REG))])
20160 (set (match_dup 0) (match_dup 1))]
20161 "operands[2] = gen_lowpart (SImode, operands[1]);")
20164 [(match_scratch:SI 2 "r")
20165 (set (match_operand:SI 0 "memory_operand" "")
20166 (match_operand:SI 1 "immediate_operand" ""))]
20168 && TARGET_SPLIT_LONG_MOVES
20169 && get_attr_length (insn) >= ix86_cost->large_insn"
20170 [(set (match_dup 2) (match_dup 1))
20171 (set (match_dup 0) (match_dup 2))]
20175 [(match_scratch:HI 2 "r")
20176 (set (match_operand:HI 0 "memory_operand" "")
20177 (match_operand:HI 1 "immediate_operand" ""))]
20179 && TARGET_SPLIT_LONG_MOVES
20180 && get_attr_length (insn) >= ix86_cost->large_insn"
20181 [(set (match_dup 2) (match_dup 1))
20182 (set (match_dup 0) (match_dup 2))]
20186 [(match_scratch:QI 2 "q")
20187 (set (match_operand:QI 0 "memory_operand" "")
20188 (match_operand:QI 1 "immediate_operand" ""))]
20190 && TARGET_SPLIT_LONG_MOVES
20191 && get_attr_length (insn) >= ix86_cost->large_insn"
20192 [(set (match_dup 2) (match_dup 1))
20193 (set (match_dup 0) (match_dup 2))]
20196 ;; Don't compare memory with zero, load and use a test instead.
20198 [(set (match_operand 0 "flags_reg_operand" "")
20199 (match_operator 1 "compare_operator"
20200 [(match_operand:SI 2 "memory_operand" "")
20202 (match_scratch:SI 3 "r")]
20203 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20204 [(set (match_dup 3) (match_dup 2))
20205 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20208 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20209 ;; Don't split NOTs with a displacement operand, because resulting XOR
20210 ;; will not be pairable anyway.
20212 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20213 ;; represented using a modRM byte. The XOR replacement is long decoded,
20214 ;; so this split helps here as well.
20216 ;; Note: Can't do this as a regular split because we can't get proper
20217 ;; lifetime information then.
20220 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20221 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20223 && ((TARGET_NOT_UNPAIRABLE
20224 && (!MEM_P (operands[0])
20225 || !memory_displacement_operand (operands[0], SImode)))
20226 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20227 && peep2_regno_dead_p (0, FLAGS_REG)"
20228 [(parallel [(set (match_dup 0)
20229 (xor:SI (match_dup 1) (const_int -1)))
20230 (clobber (reg:CC FLAGS_REG))])]
20234 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20235 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20237 && ((TARGET_NOT_UNPAIRABLE
20238 && (!MEM_P (operands[0])
20239 || !memory_displacement_operand (operands[0], HImode)))
20240 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20241 && peep2_regno_dead_p (0, FLAGS_REG)"
20242 [(parallel [(set (match_dup 0)
20243 (xor:HI (match_dup 1) (const_int -1)))
20244 (clobber (reg:CC FLAGS_REG))])]
20248 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20249 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20251 && ((TARGET_NOT_UNPAIRABLE
20252 && (!MEM_P (operands[0])
20253 || !memory_displacement_operand (operands[0], QImode)))
20254 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20255 && peep2_regno_dead_p (0, FLAGS_REG)"
20256 [(parallel [(set (match_dup 0)
20257 (xor:QI (match_dup 1) (const_int -1)))
20258 (clobber (reg:CC FLAGS_REG))])]
20261 ;; Non pairable "test imm, reg" instructions can be translated to
20262 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20263 ;; byte opcode instead of two, have a short form for byte operands),
20264 ;; so do it for other CPUs as well. Given that the value was dead,
20265 ;; this should not create any new dependencies. Pass on the sub-word
20266 ;; versions if we're concerned about partial register stalls.
20269 [(set (match_operand 0 "flags_reg_operand" "")
20270 (match_operator 1 "compare_operator"
20271 [(and:SI (match_operand:SI 2 "register_operand" "")
20272 (match_operand:SI 3 "immediate_operand" ""))
20274 "ix86_match_ccmode (insn, CCNOmode)
20275 && (true_regnum (operands[2]) != AX_REG
20276 || satisfies_constraint_K (operands[3]))
20277 && peep2_reg_dead_p (1, operands[2])"
20279 [(set (match_dup 0)
20280 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20283 (and:SI (match_dup 2) (match_dup 3)))])]
20286 ;; We don't need to handle HImode case, because it will be promoted to SImode
20287 ;; on ! TARGET_PARTIAL_REG_STALL
20290 [(set (match_operand 0 "flags_reg_operand" "")
20291 (match_operator 1 "compare_operator"
20292 [(and:QI (match_operand:QI 2 "register_operand" "")
20293 (match_operand:QI 3 "immediate_operand" ""))
20295 "! TARGET_PARTIAL_REG_STALL
20296 && ix86_match_ccmode (insn, CCNOmode)
20297 && true_regnum (operands[2]) != AX_REG
20298 && peep2_reg_dead_p (1, operands[2])"
20300 [(set (match_dup 0)
20301 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20304 (and:QI (match_dup 2) (match_dup 3)))])]
20308 [(set (match_operand 0 "flags_reg_operand" "")
20309 (match_operator 1 "compare_operator"
20312 (match_operand 2 "ext_register_operand" "")
20315 (match_operand 3 "const_int_operand" ""))
20317 "! TARGET_PARTIAL_REG_STALL
20318 && ix86_match_ccmode (insn, CCNOmode)
20319 && true_regnum (operands[2]) != AX_REG
20320 && peep2_reg_dead_p (1, operands[2])"
20321 [(parallel [(set (match_dup 0)
20330 (set (zero_extract:SI (match_dup 2)
20341 ;; Don't do logical operations with memory inputs.
20343 [(match_scratch:SI 2 "r")
20344 (parallel [(set (match_operand:SI 0 "register_operand" "")
20345 (match_operator:SI 3 "arith_or_logical_operator"
20347 (match_operand:SI 1 "memory_operand" "")]))
20348 (clobber (reg:CC FLAGS_REG))])]
20349 "! optimize_size && ! TARGET_READ_MODIFY"
20350 [(set (match_dup 2) (match_dup 1))
20351 (parallel [(set (match_dup 0)
20352 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20353 (clobber (reg:CC FLAGS_REG))])]
20357 [(match_scratch:SI 2 "r")
20358 (parallel [(set (match_operand:SI 0 "register_operand" "")
20359 (match_operator:SI 3 "arith_or_logical_operator"
20360 [(match_operand:SI 1 "memory_operand" "")
20362 (clobber (reg:CC FLAGS_REG))])]
20363 "! optimize_size && ! TARGET_READ_MODIFY"
20364 [(set (match_dup 2) (match_dup 1))
20365 (parallel [(set (match_dup 0)
20366 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20367 (clobber (reg:CC FLAGS_REG))])]
20370 ; Don't do logical operations with memory outputs
20372 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20373 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20374 ; the same decoder scheduling characteristics as the original.
20377 [(match_scratch:SI 2 "r")
20378 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20379 (match_operator:SI 3 "arith_or_logical_operator"
20381 (match_operand:SI 1 "nonmemory_operand" "")]))
20382 (clobber (reg:CC FLAGS_REG))])]
20383 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20384 [(set (match_dup 2) (match_dup 0))
20385 (parallel [(set (match_dup 2)
20386 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20387 (clobber (reg:CC FLAGS_REG))])
20388 (set (match_dup 0) (match_dup 2))]
20392 [(match_scratch:SI 2 "r")
20393 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20394 (match_operator:SI 3 "arith_or_logical_operator"
20395 [(match_operand:SI 1 "nonmemory_operand" "")
20397 (clobber (reg:CC FLAGS_REG))])]
20398 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20399 [(set (match_dup 2) (match_dup 0))
20400 (parallel [(set (match_dup 2)
20401 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20402 (clobber (reg:CC FLAGS_REG))])
20403 (set (match_dup 0) (match_dup 2))]
20406 ;; Attempt to always use XOR for zeroing registers.
20408 [(set (match_operand 0 "register_operand" "")
20409 (match_operand 1 "const0_operand" ""))]
20410 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20411 && (! TARGET_USE_MOV0 || optimize_size)
20412 && GENERAL_REG_P (operands[0])
20413 && peep2_regno_dead_p (0, FLAGS_REG)"
20414 [(parallel [(set (match_dup 0) (const_int 0))
20415 (clobber (reg:CC FLAGS_REG))])]
20417 operands[0] = gen_lowpart (word_mode, operands[0]);
20421 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20423 "(GET_MODE (operands[0]) == QImode
20424 || GET_MODE (operands[0]) == HImode)
20425 && (! TARGET_USE_MOV0 || optimize_size)
20426 && peep2_regno_dead_p (0, FLAGS_REG)"
20427 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20428 (clobber (reg:CC FLAGS_REG))])])
20430 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20432 [(set (match_operand 0 "register_operand" "")
20434 "(GET_MODE (operands[0]) == HImode
20435 || GET_MODE (operands[0]) == SImode
20436 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20437 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20438 && peep2_regno_dead_p (0, FLAGS_REG)"
20439 [(parallel [(set (match_dup 0) (const_int -1))
20440 (clobber (reg:CC FLAGS_REG))])]
20441 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20444 ;; Attempt to convert simple leas to adds. These can be created by
20447 [(set (match_operand:SI 0 "register_operand" "")
20448 (plus:SI (match_dup 0)
20449 (match_operand:SI 1 "nonmemory_operand" "")))]
20450 "peep2_regno_dead_p (0, FLAGS_REG)"
20451 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20452 (clobber (reg:CC FLAGS_REG))])]
20456 [(set (match_operand:SI 0 "register_operand" "")
20457 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20458 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20459 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20460 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20461 (clobber (reg:CC FLAGS_REG))])]
20462 "operands[2] = gen_lowpart (SImode, operands[2]);")
20465 [(set (match_operand:DI 0 "register_operand" "")
20466 (plus:DI (match_dup 0)
20467 (match_operand:DI 1 "x86_64_general_operand" "")))]
20468 "peep2_regno_dead_p (0, FLAGS_REG)"
20469 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20470 (clobber (reg:CC FLAGS_REG))])]
20474 [(set (match_operand:SI 0 "register_operand" "")
20475 (mult:SI (match_dup 0)
20476 (match_operand:SI 1 "const_int_operand" "")))]
20477 "exact_log2 (INTVAL (operands[1])) >= 0
20478 && peep2_regno_dead_p (0, FLAGS_REG)"
20479 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20480 (clobber (reg:CC FLAGS_REG))])]
20481 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20484 [(set (match_operand:DI 0 "register_operand" "")
20485 (mult:DI (match_dup 0)
20486 (match_operand:DI 1 "const_int_operand" "")))]
20487 "exact_log2 (INTVAL (operands[1])) >= 0
20488 && peep2_regno_dead_p (0, FLAGS_REG)"
20489 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20490 (clobber (reg:CC FLAGS_REG))])]
20491 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20494 [(set (match_operand:SI 0 "register_operand" "")
20495 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20496 (match_operand:DI 2 "const_int_operand" "")) 0))]
20497 "exact_log2 (INTVAL (operands[2])) >= 0
20498 && REGNO (operands[0]) == REGNO (operands[1])
20499 && peep2_regno_dead_p (0, FLAGS_REG)"
20500 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20501 (clobber (reg:CC FLAGS_REG))])]
20502 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20504 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20505 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20506 ;; many CPUs it is also faster, since special hardware to avoid esp
20507 ;; dependencies is present.
20509 ;; While some of these conversions may be done using splitters, we use peepholes
20510 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20512 ;; Convert prologue esp subtractions to push.
20513 ;; We need register to push. In order to keep verify_flow_info happy we have
20515 ;; - use scratch and clobber it in order to avoid dependencies
20516 ;; - use already live register
20517 ;; We can't use the second way right now, since there is no reliable way how to
20518 ;; verify that given register is live. First choice will also most likely in
20519 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20520 ;; call clobbered registers are dead. We may want to use base pointer as an
20521 ;; alternative when no register is available later.
20524 [(match_scratch:SI 0 "r")
20525 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20526 (clobber (reg:CC FLAGS_REG))
20527 (clobber (mem:BLK (scratch)))])]
20528 "optimize_size || !TARGET_SUB_ESP_4"
20529 [(clobber (match_dup 0))
20530 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20531 (clobber (mem:BLK (scratch)))])])
20534 [(match_scratch:SI 0 "r")
20535 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20536 (clobber (reg:CC FLAGS_REG))
20537 (clobber (mem:BLK (scratch)))])]
20538 "optimize_size || !TARGET_SUB_ESP_8"
20539 [(clobber (match_dup 0))
20540 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20541 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20542 (clobber (mem:BLK (scratch)))])])
20544 ;; Convert esp subtractions to push.
20546 [(match_scratch:SI 0 "r")
20547 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20548 (clobber (reg:CC FLAGS_REG))])]
20549 "optimize_size || !TARGET_SUB_ESP_4"
20550 [(clobber (match_dup 0))
20551 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20554 [(match_scratch:SI 0 "r")
20555 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20556 (clobber (reg:CC FLAGS_REG))])]
20557 "optimize_size || !TARGET_SUB_ESP_8"
20558 [(clobber (match_dup 0))
20559 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20560 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20562 ;; Convert epilogue deallocator to pop.
20564 [(match_scratch:SI 0 "r")
20565 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20566 (clobber (reg:CC FLAGS_REG))
20567 (clobber (mem:BLK (scratch)))])]
20568 "optimize_size || !TARGET_ADD_ESP_4"
20569 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20570 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20571 (clobber (mem:BLK (scratch)))])]
20574 ;; Two pops case is tricky, since pop causes dependency on destination register.
20575 ;; We use two registers if available.
20577 [(match_scratch:SI 0 "r")
20578 (match_scratch:SI 1 "r")
20579 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20580 (clobber (reg:CC FLAGS_REG))
20581 (clobber (mem:BLK (scratch)))])]
20582 "optimize_size || !TARGET_ADD_ESP_8"
20583 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20584 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20585 (clobber (mem:BLK (scratch)))])
20586 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20587 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20591 [(match_scratch:SI 0 "r")
20592 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20593 (clobber (reg:CC FLAGS_REG))
20594 (clobber (mem:BLK (scratch)))])]
20596 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20597 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20598 (clobber (mem:BLK (scratch)))])
20599 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20600 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20603 ;; Convert esp additions to pop.
20605 [(match_scratch:SI 0 "r")
20606 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20607 (clobber (reg:CC FLAGS_REG))])]
20609 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20610 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20613 ;; Two pops case is tricky, since pop causes dependency on destination register.
20614 ;; We use two registers if available.
20616 [(match_scratch:SI 0 "r")
20617 (match_scratch:SI 1 "r")
20618 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20619 (clobber (reg:CC FLAGS_REG))])]
20621 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20622 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20623 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20624 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20628 [(match_scratch:SI 0 "r")
20629 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20630 (clobber (reg:CC FLAGS_REG))])]
20632 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20633 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20634 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20635 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20638 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20639 ;; required and register dies. Similarly for 128 to plus -128.
20641 [(set (match_operand 0 "flags_reg_operand" "")
20642 (match_operator 1 "compare_operator"
20643 [(match_operand 2 "register_operand" "")
20644 (match_operand 3 "const_int_operand" "")]))]
20645 "(INTVAL (operands[3]) == -1
20646 || INTVAL (operands[3]) == 1
20647 || INTVAL (operands[3]) == 128)
20648 && ix86_match_ccmode (insn, CCGCmode)
20649 && peep2_reg_dead_p (1, operands[2])"
20650 [(parallel [(set (match_dup 0)
20651 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20652 (clobber (match_dup 2))])]
20656 [(match_scratch:DI 0 "r")
20657 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20658 (clobber (reg:CC FLAGS_REG))
20659 (clobber (mem:BLK (scratch)))])]
20660 "optimize_size || !TARGET_SUB_ESP_4"
20661 [(clobber (match_dup 0))
20662 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20663 (clobber (mem:BLK (scratch)))])])
20666 [(match_scratch:DI 0 "r")
20667 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20668 (clobber (reg:CC FLAGS_REG))
20669 (clobber (mem:BLK (scratch)))])]
20670 "optimize_size || !TARGET_SUB_ESP_8"
20671 [(clobber (match_dup 0))
20672 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20673 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20674 (clobber (mem:BLK (scratch)))])])
20676 ;; Convert esp subtractions to push.
20678 [(match_scratch:DI 0 "r")
20679 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20680 (clobber (reg:CC FLAGS_REG))])]
20681 "optimize_size || !TARGET_SUB_ESP_4"
20682 [(clobber (match_dup 0))
20683 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20686 [(match_scratch:DI 0 "r")
20687 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20688 (clobber (reg:CC FLAGS_REG))])]
20689 "optimize_size || !TARGET_SUB_ESP_8"
20690 [(clobber (match_dup 0))
20691 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20692 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20694 ;; Convert epilogue deallocator to pop.
20696 [(match_scratch:DI 0 "r")
20697 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20698 (clobber (reg:CC FLAGS_REG))
20699 (clobber (mem:BLK (scratch)))])]
20700 "optimize_size || !TARGET_ADD_ESP_4"
20701 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20702 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20703 (clobber (mem:BLK (scratch)))])]
20706 ;; Two pops case is tricky, since pop causes dependency on destination register.
20707 ;; We use two registers if available.
20709 [(match_scratch:DI 0 "r")
20710 (match_scratch:DI 1 "r")
20711 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20712 (clobber (reg:CC FLAGS_REG))
20713 (clobber (mem:BLK (scratch)))])]
20714 "optimize_size || !TARGET_ADD_ESP_8"
20715 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20716 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20717 (clobber (mem:BLK (scratch)))])
20718 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20719 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20723 [(match_scratch:DI 0 "r")
20724 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20725 (clobber (reg:CC FLAGS_REG))
20726 (clobber (mem:BLK (scratch)))])]
20728 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20729 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20730 (clobber (mem:BLK (scratch)))])
20731 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20732 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20735 ;; Convert esp additions to pop.
20737 [(match_scratch:DI 0 "r")
20738 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20739 (clobber (reg:CC FLAGS_REG))])]
20741 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20742 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20745 ;; Two pops case is tricky, since pop causes dependency on destination register.
20746 ;; We use two registers if available.
20748 [(match_scratch:DI 0 "r")
20749 (match_scratch:DI 1 "r")
20750 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20751 (clobber (reg:CC FLAGS_REG))])]
20753 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20754 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20755 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20756 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20760 [(match_scratch:DI 0 "r")
20761 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20762 (clobber (reg:CC FLAGS_REG))])]
20764 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20765 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20766 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20767 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20770 ;; Convert imul by three, five and nine into lea
20773 [(set (match_operand:SI 0 "register_operand" "")
20774 (mult:SI (match_operand:SI 1 "register_operand" "")
20775 (match_operand:SI 2 "const_int_operand" "")))
20776 (clobber (reg:CC FLAGS_REG))])]
20777 "INTVAL (operands[2]) == 3
20778 || INTVAL (operands[2]) == 5
20779 || INTVAL (operands[2]) == 9"
20780 [(set (match_dup 0)
20781 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20783 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20787 [(set (match_operand:SI 0 "register_operand" "")
20788 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20789 (match_operand:SI 2 "const_int_operand" "")))
20790 (clobber (reg:CC FLAGS_REG))])]
20792 && (INTVAL (operands[2]) == 3
20793 || INTVAL (operands[2]) == 5
20794 || INTVAL (operands[2]) == 9)"
20795 [(set (match_dup 0) (match_dup 1))
20797 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20799 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20803 [(set (match_operand:DI 0 "register_operand" "")
20804 (mult:DI (match_operand:DI 1 "register_operand" "")
20805 (match_operand:DI 2 "const_int_operand" "")))
20806 (clobber (reg:CC FLAGS_REG))])]
20808 && (INTVAL (operands[2]) == 3
20809 || INTVAL (operands[2]) == 5
20810 || INTVAL (operands[2]) == 9)"
20811 [(set (match_dup 0)
20812 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20814 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20818 [(set (match_operand:DI 0 "register_operand" "")
20819 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20820 (match_operand:DI 2 "const_int_operand" "")))
20821 (clobber (reg:CC FLAGS_REG))])]
20824 && (INTVAL (operands[2]) == 3
20825 || INTVAL (operands[2]) == 5
20826 || INTVAL (operands[2]) == 9)"
20827 [(set (match_dup 0) (match_dup 1))
20829 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20831 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20833 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20834 ;; imul $32bit_imm, reg, reg is direct decoded.
20836 [(match_scratch:DI 3 "r")
20837 (parallel [(set (match_operand:DI 0 "register_operand" "")
20838 (mult:DI (match_operand:DI 1 "memory_operand" "")
20839 (match_operand:DI 2 "immediate_operand" "")))
20840 (clobber (reg:CC FLAGS_REG))])]
20841 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20842 && !satisfies_constraint_K (operands[2])"
20843 [(set (match_dup 3) (match_dup 1))
20844 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20845 (clobber (reg:CC FLAGS_REG))])]
20849 [(match_scratch:SI 3 "r")
20850 (parallel [(set (match_operand:SI 0 "register_operand" "")
20851 (mult:SI (match_operand:SI 1 "memory_operand" "")
20852 (match_operand:SI 2 "immediate_operand" "")))
20853 (clobber (reg:CC FLAGS_REG))])]
20854 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20855 && !satisfies_constraint_K (operands[2])"
20856 [(set (match_dup 3) (match_dup 1))
20857 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20858 (clobber (reg:CC FLAGS_REG))])]
20862 [(match_scratch:SI 3 "r")
20863 (parallel [(set (match_operand:DI 0 "register_operand" "")
20865 (mult:SI (match_operand:SI 1 "memory_operand" "")
20866 (match_operand:SI 2 "immediate_operand" ""))))
20867 (clobber (reg:CC FLAGS_REG))])]
20868 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20869 && !satisfies_constraint_K (operands[2])"
20870 [(set (match_dup 3) (match_dup 1))
20871 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20872 (clobber (reg:CC FLAGS_REG))])]
20875 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20876 ;; Convert it into imul reg, reg
20877 ;; It would be better to force assembler to encode instruction using long
20878 ;; immediate, but there is apparently no way to do so.
20880 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20881 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20882 (match_operand:DI 2 "const_int_operand" "")))
20883 (clobber (reg:CC FLAGS_REG))])
20884 (match_scratch:DI 3 "r")]
20885 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20886 && satisfies_constraint_K (operands[2])"
20887 [(set (match_dup 3) (match_dup 2))
20888 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20889 (clobber (reg:CC FLAGS_REG))])]
20891 if (!rtx_equal_p (operands[0], operands[1]))
20892 emit_move_insn (operands[0], operands[1]);
20896 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20897 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20898 (match_operand:SI 2 "const_int_operand" "")))
20899 (clobber (reg:CC FLAGS_REG))])
20900 (match_scratch:SI 3 "r")]
20901 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20902 && satisfies_constraint_K (operands[2])"
20903 [(set (match_dup 3) (match_dup 2))
20904 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20905 (clobber (reg:CC FLAGS_REG))])]
20907 if (!rtx_equal_p (operands[0], operands[1]))
20908 emit_move_insn (operands[0], operands[1]);
20912 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20913 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20914 (match_operand:HI 2 "immediate_operand" "")))
20915 (clobber (reg:CC FLAGS_REG))])
20916 (match_scratch:HI 3 "r")]
20917 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20918 [(set (match_dup 3) (match_dup 2))
20919 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20920 (clobber (reg:CC FLAGS_REG))])]
20922 if (!rtx_equal_p (operands[0], operands[1]))
20923 emit_move_insn (operands[0], operands[1]);
20926 ;; After splitting up read-modify operations, array accesses with memory
20927 ;; operands might end up in form:
20929 ;; movl 4(%esp), %edx
20931 ;; instead of pre-splitting:
20933 ;; addl 4(%esp), %eax
20935 ;; movl 4(%esp), %edx
20936 ;; leal (%edx,%eax,4), %eax
20939 [(parallel [(set (match_operand 0 "register_operand" "")
20940 (ashift (match_operand 1 "register_operand" "")
20941 (match_operand 2 "const_int_operand" "")))
20942 (clobber (reg:CC FLAGS_REG))])
20943 (set (match_operand 3 "register_operand")
20944 (match_operand 4 "x86_64_general_operand" ""))
20945 (parallel [(set (match_operand 5 "register_operand" "")
20946 (plus (match_operand 6 "register_operand" "")
20947 (match_operand 7 "register_operand" "")))
20948 (clobber (reg:CC FLAGS_REG))])]
20949 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20950 /* Validate MODE for lea. */
20951 && ((!TARGET_PARTIAL_REG_STALL
20952 && (GET_MODE (operands[0]) == QImode
20953 || GET_MODE (operands[0]) == HImode))
20954 || GET_MODE (operands[0]) == SImode
20955 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20956 /* We reorder load and the shift. */
20957 && !rtx_equal_p (operands[1], operands[3])
20958 && !reg_overlap_mentioned_p (operands[0], operands[4])
20959 /* Last PLUS must consist of operand 0 and 3. */
20960 && !rtx_equal_p (operands[0], operands[3])
20961 && (rtx_equal_p (operands[3], operands[6])
20962 || rtx_equal_p (operands[3], operands[7]))
20963 && (rtx_equal_p (operands[0], operands[6])
20964 || rtx_equal_p (operands[0], operands[7]))
20965 /* The intermediate operand 0 must die or be same as output. */
20966 && (rtx_equal_p (operands[0], operands[5])
20967 || peep2_reg_dead_p (3, operands[0]))"
20968 [(set (match_dup 3) (match_dup 4))
20969 (set (match_dup 0) (match_dup 1))]
20971 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20972 int scale = 1 << INTVAL (operands[2]);
20973 rtx index = gen_lowpart (Pmode, operands[1]);
20974 rtx base = gen_lowpart (Pmode, operands[3]);
20975 rtx dest = gen_lowpart (mode, operands[5]);
20977 operands[1] = gen_rtx_PLUS (Pmode, base,
20978 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20980 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20981 operands[0] = dest;
20984 ;; Call-value patterns last so that the wildcard operand does not
20985 ;; disrupt insn-recog's switch tables.
20987 (define_insn "*call_value_pop_0"
20988 [(set (match_operand 0 "" "")
20989 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20990 (match_operand:SI 2 "" "")))
20991 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20992 (match_operand:SI 3 "immediate_operand" "")))]
20995 if (SIBLING_CALL_P (insn))
20998 return "call\t%P1";
21000 [(set_attr "type" "callv")])
21002 (define_insn "*call_value_pop_1"
21003 [(set (match_operand 0 "" "")
21004 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21005 (match_operand:SI 2 "" "")))
21006 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21007 (match_operand:SI 3 "immediate_operand" "i")))]
21010 if (constant_call_address_operand (operands[1], Pmode))
21012 if (SIBLING_CALL_P (insn))
21015 return "call\t%P1";
21017 if (SIBLING_CALL_P (insn))
21020 return "call\t%A1";
21022 [(set_attr "type" "callv")])
21024 (define_insn "*call_value_0"
21025 [(set (match_operand 0 "" "")
21026 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21027 (match_operand:SI 2 "" "")))]
21030 if (SIBLING_CALL_P (insn))
21033 return "call\t%P1";
21035 [(set_attr "type" "callv")])
21037 (define_insn "*call_value_0_rex64"
21038 [(set (match_operand 0 "" "")
21039 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21040 (match_operand:DI 2 "const_int_operand" "")))]
21043 if (SIBLING_CALL_P (insn))
21046 return "call\t%P1";
21048 [(set_attr "type" "callv")])
21050 (define_insn "*call_value_1"
21051 [(set (match_operand 0 "" "")
21052 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21053 (match_operand:SI 2 "" "")))]
21054 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21056 if (constant_call_address_operand (operands[1], Pmode))
21057 return "call\t%P1";
21058 return "call\t%A1";
21060 [(set_attr "type" "callv")])
21062 (define_insn "*sibcall_value_1"
21063 [(set (match_operand 0 "" "")
21064 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21065 (match_operand:SI 2 "" "")))]
21066 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21068 if (constant_call_address_operand (operands[1], Pmode))
21072 [(set_attr "type" "callv")])
21074 (define_insn "*call_value_1_rex64"
21075 [(set (match_operand 0 "" "")
21076 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21077 (match_operand:DI 2 "" "")))]
21078 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21079 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21081 if (constant_call_address_operand (operands[1], Pmode))
21082 return "call\t%P1";
21083 return "call\t%A1";
21085 [(set_attr "type" "callv")])
21087 (define_insn "*call_value_1_rex64_large"
21088 [(set (match_operand 0 "" "")
21089 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21090 (match_operand:DI 2 "" "")))]
21091 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21093 [(set_attr "type" "callv")])
21095 (define_insn "*sibcall_value_1_rex64"
21096 [(set (match_operand 0 "" "")
21097 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21098 (match_operand:DI 2 "" "")))]
21099 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21101 [(set_attr "type" "callv")])
21103 (define_insn "*sibcall_value_1_rex64_v"
21104 [(set (match_operand 0 "" "")
21105 (call (mem:QI (reg:DI R11_REG))
21106 (match_operand:DI 1 "" "")))]
21107 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21109 [(set_attr "type" "callv")])
21111 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21112 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21113 ;; caught for use by garbage collectors and the like. Using an insn that
21114 ;; maps to SIGILL makes it more likely the program will rightfully die.
21115 ;; Keeping with tradition, "6" is in honor of #UD.
21116 (define_insn "trap"
21117 [(trap_if (const_int 1) (const_int 6))]
21119 { return ASM_SHORT "0x0b0f"; }
21120 [(set_attr "length" "2")])
21122 (define_expand "sse_prologue_save"
21123 [(parallel [(set (match_operand:BLK 0 "" "")
21124 (unspec:BLK [(reg:DI 21)
21131 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21132 (use (match_operand:DI 1 "register_operand" ""))
21133 (use (match_operand:DI 2 "immediate_operand" ""))
21134 (use (label_ref:DI (match_operand 3 "" "")))])]
21138 (define_insn "*sse_prologue_save_insn"
21139 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21140 (match_operand:DI 4 "const_int_operand" "n")))
21141 (unspec:BLK [(reg:DI 21)
21148 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21149 (use (match_operand:DI 1 "register_operand" "r"))
21150 (use (match_operand:DI 2 "const_int_operand" "i"))
21151 (use (label_ref:DI (match_operand 3 "" "X")))]
21153 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21154 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21158 operands[0] = gen_rtx_MEM (Pmode,
21159 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21160 output_asm_insn (\"jmp\\t%A1\", operands);
21161 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21163 operands[4] = adjust_address (operands[0], DImode, i*16);
21164 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21165 PUT_MODE (operands[4], TImode);
21166 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21167 output_asm_insn (\"rex\", operands);
21168 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21170 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21171 CODE_LABEL_NUMBER (operands[3]));
21175 [(set_attr "type" "other")
21176 (set_attr "length_immediate" "0")
21177 (set_attr "length_address" "0")
21178 (set_attr "length" "135")
21179 (set_attr "memory" "store")
21180 (set_attr "modrm" "0")
21181 (set_attr "mode" "DI")])
21183 (define_expand "prefetch"
21184 [(prefetch (match_operand 0 "address_operand" "")
21185 (match_operand:SI 1 "const_int_operand" "")
21186 (match_operand:SI 2 "const_int_operand" ""))]
21187 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21189 int rw = INTVAL (operands[1]);
21190 int locality = INTVAL (operands[2]);
21192 gcc_assert (rw == 0 || rw == 1);
21193 gcc_assert (locality >= 0 && locality <= 3);
21194 gcc_assert (GET_MODE (operands[0]) == Pmode
21195 || GET_MODE (operands[0]) == VOIDmode);
21197 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21198 supported by SSE counterpart or the SSE prefetch is not available
21199 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21201 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21202 operands[2] = GEN_INT (3);
21204 operands[1] = const0_rtx;
21207 (define_insn "*prefetch_sse"
21208 [(prefetch (match_operand:SI 0 "address_operand" "p")
21210 (match_operand:SI 1 "const_int_operand" ""))]
21211 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21213 static const char * const patterns[4] = {
21214 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21217 int locality = INTVAL (operands[1]);
21218 gcc_assert (locality >= 0 && locality <= 3);
21220 return patterns[locality];
21222 [(set_attr "type" "sse")
21223 (set_attr "memory" "none")])
21225 (define_insn "*prefetch_sse_rex"
21226 [(prefetch (match_operand:DI 0 "address_operand" "p")
21228 (match_operand:SI 1 "const_int_operand" ""))]
21229 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21231 static const char * const patterns[4] = {
21232 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21235 int locality = INTVAL (operands[1]);
21236 gcc_assert (locality >= 0 && locality <= 3);
21238 return patterns[locality];
21240 [(set_attr "type" "sse")
21241 (set_attr "memory" "none")])
21243 (define_insn "*prefetch_3dnow"
21244 [(prefetch (match_operand:SI 0 "address_operand" "p")
21245 (match_operand:SI 1 "const_int_operand" "n")
21247 "TARGET_3DNOW && !TARGET_64BIT"
21249 if (INTVAL (operands[1]) == 0)
21250 return "prefetch\t%a0";
21252 return "prefetchw\t%a0";
21254 [(set_attr "type" "mmx")
21255 (set_attr "memory" "none")])
21257 (define_insn "*prefetch_3dnow_rex"
21258 [(prefetch (match_operand:DI 0 "address_operand" "p")
21259 (match_operand:SI 1 "const_int_operand" "n")
21261 "TARGET_3DNOW && TARGET_64BIT"
21263 if (INTVAL (operands[1]) == 0)
21264 return "prefetch\t%a0";
21266 return "prefetchw\t%a0";
21268 [(set_attr "type" "mmx")
21269 (set_attr "memory" "none")])
21271 (define_expand "stack_protect_set"
21272 [(match_operand 0 "memory_operand" "")
21273 (match_operand 1 "memory_operand" "")]
21276 #ifdef TARGET_THREAD_SSP_OFFSET
21278 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21279 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21281 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21282 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21285 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21287 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21292 (define_insn "stack_protect_set_si"
21293 [(set (match_operand:SI 0 "memory_operand" "=m")
21294 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21295 (set (match_scratch:SI 2 "=&r") (const_int 0))
21296 (clobber (reg:CC FLAGS_REG))]
21298 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21299 [(set_attr "type" "multi")])
21301 (define_insn "stack_protect_set_di"
21302 [(set (match_operand:DI 0 "memory_operand" "=m")
21303 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21304 (set (match_scratch:DI 2 "=&r") (const_int 0))
21305 (clobber (reg:CC FLAGS_REG))]
21307 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21308 [(set_attr "type" "multi")])
21310 (define_insn "stack_tls_protect_set_si"
21311 [(set (match_operand:SI 0 "memory_operand" "=m")
21312 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21313 (set (match_scratch:SI 2 "=&r") (const_int 0))
21314 (clobber (reg:CC FLAGS_REG))]
21316 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21317 [(set_attr "type" "multi")])
21319 (define_insn "stack_tls_protect_set_di"
21320 [(set (match_operand:DI 0 "memory_operand" "=m")
21321 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21322 (set (match_scratch:DI 2 "=&r") (const_int 0))
21323 (clobber (reg:CC FLAGS_REG))]
21326 /* The kernel uses a different segment register for performance reasons; a
21327 system call would not have to trash the userspace segment register,
21328 which would be expensive */
21329 if (ix86_cmodel != CM_KERNEL)
21330 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21332 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21334 [(set_attr "type" "multi")])
21336 (define_expand "stack_protect_test"
21337 [(match_operand 0 "memory_operand" "")
21338 (match_operand 1 "memory_operand" "")
21339 (match_operand 2 "" "")]
21342 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21343 ix86_compare_op0 = operands[0];
21344 ix86_compare_op1 = operands[1];
21345 ix86_compare_emitted = flags;
21347 #ifdef TARGET_THREAD_SSP_OFFSET
21349 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21350 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21352 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21353 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21356 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21358 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21360 emit_jump_insn (gen_beq (operands[2]));
21364 (define_insn "stack_protect_test_si"
21365 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21366 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21367 (match_operand:SI 2 "memory_operand" "m")]
21369 (clobber (match_scratch:SI 3 "=&r"))]
21371 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21372 [(set_attr "type" "multi")])
21374 (define_insn "stack_protect_test_di"
21375 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21376 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21377 (match_operand:DI 2 "memory_operand" "m")]
21379 (clobber (match_scratch:DI 3 "=&r"))]
21381 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21382 [(set_attr "type" "multi")])
21384 (define_insn "stack_tls_protect_test_si"
21385 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21386 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21387 (match_operand:SI 2 "const_int_operand" "i")]
21388 UNSPEC_SP_TLS_TEST))
21389 (clobber (match_scratch:SI 3 "=r"))]
21391 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21392 [(set_attr "type" "multi")])
21394 (define_insn "stack_tls_protect_test_di"
21395 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21396 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21397 (match_operand:DI 2 "const_int_operand" "i")]
21398 UNSPEC_SP_TLS_TEST))
21399 (clobber (match_scratch:DI 3 "=r"))]
21402 /* The kernel uses a different segment register for performance reasons; a
21403 system call would not have to trash the userspace segment register,
21404 which would be expensive */
21405 if (ix86_cmodel != CM_KERNEL)
21406 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21408 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21410 [(set_attr "type" "multi")])
21412 (define_mode_iterator CRC32MODE [QI HI SI])
21413 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21414 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21416 (define_insn "sse4_2_crc32<mode>"
21417 [(set (match_operand:SI 0 "register_operand" "=r")
21419 [(match_operand:SI 1 "register_operand" "0")
21420 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21423 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21424 [(set_attr "type" "sselog1")
21425 (set_attr "prefix_rep" "1")
21426 (set_attr "prefix_extra" "1")
21427 (set_attr "mode" "SI")])
21429 (define_insn "sse4_2_crc32di"
21430 [(set (match_operand:DI 0 "register_operand" "=r")
21432 [(match_operand:DI 1 "register_operand" "0")
21433 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21435 "TARGET_SSE4_2 && TARGET_64BIT"
21436 "crc32q\t{%2, %0|%0, %2}"
21437 [(set_attr "type" "sselog1")
21438 (set_attr "prefix_rep" "1")
21439 (set_attr "prefix_extra" "1")
21440 (set_attr "mode" "DI")])
21444 (include "sync.md")