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)
98 (UNSPEC_NOP 48) ; prevents combiner cleverness
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
127 (UNSPEC_FRNDINT_FLOOR 70)
128 (UNSPEC_FRNDINT_CEIL 71)
129 (UNSPEC_FRNDINT_TRUNC 72)
130 (UNSPEC_FRNDINT_MASK_PM 73)
131 (UNSPEC_FIST_FLOOR 74)
132 (UNSPEC_FIST_CEIL 75)
134 ; x87 Double output FP
135 (UNSPEC_SINCOS_COS 80)
136 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
151 (UNSPEC_SP_TLS_SET 102)
152 (UNSPEC_SP_TLS_TEST 103)
162 (UNSPEC_INSERTQI 132)
167 (UNSPEC_INSERTPS 135)
169 (UNSPEC_MOVNTDQA 137)
171 (UNSPEC_PHMINPOSUW 139)
177 (UNSPEC_PCMPESTR 144)
178 (UNSPEC_PCMPISTR 145)
181 (UNSPEC_SSE5_INTRINSIC 150)
182 (UNSPEC_SSE5_UNSIGNED_CMP 151)
183 (UNSPEC_SSE5_TRUEFALSE 152)
184 (UNSPEC_SSE5_PERMUTE 153)
185 (UNSPEC_SSE5_ASHIFT 154)
186 (UNSPEC_SSE5_LSHIFT 155)
188 (UNSPEC_CVTPH2PS 157)
189 (UNSPEC_CVTPS2PH 158)
193 [(UNSPECV_BLOCKAGE 0)
194 (UNSPECV_STACK_PROBE 1)
203 (UNSPECV_CMPXCHG_1 10)
204 (UNSPECV_CMPXCHG_2 11)
207 (UNSPECV_PROLOGUE_USE 14)
210 ;; Constants to represent pcomtrue/pcomfalse variants
220 ;; Registers by name.
236 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
239 ;; In C guard expressions, put expressions which may be compile-time
240 ;; constants first. This allows for better optimization. For
241 ;; example, write "TARGET_64BIT && reload_completed", not
242 ;; "reload_completed && TARGET_64BIT".
245 ;; Processor type. This attribute must exactly match the processor_type
246 ;; enumeration in i386.h.
247 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
248 nocona,core2,generic32,generic64,amdfam10"
249 (const (symbol_ref "ix86_tune")))
251 ;; A basic instruction type. Refinements due to arguments to be
252 ;; provided in other attributes.
255 alu,alu1,negnot,imov,imovx,lea,
256 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
257 icmp,test,ibr,setcc,icmov,
258 push,pop,call,callv,leave,
260 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
261 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
262 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
264 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
265 (const_string "other"))
267 ;; Main data type used by the insn
269 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
270 (const_string "unknown"))
272 ;; The CPU unit operations uses.
273 (define_attr "unit" "integer,i387,sse,mmx,unknown"
274 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
275 (const_string "i387")
276 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
277 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
278 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
280 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
282 (eq_attr "type" "other")
283 (const_string "unknown")]
284 (const_string "integer")))
286 ;; The (bounding maximum) length of an instruction immediate.
287 (define_attr "length_immediate" ""
288 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
291 (eq_attr "unit" "i387,sse,mmx")
293 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
295 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
296 (eq_attr "type" "imov,test")
297 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
298 (eq_attr "type" "call")
299 (if_then_else (match_operand 0 "constant_call_address_operand" "")
302 (eq_attr "type" "callv")
303 (if_then_else (match_operand 1 "constant_call_address_operand" "")
306 ;; We don't know the size before shorten_branches. Expect
307 ;; the instruction to fit for better scheduling.
308 (eq_attr "type" "ibr")
311 (symbol_ref "/* Update immediate_length and other attributes! */
312 gcc_unreachable (),1")))
314 ;; The (bounding maximum) length of an instruction address.
315 (define_attr "length_address" ""
316 (cond [(eq_attr "type" "str,other,multi,fxch")
318 (and (eq_attr "type" "call")
319 (match_operand 0 "constant_call_address_operand" ""))
321 (and (eq_attr "type" "callv")
322 (match_operand 1 "constant_call_address_operand" ""))
325 (symbol_ref "ix86_attr_length_address_default (insn)")))
327 ;; Set when length prefix is used.
328 (define_attr "prefix_data16" ""
329 (if_then_else (ior (eq_attr "mode" "HI")
330 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
334 ;; Set when string REP prefix is used.
335 (define_attr "prefix_rep" ""
336 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
340 ;; Set when 0f opcode prefix is used.
341 (define_attr "prefix_0f" ""
343 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
344 (eq_attr "unit" "sse,mmx"))
348 ;; Set when REX opcode prefix is used.
349 (define_attr "prefix_rex" ""
350 (cond [(and (eq_attr "mode" "DI")
351 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
353 (and (eq_attr "mode" "QI")
354 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
357 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
363 ;; There are also additional prefixes in SSSE3.
364 (define_attr "prefix_extra" "" (const_int 0))
366 ;; Set when modrm byte is used.
367 (define_attr "modrm" ""
368 (cond [(eq_attr "type" "str,leave")
370 (eq_attr "unit" "i387")
372 (and (eq_attr "type" "incdec")
373 (ior (match_operand:SI 1 "register_operand" "")
374 (match_operand:HI 1 "register_operand" "")))
376 (and (eq_attr "type" "push")
377 (not (match_operand 1 "memory_operand" "")))
379 (and (eq_attr "type" "pop")
380 (not (match_operand 0 "memory_operand" "")))
382 (and (eq_attr "type" "imov")
383 (ior (and (match_operand 0 "register_operand" "")
384 (match_operand 1 "immediate_operand" ""))
385 (ior (and (match_operand 0 "ax_reg_operand" "")
386 (match_operand 1 "memory_displacement_only_operand" ""))
387 (and (match_operand 0 "memory_displacement_only_operand" "")
388 (match_operand 1 "ax_reg_operand" "")))))
390 (and (eq_attr "type" "call")
391 (match_operand 0 "constant_call_address_operand" ""))
393 (and (eq_attr "type" "callv")
394 (match_operand 1 "constant_call_address_operand" ""))
399 ;; The (bounding maximum) length of an instruction in bytes.
400 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
401 ;; Later we may want to split them and compute proper length as for
403 (define_attr "length" ""
404 (cond [(eq_attr "type" "other,multi,fistp,frndint")
406 (eq_attr "type" "fcmp")
408 (eq_attr "unit" "i387")
410 (plus (attr "prefix_data16")
411 (attr "length_address")))]
412 (plus (plus (attr "modrm")
413 (plus (attr "prefix_0f")
414 (plus (attr "prefix_rex")
415 (plus (attr "prefix_extra")
417 (plus (attr "prefix_rep")
418 (plus (attr "prefix_data16")
419 (plus (attr "length_immediate")
420 (attr "length_address")))))))
422 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
423 ;; `store' if there is a simple memory reference therein, or `unknown'
424 ;; if the instruction is complex.
426 (define_attr "memory" "none,load,store,both,unknown"
427 (cond [(eq_attr "type" "other,multi,str")
428 (const_string "unknown")
429 (eq_attr "type" "lea,fcmov,fpspc")
430 (const_string "none")
431 (eq_attr "type" "fistp,leave")
432 (const_string "both")
433 (eq_attr "type" "frndint")
434 (const_string "load")
435 (eq_attr "type" "push")
436 (if_then_else (match_operand 1 "memory_operand" "")
437 (const_string "both")
438 (const_string "store"))
439 (eq_attr "type" "pop")
440 (if_then_else (match_operand 0 "memory_operand" "")
441 (const_string "both")
442 (const_string "load"))
443 (eq_attr "type" "setcc")
444 (if_then_else (match_operand 0 "memory_operand" "")
445 (const_string "store")
446 (const_string "none"))
447 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
448 (if_then_else (ior (match_operand 0 "memory_operand" "")
449 (match_operand 1 "memory_operand" ""))
450 (const_string "load")
451 (const_string "none"))
452 (eq_attr "type" "ibr")
453 (if_then_else (match_operand 0 "memory_operand" "")
454 (const_string "load")
455 (const_string "none"))
456 (eq_attr "type" "call")
457 (if_then_else (match_operand 0 "constant_call_address_operand" "")
458 (const_string "none")
459 (const_string "load"))
460 (eq_attr "type" "callv")
461 (if_then_else (match_operand 1 "constant_call_address_operand" "")
462 (const_string "none")
463 (const_string "load"))
464 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
465 (match_operand 1 "memory_operand" ""))
466 (const_string "both")
467 (and (match_operand 0 "memory_operand" "")
468 (match_operand 1 "memory_operand" ""))
469 (const_string "both")
470 (match_operand 0 "memory_operand" "")
471 (const_string "store")
472 (match_operand 1 "memory_operand" "")
473 (const_string "load")
475 "!alu1,negnot,ishift1,
476 imov,imovx,icmp,test,bitmanip,
478 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
479 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
480 (match_operand 2 "memory_operand" ""))
481 (const_string "load")
482 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
483 (match_operand 3 "memory_operand" ""))
484 (const_string "load")
486 (const_string "none")))
488 ;; Indicates if an instruction has both an immediate and a displacement.
490 (define_attr "imm_disp" "false,true,unknown"
491 (cond [(eq_attr "type" "other,multi")
492 (const_string "unknown")
493 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
494 (and (match_operand 0 "memory_displacement_operand" "")
495 (match_operand 1 "immediate_operand" "")))
496 (const_string "true")
497 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
498 (and (match_operand 0 "memory_displacement_operand" "")
499 (match_operand 2 "immediate_operand" "")))
500 (const_string "true")
502 (const_string "false")))
504 ;; Indicates if an FP operation has an integer source.
506 (define_attr "fp_int_src" "false,true"
507 (const_string "false"))
509 ;; Defines rounding mode of an FP operation.
511 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
512 (const_string "any"))
514 ;; Describe a user's asm statement.
515 (define_asm_attributes
516 [(set_attr "length" "128")
517 (set_attr "type" "multi")])
519 (define_code_iterator plusminus [plus minus])
521 ;; Base name for define_insn and insn mnemonic.
522 (define_code_attr addsub [(plus "add") (minus "sub")])
524 ;; Mark commutative operators as such in constraints.
525 (define_code_attr comm [(plus "%") (minus "")])
527 ;; All single word integer modes.
528 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
530 ;; Instruction suffix for integer modes.
531 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
533 ;; Register class for integer modes.
534 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
536 ;; Immediate operand constraint for integer modes.
537 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
539 ;; General operand predicate for integer modes.
540 (define_mode_attr general_operand
541 [(QI "general_operand")
542 (HI "general_operand")
543 (SI "general_operand")
544 (DI "x86_64_general_operand")])
546 ;; SSE and x87 SFmode and DFmode floating point modes
547 (define_mode_iterator MODEF [SF DF])
549 ;; All x87 floating point modes
550 (define_mode_iterator X87MODEF [SF DF XF])
552 ;; All integer modes handled by x87 fisttp operator.
553 (define_mode_iterator X87MODEI [HI SI DI])
555 ;; All integer modes handled by integer x87 operators.
556 (define_mode_iterator X87MODEI12 [HI SI])
558 ;; All integer modes handled by SSE cvtts?2si* operators.
559 (define_mode_iterator SSEMODEI24 [SI DI])
561 ;; SSE asm suffix for floating point modes
562 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
564 ;; SSE vector mode corresponding to a scalar mode
565 (define_mode_attr ssevecmode
566 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
568 ;; Scheduling descriptions
570 (include "pentium.md")
573 (include "athlon.md")
577 ;; Operand and operator predicates and constraints
579 (include "predicates.md")
580 (include "constraints.md")
583 ;; Compare instructions.
585 ;; All compare insns have expanders that save the operands away without
586 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
587 ;; after the cmp) will actually emit the cmpM.
589 (define_expand "cmpti"
590 [(set (reg:CC FLAGS_REG)
591 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
592 (match_operand:TI 1 "x86_64_general_operand" "")))]
595 if (MEM_P (operands[0]) && MEM_P (operands[1]))
596 operands[0] = force_reg (TImode, operands[0]);
597 ix86_compare_op0 = operands[0];
598 ix86_compare_op1 = operands[1];
602 (define_expand "cmpdi"
603 [(set (reg:CC FLAGS_REG)
604 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
605 (match_operand:DI 1 "x86_64_general_operand" "")))]
608 if (MEM_P (operands[0]) && MEM_P (operands[1]))
609 operands[0] = force_reg (DImode, operands[0]);
610 ix86_compare_op0 = operands[0];
611 ix86_compare_op1 = operands[1];
615 (define_expand "cmpsi"
616 [(set (reg:CC FLAGS_REG)
617 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
618 (match_operand:SI 1 "general_operand" "")))]
621 if (MEM_P (operands[0]) && MEM_P (operands[1]))
622 operands[0] = force_reg (SImode, operands[0]);
623 ix86_compare_op0 = operands[0];
624 ix86_compare_op1 = operands[1];
628 (define_expand "cmphi"
629 [(set (reg:CC FLAGS_REG)
630 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
631 (match_operand:HI 1 "general_operand" "")))]
634 if (MEM_P (operands[0]) && MEM_P (operands[1]))
635 operands[0] = force_reg (HImode, operands[0]);
636 ix86_compare_op0 = operands[0];
637 ix86_compare_op1 = operands[1];
641 (define_expand "cmpqi"
642 [(set (reg:CC FLAGS_REG)
643 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
644 (match_operand:QI 1 "general_operand" "")))]
647 if (MEM_P (operands[0]) && MEM_P (operands[1]))
648 operands[0] = force_reg (QImode, operands[0]);
649 ix86_compare_op0 = operands[0];
650 ix86_compare_op1 = operands[1];
654 (define_insn "cmpdi_ccno_1_rex64"
655 [(set (reg FLAGS_REG)
656 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
657 (match_operand:DI 1 "const0_operand" "n,n")))]
658 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
661 cmp{q}\t{%1, %0|%0, %1}"
662 [(set_attr "type" "test,icmp")
663 (set_attr "length_immediate" "0,1")
664 (set_attr "mode" "DI")])
666 (define_insn "*cmpdi_minus_1_rex64"
667 [(set (reg FLAGS_REG)
668 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
669 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
671 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
672 "cmp{q}\t{%1, %0|%0, %1}"
673 [(set_attr "type" "icmp")
674 (set_attr "mode" "DI")])
676 (define_expand "cmpdi_1_rex64"
677 [(set (reg:CC FLAGS_REG)
678 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
679 (match_operand:DI 1 "general_operand" "")))]
683 (define_insn "cmpdi_1_insn_rex64"
684 [(set (reg FLAGS_REG)
685 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
686 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688 "cmp{q}\t{%1, %0|%0, %1}"
689 [(set_attr "type" "icmp")
690 (set_attr "mode" "DI")])
693 (define_insn "*cmpsi_ccno_1"
694 [(set (reg FLAGS_REG)
695 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
696 (match_operand:SI 1 "const0_operand" "n,n")))]
697 "ix86_match_ccmode (insn, CCNOmode)"
700 cmp{l}\t{%1, %0|%0, %1}"
701 [(set_attr "type" "test,icmp")
702 (set_attr "length_immediate" "0,1")
703 (set_attr "mode" "SI")])
705 (define_insn "*cmpsi_minus_1"
706 [(set (reg FLAGS_REG)
707 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
708 (match_operand:SI 1 "general_operand" "ri,mr"))
710 "ix86_match_ccmode (insn, CCGOCmode)"
711 "cmp{l}\t{%1, %0|%0, %1}"
712 [(set_attr "type" "icmp")
713 (set_attr "mode" "SI")])
715 (define_expand "cmpsi_1"
716 [(set (reg:CC FLAGS_REG)
717 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
718 (match_operand:SI 1 "general_operand" "")))]
722 (define_insn "*cmpsi_1_insn"
723 [(set (reg FLAGS_REG)
724 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
725 (match_operand:SI 1 "general_operand" "ri,mr")))]
726 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
727 && ix86_match_ccmode (insn, CCmode)"
728 "cmp{l}\t{%1, %0|%0, %1}"
729 [(set_attr "type" "icmp")
730 (set_attr "mode" "SI")])
732 (define_insn "*cmphi_ccno_1"
733 [(set (reg FLAGS_REG)
734 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
735 (match_operand:HI 1 "const0_operand" "n,n")))]
736 "ix86_match_ccmode (insn, CCNOmode)"
739 cmp{w}\t{%1, %0|%0, %1}"
740 [(set_attr "type" "test,icmp")
741 (set_attr "length_immediate" "0,1")
742 (set_attr "mode" "HI")])
744 (define_insn "*cmphi_minus_1"
745 [(set (reg FLAGS_REG)
746 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
747 (match_operand:HI 1 "general_operand" "ri,mr"))
749 "ix86_match_ccmode (insn, CCGOCmode)"
750 "cmp{w}\t{%1, %0|%0, %1}"
751 [(set_attr "type" "icmp")
752 (set_attr "mode" "HI")])
754 (define_insn "*cmphi_1"
755 [(set (reg FLAGS_REG)
756 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
757 (match_operand:HI 1 "general_operand" "ri,mr")))]
758 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
759 && ix86_match_ccmode (insn, CCmode)"
760 "cmp{w}\t{%1, %0|%0, %1}"
761 [(set_attr "type" "icmp")
762 (set_attr "mode" "HI")])
764 (define_insn "*cmpqi_ccno_1"
765 [(set (reg FLAGS_REG)
766 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
767 (match_operand:QI 1 "const0_operand" "n,n")))]
768 "ix86_match_ccmode (insn, CCNOmode)"
771 cmp{b}\t{$0, %0|%0, 0}"
772 [(set_attr "type" "test,icmp")
773 (set_attr "length_immediate" "0,1")
774 (set_attr "mode" "QI")])
776 (define_insn "*cmpqi_1"
777 [(set (reg FLAGS_REG)
778 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
779 (match_operand:QI 1 "general_operand" "qi,mq")))]
780 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
781 && ix86_match_ccmode (insn, CCmode)"
782 "cmp{b}\t{%1, %0|%0, %1}"
783 [(set_attr "type" "icmp")
784 (set_attr "mode" "QI")])
786 (define_insn "*cmpqi_minus_1"
787 [(set (reg FLAGS_REG)
788 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
789 (match_operand:QI 1 "general_operand" "qi,mq"))
791 "ix86_match_ccmode (insn, CCGOCmode)"
792 "cmp{b}\t{%1, %0|%0, %1}"
793 [(set_attr "type" "icmp")
794 (set_attr "mode" "QI")])
796 (define_insn "*cmpqi_ext_1"
797 [(set (reg FLAGS_REG)
799 (match_operand:QI 0 "general_operand" "Qm")
802 (match_operand 1 "ext_register_operand" "Q")
805 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
806 "cmp{b}\t{%h1, %0|%0, %h1}"
807 [(set_attr "type" "icmp")
808 (set_attr "mode" "QI")])
810 (define_insn "*cmpqi_ext_1_rex64"
811 [(set (reg FLAGS_REG)
813 (match_operand:QI 0 "register_operand" "Q")
816 (match_operand 1 "ext_register_operand" "Q")
819 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
820 "cmp{b}\t{%h1, %0|%0, %h1}"
821 [(set_attr "type" "icmp")
822 (set_attr "mode" "QI")])
824 (define_insn "*cmpqi_ext_2"
825 [(set (reg FLAGS_REG)
829 (match_operand 0 "ext_register_operand" "Q")
832 (match_operand:QI 1 "const0_operand" "n")))]
833 "ix86_match_ccmode (insn, CCNOmode)"
835 [(set_attr "type" "test")
836 (set_attr "length_immediate" "0")
837 (set_attr "mode" "QI")])
839 (define_expand "cmpqi_ext_3"
840 [(set (reg:CC FLAGS_REG)
844 (match_operand 0 "ext_register_operand" "")
847 (match_operand:QI 1 "general_operand" "")))]
851 (define_insn "cmpqi_ext_3_insn"
852 [(set (reg FLAGS_REG)
856 (match_operand 0 "ext_register_operand" "Q")
859 (match_operand:QI 1 "general_operand" "Qmn")))]
860 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
861 "cmp{b}\t{%1, %h0|%h0, %1}"
862 [(set_attr "type" "icmp")
863 (set_attr "mode" "QI")])
865 (define_insn "cmpqi_ext_3_insn_rex64"
866 [(set (reg FLAGS_REG)
870 (match_operand 0 "ext_register_operand" "Q")
873 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
874 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
875 "cmp{b}\t{%1, %h0|%h0, %1}"
876 [(set_attr "type" "icmp")
877 (set_attr "mode" "QI")])
879 (define_insn "*cmpqi_ext_4"
880 [(set (reg FLAGS_REG)
884 (match_operand 0 "ext_register_operand" "Q")
889 (match_operand 1 "ext_register_operand" "Q")
892 "ix86_match_ccmode (insn, CCmode)"
893 "cmp{b}\t{%h1, %h0|%h0, %h1}"
894 [(set_attr "type" "icmp")
895 (set_attr "mode" "QI")])
897 ;; These implement float point compares.
898 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
899 ;; which would allow mix and match FP modes on the compares. Which is what
900 ;; the old patterns did, but with many more of them.
902 (define_expand "cmpxf"
903 [(set (reg:CC FLAGS_REG)
904 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
905 (match_operand:XF 1 "nonmemory_operand" "")))]
908 ix86_compare_op0 = operands[0];
909 ix86_compare_op1 = operands[1];
913 (define_expand "cmp<mode>"
914 [(set (reg:CC FLAGS_REG)
915 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
916 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
917 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
919 ix86_compare_op0 = operands[0];
920 ix86_compare_op1 = operands[1];
924 ;; FP compares, step 1:
925 ;; Set the FP condition codes.
927 ;; CCFPmode compare with exceptions
928 ;; CCFPUmode compare with no exceptions
930 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
931 ;; used to manage the reg stack popping would not be preserved.
933 (define_insn "*cmpfp_0"
934 [(set (match_operand:HI 0 "register_operand" "=a")
937 (match_operand 1 "register_operand" "f")
938 (match_operand 2 "const0_operand" "X"))]
940 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
941 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
942 "* return output_fp_compare (insn, operands, 0, 0);"
943 [(set_attr "type" "multi")
944 (set_attr "unit" "i387")
946 (cond [(match_operand:SF 1 "" "")
948 (match_operand:DF 1 "" "")
951 (const_string "XF")))])
953 (define_insn_and_split "*cmpfp_0_cc"
954 [(set (reg:CCFP FLAGS_REG)
956 (match_operand 1 "register_operand" "f")
957 (match_operand 2 "const0_operand" "X")))
958 (clobber (match_operand:HI 0 "register_operand" "=a"))]
959 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
960 && TARGET_SAHF && !TARGET_CMOVE
961 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
963 "&& reload_completed"
966 [(compare:CCFP (match_dup 1)(match_dup 2))]
968 (set (reg:CC FLAGS_REG)
969 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
971 [(set_attr "type" "multi")
972 (set_attr "unit" "i387")
974 (cond [(match_operand:SF 1 "" "")
976 (match_operand:DF 1 "" "")
979 (const_string "XF")))])
981 (define_insn "*cmpfp_xf"
982 [(set (match_operand:HI 0 "register_operand" "=a")
985 (match_operand:XF 1 "register_operand" "f")
986 (match_operand:XF 2 "register_operand" "f"))]
989 "* return output_fp_compare (insn, operands, 0, 0);"
990 [(set_attr "type" "multi")
991 (set_attr "unit" "i387")
992 (set_attr "mode" "XF")])
994 (define_insn_and_split "*cmpfp_xf_cc"
995 [(set (reg:CCFP FLAGS_REG)
997 (match_operand:XF 1 "register_operand" "f")
998 (match_operand:XF 2 "register_operand" "f")))
999 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1001 && TARGET_SAHF && !TARGET_CMOVE"
1003 "&& reload_completed"
1006 [(compare:CCFP (match_dup 1)(match_dup 2))]
1008 (set (reg:CC FLAGS_REG)
1009 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1011 [(set_attr "type" "multi")
1012 (set_attr "unit" "i387")
1013 (set_attr "mode" "XF")])
1015 (define_insn "*cmpfp_<mode>"
1016 [(set (match_operand:HI 0 "register_operand" "=a")
1019 (match_operand:MODEF 1 "register_operand" "f")
1020 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1023 "* return output_fp_compare (insn, operands, 0, 0);"
1024 [(set_attr "type" "multi")
1025 (set_attr "unit" "i387")
1026 (set_attr "mode" "<MODE>")])
1028 (define_insn_and_split "*cmpfp_<mode>_cc"
1029 [(set (reg:CCFP FLAGS_REG)
1031 (match_operand:MODEF 1 "register_operand" "f")
1032 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1033 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1035 && TARGET_SAHF && !TARGET_CMOVE"
1037 "&& reload_completed"
1040 [(compare:CCFP (match_dup 1)(match_dup 2))]
1042 (set (reg:CC FLAGS_REG)
1043 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1045 [(set_attr "type" "multi")
1046 (set_attr "unit" "i387")
1047 (set_attr "mode" "<MODE>")])
1049 (define_insn "*cmpfp_u"
1050 [(set (match_operand:HI 0 "register_operand" "=a")
1053 (match_operand 1 "register_operand" "f")
1054 (match_operand 2 "register_operand" "f"))]
1056 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1057 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1058 "* return output_fp_compare (insn, operands, 0, 1);"
1059 [(set_attr "type" "multi")
1060 (set_attr "unit" "i387")
1062 (cond [(match_operand:SF 1 "" "")
1064 (match_operand:DF 1 "" "")
1067 (const_string "XF")))])
1069 (define_insn_and_split "*cmpfp_u_cc"
1070 [(set (reg:CCFPU FLAGS_REG)
1072 (match_operand 1 "register_operand" "f")
1073 (match_operand 2 "register_operand" "f")))
1074 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1075 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076 && TARGET_SAHF && !TARGET_CMOVE
1077 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1079 "&& reload_completed"
1082 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1084 (set (reg:CC FLAGS_REG)
1085 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1087 [(set_attr "type" "multi")
1088 (set_attr "unit" "i387")
1090 (cond [(match_operand:SF 1 "" "")
1092 (match_operand:DF 1 "" "")
1095 (const_string "XF")))])
1097 (define_insn "*cmpfp_<mode>"
1098 [(set (match_operand:HI 0 "register_operand" "=a")
1101 (match_operand 1 "register_operand" "f")
1102 (match_operator 3 "float_operator"
1103 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1105 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1106 && TARGET_USE_<MODE>MODE_FIOP
1107 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1108 "* return output_fp_compare (insn, operands, 0, 0);"
1109 [(set_attr "type" "multi")
1110 (set_attr "unit" "i387")
1111 (set_attr "fp_int_src" "true")
1112 (set_attr "mode" "<MODE>")])
1114 (define_insn_and_split "*cmpfp_<mode>_cc"
1115 [(set (reg:CCFP FLAGS_REG)
1117 (match_operand 1 "register_operand" "f")
1118 (match_operator 3 "float_operator"
1119 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1120 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1121 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1122 && TARGET_SAHF && !TARGET_CMOVE
1123 && TARGET_USE_<MODE>MODE_FIOP
1124 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1126 "&& reload_completed"
1131 (match_op_dup 3 [(match_dup 2)]))]
1133 (set (reg:CC FLAGS_REG)
1134 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1136 [(set_attr "type" "multi")
1137 (set_attr "unit" "i387")
1138 (set_attr "fp_int_src" "true")
1139 (set_attr "mode" "<MODE>")])
1141 ;; FP compares, step 2
1142 ;; Move the fpsw to ax.
1144 (define_insn "x86_fnstsw_1"
1145 [(set (match_operand:HI 0 "register_operand" "=a")
1146 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1149 [(set_attr "length" "2")
1150 (set_attr "mode" "SI")
1151 (set_attr "unit" "i387")])
1153 ;; FP compares, step 3
1154 ;; Get ax into flags, general case.
1156 (define_insn "x86_sahf_1"
1157 [(set (reg:CC FLAGS_REG)
1158 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1162 #ifdef HAVE_AS_IX86_SAHF
1165 return ".byte\t0x9e";
1168 [(set_attr "length" "1")
1169 (set_attr "athlon_decode" "vector")
1170 (set_attr "amdfam10_decode" "direct")
1171 (set_attr "mode" "SI")])
1173 ;; Pentium Pro can do steps 1 through 3 in one go.
1174 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1175 (define_insn "*cmpfp_i_mixed"
1176 [(set (reg:CCFP FLAGS_REG)
1177 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1178 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1179 "TARGET_MIX_SSE_I387
1180 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1181 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1182 "* return output_fp_compare (insn, operands, 1, 0);"
1183 [(set_attr "type" "fcmp,ssecomi")
1185 (if_then_else (match_operand:SF 1 "" "")
1187 (const_string "DF")))
1188 (set_attr "athlon_decode" "vector")
1189 (set_attr "amdfam10_decode" "direct")])
1191 (define_insn "*cmpfp_i_sse"
1192 [(set (reg:CCFP FLAGS_REG)
1193 (compare:CCFP (match_operand 0 "register_operand" "x")
1194 (match_operand 1 "nonimmediate_operand" "xm")))]
1196 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1197 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1198 "* return output_fp_compare (insn, operands, 1, 0);"
1199 [(set_attr "type" "ssecomi")
1201 (if_then_else (match_operand:SF 1 "" "")
1203 (const_string "DF")))
1204 (set_attr "athlon_decode" "vector")
1205 (set_attr "amdfam10_decode" "direct")])
1207 (define_insn "*cmpfp_i_i387"
1208 [(set (reg:CCFP FLAGS_REG)
1209 (compare:CCFP (match_operand 0 "register_operand" "f")
1210 (match_operand 1 "register_operand" "f")))]
1211 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1213 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1214 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1215 "* return output_fp_compare (insn, operands, 1, 0);"
1216 [(set_attr "type" "fcmp")
1218 (cond [(match_operand:SF 1 "" "")
1220 (match_operand:DF 1 "" "")
1223 (const_string "XF")))
1224 (set_attr "athlon_decode" "vector")
1225 (set_attr "amdfam10_decode" "direct")])
1227 (define_insn "*cmpfp_iu_mixed"
1228 [(set (reg:CCFPU FLAGS_REG)
1229 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1230 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1231 "TARGET_MIX_SSE_I387
1232 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1233 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1234 "* return output_fp_compare (insn, operands, 1, 1);"
1235 [(set_attr "type" "fcmp,ssecomi")
1237 (if_then_else (match_operand:SF 1 "" "")
1239 (const_string "DF")))
1240 (set_attr "athlon_decode" "vector")
1241 (set_attr "amdfam10_decode" "direct")])
1243 (define_insn "*cmpfp_iu_sse"
1244 [(set (reg:CCFPU FLAGS_REG)
1245 (compare:CCFPU (match_operand 0 "register_operand" "x")
1246 (match_operand 1 "nonimmediate_operand" "xm")))]
1248 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1249 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1250 "* return output_fp_compare (insn, operands, 1, 1);"
1251 [(set_attr "type" "ssecomi")
1253 (if_then_else (match_operand:SF 1 "" "")
1255 (const_string "DF")))
1256 (set_attr "athlon_decode" "vector")
1257 (set_attr "amdfam10_decode" "direct")])
1259 (define_insn "*cmpfp_iu_387"
1260 [(set (reg:CCFPU FLAGS_REG)
1261 (compare:CCFPU (match_operand 0 "register_operand" "f")
1262 (match_operand 1 "register_operand" "f")))]
1263 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1265 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1266 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1267 "* return output_fp_compare (insn, operands, 1, 1);"
1268 [(set_attr "type" "fcmp")
1270 (cond [(match_operand:SF 1 "" "")
1272 (match_operand:DF 1 "" "")
1275 (const_string "XF")))
1276 (set_attr "athlon_decode" "vector")
1277 (set_attr "amdfam10_decode" "direct")])
1279 ;; Move instructions.
1281 ;; General case of fullword move.
1283 (define_expand "movsi"
1284 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1285 (match_operand:SI 1 "general_operand" ""))]
1287 "ix86_expand_move (SImode, operands); DONE;")
1289 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1292 ;; %%% We don't use a post-inc memory reference because x86 is not a
1293 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1294 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1295 ;; targets without our curiosities, and it is just as easy to represent
1296 ;; this differently.
1298 (define_insn "*pushsi2"
1299 [(set (match_operand:SI 0 "push_operand" "=<")
1300 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1303 [(set_attr "type" "push")
1304 (set_attr "mode" "SI")])
1306 ;; For 64BIT abi we always round up to 8 bytes.
1307 (define_insn "*pushsi2_rex64"
1308 [(set (match_operand:SI 0 "push_operand" "=X")
1309 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1312 [(set_attr "type" "push")
1313 (set_attr "mode" "SI")])
1315 (define_insn "*pushsi2_prologue"
1316 [(set (match_operand:SI 0 "push_operand" "=<")
1317 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1318 (clobber (mem:BLK (scratch)))]
1321 [(set_attr "type" "push")
1322 (set_attr "mode" "SI")])
1324 (define_insn "*popsi1_epilogue"
1325 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1326 (mem:SI (reg:SI SP_REG)))
1327 (set (reg:SI SP_REG)
1328 (plus:SI (reg:SI SP_REG) (const_int 4)))
1329 (clobber (mem:BLK (scratch)))]
1332 [(set_attr "type" "pop")
1333 (set_attr "mode" "SI")])
1335 (define_insn "popsi1"
1336 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1337 (mem:SI (reg:SI SP_REG)))
1338 (set (reg:SI SP_REG)
1339 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1342 [(set_attr "type" "pop")
1343 (set_attr "mode" "SI")])
1345 (define_insn "*movsi_xor"
1346 [(set (match_operand:SI 0 "register_operand" "=r")
1347 (match_operand:SI 1 "const0_operand" "i"))
1348 (clobber (reg:CC FLAGS_REG))]
1349 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1351 [(set_attr "type" "alu1")
1352 (set_attr "mode" "SI")
1353 (set_attr "length_immediate" "0")])
1355 (define_insn "*movsi_or"
1356 [(set (match_operand:SI 0 "register_operand" "=r")
1357 (match_operand:SI 1 "immediate_operand" "i"))
1358 (clobber (reg:CC FLAGS_REG))]
1360 && operands[1] == constm1_rtx
1361 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1363 operands[1] = constm1_rtx;
1364 return "or{l}\t{%1, %0|%0, %1}";
1366 [(set_attr "type" "alu1")
1367 (set_attr "mode" "SI")
1368 (set_attr "length_immediate" "1")])
1370 (define_insn "*movsi_1"
1371 [(set (match_operand:SI 0 "nonimmediate_operand"
1372 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1373 (match_operand:SI 1 "general_operand"
1374 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1375 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1377 switch (get_attr_type (insn))
1380 if (get_attr_mode (insn) == MODE_TI)
1381 return "pxor\t%0, %0";
1382 return "xorps\t%0, %0";
1385 switch (get_attr_mode (insn))
1388 return "movdqa\t{%1, %0|%0, %1}";
1390 return "movaps\t{%1, %0|%0, %1}";
1392 return "movd\t{%1, %0|%0, %1}";
1394 return "movss\t{%1, %0|%0, %1}";
1400 return "pxor\t%0, %0";
1403 if (get_attr_mode (insn) == MODE_DI)
1404 return "movq\t{%1, %0|%0, %1}";
1405 return "movd\t{%1, %0|%0, %1}";
1408 return "lea{l}\t{%1, %0|%0, %1}";
1411 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1412 return "mov{l}\t{%1, %0|%0, %1}";
1416 (cond [(eq_attr "alternative" "2")
1417 (const_string "mmxadd")
1418 (eq_attr "alternative" "3,4,5")
1419 (const_string "mmxmov")
1420 (eq_attr "alternative" "6")
1421 (const_string "sselog1")
1422 (eq_attr "alternative" "7,8,9,10,11")
1423 (const_string "ssemov")
1424 (match_operand:DI 1 "pic_32bit_operand" "")
1425 (const_string "lea")
1427 (const_string "imov")))
1429 (cond [(eq_attr "alternative" "2,3")
1431 (eq_attr "alternative" "6,7")
1433 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1434 (const_string "V4SF")
1435 (const_string "TI"))
1436 (and (eq_attr "alternative" "8,9,10,11")
1437 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1440 (const_string "SI")))])
1442 ;; Stores and loads of ax to arbitrary constant address.
1443 ;; We fake an second form of instruction to force reload to load address
1444 ;; into register when rax is not available
1445 (define_insn "*movabssi_1_rex64"
1446 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1447 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1448 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1450 movabs{l}\t{%1, %P0|%P0, %1}
1451 mov{l}\t{%1, %a0|%a0, %1}"
1452 [(set_attr "type" "imov")
1453 (set_attr "modrm" "0,*")
1454 (set_attr "length_address" "8,0")
1455 (set_attr "length_immediate" "0,*")
1456 (set_attr "memory" "store")
1457 (set_attr "mode" "SI")])
1459 (define_insn "*movabssi_2_rex64"
1460 [(set (match_operand:SI 0 "register_operand" "=a,r")
1461 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1462 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1464 movabs{l}\t{%P1, %0|%0, %P1}
1465 mov{l}\t{%a1, %0|%0, %a1}"
1466 [(set_attr "type" "imov")
1467 (set_attr "modrm" "0,*")
1468 (set_attr "length_address" "8,0")
1469 (set_attr "length_immediate" "0")
1470 (set_attr "memory" "load")
1471 (set_attr "mode" "SI")])
1473 (define_insn "*swapsi"
1474 [(set (match_operand:SI 0 "register_operand" "+r")
1475 (match_operand:SI 1 "register_operand" "+r"))
1480 [(set_attr "type" "imov")
1481 (set_attr "mode" "SI")
1482 (set_attr "pent_pair" "np")
1483 (set_attr "athlon_decode" "vector")
1484 (set_attr "amdfam10_decode" "double")])
1486 (define_expand "movhi"
1487 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1488 (match_operand:HI 1 "general_operand" ""))]
1490 "ix86_expand_move (HImode, operands); DONE;")
1492 (define_insn "*pushhi2"
1493 [(set (match_operand:HI 0 "push_operand" "=X")
1494 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1497 [(set_attr "type" "push")
1498 (set_attr "mode" "SI")])
1500 ;; For 64BIT abi we always round up to 8 bytes.
1501 (define_insn "*pushhi2_rex64"
1502 [(set (match_operand:HI 0 "push_operand" "=X")
1503 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1506 [(set_attr "type" "push")
1507 (set_attr "mode" "DI")])
1509 (define_insn "*movhi_1"
1510 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1511 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1512 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1514 switch (get_attr_type (insn))
1517 /* movzwl is faster than movw on p2 due to partial word stalls,
1518 though not as fast as an aligned movl. */
1519 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1521 if (get_attr_mode (insn) == MODE_SI)
1522 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1524 return "mov{w}\t{%1, %0|%0, %1}";
1528 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1529 (const_string "imov")
1530 (and (eq_attr "alternative" "0")
1531 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1533 (eq (symbol_ref "TARGET_HIMODE_MATH")
1535 (const_string "imov")
1536 (and (eq_attr "alternative" "1,2")
1537 (match_operand:HI 1 "aligned_operand" ""))
1538 (const_string "imov")
1539 (and (ne (symbol_ref "TARGET_MOVX")
1541 (eq_attr "alternative" "0,2"))
1542 (const_string "imovx")
1544 (const_string "imov")))
1546 (cond [(eq_attr "type" "imovx")
1548 (and (eq_attr "alternative" "1,2")
1549 (match_operand:HI 1 "aligned_operand" ""))
1551 (and (eq_attr "alternative" "0")
1552 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1554 (eq (symbol_ref "TARGET_HIMODE_MATH")
1558 (const_string "HI")))])
1560 ;; Stores and loads of ax to arbitrary constant address.
1561 ;; We fake an second form of instruction to force reload to load address
1562 ;; into register when rax is not available
1563 (define_insn "*movabshi_1_rex64"
1564 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1565 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1566 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1568 movabs{w}\t{%1, %P0|%P0, %1}
1569 mov{w}\t{%1, %a0|%a0, %1}"
1570 [(set_attr "type" "imov")
1571 (set_attr "modrm" "0,*")
1572 (set_attr "length_address" "8,0")
1573 (set_attr "length_immediate" "0,*")
1574 (set_attr "memory" "store")
1575 (set_attr "mode" "HI")])
1577 (define_insn "*movabshi_2_rex64"
1578 [(set (match_operand:HI 0 "register_operand" "=a,r")
1579 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1580 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1582 movabs{w}\t{%P1, %0|%0, %P1}
1583 mov{w}\t{%a1, %0|%0, %a1}"
1584 [(set_attr "type" "imov")
1585 (set_attr "modrm" "0,*")
1586 (set_attr "length_address" "8,0")
1587 (set_attr "length_immediate" "0")
1588 (set_attr "memory" "load")
1589 (set_attr "mode" "HI")])
1591 (define_insn "*swaphi_1"
1592 [(set (match_operand:HI 0 "register_operand" "+r")
1593 (match_operand:HI 1 "register_operand" "+r"))
1596 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1598 [(set_attr "type" "imov")
1599 (set_attr "mode" "SI")
1600 (set_attr "pent_pair" "np")
1601 (set_attr "athlon_decode" "vector")
1602 (set_attr "amdfam10_decode" "double")])
1604 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1605 (define_insn "*swaphi_2"
1606 [(set (match_operand:HI 0 "register_operand" "+r")
1607 (match_operand:HI 1 "register_operand" "+r"))
1610 "TARGET_PARTIAL_REG_STALL"
1612 [(set_attr "type" "imov")
1613 (set_attr "mode" "HI")
1614 (set_attr "pent_pair" "np")
1615 (set_attr "athlon_decode" "vector")])
1617 (define_expand "movstricthi"
1618 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1619 (match_operand:HI 1 "general_operand" ""))]
1620 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1622 /* Don't generate memory->memory moves, go through a register */
1623 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1624 operands[1] = force_reg (HImode, operands[1]);
1627 (define_insn "*movstricthi_1"
1628 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1629 (match_operand:HI 1 "general_operand" "rn,m"))]
1630 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1631 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1632 "mov{w}\t{%1, %0|%0, %1}"
1633 [(set_attr "type" "imov")
1634 (set_attr "mode" "HI")])
1636 (define_insn "*movstricthi_xor"
1637 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1638 (match_operand:HI 1 "const0_operand" "i"))
1639 (clobber (reg:CC FLAGS_REG))]
1641 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1643 [(set_attr "type" "alu1")
1644 (set_attr "mode" "HI")
1645 (set_attr "length_immediate" "0")])
1647 (define_expand "movqi"
1648 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1649 (match_operand:QI 1 "general_operand" ""))]
1651 "ix86_expand_move (QImode, operands); DONE;")
1653 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1654 ;; "push a byte". But actually we use pushl, which has the effect
1655 ;; of rounding the amount pushed up to a word.
1657 (define_insn "*pushqi2"
1658 [(set (match_operand:QI 0 "push_operand" "=X")
1659 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1662 [(set_attr "type" "push")
1663 (set_attr "mode" "SI")])
1665 ;; For 64BIT abi we always round up to 8 bytes.
1666 (define_insn "*pushqi2_rex64"
1667 [(set (match_operand:QI 0 "push_operand" "=X")
1668 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1671 [(set_attr "type" "push")
1672 (set_attr "mode" "DI")])
1674 ;; Situation is quite tricky about when to choose full sized (SImode) move
1675 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1676 ;; partial register dependency machines (such as AMD Athlon), where QImode
1677 ;; moves issue extra dependency and for partial register stalls machines
1678 ;; that don't use QImode patterns (and QImode move cause stall on the next
1681 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1682 ;; register stall machines with, where we use QImode instructions, since
1683 ;; partial register stall can be caused there. Then we use movzx.
1684 (define_insn "*movqi_1"
1685 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1686 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1687 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1689 switch (get_attr_type (insn))
1692 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1693 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1695 if (get_attr_mode (insn) == MODE_SI)
1696 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1698 return "mov{b}\t{%1, %0|%0, %1}";
1702 (cond [(and (eq_attr "alternative" "5")
1703 (not (match_operand:QI 1 "aligned_operand" "")))
1704 (const_string "imovx")
1705 (ne (symbol_ref "optimize_size") (const_int 0))
1706 (const_string "imov")
1707 (and (eq_attr "alternative" "3")
1708 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1710 (eq (symbol_ref "TARGET_QIMODE_MATH")
1712 (const_string "imov")
1713 (eq_attr "alternative" "3,5")
1714 (const_string "imovx")
1715 (and (ne (symbol_ref "TARGET_MOVX")
1717 (eq_attr "alternative" "2"))
1718 (const_string "imovx")
1720 (const_string "imov")))
1722 (cond [(eq_attr "alternative" "3,4,5")
1724 (eq_attr "alternative" "6")
1726 (eq_attr "type" "imovx")
1728 (and (eq_attr "type" "imov")
1729 (and (eq_attr "alternative" "0,1")
1730 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1732 (and (eq (symbol_ref "optimize_size")
1734 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1737 ;; Avoid partial register stalls when not using QImode arithmetic
1738 (and (eq_attr "type" "imov")
1739 (and (eq_attr "alternative" "0,1")
1740 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1742 (eq (symbol_ref "TARGET_QIMODE_MATH")
1746 (const_string "QI")))])
1748 (define_expand "reload_outqi"
1749 [(parallel [(match_operand:QI 0 "" "=m")
1750 (match_operand:QI 1 "register_operand" "r")
1751 (match_operand:QI 2 "register_operand" "=&q")])]
1755 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1757 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1758 if (! q_regs_operand (op1, QImode))
1760 emit_insn (gen_movqi (op2, op1));
1763 emit_insn (gen_movqi (op0, op1));
1767 (define_insn "*swapqi_1"
1768 [(set (match_operand:QI 0 "register_operand" "+r")
1769 (match_operand:QI 1 "register_operand" "+r"))
1772 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1774 [(set_attr "type" "imov")
1775 (set_attr "mode" "SI")
1776 (set_attr "pent_pair" "np")
1777 (set_attr "athlon_decode" "vector")
1778 (set_attr "amdfam10_decode" "vector")])
1780 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1781 (define_insn "*swapqi_2"
1782 [(set (match_operand:QI 0 "register_operand" "+q")
1783 (match_operand:QI 1 "register_operand" "+q"))
1786 "TARGET_PARTIAL_REG_STALL"
1788 [(set_attr "type" "imov")
1789 (set_attr "mode" "QI")
1790 (set_attr "pent_pair" "np")
1791 (set_attr "athlon_decode" "vector")])
1793 (define_expand "movstrictqi"
1794 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1795 (match_operand:QI 1 "general_operand" ""))]
1796 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1798 /* Don't generate memory->memory moves, go through a register. */
1799 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1800 operands[1] = force_reg (QImode, operands[1]);
1803 (define_insn "*movstrictqi_1"
1804 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1805 (match_operand:QI 1 "general_operand" "*qn,m"))]
1806 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1808 "mov{b}\t{%1, %0|%0, %1}"
1809 [(set_attr "type" "imov")
1810 (set_attr "mode" "QI")])
1812 (define_insn "*movstrictqi_xor"
1813 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1814 (match_operand:QI 1 "const0_operand" "i"))
1815 (clobber (reg:CC FLAGS_REG))]
1816 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1818 [(set_attr "type" "alu1")
1819 (set_attr "mode" "QI")
1820 (set_attr "length_immediate" "0")])
1822 (define_insn "*movsi_extv_1"
1823 [(set (match_operand:SI 0 "register_operand" "=R")
1824 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1828 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1829 [(set_attr "type" "imovx")
1830 (set_attr "mode" "SI")])
1832 (define_insn "*movhi_extv_1"
1833 [(set (match_operand:HI 0 "register_operand" "=R")
1834 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1838 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1839 [(set_attr "type" "imovx")
1840 (set_attr "mode" "SI")])
1842 (define_insn "*movqi_extv_1"
1843 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1844 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1849 switch (get_attr_type (insn))
1852 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1854 return "mov{b}\t{%h1, %0|%0, %h1}";
1858 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1859 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1860 (ne (symbol_ref "TARGET_MOVX")
1862 (const_string "imovx")
1863 (const_string "imov")))
1865 (if_then_else (eq_attr "type" "imovx")
1867 (const_string "QI")))])
1869 (define_insn "*movqi_extv_1_rex64"
1870 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1871 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1876 switch (get_attr_type (insn))
1879 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1881 return "mov{b}\t{%h1, %0|%0, %h1}";
1885 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1886 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1887 (ne (symbol_ref "TARGET_MOVX")
1889 (const_string "imovx")
1890 (const_string "imov")))
1892 (if_then_else (eq_attr "type" "imovx")
1894 (const_string "QI")))])
1896 ;; Stores and loads of ax to arbitrary constant address.
1897 ;; We fake an second form of instruction to force reload to load address
1898 ;; into register when rax is not available
1899 (define_insn "*movabsqi_1_rex64"
1900 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1901 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1902 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1904 movabs{b}\t{%1, %P0|%P0, %1}
1905 mov{b}\t{%1, %a0|%a0, %1}"
1906 [(set_attr "type" "imov")
1907 (set_attr "modrm" "0,*")
1908 (set_attr "length_address" "8,0")
1909 (set_attr "length_immediate" "0,*")
1910 (set_attr "memory" "store")
1911 (set_attr "mode" "QI")])
1913 (define_insn "*movabsqi_2_rex64"
1914 [(set (match_operand:QI 0 "register_operand" "=a,r")
1915 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1916 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1918 movabs{b}\t{%P1, %0|%0, %P1}
1919 mov{b}\t{%a1, %0|%0, %a1}"
1920 [(set_attr "type" "imov")
1921 (set_attr "modrm" "0,*")
1922 (set_attr "length_address" "8,0")
1923 (set_attr "length_immediate" "0")
1924 (set_attr "memory" "load")
1925 (set_attr "mode" "QI")])
1927 (define_insn "*movdi_extzv_1"
1928 [(set (match_operand:DI 0 "register_operand" "=R")
1929 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1933 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1934 [(set_attr "type" "imovx")
1935 (set_attr "mode" "DI")])
1937 (define_insn "*movsi_extzv_1"
1938 [(set (match_operand:SI 0 "register_operand" "=R")
1939 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1943 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1944 [(set_attr "type" "imovx")
1945 (set_attr "mode" "SI")])
1947 (define_insn "*movqi_extzv_2"
1948 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1949 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1954 switch (get_attr_type (insn))
1957 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1959 return "mov{b}\t{%h1, %0|%0, %h1}";
1963 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1964 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1965 (ne (symbol_ref "TARGET_MOVX")
1967 (const_string "imovx")
1968 (const_string "imov")))
1970 (if_then_else (eq_attr "type" "imovx")
1972 (const_string "QI")))])
1974 (define_insn "*movqi_extzv_2_rex64"
1975 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1976 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1981 switch (get_attr_type (insn))
1984 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1986 return "mov{b}\t{%h1, %0|%0, %h1}";
1990 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1991 (ne (symbol_ref "TARGET_MOVX")
1993 (const_string "imovx")
1994 (const_string "imov")))
1996 (if_then_else (eq_attr "type" "imovx")
1998 (const_string "QI")))])
2000 (define_insn "movsi_insv_1"
2001 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2004 (match_operand:SI 1 "general_operand" "Qmn"))]
2006 "mov{b}\t{%b1, %h0|%h0, %b1}"
2007 [(set_attr "type" "imov")
2008 (set_attr "mode" "QI")])
2010 (define_insn "*movsi_insv_1_rex64"
2011 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2014 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2016 "mov{b}\t{%b1, %h0|%h0, %b1}"
2017 [(set_attr "type" "imov")
2018 (set_attr "mode" "QI")])
2020 (define_insn "movdi_insv_1_rex64"
2021 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2024 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2026 "mov{b}\t{%b1, %h0|%h0, %b1}"
2027 [(set_attr "type" "imov")
2028 (set_attr "mode" "QI")])
2030 (define_insn "*movqi_insv_2"
2031 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2034 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2037 "mov{b}\t{%h1, %h0|%h0, %h1}"
2038 [(set_attr "type" "imov")
2039 (set_attr "mode" "QI")])
2041 (define_expand "movdi"
2042 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2043 (match_operand:DI 1 "general_operand" ""))]
2045 "ix86_expand_move (DImode, operands); DONE;")
2047 (define_insn "*pushdi"
2048 [(set (match_operand:DI 0 "push_operand" "=<")
2049 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2053 (define_insn "*pushdi2_rex64"
2054 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2055 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2060 [(set_attr "type" "push,multi")
2061 (set_attr "mode" "DI")])
2063 ;; Convert impossible pushes of immediate to existing instructions.
2064 ;; First try to get scratch register and go through it. In case this
2065 ;; fails, push sign extended lower part first and then overwrite
2066 ;; upper part by 32bit move.
2068 [(match_scratch:DI 2 "r")
2069 (set (match_operand:DI 0 "push_operand" "")
2070 (match_operand:DI 1 "immediate_operand" ""))]
2071 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072 && !x86_64_immediate_operand (operands[1], DImode)"
2073 [(set (match_dup 2) (match_dup 1))
2074 (set (match_dup 0) (match_dup 2))]
2077 ;; We need to define this as both peepholer and splitter for case
2078 ;; peephole2 pass is not run.
2079 ;; "&& 1" is needed to keep it from matching the previous pattern.
2081 [(set (match_operand:DI 0 "push_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2085 [(set (match_dup 0) (match_dup 1))
2086 (set (match_dup 2) (match_dup 3))]
2087 "split_di (operands + 1, 1, operands + 2, operands + 3);
2088 operands[1] = gen_lowpart (DImode, operands[2]);
2089 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2094 [(set (match_operand:DI 0 "push_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2097 ? epilogue_completed : reload_completed)
2098 && !symbolic_operand (operands[1], DImode)
2099 && !x86_64_immediate_operand (operands[1], DImode)"
2100 [(set (match_dup 0) (match_dup 1))
2101 (set (match_dup 2) (match_dup 3))]
2102 "split_di (operands + 1, 1, operands + 2, operands + 3);
2103 operands[1] = gen_lowpart (DImode, operands[2]);
2104 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2108 (define_insn "*pushdi2_prologue_rex64"
2109 [(set (match_operand:DI 0 "push_operand" "=<")
2110 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2111 (clobber (mem:BLK (scratch)))]
2114 [(set_attr "type" "push")
2115 (set_attr "mode" "DI")])
2117 (define_insn "*popdi1_epilogue_rex64"
2118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2119 (mem:DI (reg:DI SP_REG)))
2120 (set (reg:DI SP_REG)
2121 (plus:DI (reg:DI SP_REG) (const_int 8)))
2122 (clobber (mem:BLK (scratch)))]
2125 [(set_attr "type" "pop")
2126 (set_attr "mode" "DI")])
2128 (define_insn "popdi1"
2129 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2130 (mem:DI (reg:DI SP_REG)))
2131 (set (reg:DI SP_REG)
2132 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2135 [(set_attr "type" "pop")
2136 (set_attr "mode" "DI")])
2138 (define_insn "*movdi_xor_rex64"
2139 [(set (match_operand:DI 0 "register_operand" "=r")
2140 (match_operand:DI 1 "const0_operand" "i"))
2141 (clobber (reg:CC FLAGS_REG))]
2142 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2143 && reload_completed"
2145 [(set_attr "type" "alu1")
2146 (set_attr "mode" "SI")
2147 (set_attr "length_immediate" "0")])
2149 (define_insn "*movdi_or_rex64"
2150 [(set (match_operand:DI 0 "register_operand" "=r")
2151 (match_operand:DI 1 "const_int_operand" "i"))
2152 (clobber (reg:CC FLAGS_REG))]
2153 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2155 && operands[1] == constm1_rtx"
2157 operands[1] = constm1_rtx;
2158 return "or{q}\t{%1, %0|%0, %1}";
2160 [(set_attr "type" "alu1")
2161 (set_attr "mode" "DI")
2162 (set_attr "length_immediate" "1")])
2164 (define_insn "*movdi_2"
2165 [(set (match_operand:DI 0 "nonimmediate_operand"
2166 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2167 (match_operand:DI 1 "general_operand"
2168 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2169 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2174 movq\t{%1, %0|%0, %1}
2175 movq\t{%1, %0|%0, %1}
2177 movq\t{%1, %0|%0, %1}
2178 movdqa\t{%1, %0|%0, %1}
2179 movq\t{%1, %0|%0, %1}
2181 movlps\t{%1, %0|%0, %1}
2182 movaps\t{%1, %0|%0, %1}
2183 movlps\t{%1, %0|%0, %1}"
2184 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2185 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2188 [(set (match_operand:DI 0 "push_operand" "")
2189 (match_operand:DI 1 "general_operand" ""))]
2190 "!TARGET_64BIT && reload_completed
2191 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2193 "ix86_split_long_move (operands); DONE;")
2195 ;; %%% This multiword shite has got to go.
2197 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2198 (match_operand:DI 1 "general_operand" ""))]
2199 "!TARGET_64BIT && reload_completed
2200 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2201 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2203 "ix86_split_long_move (operands); DONE;")
2205 (define_insn "*movdi_1_rex64"
2206 [(set (match_operand:DI 0 "nonimmediate_operand"
2207 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2208 (match_operand:DI 1 "general_operand"
2209 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2210 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2212 switch (get_attr_type (insn))
2215 if (SSE_REG_P (operands[0]))
2216 return "movq2dq\t{%1, %0|%0, %1}";
2218 return "movdq2q\t{%1, %0|%0, %1}";
2221 if (get_attr_mode (insn) == MODE_TI)
2222 return "movdqa\t{%1, %0|%0, %1}";
2226 /* Moves from and into integer register is done using movd
2227 opcode with REX prefix. */
2228 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2229 return "movd\t{%1, %0|%0, %1}";
2230 return "movq\t{%1, %0|%0, %1}";
2234 return "pxor\t%0, %0";
2240 return "lea{q}\t{%a1, %0|%0, %a1}";
2243 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2244 if (get_attr_mode (insn) == MODE_SI)
2245 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2246 else if (which_alternative == 2)
2247 return "movabs{q}\t{%1, %0|%0, %1}";
2249 return "mov{q}\t{%1, %0|%0, %1}";
2253 (cond [(eq_attr "alternative" "5")
2254 (const_string "mmxadd")
2255 (eq_attr "alternative" "6,7,8,9,10")
2256 (const_string "mmxmov")
2257 (eq_attr "alternative" "11")
2258 (const_string "sselog1")
2259 (eq_attr "alternative" "12,13,14,15,16")
2260 (const_string "ssemov")
2261 (eq_attr "alternative" "17,18")
2262 (const_string "ssecvt")
2263 (eq_attr "alternative" "4")
2264 (const_string "multi")
2265 (match_operand:DI 1 "pic_32bit_operand" "")
2266 (const_string "lea")
2268 (const_string "imov")))
2269 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2270 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2271 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2273 ;; Stores and loads of ax to arbitrary constant address.
2274 ;; We fake an second form of instruction to force reload to load address
2275 ;; into register when rax is not available
2276 (define_insn "*movabsdi_1_rex64"
2277 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2278 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2279 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2281 movabs{q}\t{%1, %P0|%P0, %1}
2282 mov{q}\t{%1, %a0|%a0, %1}"
2283 [(set_attr "type" "imov")
2284 (set_attr "modrm" "0,*")
2285 (set_attr "length_address" "8,0")
2286 (set_attr "length_immediate" "0,*")
2287 (set_attr "memory" "store")
2288 (set_attr "mode" "DI")])
2290 (define_insn "*movabsdi_2_rex64"
2291 [(set (match_operand:DI 0 "register_operand" "=a,r")
2292 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2293 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2295 movabs{q}\t{%P1, %0|%0, %P1}
2296 mov{q}\t{%a1, %0|%0, %a1}"
2297 [(set_attr "type" "imov")
2298 (set_attr "modrm" "0,*")
2299 (set_attr "length_address" "8,0")
2300 (set_attr "length_immediate" "0")
2301 (set_attr "memory" "load")
2302 (set_attr "mode" "DI")])
2304 ;; Convert impossible stores of immediate to existing instructions.
2305 ;; First try to get scratch register and go through it. In case this
2306 ;; fails, move by 32bit parts.
2308 [(match_scratch:DI 2 "r")
2309 (set (match_operand:DI 0 "memory_operand" "")
2310 (match_operand:DI 1 "immediate_operand" ""))]
2311 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2312 && !x86_64_immediate_operand (operands[1], DImode)"
2313 [(set (match_dup 2) (match_dup 1))
2314 (set (match_dup 0) (match_dup 2))]
2317 ;; We need to define this as both peepholer and splitter for case
2318 ;; peephole2 pass is not run.
2319 ;; "&& 1" is needed to keep it from matching the previous pattern.
2321 [(set (match_operand:DI 0 "memory_operand" "")
2322 (match_operand:DI 1 "immediate_operand" ""))]
2323 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2324 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2325 [(set (match_dup 2) (match_dup 3))
2326 (set (match_dup 4) (match_dup 5))]
2327 "split_di (operands, 2, operands + 2, operands + 4);")
2330 [(set (match_operand:DI 0 "memory_operand" "")
2331 (match_operand:DI 1 "immediate_operand" ""))]
2332 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2333 ? epilogue_completed : reload_completed)
2334 && !symbolic_operand (operands[1], DImode)
2335 && !x86_64_immediate_operand (operands[1], DImode)"
2336 [(set (match_dup 2) (match_dup 3))
2337 (set (match_dup 4) (match_dup 5))]
2338 "split_di (operands, 2, operands + 2, operands + 4);")
2340 (define_insn "*swapdi_rex64"
2341 [(set (match_operand:DI 0 "register_operand" "+r")
2342 (match_operand:DI 1 "register_operand" "+r"))
2347 [(set_attr "type" "imov")
2348 (set_attr "mode" "DI")
2349 (set_attr "pent_pair" "np")
2350 (set_attr "athlon_decode" "vector")
2351 (set_attr "amdfam10_decode" "double")])
2353 (define_expand "movti"
2354 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2355 (match_operand:TI 1 "nonimmediate_operand" ""))]
2356 "TARGET_SSE || TARGET_64BIT"
2359 ix86_expand_move (TImode, operands);
2360 else if (push_operand (operands[0], TImode))
2361 ix86_expand_push (TImode, operands[1]);
2363 ix86_expand_vector_move (TImode, operands);
2367 (define_insn "*movti_internal"
2368 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2369 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2370 "TARGET_SSE && !TARGET_64BIT
2371 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2373 switch (which_alternative)
2376 if (get_attr_mode (insn) == MODE_V4SF)
2377 return "xorps\t%0, %0";
2379 return "pxor\t%0, %0";
2382 if (get_attr_mode (insn) == MODE_V4SF)
2383 return "movaps\t{%1, %0|%0, %1}";
2385 return "movdqa\t{%1, %0|%0, %1}";
2390 [(set_attr "type" "sselog1,ssemov,ssemov")
2392 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2393 (ne (symbol_ref "optimize_size") (const_int 0)))
2394 (const_string "V4SF")
2395 (and (eq_attr "alternative" "2")
2396 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2398 (const_string "V4SF")]
2399 (const_string "TI")))])
2401 (define_insn "*movti_rex64"
2402 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2403 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2407 switch (which_alternative)
2413 if (get_attr_mode (insn) == MODE_V4SF)
2414 return "xorps\t%0, %0";
2416 return "pxor\t%0, %0";
2419 if (get_attr_mode (insn) == MODE_V4SF)
2420 return "movaps\t{%1, %0|%0, %1}";
2422 return "movdqa\t{%1, %0|%0, %1}";
2427 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2429 (cond [(eq_attr "alternative" "2,3")
2431 (ne (symbol_ref "optimize_size")
2433 (const_string "V4SF")
2434 (const_string "TI"))
2435 (eq_attr "alternative" "4")
2437 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2439 (ne (symbol_ref "optimize_size")
2441 (const_string "V4SF")
2442 (const_string "TI"))]
2443 (const_string "DI")))])
2446 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2447 (match_operand:TI 1 "general_operand" ""))]
2448 "reload_completed && !SSE_REG_P (operands[0])
2449 && !SSE_REG_P (operands[1])"
2451 "ix86_split_long_move (operands); DONE;")
2453 ;; This expands to what emit_move_complex would generate if we didn't
2454 ;; have a movti pattern. Having this avoids problems with reload on
2455 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2456 ;; to have around all the time.
2457 (define_expand "movcdi"
2458 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2459 (match_operand:CDI 1 "general_operand" ""))]
2462 if (push_operand (operands[0], CDImode))
2463 emit_move_complex_push (CDImode, operands[0], operands[1]);
2465 emit_move_complex_parts (operands[0], operands[1]);
2469 (define_expand "movsf"
2470 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2471 (match_operand:SF 1 "general_operand" ""))]
2473 "ix86_expand_move (SFmode, operands); DONE;")
2475 (define_insn "*pushsf"
2476 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2477 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2480 /* Anything else should be already split before reg-stack. */
2481 gcc_assert (which_alternative == 1);
2482 return "push{l}\t%1";
2484 [(set_attr "type" "multi,push,multi")
2485 (set_attr "unit" "i387,*,*")
2486 (set_attr "mode" "SF,SI,SF")])
2488 (define_insn "*pushsf_rex64"
2489 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2490 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2493 /* Anything else should be already split before reg-stack. */
2494 gcc_assert (which_alternative == 1);
2495 return "push{q}\t%q1";
2497 [(set_attr "type" "multi,push,multi")
2498 (set_attr "unit" "i387,*,*")
2499 (set_attr "mode" "SF,DI,SF")])
2502 [(set (match_operand:SF 0 "push_operand" "")
2503 (match_operand:SF 1 "memory_operand" ""))]
2505 && MEM_P (operands[1])
2506 && (operands[2] = find_constant_src (insn))"
2511 ;; %%% Kill this when call knows how to work this out.
2513 [(set (match_operand:SF 0 "push_operand" "")
2514 (match_operand:SF 1 "any_fp_register_operand" ""))]
2516 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2517 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2520 [(set (match_operand:SF 0 "push_operand" "")
2521 (match_operand:SF 1 "any_fp_register_operand" ""))]
2523 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2524 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2526 (define_insn "*movsf_1"
2527 [(set (match_operand:SF 0 "nonimmediate_operand"
2528 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2529 (match_operand:SF 1 "general_operand"
2530 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2531 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2532 && (reload_in_progress || reload_completed
2533 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2534 || (!TARGET_SSE_MATH && optimize_size
2535 && standard_80387_constant_p (operands[1]))
2536 || GET_CODE (operands[1]) != CONST_DOUBLE
2537 || memory_operand (operands[0], SFmode))"
2539 switch (which_alternative)
2543 return output_387_reg_move (insn, operands);
2546 return standard_80387_constant_opcode (operands[1]);
2550 return "mov{l}\t{%1, %0|%0, %1}";
2552 if (get_attr_mode (insn) == MODE_TI)
2553 return "pxor\t%0, %0";
2555 return "xorps\t%0, %0";
2557 if (get_attr_mode (insn) == MODE_V4SF)
2558 return "movaps\t{%1, %0|%0, %1}";
2560 return "movss\t{%1, %0|%0, %1}";
2562 return "movss\t{%1, %0|%0, %1}";
2565 case 12: case 13: case 14: case 15:
2566 return "movd\t{%1, %0|%0, %1}";
2569 return "movq\t{%1, %0|%0, %1}";
2575 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2577 (cond [(eq_attr "alternative" "3,4,9,10")
2579 (eq_attr "alternative" "5")
2581 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2583 (ne (symbol_ref "TARGET_SSE2")
2585 (eq (symbol_ref "optimize_size")
2588 (const_string "V4SF"))
2589 /* For architectures resolving dependencies on
2590 whole SSE registers use APS move to break dependency
2591 chains, otherwise use short move to avoid extra work.
2593 Do the same for architectures resolving dependencies on
2594 the parts. While in DF mode it is better to always handle
2595 just register parts, the SF mode is different due to lack
2596 of instructions to load just part of the register. It is
2597 better to maintain the whole registers in single format
2598 to avoid problems on using packed logical operations. */
2599 (eq_attr "alternative" "6")
2601 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2603 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2605 (const_string "V4SF")
2606 (const_string "SF"))
2607 (eq_attr "alternative" "11")
2608 (const_string "DI")]
2609 (const_string "SF")))])
2611 (define_insn "*swapsf"
2612 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2613 (match_operand:SF 1 "fp_register_operand" "+f"))
2616 "reload_completed || TARGET_80387"
2618 if (STACK_TOP_P (operands[0]))
2623 [(set_attr "type" "fxch")
2624 (set_attr "mode" "SF")])
2626 (define_expand "movdf"
2627 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2628 (match_operand:DF 1 "general_operand" ""))]
2630 "ix86_expand_move (DFmode, operands); DONE;")
2632 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2633 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2634 ;; On the average, pushdf using integers can be still shorter. Allow this
2635 ;; pattern for optimize_size too.
2637 (define_insn "*pushdf_nointeger"
2638 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2639 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2640 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2642 /* This insn should be already split before reg-stack. */
2645 [(set_attr "type" "multi")
2646 (set_attr "unit" "i387,*,*,*")
2647 (set_attr "mode" "DF,SI,SI,DF")])
2649 (define_insn "*pushdf_integer"
2650 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2651 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2652 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2654 /* This insn should be already split before reg-stack. */
2657 [(set_attr "type" "multi")
2658 (set_attr "unit" "i387,*,*")
2659 (set_attr "mode" "DF,SI,DF")])
2661 ;; %%% Kill this when call knows how to work this out.
2663 [(set (match_operand:DF 0 "push_operand" "")
2664 (match_operand:DF 1 "any_fp_register_operand" ""))]
2665 "!TARGET_64BIT && reload_completed"
2666 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2667 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2671 [(set (match_operand:DF 0 "push_operand" "")
2672 (match_operand:DF 1 "any_fp_register_operand" ""))]
2673 "TARGET_64BIT && reload_completed"
2674 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2675 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2679 [(set (match_operand:DF 0 "push_operand" "")
2680 (match_operand:DF 1 "general_operand" ""))]
2683 "ix86_split_long_move (operands); DONE;")
2685 ;; Moving is usually shorter when only FP registers are used. This separate
2686 ;; movdf pattern avoids the use of integer registers for FP operations
2687 ;; when optimizing for size.
2689 (define_insn "*movdf_nointeger"
2690 [(set (match_operand:DF 0 "nonimmediate_operand"
2691 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2692 (match_operand:DF 1 "general_operand"
2693 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2694 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2695 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2696 && (reload_in_progress || reload_completed
2697 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2698 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2699 && !memory_operand (operands[0], DFmode)
2700 && standard_80387_constant_p (operands[1]))
2701 || GET_CODE (operands[1]) != CONST_DOUBLE
2703 || !TARGET_MEMORY_MISMATCH_STALL
2704 || reload_in_progress || reload_completed)
2705 && memory_operand (operands[0], DFmode)))"
2707 switch (which_alternative)
2711 return output_387_reg_move (insn, operands);
2714 return standard_80387_constant_opcode (operands[1]);
2720 switch (get_attr_mode (insn))
2723 return "xorps\t%0, %0";
2725 return "xorpd\t%0, %0";
2727 return "pxor\t%0, %0";
2734 switch (get_attr_mode (insn))
2737 return "movaps\t{%1, %0|%0, %1}";
2739 return "movapd\t{%1, %0|%0, %1}";
2741 return "movdqa\t{%1, %0|%0, %1}";
2743 return "movq\t{%1, %0|%0, %1}";
2745 return "movsd\t{%1, %0|%0, %1}";
2747 return "movlpd\t{%1, %0|%0, %1}";
2749 return "movlps\t{%1, %0|%0, %1}";
2758 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2760 (cond [(eq_attr "alternative" "0,1,2")
2762 (eq_attr "alternative" "3,4")
2765 /* For SSE1, we have many fewer alternatives. */
2766 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2767 (cond [(eq_attr "alternative" "5,6")
2768 (const_string "V4SF")
2770 (const_string "V2SF"))
2772 /* xorps is one byte shorter. */
2773 (eq_attr "alternative" "5")
2774 (cond [(ne (symbol_ref "optimize_size")
2776 (const_string "V4SF")
2777 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2781 (const_string "V2DF"))
2783 /* For architectures resolving dependencies on
2784 whole SSE registers use APD move to break dependency
2785 chains, otherwise use short move to avoid extra work.
2787 movaps encodes one byte shorter. */
2788 (eq_attr "alternative" "6")
2790 [(ne (symbol_ref "optimize_size")
2792 (const_string "V4SF")
2793 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2795 (const_string "V2DF")
2797 (const_string "DF"))
2798 /* For architectures resolving dependencies on register
2799 parts we may avoid extra work to zero out upper part
2801 (eq_attr "alternative" "7")
2803 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2805 (const_string "V1DF")
2806 (const_string "DF"))
2808 (const_string "DF")))])
2810 (define_insn "*movdf_integer_rex64"
2811 [(set (match_operand:DF 0 "nonimmediate_operand"
2812 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2813 (match_operand:DF 1 "general_operand"
2814 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2815 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2816 && (reload_in_progress || reload_completed
2817 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2818 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2819 && standard_80387_constant_p (operands[1]))
2820 || GET_CODE (operands[1]) != CONST_DOUBLE
2821 || memory_operand (operands[0], DFmode))"
2823 switch (which_alternative)
2827 return output_387_reg_move (insn, operands);
2830 return standard_80387_constant_opcode (operands[1]);
2837 switch (get_attr_mode (insn))
2840 return "xorps\t%0, %0";
2842 return "xorpd\t%0, %0";
2844 return "pxor\t%0, %0";
2851 switch (get_attr_mode (insn))
2854 return "movaps\t{%1, %0|%0, %1}";
2856 return "movapd\t{%1, %0|%0, %1}";
2858 return "movdqa\t{%1, %0|%0, %1}";
2860 return "movq\t{%1, %0|%0, %1}";
2862 return "movsd\t{%1, %0|%0, %1}";
2864 return "movlpd\t{%1, %0|%0, %1}";
2866 return "movlps\t{%1, %0|%0, %1}";
2873 return "movd\t{%1, %0|%0, %1}";
2879 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2881 (cond [(eq_attr "alternative" "0,1,2")
2883 (eq_attr "alternative" "3,4,9,10")
2886 /* For SSE1, we have many fewer alternatives. */
2887 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2888 (cond [(eq_attr "alternative" "5,6")
2889 (const_string "V4SF")
2891 (const_string "V2SF"))
2893 /* xorps is one byte shorter. */
2894 (eq_attr "alternative" "5")
2895 (cond [(ne (symbol_ref "optimize_size")
2897 (const_string "V4SF")
2898 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2902 (const_string "V2DF"))
2904 /* For architectures resolving dependencies on
2905 whole SSE registers use APD move to break dependency
2906 chains, otherwise use short move to avoid extra work.
2908 movaps encodes one byte shorter. */
2909 (eq_attr "alternative" "6")
2911 [(ne (symbol_ref "optimize_size")
2913 (const_string "V4SF")
2914 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2916 (const_string "V2DF")
2918 (const_string "DF"))
2919 /* For architectures resolving dependencies on register
2920 parts we may avoid extra work to zero out upper part
2922 (eq_attr "alternative" "7")
2924 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2926 (const_string "V1DF")
2927 (const_string "DF"))
2929 (const_string "DF")))])
2931 (define_insn "*movdf_integer"
2932 [(set (match_operand:DF 0 "nonimmediate_operand"
2933 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2934 (match_operand:DF 1 "general_operand"
2935 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2936 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2937 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2938 && (reload_in_progress || reload_completed
2939 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2940 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2941 && standard_80387_constant_p (operands[1]))
2942 || GET_CODE (operands[1]) != CONST_DOUBLE
2943 || memory_operand (operands[0], DFmode))"
2945 switch (which_alternative)
2949 return output_387_reg_move (insn, operands);
2952 return standard_80387_constant_opcode (operands[1]);
2959 switch (get_attr_mode (insn))
2962 return "xorps\t%0, %0";
2964 return "xorpd\t%0, %0";
2966 return "pxor\t%0, %0";
2973 switch (get_attr_mode (insn))
2976 return "movaps\t{%1, %0|%0, %1}";
2978 return "movapd\t{%1, %0|%0, %1}";
2980 return "movdqa\t{%1, %0|%0, %1}";
2982 return "movq\t{%1, %0|%0, %1}";
2984 return "movsd\t{%1, %0|%0, %1}";
2986 return "movlpd\t{%1, %0|%0, %1}";
2988 return "movlps\t{%1, %0|%0, %1}";
2997 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2999 (cond [(eq_attr "alternative" "0,1,2")
3001 (eq_attr "alternative" "3,4")
3004 /* For SSE1, we have many fewer alternatives. */
3005 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3006 (cond [(eq_attr "alternative" "5,6")
3007 (const_string "V4SF")
3009 (const_string "V2SF"))
3011 /* xorps is one byte shorter. */
3012 (eq_attr "alternative" "5")
3013 (cond [(ne (symbol_ref "optimize_size")
3015 (const_string "V4SF")
3016 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3020 (const_string "V2DF"))
3022 /* For architectures resolving dependencies on
3023 whole SSE registers use APD move to break dependency
3024 chains, otherwise use short move to avoid extra work.
3026 movaps encodes one byte shorter. */
3027 (eq_attr "alternative" "6")
3029 [(ne (symbol_ref "optimize_size")
3031 (const_string "V4SF")
3032 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3034 (const_string "V2DF")
3036 (const_string "DF"))
3037 /* For architectures resolving dependencies on register
3038 parts we may avoid extra work to zero out upper part
3040 (eq_attr "alternative" "7")
3042 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3044 (const_string "V1DF")
3045 (const_string "DF"))
3047 (const_string "DF")))])
3050 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3051 (match_operand:DF 1 "general_operand" ""))]
3053 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3054 && ! (ANY_FP_REG_P (operands[0]) ||
3055 (GET_CODE (operands[0]) == SUBREG
3056 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3057 && ! (ANY_FP_REG_P (operands[1]) ||
3058 (GET_CODE (operands[1]) == SUBREG
3059 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3061 "ix86_split_long_move (operands); DONE;")
3063 (define_insn "*swapdf"
3064 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3065 (match_operand:DF 1 "fp_register_operand" "+f"))
3068 "reload_completed || TARGET_80387"
3070 if (STACK_TOP_P (operands[0]))
3075 [(set_attr "type" "fxch")
3076 (set_attr "mode" "DF")])
3078 (define_expand "movxf"
3079 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3080 (match_operand:XF 1 "general_operand" ""))]
3082 "ix86_expand_move (XFmode, operands); DONE;")
3084 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3085 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3086 ;; Pushing using integer instructions is longer except for constants
3087 ;; and direct memory references.
3088 ;; (assuming that any given constant is pushed only once, but this ought to be
3089 ;; handled elsewhere).
3091 (define_insn "*pushxf_nointeger"
3092 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3093 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3096 /* This insn should be already split before reg-stack. */
3099 [(set_attr "type" "multi")
3100 (set_attr "unit" "i387,*,*")
3101 (set_attr "mode" "XF,SI,SI")])
3103 (define_insn "*pushxf_integer"
3104 [(set (match_operand:XF 0 "push_operand" "=<,<")
3105 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3108 /* This insn should be already split before reg-stack. */
3111 [(set_attr "type" "multi")
3112 (set_attr "unit" "i387,*")
3113 (set_attr "mode" "XF,SI")])
3116 [(set (match_operand 0 "push_operand" "")
3117 (match_operand 1 "general_operand" ""))]
3119 && (GET_MODE (operands[0]) == XFmode
3120 || GET_MODE (operands[0]) == DFmode)
3121 && !ANY_FP_REG_P (operands[1])"
3123 "ix86_split_long_move (operands); DONE;")
3126 [(set (match_operand:XF 0 "push_operand" "")
3127 (match_operand:XF 1 "any_fp_register_operand" ""))]
3129 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3130 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3131 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3134 [(set (match_operand:XF 0 "push_operand" "")
3135 (match_operand:XF 1 "any_fp_register_operand" ""))]
3137 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3138 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3139 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3141 ;; Do not use integer registers when optimizing for size
3142 (define_insn "*movxf_nointeger"
3143 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3144 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3146 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3147 && (reload_in_progress || reload_completed
3148 || (optimize_size && standard_80387_constant_p (operands[1]))
3149 || GET_CODE (operands[1]) != CONST_DOUBLE
3150 || memory_operand (operands[0], XFmode))"
3152 switch (which_alternative)
3156 return output_387_reg_move (insn, operands);
3159 return standard_80387_constant_opcode (operands[1]);
3167 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3168 (set_attr "mode" "XF,XF,XF,SI,SI")])
3170 (define_insn "*movxf_integer"
3171 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3172 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3174 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3175 && (reload_in_progress || reload_completed
3176 || (optimize_size && standard_80387_constant_p (operands[1]))
3177 || GET_CODE (operands[1]) != CONST_DOUBLE
3178 || memory_operand (operands[0], XFmode))"
3180 switch (which_alternative)
3184 return output_387_reg_move (insn, operands);
3187 return standard_80387_constant_opcode (operands[1]);
3196 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3197 (set_attr "mode" "XF,XF,XF,SI,SI")])
3199 (define_expand "movtf"
3200 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201 (match_operand:TF 1 "nonimmediate_operand" ""))]
3204 ix86_expand_move (TFmode, operands);
3208 (define_insn "*movtf_internal"
3209 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3210 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3212 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3214 switch (which_alternative)
3218 if (get_attr_mode (insn) == MODE_V4SF)
3219 return "movaps\t{%1, %0|%0, %1}";
3221 return "movdqa\t{%1, %0|%0, %1}";
3223 if (get_attr_mode (insn) == MODE_V4SF)
3224 return "xorps\t%0, %0";
3226 return "pxor\t%0, %0";
3234 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3236 (cond [(eq_attr "alternative" "0,2")
3238 (ne (symbol_ref "optimize_size")
3240 (const_string "V4SF")
3241 (const_string "TI"))
3242 (eq_attr "alternative" "1")
3244 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3246 (ne (symbol_ref "optimize_size")
3248 (const_string "V4SF")
3249 (const_string "TI"))]
3250 (const_string "DI")))])
3253 [(set (match_operand 0 "nonimmediate_operand" "")
3254 (match_operand 1 "general_operand" ""))]
3256 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3257 && GET_MODE (operands[0]) == XFmode
3258 && ! (ANY_FP_REG_P (operands[0]) ||
3259 (GET_CODE (operands[0]) == SUBREG
3260 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3261 && ! (ANY_FP_REG_P (operands[1]) ||
3262 (GET_CODE (operands[1]) == SUBREG
3263 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3265 "ix86_split_long_move (operands); DONE;")
3268 [(set (match_operand 0 "register_operand" "")
3269 (match_operand 1 "memory_operand" ""))]
3271 && MEM_P (operands[1])
3272 && (GET_MODE (operands[0]) == TFmode
3273 || GET_MODE (operands[0]) == XFmode
3274 || GET_MODE (operands[0]) == SFmode
3275 || GET_MODE (operands[0]) == DFmode)
3276 && (operands[2] = find_constant_src (insn))"
3277 [(set (match_dup 0) (match_dup 2))]
3279 rtx c = operands[2];
3280 rtx r = operands[0];
3282 if (GET_CODE (r) == SUBREG)
3287 if (!standard_sse_constant_p (c))
3290 else if (FP_REG_P (r))
3292 if (!standard_80387_constant_p (c))
3295 else if (MMX_REG_P (r))
3300 [(set (match_operand 0 "register_operand" "")
3301 (float_extend (match_operand 1 "memory_operand" "")))]
3303 && MEM_P (operands[1])
3304 && (GET_MODE (operands[0]) == TFmode
3305 || GET_MODE (operands[0]) == XFmode
3306 || GET_MODE (operands[0]) == SFmode
3307 || GET_MODE (operands[0]) == DFmode)
3308 && (operands[2] = find_constant_src (insn))"
3309 [(set (match_dup 0) (match_dup 2))]
3311 rtx c = operands[2];
3312 rtx r = operands[0];
3314 if (GET_CODE (r) == SUBREG)
3319 if (!standard_sse_constant_p (c))
3322 else if (FP_REG_P (r))
3324 if (!standard_80387_constant_p (c))
3327 else if (MMX_REG_P (r))
3331 (define_insn "swapxf"
3332 [(set (match_operand:XF 0 "register_operand" "+f")
3333 (match_operand:XF 1 "register_operand" "+f"))
3338 if (STACK_TOP_P (operands[0]))
3343 [(set_attr "type" "fxch")
3344 (set_attr "mode" "XF")])
3346 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3348 [(set (match_operand:X87MODEF 0 "register_operand" "")
3349 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3350 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3351 && (standard_80387_constant_p (operands[1]) == 8
3352 || standard_80387_constant_p (operands[1]) == 9)"
3353 [(set (match_dup 0)(match_dup 1))
3355 (neg:X87MODEF (match_dup 0)))]
3359 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3360 if (real_isnegzero (&r))
3361 operands[1] = CONST0_RTX (<MODE>mode);
3363 operands[1] = CONST1_RTX (<MODE>mode);
3367 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3368 (match_operand:TF 1 "general_operand" ""))]
3370 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3372 "ix86_split_long_move (operands); DONE;")
3374 ;; Zero extension instructions
3376 (define_expand "zero_extendhisi2"
3377 [(set (match_operand:SI 0 "register_operand" "")
3378 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3381 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3383 operands[1] = force_reg (HImode, operands[1]);
3384 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3389 (define_insn "zero_extendhisi2_and"
3390 [(set (match_operand:SI 0 "register_operand" "=r")
3391 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3392 (clobber (reg:CC FLAGS_REG))]
3393 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3395 [(set_attr "type" "alu1")
3396 (set_attr "mode" "SI")])
3399 [(set (match_operand:SI 0 "register_operand" "")
3400 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3401 (clobber (reg:CC FLAGS_REG))]
3402 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3403 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3404 (clobber (reg:CC FLAGS_REG))])]
3407 (define_insn "*zero_extendhisi2_movzwl"
3408 [(set (match_operand:SI 0 "register_operand" "=r")
3409 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3410 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3411 "movz{wl|x}\t{%1, %0|%0, %1}"
3412 [(set_attr "type" "imovx")
3413 (set_attr "mode" "SI")])
3415 (define_expand "zero_extendqihi2"
3417 [(set (match_operand:HI 0 "register_operand" "")
3418 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3419 (clobber (reg:CC FLAGS_REG))])]
3423 (define_insn "*zero_extendqihi2_and"
3424 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3425 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3426 (clobber (reg:CC FLAGS_REG))]
3427 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3429 [(set_attr "type" "alu1")
3430 (set_attr "mode" "HI")])
3432 (define_insn "*zero_extendqihi2_movzbw_and"
3433 [(set (match_operand:HI 0 "register_operand" "=r,r")
3434 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3435 (clobber (reg:CC FLAGS_REG))]
3436 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3438 [(set_attr "type" "imovx,alu1")
3439 (set_attr "mode" "HI")])
3441 ; zero extend to SImode here to avoid partial register stalls
3442 (define_insn "*zero_extendqihi2_movzbl"
3443 [(set (match_operand:HI 0 "register_operand" "=r")
3444 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3445 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3446 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3447 [(set_attr "type" "imovx")
3448 (set_attr "mode" "SI")])
3450 ;; For the movzbw case strip only the clobber
3452 [(set (match_operand:HI 0 "register_operand" "")
3453 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3454 (clobber (reg:CC FLAGS_REG))]
3456 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3457 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3458 [(set (match_operand:HI 0 "register_operand" "")
3459 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3461 ;; When source and destination does not overlap, clear destination
3462 ;; first and then do the movb
3464 [(set (match_operand:HI 0 "register_operand" "")
3465 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3466 (clobber (reg:CC FLAGS_REG))]
3468 && ANY_QI_REG_P (operands[0])
3469 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3470 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3471 [(set (match_dup 0) (const_int 0))
3472 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3473 "operands[2] = gen_lowpart (QImode, operands[0]);")
3475 ;; Rest is handled by single and.
3477 [(set (match_operand:HI 0 "register_operand" "")
3478 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3479 (clobber (reg:CC FLAGS_REG))]
3481 && true_regnum (operands[0]) == true_regnum (operands[1])"
3482 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3483 (clobber (reg:CC FLAGS_REG))])]
3486 (define_expand "zero_extendqisi2"
3488 [(set (match_operand:SI 0 "register_operand" "")
3489 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3490 (clobber (reg:CC FLAGS_REG))])]
3494 (define_insn "*zero_extendqisi2_and"
3495 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3496 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3497 (clobber (reg:CC FLAGS_REG))]
3498 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3500 [(set_attr "type" "alu1")
3501 (set_attr "mode" "SI")])
3503 (define_insn "*zero_extendqisi2_movzbw_and"
3504 [(set (match_operand:SI 0 "register_operand" "=r,r")
3505 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3506 (clobber (reg:CC FLAGS_REG))]
3507 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3509 [(set_attr "type" "imovx,alu1")
3510 (set_attr "mode" "SI")])
3512 (define_insn "*zero_extendqisi2_movzbw"
3513 [(set (match_operand:SI 0 "register_operand" "=r")
3514 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3515 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3516 "movz{bl|x}\t{%1, %0|%0, %1}"
3517 [(set_attr "type" "imovx")
3518 (set_attr "mode" "SI")])
3520 ;; For the movzbl case strip only the clobber
3522 [(set (match_operand:SI 0 "register_operand" "")
3523 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3524 (clobber (reg:CC FLAGS_REG))]
3526 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3527 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3529 (zero_extend:SI (match_dup 1)))])
3531 ;; When source and destination does not overlap, clear destination
3532 ;; first and then do the movb
3534 [(set (match_operand:SI 0 "register_operand" "")
3535 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3536 (clobber (reg:CC FLAGS_REG))]
3538 && ANY_QI_REG_P (operands[0])
3539 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3540 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3541 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3542 [(set (match_dup 0) (const_int 0))
3543 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3544 "operands[2] = gen_lowpart (QImode, operands[0]);")
3546 ;; Rest is handled by single and.
3548 [(set (match_operand:SI 0 "register_operand" "")
3549 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3550 (clobber (reg:CC FLAGS_REG))]
3552 && true_regnum (operands[0]) == true_regnum (operands[1])"
3553 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3554 (clobber (reg:CC FLAGS_REG))])]
3557 ;; %%% Kill me once multi-word ops are sane.
3558 (define_expand "zero_extendsidi2"
3559 [(set (match_operand:DI 0 "register_operand" "")
3560 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3565 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3570 (define_insn "zero_extendsidi2_32"
3571 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3573 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3574 (clobber (reg:CC FLAGS_REG))]
3580 movd\t{%1, %0|%0, %1}
3581 movd\t{%1, %0|%0, %1}
3582 movd\t{%1, %0|%0, %1}
3583 movd\t{%1, %0|%0, %1}"
3584 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3585 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3587 (define_insn "zero_extendsidi2_rex64"
3588 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3590 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3593 mov\t{%k1, %k0|%k0, %k1}
3595 movd\t{%1, %0|%0, %1}
3596 movd\t{%1, %0|%0, %1}
3597 movd\t{%1, %0|%0, %1}
3598 movd\t{%1, %0|%0, %1}"
3599 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3600 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3603 [(set (match_operand:DI 0 "memory_operand" "")
3604 (zero_extend:DI (match_dup 0)))]
3606 [(set (match_dup 4) (const_int 0))]
3607 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3610 [(set (match_operand:DI 0 "register_operand" "")
3611 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3612 (clobber (reg:CC FLAGS_REG))]
3613 "!TARGET_64BIT && reload_completed
3614 && true_regnum (operands[0]) == true_regnum (operands[1])"
3615 [(set (match_dup 4) (const_int 0))]
3616 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3619 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3620 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3621 (clobber (reg:CC FLAGS_REG))]
3622 "!TARGET_64BIT && reload_completed
3623 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3624 [(set (match_dup 3) (match_dup 1))
3625 (set (match_dup 4) (const_int 0))]
3626 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3628 (define_insn "zero_extendhidi2"
3629 [(set (match_operand:DI 0 "register_operand" "=r")
3630 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3632 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3633 [(set_attr "type" "imovx")
3634 (set_attr "mode" "DI")])
3636 (define_insn "zero_extendqidi2"
3637 [(set (match_operand:DI 0 "register_operand" "=r")
3638 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3640 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3641 [(set_attr "type" "imovx")
3642 (set_attr "mode" "DI")])
3644 ;; Sign extension instructions
3646 (define_expand "extendsidi2"
3647 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3648 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3649 (clobber (reg:CC FLAGS_REG))
3650 (clobber (match_scratch:SI 2 ""))])]
3655 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3660 (define_insn "*extendsidi2_1"
3661 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3662 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3663 (clobber (reg:CC FLAGS_REG))
3664 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3668 (define_insn "extendsidi2_rex64"
3669 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3670 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3674 movs{lq|x}\t{%1,%0|%0, %1}"
3675 [(set_attr "type" "imovx")
3676 (set_attr "mode" "DI")
3677 (set_attr "prefix_0f" "0")
3678 (set_attr "modrm" "0,1")])
3680 (define_insn "extendhidi2"
3681 [(set (match_operand:DI 0 "register_operand" "=r")
3682 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3684 "movs{wq|x}\t{%1,%0|%0, %1}"
3685 [(set_attr "type" "imovx")
3686 (set_attr "mode" "DI")])
3688 (define_insn "extendqidi2"
3689 [(set (match_operand:DI 0 "register_operand" "=r")
3690 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3692 "movs{bq|x}\t{%1,%0|%0, %1}"
3693 [(set_attr "type" "imovx")
3694 (set_attr "mode" "DI")])
3696 ;; Extend to memory case when source register does die.
3698 [(set (match_operand:DI 0 "memory_operand" "")
3699 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3700 (clobber (reg:CC FLAGS_REG))
3701 (clobber (match_operand:SI 2 "register_operand" ""))]
3703 && dead_or_set_p (insn, operands[1])
3704 && !reg_mentioned_p (operands[1], operands[0]))"
3705 [(set (match_dup 3) (match_dup 1))
3706 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3707 (clobber (reg:CC FLAGS_REG))])
3708 (set (match_dup 4) (match_dup 1))]
3709 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3711 ;; Extend to memory case when source register does not die.
3713 [(set (match_operand:DI 0 "memory_operand" "")
3714 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3715 (clobber (reg:CC FLAGS_REG))
3716 (clobber (match_operand:SI 2 "register_operand" ""))]
3720 split_di (&operands[0], 1, &operands[3], &operands[4]);
3722 emit_move_insn (operands[3], operands[1]);
3724 /* Generate a cltd if possible and doing so it profitable. */
3725 if ((optimize_size || TARGET_USE_CLTD)
3726 && true_regnum (operands[1]) == AX_REG
3727 && true_regnum (operands[2]) == DX_REG)
3729 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3733 emit_move_insn (operands[2], operands[1]);
3734 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3736 emit_move_insn (operands[4], operands[2]);
3740 ;; Extend to register case. Optimize case where source and destination
3741 ;; registers match and cases where we can use cltd.
3743 [(set (match_operand:DI 0 "register_operand" "")
3744 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3745 (clobber (reg:CC FLAGS_REG))
3746 (clobber (match_scratch:SI 2 ""))]
3750 split_di (&operands[0], 1, &operands[3], &operands[4]);
3752 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3753 emit_move_insn (operands[3], operands[1]);
3755 /* Generate a cltd if possible and doing so it profitable. */
3756 if ((optimize_size || TARGET_USE_CLTD)
3757 && true_regnum (operands[3]) == AX_REG)
3759 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3763 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3764 emit_move_insn (operands[4], operands[1]);
3766 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3770 (define_insn "extendhisi2"
3771 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3772 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3775 switch (get_attr_prefix_0f (insn))
3778 return "{cwtl|cwde}";
3780 return "movs{wl|x}\t{%1,%0|%0, %1}";
3783 [(set_attr "type" "imovx")
3784 (set_attr "mode" "SI")
3785 (set (attr "prefix_0f")
3786 ;; movsx is short decodable while cwtl is vector decoded.
3787 (if_then_else (and (eq_attr "cpu" "!k6")
3788 (eq_attr "alternative" "0"))
3790 (const_string "1")))
3792 (if_then_else (eq_attr "prefix_0f" "0")
3794 (const_string "1")))])
3796 (define_insn "*extendhisi2_zext"
3797 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3799 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3802 switch (get_attr_prefix_0f (insn))
3805 return "{cwtl|cwde}";
3807 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3810 [(set_attr "type" "imovx")
3811 (set_attr "mode" "SI")
3812 (set (attr "prefix_0f")
3813 ;; movsx is short decodable while cwtl is vector decoded.
3814 (if_then_else (and (eq_attr "cpu" "!k6")
3815 (eq_attr "alternative" "0"))
3817 (const_string "1")))
3819 (if_then_else (eq_attr "prefix_0f" "0")
3821 (const_string "1")))])
3823 (define_insn "extendqihi2"
3824 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3825 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3828 switch (get_attr_prefix_0f (insn))
3831 return "{cbtw|cbw}";
3833 return "movs{bw|x}\t{%1,%0|%0, %1}";
3836 [(set_attr "type" "imovx")
3837 (set_attr "mode" "HI")
3838 (set (attr "prefix_0f")
3839 ;; movsx is short decodable while cwtl is vector decoded.
3840 (if_then_else (and (eq_attr "cpu" "!k6")
3841 (eq_attr "alternative" "0"))
3843 (const_string "1")))
3845 (if_then_else (eq_attr "prefix_0f" "0")
3847 (const_string "1")))])
3849 (define_insn "extendqisi2"
3850 [(set (match_operand:SI 0 "register_operand" "=r")
3851 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3853 "movs{bl|x}\t{%1,%0|%0, %1}"
3854 [(set_attr "type" "imovx")
3855 (set_attr "mode" "SI")])
3857 (define_insn "*extendqisi2_zext"
3858 [(set (match_operand:DI 0 "register_operand" "=r")
3860 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3862 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3863 [(set_attr "type" "imovx")
3864 (set_attr "mode" "SI")])
3866 ;; Conversions between float and double.
3868 ;; These are all no-ops in the model used for the 80387. So just
3871 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3872 (define_insn "*dummy_extendsfdf2"
3873 [(set (match_operand:DF 0 "push_operand" "=<")
3874 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3879 [(set (match_operand:DF 0 "push_operand" "")
3880 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3882 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3883 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3886 [(set (match_operand:DF 0 "push_operand" "")
3887 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3889 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3890 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3892 (define_insn "*dummy_extendsfxf2"
3893 [(set (match_operand:XF 0 "push_operand" "=<")
3894 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3899 [(set (match_operand:XF 0 "push_operand" "")
3900 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3902 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3903 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3904 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3907 [(set (match_operand:XF 0 "push_operand" "")
3908 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3910 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3911 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3912 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3915 [(set (match_operand:XF 0 "push_operand" "")
3916 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3918 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3919 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3920 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3923 [(set (match_operand:XF 0 "push_operand" "")
3924 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3926 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3927 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3928 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3930 (define_expand "extendsfdf2"
3931 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3932 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3933 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3935 /* ??? Needed for compress_float_constant since all fp constants
3936 are LEGITIMATE_CONSTANT_P. */
3937 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3939 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3940 && standard_80387_constant_p (operands[1]) > 0)
3942 operands[1] = simplify_const_unary_operation
3943 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3944 emit_move_insn_1 (operands[0], operands[1]);
3947 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3951 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3953 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3955 We do the conversion post reload to avoid producing of 128bit spills
3956 that might lead to ICE on 32bit target. The sequence unlikely combine
3959 [(set (match_operand:DF 0 "register_operand" "")
3961 (match_operand:SF 1 "nonimmediate_operand" "")))]
3962 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3963 && reload_completed && SSE_REG_P (operands[0])"
3968 (parallel [(const_int 0) (const_int 1)]))))]
3970 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3971 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3972 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3973 Try to avoid move when unpacking can be done in source. */
3974 if (REG_P (operands[1]))
3976 /* If it is unsafe to overwrite upper half of source, we need
3977 to move to destination and unpack there. */
3978 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3979 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3980 && true_regnum (operands[0]) != true_regnum (operands[1]))
3982 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3983 emit_move_insn (tmp, operands[1]);
3986 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3987 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3990 emit_insn (gen_vec_setv4sf_0 (operands[3],
3991 CONST0_RTX (V4SFmode), operands[1]));
3994 (define_insn "*extendsfdf2_mixed"
3995 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3997 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3998 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4000 switch (which_alternative)
4004 return output_387_reg_move (insn, operands);
4007 return "cvtss2sd\t{%1, %0|%0, %1}";
4013 [(set_attr "type" "fmov,fmov,ssecvt")
4014 (set_attr "mode" "SF,XF,DF")])
4016 (define_insn "*extendsfdf2_sse"
4017 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4018 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4019 "TARGET_SSE2 && TARGET_SSE_MATH"
4020 "cvtss2sd\t{%1, %0|%0, %1}"
4021 [(set_attr "type" "ssecvt")
4022 (set_attr "mode" "DF")])
4024 (define_insn "*extendsfdf2_i387"
4025 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4026 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4028 "* return output_387_reg_move (insn, operands);"
4029 [(set_attr "type" "fmov")
4030 (set_attr "mode" "SF,XF")])
4032 (define_expand "extend<mode>xf2"
4033 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4034 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4037 /* ??? Needed for compress_float_constant since all fp constants
4038 are LEGITIMATE_CONSTANT_P. */
4039 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4041 if (standard_80387_constant_p (operands[1]) > 0)
4043 operands[1] = simplify_const_unary_operation
4044 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4045 emit_move_insn_1 (operands[0], operands[1]);
4048 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4052 (define_insn "*extend<mode>xf2_i387"
4053 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4055 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4057 "* return output_387_reg_move (insn, operands);"
4058 [(set_attr "type" "fmov")
4059 (set_attr "mode" "<MODE>,XF")])
4061 ;; %%% This seems bad bad news.
4062 ;; This cannot output into an f-reg because there is no way to be sure
4063 ;; of truncating in that case. Otherwise this is just like a simple move
4064 ;; insn. So we pretend we can output to a reg in order to get better
4065 ;; register preferencing, but we really use a stack slot.
4067 ;; Conversion from DFmode to SFmode.
4069 (define_expand "truncdfsf2"
4070 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4072 (match_operand:DF 1 "nonimmediate_operand" "")))]
4073 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4075 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4077 else if (flag_unsafe_math_optimizations)
4081 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4082 rtx temp = assign_386_stack_local (SFmode, slot);
4083 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4088 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4090 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4092 We do the conversion post reload to avoid producing of 128bit spills
4093 that might lead to ICE on 32bit target. The sequence unlikely combine
4096 [(set (match_operand:SF 0 "register_operand" "")
4098 (match_operand:DF 1 "nonimmediate_operand" "")))]
4099 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4100 && reload_completed && SSE_REG_P (operands[0])"
4103 (float_truncate:V2SF
4107 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4108 operands[3] = CONST0_RTX (V2SFmode);
4109 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4110 /* Use movsd for loading from memory, unpcklpd for registers.
4111 Try to avoid move when unpacking can be done in source, or SSE3
4112 movddup is available. */
4113 if (REG_P (operands[1]))
4116 && true_regnum (operands[0]) != true_regnum (operands[1])
4117 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4118 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4120 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4121 emit_move_insn (tmp, operands[1]);
4124 else if (!TARGET_SSE3)
4125 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4126 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4129 emit_insn (gen_sse2_loadlpd (operands[4],
4130 CONST0_RTX (V2DFmode), operands[1]));
4133 (define_expand "truncdfsf2_with_temp"
4134 [(parallel [(set (match_operand:SF 0 "" "")
4135 (float_truncate:SF (match_operand:DF 1 "" "")))
4136 (clobber (match_operand:SF 2 "" ""))])]
4139 (define_insn "*truncdfsf_fast_mixed"
4140 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4142 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4143 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4145 switch (which_alternative)
4149 return output_387_reg_move (insn, operands);
4151 return "cvtsd2ss\t{%1, %0|%0, %1}";
4156 [(set_attr "type" "fmov,fmov,ssecvt")
4157 (set_attr "mode" "SF")])
4159 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4160 ;; because nothing we do here is unsafe.
4161 (define_insn "*truncdfsf_fast_sse"
4162 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4164 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4165 "TARGET_SSE2 && TARGET_SSE_MATH"
4166 "cvtsd2ss\t{%1, %0|%0, %1}"
4167 [(set_attr "type" "ssecvt")
4168 (set_attr "mode" "SF")])
4170 (define_insn "*truncdfsf_fast_i387"
4171 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4173 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4174 "TARGET_80387 && flag_unsafe_math_optimizations"
4175 "* return output_387_reg_move (insn, operands);"
4176 [(set_attr "type" "fmov")
4177 (set_attr "mode" "SF")])
4179 (define_insn "*truncdfsf_mixed"
4180 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4182 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4183 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4184 "TARGET_MIX_SSE_I387"
4186 switch (which_alternative)
4189 return output_387_reg_move (insn, operands);
4194 return "cvtsd2ss\t{%1, %0|%0, %1}";
4199 [(set_attr "type" "fmov,multi,ssecvt")
4200 (set_attr "unit" "*,i387,*")
4201 (set_attr "mode" "SF")])
4203 (define_insn "*truncdfsf_i387"
4204 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4206 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4207 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4210 switch (which_alternative)
4213 return output_387_reg_move (insn, operands);
4221 [(set_attr "type" "fmov,multi")
4222 (set_attr "unit" "*,i387")
4223 (set_attr "mode" "SF")])
4225 (define_insn "*truncdfsf2_i387_1"
4226 [(set (match_operand:SF 0 "memory_operand" "=m")
4228 (match_operand:DF 1 "register_operand" "f")))]
4230 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4231 && !TARGET_MIX_SSE_I387"
4232 "* return output_387_reg_move (insn, operands);"
4233 [(set_attr "type" "fmov")
4234 (set_attr "mode" "SF")])
4237 [(set (match_operand:SF 0 "register_operand" "")
4239 (match_operand:DF 1 "fp_register_operand" "")))
4240 (clobber (match_operand 2 "" ""))]
4242 [(set (match_dup 2) (match_dup 1))
4243 (set (match_dup 0) (match_dup 2))]
4245 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4248 ;; Conversion from XFmode to {SF,DF}mode
4250 (define_expand "truncxf<mode>2"
4251 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4252 (float_truncate:MODEF
4253 (match_operand:XF 1 "register_operand" "")))
4254 (clobber (match_dup 2))])]
4257 if (flag_unsafe_math_optimizations)
4259 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4260 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4261 if (reg != operands[0])
4262 emit_move_insn (operands[0], reg);
4267 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4268 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4272 (define_insn "*truncxfsf2_mixed"
4273 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4275 (match_operand:XF 1 "register_operand" "f,f")))
4276 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4279 gcc_assert (!which_alternative);
4280 return output_387_reg_move (insn, operands);
4282 [(set_attr "type" "fmov,multi")
4283 (set_attr "unit" "*,i387")
4284 (set_attr "mode" "SF")])
4286 (define_insn "*truncxfdf2_mixed"
4287 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4289 (match_operand:XF 1 "register_operand" "f,f")))
4290 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4293 gcc_assert (!which_alternative);
4294 return output_387_reg_move (insn, operands);
4296 [(set_attr "type" "fmov,multi")
4297 (set_attr "unit" "*,i387")
4298 (set_attr "mode" "DF")])
4300 (define_insn "truncxf<mode>2_i387_noop"
4301 [(set (match_operand:MODEF 0 "register_operand" "=f")
4302 (float_truncate:MODEF
4303 (match_operand:XF 1 "register_operand" "f")))]
4304 "TARGET_80387 && flag_unsafe_math_optimizations"
4305 "* return output_387_reg_move (insn, operands);"
4306 [(set_attr "type" "fmov")
4307 (set_attr "mode" "<MODE>")])
4309 (define_insn "*truncxf<mode>2_i387"
4310 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4311 (float_truncate:MODEF
4312 (match_operand:XF 1 "register_operand" "f")))]
4314 "* return output_387_reg_move (insn, operands);"
4315 [(set_attr "type" "fmov")
4316 (set_attr "mode" "<MODE>")])
4319 [(set (match_operand:MODEF 0 "register_operand" "")
4320 (float_truncate:MODEF
4321 (match_operand:XF 1 "register_operand" "")))
4322 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4323 "TARGET_80387 && reload_completed"
4324 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4325 (set (match_dup 0) (match_dup 2))]
4329 [(set (match_operand:MODEF 0 "memory_operand" "")
4330 (float_truncate:MODEF
4331 (match_operand:XF 1 "register_operand" "")))
4332 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4334 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4337 ;; Signed conversion to DImode.
4339 (define_expand "fix_truncxfdi2"
4340 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4341 (fix:DI (match_operand:XF 1 "register_operand" "")))
4342 (clobber (reg:CC FLAGS_REG))])]
4347 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4352 (define_expand "fix_trunc<mode>di2"
4353 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4354 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4355 (clobber (reg:CC FLAGS_REG))])]
4356 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4359 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4361 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4364 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4366 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4367 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4368 if (out != operands[0])
4369 emit_move_insn (operands[0], out);
4374 ;; Signed conversion to SImode.
4376 (define_expand "fix_truncxfsi2"
4377 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4378 (fix:SI (match_operand:XF 1 "register_operand" "")))
4379 (clobber (reg:CC FLAGS_REG))])]
4384 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4389 (define_expand "fix_trunc<mode>si2"
4390 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4391 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4392 (clobber (reg:CC FLAGS_REG))])]
4393 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4396 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4398 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4401 if (SSE_FLOAT_MODE_P (<MODE>mode))
4403 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4404 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4405 if (out != operands[0])
4406 emit_move_insn (operands[0], out);
4411 ;; Signed conversion to HImode.
4413 (define_expand "fix_trunc<mode>hi2"
4414 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4415 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4416 (clobber (reg:CC FLAGS_REG))])]
4418 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4422 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4427 ;; Unsigned conversion to SImode.
4429 (define_expand "fixuns_trunc<mode>si2"
4431 [(set (match_operand:SI 0 "register_operand" "")
4433 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4435 (clobber (match_scratch:<ssevecmode> 3 ""))
4436 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4437 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4439 enum machine_mode mode = <MODE>mode;
4440 enum machine_mode vecmode = <ssevecmode>mode;
4441 REAL_VALUE_TYPE TWO31r;
4444 real_ldexp (&TWO31r, &dconst1, 31);
4445 two31 = const_double_from_real_value (TWO31r, mode);
4446 two31 = ix86_build_const_vector (mode, true, two31);
4447 operands[2] = force_reg (vecmode, two31);
4450 (define_insn_and_split "*fixuns_trunc<mode>_1"
4451 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4453 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4454 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4455 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4456 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4457 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4459 "&& reload_completed"
4462 ix86_split_convert_uns_si_sse (operands);
4466 ;; Unsigned conversion to HImode.
4467 ;; Without these patterns, we'll try the unsigned SI conversion which
4468 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4470 (define_expand "fixuns_trunc<mode>hi2"
4472 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4473 (set (match_operand:HI 0 "nonimmediate_operand" "")
4474 (subreg:HI (match_dup 2) 0))]
4475 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4476 "operands[2] = gen_reg_rtx (SImode);")
4478 ;; When SSE is available, it is always faster to use it!
4479 (define_insn "fix_trunc<mode>di_sse"
4480 [(set (match_operand:DI 0 "register_operand" "=r,r")
4481 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4482 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4483 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4484 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4485 [(set_attr "type" "sseicvt")
4486 (set_attr "mode" "<MODE>")
4487 (set_attr "athlon_decode" "double,vector")
4488 (set_attr "amdfam10_decode" "double,double")])
4490 (define_insn "fix_trunc<mode>si_sse"
4491 [(set (match_operand:SI 0 "register_operand" "=r,r")
4492 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4493 "SSE_FLOAT_MODE_P (<MODE>mode)
4494 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4495 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4496 [(set_attr "type" "sseicvt")
4497 (set_attr "mode" "<MODE>")
4498 (set_attr "athlon_decode" "double,vector")
4499 (set_attr "amdfam10_decode" "double,double")])
4501 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4503 [(set (match_operand:MODEF 0 "register_operand" "")
4504 (match_operand:MODEF 1 "memory_operand" ""))
4505 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4506 (fix:SSEMODEI24 (match_dup 0)))]
4507 "TARGET_SHORTEN_X87_SSE
4508 && peep2_reg_dead_p (2, operands[0])"
4509 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4512 ;; Avoid vector decoded forms of the instruction.
4514 [(match_scratch:DF 2 "Y2")
4515 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4516 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4517 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4518 [(set (match_dup 2) (match_dup 1))
4519 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4523 [(match_scratch:SF 2 "x")
4524 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4525 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4526 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4527 [(set (match_dup 2) (match_dup 1))
4528 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4531 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4532 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4533 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4534 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4536 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4537 && (TARGET_64BIT || <MODE>mode != DImode))
4539 && !(reload_completed || reload_in_progress)"
4544 if (memory_operand (operands[0], VOIDmode))
4545 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4548 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4549 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4555 [(set_attr "type" "fisttp")
4556 (set_attr "mode" "<MODE>")])
4558 (define_insn "fix_trunc<mode>_i387_fisttp"
4559 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4560 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4561 (clobber (match_scratch:XF 2 "=&1f"))]
4562 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4565 && (TARGET_64BIT || <MODE>mode != DImode))
4566 && TARGET_SSE_MATH)"
4567 "* return output_fix_trunc (insn, operands, 1);"
4568 [(set_attr "type" "fisttp")
4569 (set_attr "mode" "<MODE>")])
4571 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4572 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4573 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4574 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4575 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4576 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4578 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4579 && (TARGET_64BIT || <MODE>mode != DImode))
4580 && TARGET_SSE_MATH)"
4582 [(set_attr "type" "fisttp")
4583 (set_attr "mode" "<MODE>")])
4586 [(set (match_operand:X87MODEI 0 "register_operand" "")
4587 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4588 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4589 (clobber (match_scratch 3 ""))]
4591 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4592 (clobber (match_dup 3))])
4593 (set (match_dup 0) (match_dup 2))]
4597 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4598 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4599 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4600 (clobber (match_scratch 3 ""))]
4602 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4603 (clobber (match_dup 3))])]
4606 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4607 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4608 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4609 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4610 ;; function in i386.c.
4611 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4612 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4613 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4614 (clobber (reg:CC FLAGS_REG))]
4615 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4617 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4618 && (TARGET_64BIT || <MODE>mode != DImode))
4619 && !(reload_completed || reload_in_progress)"
4624 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4626 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4627 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4628 if (memory_operand (operands[0], VOIDmode))
4629 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4630 operands[2], operands[3]));
4633 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4634 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4635 operands[2], operands[3],
4640 [(set_attr "type" "fistp")
4641 (set_attr "i387_cw" "trunc")
4642 (set_attr "mode" "<MODE>")])
4644 (define_insn "fix_truncdi_i387"
4645 [(set (match_operand:DI 0 "memory_operand" "=m")
4646 (fix:DI (match_operand 1 "register_operand" "f")))
4647 (use (match_operand:HI 2 "memory_operand" "m"))
4648 (use (match_operand:HI 3 "memory_operand" "m"))
4649 (clobber (match_scratch:XF 4 "=&1f"))]
4650 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4652 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4653 "* return output_fix_trunc (insn, operands, 0);"
4654 [(set_attr "type" "fistp")
4655 (set_attr "i387_cw" "trunc")
4656 (set_attr "mode" "DI")])
4658 (define_insn "fix_truncdi_i387_with_temp"
4659 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4660 (fix:DI (match_operand 1 "register_operand" "f,f")))
4661 (use (match_operand:HI 2 "memory_operand" "m,m"))
4662 (use (match_operand:HI 3 "memory_operand" "m,m"))
4663 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4664 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4665 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4667 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4669 [(set_attr "type" "fistp")
4670 (set_attr "i387_cw" "trunc")
4671 (set_attr "mode" "DI")])
4674 [(set (match_operand:DI 0 "register_operand" "")
4675 (fix:DI (match_operand 1 "register_operand" "")))
4676 (use (match_operand:HI 2 "memory_operand" ""))
4677 (use (match_operand:HI 3 "memory_operand" ""))
4678 (clobber (match_operand:DI 4 "memory_operand" ""))
4679 (clobber (match_scratch 5 ""))]
4681 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4684 (clobber (match_dup 5))])
4685 (set (match_dup 0) (match_dup 4))]
4689 [(set (match_operand:DI 0 "memory_operand" "")
4690 (fix:DI (match_operand 1 "register_operand" "")))
4691 (use (match_operand:HI 2 "memory_operand" ""))
4692 (use (match_operand:HI 3 "memory_operand" ""))
4693 (clobber (match_operand:DI 4 "memory_operand" ""))
4694 (clobber (match_scratch 5 ""))]
4696 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4699 (clobber (match_dup 5))])]
4702 (define_insn "fix_trunc<mode>_i387"
4703 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4704 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4705 (use (match_operand:HI 2 "memory_operand" "m"))
4706 (use (match_operand:HI 3 "memory_operand" "m"))]
4707 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4709 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4710 "* return output_fix_trunc (insn, operands, 0);"
4711 [(set_attr "type" "fistp")
4712 (set_attr "i387_cw" "trunc")
4713 (set_attr "mode" "<MODE>")])
4715 (define_insn "fix_trunc<mode>_i387_with_temp"
4716 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4717 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4718 (use (match_operand:HI 2 "memory_operand" "m,m"))
4719 (use (match_operand:HI 3 "memory_operand" "m,m"))
4720 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4721 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4723 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4725 [(set_attr "type" "fistp")
4726 (set_attr "i387_cw" "trunc")
4727 (set_attr "mode" "<MODE>")])
4730 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4731 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4732 (use (match_operand:HI 2 "memory_operand" ""))
4733 (use (match_operand:HI 3 "memory_operand" ""))
4734 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4736 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4738 (use (match_dup 3))])
4739 (set (match_dup 0) (match_dup 4))]
4743 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4744 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4745 (use (match_operand:HI 2 "memory_operand" ""))
4746 (use (match_operand:HI 3 "memory_operand" ""))
4747 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4749 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4751 (use (match_dup 3))])]
4754 (define_insn "x86_fnstcw_1"
4755 [(set (match_operand:HI 0 "memory_operand" "=m")
4756 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4759 [(set_attr "length" "2")
4760 (set_attr "mode" "HI")
4761 (set_attr "unit" "i387")])
4763 (define_insn "x86_fldcw_1"
4764 [(set (reg:HI FPCR_REG)
4765 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4768 [(set_attr "length" "2")
4769 (set_attr "mode" "HI")
4770 (set_attr "unit" "i387")
4771 (set_attr "athlon_decode" "vector")
4772 (set_attr "amdfam10_decode" "vector")])
4774 ;; Conversion between fixed point and floating point.
4776 ;; Even though we only accept memory inputs, the backend _really_
4777 ;; wants to be able to do this between registers.
4779 (define_expand "floathi<mode>2"
4780 [(set (match_operand:MODEF 0 "register_operand" "")
4781 (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4782 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4784 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4787 (gen_floatsi<mode>2 (operands[0],
4788 convert_to_mode (SImode, operands[1], 0)));
4793 (define_insn "*floathi<mode>2_i387"
4794 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4796 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4798 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4799 || TARGET_MIX_SSE_I387)"
4803 [(set_attr "type" "fmov,multi")
4804 (set_attr "mode" "<MODE>")
4805 (set_attr "unit" "*,i387")
4806 (set_attr "fp_int_src" "true")])
4808 (define_expand "floatsi<mode>2"
4809 [(set (match_operand:MODEF 0 "register_operand" "")
4810 (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4811 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4813 /* When we use vector converts, we can't have input in memory. */
4814 if (GET_MODE (operands[0]) == DFmode
4815 && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4816 && SSE_FLOAT_MODE_P (DFmode))
4817 operands[1] = force_reg (SImode, operands[1]);
4818 else if (GET_MODE (operands[0]) == SFmode
4819 && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4820 && SSE_FLOAT_MODE_P (SFmode))
4822 /* When !flag_trapping_math, we handle SImode->SFmode vector
4823 conversions same way as SImode->DFmode.
4825 For flat_trapping_math we can't safely use vector conversion without
4826 clearing upper half, otherwise precision exception might occur.
4827 However we can still generate the common sequence converting value
4828 from general register to XMM register as:
4834 because we know that movd clears the upper half.
4836 Sadly in this case we can't rely on reload moving the value to XMM
4837 register, since we need to know if upper half is OK, so we need
4838 to do reloading by hand. We force operand to memory unless target
4839 supports inter unit moves. */
4840 if (!flag_trapping_math)
4841 operands[1] = force_reg (SImode, operands[1]);
4842 else if (!MEM_P (operands[1]))
4844 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4845 rtx tmp = assign_386_stack_local (SImode, slot);
4846 emit_move_insn (tmp, operands[1]);
4850 /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4851 !TARGET_INTER_UNIT_CONVERSIONS
4852 It is necessary for the patterns to not accept nonmemory operands
4853 as we would optimize out later. */
4854 else if (!TARGET_INTER_UNIT_CONVERSIONS
4855 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4857 && !MEM_P (operands[1]))
4859 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4860 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
4861 emit_move_insn (tmp, operands[1]);
4866 (define_insn "*floatsisf2_mixed_vector"
4867 [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4868 (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4869 "TARGET_MIX_SSE_I387 && !flag_trapping_math
4870 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4872 cvtdq2ps\t{%1, %0|%0, %1}
4875 [(set_attr "type" "sseicvt,fmov,multi")
4876 (set_attr "mode" "SF")
4877 (set_attr "unit" "*,i387,*")
4878 (set_attr "athlon_decode" "double,*,*")
4879 (set_attr "amdfam10_decode" "double,*,*")
4880 (set_attr "fp_int_src" "false,true,true")])
4882 (define_insn "*floatsisf2_mixed"
4883 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4884 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4885 "TARGET_MIX_SSE_I387
4886 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4891 cvtsi2ss\t{%1, %0|%0, %1}
4892 cvtsi2ss\t{%1, %0|%0, %1}"
4893 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4894 (set_attr "mode" "SF")
4895 (set_attr "unit" "*,i387,*,*")
4896 (set_attr "athlon_decode" "*,*,vector,double")
4897 (set_attr "amdfam10_decode" "*,*,vector,double")
4898 (set_attr "fp_int_src" "true")])
4900 (define_insn "*floatsisf2_mixed_memory"
4901 [(set (match_operand:SF 0 "register_operand" "=f,x")
4902 (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4903 "TARGET_MIX_SSE_I387
4904 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4907 cvtsi2ss\t{%1, %0|%0, %1}"
4908 [(set_attr "type" "fmov,sseicvt")
4909 (set_attr "mode" "SF")
4910 (set_attr "athlon_decode" "*,double")
4911 (set_attr "amdfam10_decode" "*,double")
4912 (set_attr "fp_int_src" "true")])
4914 (define_insn "*floatsisf2_sse_vector_nointernunit"
4915 [(set (match_operand:SF 0 "register_operand" "=x")
4916 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4917 "TARGET_SSE_MATH && flag_trapping_math
4918 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4919 && !TARGET_INTER_UNIT_MOVES"
4921 [(set_attr "type" "multi")])
4923 (define_insn "*floatsisf2_sse_vector_internunit"
4924 [(set (match_operand:SF 0 "register_operand" "=x,x")
4925 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4926 "TARGET_SSE_MATH && flag_trapping_math
4927 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4928 && TARGET_INTER_UNIT_MOVES"
4930 [(set_attr "type" "multi")])
4933 [(set (match_operand:SF 0 "register_operand" "")
4934 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4936 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4937 && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4938 && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4940 (float:V4SF (match_dup 2)))]
4942 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4943 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4944 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4948 [(set (match_operand:SF 0 "register_operand" "")
4949 (float:SF (match_operand:SI 1 "register_operand" "")))]
4951 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4952 && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4953 [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4955 (float:V4SF (match_dup 2)))]
4957 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4958 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4961 (define_insn "*floatsisf2_sse_vector"
4962 [(set (match_operand:SF 0 "register_operand" "=x")
4963 (float:SF (match_operand:SI 1 "register_operand" "x")))]
4964 "TARGET_SSE_MATH && !flag_trapping_math
4965 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4966 && !TARGET_INTER_UNIT_MOVES"
4967 "cvtdq2ps\t{%1, %0|%0, %1}"
4968 [(set_attr "type" "sseicvt")
4969 (set_attr "mode" "SF")
4970 (set_attr "athlon_decode" "double")
4971 (set_attr "amdfam10_decode" "double")
4972 (set_attr "fp_int_src" "true")])
4974 (define_insn "*floatsisf2_sse"
4975 [(set (match_operand:SF 0 "register_operand" "=x,x")
4976 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4978 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4980 "cvtsi2ss\t{%1, %0|%0, %1}"
4981 [(set_attr "type" "sseicvt")
4982 (set_attr "mode" "SF")
4983 (set_attr "athlon_decode" "vector,double")
4984 (set_attr "amdfam10_decode" "vector,double")
4985 (set_attr "fp_int_src" "true")])
4987 (define_insn "*floatsisf2_sse_memory"
4988 [(set (match_operand:SF 0 "register_operand" "=x")
4989 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4991 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4992 "cvtsi2ss\t{%1, %0|%0, %1}"
4993 [(set_attr "type" "sseicvt")
4994 (set_attr "mode" "SF")
4995 (set_attr "athlon_decode" "double")
4996 (set_attr "amdfam10_decode" "double")
4997 (set_attr "fp_int_src" "true")])
4999 (define_insn "*floatsidf2_mixed_vector"
5000 [(set (match_operand:DF 0 "register_operand" "=x,f,f")
5001 (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
5002 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5003 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5005 cvtdq2pd\t{%1, %0|%0, %1}
5008 [(set_attr "type" "sseicvt,fmov,multi")
5009 (set_attr "mode" "V2DF,DF,DF")
5010 (set_attr "unit" "*,*,i387")
5011 (set_attr "athlon_decode" "double,*,*")
5012 (set_attr "amdfam10_decode" "double,*,*")
5013 (set_attr "fp_int_src" "false,true,true")])
5015 (define_insn "*floatsidf2_mixed"
5016 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5017 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5018 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5019 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5024 cvtsi2sd\t{%1, %0|%0, %1}
5025 cvtsi2sd\t{%1, %0|%0, %1}
5026 cvtdq2pd\t{%1, %0|%0, %1}"
5027 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5028 (set_attr "mode" "DF,DF,DF,DF,V2DF")
5029 (set_attr "unit" "*,i387,*,*,*")
5030 (set_attr "athlon_decode" "*,*,double,direct,double")
5031 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5032 (set_attr "fp_int_src" "true,true,true,true,false")])
5034 (define_insn "*floatsidf2_mixed_memory"
5035 [(set (match_operand:DF 0 "register_operand" "=f,x")
5036 (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5037 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5038 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5041 cvtsi2sd\t{%1, %0|%0, %1}"
5042 [(set_attr "type" "fmov,sseicvt")
5043 (set_attr "mode" "DF")
5044 (set_attr "athlon_decode" "*,direct")
5045 (set_attr "amdfam10_decode" "*,double")
5046 (set_attr "fp_int_src" "true")])
5048 (define_insn "*floatsidf2_sse_vector"
5049 [(set (match_operand:DF 0 "register_operand" "=x")
5050 (float:DF (match_operand:SI 1 "register_operand" "x")))]
5051 "TARGET_SSE2 && TARGET_SSE_MATH
5052 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5053 "cvtdq2pd\t{%1, %0|%0, %1}"
5054 [(set_attr "type" "sseicvt")
5055 (set_attr "mode" "V2DF")
5056 (set_attr "athlon_decode" "double")
5057 (set_attr "amdfam10_decode" "double")
5058 (set_attr "fp_int_src" "true")])
5061 [(set (match_operand:DF 0 "register_operand" "")
5062 (float:DF (match_operand:SI 1 "memory_operand" "")))]
5063 "TARGET_USE_VECTOR_CONVERTS && reload_completed
5064 && SSE_REG_P (operands[0])"
5069 (parallel [(const_int 0) (const_int 1)]))))]
5071 operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5072 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5073 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5076 (define_insn "*floatsidf2_sse"
5077 [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5078 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5079 "TARGET_SSE2 && TARGET_SSE_MATH
5080 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5083 cvtsi2sd\t{%1, %0|%0, %1}
5084 cvtsi2sd\t{%1, %0|%0, %1}
5085 cvtdq2pd\t{%1, %0|%0, %1}"
5086 [(set_attr "type" "sseicvt")
5087 (set_attr "mode" "DF,DF,V2DF")
5088 (set_attr "athlon_decode" "double,direct,double")
5089 (set_attr "amdfam10_decode" "vector,double,double")
5090 (set_attr "fp_int_src" "true")])
5092 (define_insn "*floatsidf2_memory"
5093 [(set (match_operand:DF 0 "register_operand" "=x")
5094 (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5095 "TARGET_SSE2 && TARGET_SSE_MATH
5096 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5098 "cvtsi2sd\t{%1, %0|%0, %1}"
5099 [(set_attr "type" "sseicvt")
5100 (set_attr "mode" "DF")
5101 (set_attr "athlon_decode" "direct")
5102 (set_attr "amdfam10_decode" "double")
5103 (set_attr "fp_int_src" "true")])
5105 (define_insn "*floatsi<mode>2_i387"
5106 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5108 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5110 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5114 [(set_attr "type" "fmov,multi")
5115 (set_attr "mode" "<MODE>")
5116 (set_attr "unit" "*,i387")
5117 (set_attr "fp_int_src" "true")])
5119 (define_expand "floatdisf2"
5120 [(set (match_operand:SF 0 "register_operand" "")
5121 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5122 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5124 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5125 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5127 && !MEM_P (operands[1]))
5129 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5130 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5131 emit_move_insn (tmp, operands[1]);
5136 (define_insn "*floatdisf2_mixed"
5137 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5138 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5139 "TARGET_64BIT && TARGET_MIX_SSE_I387
5140 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5144 cvtsi2ss{q}\t{%1, %0|%0, %1}
5145 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5146 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5147 (set_attr "mode" "SF")
5148 (set_attr "unit" "*,i387,*,*")
5149 (set_attr "athlon_decode" "*,*,vector,double")
5150 (set_attr "amdfam10_decode" "*,*,vector,double")
5151 (set_attr "fp_int_src" "true")])
5153 (define_insn "*floatdisf2_mixed"
5154 [(set (match_operand:SF 0 "register_operand" "=f,x")
5155 (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5156 "TARGET_64BIT && TARGET_MIX_SSE_I387
5157 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5160 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5161 [(set_attr "type" "fmov,sseicvt")
5162 (set_attr "mode" "SF")
5163 (set_attr "athlon_decode" "*,double")
5164 (set_attr "amdfam10_decode" "*,double")
5165 (set_attr "fp_int_src" "true")])
5167 (define_insn "*floatdisf2_sse"
5168 [(set (match_operand:SF 0 "register_operand" "=x,x")
5169 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5170 "TARGET_64BIT && TARGET_SSE_MATH
5171 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5172 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5173 [(set_attr "type" "sseicvt")
5174 (set_attr "mode" "SF")
5175 (set_attr "athlon_decode" "vector,double")
5176 (set_attr "amdfam10_decode" "vector,double")
5177 (set_attr "fp_int_src" "true")])
5179 (define_insn "*floatdisf2_memory"
5180 [(set (match_operand:SF 0 "register_operand" "=x")
5181 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5182 "TARGET_64BIT && TARGET_SSE_MATH
5183 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5184 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5185 [(set_attr "type" "sseicvt")
5186 (set_attr "mode" "SF")
5187 (set_attr "athlon_decode" "double")
5188 (set_attr "amdfam10_decode" "double")
5189 (set_attr "fp_int_src" "true")])
5191 (define_expand "floatdidf2"
5192 [(set (match_operand:DF 0 "register_operand" "")
5193 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5194 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5196 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5198 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5201 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5202 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5204 && !MEM_P (operands[1]))
5206 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5207 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5208 emit_move_insn (tmp, operands[1]);
5213 (define_insn "*floatdidf2_mixed"
5214 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5215 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5216 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5217 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5221 cvtsi2sd{q}\t{%1, %0|%0, %1}
5222 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5223 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5224 (set_attr "mode" "DF")
5225 (set_attr "unit" "*,i387,*,*")
5226 (set_attr "athlon_decode" "*,*,double,direct")
5227 (set_attr "amdfam10_decode" "*,*,vector,double")
5228 (set_attr "fp_int_src" "true")])
5230 (define_insn "*floatdidf2_mixed_memory"
5231 [(set (match_operand:DF 0 "register_operand" "=f,x")
5232 (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5233 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5234 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5237 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5238 [(set_attr "type" "fmov,sseicvt")
5239 (set_attr "mode" "DF")
5240 (set_attr "athlon_decode" "*,direct")
5241 (set_attr "amdfam10_decode" "*,double")
5242 (set_attr "fp_int_src" "true")])
5244 (define_insn "*floatdidf2_sse"
5245 [(set (match_operand:DF 0 "register_operand" "=x,x")
5246 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5247 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5248 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5249 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5250 [(set_attr "type" "sseicvt")
5251 (set_attr "mode" "DF")
5252 (set_attr "athlon_decode" "double,direct")
5253 (set_attr "amdfam10_decode" "vector,double")
5254 (set_attr "fp_int_src" "true")])
5256 (define_insn "*floatdidf2_sse_memory"
5257 [(set (match_operand:DF 0 "register_operand" "=x")
5258 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5259 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5260 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5261 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5262 [(set_attr "type" "sseicvt")
5263 (set_attr "mode" "DF")
5264 (set_attr "athlon_decode" "direct")
5265 (set_attr "amdfam10_decode" "double")
5266 (set_attr "fp_int_src" "true")])
5268 (define_insn "*floatdi<mode>2_i387"
5269 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5271 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5273 && (!TARGET_SSE_MATH || !TARGET_64BIT
5274 || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5278 [(set_attr "type" "fmov,multi")
5279 (set_attr "mode" "<MODE>")
5280 (set_attr "unit" "*,i387")
5281 (set_attr "fp_int_src" "true")])
5283 (define_insn "float<mode>xf2"
5284 [(set (match_operand:XF 0 "register_operand" "=f,f")
5285 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5290 [(set_attr "type" "fmov,multi")
5291 (set_attr "mode" "XF")
5292 (set_attr "unit" "*,i387")
5293 (set_attr "fp_int_src" "true")])
5295 ;; %%% Kill these when reload knows how to do it.
5297 [(set (match_operand 0 "fp_register_operand" "")
5298 (float (match_operand 1 "register_operand" "")))]
5300 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5303 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5304 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5305 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5306 ix86_free_from_memory (GET_MODE (operands[1]));
5310 (define_expand "floatunssi<mode>2"
5311 [(use (match_operand:MODEF 0 "register_operand" ""))
5312 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5313 "!TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5315 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5319 (define_expand "floatunsdisf2"
5320 [(use (match_operand:SF 0 "register_operand" ""))
5321 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5322 "TARGET_64BIT && TARGET_SSE_MATH"
5323 "x86_emit_floatuns (operands); DONE;")
5325 (define_expand "floatunsdidf2"
5326 [(use (match_operand:DF 0 "register_operand" ""))
5327 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5328 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5329 && TARGET_SSE2 && TARGET_SSE_MATH"
5332 x86_emit_floatuns (operands);
5334 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5340 ;; %%% splits for addditi3
5342 (define_expand "addti3"
5343 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5344 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5345 (match_operand:TI 2 "x86_64_general_operand" "")))
5346 (clobber (reg:CC FLAGS_REG))]
5348 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5350 (define_insn "*addti3_1"
5351 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5352 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5353 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5354 (clobber (reg:CC FLAGS_REG))]
5355 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5359 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5360 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5361 (match_operand:TI 2 "x86_64_general_operand" "")))
5362 (clobber (reg:CC FLAGS_REG))]
5363 "TARGET_64BIT && reload_completed"
5364 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5366 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5367 (parallel [(set (match_dup 3)
5368 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5371 (clobber (reg:CC FLAGS_REG))])]
5372 "split_ti (operands+0, 1, operands+0, operands+3);
5373 split_ti (operands+1, 1, operands+1, operands+4);
5374 split_ti (operands+2, 1, operands+2, operands+5);")
5376 ;; %%% splits for addsidi3
5377 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5378 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5379 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5381 (define_expand "adddi3"
5382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5383 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5384 (match_operand:DI 2 "x86_64_general_operand" "")))
5385 (clobber (reg:CC FLAGS_REG))]
5387 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5389 (define_insn "*adddi3_1"
5390 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5391 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5392 (match_operand:DI 2 "general_operand" "roiF,riF")))
5393 (clobber (reg:CC FLAGS_REG))]
5394 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5398 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5399 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5400 (match_operand:DI 2 "general_operand" "")))
5401 (clobber (reg:CC FLAGS_REG))]
5402 "!TARGET_64BIT && reload_completed"
5403 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5405 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5406 (parallel [(set (match_dup 3)
5407 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5410 (clobber (reg:CC FLAGS_REG))])]
5411 "split_di (operands+0, 1, operands+0, operands+3);
5412 split_di (operands+1, 1, operands+1, operands+4);
5413 split_di (operands+2, 1, operands+2, operands+5);")
5415 (define_insn "adddi3_carry_rex64"
5416 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5417 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5418 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5419 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5420 (clobber (reg:CC FLAGS_REG))]
5421 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5422 "adc{q}\t{%2, %0|%0, %2}"
5423 [(set_attr "type" "alu")
5424 (set_attr "pent_pair" "pu")
5425 (set_attr "mode" "DI")])
5427 (define_insn "*adddi3_cc_rex64"
5428 [(set (reg:CC FLAGS_REG)
5429 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5430 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5432 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5433 (plus:DI (match_dup 1) (match_dup 2)))]
5434 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5435 "add{q}\t{%2, %0|%0, %2}"
5436 [(set_attr "type" "alu")
5437 (set_attr "mode" "DI")])
5439 (define_insn "*<addsub><mode>3_cc_overflow"
5440 [(set (reg:CCC FLAGS_REG)
5443 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5444 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5446 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5447 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5448 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5449 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5450 [(set_attr "type" "alu")
5451 (set_attr "mode" "<MODE>")])
5453 (define_insn "*add<mode>3_cconly_overflow"
5454 [(set (reg:CCC FLAGS_REG)
5456 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5457 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5459 (clobber (match_scratch:SWI 0 "=<r>"))]
5460 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5461 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5462 [(set_attr "type" "alu")
5463 (set_attr "mode" "<MODE>")])
5465 (define_insn "*sub<mode>3_cconly_overflow"
5466 [(set (reg:CCC FLAGS_REG)
5468 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5469 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5472 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5473 [(set_attr "type" "icmp")
5474 (set_attr "mode" "<MODE>")])
5476 (define_insn "*<addsub>si3_zext_cc_overflow"
5477 [(set (reg:CCC FLAGS_REG)
5479 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5480 (match_operand:SI 2 "general_operand" "g"))
5482 (set (match_operand:DI 0 "register_operand" "=r")
5483 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5484 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5485 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5486 [(set_attr "type" "alu")
5487 (set_attr "mode" "SI")])
5489 (define_insn "addqi3_carry"
5490 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5491 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5492 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5493 (match_operand:QI 2 "general_operand" "qi,qm")))
5494 (clobber (reg:CC FLAGS_REG))]
5495 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5496 "adc{b}\t{%2, %0|%0, %2}"
5497 [(set_attr "type" "alu")
5498 (set_attr "pent_pair" "pu")
5499 (set_attr "mode" "QI")])
5501 (define_insn "addhi3_carry"
5502 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5503 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5504 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5505 (match_operand:HI 2 "general_operand" "ri,rm")))
5506 (clobber (reg:CC FLAGS_REG))]
5507 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5508 "adc{w}\t{%2, %0|%0, %2}"
5509 [(set_attr "type" "alu")
5510 (set_attr "pent_pair" "pu")
5511 (set_attr "mode" "HI")])
5513 (define_insn "addsi3_carry"
5514 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5515 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5516 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5517 (match_operand:SI 2 "general_operand" "ri,rm")))
5518 (clobber (reg:CC FLAGS_REG))]
5519 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5520 "adc{l}\t{%2, %0|%0, %2}"
5521 [(set_attr "type" "alu")
5522 (set_attr "pent_pair" "pu")
5523 (set_attr "mode" "SI")])
5525 (define_insn "*addsi3_carry_zext"
5526 [(set (match_operand:DI 0 "register_operand" "=r")
5528 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5529 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5530 (match_operand:SI 2 "general_operand" "g"))))
5531 (clobber (reg:CC FLAGS_REG))]
5532 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5533 "adc{l}\t{%2, %k0|%k0, %2}"
5534 [(set_attr "type" "alu")
5535 (set_attr "pent_pair" "pu")
5536 (set_attr "mode" "SI")])
5538 (define_insn "*addsi3_cc"
5539 [(set (reg:CC FLAGS_REG)
5540 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5541 (match_operand:SI 2 "general_operand" "ri,rm")]
5543 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5544 (plus:SI (match_dup 1) (match_dup 2)))]
5545 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5546 "add{l}\t{%2, %0|%0, %2}"
5547 [(set_attr "type" "alu")
5548 (set_attr "mode" "SI")])
5550 (define_insn "addqi3_cc"
5551 [(set (reg:CC FLAGS_REG)
5552 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5553 (match_operand:QI 2 "general_operand" "qi,qm")]
5555 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5556 (plus:QI (match_dup 1) (match_dup 2)))]
5557 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5558 "add{b}\t{%2, %0|%0, %2}"
5559 [(set_attr "type" "alu")
5560 (set_attr "mode" "QI")])
5562 (define_expand "addsi3"
5563 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5564 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5565 (match_operand:SI 2 "general_operand" "")))
5566 (clobber (reg:CC FLAGS_REG))])]
5568 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5570 (define_insn "*lea_1"
5571 [(set (match_operand:SI 0 "register_operand" "=r")
5572 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5574 "lea{l}\t{%a1, %0|%0, %a1}"
5575 [(set_attr "type" "lea")
5576 (set_attr "mode" "SI")])
5578 (define_insn "*lea_1_rex64"
5579 [(set (match_operand:SI 0 "register_operand" "=r")
5580 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5582 "lea{l}\t{%a1, %0|%0, %a1}"
5583 [(set_attr "type" "lea")
5584 (set_attr "mode" "SI")])
5586 (define_insn "*lea_1_zext"
5587 [(set (match_operand:DI 0 "register_operand" "=r")
5589 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5591 "lea{l}\t{%a1, %k0|%k0, %a1}"
5592 [(set_attr "type" "lea")
5593 (set_attr "mode" "SI")])
5595 (define_insn "*lea_2_rex64"
5596 [(set (match_operand:DI 0 "register_operand" "=r")
5597 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5599 "lea{q}\t{%a1, %0|%0, %a1}"
5600 [(set_attr "type" "lea")
5601 (set_attr "mode" "DI")])
5603 ;; The lea patterns for non-Pmodes needs to be matched by several
5604 ;; insns converted to real lea by splitters.
5606 (define_insn_and_split "*lea_general_1"
5607 [(set (match_operand 0 "register_operand" "=r")
5608 (plus (plus (match_operand 1 "index_register_operand" "l")
5609 (match_operand 2 "register_operand" "r"))
5610 (match_operand 3 "immediate_operand" "i")))]
5611 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5612 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5613 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5614 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5615 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5616 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5617 || GET_MODE (operands[3]) == VOIDmode)"
5619 "&& reload_completed"
5623 operands[0] = gen_lowpart (SImode, operands[0]);
5624 operands[1] = gen_lowpart (Pmode, operands[1]);
5625 operands[2] = gen_lowpart (Pmode, operands[2]);
5626 operands[3] = gen_lowpart (Pmode, operands[3]);
5627 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5629 if (Pmode != SImode)
5630 pat = gen_rtx_SUBREG (SImode, pat, 0);
5631 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5634 [(set_attr "type" "lea")
5635 (set_attr "mode" "SI")])
5637 (define_insn_and_split "*lea_general_1_zext"
5638 [(set (match_operand:DI 0 "register_operand" "=r")
5640 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5641 (match_operand:SI 2 "register_operand" "r"))
5642 (match_operand:SI 3 "immediate_operand" "i"))))]
5645 "&& reload_completed"
5647 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5649 (match_dup 3)) 0)))]
5651 operands[1] = gen_lowpart (Pmode, operands[1]);
5652 operands[2] = gen_lowpart (Pmode, operands[2]);
5653 operands[3] = gen_lowpart (Pmode, operands[3]);
5655 [(set_attr "type" "lea")
5656 (set_attr "mode" "SI")])
5658 (define_insn_and_split "*lea_general_2"
5659 [(set (match_operand 0 "register_operand" "=r")
5660 (plus (mult (match_operand 1 "index_register_operand" "l")
5661 (match_operand 2 "const248_operand" "i"))
5662 (match_operand 3 "nonmemory_operand" "ri")))]
5663 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5664 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5665 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5666 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5667 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5668 || GET_MODE (operands[3]) == VOIDmode)"
5670 "&& reload_completed"
5674 operands[0] = gen_lowpart (SImode, operands[0]);
5675 operands[1] = gen_lowpart (Pmode, operands[1]);
5676 operands[3] = gen_lowpart (Pmode, operands[3]);
5677 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5679 if (Pmode != SImode)
5680 pat = gen_rtx_SUBREG (SImode, pat, 0);
5681 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5684 [(set_attr "type" "lea")
5685 (set_attr "mode" "SI")])
5687 (define_insn_and_split "*lea_general_2_zext"
5688 [(set (match_operand:DI 0 "register_operand" "=r")
5690 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5691 (match_operand:SI 2 "const248_operand" "n"))
5692 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5695 "&& reload_completed"
5697 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5699 (match_dup 3)) 0)))]
5701 operands[1] = gen_lowpart (Pmode, operands[1]);
5702 operands[3] = gen_lowpart (Pmode, operands[3]);
5704 [(set_attr "type" "lea")
5705 (set_attr "mode" "SI")])
5707 (define_insn_and_split "*lea_general_3"
5708 [(set (match_operand 0 "register_operand" "=r")
5709 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5710 (match_operand 2 "const248_operand" "i"))
5711 (match_operand 3 "register_operand" "r"))
5712 (match_operand 4 "immediate_operand" "i")))]
5713 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5714 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5715 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5716 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5717 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5719 "&& reload_completed"
5723 operands[0] = gen_lowpart (SImode, operands[0]);
5724 operands[1] = gen_lowpart (Pmode, operands[1]);
5725 operands[3] = gen_lowpart (Pmode, operands[3]);
5726 operands[4] = gen_lowpart (Pmode, operands[4]);
5727 pat = gen_rtx_PLUS (Pmode,
5728 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5732 if (Pmode != SImode)
5733 pat = gen_rtx_SUBREG (SImode, pat, 0);
5734 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5737 [(set_attr "type" "lea")
5738 (set_attr "mode" "SI")])
5740 (define_insn_and_split "*lea_general_3_zext"
5741 [(set (match_operand:DI 0 "register_operand" "=r")
5743 (plus:SI (plus:SI (mult:SI
5744 (match_operand:SI 1 "index_register_operand" "l")
5745 (match_operand:SI 2 "const248_operand" "n"))
5746 (match_operand:SI 3 "register_operand" "r"))
5747 (match_operand:SI 4 "immediate_operand" "i"))))]
5750 "&& reload_completed"
5752 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5755 (match_dup 4)) 0)))]
5757 operands[1] = gen_lowpart (Pmode, operands[1]);
5758 operands[3] = gen_lowpart (Pmode, operands[3]);
5759 operands[4] = gen_lowpart (Pmode, operands[4]);
5761 [(set_attr "type" "lea")
5762 (set_attr "mode" "SI")])
5764 (define_insn "*adddi_1_rex64"
5765 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5766 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5767 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5768 (clobber (reg:CC FLAGS_REG))]
5769 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5771 switch (get_attr_type (insn))
5774 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5775 return "lea{q}\t{%a2, %0|%0, %a2}";
5778 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5779 if (operands[2] == const1_rtx)
5780 return "inc{q}\t%0";
5783 gcc_assert (operands[2] == constm1_rtx);
5784 return "dec{q}\t%0";
5788 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5790 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5791 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5792 if (CONST_INT_P (operands[2])
5793 /* Avoid overflows. */
5794 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5795 && (INTVAL (operands[2]) == 128
5796 || (INTVAL (operands[2]) < 0
5797 && INTVAL (operands[2]) != -128)))
5799 operands[2] = GEN_INT (-INTVAL (operands[2]));
5800 return "sub{q}\t{%2, %0|%0, %2}";
5802 return "add{q}\t{%2, %0|%0, %2}";
5806 (cond [(eq_attr "alternative" "2")
5807 (const_string "lea")
5808 ; Current assemblers are broken and do not allow @GOTOFF in
5809 ; ought but a memory context.
5810 (match_operand:DI 2 "pic_symbolic_operand" "")
5811 (const_string "lea")
5812 (match_operand:DI 2 "incdec_operand" "")
5813 (const_string "incdec")
5815 (const_string "alu")))
5816 (set_attr "mode" "DI")])
5818 ;; Convert lea to the lea pattern to avoid flags dependency.
5820 [(set (match_operand:DI 0 "register_operand" "")
5821 (plus:DI (match_operand:DI 1 "register_operand" "")
5822 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5823 (clobber (reg:CC FLAGS_REG))]
5824 "TARGET_64BIT && reload_completed
5825 && true_regnum (operands[0]) != true_regnum (operands[1])"
5827 (plus:DI (match_dup 1)
5831 (define_insn "*adddi_2_rex64"
5832 [(set (reg FLAGS_REG)
5834 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5835 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5837 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5838 (plus:DI (match_dup 1) (match_dup 2)))]
5839 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5840 && ix86_binary_operator_ok (PLUS, DImode, operands)
5841 /* Current assemblers are broken and do not allow @GOTOFF in
5842 ought but a memory context. */
5843 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5845 switch (get_attr_type (insn))
5848 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5849 if (operands[2] == const1_rtx)
5850 return "inc{q}\t%0";
5853 gcc_assert (operands[2] == constm1_rtx);
5854 return "dec{q}\t%0";
5858 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5859 /* ???? We ought to handle there the 32bit case too
5860 - do we need new constraint? */
5861 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5862 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5863 if (CONST_INT_P (operands[2])
5864 /* Avoid overflows. */
5865 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5866 && (INTVAL (operands[2]) == 128
5867 || (INTVAL (operands[2]) < 0
5868 && INTVAL (operands[2]) != -128)))
5870 operands[2] = GEN_INT (-INTVAL (operands[2]));
5871 return "sub{q}\t{%2, %0|%0, %2}";
5873 return "add{q}\t{%2, %0|%0, %2}";
5877 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5878 (const_string "incdec")
5879 (const_string "alu")))
5880 (set_attr "mode" "DI")])
5882 (define_insn "*adddi_3_rex64"
5883 [(set (reg FLAGS_REG)
5884 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5885 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5886 (clobber (match_scratch:DI 0 "=r"))]
5888 && ix86_match_ccmode (insn, CCZmode)
5889 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5890 /* Current assemblers are broken and do not allow @GOTOFF in
5891 ought but a memory context. */
5892 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5894 switch (get_attr_type (insn))
5897 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5898 if (operands[2] == const1_rtx)
5899 return "inc{q}\t%0";
5902 gcc_assert (operands[2] == constm1_rtx);
5903 return "dec{q}\t%0";
5907 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5908 /* ???? We ought to handle there the 32bit case too
5909 - do we need new constraint? */
5910 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5911 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5912 if (CONST_INT_P (operands[2])
5913 /* Avoid overflows. */
5914 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5915 && (INTVAL (operands[2]) == 128
5916 || (INTVAL (operands[2]) < 0
5917 && INTVAL (operands[2]) != -128)))
5919 operands[2] = GEN_INT (-INTVAL (operands[2]));
5920 return "sub{q}\t{%2, %0|%0, %2}";
5922 return "add{q}\t{%2, %0|%0, %2}";
5926 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5927 (const_string "incdec")
5928 (const_string "alu")))
5929 (set_attr "mode" "DI")])
5931 ; For comparisons against 1, -1 and 128, we may generate better code
5932 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5933 ; is matched then. We can't accept general immediate, because for
5934 ; case of overflows, the result is messed up.
5935 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5937 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5938 ; only for comparisons not depending on it.
5939 (define_insn "*adddi_4_rex64"
5940 [(set (reg FLAGS_REG)
5941 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5942 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5943 (clobber (match_scratch:DI 0 "=rm"))]
5945 && ix86_match_ccmode (insn, CCGCmode)"
5947 switch (get_attr_type (insn))
5950 if (operands[2] == constm1_rtx)
5951 return "inc{q}\t%0";
5954 gcc_assert (operands[2] == const1_rtx);
5955 return "dec{q}\t%0";
5959 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5960 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5962 if ((INTVAL (operands[2]) == -128
5963 || (INTVAL (operands[2]) > 0
5964 && INTVAL (operands[2]) != 128))
5965 /* Avoid overflows. */
5966 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5967 return "sub{q}\t{%2, %0|%0, %2}";
5968 operands[2] = GEN_INT (-INTVAL (operands[2]));
5969 return "add{q}\t{%2, %0|%0, %2}";
5973 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5974 (const_string "incdec")
5975 (const_string "alu")))
5976 (set_attr "mode" "DI")])
5978 (define_insn "*adddi_5_rex64"
5979 [(set (reg FLAGS_REG)
5981 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5982 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5984 (clobber (match_scratch:DI 0 "=r"))]
5986 && ix86_match_ccmode (insn, CCGOCmode)
5987 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5988 /* Current assemblers are broken and do not allow @GOTOFF in
5989 ought but a memory context. */
5990 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5992 switch (get_attr_type (insn))
5995 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5996 if (operands[2] == const1_rtx)
5997 return "inc{q}\t%0";
6000 gcc_assert (operands[2] == constm1_rtx);
6001 return "dec{q}\t%0";
6005 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6006 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6007 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6008 if (CONST_INT_P (operands[2])
6009 /* Avoid overflows. */
6010 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6011 && (INTVAL (operands[2]) == 128
6012 || (INTVAL (operands[2]) < 0
6013 && INTVAL (operands[2]) != -128)))
6015 operands[2] = GEN_INT (-INTVAL (operands[2]));
6016 return "sub{q}\t{%2, %0|%0, %2}";
6018 return "add{q}\t{%2, %0|%0, %2}";
6022 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6023 (const_string "incdec")
6024 (const_string "alu")))
6025 (set_attr "mode" "DI")])
6028 (define_insn "*addsi_1"
6029 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6030 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6031 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6032 (clobber (reg:CC FLAGS_REG))]
6033 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6035 switch (get_attr_type (insn))
6038 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6039 return "lea{l}\t{%a2, %0|%0, %a2}";
6042 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6043 if (operands[2] == const1_rtx)
6044 return "inc{l}\t%0";
6047 gcc_assert (operands[2] == constm1_rtx);
6048 return "dec{l}\t%0";
6052 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6054 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6055 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6056 if (CONST_INT_P (operands[2])
6057 && (INTVAL (operands[2]) == 128
6058 || (INTVAL (operands[2]) < 0
6059 && INTVAL (operands[2]) != -128)))
6061 operands[2] = GEN_INT (-INTVAL (operands[2]));
6062 return "sub{l}\t{%2, %0|%0, %2}";
6064 return "add{l}\t{%2, %0|%0, %2}";
6068 (cond [(eq_attr "alternative" "2")
6069 (const_string "lea")
6070 ; Current assemblers are broken and do not allow @GOTOFF in
6071 ; ought but a memory context.
6072 (match_operand:SI 2 "pic_symbolic_operand" "")
6073 (const_string "lea")
6074 (match_operand:SI 2 "incdec_operand" "")
6075 (const_string "incdec")
6077 (const_string "alu")))
6078 (set_attr "mode" "SI")])
6080 ;; Convert lea to the lea pattern to avoid flags dependency.
6082 [(set (match_operand 0 "register_operand" "")
6083 (plus (match_operand 1 "register_operand" "")
6084 (match_operand 2 "nonmemory_operand" "")))
6085 (clobber (reg:CC FLAGS_REG))]
6087 && true_regnum (operands[0]) != true_regnum (operands[1])"
6091 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6092 may confuse gen_lowpart. */
6093 if (GET_MODE (operands[0]) != Pmode)
6095 operands[1] = gen_lowpart (Pmode, operands[1]);
6096 operands[2] = gen_lowpart (Pmode, operands[2]);
6098 operands[0] = gen_lowpart (SImode, operands[0]);
6099 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6100 if (Pmode != SImode)
6101 pat = gen_rtx_SUBREG (SImode, pat, 0);
6102 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6106 ;; It may seem that nonimmediate operand is proper one for operand 1.
6107 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6108 ;; we take care in ix86_binary_operator_ok to not allow two memory
6109 ;; operands so proper swapping will be done in reload. This allow
6110 ;; patterns constructed from addsi_1 to match.
6111 (define_insn "addsi_1_zext"
6112 [(set (match_operand:DI 0 "register_operand" "=r,r")
6114 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6115 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6116 (clobber (reg:CC FLAGS_REG))]
6117 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6119 switch (get_attr_type (insn))
6122 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6123 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6126 if (operands[2] == const1_rtx)
6127 return "inc{l}\t%k0";
6130 gcc_assert (operands[2] == constm1_rtx);
6131 return "dec{l}\t%k0";
6135 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6136 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6137 if (CONST_INT_P (operands[2])
6138 && (INTVAL (operands[2]) == 128
6139 || (INTVAL (operands[2]) < 0
6140 && INTVAL (operands[2]) != -128)))
6142 operands[2] = GEN_INT (-INTVAL (operands[2]));
6143 return "sub{l}\t{%2, %k0|%k0, %2}";
6145 return "add{l}\t{%2, %k0|%k0, %2}";
6149 (cond [(eq_attr "alternative" "1")
6150 (const_string "lea")
6151 ; Current assemblers are broken and do not allow @GOTOFF in
6152 ; ought but a memory context.
6153 (match_operand:SI 2 "pic_symbolic_operand" "")
6154 (const_string "lea")
6155 (match_operand:SI 2 "incdec_operand" "")
6156 (const_string "incdec")
6158 (const_string "alu")))
6159 (set_attr "mode" "SI")])
6161 ;; Convert lea to the lea pattern to avoid flags dependency.
6163 [(set (match_operand:DI 0 "register_operand" "")
6165 (plus:SI (match_operand:SI 1 "register_operand" "")
6166 (match_operand:SI 2 "nonmemory_operand" ""))))
6167 (clobber (reg:CC FLAGS_REG))]
6168 "TARGET_64BIT && reload_completed
6169 && true_regnum (operands[0]) != true_regnum (operands[1])"
6171 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6173 operands[1] = gen_lowpart (Pmode, operands[1]);
6174 operands[2] = gen_lowpart (Pmode, operands[2]);
6177 (define_insn "*addsi_2"
6178 [(set (reg FLAGS_REG)
6180 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6181 (match_operand:SI 2 "general_operand" "rmni,rni"))
6183 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6184 (plus:SI (match_dup 1) (match_dup 2)))]
6185 "ix86_match_ccmode (insn, CCGOCmode)
6186 && ix86_binary_operator_ok (PLUS, SImode, operands)
6187 /* Current assemblers are broken and do not allow @GOTOFF in
6188 ought but a memory context. */
6189 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6191 switch (get_attr_type (insn))
6194 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6195 if (operands[2] == const1_rtx)
6196 return "inc{l}\t%0";
6199 gcc_assert (operands[2] == constm1_rtx);
6200 return "dec{l}\t%0";
6204 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6205 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6206 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6207 if (CONST_INT_P (operands[2])
6208 && (INTVAL (operands[2]) == 128
6209 || (INTVAL (operands[2]) < 0
6210 && INTVAL (operands[2]) != -128)))
6212 operands[2] = GEN_INT (-INTVAL (operands[2]));
6213 return "sub{l}\t{%2, %0|%0, %2}";
6215 return "add{l}\t{%2, %0|%0, %2}";
6219 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6220 (const_string "incdec")
6221 (const_string "alu")))
6222 (set_attr "mode" "SI")])
6224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6225 (define_insn "*addsi_2_zext"
6226 [(set (reg FLAGS_REG)
6228 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6229 (match_operand:SI 2 "general_operand" "rmni"))
6231 (set (match_operand:DI 0 "register_operand" "=r")
6232 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6233 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6234 && ix86_binary_operator_ok (PLUS, SImode, operands)
6235 /* Current assemblers are broken and do not allow @GOTOFF in
6236 ought but a memory context. */
6237 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6239 switch (get_attr_type (insn))
6242 if (operands[2] == const1_rtx)
6243 return "inc{l}\t%k0";
6246 gcc_assert (operands[2] == constm1_rtx);
6247 return "dec{l}\t%k0";
6251 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6252 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6253 if (CONST_INT_P (operands[2])
6254 && (INTVAL (operands[2]) == 128
6255 || (INTVAL (operands[2]) < 0
6256 && INTVAL (operands[2]) != -128)))
6258 operands[2] = GEN_INT (-INTVAL (operands[2]));
6259 return "sub{l}\t{%2, %k0|%k0, %2}";
6261 return "add{l}\t{%2, %k0|%k0, %2}";
6265 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6266 (const_string "incdec")
6267 (const_string "alu")))
6268 (set_attr "mode" "SI")])
6270 (define_insn "*addsi_3"
6271 [(set (reg FLAGS_REG)
6272 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6273 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6274 (clobber (match_scratch:SI 0 "=r"))]
6275 "ix86_match_ccmode (insn, CCZmode)
6276 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6277 /* Current assemblers are broken and do not allow @GOTOFF in
6278 ought but a memory context. */
6279 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6281 switch (get_attr_type (insn))
6284 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6285 if (operands[2] == const1_rtx)
6286 return "inc{l}\t%0";
6289 gcc_assert (operands[2] == constm1_rtx);
6290 return "dec{l}\t%0";
6294 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6295 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6296 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6297 if (CONST_INT_P (operands[2])
6298 && (INTVAL (operands[2]) == 128
6299 || (INTVAL (operands[2]) < 0
6300 && INTVAL (operands[2]) != -128)))
6302 operands[2] = GEN_INT (-INTVAL (operands[2]));
6303 return "sub{l}\t{%2, %0|%0, %2}";
6305 return "add{l}\t{%2, %0|%0, %2}";
6309 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6310 (const_string "incdec")
6311 (const_string "alu")))
6312 (set_attr "mode" "SI")])
6314 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6315 (define_insn "*addsi_3_zext"
6316 [(set (reg FLAGS_REG)
6317 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6318 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6319 (set (match_operand:DI 0 "register_operand" "=r")
6320 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6321 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6322 && ix86_binary_operator_ok (PLUS, SImode, operands)
6323 /* Current assemblers are broken and do not allow @GOTOFF in
6324 ought but a memory context. */
6325 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6327 switch (get_attr_type (insn))
6330 if (operands[2] == const1_rtx)
6331 return "inc{l}\t%k0";
6334 gcc_assert (operands[2] == constm1_rtx);
6335 return "dec{l}\t%k0";
6339 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6340 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6341 if (CONST_INT_P (operands[2])
6342 && (INTVAL (operands[2]) == 128
6343 || (INTVAL (operands[2]) < 0
6344 && INTVAL (operands[2]) != -128)))
6346 operands[2] = GEN_INT (-INTVAL (operands[2]));
6347 return "sub{l}\t{%2, %k0|%k0, %2}";
6349 return "add{l}\t{%2, %k0|%k0, %2}";
6353 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6354 (const_string "incdec")
6355 (const_string "alu")))
6356 (set_attr "mode" "SI")])
6358 ; For comparisons against 1, -1 and 128, we may generate better code
6359 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6360 ; is matched then. We can't accept general immediate, because for
6361 ; case of overflows, the result is messed up.
6362 ; This pattern also don't hold of 0x80000000, since the value overflows
6364 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6365 ; only for comparisons not depending on it.
6366 (define_insn "*addsi_4"
6367 [(set (reg FLAGS_REG)
6368 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6369 (match_operand:SI 2 "const_int_operand" "n")))
6370 (clobber (match_scratch:SI 0 "=rm"))]
6371 "ix86_match_ccmode (insn, CCGCmode)
6372 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6374 switch (get_attr_type (insn))
6377 if (operands[2] == constm1_rtx)
6378 return "inc{l}\t%0";
6381 gcc_assert (operands[2] == const1_rtx);
6382 return "dec{l}\t%0";
6386 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6387 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6388 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6389 if ((INTVAL (operands[2]) == -128
6390 || (INTVAL (operands[2]) > 0
6391 && INTVAL (operands[2]) != 128)))
6392 return "sub{l}\t{%2, %0|%0, %2}";
6393 operands[2] = GEN_INT (-INTVAL (operands[2]));
6394 return "add{l}\t{%2, %0|%0, %2}";
6398 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6399 (const_string "incdec")
6400 (const_string "alu")))
6401 (set_attr "mode" "SI")])
6403 (define_insn "*addsi_5"
6404 [(set (reg FLAGS_REG)
6406 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6407 (match_operand:SI 2 "general_operand" "rmni"))
6409 (clobber (match_scratch:SI 0 "=r"))]
6410 "ix86_match_ccmode (insn, CCGOCmode)
6411 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6412 /* Current assemblers are broken and do not allow @GOTOFF in
6413 ought but a memory context. */
6414 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6416 switch (get_attr_type (insn))
6419 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6420 if (operands[2] == const1_rtx)
6421 return "inc{l}\t%0";
6424 gcc_assert (operands[2] == constm1_rtx);
6425 return "dec{l}\t%0";
6429 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6430 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6431 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6432 if (CONST_INT_P (operands[2])
6433 && (INTVAL (operands[2]) == 128
6434 || (INTVAL (operands[2]) < 0
6435 && INTVAL (operands[2]) != -128)))
6437 operands[2] = GEN_INT (-INTVAL (operands[2]));
6438 return "sub{l}\t{%2, %0|%0, %2}";
6440 return "add{l}\t{%2, %0|%0, %2}";
6444 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6445 (const_string "incdec")
6446 (const_string "alu")))
6447 (set_attr "mode" "SI")])
6449 (define_expand "addhi3"
6450 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6451 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6452 (match_operand:HI 2 "general_operand" "")))
6453 (clobber (reg:CC FLAGS_REG))])]
6454 "TARGET_HIMODE_MATH"
6455 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6457 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6458 ;; type optimizations enabled by define-splits. This is not important
6459 ;; for PII, and in fact harmful because of partial register stalls.
6461 (define_insn "*addhi_1_lea"
6462 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6463 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6464 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6465 (clobber (reg:CC FLAGS_REG))]
6466 "!TARGET_PARTIAL_REG_STALL
6467 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6469 switch (get_attr_type (insn))
6474 if (operands[2] == const1_rtx)
6475 return "inc{w}\t%0";
6478 gcc_assert (operands[2] == constm1_rtx);
6479 return "dec{w}\t%0";
6483 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6484 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6485 if (CONST_INT_P (operands[2])
6486 && (INTVAL (operands[2]) == 128
6487 || (INTVAL (operands[2]) < 0
6488 && INTVAL (operands[2]) != -128)))
6490 operands[2] = GEN_INT (-INTVAL (operands[2]));
6491 return "sub{w}\t{%2, %0|%0, %2}";
6493 return "add{w}\t{%2, %0|%0, %2}";
6497 (if_then_else (eq_attr "alternative" "2")
6498 (const_string "lea")
6499 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6500 (const_string "incdec")
6501 (const_string "alu"))))
6502 (set_attr "mode" "HI,HI,SI")])
6504 (define_insn "*addhi_1"
6505 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6506 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6507 (match_operand:HI 2 "general_operand" "ri,rm")))
6508 (clobber (reg:CC FLAGS_REG))]
6509 "TARGET_PARTIAL_REG_STALL
6510 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6512 switch (get_attr_type (insn))
6515 if (operands[2] == const1_rtx)
6516 return "inc{w}\t%0";
6519 gcc_assert (operands[2] == constm1_rtx);
6520 return "dec{w}\t%0";
6524 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6525 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6526 if (CONST_INT_P (operands[2])
6527 && (INTVAL (operands[2]) == 128
6528 || (INTVAL (operands[2]) < 0
6529 && INTVAL (operands[2]) != -128)))
6531 operands[2] = GEN_INT (-INTVAL (operands[2]));
6532 return "sub{w}\t{%2, %0|%0, %2}";
6534 return "add{w}\t{%2, %0|%0, %2}";
6538 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6539 (const_string "incdec")
6540 (const_string "alu")))
6541 (set_attr "mode" "HI")])
6543 (define_insn "*addhi_2"
6544 [(set (reg FLAGS_REG)
6546 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6547 (match_operand:HI 2 "general_operand" "rmni,rni"))
6549 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6550 (plus:HI (match_dup 1) (match_dup 2)))]
6551 "ix86_match_ccmode (insn, CCGOCmode)
6552 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6554 switch (get_attr_type (insn))
6557 if (operands[2] == const1_rtx)
6558 return "inc{w}\t%0";
6561 gcc_assert (operands[2] == constm1_rtx);
6562 return "dec{w}\t%0";
6566 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6567 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6568 if (CONST_INT_P (operands[2])
6569 && (INTVAL (operands[2]) == 128
6570 || (INTVAL (operands[2]) < 0
6571 && INTVAL (operands[2]) != -128)))
6573 operands[2] = GEN_INT (-INTVAL (operands[2]));
6574 return "sub{w}\t{%2, %0|%0, %2}";
6576 return "add{w}\t{%2, %0|%0, %2}";
6580 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6581 (const_string "incdec")
6582 (const_string "alu")))
6583 (set_attr "mode" "HI")])
6585 (define_insn "*addhi_3"
6586 [(set (reg FLAGS_REG)
6587 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6588 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6589 (clobber (match_scratch:HI 0 "=r"))]
6590 "ix86_match_ccmode (insn, CCZmode)
6591 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6593 switch (get_attr_type (insn))
6596 if (operands[2] == const1_rtx)
6597 return "inc{w}\t%0";
6600 gcc_assert (operands[2] == constm1_rtx);
6601 return "dec{w}\t%0";
6605 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6606 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6607 if (CONST_INT_P (operands[2])
6608 && (INTVAL (operands[2]) == 128
6609 || (INTVAL (operands[2]) < 0
6610 && INTVAL (operands[2]) != -128)))
6612 operands[2] = GEN_INT (-INTVAL (operands[2]));
6613 return "sub{w}\t{%2, %0|%0, %2}";
6615 return "add{w}\t{%2, %0|%0, %2}";
6619 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6620 (const_string "incdec")
6621 (const_string "alu")))
6622 (set_attr "mode" "HI")])
6624 ; See comments above addsi_4 for details.
6625 (define_insn "*addhi_4"
6626 [(set (reg FLAGS_REG)
6627 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6628 (match_operand:HI 2 "const_int_operand" "n")))
6629 (clobber (match_scratch:HI 0 "=rm"))]
6630 "ix86_match_ccmode (insn, CCGCmode)
6631 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6633 switch (get_attr_type (insn))
6636 if (operands[2] == constm1_rtx)
6637 return "inc{w}\t%0";
6640 gcc_assert (operands[2] == const1_rtx);
6641 return "dec{w}\t%0";
6645 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6646 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6647 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6648 if ((INTVAL (operands[2]) == -128
6649 || (INTVAL (operands[2]) > 0
6650 && INTVAL (operands[2]) != 128)))
6651 return "sub{w}\t{%2, %0|%0, %2}";
6652 operands[2] = GEN_INT (-INTVAL (operands[2]));
6653 return "add{w}\t{%2, %0|%0, %2}";
6657 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6658 (const_string "incdec")
6659 (const_string "alu")))
6660 (set_attr "mode" "SI")])
6663 (define_insn "*addhi_5"
6664 [(set (reg FLAGS_REG)
6666 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6667 (match_operand:HI 2 "general_operand" "rmni"))
6669 (clobber (match_scratch:HI 0 "=r"))]
6670 "ix86_match_ccmode (insn, CCGOCmode)
6671 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6673 switch (get_attr_type (insn))
6676 if (operands[2] == const1_rtx)
6677 return "inc{w}\t%0";
6680 gcc_assert (operands[2] == constm1_rtx);
6681 return "dec{w}\t%0";
6685 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6686 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6687 if (CONST_INT_P (operands[2])
6688 && (INTVAL (operands[2]) == 128
6689 || (INTVAL (operands[2]) < 0
6690 && INTVAL (operands[2]) != -128)))
6692 operands[2] = GEN_INT (-INTVAL (operands[2]));
6693 return "sub{w}\t{%2, %0|%0, %2}";
6695 return "add{w}\t{%2, %0|%0, %2}";
6699 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6700 (const_string "incdec")
6701 (const_string "alu")))
6702 (set_attr "mode" "HI")])
6704 (define_expand "addqi3"
6705 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6706 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6707 (match_operand:QI 2 "general_operand" "")))
6708 (clobber (reg:CC FLAGS_REG))])]
6709 "TARGET_QIMODE_MATH"
6710 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6712 ;; %%% Potential partial reg stall on alternative 2. What to do?
6713 (define_insn "*addqi_1_lea"
6714 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6715 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6716 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6717 (clobber (reg:CC FLAGS_REG))]
6718 "!TARGET_PARTIAL_REG_STALL
6719 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6721 int widen = (which_alternative == 2);
6722 switch (get_attr_type (insn))
6727 if (operands[2] == const1_rtx)
6728 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6731 gcc_assert (operands[2] == constm1_rtx);
6732 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6736 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6737 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6738 if (CONST_INT_P (operands[2])
6739 && (INTVAL (operands[2]) == 128
6740 || (INTVAL (operands[2]) < 0
6741 && INTVAL (operands[2]) != -128)))
6743 operands[2] = GEN_INT (-INTVAL (operands[2]));
6745 return "sub{l}\t{%2, %k0|%k0, %2}";
6747 return "sub{b}\t{%2, %0|%0, %2}";
6750 return "add{l}\t{%k2, %k0|%k0, %k2}";
6752 return "add{b}\t{%2, %0|%0, %2}";
6756 (if_then_else (eq_attr "alternative" "3")
6757 (const_string "lea")
6758 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6759 (const_string "incdec")
6760 (const_string "alu"))))
6761 (set_attr "mode" "QI,QI,SI,SI")])
6763 (define_insn "*addqi_1"
6764 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6765 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6766 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6767 (clobber (reg:CC FLAGS_REG))]
6768 "TARGET_PARTIAL_REG_STALL
6769 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6771 int widen = (which_alternative == 2);
6772 switch (get_attr_type (insn))
6775 if (operands[2] == const1_rtx)
6776 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6779 gcc_assert (operands[2] == constm1_rtx);
6780 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6784 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6785 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6786 if (CONST_INT_P (operands[2])
6787 && (INTVAL (operands[2]) == 128
6788 || (INTVAL (operands[2]) < 0
6789 && INTVAL (operands[2]) != -128)))
6791 operands[2] = GEN_INT (-INTVAL (operands[2]));
6793 return "sub{l}\t{%2, %k0|%k0, %2}";
6795 return "sub{b}\t{%2, %0|%0, %2}";
6798 return "add{l}\t{%k2, %k0|%k0, %k2}";
6800 return "add{b}\t{%2, %0|%0, %2}";
6804 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6805 (const_string "incdec")
6806 (const_string "alu")))
6807 (set_attr "mode" "QI,QI,SI")])
6809 (define_insn "*addqi_1_slp"
6810 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6811 (plus:QI (match_dup 0)
6812 (match_operand:QI 1 "general_operand" "qn,qnm")))
6813 (clobber (reg:CC FLAGS_REG))]
6814 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6815 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6817 switch (get_attr_type (insn))
6820 if (operands[1] == const1_rtx)
6821 return "inc{b}\t%0";
6824 gcc_assert (operands[1] == constm1_rtx);
6825 return "dec{b}\t%0";
6829 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6830 if (CONST_INT_P (operands[1])
6831 && INTVAL (operands[1]) < 0)
6833 operands[1] = GEN_INT (-INTVAL (operands[1]));
6834 return "sub{b}\t{%1, %0|%0, %1}";
6836 return "add{b}\t{%1, %0|%0, %1}";
6840 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6841 (const_string "incdec")
6842 (const_string "alu1")))
6843 (set (attr "memory")
6844 (if_then_else (match_operand 1 "memory_operand" "")
6845 (const_string "load")
6846 (const_string "none")))
6847 (set_attr "mode" "QI")])
6849 (define_insn "*addqi_2"
6850 [(set (reg FLAGS_REG)
6852 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6853 (match_operand:QI 2 "general_operand" "qmni,qni"))
6855 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6856 (plus:QI (match_dup 1) (match_dup 2)))]
6857 "ix86_match_ccmode (insn, CCGOCmode)
6858 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6860 switch (get_attr_type (insn))
6863 if (operands[2] == const1_rtx)
6864 return "inc{b}\t%0";
6867 gcc_assert (operands[2] == constm1_rtx
6868 || (CONST_INT_P (operands[2])
6869 && INTVAL (operands[2]) == 255));
6870 return "dec{b}\t%0";
6874 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6875 if (CONST_INT_P (operands[2])
6876 && INTVAL (operands[2]) < 0)
6878 operands[2] = GEN_INT (-INTVAL (operands[2]));
6879 return "sub{b}\t{%2, %0|%0, %2}";
6881 return "add{b}\t{%2, %0|%0, %2}";
6885 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6886 (const_string "incdec")
6887 (const_string "alu")))
6888 (set_attr "mode" "QI")])
6890 (define_insn "*addqi_3"
6891 [(set (reg FLAGS_REG)
6892 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6893 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6894 (clobber (match_scratch:QI 0 "=q"))]
6895 "ix86_match_ccmode (insn, CCZmode)
6896 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6898 switch (get_attr_type (insn))
6901 if (operands[2] == const1_rtx)
6902 return "inc{b}\t%0";
6905 gcc_assert (operands[2] == constm1_rtx
6906 || (CONST_INT_P (operands[2])
6907 && INTVAL (operands[2]) == 255));
6908 return "dec{b}\t%0";
6912 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6913 if (CONST_INT_P (operands[2])
6914 && INTVAL (operands[2]) < 0)
6916 operands[2] = GEN_INT (-INTVAL (operands[2]));
6917 return "sub{b}\t{%2, %0|%0, %2}";
6919 return "add{b}\t{%2, %0|%0, %2}";
6923 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6924 (const_string "incdec")
6925 (const_string "alu")))
6926 (set_attr "mode" "QI")])
6928 ; See comments above addsi_4 for details.
6929 (define_insn "*addqi_4"
6930 [(set (reg FLAGS_REG)
6931 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6932 (match_operand:QI 2 "const_int_operand" "n")))
6933 (clobber (match_scratch:QI 0 "=qm"))]
6934 "ix86_match_ccmode (insn, CCGCmode)
6935 && (INTVAL (operands[2]) & 0xff) != 0x80"
6937 switch (get_attr_type (insn))
6940 if (operands[2] == constm1_rtx
6941 || (CONST_INT_P (operands[2])
6942 && INTVAL (operands[2]) == 255))
6943 return "inc{b}\t%0";
6946 gcc_assert (operands[2] == const1_rtx);
6947 return "dec{b}\t%0";
6951 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6952 if (INTVAL (operands[2]) < 0)
6954 operands[2] = GEN_INT (-INTVAL (operands[2]));
6955 return "add{b}\t{%2, %0|%0, %2}";
6957 return "sub{b}\t{%2, %0|%0, %2}";
6961 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6962 (const_string "incdec")
6963 (const_string "alu")))
6964 (set_attr "mode" "QI")])
6967 (define_insn "*addqi_5"
6968 [(set (reg FLAGS_REG)
6970 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6971 (match_operand:QI 2 "general_operand" "qmni"))
6973 (clobber (match_scratch:QI 0 "=q"))]
6974 "ix86_match_ccmode (insn, CCGOCmode)
6975 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6977 switch (get_attr_type (insn))
6980 if (operands[2] == const1_rtx)
6981 return "inc{b}\t%0";
6984 gcc_assert (operands[2] == constm1_rtx
6985 || (CONST_INT_P (operands[2])
6986 && INTVAL (operands[2]) == 255));
6987 return "dec{b}\t%0";
6991 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6992 if (CONST_INT_P (operands[2])
6993 && INTVAL (operands[2]) < 0)
6995 operands[2] = GEN_INT (-INTVAL (operands[2]));
6996 return "sub{b}\t{%2, %0|%0, %2}";
6998 return "add{b}\t{%2, %0|%0, %2}";
7002 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7003 (const_string "incdec")
7004 (const_string "alu")))
7005 (set_attr "mode" "QI")])
7008 (define_insn "addqi_ext_1"
7009 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7014 (match_operand 1 "ext_register_operand" "0")
7017 (match_operand:QI 2 "general_operand" "Qmn")))
7018 (clobber (reg:CC FLAGS_REG))]
7021 switch (get_attr_type (insn))
7024 if (operands[2] == const1_rtx)
7025 return "inc{b}\t%h0";
7028 gcc_assert (operands[2] == constm1_rtx
7029 || (CONST_INT_P (operands[2])
7030 && INTVAL (operands[2]) == 255));
7031 return "dec{b}\t%h0";
7035 return "add{b}\t{%2, %h0|%h0, %2}";
7039 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7040 (const_string "incdec")
7041 (const_string "alu")))
7042 (set_attr "mode" "QI")])
7044 (define_insn "*addqi_ext_1_rex64"
7045 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7050 (match_operand 1 "ext_register_operand" "0")
7053 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7054 (clobber (reg:CC FLAGS_REG))]
7057 switch (get_attr_type (insn))
7060 if (operands[2] == const1_rtx)
7061 return "inc{b}\t%h0";
7064 gcc_assert (operands[2] == constm1_rtx
7065 || (CONST_INT_P (operands[2])
7066 && INTVAL (operands[2]) == 255));
7067 return "dec{b}\t%h0";
7071 return "add{b}\t{%2, %h0|%h0, %2}";
7075 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7076 (const_string "incdec")
7077 (const_string "alu")))
7078 (set_attr "mode" "QI")])
7080 (define_insn "*addqi_ext_2"
7081 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7086 (match_operand 1 "ext_register_operand" "%0")
7090 (match_operand 2 "ext_register_operand" "Q")
7093 (clobber (reg:CC FLAGS_REG))]
7095 "add{b}\t{%h2, %h0|%h0, %h2}"
7096 [(set_attr "type" "alu")
7097 (set_attr "mode" "QI")])
7099 ;; The patterns that match these are at the end of this file.
7101 (define_expand "addxf3"
7102 [(set (match_operand:XF 0 "register_operand" "")
7103 (plus:XF (match_operand:XF 1 "register_operand" "")
7104 (match_operand:XF 2 "register_operand" "")))]
7108 (define_expand "add<mode>3"
7109 [(set (match_operand:MODEF 0 "register_operand" "")
7110 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7111 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7112 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7115 ;; Subtract instructions
7117 ;; %%% splits for subditi3
7119 (define_expand "subti3"
7120 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7121 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7122 (match_operand:TI 2 "x86_64_general_operand" "")))
7123 (clobber (reg:CC FLAGS_REG))])]
7125 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7127 (define_insn "*subti3_1"
7128 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7129 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7130 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7131 (clobber (reg:CC FLAGS_REG))]
7132 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7136 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7137 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7138 (match_operand:TI 2 "x86_64_general_operand" "")))
7139 (clobber (reg:CC FLAGS_REG))]
7140 "TARGET_64BIT && reload_completed"
7141 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7142 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7143 (parallel [(set (match_dup 3)
7144 (minus:DI (match_dup 4)
7145 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7147 (clobber (reg:CC FLAGS_REG))])]
7148 "split_ti (operands+0, 1, operands+0, operands+3);
7149 split_ti (operands+1, 1, operands+1, operands+4);
7150 split_ti (operands+2, 1, operands+2, operands+5);")
7152 ;; %%% splits for subsidi3
7154 (define_expand "subdi3"
7155 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7156 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7157 (match_operand:DI 2 "x86_64_general_operand" "")))
7158 (clobber (reg:CC FLAGS_REG))])]
7160 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7162 (define_insn "*subdi3_1"
7163 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7164 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7165 (match_operand:DI 2 "general_operand" "roiF,riF")))
7166 (clobber (reg:CC FLAGS_REG))]
7167 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7171 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7172 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7173 (match_operand:DI 2 "general_operand" "")))
7174 (clobber (reg:CC FLAGS_REG))]
7175 "!TARGET_64BIT && reload_completed"
7176 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7177 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7178 (parallel [(set (match_dup 3)
7179 (minus:SI (match_dup 4)
7180 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7182 (clobber (reg:CC FLAGS_REG))])]
7183 "split_di (operands+0, 1, operands+0, operands+3);
7184 split_di (operands+1, 1, operands+1, operands+4);
7185 split_di (operands+2, 1, operands+2, operands+5);")
7187 (define_insn "subdi3_carry_rex64"
7188 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7189 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7190 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7191 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7192 (clobber (reg:CC FLAGS_REG))]
7193 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7194 "sbb{q}\t{%2, %0|%0, %2}"
7195 [(set_attr "type" "alu")
7196 (set_attr "pent_pair" "pu")
7197 (set_attr "mode" "DI")])
7199 (define_insn "*subdi_1_rex64"
7200 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7201 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7202 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7203 (clobber (reg:CC FLAGS_REG))]
7204 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7205 "sub{q}\t{%2, %0|%0, %2}"
7206 [(set_attr "type" "alu")
7207 (set_attr "mode" "DI")])
7209 (define_insn "*subdi_2_rex64"
7210 [(set (reg FLAGS_REG)
7212 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7213 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7215 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7216 (minus:DI (match_dup 1) (match_dup 2)))]
7217 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7218 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7219 "sub{q}\t{%2, %0|%0, %2}"
7220 [(set_attr "type" "alu")
7221 (set_attr "mode" "DI")])
7223 (define_insn "*subdi_3_rex63"
7224 [(set (reg FLAGS_REG)
7225 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7226 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7227 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7228 (minus:DI (match_dup 1) (match_dup 2)))]
7229 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7230 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7231 "sub{q}\t{%2, %0|%0, %2}"
7232 [(set_attr "type" "alu")
7233 (set_attr "mode" "DI")])
7235 (define_insn "subqi3_carry"
7236 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7237 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7238 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7239 (match_operand:QI 2 "general_operand" "qi,qm"))))
7240 (clobber (reg:CC FLAGS_REG))]
7241 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7242 "sbb{b}\t{%2, %0|%0, %2}"
7243 [(set_attr "type" "alu")
7244 (set_attr "pent_pair" "pu")
7245 (set_attr "mode" "QI")])
7247 (define_insn "subhi3_carry"
7248 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7249 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7250 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7251 (match_operand:HI 2 "general_operand" "ri,rm"))))
7252 (clobber (reg:CC FLAGS_REG))]
7253 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7254 "sbb{w}\t{%2, %0|%0, %2}"
7255 [(set_attr "type" "alu")
7256 (set_attr "pent_pair" "pu")
7257 (set_attr "mode" "HI")])
7259 (define_insn "subsi3_carry"
7260 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7261 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7262 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7263 (match_operand:SI 2 "general_operand" "ri,rm"))))
7264 (clobber (reg:CC FLAGS_REG))]
7265 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7266 "sbb{l}\t{%2, %0|%0, %2}"
7267 [(set_attr "type" "alu")
7268 (set_attr "pent_pair" "pu")
7269 (set_attr "mode" "SI")])
7271 (define_insn "subsi3_carry_zext"
7272 [(set (match_operand:DI 0 "register_operand" "=r")
7274 (minus:SI (match_operand:SI 1 "register_operand" "0")
7275 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7276 (match_operand:SI 2 "general_operand" "g")))))
7277 (clobber (reg:CC FLAGS_REG))]
7278 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7279 "sbb{l}\t{%2, %k0|%k0, %2}"
7280 [(set_attr "type" "alu")
7281 (set_attr "pent_pair" "pu")
7282 (set_attr "mode" "SI")])
7284 (define_expand "subsi3"
7285 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7286 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7287 (match_operand:SI 2 "general_operand" "")))
7288 (clobber (reg:CC FLAGS_REG))])]
7290 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7292 (define_insn "*subsi_1"
7293 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7294 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7295 (match_operand:SI 2 "general_operand" "ri,rm")))
7296 (clobber (reg:CC FLAGS_REG))]
7297 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7298 "sub{l}\t{%2, %0|%0, %2}"
7299 [(set_attr "type" "alu")
7300 (set_attr "mode" "SI")])
7302 (define_insn "*subsi_1_zext"
7303 [(set (match_operand:DI 0 "register_operand" "=r")
7305 (minus:SI (match_operand:SI 1 "register_operand" "0")
7306 (match_operand:SI 2 "general_operand" "g"))))
7307 (clobber (reg:CC FLAGS_REG))]
7308 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7309 "sub{l}\t{%2, %k0|%k0, %2}"
7310 [(set_attr "type" "alu")
7311 (set_attr "mode" "SI")])
7313 (define_insn "*subsi_2"
7314 [(set (reg FLAGS_REG)
7316 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7317 (match_operand:SI 2 "general_operand" "ri,rm"))
7319 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7320 (minus:SI (match_dup 1) (match_dup 2)))]
7321 "ix86_match_ccmode (insn, CCGOCmode)
7322 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7323 "sub{l}\t{%2, %0|%0, %2}"
7324 [(set_attr "type" "alu")
7325 (set_attr "mode" "SI")])
7327 (define_insn "*subsi_2_zext"
7328 [(set (reg FLAGS_REG)
7330 (minus:SI (match_operand:SI 1 "register_operand" "0")
7331 (match_operand:SI 2 "general_operand" "g"))
7333 (set (match_operand:DI 0 "register_operand" "=r")
7335 (minus:SI (match_dup 1)
7337 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7338 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7339 "sub{l}\t{%2, %k0|%k0, %2}"
7340 [(set_attr "type" "alu")
7341 (set_attr "mode" "SI")])
7343 (define_insn "*subsi_3"
7344 [(set (reg FLAGS_REG)
7345 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7346 (match_operand:SI 2 "general_operand" "ri,rm")))
7347 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7348 (minus:SI (match_dup 1) (match_dup 2)))]
7349 "ix86_match_ccmode (insn, CCmode)
7350 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7351 "sub{l}\t{%2, %0|%0, %2}"
7352 [(set_attr "type" "alu")
7353 (set_attr "mode" "SI")])
7355 (define_insn "*subsi_3_zext"
7356 [(set (reg FLAGS_REG)
7357 (compare (match_operand:SI 1 "register_operand" "0")
7358 (match_operand:SI 2 "general_operand" "g")))
7359 (set (match_operand:DI 0 "register_operand" "=r")
7361 (minus:SI (match_dup 1)
7363 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7364 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7365 "sub{l}\t{%2, %1|%1, %2}"
7366 [(set_attr "type" "alu")
7367 (set_attr "mode" "DI")])
7369 (define_expand "subhi3"
7370 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7371 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7372 (match_operand:HI 2 "general_operand" "")))
7373 (clobber (reg:CC FLAGS_REG))])]
7374 "TARGET_HIMODE_MATH"
7375 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7377 (define_insn "*subhi_1"
7378 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7379 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7380 (match_operand:HI 2 "general_operand" "ri,rm")))
7381 (clobber (reg:CC FLAGS_REG))]
7382 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7383 "sub{w}\t{%2, %0|%0, %2}"
7384 [(set_attr "type" "alu")
7385 (set_attr "mode" "HI")])
7387 (define_insn "*subhi_2"
7388 [(set (reg FLAGS_REG)
7390 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7391 (match_operand:HI 2 "general_operand" "ri,rm"))
7393 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7394 (minus:HI (match_dup 1) (match_dup 2)))]
7395 "ix86_match_ccmode (insn, CCGOCmode)
7396 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7397 "sub{w}\t{%2, %0|%0, %2}"
7398 [(set_attr "type" "alu")
7399 (set_attr "mode" "HI")])
7401 (define_insn "*subhi_3"
7402 [(set (reg FLAGS_REG)
7403 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7404 (match_operand:HI 2 "general_operand" "ri,rm")))
7405 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7406 (minus:HI (match_dup 1) (match_dup 2)))]
7407 "ix86_match_ccmode (insn, CCmode)
7408 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7409 "sub{w}\t{%2, %0|%0, %2}"
7410 [(set_attr "type" "alu")
7411 (set_attr "mode" "HI")])
7413 (define_expand "subqi3"
7414 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7415 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7416 (match_operand:QI 2 "general_operand" "")))
7417 (clobber (reg:CC FLAGS_REG))])]
7418 "TARGET_QIMODE_MATH"
7419 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7421 (define_insn "*subqi_1"
7422 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7423 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7424 (match_operand:QI 2 "general_operand" "qn,qmn")))
7425 (clobber (reg:CC FLAGS_REG))]
7426 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7427 "sub{b}\t{%2, %0|%0, %2}"
7428 [(set_attr "type" "alu")
7429 (set_attr "mode" "QI")])
7431 (define_insn "*subqi_1_slp"
7432 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7433 (minus:QI (match_dup 0)
7434 (match_operand:QI 1 "general_operand" "qn,qmn")))
7435 (clobber (reg:CC FLAGS_REG))]
7436 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7438 "sub{b}\t{%1, %0|%0, %1}"
7439 [(set_attr "type" "alu1")
7440 (set_attr "mode" "QI")])
7442 (define_insn "*subqi_2"
7443 [(set (reg FLAGS_REG)
7445 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7446 (match_operand:QI 2 "general_operand" "qi,qm"))
7448 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7449 (minus:HI (match_dup 1) (match_dup 2)))]
7450 "ix86_match_ccmode (insn, CCGOCmode)
7451 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7452 "sub{b}\t{%2, %0|%0, %2}"
7453 [(set_attr "type" "alu")
7454 (set_attr "mode" "QI")])
7456 (define_insn "*subqi_3"
7457 [(set (reg FLAGS_REG)
7458 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7459 (match_operand:QI 2 "general_operand" "qi,qm")))
7460 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7461 (minus:HI (match_dup 1) (match_dup 2)))]
7462 "ix86_match_ccmode (insn, CCmode)
7463 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7464 "sub{b}\t{%2, %0|%0, %2}"
7465 [(set_attr "type" "alu")
7466 (set_attr "mode" "QI")])
7468 ;; The patterns that match these are at the end of this file.
7470 (define_expand "subxf3"
7471 [(set (match_operand:XF 0 "register_operand" "")
7472 (minus:XF (match_operand:XF 1 "register_operand" "")
7473 (match_operand:XF 2 "register_operand" "")))]
7477 (define_expand "sub<mode>3"
7478 [(set (match_operand:MODEF 0 "register_operand" "")
7479 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7480 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7481 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7484 ;; Multiply instructions
7486 (define_expand "muldi3"
7487 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7488 (mult:DI (match_operand:DI 1 "register_operand" "")
7489 (match_operand:DI 2 "x86_64_general_operand" "")))
7490 (clobber (reg:CC FLAGS_REG))])]
7495 ;; IMUL reg64, reg64, imm8 Direct
7496 ;; IMUL reg64, mem64, imm8 VectorPath
7497 ;; IMUL reg64, reg64, imm32 Direct
7498 ;; IMUL reg64, mem64, imm32 VectorPath
7499 ;; IMUL reg64, reg64 Direct
7500 ;; IMUL reg64, mem64 Direct
7502 (define_insn "*muldi3_1_rex64"
7503 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7504 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7505 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7506 (clobber (reg:CC FLAGS_REG))]
7508 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7510 imul{q}\t{%2, %1, %0|%0, %1, %2}
7511 imul{q}\t{%2, %1, %0|%0, %1, %2}
7512 imul{q}\t{%2, %0|%0, %2}"
7513 [(set_attr "type" "imul")
7514 (set_attr "prefix_0f" "0,0,1")
7515 (set (attr "athlon_decode")
7516 (cond [(eq_attr "cpu" "athlon")
7517 (const_string "vector")
7518 (eq_attr "alternative" "1")
7519 (const_string "vector")
7520 (and (eq_attr "alternative" "2")
7521 (match_operand 1 "memory_operand" ""))
7522 (const_string "vector")]
7523 (const_string "direct")))
7524 (set (attr "amdfam10_decode")
7525 (cond [(and (eq_attr "alternative" "0,1")
7526 (match_operand 1 "memory_operand" ""))
7527 (const_string "vector")]
7528 (const_string "direct")))
7529 (set_attr "mode" "DI")])
7531 (define_expand "mulsi3"
7532 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7533 (mult:SI (match_operand:SI 1 "register_operand" "")
7534 (match_operand:SI 2 "general_operand" "")))
7535 (clobber (reg:CC FLAGS_REG))])]
7540 ;; IMUL reg32, reg32, imm8 Direct
7541 ;; IMUL reg32, mem32, imm8 VectorPath
7542 ;; IMUL reg32, reg32, imm32 Direct
7543 ;; IMUL reg32, mem32, imm32 VectorPath
7544 ;; IMUL reg32, reg32 Direct
7545 ;; IMUL reg32, mem32 Direct
7547 (define_insn "*mulsi3_1"
7548 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7549 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7550 (match_operand:SI 2 "general_operand" "K,i,mr")))
7551 (clobber (reg:CC FLAGS_REG))]
7552 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7554 imul{l}\t{%2, %1, %0|%0, %1, %2}
7555 imul{l}\t{%2, %1, %0|%0, %1, %2}
7556 imul{l}\t{%2, %0|%0, %2}"
7557 [(set_attr "type" "imul")
7558 (set_attr "prefix_0f" "0,0,1")
7559 (set (attr "athlon_decode")
7560 (cond [(eq_attr "cpu" "athlon")
7561 (const_string "vector")
7562 (eq_attr "alternative" "1")
7563 (const_string "vector")
7564 (and (eq_attr "alternative" "2")
7565 (match_operand 1 "memory_operand" ""))
7566 (const_string "vector")]
7567 (const_string "direct")))
7568 (set (attr "amdfam10_decode")
7569 (cond [(and (eq_attr "alternative" "0,1")
7570 (match_operand 1 "memory_operand" ""))
7571 (const_string "vector")]
7572 (const_string "direct")))
7573 (set_attr "mode" "SI")])
7575 (define_insn "*mulsi3_1_zext"
7576 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7578 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7579 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7580 (clobber (reg:CC FLAGS_REG))]
7582 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7584 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7585 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7586 imul{l}\t{%2, %k0|%k0, %2}"
7587 [(set_attr "type" "imul")
7588 (set_attr "prefix_0f" "0,0,1")
7589 (set (attr "athlon_decode")
7590 (cond [(eq_attr "cpu" "athlon")
7591 (const_string "vector")
7592 (eq_attr "alternative" "1")
7593 (const_string "vector")
7594 (and (eq_attr "alternative" "2")
7595 (match_operand 1 "memory_operand" ""))
7596 (const_string "vector")]
7597 (const_string "direct")))
7598 (set (attr "amdfam10_decode")
7599 (cond [(and (eq_attr "alternative" "0,1")
7600 (match_operand 1 "memory_operand" ""))
7601 (const_string "vector")]
7602 (const_string "direct")))
7603 (set_attr "mode" "SI")])
7605 (define_expand "mulhi3"
7606 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7607 (mult:HI (match_operand:HI 1 "register_operand" "")
7608 (match_operand:HI 2 "general_operand" "")))
7609 (clobber (reg:CC FLAGS_REG))])]
7610 "TARGET_HIMODE_MATH"
7614 ;; IMUL reg16, reg16, imm8 VectorPath
7615 ;; IMUL reg16, mem16, imm8 VectorPath
7616 ;; IMUL reg16, reg16, imm16 VectorPath
7617 ;; IMUL reg16, mem16, imm16 VectorPath
7618 ;; IMUL reg16, reg16 Direct
7619 ;; IMUL reg16, mem16 Direct
7620 (define_insn "*mulhi3_1"
7621 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7622 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7623 (match_operand:HI 2 "general_operand" "K,i,mr")))
7624 (clobber (reg:CC FLAGS_REG))]
7625 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7627 imul{w}\t{%2, %1, %0|%0, %1, %2}
7628 imul{w}\t{%2, %1, %0|%0, %1, %2}
7629 imul{w}\t{%2, %0|%0, %2}"
7630 [(set_attr "type" "imul")
7631 (set_attr "prefix_0f" "0,0,1")
7632 (set (attr "athlon_decode")
7633 (cond [(eq_attr "cpu" "athlon")
7634 (const_string "vector")
7635 (eq_attr "alternative" "1,2")
7636 (const_string "vector")]
7637 (const_string "direct")))
7638 (set (attr "amdfam10_decode")
7639 (cond [(eq_attr "alternative" "0,1")
7640 (const_string "vector")]
7641 (const_string "direct")))
7642 (set_attr "mode" "HI")])
7644 (define_expand "mulqi3"
7645 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7646 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7647 (match_operand:QI 2 "register_operand" "")))
7648 (clobber (reg:CC FLAGS_REG))])]
7649 "TARGET_QIMODE_MATH"
7656 (define_insn "*mulqi3_1"
7657 [(set (match_operand:QI 0 "register_operand" "=a")
7658 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7659 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7660 (clobber (reg:CC FLAGS_REG))]
7662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7664 [(set_attr "type" "imul")
7665 (set_attr "length_immediate" "0")
7666 (set (attr "athlon_decode")
7667 (if_then_else (eq_attr "cpu" "athlon")
7668 (const_string "vector")
7669 (const_string "direct")))
7670 (set_attr "amdfam10_decode" "direct")
7671 (set_attr "mode" "QI")])
7673 (define_expand "umulqihi3"
7674 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7675 (mult:HI (zero_extend:HI
7676 (match_operand:QI 1 "nonimmediate_operand" ""))
7678 (match_operand:QI 2 "register_operand" ""))))
7679 (clobber (reg:CC FLAGS_REG))])]
7680 "TARGET_QIMODE_MATH"
7683 (define_insn "*umulqihi3_1"
7684 [(set (match_operand:HI 0 "register_operand" "=a")
7685 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7686 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7687 (clobber (reg:CC FLAGS_REG))]
7689 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7691 [(set_attr "type" "imul")
7692 (set_attr "length_immediate" "0")
7693 (set (attr "athlon_decode")
7694 (if_then_else (eq_attr "cpu" "athlon")
7695 (const_string "vector")
7696 (const_string "direct")))
7697 (set_attr "amdfam10_decode" "direct")
7698 (set_attr "mode" "QI")])
7700 (define_expand "mulqihi3"
7701 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7702 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7703 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7704 (clobber (reg:CC FLAGS_REG))])]
7705 "TARGET_QIMODE_MATH"
7708 (define_insn "*mulqihi3_insn"
7709 [(set (match_operand:HI 0 "register_operand" "=a")
7710 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7711 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7712 (clobber (reg:CC FLAGS_REG))]
7714 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7716 [(set_attr "type" "imul")
7717 (set_attr "length_immediate" "0")
7718 (set (attr "athlon_decode")
7719 (if_then_else (eq_attr "cpu" "athlon")
7720 (const_string "vector")
7721 (const_string "direct")))
7722 (set_attr "amdfam10_decode" "direct")
7723 (set_attr "mode" "QI")])
7725 (define_expand "umulditi3"
7726 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7727 (mult:TI (zero_extend:TI
7728 (match_operand:DI 1 "nonimmediate_operand" ""))
7730 (match_operand:DI 2 "register_operand" ""))))
7731 (clobber (reg:CC FLAGS_REG))])]
7735 (define_insn "*umulditi3_insn"
7736 [(set (match_operand:TI 0 "register_operand" "=A")
7737 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7738 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7739 (clobber (reg:CC FLAGS_REG))]
7741 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7743 [(set_attr "type" "imul")
7744 (set_attr "length_immediate" "0")
7745 (set (attr "athlon_decode")
7746 (if_then_else (eq_attr "cpu" "athlon")
7747 (const_string "vector")
7748 (const_string "double")))
7749 (set_attr "amdfam10_decode" "double")
7750 (set_attr "mode" "DI")])
7752 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7753 (define_expand "umulsidi3"
7754 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7755 (mult:DI (zero_extend:DI
7756 (match_operand:SI 1 "nonimmediate_operand" ""))
7758 (match_operand:SI 2 "register_operand" ""))))
7759 (clobber (reg:CC FLAGS_REG))])]
7763 (define_insn "*umulsidi3_insn"
7764 [(set (match_operand:DI 0 "register_operand" "=A")
7765 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7766 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7767 (clobber (reg:CC FLAGS_REG))]
7769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7771 [(set_attr "type" "imul")
7772 (set_attr "length_immediate" "0")
7773 (set (attr "athlon_decode")
7774 (if_then_else (eq_attr "cpu" "athlon")
7775 (const_string "vector")
7776 (const_string "double")))
7777 (set_attr "amdfam10_decode" "double")
7778 (set_attr "mode" "SI")])
7780 (define_expand "mulditi3"
7781 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7782 (mult:TI (sign_extend:TI
7783 (match_operand:DI 1 "nonimmediate_operand" ""))
7785 (match_operand:DI 2 "register_operand" ""))))
7786 (clobber (reg:CC FLAGS_REG))])]
7790 (define_insn "*mulditi3_insn"
7791 [(set (match_operand:TI 0 "register_operand" "=A")
7792 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7793 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7794 (clobber (reg:CC FLAGS_REG))]
7796 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7798 [(set_attr "type" "imul")
7799 (set_attr "length_immediate" "0")
7800 (set (attr "athlon_decode")
7801 (if_then_else (eq_attr "cpu" "athlon")
7802 (const_string "vector")
7803 (const_string "double")))
7804 (set_attr "amdfam10_decode" "double")
7805 (set_attr "mode" "DI")])
7807 (define_expand "mulsidi3"
7808 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7809 (mult:DI (sign_extend:DI
7810 (match_operand:SI 1 "nonimmediate_operand" ""))
7812 (match_operand:SI 2 "register_operand" ""))))
7813 (clobber (reg:CC FLAGS_REG))])]
7817 (define_insn "*mulsidi3_insn"
7818 [(set (match_operand:DI 0 "register_operand" "=A")
7819 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7820 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7821 (clobber (reg:CC FLAGS_REG))]
7823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7825 [(set_attr "type" "imul")
7826 (set_attr "length_immediate" "0")
7827 (set (attr "athlon_decode")
7828 (if_then_else (eq_attr "cpu" "athlon")
7829 (const_string "vector")
7830 (const_string "double")))
7831 (set_attr "amdfam10_decode" "double")
7832 (set_attr "mode" "SI")])
7834 (define_expand "umuldi3_highpart"
7835 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7838 (mult:TI (zero_extend:TI
7839 (match_operand:DI 1 "nonimmediate_operand" ""))
7841 (match_operand:DI 2 "register_operand" "")))
7843 (clobber (match_scratch:DI 3 ""))
7844 (clobber (reg:CC FLAGS_REG))])]
7848 (define_insn "*umuldi3_highpart_rex64"
7849 [(set (match_operand:DI 0 "register_operand" "=d")
7852 (mult:TI (zero_extend:TI
7853 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7855 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7857 (clobber (match_scratch:DI 3 "=1"))
7858 (clobber (reg:CC FLAGS_REG))]
7860 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7862 [(set_attr "type" "imul")
7863 (set_attr "length_immediate" "0")
7864 (set (attr "athlon_decode")
7865 (if_then_else (eq_attr "cpu" "athlon")
7866 (const_string "vector")
7867 (const_string "double")))
7868 (set_attr "amdfam10_decode" "double")
7869 (set_attr "mode" "DI")])
7871 (define_expand "umulsi3_highpart"
7872 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7875 (mult:DI (zero_extend:DI
7876 (match_operand:SI 1 "nonimmediate_operand" ""))
7878 (match_operand:SI 2 "register_operand" "")))
7880 (clobber (match_scratch:SI 3 ""))
7881 (clobber (reg:CC FLAGS_REG))])]
7885 (define_insn "*umulsi3_highpart_insn"
7886 [(set (match_operand:SI 0 "register_operand" "=d")
7889 (mult:DI (zero_extend:DI
7890 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7892 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7894 (clobber (match_scratch:SI 3 "=1"))
7895 (clobber (reg:CC FLAGS_REG))]
7896 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7898 [(set_attr "type" "imul")
7899 (set_attr "length_immediate" "0")
7900 (set (attr "athlon_decode")
7901 (if_then_else (eq_attr "cpu" "athlon")
7902 (const_string "vector")
7903 (const_string "double")))
7904 (set_attr "amdfam10_decode" "double")
7905 (set_attr "mode" "SI")])
7907 (define_insn "*umulsi3_highpart_zext"
7908 [(set (match_operand:DI 0 "register_operand" "=d")
7909 (zero_extend:DI (truncate:SI
7911 (mult:DI (zero_extend:DI
7912 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7914 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7916 (clobber (match_scratch:SI 3 "=1"))
7917 (clobber (reg:CC FLAGS_REG))]
7919 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7921 [(set_attr "type" "imul")
7922 (set_attr "length_immediate" "0")
7923 (set (attr "athlon_decode")
7924 (if_then_else (eq_attr "cpu" "athlon")
7925 (const_string "vector")
7926 (const_string "double")))
7927 (set_attr "amdfam10_decode" "double")
7928 (set_attr "mode" "SI")])
7930 (define_expand "smuldi3_highpart"
7931 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7934 (mult:TI (sign_extend:TI
7935 (match_operand:DI 1 "nonimmediate_operand" ""))
7937 (match_operand:DI 2 "register_operand" "")))
7939 (clobber (match_scratch:DI 3 ""))
7940 (clobber (reg:CC FLAGS_REG))])]
7944 (define_insn "*smuldi3_highpart_rex64"
7945 [(set (match_operand:DI 0 "register_operand" "=d")
7948 (mult:TI (sign_extend:TI
7949 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7951 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7953 (clobber (match_scratch:DI 3 "=1"))
7954 (clobber (reg:CC FLAGS_REG))]
7956 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7958 [(set_attr "type" "imul")
7959 (set (attr "athlon_decode")
7960 (if_then_else (eq_attr "cpu" "athlon")
7961 (const_string "vector")
7962 (const_string "double")))
7963 (set_attr "amdfam10_decode" "double")
7964 (set_attr "mode" "DI")])
7966 (define_expand "smulsi3_highpart"
7967 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7970 (mult:DI (sign_extend:DI
7971 (match_operand:SI 1 "nonimmediate_operand" ""))
7973 (match_operand:SI 2 "register_operand" "")))
7975 (clobber (match_scratch:SI 3 ""))
7976 (clobber (reg:CC FLAGS_REG))])]
7980 (define_insn "*smulsi3_highpart_insn"
7981 [(set (match_operand:SI 0 "register_operand" "=d")
7984 (mult:DI (sign_extend:DI
7985 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7987 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7989 (clobber (match_scratch:SI 3 "=1"))
7990 (clobber (reg:CC FLAGS_REG))]
7991 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7993 [(set_attr "type" "imul")
7994 (set (attr "athlon_decode")
7995 (if_then_else (eq_attr "cpu" "athlon")
7996 (const_string "vector")
7997 (const_string "double")))
7998 (set_attr "amdfam10_decode" "double")
7999 (set_attr "mode" "SI")])
8001 (define_insn "*smulsi3_highpart_zext"
8002 [(set (match_operand:DI 0 "register_operand" "=d")
8003 (zero_extend:DI (truncate:SI
8005 (mult:DI (sign_extend:DI
8006 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8008 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8010 (clobber (match_scratch:SI 3 "=1"))
8011 (clobber (reg:CC FLAGS_REG))]
8013 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8015 [(set_attr "type" "imul")
8016 (set (attr "athlon_decode")
8017 (if_then_else (eq_attr "cpu" "athlon")
8018 (const_string "vector")
8019 (const_string "double")))
8020 (set_attr "amdfam10_decode" "double")
8021 (set_attr "mode" "SI")])
8023 ;; The patterns that match these are at the end of this file.
8025 (define_expand "mulxf3"
8026 [(set (match_operand:XF 0 "register_operand" "")
8027 (mult:XF (match_operand:XF 1 "register_operand" "")
8028 (match_operand:XF 2 "register_operand" "")))]
8032 (define_expand "mul<mode>3"
8033 [(set (match_operand:MODEF 0 "register_operand" "")
8034 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8035 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8036 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8039 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8042 ;; Divide instructions
8044 (define_insn "divqi3"
8045 [(set (match_operand:QI 0 "register_operand" "=a")
8046 (div:QI (match_operand:HI 1 "register_operand" "0")
8047 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8048 (clobber (reg:CC FLAGS_REG))]
8049 "TARGET_QIMODE_MATH"
8051 [(set_attr "type" "idiv")
8052 (set_attr "mode" "QI")])
8054 (define_insn "udivqi3"
8055 [(set (match_operand:QI 0 "register_operand" "=a")
8056 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8057 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8058 (clobber (reg:CC FLAGS_REG))]
8059 "TARGET_QIMODE_MATH"
8061 [(set_attr "type" "idiv")
8062 (set_attr "mode" "QI")])
8064 ;; The patterns that match these are at the end of this file.
8066 (define_expand "divxf3"
8067 [(set (match_operand:XF 0 "register_operand" "")
8068 (div:XF (match_operand:XF 1 "register_operand" "")
8069 (match_operand:XF 2 "register_operand" "")))]
8073 (define_expand "divdf3"
8074 [(set (match_operand:DF 0 "register_operand" "")
8075 (div:DF (match_operand:DF 1 "register_operand" "")
8076 (match_operand:DF 2 "nonimmediate_operand" "")))]
8077 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8080 (define_expand "divsf3"
8081 [(set (match_operand:SF 0 "register_operand" "")
8082 (div:SF (match_operand:SF 1 "register_operand" "")
8083 (match_operand:SF 2 "nonimmediate_operand" "")))]
8084 "TARGET_80387 || TARGET_SSE_MATH"
8086 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8087 && flag_finite_math_only && !flag_trapping_math
8088 && flag_unsafe_math_optimizations)
8090 ix86_emit_swdivsf (operands[0], operands[1],
8091 operands[2], SFmode);
8096 ;; Remainder instructions.
8098 (define_expand "divmoddi4"
8099 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8100 (div:DI (match_operand:DI 1 "register_operand" "")
8101 (match_operand:DI 2 "nonimmediate_operand" "")))
8102 (set (match_operand:DI 3 "register_operand" "")
8103 (mod:DI (match_dup 1) (match_dup 2)))
8104 (clobber (reg:CC FLAGS_REG))])]
8108 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8109 ;; Penalize eax case slightly because it results in worse scheduling
8111 (define_insn "*divmoddi4_nocltd_rex64"
8112 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8113 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8114 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8115 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8116 (mod:DI (match_dup 2) (match_dup 3)))
8117 (clobber (reg:CC FLAGS_REG))]
8118 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8120 [(set_attr "type" "multi")])
8122 (define_insn "*divmoddi4_cltd_rex64"
8123 [(set (match_operand:DI 0 "register_operand" "=a")
8124 (div:DI (match_operand:DI 2 "register_operand" "a")
8125 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8126 (set (match_operand:DI 1 "register_operand" "=&d")
8127 (mod:DI (match_dup 2) (match_dup 3)))
8128 (clobber (reg:CC FLAGS_REG))]
8129 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8131 [(set_attr "type" "multi")])
8133 (define_insn "*divmoddi_noext_rex64"
8134 [(set (match_operand:DI 0 "register_operand" "=a")
8135 (div:DI (match_operand:DI 1 "register_operand" "0")
8136 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8137 (set (match_operand:DI 3 "register_operand" "=d")
8138 (mod:DI (match_dup 1) (match_dup 2)))
8139 (use (match_operand:DI 4 "register_operand" "3"))
8140 (clobber (reg:CC FLAGS_REG))]
8143 [(set_attr "type" "idiv")
8144 (set_attr "mode" "DI")])
8147 [(set (match_operand:DI 0 "register_operand" "")
8148 (div:DI (match_operand:DI 1 "register_operand" "")
8149 (match_operand:DI 2 "nonimmediate_operand" "")))
8150 (set (match_operand:DI 3 "register_operand" "")
8151 (mod:DI (match_dup 1) (match_dup 2)))
8152 (clobber (reg:CC FLAGS_REG))]
8153 "TARGET_64BIT && reload_completed"
8154 [(parallel [(set (match_dup 3)
8155 (ashiftrt:DI (match_dup 4) (const_int 63)))
8156 (clobber (reg:CC FLAGS_REG))])
8157 (parallel [(set (match_dup 0)
8158 (div:DI (reg:DI 0) (match_dup 2)))
8160 (mod:DI (reg:DI 0) (match_dup 2)))
8162 (clobber (reg:CC FLAGS_REG))])]
8164 /* Avoid use of cltd in favor of a mov+shift. */
8165 if (!TARGET_USE_CLTD && !optimize_size)
8167 if (true_regnum (operands[1]))
8168 emit_move_insn (operands[0], operands[1]);
8170 emit_move_insn (operands[3], operands[1]);
8171 operands[4] = operands[3];
8175 gcc_assert (!true_regnum (operands[1]));
8176 operands[4] = operands[1];
8181 (define_expand "divmodsi4"
8182 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8183 (div:SI (match_operand:SI 1 "register_operand" "")
8184 (match_operand:SI 2 "nonimmediate_operand" "")))
8185 (set (match_operand:SI 3 "register_operand" "")
8186 (mod:SI (match_dup 1) (match_dup 2)))
8187 (clobber (reg:CC FLAGS_REG))])]
8191 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8192 ;; Penalize eax case slightly because it results in worse scheduling
8194 (define_insn "*divmodsi4_nocltd"
8195 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8196 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8197 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8198 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8199 (mod:SI (match_dup 2) (match_dup 3)))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "!optimize_size && !TARGET_USE_CLTD"
8203 [(set_attr "type" "multi")])
8205 (define_insn "*divmodsi4_cltd"
8206 [(set (match_operand:SI 0 "register_operand" "=a")
8207 (div:SI (match_operand:SI 2 "register_operand" "a")
8208 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8209 (set (match_operand:SI 1 "register_operand" "=&d")
8210 (mod:SI (match_dup 2) (match_dup 3)))
8211 (clobber (reg:CC FLAGS_REG))]
8212 "optimize_size || TARGET_USE_CLTD"
8214 [(set_attr "type" "multi")])
8216 (define_insn "*divmodsi_noext"
8217 [(set (match_operand:SI 0 "register_operand" "=a")
8218 (div:SI (match_operand:SI 1 "register_operand" "0")
8219 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8220 (set (match_operand:SI 3 "register_operand" "=d")
8221 (mod:SI (match_dup 1) (match_dup 2)))
8222 (use (match_operand:SI 4 "register_operand" "3"))
8223 (clobber (reg:CC FLAGS_REG))]
8226 [(set_attr "type" "idiv")
8227 (set_attr "mode" "SI")])
8230 [(set (match_operand:SI 0 "register_operand" "")
8231 (div:SI (match_operand:SI 1 "register_operand" "")
8232 (match_operand:SI 2 "nonimmediate_operand" "")))
8233 (set (match_operand:SI 3 "register_operand" "")
8234 (mod:SI (match_dup 1) (match_dup 2)))
8235 (clobber (reg:CC FLAGS_REG))]
8237 [(parallel [(set (match_dup 3)
8238 (ashiftrt:SI (match_dup 4) (const_int 31)))
8239 (clobber (reg:CC FLAGS_REG))])
8240 (parallel [(set (match_dup 0)
8241 (div:SI (reg:SI 0) (match_dup 2)))
8243 (mod:SI (reg:SI 0) (match_dup 2)))
8245 (clobber (reg:CC FLAGS_REG))])]
8247 /* Avoid use of cltd in favor of a mov+shift. */
8248 if (!TARGET_USE_CLTD && !optimize_size)
8250 if (true_regnum (operands[1]))
8251 emit_move_insn (operands[0], operands[1]);
8253 emit_move_insn (operands[3], operands[1]);
8254 operands[4] = operands[3];
8258 gcc_assert (!true_regnum (operands[1]));
8259 operands[4] = operands[1];
8263 (define_insn "divmodhi4"
8264 [(set (match_operand:HI 0 "register_operand" "=a")
8265 (div:HI (match_operand:HI 1 "register_operand" "0")
8266 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8267 (set (match_operand:HI 3 "register_operand" "=&d")
8268 (mod:HI (match_dup 1) (match_dup 2)))
8269 (clobber (reg:CC FLAGS_REG))]
8270 "TARGET_HIMODE_MATH"
8272 [(set_attr "type" "multi")
8273 (set_attr "length_immediate" "0")
8274 (set_attr "mode" "SI")])
8276 (define_insn "udivmoddi4"
8277 [(set (match_operand:DI 0 "register_operand" "=a")
8278 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8279 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8280 (set (match_operand:DI 3 "register_operand" "=&d")
8281 (umod:DI (match_dup 1) (match_dup 2)))
8282 (clobber (reg:CC FLAGS_REG))]
8284 "xor{q}\t%3, %3\;div{q}\t%2"
8285 [(set_attr "type" "multi")
8286 (set_attr "length_immediate" "0")
8287 (set_attr "mode" "DI")])
8289 (define_insn "*udivmoddi4_noext"
8290 [(set (match_operand:DI 0 "register_operand" "=a")
8291 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8292 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8293 (set (match_operand:DI 3 "register_operand" "=d")
8294 (umod:DI (match_dup 1) (match_dup 2)))
8296 (clobber (reg:CC FLAGS_REG))]
8299 [(set_attr "type" "idiv")
8300 (set_attr "mode" "DI")])
8303 [(set (match_operand:DI 0 "register_operand" "")
8304 (udiv:DI (match_operand:DI 1 "register_operand" "")
8305 (match_operand:DI 2 "nonimmediate_operand" "")))
8306 (set (match_operand:DI 3 "register_operand" "")
8307 (umod:DI (match_dup 1) (match_dup 2)))
8308 (clobber (reg:CC FLAGS_REG))]
8309 "TARGET_64BIT && reload_completed"
8310 [(set (match_dup 3) (const_int 0))
8311 (parallel [(set (match_dup 0)
8312 (udiv:DI (match_dup 1) (match_dup 2)))
8314 (umod:DI (match_dup 1) (match_dup 2)))
8316 (clobber (reg:CC FLAGS_REG))])]
8319 (define_insn "udivmodsi4"
8320 [(set (match_operand:SI 0 "register_operand" "=a")
8321 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8322 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8323 (set (match_operand:SI 3 "register_operand" "=&d")
8324 (umod:SI (match_dup 1) (match_dup 2)))
8325 (clobber (reg:CC FLAGS_REG))]
8327 "xor{l}\t%3, %3\;div{l}\t%2"
8328 [(set_attr "type" "multi")
8329 (set_attr "length_immediate" "0")
8330 (set_attr "mode" "SI")])
8332 (define_insn "*udivmodsi4_noext"
8333 [(set (match_operand:SI 0 "register_operand" "=a")
8334 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8335 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8336 (set (match_operand:SI 3 "register_operand" "=d")
8337 (umod:SI (match_dup 1) (match_dup 2)))
8339 (clobber (reg:CC FLAGS_REG))]
8342 [(set_attr "type" "idiv")
8343 (set_attr "mode" "SI")])
8346 [(set (match_operand:SI 0 "register_operand" "")
8347 (udiv:SI (match_operand:SI 1 "register_operand" "")
8348 (match_operand:SI 2 "nonimmediate_operand" "")))
8349 (set (match_operand:SI 3 "register_operand" "")
8350 (umod:SI (match_dup 1) (match_dup 2)))
8351 (clobber (reg:CC FLAGS_REG))]
8353 [(set (match_dup 3) (const_int 0))
8354 (parallel [(set (match_dup 0)
8355 (udiv:SI (match_dup 1) (match_dup 2)))
8357 (umod:SI (match_dup 1) (match_dup 2)))
8359 (clobber (reg:CC FLAGS_REG))])]
8362 (define_expand "udivmodhi4"
8363 [(set (match_dup 4) (const_int 0))
8364 (parallel [(set (match_operand:HI 0 "register_operand" "")
8365 (udiv:HI (match_operand:HI 1 "register_operand" "")
8366 (match_operand:HI 2 "nonimmediate_operand" "")))
8367 (set (match_operand:HI 3 "register_operand" "")
8368 (umod:HI (match_dup 1) (match_dup 2)))
8370 (clobber (reg:CC FLAGS_REG))])]
8371 "TARGET_HIMODE_MATH"
8372 "operands[4] = gen_reg_rtx (HImode);")
8374 (define_insn "*udivmodhi_noext"
8375 [(set (match_operand:HI 0 "register_operand" "=a")
8376 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8377 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8378 (set (match_operand:HI 3 "register_operand" "=d")
8379 (umod:HI (match_dup 1) (match_dup 2)))
8380 (use (match_operand:HI 4 "register_operand" "3"))
8381 (clobber (reg:CC FLAGS_REG))]
8384 [(set_attr "type" "idiv")
8385 (set_attr "mode" "HI")])
8387 ;; We cannot use div/idiv for double division, because it causes
8388 ;; "division by zero" on the overflow and that's not what we expect
8389 ;; from truncate. Because true (non truncating) double division is
8390 ;; never generated, we can't create this insn anyway.
8393 ; [(set (match_operand:SI 0 "register_operand" "=a")
8395 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8397 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8398 ; (set (match_operand:SI 3 "register_operand" "=d")
8400 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8401 ; (clobber (reg:CC FLAGS_REG))]
8403 ; "div{l}\t{%2, %0|%0, %2}"
8404 ; [(set_attr "type" "idiv")])
8406 ;;- Logical AND instructions
8408 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8409 ;; Note that this excludes ah.
8411 (define_insn "*testdi_1_rex64"
8412 [(set (reg FLAGS_REG)
8414 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8415 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8417 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8418 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8420 test{l}\t{%k1, %k0|%k0, %k1}
8421 test{l}\t{%k1, %k0|%k0, %k1}
8422 test{q}\t{%1, %0|%0, %1}
8423 test{q}\t{%1, %0|%0, %1}
8424 test{q}\t{%1, %0|%0, %1}"
8425 [(set_attr "type" "test")
8426 (set_attr "modrm" "0,1,0,1,1")
8427 (set_attr "mode" "SI,SI,DI,DI,DI")
8428 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8430 (define_insn "testsi_1"
8431 [(set (reg FLAGS_REG)
8433 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8434 (match_operand:SI 1 "general_operand" "in,in,rin"))
8436 "ix86_match_ccmode (insn, CCNOmode)
8437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8438 "test{l}\t{%1, %0|%0, %1}"
8439 [(set_attr "type" "test")
8440 (set_attr "modrm" "0,1,1")
8441 (set_attr "mode" "SI")
8442 (set_attr "pent_pair" "uv,np,uv")])
8444 (define_expand "testsi_ccno_1"
8445 [(set (reg:CCNO FLAGS_REG)
8447 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8448 (match_operand:SI 1 "nonmemory_operand" ""))
8453 (define_insn "*testhi_1"
8454 [(set (reg FLAGS_REG)
8455 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8456 (match_operand:HI 1 "general_operand" "n,n,rn"))
8458 "ix86_match_ccmode (insn, CCNOmode)
8459 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8460 "test{w}\t{%1, %0|%0, %1}"
8461 [(set_attr "type" "test")
8462 (set_attr "modrm" "0,1,1")
8463 (set_attr "mode" "HI")
8464 (set_attr "pent_pair" "uv,np,uv")])
8466 (define_expand "testqi_ccz_1"
8467 [(set (reg:CCZ FLAGS_REG)
8468 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8469 (match_operand:QI 1 "nonmemory_operand" ""))
8474 (define_insn "*testqi_1_maybe_si"
8475 [(set (reg FLAGS_REG)
8478 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8479 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8481 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8482 && ix86_match_ccmode (insn,
8483 CONST_INT_P (operands[1])
8484 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8486 if (which_alternative == 3)
8488 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8489 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8490 return "test{l}\t{%1, %k0|%k0, %1}";
8492 return "test{b}\t{%1, %0|%0, %1}";
8494 [(set_attr "type" "test")
8495 (set_attr "modrm" "0,1,1,1")
8496 (set_attr "mode" "QI,QI,QI,SI")
8497 (set_attr "pent_pair" "uv,np,uv,np")])
8499 (define_insn "*testqi_1"
8500 [(set (reg FLAGS_REG)
8503 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8504 (match_operand:QI 1 "general_operand" "n,n,qn"))
8506 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8507 && ix86_match_ccmode (insn, CCNOmode)"
8508 "test{b}\t{%1, %0|%0, %1}"
8509 [(set_attr "type" "test")
8510 (set_attr "modrm" "0,1,1")
8511 (set_attr "mode" "QI")
8512 (set_attr "pent_pair" "uv,np,uv")])
8514 (define_expand "testqi_ext_ccno_0"
8515 [(set (reg:CCNO FLAGS_REG)
8519 (match_operand 0 "ext_register_operand" "")
8522 (match_operand 1 "const_int_operand" ""))
8527 (define_insn "*testqi_ext_0"
8528 [(set (reg FLAGS_REG)
8532 (match_operand 0 "ext_register_operand" "Q")
8535 (match_operand 1 "const_int_operand" "n"))
8537 "ix86_match_ccmode (insn, CCNOmode)"
8538 "test{b}\t{%1, %h0|%h0, %1}"
8539 [(set_attr "type" "test")
8540 (set_attr "mode" "QI")
8541 (set_attr "length_immediate" "1")
8542 (set_attr "pent_pair" "np")])
8544 (define_insn "*testqi_ext_1"
8545 [(set (reg FLAGS_REG)
8549 (match_operand 0 "ext_register_operand" "Q")
8553 (match_operand:QI 1 "general_operand" "Qm")))
8555 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8556 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8557 "test{b}\t{%1, %h0|%h0, %1}"
8558 [(set_attr "type" "test")
8559 (set_attr "mode" "QI")])
8561 (define_insn "*testqi_ext_1_rex64"
8562 [(set (reg FLAGS_REG)
8566 (match_operand 0 "ext_register_operand" "Q")
8570 (match_operand:QI 1 "register_operand" "Q")))
8572 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8573 "test{b}\t{%1, %h0|%h0, %1}"
8574 [(set_attr "type" "test")
8575 (set_attr "mode" "QI")])
8577 (define_insn "*testqi_ext_2"
8578 [(set (reg FLAGS_REG)
8582 (match_operand 0 "ext_register_operand" "Q")
8586 (match_operand 1 "ext_register_operand" "Q")
8590 "ix86_match_ccmode (insn, CCNOmode)"
8591 "test{b}\t{%h1, %h0|%h0, %h1}"
8592 [(set_attr "type" "test")
8593 (set_attr "mode" "QI")])
8595 ;; Combine likes to form bit extractions for some tests. Humor it.
8596 (define_insn "*testqi_ext_3"
8597 [(set (reg FLAGS_REG)
8598 (compare (zero_extract:SI
8599 (match_operand 0 "nonimmediate_operand" "rm")
8600 (match_operand:SI 1 "const_int_operand" "")
8601 (match_operand:SI 2 "const_int_operand" ""))
8603 "ix86_match_ccmode (insn, CCNOmode)
8604 && INTVAL (operands[1]) > 0
8605 && INTVAL (operands[2]) >= 0
8606 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8607 && (GET_MODE (operands[0]) == SImode
8608 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8609 || GET_MODE (operands[0]) == HImode
8610 || GET_MODE (operands[0]) == QImode)"
8613 (define_insn "*testqi_ext_3_rex64"
8614 [(set (reg FLAGS_REG)
8615 (compare (zero_extract:DI
8616 (match_operand 0 "nonimmediate_operand" "rm")
8617 (match_operand:DI 1 "const_int_operand" "")
8618 (match_operand:DI 2 "const_int_operand" ""))
8621 && ix86_match_ccmode (insn, CCNOmode)
8622 && INTVAL (operands[1]) > 0
8623 && INTVAL (operands[2]) >= 0
8624 /* Ensure that resulting mask is zero or sign extended operand. */
8625 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8626 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8627 && INTVAL (operands[1]) > 32))
8628 && (GET_MODE (operands[0]) == SImode
8629 || GET_MODE (operands[0]) == DImode
8630 || GET_MODE (operands[0]) == HImode
8631 || GET_MODE (operands[0]) == QImode)"
8635 [(set (match_operand 0 "flags_reg_operand" "")
8636 (match_operator 1 "compare_operator"
8638 (match_operand 2 "nonimmediate_operand" "")
8639 (match_operand 3 "const_int_operand" "")
8640 (match_operand 4 "const_int_operand" ""))
8642 "ix86_match_ccmode (insn, CCNOmode)"
8643 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8645 rtx val = operands[2];
8646 HOST_WIDE_INT len = INTVAL (operands[3]);
8647 HOST_WIDE_INT pos = INTVAL (operands[4]);
8649 enum machine_mode mode, submode;
8651 mode = GET_MODE (val);
8654 /* ??? Combine likes to put non-volatile mem extractions in QImode
8655 no matter the size of the test. So find a mode that works. */
8656 if (! MEM_VOLATILE_P (val))
8658 mode = smallest_mode_for_size (pos + len, MODE_INT);
8659 val = adjust_address (val, mode, 0);
8662 else if (GET_CODE (val) == SUBREG
8663 && (submode = GET_MODE (SUBREG_REG (val)),
8664 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8665 && pos + len <= GET_MODE_BITSIZE (submode))
8667 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8669 val = SUBREG_REG (val);
8671 else if (mode == HImode && pos + len <= 8)
8673 /* Small HImode tests can be converted to QImode. */
8675 val = gen_lowpart (QImode, val);
8678 if (len == HOST_BITS_PER_WIDE_INT)
8681 mask = ((HOST_WIDE_INT)1 << len) - 1;
8684 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8687 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8688 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8689 ;; this is relatively important trick.
8690 ;; Do the conversion only post-reload to avoid limiting of the register class
8693 [(set (match_operand 0 "flags_reg_operand" "")
8694 (match_operator 1 "compare_operator"
8695 [(and (match_operand 2 "register_operand" "")
8696 (match_operand 3 "const_int_operand" ""))
8699 && QI_REG_P (operands[2])
8700 && GET_MODE (operands[2]) != QImode
8701 && ((ix86_match_ccmode (insn, CCZmode)
8702 && !(INTVAL (operands[3]) & ~(255 << 8)))
8703 || (ix86_match_ccmode (insn, CCNOmode)
8704 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8707 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8710 "operands[2] = gen_lowpart (SImode, operands[2]);
8711 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8714 [(set (match_operand 0 "flags_reg_operand" "")
8715 (match_operator 1 "compare_operator"
8716 [(and (match_operand 2 "nonimmediate_operand" "")
8717 (match_operand 3 "const_int_operand" ""))
8720 && GET_MODE (operands[2]) != QImode
8721 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8722 && ((ix86_match_ccmode (insn, CCZmode)
8723 && !(INTVAL (operands[3]) & ~255))
8724 || (ix86_match_ccmode (insn, CCNOmode)
8725 && !(INTVAL (operands[3]) & ~127)))"
8727 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8729 "operands[2] = gen_lowpart (QImode, operands[2]);
8730 operands[3] = gen_lowpart (QImode, operands[3]);")
8733 ;; %%% This used to optimize known byte-wide and operations to memory,
8734 ;; and sometimes to QImode registers. If this is considered useful,
8735 ;; it should be done with splitters.
8737 (define_expand "anddi3"
8738 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8739 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8740 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8741 (clobber (reg:CC FLAGS_REG))]
8743 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8745 (define_insn "*anddi_1_rex64"
8746 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8747 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8748 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8749 (clobber (reg:CC FLAGS_REG))]
8750 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8752 switch (get_attr_type (insn))
8756 enum machine_mode mode;
8758 gcc_assert (CONST_INT_P (operands[2]));
8759 if (INTVAL (operands[2]) == 0xff)
8763 gcc_assert (INTVAL (operands[2]) == 0xffff);
8767 operands[1] = gen_lowpart (mode, operands[1]);
8769 return "movz{bq|x}\t{%1,%0|%0, %1}";
8771 return "movz{wq|x}\t{%1,%0|%0, %1}";
8775 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8776 if (get_attr_mode (insn) == MODE_SI)
8777 return "and{l}\t{%k2, %k0|%k0, %k2}";
8779 return "and{q}\t{%2, %0|%0, %2}";
8782 [(set_attr "type" "alu,alu,alu,imovx")
8783 (set_attr "length_immediate" "*,*,*,0")
8784 (set_attr "mode" "SI,DI,DI,DI")])
8786 (define_insn "*anddi_2"
8787 [(set (reg FLAGS_REG)
8788 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8789 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8791 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8792 (and:DI (match_dup 1) (match_dup 2)))]
8793 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8794 && ix86_binary_operator_ok (AND, DImode, operands)"
8796 and{l}\t{%k2, %k0|%k0, %k2}
8797 and{q}\t{%2, %0|%0, %2}
8798 and{q}\t{%2, %0|%0, %2}"
8799 [(set_attr "type" "alu")
8800 (set_attr "mode" "SI,DI,DI")])
8802 (define_expand "andsi3"
8803 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8804 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8805 (match_operand:SI 2 "general_operand" "")))
8806 (clobber (reg:CC FLAGS_REG))]
8808 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8810 (define_insn "*andsi_1"
8811 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8812 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8813 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8814 (clobber (reg:CC FLAGS_REG))]
8815 "ix86_binary_operator_ok (AND, SImode, operands)"
8817 switch (get_attr_type (insn))
8821 enum machine_mode mode;
8823 gcc_assert (CONST_INT_P (operands[2]));
8824 if (INTVAL (operands[2]) == 0xff)
8828 gcc_assert (INTVAL (operands[2]) == 0xffff);
8832 operands[1] = gen_lowpart (mode, operands[1]);
8834 return "movz{bl|x}\t{%1,%0|%0, %1}";
8836 return "movz{wl|x}\t{%1,%0|%0, %1}";
8840 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8841 return "and{l}\t{%2, %0|%0, %2}";
8844 [(set_attr "type" "alu,alu,imovx")
8845 (set_attr "length_immediate" "*,*,0")
8846 (set_attr "mode" "SI")])
8849 [(set (match_operand 0 "register_operand" "")
8851 (const_int -65536)))
8852 (clobber (reg:CC FLAGS_REG))]
8853 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8854 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8855 "operands[1] = gen_lowpart (HImode, operands[0]);")
8858 [(set (match_operand 0 "ext_register_operand" "")
8861 (clobber (reg:CC FLAGS_REG))]
8862 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8863 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8864 "operands[1] = gen_lowpart (QImode, operands[0]);")
8867 [(set (match_operand 0 "ext_register_operand" "")
8869 (const_int -65281)))
8870 (clobber (reg:CC FLAGS_REG))]
8871 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8872 [(parallel [(set (zero_extract:SI (match_dup 0)
8876 (zero_extract:SI (match_dup 0)
8879 (zero_extract:SI (match_dup 0)
8882 (clobber (reg:CC FLAGS_REG))])]
8883 "operands[0] = gen_lowpart (SImode, operands[0]);")
8885 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8886 (define_insn "*andsi_1_zext"
8887 [(set (match_operand:DI 0 "register_operand" "=r")
8889 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8890 (match_operand:SI 2 "general_operand" "g"))))
8891 (clobber (reg:CC FLAGS_REG))]
8892 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8893 "and{l}\t{%2, %k0|%k0, %2}"
8894 [(set_attr "type" "alu")
8895 (set_attr "mode" "SI")])
8897 (define_insn "*andsi_2"
8898 [(set (reg FLAGS_REG)
8899 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8900 (match_operand:SI 2 "general_operand" "g,ri"))
8902 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8903 (and:SI (match_dup 1) (match_dup 2)))]
8904 "ix86_match_ccmode (insn, CCNOmode)
8905 && ix86_binary_operator_ok (AND, SImode, operands)"
8906 "and{l}\t{%2, %0|%0, %2}"
8907 [(set_attr "type" "alu")
8908 (set_attr "mode" "SI")])
8910 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8911 (define_insn "*andsi_2_zext"
8912 [(set (reg FLAGS_REG)
8913 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8914 (match_operand:SI 2 "general_operand" "g"))
8916 (set (match_operand:DI 0 "register_operand" "=r")
8917 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8918 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8919 && ix86_binary_operator_ok (AND, SImode, operands)"
8920 "and{l}\t{%2, %k0|%k0, %2}"
8921 [(set_attr "type" "alu")
8922 (set_attr "mode" "SI")])
8924 (define_expand "andhi3"
8925 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8926 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8927 (match_operand:HI 2 "general_operand" "")))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "TARGET_HIMODE_MATH"
8930 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8932 (define_insn "*andhi_1"
8933 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8934 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8935 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8936 (clobber (reg:CC FLAGS_REG))]
8937 "ix86_binary_operator_ok (AND, HImode, operands)"
8939 switch (get_attr_type (insn))
8942 gcc_assert (CONST_INT_P (operands[2]));
8943 gcc_assert (INTVAL (operands[2]) == 0xff);
8944 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8947 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8949 return "and{w}\t{%2, %0|%0, %2}";
8952 [(set_attr "type" "alu,alu,imovx")
8953 (set_attr "length_immediate" "*,*,0")
8954 (set_attr "mode" "HI,HI,SI")])
8956 (define_insn "*andhi_2"
8957 [(set (reg FLAGS_REG)
8958 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8959 (match_operand:HI 2 "general_operand" "g,ri"))
8961 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8962 (and:HI (match_dup 1) (match_dup 2)))]
8963 "ix86_match_ccmode (insn, CCNOmode)
8964 && ix86_binary_operator_ok (AND, HImode, operands)"
8965 "and{w}\t{%2, %0|%0, %2}"
8966 [(set_attr "type" "alu")
8967 (set_attr "mode" "HI")])
8969 (define_expand "andqi3"
8970 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8971 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8972 (match_operand:QI 2 "general_operand" "")))
8973 (clobber (reg:CC FLAGS_REG))]
8974 "TARGET_QIMODE_MATH"
8975 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8977 ;; %%% Potential partial reg stall on alternative 2. What to do?
8978 (define_insn "*andqi_1"
8979 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8980 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8981 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8982 (clobber (reg:CC FLAGS_REG))]
8983 "ix86_binary_operator_ok (AND, QImode, operands)"
8985 and{b}\t{%2, %0|%0, %2}
8986 and{b}\t{%2, %0|%0, %2}
8987 and{l}\t{%k2, %k0|%k0, %k2}"
8988 [(set_attr "type" "alu")
8989 (set_attr "mode" "QI,QI,SI")])
8991 (define_insn "*andqi_1_slp"
8992 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8993 (and:QI (match_dup 0)
8994 (match_operand:QI 1 "general_operand" "qi,qmi")))
8995 (clobber (reg:CC FLAGS_REG))]
8996 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8997 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8998 "and{b}\t{%1, %0|%0, %1}"
8999 [(set_attr "type" "alu1")
9000 (set_attr "mode" "QI")])
9002 (define_insn "*andqi_2_maybe_si"
9003 [(set (reg FLAGS_REG)
9005 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9006 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9008 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9009 (and:QI (match_dup 1) (match_dup 2)))]
9010 "ix86_binary_operator_ok (AND, QImode, operands)
9011 && ix86_match_ccmode (insn,
9012 CONST_INT_P (operands[2])
9013 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9015 if (which_alternative == 2)
9017 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9018 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9019 return "and{l}\t{%2, %k0|%k0, %2}";
9021 return "and{b}\t{%2, %0|%0, %2}";
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "QI,QI,SI")])
9026 (define_insn "*andqi_2"
9027 [(set (reg FLAGS_REG)
9029 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9030 (match_operand:QI 2 "general_operand" "qim,qi"))
9032 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9033 (and:QI (match_dup 1) (match_dup 2)))]
9034 "ix86_match_ccmode (insn, CCNOmode)
9035 && ix86_binary_operator_ok (AND, QImode, operands)"
9036 "and{b}\t{%2, %0|%0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "QI")])
9040 (define_insn "*andqi_2_slp"
9041 [(set (reg FLAGS_REG)
9043 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9044 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9046 (set (strict_low_part (match_dup 0))
9047 (and:QI (match_dup 0) (match_dup 1)))]
9048 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9049 && ix86_match_ccmode (insn, CCNOmode)
9050 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9051 "and{b}\t{%1, %0|%0, %1}"
9052 [(set_attr "type" "alu1")
9053 (set_attr "mode" "QI")])
9055 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9056 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9057 ;; for a QImode operand, which of course failed.
9059 (define_insn "andqi_ext_0"
9060 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9065 (match_operand 1 "ext_register_operand" "0")
9068 (match_operand 2 "const_int_operand" "n")))
9069 (clobber (reg:CC FLAGS_REG))]
9071 "and{b}\t{%2, %h0|%h0, %2}"
9072 [(set_attr "type" "alu")
9073 (set_attr "length_immediate" "1")
9074 (set_attr "mode" "QI")])
9076 ;; Generated by peephole translating test to and. This shows up
9077 ;; often in fp comparisons.
9079 (define_insn "*andqi_ext_0_cc"
9080 [(set (reg FLAGS_REG)
9084 (match_operand 1 "ext_register_operand" "0")
9087 (match_operand 2 "const_int_operand" "n"))
9089 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9098 "ix86_match_ccmode (insn, CCNOmode)"
9099 "and{b}\t{%2, %h0|%h0, %2}"
9100 [(set_attr "type" "alu")
9101 (set_attr "length_immediate" "1")
9102 (set_attr "mode" "QI")])
9104 (define_insn "*andqi_ext_1"
9105 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9110 (match_operand 1 "ext_register_operand" "0")
9114 (match_operand:QI 2 "general_operand" "Qm"))))
9115 (clobber (reg:CC FLAGS_REG))]
9117 "and{b}\t{%2, %h0|%h0, %2}"
9118 [(set_attr "type" "alu")
9119 (set_attr "length_immediate" "0")
9120 (set_attr "mode" "QI")])
9122 (define_insn "*andqi_ext_1_rex64"
9123 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128 (match_operand 1 "ext_register_operand" "0")
9132 (match_operand 2 "ext_register_operand" "Q"))))
9133 (clobber (reg:CC FLAGS_REG))]
9135 "and{b}\t{%2, %h0|%h0, %2}"
9136 [(set_attr "type" "alu")
9137 (set_attr "length_immediate" "0")
9138 (set_attr "mode" "QI")])
9140 (define_insn "*andqi_ext_2"
9141 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9146 (match_operand 1 "ext_register_operand" "%0")
9150 (match_operand 2 "ext_register_operand" "Q")
9153 (clobber (reg:CC FLAGS_REG))]
9155 "and{b}\t{%h2, %h0|%h0, %h2}"
9156 [(set_attr "type" "alu")
9157 (set_attr "length_immediate" "0")
9158 (set_attr "mode" "QI")])
9160 ;; Convert wide AND instructions with immediate operand to shorter QImode
9161 ;; equivalents when possible.
9162 ;; Don't do the splitting with memory operands, since it introduces risk
9163 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9164 ;; for size, but that can (should?) be handled by generic code instead.
9166 [(set (match_operand 0 "register_operand" "")
9167 (and (match_operand 1 "register_operand" "")
9168 (match_operand 2 "const_int_operand" "")))
9169 (clobber (reg:CC FLAGS_REG))]
9171 && QI_REG_P (operands[0])
9172 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9173 && !(~INTVAL (operands[2]) & ~(255 << 8))
9174 && GET_MODE (operands[0]) != QImode"
9175 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9176 (and:SI (zero_extract:SI (match_dup 1)
9177 (const_int 8) (const_int 8))
9179 (clobber (reg:CC FLAGS_REG))])]
9180 "operands[0] = gen_lowpart (SImode, operands[0]);
9181 operands[1] = gen_lowpart (SImode, operands[1]);
9182 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9184 ;; Since AND can be encoded with sign extended immediate, this is only
9185 ;; profitable when 7th bit is not set.
9187 [(set (match_operand 0 "register_operand" "")
9188 (and (match_operand 1 "general_operand" "")
9189 (match_operand 2 "const_int_operand" "")))
9190 (clobber (reg:CC FLAGS_REG))]
9192 && ANY_QI_REG_P (operands[0])
9193 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9194 && !(~INTVAL (operands[2]) & ~255)
9195 && !(INTVAL (operands[2]) & 128)
9196 && GET_MODE (operands[0]) != QImode"
9197 [(parallel [(set (strict_low_part (match_dup 0))
9198 (and:QI (match_dup 1)
9200 (clobber (reg:CC FLAGS_REG))])]
9201 "operands[0] = gen_lowpart (QImode, operands[0]);
9202 operands[1] = gen_lowpart (QImode, operands[1]);
9203 operands[2] = gen_lowpart (QImode, operands[2]);")
9205 ;; Logical inclusive OR instructions
9207 ;; %%% This used to optimize known byte-wide and operations to memory.
9208 ;; If this is considered useful, it should be done with splitters.
9210 (define_expand "iordi3"
9211 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9212 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9213 (match_operand:DI 2 "x86_64_general_operand" "")))
9214 (clobber (reg:CC FLAGS_REG))]
9216 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9218 (define_insn "*iordi_1_rex64"
9219 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9220 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9221 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9222 (clobber (reg:CC FLAGS_REG))]
9224 && ix86_binary_operator_ok (IOR, DImode, operands)"
9225 "or{q}\t{%2, %0|%0, %2}"
9226 [(set_attr "type" "alu")
9227 (set_attr "mode" "DI")])
9229 (define_insn "*iordi_2_rex64"
9230 [(set (reg FLAGS_REG)
9231 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9232 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9234 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9235 (ior:DI (match_dup 1) (match_dup 2)))]
9237 && ix86_match_ccmode (insn, CCNOmode)
9238 && ix86_binary_operator_ok (IOR, DImode, operands)"
9239 "or{q}\t{%2, %0|%0, %2}"
9240 [(set_attr "type" "alu")
9241 (set_attr "mode" "DI")])
9243 (define_insn "*iordi_3_rex64"
9244 [(set (reg FLAGS_REG)
9245 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9246 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9248 (clobber (match_scratch:DI 0 "=r"))]
9250 && ix86_match_ccmode (insn, CCNOmode)
9251 && ix86_binary_operator_ok (IOR, DImode, operands)"
9252 "or{q}\t{%2, %0|%0, %2}"
9253 [(set_attr "type" "alu")
9254 (set_attr "mode" "DI")])
9257 (define_expand "iorsi3"
9258 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9259 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9260 (match_operand:SI 2 "general_operand" "")))
9261 (clobber (reg:CC FLAGS_REG))]
9263 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9265 (define_insn "*iorsi_1"
9266 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9267 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9268 (match_operand:SI 2 "general_operand" "ri,g")))
9269 (clobber (reg:CC FLAGS_REG))]
9270 "ix86_binary_operator_ok (IOR, SImode, operands)"
9271 "or{l}\t{%2, %0|%0, %2}"
9272 [(set_attr "type" "alu")
9273 (set_attr "mode" "SI")])
9275 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9276 (define_insn "*iorsi_1_zext"
9277 [(set (match_operand:DI 0 "register_operand" "=r")
9279 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9280 (match_operand:SI 2 "general_operand" "g"))))
9281 (clobber (reg:CC FLAGS_REG))]
9282 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9283 "or{l}\t{%2, %k0|%k0, %2}"
9284 [(set_attr "type" "alu")
9285 (set_attr "mode" "SI")])
9287 (define_insn "*iorsi_1_zext_imm"
9288 [(set (match_operand:DI 0 "register_operand" "=r")
9289 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9290 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9291 (clobber (reg:CC FLAGS_REG))]
9293 "or{l}\t{%2, %k0|%k0, %2}"
9294 [(set_attr "type" "alu")
9295 (set_attr "mode" "SI")])
9297 (define_insn "*iorsi_2"
9298 [(set (reg FLAGS_REG)
9299 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9300 (match_operand:SI 2 "general_operand" "g,ri"))
9302 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9303 (ior:SI (match_dup 1) (match_dup 2)))]
9304 "ix86_match_ccmode (insn, CCNOmode)
9305 && ix86_binary_operator_ok (IOR, SImode, operands)"
9306 "or{l}\t{%2, %0|%0, %2}"
9307 [(set_attr "type" "alu")
9308 (set_attr "mode" "SI")])
9310 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9311 ;; ??? Special case for immediate operand is missing - it is tricky.
9312 (define_insn "*iorsi_2_zext"
9313 [(set (reg FLAGS_REG)
9314 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9315 (match_operand:SI 2 "general_operand" "g"))
9317 (set (match_operand:DI 0 "register_operand" "=r")
9318 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9319 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9320 && ix86_binary_operator_ok (IOR, SImode, operands)"
9321 "or{l}\t{%2, %k0|%k0, %2}"
9322 [(set_attr "type" "alu")
9323 (set_attr "mode" "SI")])
9325 (define_insn "*iorsi_2_zext_imm"
9326 [(set (reg FLAGS_REG)
9327 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9328 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9330 (set (match_operand:DI 0 "register_operand" "=r")
9331 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9332 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9333 && ix86_binary_operator_ok (IOR, SImode, operands)"
9334 "or{l}\t{%2, %k0|%k0, %2}"
9335 [(set_attr "type" "alu")
9336 (set_attr "mode" "SI")])
9338 (define_insn "*iorsi_3"
9339 [(set (reg FLAGS_REG)
9340 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9341 (match_operand:SI 2 "general_operand" "g"))
9343 (clobber (match_scratch:SI 0 "=r"))]
9344 "ix86_match_ccmode (insn, CCNOmode)
9345 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9346 "or{l}\t{%2, %0|%0, %2}"
9347 [(set_attr "type" "alu")
9348 (set_attr "mode" "SI")])
9350 (define_expand "iorhi3"
9351 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9352 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9353 (match_operand:HI 2 "general_operand" "")))
9354 (clobber (reg:CC FLAGS_REG))]
9355 "TARGET_HIMODE_MATH"
9356 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9358 (define_insn "*iorhi_1"
9359 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9360 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9361 (match_operand:HI 2 "general_operand" "g,ri")))
9362 (clobber (reg:CC FLAGS_REG))]
9363 "ix86_binary_operator_ok (IOR, HImode, operands)"
9364 "or{w}\t{%2, %0|%0, %2}"
9365 [(set_attr "type" "alu")
9366 (set_attr "mode" "HI")])
9368 (define_insn "*iorhi_2"
9369 [(set (reg FLAGS_REG)
9370 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9371 (match_operand:HI 2 "general_operand" "g,ri"))
9373 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9374 (ior:HI (match_dup 1) (match_dup 2)))]
9375 "ix86_match_ccmode (insn, CCNOmode)
9376 && ix86_binary_operator_ok (IOR, HImode, operands)"
9377 "or{w}\t{%2, %0|%0, %2}"
9378 [(set_attr "type" "alu")
9379 (set_attr "mode" "HI")])
9381 (define_insn "*iorhi_3"
9382 [(set (reg FLAGS_REG)
9383 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9384 (match_operand:HI 2 "general_operand" "g"))
9386 (clobber (match_scratch:HI 0 "=r"))]
9387 "ix86_match_ccmode (insn, CCNOmode)
9388 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9389 "or{w}\t{%2, %0|%0, %2}"
9390 [(set_attr "type" "alu")
9391 (set_attr "mode" "HI")])
9393 (define_expand "iorqi3"
9394 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9395 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9396 (match_operand:QI 2 "general_operand" "")))
9397 (clobber (reg:CC FLAGS_REG))]
9398 "TARGET_QIMODE_MATH"
9399 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9401 ;; %%% Potential partial reg stall on alternative 2. What to do?
9402 (define_insn "*iorqi_1"
9403 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9404 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9405 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9406 (clobber (reg:CC FLAGS_REG))]
9407 "ix86_binary_operator_ok (IOR, QImode, operands)"
9409 or{b}\t{%2, %0|%0, %2}
9410 or{b}\t{%2, %0|%0, %2}
9411 or{l}\t{%k2, %k0|%k0, %k2}"
9412 [(set_attr "type" "alu")
9413 (set_attr "mode" "QI,QI,SI")])
9415 (define_insn "*iorqi_1_slp"
9416 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9417 (ior:QI (match_dup 0)
9418 (match_operand:QI 1 "general_operand" "qmi,qi")))
9419 (clobber (reg:CC FLAGS_REG))]
9420 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9421 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9422 "or{b}\t{%1, %0|%0, %1}"
9423 [(set_attr "type" "alu1")
9424 (set_attr "mode" "QI")])
9426 (define_insn "*iorqi_2"
9427 [(set (reg FLAGS_REG)
9428 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9429 (match_operand:QI 2 "general_operand" "qim,qi"))
9431 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9432 (ior:QI (match_dup 1) (match_dup 2)))]
9433 "ix86_match_ccmode (insn, CCNOmode)
9434 && ix86_binary_operator_ok (IOR, QImode, operands)"
9435 "or{b}\t{%2, %0|%0, %2}"
9436 [(set_attr "type" "alu")
9437 (set_attr "mode" "QI")])
9439 (define_insn "*iorqi_2_slp"
9440 [(set (reg FLAGS_REG)
9441 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9442 (match_operand:QI 1 "general_operand" "qim,qi"))
9444 (set (strict_low_part (match_dup 0))
9445 (ior:QI (match_dup 0) (match_dup 1)))]
9446 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9447 && ix86_match_ccmode (insn, CCNOmode)
9448 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9449 "or{b}\t{%1, %0|%0, %1}"
9450 [(set_attr "type" "alu1")
9451 (set_attr "mode" "QI")])
9453 (define_insn "*iorqi_3"
9454 [(set (reg FLAGS_REG)
9455 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9456 (match_operand:QI 2 "general_operand" "qim"))
9458 (clobber (match_scratch:QI 0 "=q"))]
9459 "ix86_match_ccmode (insn, CCNOmode)
9460 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9461 "or{b}\t{%2, %0|%0, %2}"
9462 [(set_attr "type" "alu")
9463 (set_attr "mode" "QI")])
9465 (define_insn "iorqi_ext_0"
9466 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9471 (match_operand 1 "ext_register_operand" "0")
9474 (match_operand 2 "const_int_operand" "n")))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9477 "or{b}\t{%2, %h0|%h0, %2}"
9478 [(set_attr "type" "alu")
9479 (set_attr "length_immediate" "1")
9480 (set_attr "mode" "QI")])
9482 (define_insn "*iorqi_ext_1"
9483 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9488 (match_operand 1 "ext_register_operand" "0")
9492 (match_operand:QI 2 "general_operand" "Qm"))))
9493 (clobber (reg:CC FLAGS_REG))]
9495 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9496 "or{b}\t{%2, %h0|%h0, %2}"
9497 [(set_attr "type" "alu")
9498 (set_attr "length_immediate" "0")
9499 (set_attr "mode" "QI")])
9501 (define_insn "*iorqi_ext_1_rex64"
9502 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9507 (match_operand 1 "ext_register_operand" "0")
9511 (match_operand 2 "ext_register_operand" "Q"))))
9512 (clobber (reg:CC FLAGS_REG))]
9514 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9515 "or{b}\t{%2, %h0|%h0, %2}"
9516 [(set_attr "type" "alu")
9517 (set_attr "length_immediate" "0")
9518 (set_attr "mode" "QI")])
9520 (define_insn "*iorqi_ext_2"
9521 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9525 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9528 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9531 (clobber (reg:CC FLAGS_REG))]
9532 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9533 "ior{b}\t{%h2, %h0|%h0, %h2}"
9534 [(set_attr "type" "alu")
9535 (set_attr "length_immediate" "0")
9536 (set_attr "mode" "QI")])
9539 [(set (match_operand 0 "register_operand" "")
9540 (ior (match_operand 1 "register_operand" "")
9541 (match_operand 2 "const_int_operand" "")))
9542 (clobber (reg:CC FLAGS_REG))]
9544 && QI_REG_P (operands[0])
9545 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9546 && !(INTVAL (operands[2]) & ~(255 << 8))
9547 && GET_MODE (operands[0]) != QImode"
9548 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9549 (ior:SI (zero_extract:SI (match_dup 1)
9550 (const_int 8) (const_int 8))
9552 (clobber (reg:CC FLAGS_REG))])]
9553 "operands[0] = gen_lowpart (SImode, operands[0]);
9554 operands[1] = gen_lowpart (SImode, operands[1]);
9555 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9557 ;; Since OR can be encoded with sign extended immediate, this is only
9558 ;; profitable when 7th bit is set.
9560 [(set (match_operand 0 "register_operand" "")
9561 (ior (match_operand 1 "general_operand" "")
9562 (match_operand 2 "const_int_operand" "")))
9563 (clobber (reg:CC FLAGS_REG))]
9565 && ANY_QI_REG_P (operands[0])
9566 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9567 && !(INTVAL (operands[2]) & ~255)
9568 && (INTVAL (operands[2]) & 128)
9569 && GET_MODE (operands[0]) != QImode"
9570 [(parallel [(set (strict_low_part (match_dup 0))
9571 (ior:QI (match_dup 1)
9573 (clobber (reg:CC FLAGS_REG))])]
9574 "operands[0] = gen_lowpart (QImode, operands[0]);
9575 operands[1] = gen_lowpart (QImode, operands[1]);
9576 operands[2] = gen_lowpart (QImode, operands[2]);")
9578 ;; Logical XOR instructions
9580 ;; %%% This used to optimize known byte-wide and operations to memory.
9581 ;; If this is considered useful, it should be done with splitters.
9583 (define_expand "xordi3"
9584 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9585 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9586 (match_operand:DI 2 "x86_64_general_operand" "")))
9587 (clobber (reg:CC FLAGS_REG))]
9589 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9591 (define_insn "*xordi_1_rex64"
9592 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9593 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9594 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9595 (clobber (reg:CC FLAGS_REG))]
9597 && ix86_binary_operator_ok (XOR, DImode, operands)"
9599 xor{q}\t{%2, %0|%0, %2}
9600 xor{q}\t{%2, %0|%0, %2}"
9601 [(set_attr "type" "alu")
9602 (set_attr "mode" "DI,DI")])
9604 (define_insn "*xordi_2_rex64"
9605 [(set (reg FLAGS_REG)
9606 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9607 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9609 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9610 (xor:DI (match_dup 1) (match_dup 2)))]
9612 && ix86_match_ccmode (insn, CCNOmode)
9613 && ix86_binary_operator_ok (XOR, DImode, operands)"
9615 xor{q}\t{%2, %0|%0, %2}
9616 xor{q}\t{%2, %0|%0, %2}"
9617 [(set_attr "type" "alu")
9618 (set_attr "mode" "DI,DI")])
9620 (define_insn "*xordi_3_rex64"
9621 [(set (reg FLAGS_REG)
9622 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9623 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9625 (clobber (match_scratch:DI 0 "=r"))]
9627 && ix86_match_ccmode (insn, CCNOmode)
9628 && ix86_binary_operator_ok (XOR, DImode, operands)"
9629 "xor{q}\t{%2, %0|%0, %2}"
9630 [(set_attr "type" "alu")
9631 (set_attr "mode" "DI")])
9633 (define_expand "xorsi3"
9634 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9635 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9636 (match_operand:SI 2 "general_operand" "")))
9637 (clobber (reg:CC FLAGS_REG))]
9639 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9641 (define_insn "*xorsi_1"
9642 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9643 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9644 (match_operand:SI 2 "general_operand" "ri,rm")))
9645 (clobber (reg:CC FLAGS_REG))]
9646 "ix86_binary_operator_ok (XOR, SImode, operands)"
9647 "xor{l}\t{%2, %0|%0, %2}"
9648 [(set_attr "type" "alu")
9649 (set_attr "mode" "SI")])
9651 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9652 ;; Add speccase for immediates
9653 (define_insn "*xorsi_1_zext"
9654 [(set (match_operand:DI 0 "register_operand" "=r")
9656 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9657 (match_operand:SI 2 "general_operand" "g"))))
9658 (clobber (reg:CC FLAGS_REG))]
9659 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9660 "xor{l}\t{%2, %k0|%k0, %2}"
9661 [(set_attr "type" "alu")
9662 (set_attr "mode" "SI")])
9664 (define_insn "*xorsi_1_zext_imm"
9665 [(set (match_operand:DI 0 "register_operand" "=r")
9666 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9667 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9668 (clobber (reg:CC FLAGS_REG))]
9669 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9670 "xor{l}\t{%2, %k0|%k0, %2}"
9671 [(set_attr "type" "alu")
9672 (set_attr "mode" "SI")])
9674 (define_insn "*xorsi_2"
9675 [(set (reg FLAGS_REG)
9676 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9677 (match_operand:SI 2 "general_operand" "g,ri"))
9679 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9680 (xor:SI (match_dup 1) (match_dup 2)))]
9681 "ix86_match_ccmode (insn, CCNOmode)
9682 && ix86_binary_operator_ok (XOR, SImode, operands)"
9683 "xor{l}\t{%2, %0|%0, %2}"
9684 [(set_attr "type" "alu")
9685 (set_attr "mode" "SI")])
9687 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9688 ;; ??? Special case for immediate operand is missing - it is tricky.
9689 (define_insn "*xorsi_2_zext"
9690 [(set (reg FLAGS_REG)
9691 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9692 (match_operand:SI 2 "general_operand" "g"))
9694 (set (match_operand:DI 0 "register_operand" "=r")
9695 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9696 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9697 && ix86_binary_operator_ok (XOR, SImode, operands)"
9698 "xor{l}\t{%2, %k0|%k0, %2}"
9699 [(set_attr "type" "alu")
9700 (set_attr "mode" "SI")])
9702 (define_insn "*xorsi_2_zext_imm"
9703 [(set (reg FLAGS_REG)
9704 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9705 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9707 (set (match_operand:DI 0 "register_operand" "=r")
9708 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9709 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9710 && ix86_binary_operator_ok (XOR, SImode, operands)"
9711 "xor{l}\t{%2, %k0|%k0, %2}"
9712 [(set_attr "type" "alu")
9713 (set_attr "mode" "SI")])
9715 (define_insn "*xorsi_3"
9716 [(set (reg FLAGS_REG)
9717 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9718 (match_operand:SI 2 "general_operand" "g"))
9720 (clobber (match_scratch:SI 0 "=r"))]
9721 "ix86_match_ccmode (insn, CCNOmode)
9722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9723 "xor{l}\t{%2, %0|%0, %2}"
9724 [(set_attr "type" "alu")
9725 (set_attr "mode" "SI")])
9727 (define_expand "xorhi3"
9728 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9729 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9730 (match_operand:HI 2 "general_operand" "")))
9731 (clobber (reg:CC FLAGS_REG))]
9732 "TARGET_HIMODE_MATH"
9733 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9735 (define_insn "*xorhi_1"
9736 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9737 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9738 (match_operand:HI 2 "general_operand" "g,ri")))
9739 (clobber (reg:CC FLAGS_REG))]
9740 "ix86_binary_operator_ok (XOR, HImode, operands)"
9741 "xor{w}\t{%2, %0|%0, %2}"
9742 [(set_attr "type" "alu")
9743 (set_attr "mode" "HI")])
9745 (define_insn "*xorhi_2"
9746 [(set (reg FLAGS_REG)
9747 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9748 (match_operand:HI 2 "general_operand" "g,ri"))
9750 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9751 (xor:HI (match_dup 1) (match_dup 2)))]
9752 "ix86_match_ccmode (insn, CCNOmode)
9753 && ix86_binary_operator_ok (XOR, HImode, operands)"
9754 "xor{w}\t{%2, %0|%0, %2}"
9755 [(set_attr "type" "alu")
9756 (set_attr "mode" "HI")])
9758 (define_insn "*xorhi_3"
9759 [(set (reg FLAGS_REG)
9760 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9761 (match_operand:HI 2 "general_operand" "g"))
9763 (clobber (match_scratch:HI 0 "=r"))]
9764 "ix86_match_ccmode (insn, CCNOmode)
9765 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9766 "xor{w}\t{%2, %0|%0, %2}"
9767 [(set_attr "type" "alu")
9768 (set_attr "mode" "HI")])
9770 (define_expand "xorqi3"
9771 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9772 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9773 (match_operand:QI 2 "general_operand" "")))
9774 (clobber (reg:CC FLAGS_REG))]
9775 "TARGET_QIMODE_MATH"
9776 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9778 ;; %%% Potential partial reg stall on alternative 2. What to do?
9779 (define_insn "*xorqi_1"
9780 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9781 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9782 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9783 (clobber (reg:CC FLAGS_REG))]
9784 "ix86_binary_operator_ok (XOR, QImode, operands)"
9786 xor{b}\t{%2, %0|%0, %2}
9787 xor{b}\t{%2, %0|%0, %2}
9788 xor{l}\t{%k2, %k0|%k0, %k2}"
9789 [(set_attr "type" "alu")
9790 (set_attr "mode" "QI,QI,SI")])
9792 (define_insn "*xorqi_1_slp"
9793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9794 (xor:QI (match_dup 0)
9795 (match_operand:QI 1 "general_operand" "qi,qmi")))
9796 (clobber (reg:CC FLAGS_REG))]
9797 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9798 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9799 "xor{b}\t{%1, %0|%0, %1}"
9800 [(set_attr "type" "alu1")
9801 (set_attr "mode" "QI")])
9803 (define_insn "xorqi_ext_0"
9804 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9809 (match_operand 1 "ext_register_operand" "0")
9812 (match_operand 2 "const_int_operand" "n")))
9813 (clobber (reg:CC FLAGS_REG))]
9814 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9815 "xor{b}\t{%2, %h0|%h0, %2}"
9816 [(set_attr "type" "alu")
9817 (set_attr "length_immediate" "1")
9818 (set_attr "mode" "QI")])
9820 (define_insn "*xorqi_ext_1"
9821 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9826 (match_operand 1 "ext_register_operand" "0")
9830 (match_operand:QI 2 "general_operand" "Qm"))))
9831 (clobber (reg:CC FLAGS_REG))]
9833 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9834 "xor{b}\t{%2, %h0|%h0, %2}"
9835 [(set_attr "type" "alu")
9836 (set_attr "length_immediate" "0")
9837 (set_attr "mode" "QI")])
9839 (define_insn "*xorqi_ext_1_rex64"
9840 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9845 (match_operand 1 "ext_register_operand" "0")
9849 (match_operand 2 "ext_register_operand" "Q"))))
9850 (clobber (reg:CC FLAGS_REG))]
9852 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9853 "xor{b}\t{%2, %h0|%h0, %2}"
9854 [(set_attr "type" "alu")
9855 (set_attr "length_immediate" "0")
9856 (set_attr "mode" "QI")])
9858 (define_insn "*xorqi_ext_2"
9859 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9863 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9866 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9869 (clobber (reg:CC FLAGS_REG))]
9870 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9871 "xor{b}\t{%h2, %h0|%h0, %h2}"
9872 [(set_attr "type" "alu")
9873 (set_attr "length_immediate" "0")
9874 (set_attr "mode" "QI")])
9876 (define_insn "*xorqi_cc_1"
9877 [(set (reg FLAGS_REG)
9879 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9880 (match_operand:QI 2 "general_operand" "qim,qi"))
9882 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9883 (xor:QI (match_dup 1) (match_dup 2)))]
9884 "ix86_match_ccmode (insn, CCNOmode)
9885 && ix86_binary_operator_ok (XOR, QImode, operands)"
9886 "xor{b}\t{%2, %0|%0, %2}"
9887 [(set_attr "type" "alu")
9888 (set_attr "mode" "QI")])
9890 (define_insn "*xorqi_2_slp"
9891 [(set (reg FLAGS_REG)
9892 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9893 (match_operand:QI 1 "general_operand" "qim,qi"))
9895 (set (strict_low_part (match_dup 0))
9896 (xor:QI (match_dup 0) (match_dup 1)))]
9897 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9898 && ix86_match_ccmode (insn, CCNOmode)
9899 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9900 "xor{b}\t{%1, %0|%0, %1}"
9901 [(set_attr "type" "alu1")
9902 (set_attr "mode" "QI")])
9904 (define_insn "*xorqi_cc_2"
9905 [(set (reg FLAGS_REG)
9907 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9908 (match_operand:QI 2 "general_operand" "qim"))
9910 (clobber (match_scratch:QI 0 "=q"))]
9911 "ix86_match_ccmode (insn, CCNOmode)
9912 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9913 "xor{b}\t{%2, %0|%0, %2}"
9914 [(set_attr "type" "alu")
9915 (set_attr "mode" "QI")])
9917 (define_insn "*xorqi_cc_ext_1"
9918 [(set (reg FLAGS_REG)
9922 (match_operand 1 "ext_register_operand" "0")
9925 (match_operand:QI 2 "general_operand" "qmn"))
9927 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9931 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9933 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9934 "xor{b}\t{%2, %h0|%h0, %2}"
9935 [(set_attr "type" "alu")
9936 (set_attr "mode" "QI")])
9938 (define_insn "*xorqi_cc_ext_1_rex64"
9939 [(set (reg FLAGS_REG)
9943 (match_operand 1 "ext_register_operand" "0")
9946 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9948 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9952 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9954 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9955 "xor{b}\t{%2, %h0|%h0, %2}"
9956 [(set_attr "type" "alu")
9957 (set_attr "mode" "QI")])
9959 (define_expand "xorqi_cc_ext_1"
9961 (set (reg:CCNO FLAGS_REG)
9965 (match_operand 1 "ext_register_operand" "")
9968 (match_operand:QI 2 "general_operand" ""))
9970 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9974 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9980 [(set (match_operand 0 "register_operand" "")
9981 (xor (match_operand 1 "register_operand" "")
9982 (match_operand 2 "const_int_operand" "")))
9983 (clobber (reg:CC FLAGS_REG))]
9985 && QI_REG_P (operands[0])
9986 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9987 && !(INTVAL (operands[2]) & ~(255 << 8))
9988 && GET_MODE (operands[0]) != QImode"
9989 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9990 (xor:SI (zero_extract:SI (match_dup 1)
9991 (const_int 8) (const_int 8))
9993 (clobber (reg:CC FLAGS_REG))])]
9994 "operands[0] = gen_lowpart (SImode, operands[0]);
9995 operands[1] = gen_lowpart (SImode, operands[1]);
9996 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9998 ;; Since XOR can be encoded with sign extended immediate, this is only
9999 ;; profitable when 7th bit is set.
10001 [(set (match_operand 0 "register_operand" "")
10002 (xor (match_operand 1 "general_operand" "")
10003 (match_operand 2 "const_int_operand" "")))
10004 (clobber (reg:CC FLAGS_REG))]
10006 && ANY_QI_REG_P (operands[0])
10007 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10008 && !(INTVAL (operands[2]) & ~255)
10009 && (INTVAL (operands[2]) & 128)
10010 && GET_MODE (operands[0]) != QImode"
10011 [(parallel [(set (strict_low_part (match_dup 0))
10012 (xor:QI (match_dup 1)
10014 (clobber (reg:CC FLAGS_REG))])]
10015 "operands[0] = gen_lowpart (QImode, operands[0]);
10016 operands[1] = gen_lowpart (QImode, operands[1]);
10017 operands[2] = gen_lowpart (QImode, operands[2]);")
10019 ;; Negation instructions
10021 (define_expand "negti2"
10022 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10023 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10024 (clobber (reg:CC FLAGS_REG))])]
10026 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10028 (define_insn "*negti2_1"
10029 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10030 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10031 (clobber (reg:CC FLAGS_REG))]
10033 && ix86_unary_operator_ok (NEG, TImode, operands)"
10037 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10038 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10039 (clobber (reg:CC FLAGS_REG))]
10040 "TARGET_64BIT && reload_completed"
10042 [(set (reg:CCZ FLAGS_REG)
10043 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10044 (set (match_dup 0) (neg:DI (match_dup 2)))])
10046 [(set (match_dup 1)
10047 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10050 (clobber (reg:CC FLAGS_REG))])
10052 [(set (match_dup 1)
10053 (neg:DI (match_dup 1)))
10054 (clobber (reg:CC FLAGS_REG))])]
10055 "split_ti (operands+1, 1, operands+2, operands+3);
10056 split_ti (operands+0, 1, operands+0, operands+1);")
10058 (define_expand "negdi2"
10059 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10060 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10061 (clobber (reg:CC FLAGS_REG))])]
10063 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10065 (define_insn "*negdi2_1"
10066 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10067 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10068 (clobber (reg:CC FLAGS_REG))]
10070 && ix86_unary_operator_ok (NEG, DImode, operands)"
10074 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10075 (neg:DI (match_operand:DI 1 "general_operand" "")))
10076 (clobber (reg:CC FLAGS_REG))]
10077 "!TARGET_64BIT && reload_completed"
10079 [(set (reg:CCZ FLAGS_REG)
10080 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10081 (set (match_dup 0) (neg:SI (match_dup 2)))])
10083 [(set (match_dup 1)
10084 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10087 (clobber (reg:CC FLAGS_REG))])
10089 [(set (match_dup 1)
10090 (neg:SI (match_dup 1)))
10091 (clobber (reg:CC FLAGS_REG))])]
10092 "split_di (operands+1, 1, operands+2, operands+3);
10093 split_di (operands+0, 1, operands+0, operands+1);")
10095 (define_insn "*negdi2_1_rex64"
10096 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10097 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10098 (clobber (reg:CC FLAGS_REG))]
10099 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10101 [(set_attr "type" "negnot")
10102 (set_attr "mode" "DI")])
10104 ;; The problem with neg is that it does not perform (compare x 0),
10105 ;; it really performs (compare 0 x), which leaves us with the zero
10106 ;; flag being the only useful item.
10108 (define_insn "*negdi2_cmpz_rex64"
10109 [(set (reg:CCZ FLAGS_REG)
10110 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10112 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10113 (neg:DI (match_dup 1)))]
10114 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10116 [(set_attr "type" "negnot")
10117 (set_attr "mode" "DI")])
10120 (define_expand "negsi2"
10121 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10122 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10123 (clobber (reg:CC FLAGS_REG))])]
10125 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10127 (define_insn "*negsi2_1"
10128 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10129 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10130 (clobber (reg:CC FLAGS_REG))]
10131 "ix86_unary_operator_ok (NEG, SImode, operands)"
10133 [(set_attr "type" "negnot")
10134 (set_attr "mode" "SI")])
10136 ;; Combine is quite creative about this pattern.
10137 (define_insn "*negsi2_1_zext"
10138 [(set (match_operand:DI 0 "register_operand" "=r")
10139 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10142 (clobber (reg:CC FLAGS_REG))]
10143 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10145 [(set_attr "type" "negnot")
10146 (set_attr "mode" "SI")])
10148 ;; The problem with neg is that it does not perform (compare x 0),
10149 ;; it really performs (compare 0 x), which leaves us with the zero
10150 ;; flag being the only useful item.
10152 (define_insn "*negsi2_cmpz"
10153 [(set (reg:CCZ FLAGS_REG)
10154 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10156 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10157 (neg:SI (match_dup 1)))]
10158 "ix86_unary_operator_ok (NEG, SImode, operands)"
10160 [(set_attr "type" "negnot")
10161 (set_attr "mode" "SI")])
10163 (define_insn "*negsi2_cmpz_zext"
10164 [(set (reg:CCZ FLAGS_REG)
10165 (compare:CCZ (lshiftrt:DI
10167 (match_operand:DI 1 "register_operand" "0")
10171 (set (match_operand:DI 0 "register_operand" "=r")
10172 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10175 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10177 [(set_attr "type" "negnot")
10178 (set_attr "mode" "SI")])
10180 (define_expand "neghi2"
10181 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10182 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10183 (clobber (reg:CC FLAGS_REG))])]
10184 "TARGET_HIMODE_MATH"
10185 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10187 (define_insn "*neghi2_1"
10188 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10189 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10190 (clobber (reg:CC FLAGS_REG))]
10191 "ix86_unary_operator_ok (NEG, HImode, operands)"
10193 [(set_attr "type" "negnot")
10194 (set_attr "mode" "HI")])
10196 (define_insn "*neghi2_cmpz"
10197 [(set (reg:CCZ FLAGS_REG)
10198 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10200 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10201 (neg:HI (match_dup 1)))]
10202 "ix86_unary_operator_ok (NEG, HImode, operands)"
10204 [(set_attr "type" "negnot")
10205 (set_attr "mode" "HI")])
10207 (define_expand "negqi2"
10208 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10209 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10210 (clobber (reg:CC FLAGS_REG))])]
10211 "TARGET_QIMODE_MATH"
10212 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10214 (define_insn "*negqi2_1"
10215 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10216 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10217 (clobber (reg:CC FLAGS_REG))]
10218 "ix86_unary_operator_ok (NEG, QImode, operands)"
10220 [(set_attr "type" "negnot")
10221 (set_attr "mode" "QI")])
10223 (define_insn "*negqi2_cmpz"
10224 [(set (reg:CCZ FLAGS_REG)
10225 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10227 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10228 (neg:QI (match_dup 1)))]
10229 "ix86_unary_operator_ok (NEG, QImode, operands)"
10231 [(set_attr "type" "negnot")
10232 (set_attr "mode" "QI")])
10234 ;; Changing of sign for FP values is doable using integer unit too.
10236 (define_expand "neg<mode>2"
10237 [(set (match_operand:X87MODEF 0 "register_operand" "")
10238 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10239 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10240 "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10242 (define_expand "abs<mode>2"
10243 [(set (match_operand:X87MODEF 0 "register_operand" "")
10244 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10245 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10246 "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10248 (define_insn "*absneg<mode>2_mixed"
10249 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10250 (match_operator:MODEF 3 "absneg_operator"
10251 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10252 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10253 (clobber (reg:CC FLAGS_REG))]
10254 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10257 (define_insn "*absneg<mode>2_sse"
10258 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10259 (match_operator:MODEF 3 "absneg_operator"
10260 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10261 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10262 (clobber (reg:CC FLAGS_REG))]
10263 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10266 (define_insn "*absneg<mode>2_i387"
10267 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10268 (match_operator:X87MODEF 3 "absneg_operator"
10269 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10270 (use (match_operand 2 "" ""))
10271 (clobber (reg:CC FLAGS_REG))]
10272 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10275 (define_expand "negtf2"
10276 [(set (match_operand:TF 0 "register_operand" "")
10277 (neg:TF (match_operand:TF 1 "register_operand" "")))]
10279 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10281 (define_expand "abstf2"
10282 [(set (match_operand:TF 0 "register_operand" "")
10283 (abs:TF (match_operand:TF 1 "register_operand" "")))]
10285 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10287 (define_insn "*absnegtf2_sse"
10288 [(set (match_operand:TF 0 "register_operand" "=x,x")
10289 (match_operator:TF 3 "absneg_operator"
10290 [(match_operand:TF 1 "register_operand" "0,x")]))
10291 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10292 (clobber (reg:CC FLAGS_REG))]
10296 ;; Splitters for fp abs and neg.
10299 [(set (match_operand 0 "fp_register_operand" "")
10300 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10301 (use (match_operand 2 "" ""))
10302 (clobber (reg:CC FLAGS_REG))]
10304 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10307 [(set (match_operand 0 "register_operand" "")
10308 (match_operator 3 "absneg_operator"
10309 [(match_operand 1 "register_operand" "")]))
10310 (use (match_operand 2 "nonimmediate_operand" ""))
10311 (clobber (reg:CC FLAGS_REG))]
10312 "reload_completed && SSE_REG_P (operands[0])"
10313 [(set (match_dup 0) (match_dup 3))]
10315 enum machine_mode mode = GET_MODE (operands[0]);
10316 enum machine_mode vmode = GET_MODE (operands[2]);
10319 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10320 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10321 if (operands_match_p (operands[0], operands[2]))
10324 operands[1] = operands[2];
10327 if (GET_CODE (operands[3]) == ABS)
10328 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10330 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10335 [(set (match_operand:SF 0 "register_operand" "")
10336 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10337 (use (match_operand:V4SF 2 "" ""))
10338 (clobber (reg:CC FLAGS_REG))]
10340 [(parallel [(set (match_dup 0) (match_dup 1))
10341 (clobber (reg:CC FLAGS_REG))])]
10344 operands[0] = gen_lowpart (SImode, operands[0]);
10345 if (GET_CODE (operands[1]) == ABS)
10347 tmp = gen_int_mode (0x7fffffff, SImode);
10348 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10352 tmp = gen_int_mode (0x80000000, SImode);
10353 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10359 [(set (match_operand:DF 0 "register_operand" "")
10360 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10361 (use (match_operand 2 "" ""))
10362 (clobber (reg:CC FLAGS_REG))]
10364 [(parallel [(set (match_dup 0) (match_dup 1))
10365 (clobber (reg:CC FLAGS_REG))])]
10370 tmp = gen_lowpart (DImode, operands[0]);
10371 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10374 if (GET_CODE (operands[1]) == ABS)
10377 tmp = gen_rtx_NOT (DImode, tmp);
10381 operands[0] = gen_highpart (SImode, operands[0]);
10382 if (GET_CODE (operands[1]) == ABS)
10384 tmp = gen_int_mode (0x7fffffff, SImode);
10385 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10389 tmp = gen_int_mode (0x80000000, SImode);
10390 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10397 [(set (match_operand:XF 0 "register_operand" "")
10398 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10399 (use (match_operand 2 "" ""))
10400 (clobber (reg:CC FLAGS_REG))]
10402 [(parallel [(set (match_dup 0) (match_dup 1))
10403 (clobber (reg:CC FLAGS_REG))])]
10406 operands[0] = gen_rtx_REG (SImode,
10407 true_regnum (operands[0])
10408 + (TARGET_64BIT ? 1 : 2));
10409 if (GET_CODE (operands[1]) == ABS)
10411 tmp = GEN_INT (0x7fff);
10412 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10416 tmp = GEN_INT (0x8000);
10417 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10422 ;; Conditionalize these after reload. If they match before reload, we
10423 ;; lose the clobber and ability to use integer instructions.
10425 (define_insn "*neg<mode>2_1"
10426 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10427 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10429 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10431 [(set_attr "type" "fsgn")
10432 (set_attr "mode" "<MODE>")])
10434 (define_insn "*abs<mode>2_1"
10435 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10436 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10438 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10440 [(set_attr "type" "fsgn")
10441 (set_attr "mode" "<MODE>")])
10443 (define_insn "*negextendsfdf2"
10444 [(set (match_operand:DF 0 "register_operand" "=f")
10445 (neg:DF (float_extend:DF
10446 (match_operand:SF 1 "register_operand" "0"))))]
10447 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10449 [(set_attr "type" "fsgn")
10450 (set_attr "mode" "DF")])
10452 (define_insn "*negextenddfxf2"
10453 [(set (match_operand:XF 0 "register_operand" "=f")
10454 (neg:XF (float_extend:XF
10455 (match_operand:DF 1 "register_operand" "0"))))]
10458 [(set_attr "type" "fsgn")
10459 (set_attr "mode" "XF")])
10461 (define_insn "*negextendsfxf2"
10462 [(set (match_operand:XF 0 "register_operand" "=f")
10463 (neg:XF (float_extend:XF
10464 (match_operand:SF 1 "register_operand" "0"))))]
10467 [(set_attr "type" "fsgn")
10468 (set_attr "mode" "XF")])
10470 (define_insn "*absextendsfdf2"
10471 [(set (match_operand:DF 0 "register_operand" "=f")
10472 (abs:DF (float_extend:DF
10473 (match_operand:SF 1 "register_operand" "0"))))]
10474 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10476 [(set_attr "type" "fsgn")
10477 (set_attr "mode" "DF")])
10479 (define_insn "*absextenddfxf2"
10480 [(set (match_operand:XF 0 "register_operand" "=f")
10481 (abs:XF (float_extend:XF
10482 (match_operand:DF 1 "register_operand" "0"))))]
10485 [(set_attr "type" "fsgn")
10486 (set_attr "mode" "XF")])
10488 (define_insn "*absextendsfxf2"
10489 [(set (match_operand:XF 0 "register_operand" "=f")
10490 (abs:XF (float_extend:XF
10491 (match_operand:SF 1 "register_operand" "0"))))]
10494 [(set_attr "type" "fsgn")
10495 (set_attr "mode" "XF")])
10497 ;; Copysign instructions
10499 (define_mode_iterator CSGNMODE [SF DF TF])
10500 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10502 (define_expand "copysign<mode>3"
10503 [(match_operand:CSGNMODE 0 "register_operand" "")
10504 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10505 (match_operand:CSGNMODE 2 "register_operand" "")]
10506 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10507 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10509 ix86_expand_copysign (operands);
10513 (define_insn_and_split "copysign<mode>3_const"
10514 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10516 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10517 (match_operand:CSGNMODE 2 "register_operand" "0")
10518 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10520 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10521 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10523 "&& reload_completed"
10526 ix86_split_copysign_const (operands);
10530 (define_insn "copysign<mode>3_var"
10531 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10533 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10534 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10535 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10536 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10538 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10539 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10540 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10544 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10546 [(match_operand:CSGNMODE 2 "register_operand" "")
10547 (match_operand:CSGNMODE 3 "register_operand" "")
10548 (match_operand:<CSGNVMODE> 4 "" "")
10549 (match_operand:<CSGNVMODE> 5 "" "")]
10551 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10552 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10553 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10554 && reload_completed"
10557 ix86_split_copysign_var (operands);
10561 ;; One complement instructions
10563 (define_expand "one_cmpldi2"
10564 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10565 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10567 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10569 (define_insn "*one_cmpldi2_1_rex64"
10570 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10571 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10572 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10574 [(set_attr "type" "negnot")
10575 (set_attr "mode" "DI")])
10577 (define_insn "*one_cmpldi2_2_rex64"
10578 [(set (reg FLAGS_REG)
10579 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10581 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10582 (not:DI (match_dup 1)))]
10583 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10584 && ix86_unary_operator_ok (NOT, DImode, operands)"
10586 [(set_attr "type" "alu1")
10587 (set_attr "mode" "DI")])
10590 [(set (match_operand 0 "flags_reg_operand" "")
10591 (match_operator 2 "compare_operator"
10592 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10594 (set (match_operand:DI 1 "nonimmediate_operand" "")
10595 (not:DI (match_dup 3)))]
10596 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10597 [(parallel [(set (match_dup 0)
10599 [(xor:DI (match_dup 3) (const_int -1))
10602 (xor:DI (match_dup 3) (const_int -1)))])]
10605 (define_expand "one_cmplsi2"
10606 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10607 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10609 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10611 (define_insn "*one_cmplsi2_1"
10612 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10613 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10614 "ix86_unary_operator_ok (NOT, SImode, operands)"
10616 [(set_attr "type" "negnot")
10617 (set_attr "mode" "SI")])
10619 ;; ??? Currently never generated - xor is used instead.
10620 (define_insn "*one_cmplsi2_1_zext"
10621 [(set (match_operand:DI 0 "register_operand" "=r")
10622 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10623 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10625 [(set_attr "type" "negnot")
10626 (set_attr "mode" "SI")])
10628 (define_insn "*one_cmplsi2_2"
10629 [(set (reg FLAGS_REG)
10630 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10632 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10633 (not:SI (match_dup 1)))]
10634 "ix86_match_ccmode (insn, CCNOmode)
10635 && ix86_unary_operator_ok (NOT, SImode, operands)"
10637 [(set_attr "type" "alu1")
10638 (set_attr "mode" "SI")])
10641 [(set (match_operand 0 "flags_reg_operand" "")
10642 (match_operator 2 "compare_operator"
10643 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10645 (set (match_operand:SI 1 "nonimmediate_operand" "")
10646 (not:SI (match_dup 3)))]
10647 "ix86_match_ccmode (insn, CCNOmode)"
10648 [(parallel [(set (match_dup 0)
10649 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10652 (xor:SI (match_dup 3) (const_int -1)))])]
10655 ;; ??? Currently never generated - xor is used instead.
10656 (define_insn "*one_cmplsi2_2_zext"
10657 [(set (reg FLAGS_REG)
10658 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10660 (set (match_operand:DI 0 "register_operand" "=r")
10661 (zero_extend:DI (not:SI (match_dup 1))))]
10662 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10663 && ix86_unary_operator_ok (NOT, SImode, operands)"
10665 [(set_attr "type" "alu1")
10666 (set_attr "mode" "SI")])
10669 [(set (match_operand 0 "flags_reg_operand" "")
10670 (match_operator 2 "compare_operator"
10671 [(not:SI (match_operand:SI 3 "register_operand" ""))
10673 (set (match_operand:DI 1 "register_operand" "")
10674 (zero_extend:DI (not:SI (match_dup 3))))]
10675 "ix86_match_ccmode (insn, CCNOmode)"
10676 [(parallel [(set (match_dup 0)
10677 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10680 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10683 (define_expand "one_cmplhi2"
10684 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10685 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10686 "TARGET_HIMODE_MATH"
10687 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10689 (define_insn "*one_cmplhi2_1"
10690 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10691 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10692 "ix86_unary_operator_ok (NOT, HImode, operands)"
10694 [(set_attr "type" "negnot")
10695 (set_attr "mode" "HI")])
10697 (define_insn "*one_cmplhi2_2"
10698 [(set (reg FLAGS_REG)
10699 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10701 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10702 (not:HI (match_dup 1)))]
10703 "ix86_match_ccmode (insn, CCNOmode)
10704 && ix86_unary_operator_ok (NEG, HImode, operands)"
10706 [(set_attr "type" "alu1")
10707 (set_attr "mode" "HI")])
10710 [(set (match_operand 0 "flags_reg_operand" "")
10711 (match_operator 2 "compare_operator"
10712 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10714 (set (match_operand:HI 1 "nonimmediate_operand" "")
10715 (not:HI (match_dup 3)))]
10716 "ix86_match_ccmode (insn, CCNOmode)"
10717 [(parallel [(set (match_dup 0)
10718 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10721 (xor:HI (match_dup 3) (const_int -1)))])]
10724 ;; %%% Potential partial reg stall on alternative 1. What to do?
10725 (define_expand "one_cmplqi2"
10726 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10727 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10728 "TARGET_QIMODE_MATH"
10729 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10731 (define_insn "*one_cmplqi2_1"
10732 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10733 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10734 "ix86_unary_operator_ok (NOT, QImode, operands)"
10738 [(set_attr "type" "negnot")
10739 (set_attr "mode" "QI,SI")])
10741 (define_insn "*one_cmplqi2_2"
10742 [(set (reg FLAGS_REG)
10743 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10745 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10746 (not:QI (match_dup 1)))]
10747 "ix86_match_ccmode (insn, CCNOmode)
10748 && ix86_unary_operator_ok (NOT, QImode, operands)"
10750 [(set_attr "type" "alu1")
10751 (set_attr "mode" "QI")])
10754 [(set (match_operand 0 "flags_reg_operand" "")
10755 (match_operator 2 "compare_operator"
10756 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10758 (set (match_operand:QI 1 "nonimmediate_operand" "")
10759 (not:QI (match_dup 3)))]
10760 "ix86_match_ccmode (insn, CCNOmode)"
10761 [(parallel [(set (match_dup 0)
10762 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10765 (xor:QI (match_dup 3) (const_int -1)))])]
10768 ;; Arithmetic shift instructions
10770 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10771 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10772 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10773 ;; from the assembler input.
10775 ;; This instruction shifts the target reg/mem as usual, but instead of
10776 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10777 ;; is a left shift double, bits are taken from the high order bits of
10778 ;; reg, else if the insn is a shift right double, bits are taken from the
10779 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10780 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10782 ;; Since sh[lr]d does not change the `reg' operand, that is done
10783 ;; separately, making all shifts emit pairs of shift double and normal
10784 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10785 ;; support a 63 bit shift, each shift where the count is in a reg expands
10786 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10788 ;; If the shift count is a constant, we need never emit more than one
10789 ;; shift pair, instead using moves and sign extension for counts greater
10792 (define_expand "ashlti3"
10793 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10794 (ashift:TI (match_operand:TI 1 "register_operand" "")
10795 (match_operand:QI 2 "nonmemory_operand" "")))
10796 (clobber (reg:CC FLAGS_REG))])]
10799 if (! immediate_operand (operands[2], QImode))
10801 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10804 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10808 (define_insn "ashlti3_1"
10809 [(set (match_operand:TI 0 "register_operand" "=r")
10810 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10811 (match_operand:QI 2 "register_operand" "c")))
10812 (clobber (match_scratch:DI 3 "=&r"))
10813 (clobber (reg:CC FLAGS_REG))]
10816 [(set_attr "type" "multi")])
10818 ;; This pattern must be defined before *ashlti3_2 to prevent
10819 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10821 (define_insn "sse2_ashlti3"
10822 [(set (match_operand:TI 0 "register_operand" "=x")
10823 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10824 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10827 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10828 return "pslldq\t{%2, %0|%0, %2}";
10830 [(set_attr "type" "sseishft")
10831 (set_attr "prefix_data16" "1")
10832 (set_attr "mode" "TI")])
10834 (define_insn "*ashlti3_2"
10835 [(set (match_operand:TI 0 "register_operand" "=r")
10836 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10837 (match_operand:QI 2 "immediate_operand" "O")))
10838 (clobber (reg:CC FLAGS_REG))]
10841 [(set_attr "type" "multi")])
10844 [(set (match_operand:TI 0 "register_operand" "")
10845 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10846 (match_operand:QI 2 "register_operand" "")))
10847 (clobber (match_scratch:DI 3 ""))
10848 (clobber (reg:CC FLAGS_REG))]
10849 "TARGET_64BIT && reload_completed"
10851 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10854 [(set (match_operand:TI 0 "register_operand" "")
10855 (ashift:TI (match_operand:TI 1 "register_operand" "")
10856 (match_operand:QI 2 "immediate_operand" "")))
10857 (clobber (reg:CC FLAGS_REG))]
10858 "TARGET_64BIT && reload_completed"
10860 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10862 (define_insn "x86_64_shld"
10863 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10864 (ior:DI (ashift:DI (match_dup 0)
10865 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10866 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10867 (minus:QI (const_int 64) (match_dup 2)))))
10868 (clobber (reg:CC FLAGS_REG))]
10871 shld{q}\t{%2, %1, %0|%0, %1, %2}
10872 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10873 [(set_attr "type" "ishift")
10874 (set_attr "prefix_0f" "1")
10875 (set_attr "mode" "DI")
10876 (set_attr "athlon_decode" "vector")
10877 (set_attr "amdfam10_decode" "vector")])
10879 (define_expand "x86_64_shift_adj"
10880 [(set (reg:CCZ FLAGS_REG)
10881 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10884 (set (match_operand:DI 0 "register_operand" "")
10885 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10886 (match_operand:DI 1 "register_operand" "")
10889 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10890 (match_operand:DI 3 "register_operand" "r")
10895 (define_expand "ashldi3"
10896 [(set (match_operand:DI 0 "shiftdi_operand" "")
10897 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10898 (match_operand:QI 2 "nonmemory_operand" "")))]
10900 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10902 (define_insn "*ashldi3_1_rex64"
10903 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10904 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10905 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10906 (clobber (reg:CC FLAGS_REG))]
10907 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10909 switch (get_attr_type (insn))
10912 gcc_assert (operands[2] == const1_rtx);
10913 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10914 return "add{q}\t%0, %0";
10917 gcc_assert (CONST_INT_P (operands[2]));
10918 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10919 operands[1] = gen_rtx_MULT (DImode, operands[1],
10920 GEN_INT (1 << INTVAL (operands[2])));
10921 return "lea{q}\t{%a1, %0|%0, %a1}";
10924 if (REG_P (operands[2]))
10925 return "sal{q}\t{%b2, %0|%0, %b2}";
10926 else if (operands[2] == const1_rtx
10927 && (TARGET_SHIFT1 || optimize_size))
10928 return "sal{q}\t%0";
10930 return "sal{q}\t{%2, %0|%0, %2}";
10933 [(set (attr "type")
10934 (cond [(eq_attr "alternative" "1")
10935 (const_string "lea")
10936 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10938 (match_operand 0 "register_operand" ""))
10939 (match_operand 2 "const1_operand" ""))
10940 (const_string "alu")
10942 (const_string "ishift")))
10943 (set_attr "mode" "DI")])
10945 ;; Convert lea to the lea pattern to avoid flags dependency.
10947 [(set (match_operand:DI 0 "register_operand" "")
10948 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10949 (match_operand:QI 2 "immediate_operand" "")))
10950 (clobber (reg:CC FLAGS_REG))]
10951 "TARGET_64BIT && reload_completed
10952 && true_regnum (operands[0]) != true_regnum (operands[1])"
10953 [(set (match_dup 0)
10954 (mult:DI (match_dup 1)
10956 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10958 ;; This pattern can't accept a variable shift count, since shifts by
10959 ;; zero don't affect the flags. We assume that shifts by constant
10960 ;; zero are optimized away.
10961 (define_insn "*ashldi3_cmp_rex64"
10962 [(set (reg FLAGS_REG)
10964 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10965 (match_operand:QI 2 "immediate_operand" "e"))
10967 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10968 (ashift:DI (match_dup 1) (match_dup 2)))]
10971 || !TARGET_PARTIAL_FLAG_REG_STALL
10972 || (operands[2] == const1_rtx
10974 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10975 && ix86_match_ccmode (insn, CCGOCmode)
10976 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10978 switch (get_attr_type (insn))
10981 gcc_assert (operands[2] == const1_rtx);
10982 return "add{q}\t%0, %0";
10985 if (REG_P (operands[2]))
10986 return "sal{q}\t{%b2, %0|%0, %b2}";
10987 else if (operands[2] == const1_rtx
10988 && (TARGET_SHIFT1 || optimize_size))
10989 return "sal{q}\t%0";
10991 return "sal{q}\t{%2, %0|%0, %2}";
10994 [(set (attr "type")
10995 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10997 (match_operand 0 "register_operand" ""))
10998 (match_operand 2 "const1_operand" ""))
10999 (const_string "alu")
11001 (const_string "ishift")))
11002 (set_attr "mode" "DI")])
11004 (define_insn "*ashldi3_cconly_rex64"
11005 [(set (reg FLAGS_REG)
11007 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11008 (match_operand:QI 2 "immediate_operand" "e"))
11010 (clobber (match_scratch:DI 0 "=r"))]
11013 || !TARGET_PARTIAL_FLAG_REG_STALL
11014 || (operands[2] == const1_rtx
11016 || TARGET_DOUBLE_WITH_ADD)))
11017 && ix86_match_ccmode (insn, CCGOCmode)
11018 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11020 switch (get_attr_type (insn))
11023 gcc_assert (operands[2] == const1_rtx);
11024 return "add{q}\t%0, %0";
11027 if (REG_P (operands[2]))
11028 return "sal{q}\t{%b2, %0|%0, %b2}";
11029 else if (operands[2] == const1_rtx
11030 && (TARGET_SHIFT1 || optimize_size))
11031 return "sal{q}\t%0";
11033 return "sal{q}\t{%2, %0|%0, %2}";
11036 [(set (attr "type")
11037 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11039 (match_operand 0 "register_operand" ""))
11040 (match_operand 2 "const1_operand" ""))
11041 (const_string "alu")
11043 (const_string "ishift")))
11044 (set_attr "mode" "DI")])
11046 (define_insn "*ashldi3_1"
11047 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11048 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11049 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11050 (clobber (reg:CC FLAGS_REG))]
11053 [(set_attr "type" "multi")])
11055 ;; By default we don't ask for a scratch register, because when DImode
11056 ;; values are manipulated, registers are already at a premium. But if
11057 ;; we have one handy, we won't turn it away.
11059 [(match_scratch:SI 3 "r")
11060 (parallel [(set (match_operand:DI 0 "register_operand" "")
11061 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11062 (match_operand:QI 2 "nonmemory_operand" "")))
11063 (clobber (reg:CC FLAGS_REG))])
11065 "!TARGET_64BIT && TARGET_CMOVE"
11067 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11070 [(set (match_operand:DI 0 "register_operand" "")
11071 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11072 (match_operand:QI 2 "nonmemory_operand" "")))
11073 (clobber (reg:CC FLAGS_REG))]
11074 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11075 ? epilogue_completed : reload_completed)"
11077 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11079 (define_insn "x86_shld_1"
11080 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11081 (ior:SI (ashift:SI (match_dup 0)
11082 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11083 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11084 (minus:QI (const_int 32) (match_dup 2)))))
11085 (clobber (reg:CC FLAGS_REG))]
11088 shld{l}\t{%2, %1, %0|%0, %1, %2}
11089 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11090 [(set_attr "type" "ishift")
11091 (set_attr "prefix_0f" "1")
11092 (set_attr "mode" "SI")
11093 (set_attr "pent_pair" "np")
11094 (set_attr "athlon_decode" "vector")
11095 (set_attr "amdfam10_decode" "vector")])
11097 (define_expand "x86_shift_adj_1"
11098 [(set (reg:CCZ FLAGS_REG)
11099 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11102 (set (match_operand:SI 0 "register_operand" "")
11103 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11104 (match_operand:SI 1 "register_operand" "")
11107 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11108 (match_operand:SI 3 "register_operand" "r")
11113 (define_expand "x86_shift_adj_2"
11114 [(use (match_operand:SI 0 "register_operand" ""))
11115 (use (match_operand:SI 1 "register_operand" ""))
11116 (use (match_operand:QI 2 "register_operand" ""))]
11119 rtx label = gen_label_rtx ();
11122 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11124 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11125 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11126 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11127 gen_rtx_LABEL_REF (VOIDmode, label),
11129 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11130 JUMP_LABEL (tmp) = label;
11132 emit_move_insn (operands[0], operands[1]);
11133 ix86_expand_clear (operands[1]);
11135 emit_label (label);
11136 LABEL_NUSES (label) = 1;
11141 (define_expand "ashlsi3"
11142 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11143 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11144 (match_operand:QI 2 "nonmemory_operand" "")))
11145 (clobber (reg:CC FLAGS_REG))]
11147 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11149 (define_insn "*ashlsi3_1"
11150 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11151 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11152 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11153 (clobber (reg:CC FLAGS_REG))]
11154 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11156 switch (get_attr_type (insn))
11159 gcc_assert (operands[2] == const1_rtx);
11160 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11161 return "add{l}\t%0, %0";
11167 if (REG_P (operands[2]))
11168 return "sal{l}\t{%b2, %0|%0, %b2}";
11169 else if (operands[2] == const1_rtx
11170 && (TARGET_SHIFT1 || optimize_size))
11171 return "sal{l}\t%0";
11173 return "sal{l}\t{%2, %0|%0, %2}";
11176 [(set (attr "type")
11177 (cond [(eq_attr "alternative" "1")
11178 (const_string "lea")
11179 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11181 (match_operand 0 "register_operand" ""))
11182 (match_operand 2 "const1_operand" ""))
11183 (const_string "alu")
11185 (const_string "ishift")))
11186 (set_attr "mode" "SI")])
11188 ;; Convert lea to the lea pattern to avoid flags dependency.
11190 [(set (match_operand 0 "register_operand" "")
11191 (ashift (match_operand 1 "index_register_operand" "")
11192 (match_operand:QI 2 "const_int_operand" "")))
11193 (clobber (reg:CC FLAGS_REG))]
11195 && true_regnum (operands[0]) != true_regnum (operands[1])
11196 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11200 enum machine_mode mode = GET_MODE (operands[0]);
11202 if (GET_MODE_SIZE (mode) < 4)
11203 operands[0] = gen_lowpart (SImode, operands[0]);
11205 operands[1] = gen_lowpart (Pmode, operands[1]);
11206 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11208 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11209 if (Pmode != SImode)
11210 pat = gen_rtx_SUBREG (SImode, pat, 0);
11211 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11215 ;; Rare case of shifting RSP is handled by generating move and shift
11217 [(set (match_operand 0 "register_operand" "")
11218 (ashift (match_operand 1 "register_operand" "")
11219 (match_operand:QI 2 "const_int_operand" "")))
11220 (clobber (reg:CC FLAGS_REG))]
11222 && true_regnum (operands[0]) != true_regnum (operands[1])"
11226 emit_move_insn (operands[0], operands[1]);
11227 pat = gen_rtx_SET (VOIDmode, operands[0],
11228 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11229 operands[0], operands[2]));
11230 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11231 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11235 (define_insn "*ashlsi3_1_zext"
11236 [(set (match_operand:DI 0 "register_operand" "=r,r")
11237 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11238 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11239 (clobber (reg:CC FLAGS_REG))]
11240 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11242 switch (get_attr_type (insn))
11245 gcc_assert (operands[2] == const1_rtx);
11246 return "add{l}\t%k0, %k0";
11252 if (REG_P (operands[2]))
11253 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11254 else if (operands[2] == const1_rtx
11255 && (TARGET_SHIFT1 || optimize_size))
11256 return "sal{l}\t%k0";
11258 return "sal{l}\t{%2, %k0|%k0, %2}";
11261 [(set (attr "type")
11262 (cond [(eq_attr "alternative" "1")
11263 (const_string "lea")
11264 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11266 (match_operand 2 "const1_operand" ""))
11267 (const_string "alu")
11269 (const_string "ishift")))
11270 (set_attr "mode" "SI")])
11272 ;; Convert lea to the lea pattern to avoid flags dependency.
11274 [(set (match_operand:DI 0 "register_operand" "")
11275 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11276 (match_operand:QI 2 "const_int_operand" ""))))
11277 (clobber (reg:CC FLAGS_REG))]
11278 "TARGET_64BIT && reload_completed
11279 && true_regnum (operands[0]) != true_regnum (operands[1])"
11280 [(set (match_dup 0) (zero_extend:DI
11281 (subreg:SI (mult:SI (match_dup 1)
11282 (match_dup 2)) 0)))]
11284 operands[1] = gen_lowpart (Pmode, operands[1]);
11285 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11288 ;; This pattern can't accept a variable shift count, since shifts by
11289 ;; zero don't affect the flags. We assume that shifts by constant
11290 ;; zero are optimized away.
11291 (define_insn "*ashlsi3_cmp"
11292 [(set (reg FLAGS_REG)
11294 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11295 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11297 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11298 (ashift:SI (match_dup 1) (match_dup 2)))]
11300 || !TARGET_PARTIAL_FLAG_REG_STALL
11301 || (operands[2] == const1_rtx
11303 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11304 && ix86_match_ccmode (insn, CCGOCmode)
11305 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11307 switch (get_attr_type (insn))
11310 gcc_assert (operands[2] == const1_rtx);
11311 return "add{l}\t%0, %0";
11314 if (REG_P (operands[2]))
11315 return "sal{l}\t{%b2, %0|%0, %b2}";
11316 else if (operands[2] == const1_rtx
11317 && (TARGET_SHIFT1 || optimize_size))
11318 return "sal{l}\t%0";
11320 return "sal{l}\t{%2, %0|%0, %2}";
11323 [(set (attr "type")
11324 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11326 (match_operand 0 "register_operand" ""))
11327 (match_operand 2 "const1_operand" ""))
11328 (const_string "alu")
11330 (const_string "ishift")))
11331 (set_attr "mode" "SI")])
11333 (define_insn "*ashlsi3_cconly"
11334 [(set (reg FLAGS_REG)
11336 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11337 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11339 (clobber (match_scratch:SI 0 "=r"))]
11341 || !TARGET_PARTIAL_FLAG_REG_STALL
11342 || (operands[2] == const1_rtx
11344 || TARGET_DOUBLE_WITH_ADD)))
11345 && ix86_match_ccmode (insn, CCGOCmode)
11346 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11348 switch (get_attr_type (insn))
11351 gcc_assert (operands[2] == const1_rtx);
11352 return "add{l}\t%0, %0";
11355 if (REG_P (operands[2]))
11356 return "sal{l}\t{%b2, %0|%0, %b2}";
11357 else if (operands[2] == const1_rtx
11358 && (TARGET_SHIFT1 || optimize_size))
11359 return "sal{l}\t%0";
11361 return "sal{l}\t{%2, %0|%0, %2}";
11364 [(set (attr "type")
11365 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11367 (match_operand 0 "register_operand" ""))
11368 (match_operand 2 "const1_operand" ""))
11369 (const_string "alu")
11371 (const_string "ishift")))
11372 (set_attr "mode" "SI")])
11374 (define_insn "*ashlsi3_cmp_zext"
11375 [(set (reg FLAGS_REG)
11377 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11378 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11380 (set (match_operand:DI 0 "register_operand" "=r")
11381 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11384 || !TARGET_PARTIAL_FLAG_REG_STALL
11385 || (operands[2] == const1_rtx
11387 || TARGET_DOUBLE_WITH_ADD)))
11388 && ix86_match_ccmode (insn, CCGOCmode)
11389 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11391 switch (get_attr_type (insn))
11394 gcc_assert (operands[2] == const1_rtx);
11395 return "add{l}\t%k0, %k0";
11398 if (REG_P (operands[2]))
11399 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11400 else if (operands[2] == const1_rtx
11401 && (TARGET_SHIFT1 || optimize_size))
11402 return "sal{l}\t%k0";
11404 return "sal{l}\t{%2, %k0|%k0, %2}";
11407 [(set (attr "type")
11408 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11410 (match_operand 2 "const1_operand" ""))
11411 (const_string "alu")
11413 (const_string "ishift")))
11414 (set_attr "mode" "SI")])
11416 (define_expand "ashlhi3"
11417 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11418 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11419 (match_operand:QI 2 "nonmemory_operand" "")))
11420 (clobber (reg:CC FLAGS_REG))]
11421 "TARGET_HIMODE_MATH"
11422 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11424 (define_insn "*ashlhi3_1_lea"
11425 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11426 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11427 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11428 (clobber (reg:CC FLAGS_REG))]
11429 "!TARGET_PARTIAL_REG_STALL
11430 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11432 switch (get_attr_type (insn))
11437 gcc_assert (operands[2] == const1_rtx);
11438 return "add{w}\t%0, %0";
11441 if (REG_P (operands[2]))
11442 return "sal{w}\t{%b2, %0|%0, %b2}";
11443 else if (operands[2] == const1_rtx
11444 && (TARGET_SHIFT1 || optimize_size))
11445 return "sal{w}\t%0";
11447 return "sal{w}\t{%2, %0|%0, %2}";
11450 [(set (attr "type")
11451 (cond [(eq_attr "alternative" "1")
11452 (const_string "lea")
11453 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11455 (match_operand 0 "register_operand" ""))
11456 (match_operand 2 "const1_operand" ""))
11457 (const_string "alu")
11459 (const_string "ishift")))
11460 (set_attr "mode" "HI,SI")])
11462 (define_insn "*ashlhi3_1"
11463 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11464 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11465 (match_operand:QI 2 "nonmemory_operand" "cI")))
11466 (clobber (reg:CC FLAGS_REG))]
11467 "TARGET_PARTIAL_REG_STALL
11468 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11470 switch (get_attr_type (insn))
11473 gcc_assert (operands[2] == const1_rtx);
11474 return "add{w}\t%0, %0";
11477 if (REG_P (operands[2]))
11478 return "sal{w}\t{%b2, %0|%0, %b2}";
11479 else if (operands[2] == const1_rtx
11480 && (TARGET_SHIFT1 || optimize_size))
11481 return "sal{w}\t%0";
11483 return "sal{w}\t{%2, %0|%0, %2}";
11486 [(set (attr "type")
11487 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11489 (match_operand 0 "register_operand" ""))
11490 (match_operand 2 "const1_operand" ""))
11491 (const_string "alu")
11493 (const_string "ishift")))
11494 (set_attr "mode" "HI")])
11496 ;; This pattern can't accept a variable shift count, since shifts by
11497 ;; zero don't affect the flags. We assume that shifts by constant
11498 ;; zero are optimized away.
11499 (define_insn "*ashlhi3_cmp"
11500 [(set (reg FLAGS_REG)
11502 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11503 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11505 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11506 (ashift:HI (match_dup 1) (match_dup 2)))]
11508 || !TARGET_PARTIAL_FLAG_REG_STALL
11509 || (operands[2] == const1_rtx
11511 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11512 && ix86_match_ccmode (insn, CCGOCmode)
11513 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11515 switch (get_attr_type (insn))
11518 gcc_assert (operands[2] == const1_rtx);
11519 return "add{w}\t%0, %0";
11522 if (REG_P (operands[2]))
11523 return "sal{w}\t{%b2, %0|%0, %b2}";
11524 else if (operands[2] == const1_rtx
11525 && (TARGET_SHIFT1 || optimize_size))
11526 return "sal{w}\t%0";
11528 return "sal{w}\t{%2, %0|%0, %2}";
11531 [(set (attr "type")
11532 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11534 (match_operand 0 "register_operand" ""))
11535 (match_operand 2 "const1_operand" ""))
11536 (const_string "alu")
11538 (const_string "ishift")))
11539 (set_attr "mode" "HI")])
11541 (define_insn "*ashlhi3_cconly"
11542 [(set (reg FLAGS_REG)
11544 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11545 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11547 (clobber (match_scratch:HI 0 "=r"))]
11549 || !TARGET_PARTIAL_FLAG_REG_STALL
11550 || (operands[2] == const1_rtx
11552 || TARGET_DOUBLE_WITH_ADD)))
11553 && ix86_match_ccmode (insn, CCGOCmode)
11554 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11556 switch (get_attr_type (insn))
11559 gcc_assert (operands[2] == const1_rtx);
11560 return "add{w}\t%0, %0";
11563 if (REG_P (operands[2]))
11564 return "sal{w}\t{%b2, %0|%0, %b2}";
11565 else if (operands[2] == const1_rtx
11566 && (TARGET_SHIFT1 || optimize_size))
11567 return "sal{w}\t%0";
11569 return "sal{w}\t{%2, %0|%0, %2}";
11572 [(set (attr "type")
11573 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11575 (match_operand 0 "register_operand" ""))
11576 (match_operand 2 "const1_operand" ""))
11577 (const_string "alu")
11579 (const_string "ishift")))
11580 (set_attr "mode" "HI")])
11582 (define_expand "ashlqi3"
11583 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11584 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11585 (match_operand:QI 2 "nonmemory_operand" "")))
11586 (clobber (reg:CC FLAGS_REG))]
11587 "TARGET_QIMODE_MATH"
11588 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11590 ;; %%% Potential partial reg stall on alternative 2. What to do?
11592 (define_insn "*ashlqi3_1_lea"
11593 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11594 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11595 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11596 (clobber (reg:CC FLAGS_REG))]
11597 "!TARGET_PARTIAL_REG_STALL
11598 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11600 switch (get_attr_type (insn))
11605 gcc_assert (operands[2] == const1_rtx);
11606 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11607 return "add{l}\t%k0, %k0";
11609 return "add{b}\t%0, %0";
11612 if (REG_P (operands[2]))
11614 if (get_attr_mode (insn) == MODE_SI)
11615 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11617 return "sal{b}\t{%b2, %0|%0, %b2}";
11619 else if (operands[2] == const1_rtx
11620 && (TARGET_SHIFT1 || optimize_size))
11622 if (get_attr_mode (insn) == MODE_SI)
11623 return "sal{l}\t%0";
11625 return "sal{b}\t%0";
11629 if (get_attr_mode (insn) == MODE_SI)
11630 return "sal{l}\t{%2, %k0|%k0, %2}";
11632 return "sal{b}\t{%2, %0|%0, %2}";
11636 [(set (attr "type")
11637 (cond [(eq_attr "alternative" "2")
11638 (const_string "lea")
11639 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11641 (match_operand 0 "register_operand" ""))
11642 (match_operand 2 "const1_operand" ""))
11643 (const_string "alu")
11645 (const_string "ishift")))
11646 (set_attr "mode" "QI,SI,SI")])
11648 (define_insn "*ashlqi3_1"
11649 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11650 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11651 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11652 (clobber (reg:CC FLAGS_REG))]
11653 "TARGET_PARTIAL_REG_STALL
11654 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11656 switch (get_attr_type (insn))
11659 gcc_assert (operands[2] == const1_rtx);
11660 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11661 return "add{l}\t%k0, %k0";
11663 return "add{b}\t%0, %0";
11666 if (REG_P (operands[2]))
11668 if (get_attr_mode (insn) == MODE_SI)
11669 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11671 return "sal{b}\t{%b2, %0|%0, %b2}";
11673 else if (operands[2] == const1_rtx
11674 && (TARGET_SHIFT1 || optimize_size))
11676 if (get_attr_mode (insn) == MODE_SI)
11677 return "sal{l}\t%0";
11679 return "sal{b}\t%0";
11683 if (get_attr_mode (insn) == MODE_SI)
11684 return "sal{l}\t{%2, %k0|%k0, %2}";
11686 return "sal{b}\t{%2, %0|%0, %2}";
11690 [(set (attr "type")
11691 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11693 (match_operand 0 "register_operand" ""))
11694 (match_operand 2 "const1_operand" ""))
11695 (const_string "alu")
11697 (const_string "ishift")))
11698 (set_attr "mode" "QI,SI")])
11700 ;; This pattern can't accept a variable shift count, since shifts by
11701 ;; zero don't affect the flags. We assume that shifts by constant
11702 ;; zero are optimized away.
11703 (define_insn "*ashlqi3_cmp"
11704 [(set (reg FLAGS_REG)
11706 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11707 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11709 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11710 (ashift:QI (match_dup 1) (match_dup 2)))]
11712 || !TARGET_PARTIAL_FLAG_REG_STALL
11713 || (operands[2] == const1_rtx
11715 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11716 && ix86_match_ccmode (insn, CCGOCmode)
11717 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11719 switch (get_attr_type (insn))
11722 gcc_assert (operands[2] == const1_rtx);
11723 return "add{b}\t%0, %0";
11726 if (REG_P (operands[2]))
11727 return "sal{b}\t{%b2, %0|%0, %b2}";
11728 else if (operands[2] == const1_rtx
11729 && (TARGET_SHIFT1 || optimize_size))
11730 return "sal{b}\t%0";
11732 return "sal{b}\t{%2, %0|%0, %2}";
11735 [(set (attr "type")
11736 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11738 (match_operand 0 "register_operand" ""))
11739 (match_operand 2 "const1_operand" ""))
11740 (const_string "alu")
11742 (const_string "ishift")))
11743 (set_attr "mode" "QI")])
11745 (define_insn "*ashlqi3_cconly"
11746 [(set (reg FLAGS_REG)
11748 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11749 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11751 (clobber (match_scratch:QI 0 "=q"))]
11753 || !TARGET_PARTIAL_FLAG_REG_STALL
11754 || (operands[2] == const1_rtx
11756 || TARGET_DOUBLE_WITH_ADD)))
11757 && ix86_match_ccmode (insn, CCGOCmode)
11758 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11760 switch (get_attr_type (insn))
11763 gcc_assert (operands[2] == const1_rtx);
11764 return "add{b}\t%0, %0";
11767 if (REG_P (operands[2]))
11768 return "sal{b}\t{%b2, %0|%0, %b2}";
11769 else if (operands[2] == const1_rtx
11770 && (TARGET_SHIFT1 || optimize_size))
11771 return "sal{b}\t%0";
11773 return "sal{b}\t{%2, %0|%0, %2}";
11776 [(set (attr "type")
11777 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11779 (match_operand 0 "register_operand" ""))
11780 (match_operand 2 "const1_operand" ""))
11781 (const_string "alu")
11783 (const_string "ishift")))
11784 (set_attr "mode" "QI")])
11786 ;; See comment above `ashldi3' about how this works.
11788 (define_expand "ashrti3"
11789 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11790 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11791 (match_operand:QI 2 "nonmemory_operand" "")))
11792 (clobber (reg:CC FLAGS_REG))])]
11795 if (! immediate_operand (operands[2], QImode))
11797 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11800 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11804 (define_insn "ashrti3_1"
11805 [(set (match_operand:TI 0 "register_operand" "=r")
11806 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11807 (match_operand:QI 2 "register_operand" "c")))
11808 (clobber (match_scratch:DI 3 "=&r"))
11809 (clobber (reg:CC FLAGS_REG))]
11812 [(set_attr "type" "multi")])
11814 (define_insn "*ashrti3_2"
11815 [(set (match_operand:TI 0 "register_operand" "=r")
11816 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11817 (match_operand:QI 2 "immediate_operand" "O")))
11818 (clobber (reg:CC FLAGS_REG))]
11821 [(set_attr "type" "multi")])
11824 [(set (match_operand:TI 0 "register_operand" "")
11825 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11826 (match_operand:QI 2 "register_operand" "")))
11827 (clobber (match_scratch:DI 3 ""))
11828 (clobber (reg:CC FLAGS_REG))]
11829 "TARGET_64BIT && reload_completed"
11831 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11834 [(set (match_operand:TI 0 "register_operand" "")
11835 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11836 (match_operand:QI 2 "immediate_operand" "")))
11837 (clobber (reg:CC FLAGS_REG))]
11838 "TARGET_64BIT && reload_completed"
11840 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11842 (define_insn "x86_64_shrd"
11843 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11844 (ior:DI (ashiftrt:DI (match_dup 0)
11845 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11846 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11847 (minus:QI (const_int 64) (match_dup 2)))))
11848 (clobber (reg:CC FLAGS_REG))]
11851 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11852 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11853 [(set_attr "type" "ishift")
11854 (set_attr "prefix_0f" "1")
11855 (set_attr "mode" "DI")
11856 (set_attr "athlon_decode" "vector")
11857 (set_attr "amdfam10_decode" "vector")])
11859 (define_expand "ashrdi3"
11860 [(set (match_operand:DI 0 "shiftdi_operand" "")
11861 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11862 (match_operand:QI 2 "nonmemory_operand" "")))]
11864 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11866 (define_insn "*ashrdi3_63_rex64"
11867 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11868 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11869 (match_operand:DI 2 "const_int_operand" "i,i")))
11870 (clobber (reg:CC FLAGS_REG))]
11871 "TARGET_64BIT && INTVAL (operands[2]) == 63
11872 && (TARGET_USE_CLTD || optimize_size)
11873 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11876 sar{q}\t{%2, %0|%0, %2}"
11877 [(set_attr "type" "imovx,ishift")
11878 (set_attr "prefix_0f" "0,*")
11879 (set_attr "length_immediate" "0,*")
11880 (set_attr "modrm" "0,1")
11881 (set_attr "mode" "DI")])
11883 (define_insn "*ashrdi3_1_one_bit_rex64"
11884 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11885 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11886 (match_operand:QI 2 "const1_operand" "")))
11887 (clobber (reg:CC FLAGS_REG))]
11889 && (TARGET_SHIFT1 || optimize_size)
11890 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11892 [(set_attr "type" "ishift")
11893 (set (attr "length")
11894 (if_then_else (match_operand:DI 0 "register_operand" "")
11896 (const_string "*")))])
11898 (define_insn "*ashrdi3_1_rex64"
11899 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11900 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11901 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11902 (clobber (reg:CC FLAGS_REG))]
11903 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11905 sar{q}\t{%2, %0|%0, %2}
11906 sar{q}\t{%b2, %0|%0, %b2}"
11907 [(set_attr "type" "ishift")
11908 (set_attr "mode" "DI")])
11910 ;; This pattern can't accept a variable shift count, since shifts by
11911 ;; zero don't affect the flags. We assume that shifts by constant
11912 ;; zero are optimized away.
11913 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11914 [(set (reg FLAGS_REG)
11916 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11917 (match_operand:QI 2 "const1_operand" ""))
11919 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11920 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11922 && (TARGET_SHIFT1 || optimize_size)
11923 && ix86_match_ccmode (insn, CCGOCmode)
11924 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11926 [(set_attr "type" "ishift")
11927 (set (attr "length")
11928 (if_then_else (match_operand:DI 0 "register_operand" "")
11930 (const_string "*")))])
11932 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11933 [(set (reg FLAGS_REG)
11935 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11936 (match_operand:QI 2 "const1_operand" ""))
11938 (clobber (match_scratch:DI 0 "=r"))]
11940 && (TARGET_SHIFT1 || optimize_size)
11941 && ix86_match_ccmode (insn, CCGOCmode)
11942 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11944 [(set_attr "type" "ishift")
11945 (set_attr "length" "2")])
11947 ;; This pattern can't accept a variable shift count, since shifts by
11948 ;; zero don't affect the flags. We assume that shifts by constant
11949 ;; zero are optimized away.
11950 (define_insn "*ashrdi3_cmp_rex64"
11951 [(set (reg FLAGS_REG)
11953 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11954 (match_operand:QI 2 "const_int_operand" "n"))
11956 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11957 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11959 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11960 && ix86_match_ccmode (insn, CCGOCmode)
11961 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11962 "sar{q}\t{%2, %0|%0, %2}"
11963 [(set_attr "type" "ishift")
11964 (set_attr "mode" "DI")])
11966 (define_insn "*ashrdi3_cconly_rex64"
11967 [(set (reg FLAGS_REG)
11969 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11970 (match_operand:QI 2 "const_int_operand" "n"))
11972 (clobber (match_scratch:DI 0 "=r"))]
11974 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11975 && ix86_match_ccmode (insn, CCGOCmode)
11976 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11977 "sar{q}\t{%2, %0|%0, %2}"
11978 [(set_attr "type" "ishift")
11979 (set_attr "mode" "DI")])
11981 (define_insn "*ashrdi3_1"
11982 [(set (match_operand:DI 0 "register_operand" "=r")
11983 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11984 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11985 (clobber (reg:CC FLAGS_REG))]
11988 [(set_attr "type" "multi")])
11990 ;; By default we don't ask for a scratch register, because when DImode
11991 ;; values are manipulated, registers are already at a premium. But if
11992 ;; we have one handy, we won't turn it away.
11994 [(match_scratch:SI 3 "r")
11995 (parallel [(set (match_operand:DI 0 "register_operand" "")
11996 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11997 (match_operand:QI 2 "nonmemory_operand" "")))
11998 (clobber (reg:CC FLAGS_REG))])
12000 "!TARGET_64BIT && TARGET_CMOVE"
12002 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12005 [(set (match_operand:DI 0 "register_operand" "")
12006 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12007 (match_operand:QI 2 "nonmemory_operand" "")))
12008 (clobber (reg:CC FLAGS_REG))]
12009 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12010 ? epilogue_completed : reload_completed)"
12012 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12014 (define_insn "x86_shrd_1"
12015 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12016 (ior:SI (ashiftrt:SI (match_dup 0)
12017 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12018 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12019 (minus:QI (const_int 32) (match_dup 2)))))
12020 (clobber (reg:CC FLAGS_REG))]
12023 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12024 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12025 [(set_attr "type" "ishift")
12026 (set_attr "prefix_0f" "1")
12027 (set_attr "pent_pair" "np")
12028 (set_attr "mode" "SI")])
12030 (define_expand "x86_shift_adj_3"
12031 [(use (match_operand:SI 0 "register_operand" ""))
12032 (use (match_operand:SI 1 "register_operand" ""))
12033 (use (match_operand:QI 2 "register_operand" ""))]
12036 rtx label = gen_label_rtx ();
12039 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12041 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12042 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12043 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12044 gen_rtx_LABEL_REF (VOIDmode, label),
12046 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12047 JUMP_LABEL (tmp) = label;
12049 emit_move_insn (operands[0], operands[1]);
12050 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12052 emit_label (label);
12053 LABEL_NUSES (label) = 1;
12058 (define_insn "ashrsi3_31"
12059 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12060 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12061 (match_operand:SI 2 "const_int_operand" "i,i")))
12062 (clobber (reg:CC FLAGS_REG))]
12063 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12064 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12067 sar{l}\t{%2, %0|%0, %2}"
12068 [(set_attr "type" "imovx,ishift")
12069 (set_attr "prefix_0f" "0,*")
12070 (set_attr "length_immediate" "0,*")
12071 (set_attr "modrm" "0,1")
12072 (set_attr "mode" "SI")])
12074 (define_insn "*ashrsi3_31_zext"
12075 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12076 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12077 (match_operand:SI 2 "const_int_operand" "i,i"))))
12078 (clobber (reg:CC FLAGS_REG))]
12079 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12080 && INTVAL (operands[2]) == 31
12081 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12084 sar{l}\t{%2, %k0|%k0, %2}"
12085 [(set_attr "type" "imovx,ishift")
12086 (set_attr "prefix_0f" "0,*")
12087 (set_attr "length_immediate" "0,*")
12088 (set_attr "modrm" "0,1")
12089 (set_attr "mode" "SI")])
12091 (define_expand "ashrsi3"
12092 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12093 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12094 (match_operand:QI 2 "nonmemory_operand" "")))
12095 (clobber (reg:CC FLAGS_REG))]
12097 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12099 (define_insn "*ashrsi3_1_one_bit"
12100 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12101 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12102 (match_operand:QI 2 "const1_operand" "")))
12103 (clobber (reg:CC FLAGS_REG))]
12104 "(TARGET_SHIFT1 || optimize_size)
12105 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12107 [(set_attr "type" "ishift")
12108 (set (attr "length")
12109 (if_then_else (match_operand:SI 0 "register_operand" "")
12111 (const_string "*")))])
12113 (define_insn "*ashrsi3_1_one_bit_zext"
12114 [(set (match_operand:DI 0 "register_operand" "=r")
12115 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12116 (match_operand:QI 2 "const1_operand" ""))))
12117 (clobber (reg:CC FLAGS_REG))]
12119 && (TARGET_SHIFT1 || optimize_size)
12120 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12122 [(set_attr "type" "ishift")
12123 (set_attr "length" "2")])
12125 (define_insn "*ashrsi3_1"
12126 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12127 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12128 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12129 (clobber (reg:CC FLAGS_REG))]
12130 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12132 sar{l}\t{%2, %0|%0, %2}
12133 sar{l}\t{%b2, %0|%0, %b2}"
12134 [(set_attr "type" "ishift")
12135 (set_attr "mode" "SI")])
12137 (define_insn "*ashrsi3_1_zext"
12138 [(set (match_operand:DI 0 "register_operand" "=r,r")
12139 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12140 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12141 (clobber (reg:CC FLAGS_REG))]
12142 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12144 sar{l}\t{%2, %k0|%k0, %2}
12145 sar{l}\t{%b2, %k0|%k0, %b2}"
12146 [(set_attr "type" "ishift")
12147 (set_attr "mode" "SI")])
12149 ;; This pattern can't accept a variable shift count, since shifts by
12150 ;; zero don't affect the flags. We assume that shifts by constant
12151 ;; zero are optimized away.
12152 (define_insn "*ashrsi3_one_bit_cmp"
12153 [(set (reg FLAGS_REG)
12155 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12156 (match_operand:QI 2 "const1_operand" ""))
12158 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12159 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12160 "(TARGET_SHIFT1 || optimize_size)
12161 && ix86_match_ccmode (insn, CCGOCmode)
12162 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12164 [(set_attr "type" "ishift")
12165 (set (attr "length")
12166 (if_then_else (match_operand:SI 0 "register_operand" "")
12168 (const_string "*")))])
12170 (define_insn "*ashrsi3_one_bit_cconly"
12171 [(set (reg FLAGS_REG)
12173 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12174 (match_operand:QI 2 "const1_operand" ""))
12176 (clobber (match_scratch:SI 0 "=r"))]
12177 "(TARGET_SHIFT1 || optimize_size)
12178 && ix86_match_ccmode (insn, CCGOCmode)
12179 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12181 [(set_attr "type" "ishift")
12182 (set_attr "length" "2")])
12184 (define_insn "*ashrsi3_one_bit_cmp_zext"
12185 [(set (reg FLAGS_REG)
12187 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12188 (match_operand:QI 2 "const1_operand" ""))
12190 (set (match_operand:DI 0 "register_operand" "=r")
12191 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12193 && (TARGET_SHIFT1 || optimize_size)
12194 && ix86_match_ccmode (insn, CCmode)
12195 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12197 [(set_attr "type" "ishift")
12198 (set_attr "length" "2")])
12200 ;; This pattern can't accept a variable shift count, since shifts by
12201 ;; zero don't affect the flags. We assume that shifts by constant
12202 ;; zero are optimized away.
12203 (define_insn "*ashrsi3_cmp"
12204 [(set (reg FLAGS_REG)
12206 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12207 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12209 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12210 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12211 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12212 && ix86_match_ccmode (insn, CCGOCmode)
12213 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12214 "sar{l}\t{%2, %0|%0, %2}"
12215 [(set_attr "type" "ishift")
12216 (set_attr "mode" "SI")])
12218 (define_insn "*ashrsi3_cconly"
12219 [(set (reg FLAGS_REG)
12221 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12222 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12224 (clobber (match_scratch:SI 0 "=r"))]
12225 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12226 && ix86_match_ccmode (insn, CCGOCmode)
12227 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12228 "sar{l}\t{%2, %0|%0, %2}"
12229 [(set_attr "type" "ishift")
12230 (set_attr "mode" "SI")])
12232 (define_insn "*ashrsi3_cmp_zext"
12233 [(set (reg FLAGS_REG)
12235 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12236 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12238 (set (match_operand:DI 0 "register_operand" "=r")
12239 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12241 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12242 && ix86_match_ccmode (insn, CCGOCmode)
12243 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12244 "sar{l}\t{%2, %k0|%k0, %2}"
12245 [(set_attr "type" "ishift")
12246 (set_attr "mode" "SI")])
12248 (define_expand "ashrhi3"
12249 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12250 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12251 (match_operand:QI 2 "nonmemory_operand" "")))
12252 (clobber (reg:CC FLAGS_REG))]
12253 "TARGET_HIMODE_MATH"
12254 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12256 (define_insn "*ashrhi3_1_one_bit"
12257 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12258 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12259 (match_operand:QI 2 "const1_operand" "")))
12260 (clobber (reg:CC FLAGS_REG))]
12261 "(TARGET_SHIFT1 || optimize_size)
12262 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12264 [(set_attr "type" "ishift")
12265 (set (attr "length")
12266 (if_then_else (match_operand 0 "register_operand" "")
12268 (const_string "*")))])
12270 (define_insn "*ashrhi3_1"
12271 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12272 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12273 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12274 (clobber (reg:CC FLAGS_REG))]
12275 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12277 sar{w}\t{%2, %0|%0, %2}
12278 sar{w}\t{%b2, %0|%0, %b2}"
12279 [(set_attr "type" "ishift")
12280 (set_attr "mode" "HI")])
12282 ;; This pattern can't accept a variable shift count, since shifts by
12283 ;; zero don't affect the flags. We assume that shifts by constant
12284 ;; zero are optimized away.
12285 (define_insn "*ashrhi3_one_bit_cmp"
12286 [(set (reg FLAGS_REG)
12288 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12289 (match_operand:QI 2 "const1_operand" ""))
12291 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12292 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12293 "(TARGET_SHIFT1 || optimize_size)
12294 && ix86_match_ccmode (insn, CCGOCmode)
12295 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12297 [(set_attr "type" "ishift")
12298 (set (attr "length")
12299 (if_then_else (match_operand 0 "register_operand" "")
12301 (const_string "*")))])
12303 (define_insn "*ashrhi3_one_bit_cconly"
12304 [(set (reg FLAGS_REG)
12306 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12307 (match_operand:QI 2 "const1_operand" ""))
12309 (clobber (match_scratch:HI 0 "=r"))]
12310 "(TARGET_SHIFT1 || optimize_size)
12311 && ix86_match_ccmode (insn, CCGOCmode)
12312 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12314 [(set_attr "type" "ishift")
12315 (set_attr "length" "2")])
12317 ;; This pattern can't accept a variable shift count, since shifts by
12318 ;; zero don't affect the flags. We assume that shifts by constant
12319 ;; zero are optimized away.
12320 (define_insn "*ashrhi3_cmp"
12321 [(set (reg FLAGS_REG)
12323 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12324 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12326 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12327 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12328 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12329 && ix86_match_ccmode (insn, CCGOCmode)
12330 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12331 "sar{w}\t{%2, %0|%0, %2}"
12332 [(set_attr "type" "ishift")
12333 (set_attr "mode" "HI")])
12335 (define_insn "*ashrhi3_cconly"
12336 [(set (reg FLAGS_REG)
12338 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12339 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12341 (clobber (match_scratch:HI 0 "=r"))]
12342 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12343 && ix86_match_ccmode (insn, CCGOCmode)
12344 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12345 "sar{w}\t{%2, %0|%0, %2}"
12346 [(set_attr "type" "ishift")
12347 (set_attr "mode" "HI")])
12349 (define_expand "ashrqi3"
12350 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12351 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12352 (match_operand:QI 2 "nonmemory_operand" "")))
12353 (clobber (reg:CC FLAGS_REG))]
12354 "TARGET_QIMODE_MATH"
12355 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12357 (define_insn "*ashrqi3_1_one_bit"
12358 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12359 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12360 (match_operand:QI 2 "const1_operand" "")))
12361 (clobber (reg:CC FLAGS_REG))]
12362 "(TARGET_SHIFT1 || optimize_size)
12363 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12365 [(set_attr "type" "ishift")
12366 (set (attr "length")
12367 (if_then_else (match_operand 0 "register_operand" "")
12369 (const_string "*")))])
12371 (define_insn "*ashrqi3_1_one_bit_slp"
12372 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12373 (ashiftrt:QI (match_dup 0)
12374 (match_operand:QI 1 "const1_operand" "")))
12375 (clobber (reg:CC FLAGS_REG))]
12376 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12377 && (TARGET_SHIFT1 || optimize_size)
12378 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12380 [(set_attr "type" "ishift1")
12381 (set (attr "length")
12382 (if_then_else (match_operand 0 "register_operand" "")
12384 (const_string "*")))])
12386 (define_insn "*ashrqi3_1"
12387 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12388 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12389 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12390 (clobber (reg:CC FLAGS_REG))]
12391 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12393 sar{b}\t{%2, %0|%0, %2}
12394 sar{b}\t{%b2, %0|%0, %b2}"
12395 [(set_attr "type" "ishift")
12396 (set_attr "mode" "QI")])
12398 (define_insn "*ashrqi3_1_slp"
12399 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12400 (ashiftrt:QI (match_dup 0)
12401 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12402 (clobber (reg:CC FLAGS_REG))]
12403 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12404 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12406 sar{b}\t{%1, %0|%0, %1}
12407 sar{b}\t{%b1, %0|%0, %b1}"
12408 [(set_attr "type" "ishift1")
12409 (set_attr "mode" "QI")])
12411 ;; This pattern can't accept a variable shift count, since shifts by
12412 ;; zero don't affect the flags. We assume that shifts by constant
12413 ;; zero are optimized away.
12414 (define_insn "*ashrqi3_one_bit_cmp"
12415 [(set (reg FLAGS_REG)
12417 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12418 (match_operand:QI 2 "const1_operand" "I"))
12420 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12421 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12422 "(TARGET_SHIFT1 || optimize_size)
12423 && ix86_match_ccmode (insn, CCGOCmode)
12424 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12426 [(set_attr "type" "ishift")
12427 (set (attr "length")
12428 (if_then_else (match_operand 0 "register_operand" "")
12430 (const_string "*")))])
12432 (define_insn "*ashrqi3_one_bit_cconly"
12433 [(set (reg FLAGS_REG)
12435 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12436 (match_operand:QI 2 "const1_operand" "I"))
12438 (clobber (match_scratch:QI 0 "=q"))]
12439 "(TARGET_SHIFT1 || optimize_size)
12440 && ix86_match_ccmode (insn, CCGOCmode)
12441 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12443 [(set_attr "type" "ishift")
12444 (set_attr "length" "2")])
12446 ;; This pattern can't accept a variable shift count, since shifts by
12447 ;; zero don't affect the flags. We assume that shifts by constant
12448 ;; zero are optimized away.
12449 (define_insn "*ashrqi3_cmp"
12450 [(set (reg FLAGS_REG)
12452 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12453 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12455 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12456 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12457 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12458 && ix86_match_ccmode (insn, CCGOCmode)
12459 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12460 "sar{b}\t{%2, %0|%0, %2}"
12461 [(set_attr "type" "ishift")
12462 (set_attr "mode" "QI")])
12464 (define_insn "*ashrqi3_cconly"
12465 [(set (reg FLAGS_REG)
12467 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12468 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12470 (clobber (match_scratch:QI 0 "=q"))]
12471 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12472 && ix86_match_ccmode (insn, CCGOCmode)
12473 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12474 "sar{b}\t{%2, %0|%0, %2}"
12475 [(set_attr "type" "ishift")
12476 (set_attr "mode" "QI")])
12479 ;; Logical shift instructions
12481 ;; See comment above `ashldi3' about how this works.
12483 (define_expand "lshrti3"
12484 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12485 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12486 (match_operand:QI 2 "nonmemory_operand" "")))
12487 (clobber (reg:CC FLAGS_REG))])]
12490 if (! immediate_operand (operands[2], QImode))
12492 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12495 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12499 (define_insn "lshrti3_1"
12500 [(set (match_operand:TI 0 "register_operand" "=r")
12501 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12502 (match_operand:QI 2 "register_operand" "c")))
12503 (clobber (match_scratch:DI 3 "=&r"))
12504 (clobber (reg:CC FLAGS_REG))]
12507 [(set_attr "type" "multi")])
12509 ;; This pattern must be defined before *lshrti3_2 to prevent
12510 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12512 (define_insn "sse2_lshrti3"
12513 [(set (match_operand:TI 0 "register_operand" "=x")
12514 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12515 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12518 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12519 return "psrldq\t{%2, %0|%0, %2}";
12521 [(set_attr "type" "sseishft")
12522 (set_attr "prefix_data16" "1")
12523 (set_attr "mode" "TI")])
12525 (define_insn "*lshrti3_2"
12526 [(set (match_operand:TI 0 "register_operand" "=r")
12527 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12528 (match_operand:QI 2 "immediate_operand" "O")))
12529 (clobber (reg:CC FLAGS_REG))]
12532 [(set_attr "type" "multi")])
12535 [(set (match_operand:TI 0 "register_operand" "")
12536 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12537 (match_operand:QI 2 "register_operand" "")))
12538 (clobber (match_scratch:DI 3 ""))
12539 (clobber (reg:CC FLAGS_REG))]
12540 "TARGET_64BIT && reload_completed"
12542 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12545 [(set (match_operand:TI 0 "register_operand" "")
12546 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12547 (match_operand:QI 2 "immediate_operand" "")))
12548 (clobber (reg:CC FLAGS_REG))]
12549 "TARGET_64BIT && reload_completed"
12551 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12553 (define_expand "lshrdi3"
12554 [(set (match_operand:DI 0 "shiftdi_operand" "")
12555 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12556 (match_operand:QI 2 "nonmemory_operand" "")))]
12558 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12560 (define_insn "*lshrdi3_1_one_bit_rex64"
12561 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12562 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12563 (match_operand:QI 2 "const1_operand" "")))
12564 (clobber (reg:CC FLAGS_REG))]
12566 && (TARGET_SHIFT1 || optimize_size)
12567 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12569 [(set_attr "type" "ishift")
12570 (set (attr "length")
12571 (if_then_else (match_operand:DI 0 "register_operand" "")
12573 (const_string "*")))])
12575 (define_insn "*lshrdi3_1_rex64"
12576 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12577 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12578 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12579 (clobber (reg:CC FLAGS_REG))]
12580 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12582 shr{q}\t{%2, %0|%0, %2}
12583 shr{q}\t{%b2, %0|%0, %b2}"
12584 [(set_attr "type" "ishift")
12585 (set_attr "mode" "DI")])
12587 ;; This pattern can't accept a variable shift count, since shifts by
12588 ;; zero don't affect the flags. We assume that shifts by constant
12589 ;; zero are optimized away.
12590 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12591 [(set (reg FLAGS_REG)
12593 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12594 (match_operand:QI 2 "const1_operand" ""))
12596 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12597 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12599 && (TARGET_SHIFT1 || optimize_size)
12600 && ix86_match_ccmode (insn, CCGOCmode)
12601 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12603 [(set_attr "type" "ishift")
12604 (set (attr "length")
12605 (if_then_else (match_operand:DI 0 "register_operand" "")
12607 (const_string "*")))])
12609 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12610 [(set (reg FLAGS_REG)
12612 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12613 (match_operand:QI 2 "const1_operand" ""))
12615 (clobber (match_scratch:DI 0 "=r"))]
12617 && (TARGET_SHIFT1 || optimize_size)
12618 && ix86_match_ccmode (insn, CCGOCmode)
12619 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12621 [(set_attr "type" "ishift")
12622 (set_attr "length" "2")])
12624 ;; This pattern can't accept a variable shift count, since shifts by
12625 ;; zero don't affect the flags. We assume that shifts by constant
12626 ;; zero are optimized away.
12627 (define_insn "*lshrdi3_cmp_rex64"
12628 [(set (reg FLAGS_REG)
12630 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12631 (match_operand:QI 2 "const_int_operand" "e"))
12633 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12634 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12636 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12637 && ix86_match_ccmode (insn, CCGOCmode)
12638 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12639 "shr{q}\t{%2, %0|%0, %2}"
12640 [(set_attr "type" "ishift")
12641 (set_attr "mode" "DI")])
12643 (define_insn "*lshrdi3_cconly_rex64"
12644 [(set (reg FLAGS_REG)
12646 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12647 (match_operand:QI 2 "const_int_operand" "e"))
12649 (clobber (match_scratch:DI 0 "=r"))]
12651 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12652 && ix86_match_ccmode (insn, CCGOCmode)
12653 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12654 "shr{q}\t{%2, %0|%0, %2}"
12655 [(set_attr "type" "ishift")
12656 (set_attr "mode" "DI")])
12658 (define_insn "*lshrdi3_1"
12659 [(set (match_operand:DI 0 "register_operand" "=r")
12660 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12661 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12662 (clobber (reg:CC FLAGS_REG))]
12665 [(set_attr "type" "multi")])
12667 ;; By default we don't ask for a scratch register, because when DImode
12668 ;; values are manipulated, registers are already at a premium. But if
12669 ;; we have one handy, we won't turn it away.
12671 [(match_scratch:SI 3 "r")
12672 (parallel [(set (match_operand:DI 0 "register_operand" "")
12673 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12674 (match_operand:QI 2 "nonmemory_operand" "")))
12675 (clobber (reg:CC FLAGS_REG))])
12677 "!TARGET_64BIT && TARGET_CMOVE"
12679 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12682 [(set (match_operand:DI 0 "register_operand" "")
12683 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12684 (match_operand:QI 2 "nonmemory_operand" "")))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12687 ? epilogue_completed : reload_completed)"
12689 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12691 (define_expand "lshrsi3"
12692 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12693 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12694 (match_operand:QI 2 "nonmemory_operand" "")))
12695 (clobber (reg:CC FLAGS_REG))]
12697 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12699 (define_insn "*lshrsi3_1_one_bit"
12700 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12701 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12702 (match_operand:QI 2 "const1_operand" "")))
12703 (clobber (reg:CC FLAGS_REG))]
12704 "(TARGET_SHIFT1 || optimize_size)
12705 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12707 [(set_attr "type" "ishift")
12708 (set (attr "length")
12709 (if_then_else (match_operand:SI 0 "register_operand" "")
12711 (const_string "*")))])
12713 (define_insn "*lshrsi3_1_one_bit_zext"
12714 [(set (match_operand:DI 0 "register_operand" "=r")
12715 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12716 (match_operand:QI 2 "const1_operand" "")))
12717 (clobber (reg:CC FLAGS_REG))]
12719 && (TARGET_SHIFT1 || optimize_size)
12720 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12722 [(set_attr "type" "ishift")
12723 (set_attr "length" "2")])
12725 (define_insn "*lshrsi3_1"
12726 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12727 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12728 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12729 (clobber (reg:CC FLAGS_REG))]
12730 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12732 shr{l}\t{%2, %0|%0, %2}
12733 shr{l}\t{%b2, %0|%0, %b2}"
12734 [(set_attr "type" "ishift")
12735 (set_attr "mode" "SI")])
12737 (define_insn "*lshrsi3_1_zext"
12738 [(set (match_operand:DI 0 "register_operand" "=r,r")
12740 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12741 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12742 (clobber (reg:CC FLAGS_REG))]
12743 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12745 shr{l}\t{%2, %k0|%k0, %2}
12746 shr{l}\t{%b2, %k0|%k0, %b2}"
12747 [(set_attr "type" "ishift")
12748 (set_attr "mode" "SI")])
12750 ;; This pattern can't accept a variable shift count, since shifts by
12751 ;; zero don't affect the flags. We assume that shifts by constant
12752 ;; zero are optimized away.
12753 (define_insn "*lshrsi3_one_bit_cmp"
12754 [(set (reg FLAGS_REG)
12756 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12757 (match_operand:QI 2 "const1_operand" ""))
12759 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12760 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12761 "(TARGET_SHIFT1 || optimize_size)
12762 && ix86_match_ccmode (insn, CCGOCmode)
12763 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12765 [(set_attr "type" "ishift")
12766 (set (attr "length")
12767 (if_then_else (match_operand:SI 0 "register_operand" "")
12769 (const_string "*")))])
12771 (define_insn "*lshrsi3_one_bit_cconly"
12772 [(set (reg FLAGS_REG)
12774 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12775 (match_operand:QI 2 "const1_operand" ""))
12777 (clobber (match_scratch:SI 0 "=r"))]
12778 "(TARGET_SHIFT1 || optimize_size)
12779 && ix86_match_ccmode (insn, CCGOCmode)
12780 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12782 [(set_attr "type" "ishift")
12783 (set_attr "length" "2")])
12785 (define_insn "*lshrsi3_cmp_one_bit_zext"
12786 [(set (reg FLAGS_REG)
12788 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12789 (match_operand:QI 2 "const1_operand" ""))
12791 (set (match_operand:DI 0 "register_operand" "=r")
12792 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12794 && (TARGET_SHIFT1 || optimize_size)
12795 && ix86_match_ccmode (insn, CCGOCmode)
12796 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12798 [(set_attr "type" "ishift")
12799 (set_attr "length" "2")])
12801 ;; This pattern can't accept a variable shift count, since shifts by
12802 ;; zero don't affect the flags. We assume that shifts by constant
12803 ;; zero are optimized away.
12804 (define_insn "*lshrsi3_cmp"
12805 [(set (reg FLAGS_REG)
12807 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12808 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12810 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12811 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12812 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12813 && ix86_match_ccmode (insn, CCGOCmode)
12814 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12815 "shr{l}\t{%2, %0|%0, %2}"
12816 [(set_attr "type" "ishift")
12817 (set_attr "mode" "SI")])
12819 (define_insn "*lshrsi3_cconly"
12820 [(set (reg FLAGS_REG)
12822 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12823 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12825 (clobber (match_scratch:SI 0 "=r"))]
12826 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12827 && ix86_match_ccmode (insn, CCGOCmode)
12828 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12829 "shr{l}\t{%2, %0|%0, %2}"
12830 [(set_attr "type" "ishift")
12831 (set_attr "mode" "SI")])
12833 (define_insn "*lshrsi3_cmp_zext"
12834 [(set (reg FLAGS_REG)
12836 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12837 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12839 (set (match_operand:DI 0 "register_operand" "=r")
12840 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12842 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12843 && ix86_match_ccmode (insn, CCGOCmode)
12844 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12845 "shr{l}\t{%2, %k0|%k0, %2}"
12846 [(set_attr "type" "ishift")
12847 (set_attr "mode" "SI")])
12849 (define_expand "lshrhi3"
12850 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12851 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12852 (match_operand:QI 2 "nonmemory_operand" "")))
12853 (clobber (reg:CC FLAGS_REG))]
12854 "TARGET_HIMODE_MATH"
12855 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12857 (define_insn "*lshrhi3_1_one_bit"
12858 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12859 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12860 (match_operand:QI 2 "const1_operand" "")))
12861 (clobber (reg:CC FLAGS_REG))]
12862 "(TARGET_SHIFT1 || optimize_size)
12863 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12865 [(set_attr "type" "ishift")
12866 (set (attr "length")
12867 (if_then_else (match_operand 0 "register_operand" "")
12869 (const_string "*")))])
12871 (define_insn "*lshrhi3_1"
12872 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12873 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12874 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12875 (clobber (reg:CC FLAGS_REG))]
12876 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12878 shr{w}\t{%2, %0|%0, %2}
12879 shr{w}\t{%b2, %0|%0, %b2}"
12880 [(set_attr "type" "ishift")
12881 (set_attr "mode" "HI")])
12883 ;; This pattern can't accept a variable shift count, since shifts by
12884 ;; zero don't affect the flags. We assume that shifts by constant
12885 ;; zero are optimized away.
12886 (define_insn "*lshrhi3_one_bit_cmp"
12887 [(set (reg FLAGS_REG)
12889 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12890 (match_operand:QI 2 "const1_operand" ""))
12892 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12893 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12894 "(TARGET_SHIFT1 || optimize_size)
12895 && ix86_match_ccmode (insn, CCGOCmode)
12896 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12898 [(set_attr "type" "ishift")
12899 (set (attr "length")
12900 (if_then_else (match_operand:SI 0 "register_operand" "")
12902 (const_string "*")))])
12904 (define_insn "*lshrhi3_one_bit_cconly"
12905 [(set (reg FLAGS_REG)
12907 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12908 (match_operand:QI 2 "const1_operand" ""))
12910 (clobber (match_scratch:HI 0 "=r"))]
12911 "(TARGET_SHIFT1 || optimize_size)
12912 && ix86_match_ccmode (insn, CCGOCmode)
12913 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12915 [(set_attr "type" "ishift")
12916 (set_attr "length" "2")])
12918 ;; This pattern can't accept a variable shift count, since shifts by
12919 ;; zero don't affect the flags. We assume that shifts by constant
12920 ;; zero are optimized away.
12921 (define_insn "*lshrhi3_cmp"
12922 [(set (reg FLAGS_REG)
12924 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12925 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12927 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12928 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12929 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12930 && ix86_match_ccmode (insn, CCGOCmode)
12931 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12932 "shr{w}\t{%2, %0|%0, %2}"
12933 [(set_attr "type" "ishift")
12934 (set_attr "mode" "HI")])
12936 (define_insn "*lshrhi3_cconly"
12937 [(set (reg FLAGS_REG)
12939 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12940 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12942 (clobber (match_scratch:HI 0 "=r"))]
12943 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12944 && ix86_match_ccmode (insn, CCGOCmode)
12945 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12946 "shr{w}\t{%2, %0|%0, %2}"
12947 [(set_attr "type" "ishift")
12948 (set_attr "mode" "HI")])
12950 (define_expand "lshrqi3"
12951 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12952 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12953 (match_operand:QI 2 "nonmemory_operand" "")))
12954 (clobber (reg:CC FLAGS_REG))]
12955 "TARGET_QIMODE_MATH"
12956 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12958 (define_insn "*lshrqi3_1_one_bit"
12959 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12960 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12961 (match_operand:QI 2 "const1_operand" "")))
12962 (clobber (reg:CC FLAGS_REG))]
12963 "(TARGET_SHIFT1 || optimize_size)
12964 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12966 [(set_attr "type" "ishift")
12967 (set (attr "length")
12968 (if_then_else (match_operand 0 "register_operand" "")
12970 (const_string "*")))])
12972 (define_insn "*lshrqi3_1_one_bit_slp"
12973 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12974 (lshiftrt:QI (match_dup 0)
12975 (match_operand:QI 1 "const1_operand" "")))
12976 (clobber (reg:CC FLAGS_REG))]
12977 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12978 && (TARGET_SHIFT1 || optimize_size)"
12980 [(set_attr "type" "ishift1")
12981 (set (attr "length")
12982 (if_then_else (match_operand 0 "register_operand" "")
12984 (const_string "*")))])
12986 (define_insn "*lshrqi3_1"
12987 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12988 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12989 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12990 (clobber (reg:CC FLAGS_REG))]
12991 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12993 shr{b}\t{%2, %0|%0, %2}
12994 shr{b}\t{%b2, %0|%0, %b2}"
12995 [(set_attr "type" "ishift")
12996 (set_attr "mode" "QI")])
12998 (define_insn "*lshrqi3_1_slp"
12999 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13000 (lshiftrt:QI (match_dup 0)
13001 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13002 (clobber (reg:CC FLAGS_REG))]
13003 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13004 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13006 shr{b}\t{%1, %0|%0, %1}
13007 shr{b}\t{%b1, %0|%0, %b1}"
13008 [(set_attr "type" "ishift1")
13009 (set_attr "mode" "QI")])
13011 ;; This pattern can't accept a variable shift count, since shifts by
13012 ;; zero don't affect the flags. We assume that shifts by constant
13013 ;; zero are optimized away.
13014 (define_insn "*lshrqi2_one_bit_cmp"
13015 [(set (reg FLAGS_REG)
13017 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13018 (match_operand:QI 2 "const1_operand" ""))
13020 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13021 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13022 "(TARGET_SHIFT1 || optimize_size)
13023 && ix86_match_ccmode (insn, CCGOCmode)
13024 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13026 [(set_attr "type" "ishift")
13027 (set (attr "length")
13028 (if_then_else (match_operand:SI 0 "register_operand" "")
13030 (const_string "*")))])
13032 (define_insn "*lshrqi2_one_bit_cconly"
13033 [(set (reg FLAGS_REG)
13035 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13036 (match_operand:QI 2 "const1_operand" ""))
13038 (clobber (match_scratch:QI 0 "=q"))]
13039 "(TARGET_SHIFT1 || optimize_size)
13040 && ix86_match_ccmode (insn, CCGOCmode)
13041 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13043 [(set_attr "type" "ishift")
13044 (set_attr "length" "2")])
13046 ;; This pattern can't accept a variable shift count, since shifts by
13047 ;; zero don't affect the flags. We assume that shifts by constant
13048 ;; zero are optimized away.
13049 (define_insn "*lshrqi2_cmp"
13050 [(set (reg FLAGS_REG)
13052 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13053 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13055 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13056 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13057 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13058 && ix86_match_ccmode (insn, CCGOCmode)
13059 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13060 "shr{b}\t{%2, %0|%0, %2}"
13061 [(set_attr "type" "ishift")
13062 (set_attr "mode" "QI")])
13064 (define_insn "*lshrqi2_cconly"
13065 [(set (reg FLAGS_REG)
13067 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13068 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13070 (clobber (match_scratch:QI 0 "=q"))]
13071 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13072 && ix86_match_ccmode (insn, CCGOCmode)
13073 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13074 "shr{b}\t{%2, %0|%0, %2}"
13075 [(set_attr "type" "ishift")
13076 (set_attr "mode" "QI")])
13078 ;; Rotate instructions
13080 (define_expand "rotldi3"
13081 [(set (match_operand:DI 0 "shiftdi_operand" "")
13082 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13083 (match_operand:QI 2 "nonmemory_operand" "")))
13084 (clobber (reg:CC FLAGS_REG))]
13089 ix86_expand_binary_operator (ROTATE, DImode, operands);
13092 if (!const_1_to_31_operand (operands[2], VOIDmode))
13094 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13098 ;; Implement rotation using two double-precision shift instructions
13099 ;; and a scratch register.
13100 (define_insn_and_split "ix86_rotldi3"
13101 [(set (match_operand:DI 0 "register_operand" "=r")
13102 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13103 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13104 (clobber (reg:CC FLAGS_REG))
13105 (clobber (match_scratch:SI 3 "=&r"))]
13108 "&& reload_completed"
13109 [(set (match_dup 3) (match_dup 4))
13111 [(set (match_dup 4)
13112 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13113 (lshiftrt:SI (match_dup 5)
13114 (minus:QI (const_int 32) (match_dup 2)))))
13115 (clobber (reg:CC FLAGS_REG))])
13117 [(set (match_dup 5)
13118 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13119 (lshiftrt:SI (match_dup 3)
13120 (minus:QI (const_int 32) (match_dup 2)))))
13121 (clobber (reg:CC FLAGS_REG))])]
13122 "split_di (operands, 1, operands + 4, operands + 5);")
13124 (define_insn "*rotlsi3_1_one_bit_rex64"
13125 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13126 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13127 (match_operand:QI 2 "const1_operand" "")))
13128 (clobber (reg:CC FLAGS_REG))]
13130 && (TARGET_SHIFT1 || optimize_size)
13131 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13133 [(set_attr "type" "rotate")
13134 (set (attr "length")
13135 (if_then_else (match_operand:DI 0 "register_operand" "")
13137 (const_string "*")))])
13139 (define_insn "*rotldi3_1_rex64"
13140 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13141 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13142 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13143 (clobber (reg:CC FLAGS_REG))]
13144 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13146 rol{q}\t{%2, %0|%0, %2}
13147 rol{q}\t{%b2, %0|%0, %b2}"
13148 [(set_attr "type" "rotate")
13149 (set_attr "mode" "DI")])
13151 (define_expand "rotlsi3"
13152 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13153 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13154 (match_operand:QI 2 "nonmemory_operand" "")))
13155 (clobber (reg:CC FLAGS_REG))]
13157 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13159 (define_insn "*rotlsi3_1_one_bit"
13160 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13161 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13162 (match_operand:QI 2 "const1_operand" "")))
13163 (clobber (reg:CC FLAGS_REG))]
13164 "(TARGET_SHIFT1 || optimize_size)
13165 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13167 [(set_attr "type" "rotate")
13168 (set (attr "length")
13169 (if_then_else (match_operand:SI 0 "register_operand" "")
13171 (const_string "*")))])
13173 (define_insn "*rotlsi3_1_one_bit_zext"
13174 [(set (match_operand:DI 0 "register_operand" "=r")
13176 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13177 (match_operand:QI 2 "const1_operand" ""))))
13178 (clobber (reg:CC FLAGS_REG))]
13180 && (TARGET_SHIFT1 || optimize_size)
13181 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13183 [(set_attr "type" "rotate")
13184 (set_attr "length" "2")])
13186 (define_insn "*rotlsi3_1"
13187 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13188 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13189 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13190 (clobber (reg:CC FLAGS_REG))]
13191 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13193 rol{l}\t{%2, %0|%0, %2}
13194 rol{l}\t{%b2, %0|%0, %b2}"
13195 [(set_attr "type" "rotate")
13196 (set_attr "mode" "SI")])
13198 (define_insn "*rotlsi3_1_zext"
13199 [(set (match_operand:DI 0 "register_operand" "=r,r")
13201 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13202 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13203 (clobber (reg:CC FLAGS_REG))]
13204 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13206 rol{l}\t{%2, %k0|%k0, %2}
13207 rol{l}\t{%b2, %k0|%k0, %b2}"
13208 [(set_attr "type" "rotate")
13209 (set_attr "mode" "SI")])
13211 (define_expand "rotlhi3"
13212 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13213 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13214 (match_operand:QI 2 "nonmemory_operand" "")))
13215 (clobber (reg:CC FLAGS_REG))]
13216 "TARGET_HIMODE_MATH"
13217 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13219 (define_insn "*rotlhi3_1_one_bit"
13220 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13221 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13222 (match_operand:QI 2 "const1_operand" "")))
13223 (clobber (reg:CC FLAGS_REG))]
13224 "(TARGET_SHIFT1 || optimize_size)
13225 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13227 [(set_attr "type" "rotate")
13228 (set (attr "length")
13229 (if_then_else (match_operand 0 "register_operand" "")
13231 (const_string "*")))])
13233 (define_insn "*rotlhi3_1"
13234 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13235 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13236 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13237 (clobber (reg:CC FLAGS_REG))]
13238 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13240 rol{w}\t{%2, %0|%0, %2}
13241 rol{w}\t{%b2, %0|%0, %b2}"
13242 [(set_attr "type" "rotate")
13243 (set_attr "mode" "HI")])
13246 [(set (match_operand:HI 0 "register_operand" "")
13247 (rotate:HI (match_dup 0) (const_int 8)))
13248 (clobber (reg:CC FLAGS_REG))]
13250 [(parallel [(set (strict_low_part (match_dup 0))
13251 (bswap:HI (match_dup 0)))
13252 (clobber (reg:CC FLAGS_REG))])]
13255 (define_expand "rotlqi3"
13256 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13257 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13258 (match_operand:QI 2 "nonmemory_operand" "")))
13259 (clobber (reg:CC FLAGS_REG))]
13260 "TARGET_QIMODE_MATH"
13261 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13263 (define_insn "*rotlqi3_1_one_bit_slp"
13264 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13265 (rotate:QI (match_dup 0)
13266 (match_operand:QI 1 "const1_operand" "")))
13267 (clobber (reg:CC FLAGS_REG))]
13268 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13269 && (TARGET_SHIFT1 || optimize_size)"
13271 [(set_attr "type" "rotate1")
13272 (set (attr "length")
13273 (if_then_else (match_operand 0 "register_operand" "")
13275 (const_string "*")))])
13277 (define_insn "*rotlqi3_1_one_bit"
13278 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13279 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13280 (match_operand:QI 2 "const1_operand" "")))
13281 (clobber (reg:CC FLAGS_REG))]
13282 "(TARGET_SHIFT1 || optimize_size)
13283 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13285 [(set_attr "type" "rotate")
13286 (set (attr "length")
13287 (if_then_else (match_operand 0 "register_operand" "")
13289 (const_string "*")))])
13291 (define_insn "*rotlqi3_1_slp"
13292 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13293 (rotate:QI (match_dup 0)
13294 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13295 (clobber (reg:CC FLAGS_REG))]
13296 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13297 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13299 rol{b}\t{%1, %0|%0, %1}
13300 rol{b}\t{%b1, %0|%0, %b1}"
13301 [(set_attr "type" "rotate1")
13302 (set_attr "mode" "QI")])
13304 (define_insn "*rotlqi3_1"
13305 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13306 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13307 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13308 (clobber (reg:CC FLAGS_REG))]
13309 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13311 rol{b}\t{%2, %0|%0, %2}
13312 rol{b}\t{%b2, %0|%0, %b2}"
13313 [(set_attr "type" "rotate")
13314 (set_attr "mode" "QI")])
13316 (define_expand "rotrdi3"
13317 [(set (match_operand:DI 0 "shiftdi_operand" "")
13318 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13319 (match_operand:QI 2 "nonmemory_operand" "")))
13320 (clobber (reg:CC FLAGS_REG))]
13325 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13328 if (!const_1_to_31_operand (operands[2], VOIDmode))
13330 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13334 ;; Implement rotation using two double-precision shift instructions
13335 ;; and a scratch register.
13336 (define_insn_and_split "ix86_rotrdi3"
13337 [(set (match_operand:DI 0 "register_operand" "=r")
13338 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13339 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13340 (clobber (reg:CC FLAGS_REG))
13341 (clobber (match_scratch:SI 3 "=&r"))]
13344 "&& reload_completed"
13345 [(set (match_dup 3) (match_dup 4))
13347 [(set (match_dup 4)
13348 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13349 (ashift:SI (match_dup 5)
13350 (minus:QI (const_int 32) (match_dup 2)))))
13351 (clobber (reg:CC FLAGS_REG))])
13353 [(set (match_dup 5)
13354 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13355 (ashift:SI (match_dup 3)
13356 (minus:QI (const_int 32) (match_dup 2)))))
13357 (clobber (reg:CC FLAGS_REG))])]
13358 "split_di (operands, 1, operands + 4, operands + 5);")
13360 (define_insn "*rotrdi3_1_one_bit_rex64"
13361 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13362 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13363 (match_operand:QI 2 "const1_operand" "")))
13364 (clobber (reg:CC FLAGS_REG))]
13366 && (TARGET_SHIFT1 || optimize_size)
13367 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13369 [(set_attr "type" "rotate")
13370 (set (attr "length")
13371 (if_then_else (match_operand:DI 0 "register_operand" "")
13373 (const_string "*")))])
13375 (define_insn "*rotrdi3_1_rex64"
13376 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13377 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13378 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13379 (clobber (reg:CC FLAGS_REG))]
13380 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13382 ror{q}\t{%2, %0|%0, %2}
13383 ror{q}\t{%b2, %0|%0, %b2}"
13384 [(set_attr "type" "rotate")
13385 (set_attr "mode" "DI")])
13387 (define_expand "rotrsi3"
13388 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13389 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13390 (match_operand:QI 2 "nonmemory_operand" "")))
13391 (clobber (reg:CC FLAGS_REG))]
13393 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13395 (define_insn "*rotrsi3_1_one_bit"
13396 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13397 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13398 (match_operand:QI 2 "const1_operand" "")))
13399 (clobber (reg:CC FLAGS_REG))]
13400 "(TARGET_SHIFT1 || optimize_size)
13401 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13403 [(set_attr "type" "rotate")
13404 (set (attr "length")
13405 (if_then_else (match_operand:SI 0 "register_operand" "")
13407 (const_string "*")))])
13409 (define_insn "*rotrsi3_1_one_bit_zext"
13410 [(set (match_operand:DI 0 "register_operand" "=r")
13412 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13413 (match_operand:QI 2 "const1_operand" ""))))
13414 (clobber (reg:CC FLAGS_REG))]
13416 && (TARGET_SHIFT1 || optimize_size)
13417 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13419 [(set_attr "type" "rotate")
13420 (set (attr "length")
13421 (if_then_else (match_operand:SI 0 "register_operand" "")
13423 (const_string "*")))])
13425 (define_insn "*rotrsi3_1"
13426 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13427 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13428 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13429 (clobber (reg:CC FLAGS_REG))]
13430 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13432 ror{l}\t{%2, %0|%0, %2}
13433 ror{l}\t{%b2, %0|%0, %b2}"
13434 [(set_attr "type" "rotate")
13435 (set_attr "mode" "SI")])
13437 (define_insn "*rotrsi3_1_zext"
13438 [(set (match_operand:DI 0 "register_operand" "=r,r")
13440 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13441 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13442 (clobber (reg:CC FLAGS_REG))]
13443 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13445 ror{l}\t{%2, %k0|%k0, %2}
13446 ror{l}\t{%b2, %k0|%k0, %b2}"
13447 [(set_attr "type" "rotate")
13448 (set_attr "mode" "SI")])
13450 (define_expand "rotrhi3"
13451 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13452 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13453 (match_operand:QI 2 "nonmemory_operand" "")))
13454 (clobber (reg:CC FLAGS_REG))]
13455 "TARGET_HIMODE_MATH"
13456 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13458 (define_insn "*rotrhi3_one_bit"
13459 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13460 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13461 (match_operand:QI 2 "const1_operand" "")))
13462 (clobber (reg:CC FLAGS_REG))]
13463 "(TARGET_SHIFT1 || optimize_size)
13464 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13466 [(set_attr "type" "rotate")
13467 (set (attr "length")
13468 (if_then_else (match_operand 0 "register_operand" "")
13470 (const_string "*")))])
13472 (define_insn "*rotrhi3_1"
13473 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13474 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13475 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13476 (clobber (reg:CC FLAGS_REG))]
13477 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13479 ror{w}\t{%2, %0|%0, %2}
13480 ror{w}\t{%b2, %0|%0, %b2}"
13481 [(set_attr "type" "rotate")
13482 (set_attr "mode" "HI")])
13485 [(set (match_operand:HI 0 "register_operand" "")
13486 (rotatert:HI (match_dup 0) (const_int 8)))
13487 (clobber (reg:CC FLAGS_REG))]
13489 [(parallel [(set (strict_low_part (match_dup 0))
13490 (bswap:HI (match_dup 0)))
13491 (clobber (reg:CC FLAGS_REG))])]
13494 (define_expand "rotrqi3"
13495 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13496 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13497 (match_operand:QI 2 "nonmemory_operand" "")))
13498 (clobber (reg:CC FLAGS_REG))]
13499 "TARGET_QIMODE_MATH"
13500 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13502 (define_insn "*rotrqi3_1_one_bit"
13503 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13504 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13505 (match_operand:QI 2 "const1_operand" "")))
13506 (clobber (reg:CC FLAGS_REG))]
13507 "(TARGET_SHIFT1 || optimize_size)
13508 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13510 [(set_attr "type" "rotate")
13511 (set (attr "length")
13512 (if_then_else (match_operand 0 "register_operand" "")
13514 (const_string "*")))])
13516 (define_insn "*rotrqi3_1_one_bit_slp"
13517 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13518 (rotatert:QI (match_dup 0)
13519 (match_operand:QI 1 "const1_operand" "")))
13520 (clobber (reg:CC FLAGS_REG))]
13521 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13522 && (TARGET_SHIFT1 || optimize_size)"
13524 [(set_attr "type" "rotate1")
13525 (set (attr "length")
13526 (if_then_else (match_operand 0 "register_operand" "")
13528 (const_string "*")))])
13530 (define_insn "*rotrqi3_1"
13531 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13532 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13533 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13534 (clobber (reg:CC FLAGS_REG))]
13535 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13537 ror{b}\t{%2, %0|%0, %2}
13538 ror{b}\t{%b2, %0|%0, %b2}"
13539 [(set_attr "type" "rotate")
13540 (set_attr "mode" "QI")])
13542 (define_insn "*rotrqi3_1_slp"
13543 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13544 (rotatert:QI (match_dup 0)
13545 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13546 (clobber (reg:CC FLAGS_REG))]
13547 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13548 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13550 ror{b}\t{%1, %0|%0, %1}
13551 ror{b}\t{%b1, %0|%0, %b1}"
13552 [(set_attr "type" "rotate1")
13553 (set_attr "mode" "QI")])
13555 ;; Bit set / bit test instructions
13557 (define_expand "extv"
13558 [(set (match_operand:SI 0 "register_operand" "")
13559 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13560 (match_operand:SI 2 "const8_operand" "")
13561 (match_operand:SI 3 "const8_operand" "")))]
13564 /* Handle extractions from %ah et al. */
13565 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13568 /* From mips.md: extract_bit_field doesn't verify that our source
13569 matches the predicate, so check it again here. */
13570 if (! ext_register_operand (operands[1], VOIDmode))
13574 (define_expand "extzv"
13575 [(set (match_operand:SI 0 "register_operand" "")
13576 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13577 (match_operand:SI 2 "const8_operand" "")
13578 (match_operand:SI 3 "const8_operand" "")))]
13581 /* Handle extractions from %ah et al. */
13582 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13585 /* From mips.md: extract_bit_field doesn't verify that our source
13586 matches the predicate, so check it again here. */
13587 if (! ext_register_operand (operands[1], VOIDmode))
13591 (define_expand "insv"
13592 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13593 (match_operand 1 "const8_operand" "")
13594 (match_operand 2 "const8_operand" ""))
13595 (match_operand 3 "register_operand" ""))]
13598 /* Handle insertions to %ah et al. */
13599 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13602 /* From mips.md: insert_bit_field doesn't verify that our source
13603 matches the predicate, so check it again here. */
13604 if (! ext_register_operand (operands[0], VOIDmode))
13608 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13610 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13615 ;; %%% bts, btr, btc, bt.
13616 ;; In general these instructions are *slow* when applied to memory,
13617 ;; since they enforce atomic operation. When applied to registers,
13618 ;; it depends on the cpu implementation. They're never faster than
13619 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13620 ;; no point. But in 64-bit, we can't hold the relevant immediates
13621 ;; within the instruction itself, so operating on bits in the high
13622 ;; 32-bits of a register becomes easier.
13624 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13625 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13626 ;; negdf respectively, so they can never be disabled entirely.
13628 (define_insn "*btsq"
13629 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13631 (match_operand:DI 1 "const_0_to_63_operand" ""))
13633 (clobber (reg:CC FLAGS_REG))]
13634 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13636 [(set_attr "type" "alu1")])
13638 (define_insn "*btrq"
13639 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13641 (match_operand:DI 1 "const_0_to_63_operand" ""))
13643 (clobber (reg:CC FLAGS_REG))]
13644 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13646 [(set_attr "type" "alu1")])
13648 (define_insn "*btcq"
13649 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13651 (match_operand:DI 1 "const_0_to_63_operand" ""))
13652 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13653 (clobber (reg:CC FLAGS_REG))]
13654 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13656 [(set_attr "type" "alu1")])
13658 ;; Allow Nocona to avoid these instructions if a register is available.
13661 [(match_scratch:DI 2 "r")
13662 (parallel [(set (zero_extract:DI
13663 (match_operand:DI 0 "register_operand" "")
13665 (match_operand:DI 1 "const_0_to_63_operand" ""))
13667 (clobber (reg:CC FLAGS_REG))])]
13668 "TARGET_64BIT && !TARGET_USE_BT"
13671 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13674 if (HOST_BITS_PER_WIDE_INT >= 64)
13675 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13676 else if (i < HOST_BITS_PER_WIDE_INT)
13677 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13679 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13681 op1 = immed_double_const (lo, hi, DImode);
13684 emit_move_insn (operands[2], op1);
13688 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13693 [(match_scratch:DI 2 "r")
13694 (parallel [(set (zero_extract:DI
13695 (match_operand:DI 0 "register_operand" "")
13697 (match_operand:DI 1 "const_0_to_63_operand" ""))
13699 (clobber (reg:CC FLAGS_REG))])]
13700 "TARGET_64BIT && !TARGET_USE_BT"
13703 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13706 if (HOST_BITS_PER_WIDE_INT >= 64)
13707 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13708 else if (i < HOST_BITS_PER_WIDE_INT)
13709 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13711 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13713 op1 = immed_double_const (~lo, ~hi, DImode);
13716 emit_move_insn (operands[2], op1);
13720 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13725 [(match_scratch:DI 2 "r")
13726 (parallel [(set (zero_extract:DI
13727 (match_operand:DI 0 "register_operand" "")
13729 (match_operand:DI 1 "const_0_to_63_operand" ""))
13730 (not:DI (zero_extract:DI
13731 (match_dup 0) (const_int 1) (match_dup 1))))
13732 (clobber (reg:CC FLAGS_REG))])]
13733 "TARGET_64BIT && !TARGET_USE_BT"
13736 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13739 if (HOST_BITS_PER_WIDE_INT >= 64)
13740 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13741 else if (i < HOST_BITS_PER_WIDE_INT)
13742 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13744 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13746 op1 = immed_double_const (lo, hi, DImode);
13749 emit_move_insn (operands[2], op1);
13753 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13757 ;; Store-flag instructions.
13759 ;; For all sCOND expanders, also expand the compare or test insn that
13760 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13762 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13763 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13764 ;; way, which can later delete the movzx if only QImode is needed.
13766 (define_expand "seq"
13767 [(set (match_operand:QI 0 "register_operand" "")
13768 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13770 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13772 (define_expand "sne"
13773 [(set (match_operand:QI 0 "register_operand" "")
13774 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13776 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13778 (define_expand "sgt"
13779 [(set (match_operand:QI 0 "register_operand" "")
13780 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13782 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13784 (define_expand "sgtu"
13785 [(set (match_operand:QI 0 "register_operand" "")
13786 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13788 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13790 (define_expand "slt"
13791 [(set (match_operand:QI 0 "register_operand" "")
13792 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13794 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13796 (define_expand "sltu"
13797 [(set (match_operand:QI 0 "register_operand" "")
13798 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13800 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13802 (define_expand "sge"
13803 [(set (match_operand:QI 0 "register_operand" "")
13804 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13806 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13808 (define_expand "sgeu"
13809 [(set (match_operand:QI 0 "register_operand" "")
13810 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13812 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13814 (define_expand "sle"
13815 [(set (match_operand:QI 0 "register_operand" "")
13816 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13818 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13820 (define_expand "sleu"
13821 [(set (match_operand:QI 0 "register_operand" "")
13822 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13824 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13826 (define_expand "sunordered"
13827 [(set (match_operand:QI 0 "register_operand" "")
13828 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13829 "TARGET_80387 || TARGET_SSE"
13830 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13832 (define_expand "sordered"
13833 [(set (match_operand:QI 0 "register_operand" "")
13834 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13836 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13838 (define_expand "suneq"
13839 [(set (match_operand:QI 0 "register_operand" "")
13840 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13841 "TARGET_80387 || TARGET_SSE"
13842 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13844 (define_expand "sunge"
13845 [(set (match_operand:QI 0 "register_operand" "")
13846 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13847 "TARGET_80387 || TARGET_SSE"
13848 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13850 (define_expand "sungt"
13851 [(set (match_operand:QI 0 "register_operand" "")
13852 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13853 "TARGET_80387 || TARGET_SSE"
13854 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13856 (define_expand "sunle"
13857 [(set (match_operand:QI 0 "register_operand" "")
13858 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13859 "TARGET_80387 || TARGET_SSE"
13860 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13862 (define_expand "sunlt"
13863 [(set (match_operand:QI 0 "register_operand" "")
13864 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13865 "TARGET_80387 || TARGET_SSE"
13866 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13868 (define_expand "sltgt"
13869 [(set (match_operand:QI 0 "register_operand" "")
13870 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13871 "TARGET_80387 || TARGET_SSE"
13872 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13874 (define_insn "*setcc_1"
13875 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13876 (match_operator:QI 1 "ix86_comparison_operator"
13877 [(reg FLAGS_REG) (const_int 0)]))]
13880 [(set_attr "type" "setcc")
13881 (set_attr "mode" "QI")])
13883 (define_insn "*setcc_2"
13884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13885 (match_operator:QI 1 "ix86_comparison_operator"
13886 [(reg FLAGS_REG) (const_int 0)]))]
13889 [(set_attr "type" "setcc")
13890 (set_attr "mode" "QI")])
13892 ;; In general it is not safe to assume too much about CCmode registers,
13893 ;; so simplify-rtx stops when it sees a second one. Under certain
13894 ;; conditions this is safe on x86, so help combine not create
13901 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13902 (ne:QI (match_operator 1 "ix86_comparison_operator"
13903 [(reg FLAGS_REG) (const_int 0)])
13906 [(set (match_dup 0) (match_dup 1))]
13908 PUT_MODE (operands[1], QImode);
13912 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13913 (ne:QI (match_operator 1 "ix86_comparison_operator"
13914 [(reg FLAGS_REG) (const_int 0)])
13917 [(set (match_dup 0) (match_dup 1))]
13919 PUT_MODE (operands[1], QImode);
13923 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13924 (eq:QI (match_operator 1 "ix86_comparison_operator"
13925 [(reg FLAGS_REG) (const_int 0)])
13928 [(set (match_dup 0) (match_dup 1))]
13930 rtx new_op1 = copy_rtx (operands[1]);
13931 operands[1] = new_op1;
13932 PUT_MODE (new_op1, QImode);
13933 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13934 GET_MODE (XEXP (new_op1, 0))));
13936 /* Make sure that (a) the CCmode we have for the flags is strong
13937 enough for the reversed compare or (b) we have a valid FP compare. */
13938 if (! ix86_comparison_operator (new_op1, VOIDmode))
13943 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13944 (eq:QI (match_operator 1 "ix86_comparison_operator"
13945 [(reg FLAGS_REG) (const_int 0)])
13948 [(set (match_dup 0) (match_dup 1))]
13950 rtx new_op1 = copy_rtx (operands[1]);
13951 operands[1] = new_op1;
13952 PUT_MODE (new_op1, QImode);
13953 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13954 GET_MODE (XEXP (new_op1, 0))));
13956 /* Make sure that (a) the CCmode we have for the flags is strong
13957 enough for the reversed compare or (b) we have a valid FP compare. */
13958 if (! ix86_comparison_operator (new_op1, VOIDmode))
13962 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13963 ;; subsequent logical operations are used to imitate conditional moves.
13964 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13967 (define_insn "*sse_setccsf"
13968 [(set (match_operand:SF 0 "register_operand" "=x")
13969 (match_operator:SF 1 "sse_comparison_operator"
13970 [(match_operand:SF 2 "register_operand" "0")
13971 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13972 "TARGET_SSE && !TARGET_SSE5"
13973 "cmp%D1ss\t{%3, %0|%0, %3}"
13974 [(set_attr "type" "ssecmp")
13975 (set_attr "mode" "SF")])
13977 (define_insn "*sse_setccdf"
13978 [(set (match_operand:DF 0 "register_operand" "=x")
13979 (match_operator:DF 1 "sse_comparison_operator"
13980 [(match_operand:DF 2 "register_operand" "0")
13981 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13982 "TARGET_SSE2 && !TARGET_SSE5"
13983 "cmp%D1sd\t{%3, %0|%0, %3}"
13984 [(set_attr "type" "ssecmp")
13985 (set_attr "mode" "DF")])
13987 (define_insn "*sse5_setcc<mode>"
13988 [(set (match_operand:MODEF 0 "register_operand" "=x")
13989 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13990 [(match_operand:MODEF 2 "register_operand" "x")
13991 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13993 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13994 [(set_attr "type" "sse4arg")
13995 (set_attr "mode" "<MODE>")])
13998 ;; Basic conditional jump instructions.
13999 ;; We ignore the overflow flag for signed branch instructions.
14001 ;; For all bCOND expanders, also expand the compare or test insn that
14002 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14004 (define_expand "beq"
14006 (if_then_else (match_dup 1)
14007 (label_ref (match_operand 0 "" ""))
14010 "ix86_expand_branch (EQ, operands[0]); DONE;")
14012 (define_expand "bne"
14014 (if_then_else (match_dup 1)
14015 (label_ref (match_operand 0 "" ""))
14018 "ix86_expand_branch (NE, operands[0]); DONE;")
14020 (define_expand "bgt"
14022 (if_then_else (match_dup 1)
14023 (label_ref (match_operand 0 "" ""))
14026 "ix86_expand_branch (GT, operands[0]); DONE;")
14028 (define_expand "bgtu"
14030 (if_then_else (match_dup 1)
14031 (label_ref (match_operand 0 "" ""))
14034 "ix86_expand_branch (GTU, operands[0]); DONE;")
14036 (define_expand "blt"
14038 (if_then_else (match_dup 1)
14039 (label_ref (match_operand 0 "" ""))
14042 "ix86_expand_branch (LT, operands[0]); DONE;")
14044 (define_expand "bltu"
14046 (if_then_else (match_dup 1)
14047 (label_ref (match_operand 0 "" ""))
14050 "ix86_expand_branch (LTU, operands[0]); DONE;")
14052 (define_expand "bge"
14054 (if_then_else (match_dup 1)
14055 (label_ref (match_operand 0 "" ""))
14058 "ix86_expand_branch (GE, operands[0]); DONE;")
14060 (define_expand "bgeu"
14062 (if_then_else (match_dup 1)
14063 (label_ref (match_operand 0 "" ""))
14066 "ix86_expand_branch (GEU, operands[0]); DONE;")
14068 (define_expand "ble"
14070 (if_then_else (match_dup 1)
14071 (label_ref (match_operand 0 "" ""))
14074 "ix86_expand_branch (LE, operands[0]); DONE;")
14076 (define_expand "bleu"
14078 (if_then_else (match_dup 1)
14079 (label_ref (match_operand 0 "" ""))
14082 "ix86_expand_branch (LEU, operands[0]); DONE;")
14084 (define_expand "bunordered"
14086 (if_then_else (match_dup 1)
14087 (label_ref (match_operand 0 "" ""))
14089 "TARGET_80387 || TARGET_SSE_MATH"
14090 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14092 (define_expand "bordered"
14094 (if_then_else (match_dup 1)
14095 (label_ref (match_operand 0 "" ""))
14097 "TARGET_80387 || TARGET_SSE_MATH"
14098 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14100 (define_expand "buneq"
14102 (if_then_else (match_dup 1)
14103 (label_ref (match_operand 0 "" ""))
14105 "TARGET_80387 || TARGET_SSE_MATH"
14106 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14108 (define_expand "bunge"
14110 (if_then_else (match_dup 1)
14111 (label_ref (match_operand 0 "" ""))
14113 "TARGET_80387 || TARGET_SSE_MATH"
14114 "ix86_expand_branch (UNGE, operands[0]); DONE;")
14116 (define_expand "bungt"
14118 (if_then_else (match_dup 1)
14119 (label_ref (match_operand 0 "" ""))
14121 "TARGET_80387 || TARGET_SSE_MATH"
14122 "ix86_expand_branch (UNGT, operands[0]); DONE;")
14124 (define_expand "bunle"
14126 (if_then_else (match_dup 1)
14127 (label_ref (match_operand 0 "" ""))
14129 "TARGET_80387 || TARGET_SSE_MATH"
14130 "ix86_expand_branch (UNLE, operands[0]); DONE;")
14132 (define_expand "bunlt"
14134 (if_then_else (match_dup 1)
14135 (label_ref (match_operand 0 "" ""))
14137 "TARGET_80387 || TARGET_SSE_MATH"
14138 "ix86_expand_branch (UNLT, operands[0]); DONE;")
14140 (define_expand "bltgt"
14142 (if_then_else (match_dup 1)
14143 (label_ref (match_operand 0 "" ""))
14145 "TARGET_80387 || TARGET_SSE_MATH"
14146 "ix86_expand_branch (LTGT, operands[0]); DONE;")
14148 (define_insn "*jcc_1"
14150 (if_then_else (match_operator 1 "ix86_comparison_operator"
14151 [(reg FLAGS_REG) (const_int 0)])
14152 (label_ref (match_operand 0 "" ""))
14156 [(set_attr "type" "ibr")
14157 (set_attr "modrm" "0")
14158 (set (attr "length")
14159 (if_then_else (and (ge (minus (match_dup 0) (pc))
14161 (lt (minus (match_dup 0) (pc))
14166 (define_insn "*jcc_2"
14168 (if_then_else (match_operator 1 "ix86_comparison_operator"
14169 [(reg FLAGS_REG) (const_int 0)])
14171 (label_ref (match_operand 0 "" ""))))]
14174 [(set_attr "type" "ibr")
14175 (set_attr "modrm" "0")
14176 (set (attr "length")
14177 (if_then_else (and (ge (minus (match_dup 0) (pc))
14179 (lt (minus (match_dup 0) (pc))
14184 ;; In general it is not safe to assume too much about CCmode registers,
14185 ;; so simplify-rtx stops when it sees a second one. Under certain
14186 ;; conditions this is safe on x86, so help combine not create
14194 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14195 [(reg FLAGS_REG) (const_int 0)])
14197 (label_ref (match_operand 1 "" ""))
14201 (if_then_else (match_dup 0)
14202 (label_ref (match_dup 1))
14205 PUT_MODE (operands[0], VOIDmode);
14210 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14211 [(reg FLAGS_REG) (const_int 0)])
14213 (label_ref (match_operand 1 "" ""))
14217 (if_then_else (match_dup 0)
14218 (label_ref (match_dup 1))
14221 rtx new_op0 = copy_rtx (operands[0]);
14222 operands[0] = new_op0;
14223 PUT_MODE (new_op0, VOIDmode);
14224 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14225 GET_MODE (XEXP (new_op0, 0))));
14227 /* Make sure that (a) the CCmode we have for the flags is strong
14228 enough for the reversed compare or (b) we have a valid FP compare. */
14229 if (! ix86_comparison_operator (new_op0, VOIDmode))
14233 ;; Define combination compare-and-branch fp compare instructions to use
14234 ;; during early optimization. Splitting the operation apart early makes
14235 ;; for bad code when we want to reverse the operation.
14237 (define_insn "*fp_jcc_1_mixed"
14239 (if_then_else (match_operator 0 "comparison_operator"
14240 [(match_operand 1 "register_operand" "f,x")
14241 (match_operand 2 "nonimmediate_operand" "f,xm")])
14242 (label_ref (match_operand 3 "" ""))
14244 (clobber (reg:CCFP FPSR_REG))
14245 (clobber (reg:CCFP FLAGS_REG))]
14246 "TARGET_MIX_SSE_I387
14247 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14248 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14249 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14252 (define_insn "*fp_jcc_1_sse"
14254 (if_then_else (match_operator 0 "comparison_operator"
14255 [(match_operand 1 "register_operand" "x")
14256 (match_operand 2 "nonimmediate_operand" "xm")])
14257 (label_ref (match_operand 3 "" ""))
14259 (clobber (reg:CCFP FPSR_REG))
14260 (clobber (reg:CCFP FLAGS_REG))]
14262 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14263 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14264 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14267 (define_insn "*fp_jcc_1_387"
14269 (if_then_else (match_operator 0 "comparison_operator"
14270 [(match_operand 1 "register_operand" "f")
14271 (match_operand 2 "register_operand" "f")])
14272 (label_ref (match_operand 3 "" ""))
14274 (clobber (reg:CCFP FPSR_REG))
14275 (clobber (reg:CCFP FLAGS_REG))]
14276 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14278 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14279 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14282 (define_insn "*fp_jcc_2_mixed"
14284 (if_then_else (match_operator 0 "comparison_operator"
14285 [(match_operand 1 "register_operand" "f,x")
14286 (match_operand 2 "nonimmediate_operand" "f,xm")])
14288 (label_ref (match_operand 3 "" ""))))
14289 (clobber (reg:CCFP FPSR_REG))
14290 (clobber (reg:CCFP FLAGS_REG))]
14291 "TARGET_MIX_SSE_I387
14292 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14293 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14294 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14297 (define_insn "*fp_jcc_2_sse"
14299 (if_then_else (match_operator 0 "comparison_operator"
14300 [(match_operand 1 "register_operand" "x")
14301 (match_operand 2 "nonimmediate_operand" "xm")])
14303 (label_ref (match_operand 3 "" ""))))
14304 (clobber (reg:CCFP FPSR_REG))
14305 (clobber (reg:CCFP FLAGS_REG))]
14307 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14308 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14309 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14312 (define_insn "*fp_jcc_2_387"
14314 (if_then_else (match_operator 0 "comparison_operator"
14315 [(match_operand 1 "register_operand" "f")
14316 (match_operand 2 "register_operand" "f")])
14318 (label_ref (match_operand 3 "" ""))))
14319 (clobber (reg:CCFP FPSR_REG))
14320 (clobber (reg:CCFP FLAGS_REG))]
14321 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14323 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14324 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14327 (define_insn "*fp_jcc_3_387"
14329 (if_then_else (match_operator 0 "comparison_operator"
14330 [(match_operand 1 "register_operand" "f")
14331 (match_operand 2 "nonimmediate_operand" "fm")])
14332 (label_ref (match_operand 3 "" ""))
14334 (clobber (reg:CCFP FPSR_REG))
14335 (clobber (reg:CCFP FLAGS_REG))
14336 (clobber (match_scratch:HI 4 "=a"))]
14338 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14339 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14340 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14341 && SELECT_CC_MODE (GET_CODE (operands[0]),
14342 operands[1], operands[2]) == CCFPmode
14343 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14346 (define_insn "*fp_jcc_4_387"
14348 (if_then_else (match_operator 0 "comparison_operator"
14349 [(match_operand 1 "register_operand" "f")
14350 (match_operand 2 "nonimmediate_operand" "fm")])
14352 (label_ref (match_operand 3 "" ""))))
14353 (clobber (reg:CCFP FPSR_REG))
14354 (clobber (reg:CCFP FLAGS_REG))
14355 (clobber (match_scratch:HI 4 "=a"))]
14357 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14358 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14359 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14360 && SELECT_CC_MODE (GET_CODE (operands[0]),
14361 operands[1], operands[2]) == CCFPmode
14362 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14365 (define_insn "*fp_jcc_5_387"
14367 (if_then_else (match_operator 0 "comparison_operator"
14368 [(match_operand 1 "register_operand" "f")
14369 (match_operand 2 "register_operand" "f")])
14370 (label_ref (match_operand 3 "" ""))
14372 (clobber (reg:CCFP FPSR_REG))
14373 (clobber (reg:CCFP FLAGS_REG))
14374 (clobber (match_scratch:HI 4 "=a"))]
14375 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14376 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14377 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14380 (define_insn "*fp_jcc_6_387"
14382 (if_then_else (match_operator 0 "comparison_operator"
14383 [(match_operand 1 "register_operand" "f")
14384 (match_operand 2 "register_operand" "f")])
14386 (label_ref (match_operand 3 "" ""))))
14387 (clobber (reg:CCFP FPSR_REG))
14388 (clobber (reg:CCFP FLAGS_REG))
14389 (clobber (match_scratch:HI 4 "=a"))]
14390 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14391 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14392 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14395 (define_insn "*fp_jcc_7_387"
14397 (if_then_else (match_operator 0 "comparison_operator"
14398 [(match_operand 1 "register_operand" "f")
14399 (match_operand 2 "const0_operand" "X")])
14400 (label_ref (match_operand 3 "" ""))
14402 (clobber (reg:CCFP FPSR_REG))
14403 (clobber (reg:CCFP FLAGS_REG))
14404 (clobber (match_scratch:HI 4 "=a"))]
14405 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14406 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14407 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14408 && SELECT_CC_MODE (GET_CODE (operands[0]),
14409 operands[1], operands[2]) == CCFPmode
14410 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14413 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14414 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14415 ;; with a precedence over other operators and is always put in the first
14416 ;; place. Swap condition and operands to match ficom instruction.
14418 (define_insn "*fp_jcc_8<mode>_387"
14420 (if_then_else (match_operator 0 "comparison_operator"
14421 [(match_operator 1 "float_operator"
14422 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14423 (match_operand 3 "register_operand" "f,f")])
14424 (label_ref (match_operand 4 "" ""))
14426 (clobber (reg:CCFP FPSR_REG))
14427 (clobber (reg:CCFP FLAGS_REG))
14428 (clobber (match_scratch:HI 5 "=a,a"))]
14429 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14430 && TARGET_USE_<MODE>MODE_FIOP
14431 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14432 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14433 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14434 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14439 (if_then_else (match_operator 0 "comparison_operator"
14440 [(match_operand 1 "register_operand" "")
14441 (match_operand 2 "nonimmediate_operand" "")])
14442 (match_operand 3 "" "")
14443 (match_operand 4 "" "")))
14444 (clobber (reg:CCFP FPSR_REG))
14445 (clobber (reg:CCFP FLAGS_REG))]
14449 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14450 operands[3], operands[4], NULL_RTX, NULL_RTX);
14456 (if_then_else (match_operator 0 "comparison_operator"
14457 [(match_operand 1 "register_operand" "")
14458 (match_operand 2 "general_operand" "")])
14459 (match_operand 3 "" "")
14460 (match_operand 4 "" "")))
14461 (clobber (reg:CCFP FPSR_REG))
14462 (clobber (reg:CCFP FLAGS_REG))
14463 (clobber (match_scratch:HI 5 "=a"))]
14467 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14468 operands[3], operands[4], operands[5], NULL_RTX);
14474 (if_then_else (match_operator 0 "comparison_operator"
14475 [(match_operator 1 "float_operator"
14476 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14477 (match_operand 3 "register_operand" "")])
14478 (match_operand 4 "" "")
14479 (match_operand 5 "" "")))
14480 (clobber (reg:CCFP FPSR_REG))
14481 (clobber (reg:CCFP FLAGS_REG))
14482 (clobber (match_scratch:HI 6 "=a"))]
14486 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14487 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14488 operands[3], operands[7],
14489 operands[4], operands[5], operands[6], NULL_RTX);
14493 ;; %%% Kill this when reload knows how to do it.
14496 (if_then_else (match_operator 0 "comparison_operator"
14497 [(match_operator 1 "float_operator"
14498 [(match_operand:X87MODEI12 2 "register_operand" "")])
14499 (match_operand 3 "register_operand" "")])
14500 (match_operand 4 "" "")
14501 (match_operand 5 "" "")))
14502 (clobber (reg:CCFP FPSR_REG))
14503 (clobber (reg:CCFP FLAGS_REG))
14504 (clobber (match_scratch:HI 6 "=a"))]
14508 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14509 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14510 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14511 operands[3], operands[7],
14512 operands[4], operands[5], operands[6], operands[2]);
14516 ;; Unconditional and other jump instructions
14518 (define_insn "jump"
14520 (label_ref (match_operand 0 "" "")))]
14523 [(set_attr "type" "ibr")
14524 (set (attr "length")
14525 (if_then_else (and (ge (minus (match_dup 0) (pc))
14527 (lt (minus (match_dup 0) (pc))
14531 (set_attr "modrm" "0")])
14533 (define_expand "indirect_jump"
14534 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14538 (define_insn "*indirect_jump"
14539 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14542 [(set_attr "type" "ibr")
14543 (set_attr "length_immediate" "0")])
14545 (define_insn "*indirect_jump_rtx64"
14546 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14549 [(set_attr "type" "ibr")
14550 (set_attr "length_immediate" "0")])
14552 (define_expand "tablejump"
14553 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14554 (use (label_ref (match_operand 1 "" "")))])]
14557 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14558 relative. Convert the relative address to an absolute address. */
14562 enum rtx_code code;
14564 /* We can't use @GOTOFF for text labels on VxWorks;
14565 see gotoff_operand. */
14566 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14570 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14572 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14576 op1 = pic_offset_table_rtx;
14581 op0 = pic_offset_table_rtx;
14585 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14590 (define_insn "*tablejump_1"
14591 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14592 (use (label_ref (match_operand 1 "" "")))]
14595 [(set_attr "type" "ibr")
14596 (set_attr "length_immediate" "0")])
14598 (define_insn "*tablejump_1_rtx64"
14599 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14600 (use (label_ref (match_operand 1 "" "")))]
14603 [(set_attr "type" "ibr")
14604 (set_attr "length_immediate" "0")])
14606 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14609 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14610 (set (match_operand:QI 1 "register_operand" "")
14611 (match_operator:QI 2 "ix86_comparison_operator"
14612 [(reg FLAGS_REG) (const_int 0)]))
14613 (set (match_operand 3 "q_regs_operand" "")
14614 (zero_extend (match_dup 1)))]
14615 "(peep2_reg_dead_p (3, operands[1])
14616 || operands_match_p (operands[1], operands[3]))
14617 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14618 [(set (match_dup 4) (match_dup 0))
14619 (set (strict_low_part (match_dup 5))
14622 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14623 operands[5] = gen_lowpart (QImode, operands[3]);
14624 ix86_expand_clear (operands[3]);
14627 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14630 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14631 (set (match_operand:QI 1 "register_operand" "")
14632 (match_operator:QI 2 "ix86_comparison_operator"
14633 [(reg FLAGS_REG) (const_int 0)]))
14634 (parallel [(set (match_operand 3 "q_regs_operand" "")
14635 (zero_extend (match_dup 1)))
14636 (clobber (reg:CC FLAGS_REG))])]
14637 "(peep2_reg_dead_p (3, operands[1])
14638 || operands_match_p (operands[1], operands[3]))
14639 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14640 [(set (match_dup 4) (match_dup 0))
14641 (set (strict_low_part (match_dup 5))
14644 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14645 operands[5] = gen_lowpart (QImode, operands[3]);
14646 ix86_expand_clear (operands[3]);
14649 ;; Call instructions.
14651 ;; The predicates normally associated with named expanders are not properly
14652 ;; checked for calls. This is a bug in the generic code, but it isn't that
14653 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14655 ;; Call subroutine returning no value.
14657 (define_expand "call_pop"
14658 [(parallel [(call (match_operand:QI 0 "" "")
14659 (match_operand:SI 1 "" ""))
14660 (set (reg:SI SP_REG)
14661 (plus:SI (reg:SI SP_REG)
14662 (match_operand:SI 3 "" "")))])]
14665 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14669 (define_insn "*call_pop_0"
14670 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14671 (match_operand:SI 1 "" ""))
14672 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14673 (match_operand:SI 2 "immediate_operand" "")))]
14676 if (SIBLING_CALL_P (insn))
14679 return "call\t%P0";
14681 [(set_attr "type" "call")])
14683 (define_insn "*call_pop_1"
14684 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14685 (match_operand:SI 1 "" ""))
14686 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14687 (match_operand:SI 2 "immediate_operand" "i")))]
14690 if (constant_call_address_operand (operands[0], Pmode))
14692 if (SIBLING_CALL_P (insn))
14695 return "call\t%P0";
14697 if (SIBLING_CALL_P (insn))
14700 return "call\t%A0";
14702 [(set_attr "type" "call")])
14704 (define_expand "call"
14705 [(call (match_operand:QI 0 "" "")
14706 (match_operand 1 "" ""))
14707 (use (match_operand 2 "" ""))]
14710 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14714 (define_expand "sibcall"
14715 [(call (match_operand:QI 0 "" "")
14716 (match_operand 1 "" ""))
14717 (use (match_operand 2 "" ""))]
14720 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14724 (define_insn "*call_0"
14725 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14726 (match_operand 1 "" ""))]
14729 if (SIBLING_CALL_P (insn))
14732 return "call\t%P0";
14734 [(set_attr "type" "call")])
14736 (define_insn "*call_1"
14737 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14738 (match_operand 1 "" ""))]
14739 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14741 if (constant_call_address_operand (operands[0], Pmode))
14742 return "call\t%P0";
14743 return "call\t%A0";
14745 [(set_attr "type" "call")])
14747 (define_insn "*sibcall_1"
14748 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14749 (match_operand 1 "" ""))]
14750 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14752 if (constant_call_address_operand (operands[0], Pmode))
14756 [(set_attr "type" "call")])
14758 (define_insn "*call_1_rex64"
14759 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14760 (match_operand 1 "" ""))]
14761 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14762 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14764 if (constant_call_address_operand (operands[0], Pmode))
14765 return "call\t%P0";
14766 return "call\t%A0";
14768 [(set_attr "type" "call")])
14770 (define_insn "*call_1_rex64_large"
14771 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14772 (match_operand 1 "" ""))]
14773 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14775 [(set_attr "type" "call")])
14777 (define_insn "*sibcall_1_rex64"
14778 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14779 (match_operand 1 "" ""))]
14780 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14782 [(set_attr "type" "call")])
14784 (define_insn "*sibcall_1_rex64_v"
14785 [(call (mem:QI (reg:DI R11_REG))
14786 (match_operand 0 "" ""))]
14787 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14789 [(set_attr "type" "call")])
14792 ;; Call subroutine, returning value in operand 0
14794 (define_expand "call_value_pop"
14795 [(parallel [(set (match_operand 0 "" "")
14796 (call (match_operand:QI 1 "" "")
14797 (match_operand:SI 2 "" "")))
14798 (set (reg:SI SP_REG)
14799 (plus:SI (reg:SI SP_REG)
14800 (match_operand:SI 4 "" "")))])]
14803 ix86_expand_call (operands[0], operands[1], operands[2],
14804 operands[3], operands[4], 0);
14808 (define_expand "call_value"
14809 [(set (match_operand 0 "" "")
14810 (call (match_operand:QI 1 "" "")
14811 (match_operand:SI 2 "" "")))
14812 (use (match_operand:SI 3 "" ""))]
14813 ;; Operand 2 not used on the i386.
14816 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14820 (define_expand "sibcall_value"
14821 [(set (match_operand 0 "" "")
14822 (call (match_operand:QI 1 "" "")
14823 (match_operand:SI 2 "" "")))
14824 (use (match_operand:SI 3 "" ""))]
14825 ;; Operand 2 not used on the i386.
14828 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14832 ;; Call subroutine returning any type.
14834 (define_expand "untyped_call"
14835 [(parallel [(call (match_operand 0 "" "")
14837 (match_operand 1 "" "")
14838 (match_operand 2 "" "")])]
14843 /* In order to give reg-stack an easier job in validating two
14844 coprocessor registers as containing a possible return value,
14845 simply pretend the untyped call returns a complex long double
14848 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14849 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14850 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14853 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14855 rtx set = XVECEXP (operands[2], 0, i);
14856 emit_move_insn (SET_DEST (set), SET_SRC (set));
14859 /* The optimizer does not know that the call sets the function value
14860 registers we stored in the result block. We avoid problems by
14861 claiming that all hard registers are used and clobbered at this
14863 emit_insn (gen_blockage ());
14868 ;; Prologue and epilogue instructions
14870 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14871 ;; all of memory. This blocks insns from being moved across this point.
14873 (define_insn "blockage"
14874 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14877 [(set_attr "length" "0")])
14879 ;; As USE insns aren't meaningful after reload, this is used instead
14880 ;; to prevent deleting instructions setting registers for PIC code
14881 (define_insn "prologue_use"
14882 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14885 [(set_attr "length" "0")])
14887 ;; Insn emitted into the body of a function to return from a function.
14888 ;; This is only done if the function's epilogue is known to be simple.
14889 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14891 (define_expand "return"
14893 "ix86_can_use_return_insn_p ()"
14895 if (current_function_pops_args)
14897 rtx popc = GEN_INT (current_function_pops_args);
14898 emit_jump_insn (gen_return_pop_internal (popc));
14903 (define_insn "return_internal"
14907 [(set_attr "length" "1")
14908 (set_attr "length_immediate" "0")
14909 (set_attr "modrm" "0")])
14911 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14912 ;; instruction Athlon and K8 have.
14914 (define_insn "return_internal_long"
14916 (unspec [(const_int 0)] UNSPEC_REP)]
14919 [(set_attr "length" "1")
14920 (set_attr "length_immediate" "0")
14921 (set_attr "prefix_rep" "1")
14922 (set_attr "modrm" "0")])
14924 (define_insn "return_pop_internal"
14926 (use (match_operand:SI 0 "const_int_operand" ""))]
14929 [(set_attr "length" "3")
14930 (set_attr "length_immediate" "2")
14931 (set_attr "modrm" "0")])
14933 (define_insn "return_indirect_internal"
14935 (use (match_operand:SI 0 "register_operand" "r"))]
14938 [(set_attr "type" "ibr")
14939 (set_attr "length_immediate" "0")])
14945 [(set_attr "length" "1")
14946 (set_attr "length_immediate" "0")
14947 (set_attr "modrm" "0")])
14949 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14950 ;; branch prediction penalty for the third jump in a 16-byte
14953 (define_insn "align"
14954 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14957 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14958 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14960 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14961 The align insn is used to avoid 3 jump instructions in the row to improve
14962 branch prediction and the benefits hardly outweigh the cost of extra 8
14963 nops on the average inserted by full alignment pseudo operation. */
14967 [(set_attr "length" "16")])
14969 (define_expand "prologue"
14972 "ix86_expand_prologue (); DONE;")
14974 (define_insn "set_got"
14975 [(set (match_operand:SI 0 "register_operand" "=r")
14976 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14977 (clobber (reg:CC FLAGS_REG))]
14979 { return output_set_got (operands[0], NULL_RTX); }
14980 [(set_attr "type" "multi")
14981 (set_attr "length" "12")])
14983 (define_insn "set_got_labelled"
14984 [(set (match_operand:SI 0 "register_operand" "=r")
14985 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14987 (clobber (reg:CC FLAGS_REG))]
14989 { return output_set_got (operands[0], operands[1]); }
14990 [(set_attr "type" "multi")
14991 (set_attr "length" "12")])
14993 (define_insn "set_got_rex64"
14994 [(set (match_operand:DI 0 "register_operand" "=r")
14995 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14997 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14998 [(set_attr "type" "lea")
14999 (set_attr "length" "6")])
15001 (define_insn "set_rip_rex64"
15002 [(set (match_operand:DI 0 "register_operand" "=r")
15003 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15005 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15006 [(set_attr "type" "lea")
15007 (set_attr "length" "6")])
15009 (define_insn "set_got_offset_rex64"
15010 [(set (match_operand:DI 0 "register_operand" "=r")
15011 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15013 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15014 [(set_attr "type" "imov")
15015 (set_attr "length" "11")])
15017 (define_expand "epilogue"
15020 "ix86_expand_epilogue (1); DONE;")
15022 (define_expand "sibcall_epilogue"
15025 "ix86_expand_epilogue (0); DONE;")
15027 (define_expand "eh_return"
15028 [(use (match_operand 0 "register_operand" ""))]
15031 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15033 /* Tricky bit: we write the address of the handler to which we will
15034 be returning into someone else's stack frame, one word below the
15035 stack address we wish to restore. */
15036 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15037 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15038 tmp = gen_rtx_MEM (Pmode, tmp);
15039 emit_move_insn (tmp, ra);
15041 if (Pmode == SImode)
15042 emit_jump_insn (gen_eh_return_si (sa));
15044 emit_jump_insn (gen_eh_return_di (sa));
15049 (define_insn_and_split "eh_return_si"
15051 (unspec [(match_operand:SI 0 "register_operand" "c")]
15052 UNSPEC_EH_RETURN))]
15057 "ix86_expand_epilogue (2); DONE;")
15059 (define_insn_and_split "eh_return_di"
15061 (unspec [(match_operand:DI 0 "register_operand" "c")]
15062 UNSPEC_EH_RETURN))]
15067 "ix86_expand_epilogue (2); DONE;")
15069 (define_insn "leave"
15070 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15071 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15072 (clobber (mem:BLK (scratch)))]
15075 [(set_attr "type" "leave")])
15077 (define_insn "leave_rex64"
15078 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15079 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15080 (clobber (mem:BLK (scratch)))]
15083 [(set_attr "type" "leave")])
15085 (define_expand "ffssi2"
15087 [(set (match_operand:SI 0 "register_operand" "")
15088 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15089 (clobber (match_scratch:SI 2 ""))
15090 (clobber (reg:CC FLAGS_REG))])]
15095 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15100 (define_expand "ffs_cmove"
15101 [(set (match_dup 2) (const_int -1))
15102 (parallel [(set (reg:CCZ FLAGS_REG)
15103 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15105 (set (match_operand:SI 0 "nonimmediate_operand" "")
15106 (ctz:SI (match_dup 1)))])
15107 (set (match_dup 0) (if_then_else:SI
15108 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15111 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15112 (clobber (reg:CC FLAGS_REG))])]
15114 "operands[2] = gen_reg_rtx (SImode);")
15116 (define_insn_and_split "*ffs_no_cmove"
15117 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15118 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15119 (clobber (match_scratch:SI 2 "=&q"))
15120 (clobber (reg:CC FLAGS_REG))]
15123 "&& reload_completed"
15124 [(parallel [(set (reg:CCZ FLAGS_REG)
15125 (compare:CCZ (match_dup 1) (const_int 0)))
15126 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15127 (set (strict_low_part (match_dup 3))
15128 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15129 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15130 (clobber (reg:CC FLAGS_REG))])
15131 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15132 (clobber (reg:CC FLAGS_REG))])
15133 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15134 (clobber (reg:CC FLAGS_REG))])]
15136 operands[3] = gen_lowpart (QImode, operands[2]);
15137 ix86_expand_clear (operands[2]);
15140 (define_insn "*ffssi_1"
15141 [(set (reg:CCZ FLAGS_REG)
15142 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15144 (set (match_operand:SI 0 "register_operand" "=r")
15145 (ctz:SI (match_dup 1)))]
15147 "bsf{l}\t{%1, %0|%0, %1}"
15148 [(set_attr "prefix_0f" "1")])
15150 (define_expand "ffsdi2"
15151 [(set (match_dup 2) (const_int -1))
15152 (parallel [(set (reg:CCZ FLAGS_REG)
15153 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15155 (set (match_operand:DI 0 "nonimmediate_operand" "")
15156 (ctz:DI (match_dup 1)))])
15157 (set (match_dup 0) (if_then_else:DI
15158 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15161 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15162 (clobber (reg:CC FLAGS_REG))])]
15164 "operands[2] = gen_reg_rtx (DImode);")
15166 (define_insn "*ffsdi_1"
15167 [(set (reg:CCZ FLAGS_REG)
15168 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15170 (set (match_operand:DI 0 "register_operand" "=r")
15171 (ctz:DI (match_dup 1)))]
15173 "bsf{q}\t{%1, %0|%0, %1}"
15174 [(set_attr "prefix_0f" "1")])
15176 (define_insn "ctzsi2"
15177 [(set (match_operand:SI 0 "register_operand" "=r")
15178 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15179 (clobber (reg:CC FLAGS_REG))]
15181 "bsf{l}\t{%1, %0|%0, %1}"
15182 [(set_attr "prefix_0f" "1")])
15184 (define_insn "ctzdi2"
15185 [(set (match_operand:DI 0 "register_operand" "=r")
15186 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15187 (clobber (reg:CC FLAGS_REG))]
15189 "bsf{q}\t{%1, %0|%0, %1}"
15190 [(set_attr "prefix_0f" "1")])
15192 (define_expand "clzsi2"
15194 [(set (match_operand:SI 0 "register_operand" "")
15195 (minus:SI (const_int 31)
15196 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15197 (clobber (reg:CC FLAGS_REG))])
15199 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15200 (clobber (reg:CC FLAGS_REG))])]
15205 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15210 (define_insn "clzsi2_abm"
15211 [(set (match_operand:SI 0 "register_operand" "=r")
15212 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15213 (clobber (reg:CC FLAGS_REG))]
15215 "lzcnt{l}\t{%1, %0|%0, %1}"
15216 [(set_attr "prefix_rep" "1")
15217 (set_attr "type" "bitmanip")
15218 (set_attr "mode" "SI")])
15220 (define_insn "*bsr"
15221 [(set (match_operand:SI 0 "register_operand" "=r")
15222 (minus:SI (const_int 31)
15223 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15224 (clobber (reg:CC FLAGS_REG))]
15226 "bsr{l}\t{%1, %0|%0, %1}"
15227 [(set_attr "prefix_0f" "1")
15228 (set_attr "mode" "SI")])
15230 (define_insn "popcountsi2"
15231 [(set (match_operand:SI 0 "register_operand" "=r")
15232 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15233 (clobber (reg:CC FLAGS_REG))]
15235 "popcnt{l}\t{%1, %0|%0, %1}"
15236 [(set_attr "prefix_rep" "1")
15237 (set_attr "type" "bitmanip")
15238 (set_attr "mode" "SI")])
15240 (define_insn "*popcountsi2_cmp"
15241 [(set (reg FLAGS_REG)
15243 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15245 (set (match_operand:SI 0 "register_operand" "=r")
15246 (popcount:SI (match_dup 1)))]
15247 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15248 "popcnt{l}\t{%1, %0|%0, %1}"
15249 [(set_attr "prefix_rep" "1")
15250 (set_attr "type" "bitmanip")
15251 (set_attr "mode" "SI")])
15253 (define_insn "*popcountsi2_cmp_zext"
15254 [(set (reg FLAGS_REG)
15256 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15258 (set (match_operand:DI 0 "register_operand" "=r")
15259 (zero_extend:DI(popcount:SI (match_dup 1))))]
15260 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15261 "popcnt{l}\t{%1, %0|%0, %1}"
15262 [(set_attr "prefix_rep" "1")
15263 (set_attr "type" "bitmanip")
15264 (set_attr "mode" "SI")])
15266 (define_expand "bswapsi2"
15267 [(set (match_operand:SI 0 "register_operand" "")
15268 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15273 rtx x = operands[0];
15275 emit_move_insn (x, operands[1]);
15276 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15277 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15278 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15283 (define_insn "*bswapsi_1"
15284 [(set (match_operand:SI 0 "register_operand" "=r")
15285 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15288 [(set_attr "prefix_0f" "1")
15289 (set_attr "length" "2")])
15291 (define_insn "*bswaphi_lowpart_1"
15292 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15293 (bswap:HI (match_dup 0)))
15294 (clobber (reg:CC FLAGS_REG))]
15295 "TARGET_USE_XCHGB || optimize_size"
15297 xchg{b}\t{%h0, %b0|%b0, %h0}
15298 rol{w}\t{$8, %0|%0, 8}"
15299 [(set_attr "length" "2,4")
15300 (set_attr "mode" "QI,HI")])
15302 (define_insn "bswaphi_lowpart"
15303 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15304 (bswap:HI (match_dup 0)))
15305 (clobber (reg:CC FLAGS_REG))]
15307 "rol{w}\t{$8, %0|%0, 8}"
15308 [(set_attr "length" "4")
15309 (set_attr "mode" "HI")])
15311 (define_insn "bswapdi2"
15312 [(set (match_operand:DI 0 "register_operand" "=r")
15313 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15316 [(set_attr "prefix_0f" "1")
15317 (set_attr "length" "3")])
15319 (define_expand "clzdi2"
15321 [(set (match_operand:DI 0 "register_operand" "")
15322 (minus:DI (const_int 63)
15323 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15324 (clobber (reg:CC FLAGS_REG))])
15326 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15327 (clobber (reg:CC FLAGS_REG))])]
15332 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15337 (define_insn "clzdi2_abm"
15338 [(set (match_operand:DI 0 "register_operand" "=r")
15339 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15340 (clobber (reg:CC FLAGS_REG))]
15341 "TARGET_64BIT && TARGET_ABM"
15342 "lzcnt{q}\t{%1, %0|%0, %1}"
15343 [(set_attr "prefix_rep" "1")
15344 (set_attr "type" "bitmanip")
15345 (set_attr "mode" "DI")])
15347 (define_insn "*bsr_rex64"
15348 [(set (match_operand:DI 0 "register_operand" "=r")
15349 (minus:DI (const_int 63)
15350 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15351 (clobber (reg:CC FLAGS_REG))]
15353 "bsr{q}\t{%1, %0|%0, %1}"
15354 [(set_attr "prefix_0f" "1")
15355 (set_attr "mode" "DI")])
15357 (define_insn "popcountdi2"
15358 [(set (match_operand:DI 0 "register_operand" "=r")
15359 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15360 (clobber (reg:CC FLAGS_REG))]
15361 "TARGET_64BIT && TARGET_POPCNT"
15362 "popcnt{q}\t{%1, %0|%0, %1}"
15363 [(set_attr "prefix_rep" "1")
15364 (set_attr "type" "bitmanip")
15365 (set_attr "mode" "DI")])
15367 (define_insn "*popcountdi2_cmp"
15368 [(set (reg FLAGS_REG)
15370 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15372 (set (match_operand:DI 0 "register_operand" "=r")
15373 (popcount:DI (match_dup 1)))]
15374 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15375 "popcnt{q}\t{%1, %0|%0, %1}"
15376 [(set_attr "prefix_rep" "1")
15377 (set_attr "type" "bitmanip")
15378 (set_attr "mode" "DI")])
15380 (define_expand "clzhi2"
15382 [(set (match_operand:HI 0 "register_operand" "")
15383 (minus:HI (const_int 15)
15384 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15385 (clobber (reg:CC FLAGS_REG))])
15387 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15388 (clobber (reg:CC FLAGS_REG))])]
15393 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15398 (define_insn "clzhi2_abm"
15399 [(set (match_operand:HI 0 "register_operand" "=r")
15400 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15401 (clobber (reg:CC FLAGS_REG))]
15403 "lzcnt{w}\t{%1, %0|%0, %1}"
15404 [(set_attr "prefix_rep" "1")
15405 (set_attr "type" "bitmanip")
15406 (set_attr "mode" "HI")])
15408 (define_insn "*bsrhi"
15409 [(set (match_operand:HI 0 "register_operand" "=r")
15410 (minus:HI (const_int 15)
15411 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15412 (clobber (reg:CC FLAGS_REG))]
15414 "bsr{w}\t{%1, %0|%0, %1}"
15415 [(set_attr "prefix_0f" "1")
15416 (set_attr "mode" "HI")])
15418 (define_insn "popcounthi2"
15419 [(set (match_operand:HI 0 "register_operand" "=r")
15420 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15421 (clobber (reg:CC FLAGS_REG))]
15423 "popcnt{w}\t{%1, %0|%0, %1}"
15424 [(set_attr "prefix_rep" "1")
15425 (set_attr "type" "bitmanip")
15426 (set_attr "mode" "HI")])
15428 (define_insn "*popcounthi2_cmp"
15429 [(set (reg FLAGS_REG)
15431 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15433 (set (match_operand:HI 0 "register_operand" "=r")
15434 (popcount:HI (match_dup 1)))]
15435 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15436 "popcnt{w}\t{%1, %0|%0, %1}"
15437 [(set_attr "prefix_rep" "1")
15438 (set_attr "type" "bitmanip")
15439 (set_attr "mode" "HI")])
15441 (define_expand "paritydi2"
15442 [(set (match_operand:DI 0 "register_operand" "")
15443 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15446 rtx scratch = gen_reg_rtx (QImode);
15449 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15450 NULL_RTX, operands[1]));
15452 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15453 gen_rtx_REG (CCmode, FLAGS_REG),
15455 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15458 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15461 rtx tmp = gen_reg_rtx (SImode);
15463 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15464 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15469 (define_insn_and_split "paritydi2_cmp"
15470 [(set (reg:CC FLAGS_REG)
15471 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15472 (clobber (match_scratch:DI 0 "=r,X"))
15473 (clobber (match_scratch:SI 1 "=r,r"))
15474 (clobber (match_scratch:HI 2 "=Q,Q"))]
15477 "&& reload_completed"
15479 [(set (match_dup 1)
15480 (xor:SI (match_dup 1) (match_dup 4)))
15481 (clobber (reg:CC FLAGS_REG))])
15483 [(set (reg:CC FLAGS_REG)
15484 (parity:CC (match_dup 1)))
15485 (clobber (match_dup 1))
15486 (clobber (match_dup 2))])]
15488 operands[4] = gen_lowpart (SImode, operands[3]);
15490 if (MEM_P (operands[3]))
15491 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15492 else if (! TARGET_64BIT)
15493 operands[1] = gen_highpart (SImode, operands[3]);
15496 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15497 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15501 (define_expand "paritysi2"
15502 [(set (match_operand:SI 0 "register_operand" "")
15503 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15506 rtx scratch = gen_reg_rtx (QImode);
15509 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15511 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15512 gen_rtx_REG (CCmode, FLAGS_REG),
15514 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15516 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15520 (define_insn_and_split "paritysi2_cmp"
15521 [(set (reg:CC FLAGS_REG)
15522 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15523 (clobber (match_scratch:SI 0 "=r,X"))
15524 (clobber (match_scratch:HI 1 "=Q,Q"))]
15527 "&& reload_completed"
15529 [(set (match_dup 1)
15530 (xor:HI (match_dup 1) (match_dup 3)))
15531 (clobber (reg:CC FLAGS_REG))])
15533 [(set (reg:CC FLAGS_REG)
15534 (parity:CC (match_dup 1)))
15535 (clobber (match_dup 1))])]
15537 operands[3] = gen_lowpart (HImode, operands[2]);
15539 if (MEM_P (operands[2]))
15540 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15543 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15544 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15548 (define_insn "*parityhi2_cmp"
15549 [(set (reg:CC FLAGS_REG)
15550 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15551 (clobber (match_scratch:HI 0 "=Q"))]
15553 "xor{b}\t{%h0, %b0|%b0, %h0}"
15554 [(set_attr "length" "2")
15555 (set_attr "mode" "HI")])
15557 (define_insn "*parityqi2_cmp"
15558 [(set (reg:CC FLAGS_REG)
15559 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15562 [(set_attr "length" "2")
15563 (set_attr "mode" "QI")])
15565 ;; Thread-local storage patterns for ELF.
15567 ;; Note that these code sequences must appear exactly as shown
15568 ;; in order to allow linker relaxation.
15570 (define_insn "*tls_global_dynamic_32_gnu"
15571 [(set (match_operand:SI 0 "register_operand" "=a")
15572 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15573 (match_operand:SI 2 "tls_symbolic_operand" "")
15574 (match_operand:SI 3 "call_insn_operand" "")]
15576 (clobber (match_scratch:SI 4 "=d"))
15577 (clobber (match_scratch:SI 5 "=c"))
15578 (clobber (reg:CC FLAGS_REG))]
15579 "!TARGET_64BIT && TARGET_GNU_TLS"
15580 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15581 [(set_attr "type" "multi")
15582 (set_attr "length" "12")])
15584 (define_insn "*tls_global_dynamic_32_sun"
15585 [(set (match_operand:SI 0 "register_operand" "=a")
15586 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15587 (match_operand:SI 2 "tls_symbolic_operand" "")
15588 (match_operand:SI 3 "call_insn_operand" "")]
15590 (clobber (match_scratch:SI 4 "=d"))
15591 (clobber (match_scratch:SI 5 "=c"))
15592 (clobber (reg:CC FLAGS_REG))]
15593 "!TARGET_64BIT && TARGET_SUN_TLS"
15594 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15595 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15596 [(set_attr "type" "multi")
15597 (set_attr "length" "14")])
15599 (define_expand "tls_global_dynamic_32"
15600 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15603 (match_operand:SI 1 "tls_symbolic_operand" "")
15606 (clobber (match_scratch:SI 4 ""))
15607 (clobber (match_scratch:SI 5 ""))
15608 (clobber (reg:CC FLAGS_REG))])]
15612 operands[2] = pic_offset_table_rtx;
15615 operands[2] = gen_reg_rtx (Pmode);
15616 emit_insn (gen_set_got (operands[2]));
15618 if (TARGET_GNU2_TLS)
15620 emit_insn (gen_tls_dynamic_gnu2_32
15621 (operands[0], operands[1], operands[2]));
15624 operands[3] = ix86_tls_get_addr ();
15627 (define_insn "*tls_global_dynamic_64"
15628 [(set (match_operand:DI 0 "register_operand" "=a")
15629 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15630 (match_operand:DI 3 "" "")))
15631 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15634 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15635 [(set_attr "type" "multi")
15636 (set_attr "length" "16")])
15638 (define_expand "tls_global_dynamic_64"
15639 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15640 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15641 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15645 if (TARGET_GNU2_TLS)
15647 emit_insn (gen_tls_dynamic_gnu2_64
15648 (operands[0], operands[1]));
15651 operands[2] = ix86_tls_get_addr ();
15654 (define_insn "*tls_local_dynamic_base_32_gnu"
15655 [(set (match_operand:SI 0 "register_operand" "=a")
15656 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15657 (match_operand:SI 2 "call_insn_operand" "")]
15658 UNSPEC_TLS_LD_BASE))
15659 (clobber (match_scratch:SI 3 "=d"))
15660 (clobber (match_scratch:SI 4 "=c"))
15661 (clobber (reg:CC FLAGS_REG))]
15662 "!TARGET_64BIT && TARGET_GNU_TLS"
15663 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15664 [(set_attr "type" "multi")
15665 (set_attr "length" "11")])
15667 (define_insn "*tls_local_dynamic_base_32_sun"
15668 [(set (match_operand:SI 0 "register_operand" "=a")
15669 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15670 (match_operand:SI 2 "call_insn_operand" "")]
15671 UNSPEC_TLS_LD_BASE))
15672 (clobber (match_scratch:SI 3 "=d"))
15673 (clobber (match_scratch:SI 4 "=c"))
15674 (clobber (reg:CC FLAGS_REG))]
15675 "!TARGET_64BIT && TARGET_SUN_TLS"
15676 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15677 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15678 [(set_attr "type" "multi")
15679 (set_attr "length" "13")])
15681 (define_expand "tls_local_dynamic_base_32"
15682 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15683 (unspec:SI [(match_dup 1) (match_dup 2)]
15684 UNSPEC_TLS_LD_BASE))
15685 (clobber (match_scratch:SI 3 ""))
15686 (clobber (match_scratch:SI 4 ""))
15687 (clobber (reg:CC FLAGS_REG))])]
15691 operands[1] = pic_offset_table_rtx;
15694 operands[1] = gen_reg_rtx (Pmode);
15695 emit_insn (gen_set_got (operands[1]));
15697 if (TARGET_GNU2_TLS)
15699 emit_insn (gen_tls_dynamic_gnu2_32
15700 (operands[0], ix86_tls_module_base (), operands[1]));
15703 operands[2] = ix86_tls_get_addr ();
15706 (define_insn "*tls_local_dynamic_base_64"
15707 [(set (match_operand:DI 0 "register_operand" "=a")
15708 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15709 (match_operand:DI 2 "" "")))
15710 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15712 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15713 [(set_attr "type" "multi")
15714 (set_attr "length" "12")])
15716 (define_expand "tls_local_dynamic_base_64"
15717 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15718 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15719 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15722 if (TARGET_GNU2_TLS)
15724 emit_insn (gen_tls_dynamic_gnu2_64
15725 (operands[0], ix86_tls_module_base ()));
15728 operands[1] = ix86_tls_get_addr ();
15731 ;; Local dynamic of a single variable is a lose. Show combine how
15732 ;; to convert that back to global dynamic.
15734 (define_insn_and_split "*tls_local_dynamic_32_once"
15735 [(set (match_operand:SI 0 "register_operand" "=a")
15736 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15737 (match_operand:SI 2 "call_insn_operand" "")]
15738 UNSPEC_TLS_LD_BASE)
15739 (const:SI (unspec:SI
15740 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15742 (clobber (match_scratch:SI 4 "=d"))
15743 (clobber (match_scratch:SI 5 "=c"))
15744 (clobber (reg:CC FLAGS_REG))]
15748 [(parallel [(set (match_dup 0)
15749 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15751 (clobber (match_dup 4))
15752 (clobber (match_dup 5))
15753 (clobber (reg:CC FLAGS_REG))])]
15756 ;; Load and add the thread base pointer from %gs:0.
15758 (define_insn "*load_tp_si"
15759 [(set (match_operand:SI 0 "register_operand" "=r")
15760 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15762 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15763 [(set_attr "type" "imov")
15764 (set_attr "modrm" "0")
15765 (set_attr "length" "7")
15766 (set_attr "memory" "load")
15767 (set_attr "imm_disp" "false")])
15769 (define_insn "*add_tp_si"
15770 [(set (match_operand:SI 0 "register_operand" "=r")
15771 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15772 (match_operand:SI 1 "register_operand" "0")))
15773 (clobber (reg:CC FLAGS_REG))]
15775 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15776 [(set_attr "type" "alu")
15777 (set_attr "modrm" "0")
15778 (set_attr "length" "7")
15779 (set_attr "memory" "load")
15780 (set_attr "imm_disp" "false")])
15782 (define_insn "*load_tp_di"
15783 [(set (match_operand:DI 0 "register_operand" "=r")
15784 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15786 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15787 [(set_attr "type" "imov")
15788 (set_attr "modrm" "0")
15789 (set_attr "length" "7")
15790 (set_attr "memory" "load")
15791 (set_attr "imm_disp" "false")])
15793 (define_insn "*add_tp_di"
15794 [(set (match_operand:DI 0 "register_operand" "=r")
15795 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15796 (match_operand:DI 1 "register_operand" "0")))
15797 (clobber (reg:CC FLAGS_REG))]
15799 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15800 [(set_attr "type" "alu")
15801 (set_attr "modrm" "0")
15802 (set_attr "length" "7")
15803 (set_attr "memory" "load")
15804 (set_attr "imm_disp" "false")])
15806 ;; GNU2 TLS patterns can be split.
15808 (define_expand "tls_dynamic_gnu2_32"
15809 [(set (match_dup 3)
15810 (plus:SI (match_operand:SI 2 "register_operand" "")
15812 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15815 [(set (match_operand:SI 0 "register_operand" "")
15816 (unspec:SI [(match_dup 1) (match_dup 3)
15817 (match_dup 2) (reg:SI SP_REG)]
15819 (clobber (reg:CC FLAGS_REG))])]
15820 "!TARGET_64BIT && TARGET_GNU2_TLS"
15822 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15823 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15826 (define_insn "*tls_dynamic_lea_32"
15827 [(set (match_operand:SI 0 "register_operand" "=r")
15828 (plus:SI (match_operand:SI 1 "register_operand" "b")
15830 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15831 UNSPEC_TLSDESC))))]
15832 "!TARGET_64BIT && TARGET_GNU2_TLS"
15833 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15834 [(set_attr "type" "lea")
15835 (set_attr "mode" "SI")
15836 (set_attr "length" "6")
15837 (set_attr "length_address" "4")])
15839 (define_insn "*tls_dynamic_call_32"
15840 [(set (match_operand:SI 0 "register_operand" "=a")
15841 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15842 (match_operand:SI 2 "register_operand" "0")
15843 ;; we have to make sure %ebx still points to the GOT
15844 (match_operand:SI 3 "register_operand" "b")
15847 (clobber (reg:CC FLAGS_REG))]
15848 "!TARGET_64BIT && TARGET_GNU2_TLS"
15849 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15850 [(set_attr "type" "call")
15851 (set_attr "length" "2")
15852 (set_attr "length_address" "0")])
15854 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15855 [(set (match_operand:SI 0 "register_operand" "=&a")
15857 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15858 (match_operand:SI 4 "" "")
15859 (match_operand:SI 2 "register_operand" "b")
15862 (const:SI (unspec:SI
15863 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15865 (clobber (reg:CC FLAGS_REG))]
15866 "!TARGET_64BIT && TARGET_GNU2_TLS"
15869 [(set (match_dup 0) (match_dup 5))]
15871 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15872 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15875 (define_expand "tls_dynamic_gnu2_64"
15876 [(set (match_dup 2)
15877 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15880 [(set (match_operand:DI 0 "register_operand" "")
15881 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15883 (clobber (reg:CC FLAGS_REG))])]
15884 "TARGET_64BIT && TARGET_GNU2_TLS"
15886 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15887 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15890 (define_insn "*tls_dynamic_lea_64"
15891 [(set (match_operand:DI 0 "register_operand" "=r")
15892 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15894 "TARGET_64BIT && TARGET_GNU2_TLS"
15895 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15896 [(set_attr "type" "lea")
15897 (set_attr "mode" "DI")
15898 (set_attr "length" "7")
15899 (set_attr "length_address" "4")])
15901 (define_insn "*tls_dynamic_call_64"
15902 [(set (match_operand:DI 0 "register_operand" "=a")
15903 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15904 (match_operand:DI 2 "register_operand" "0")
15907 (clobber (reg:CC FLAGS_REG))]
15908 "TARGET_64BIT && TARGET_GNU2_TLS"
15909 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15910 [(set_attr "type" "call")
15911 (set_attr "length" "2")
15912 (set_attr "length_address" "0")])
15914 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15915 [(set (match_operand:DI 0 "register_operand" "=&a")
15917 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15918 (match_operand:DI 3 "" "")
15921 (const:DI (unspec:DI
15922 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15924 (clobber (reg:CC FLAGS_REG))]
15925 "TARGET_64BIT && TARGET_GNU2_TLS"
15928 [(set (match_dup 0) (match_dup 4))]
15930 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15931 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15936 ;; These patterns match the binary 387 instructions for addM3, subM3,
15937 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15938 ;; SFmode. The first is the normal insn, the second the same insn but
15939 ;; with one operand a conversion, and the third the same insn but with
15940 ;; the other operand a conversion. The conversion may be SFmode or
15941 ;; SImode if the target mode DFmode, but only SImode if the target mode
15944 ;; Gcc is slightly more smart about handling normal two address instructions
15945 ;; so use special patterns for add and mull.
15947 (define_insn "*fop_sf_comm_mixed"
15948 [(set (match_operand:SF 0 "register_operand" "=f,x")
15949 (match_operator:SF 3 "binary_fp_operator"
15950 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15951 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15952 "TARGET_MIX_SSE_I387
15953 && COMMUTATIVE_ARITH_P (operands[3])
15954 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15955 "* return output_387_binary_op (insn, operands);"
15956 [(set (attr "type")
15957 (if_then_else (eq_attr "alternative" "1")
15958 (if_then_else (match_operand:SF 3 "mult_operator" "")
15959 (const_string "ssemul")
15960 (const_string "sseadd"))
15961 (if_then_else (match_operand:SF 3 "mult_operator" "")
15962 (const_string "fmul")
15963 (const_string "fop"))))
15964 (set_attr "mode" "SF")])
15966 (define_insn "*fop_sf_comm_sse"
15967 [(set (match_operand:SF 0 "register_operand" "=x")
15968 (match_operator:SF 3 "binary_fp_operator"
15969 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15970 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15972 && COMMUTATIVE_ARITH_P (operands[3])
15973 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15974 "* return output_387_binary_op (insn, operands);"
15975 [(set (attr "type")
15976 (if_then_else (match_operand:SF 3 "mult_operator" "")
15977 (const_string "ssemul")
15978 (const_string "sseadd")))
15979 (set_attr "mode" "SF")])
15981 (define_insn "*fop_sf_comm_i387"
15982 [(set (match_operand:SF 0 "register_operand" "=f")
15983 (match_operator:SF 3 "binary_fp_operator"
15984 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15985 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15987 && COMMUTATIVE_ARITH_P (operands[3])
15988 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15989 "* return output_387_binary_op (insn, operands);"
15990 [(set (attr "type")
15991 (if_then_else (match_operand:SF 3 "mult_operator" "")
15992 (const_string "fmul")
15993 (const_string "fop")))
15994 (set_attr "mode" "SF")])
15996 (define_insn "*fop_sf_1_mixed"
15997 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15998 (match_operator:SF 3 "binary_fp_operator"
15999 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
16000 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
16001 "TARGET_MIX_SSE_I387
16002 && !COMMUTATIVE_ARITH_P (operands[3])
16003 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16004 "* return output_387_binary_op (insn, operands);"
16005 [(set (attr "type")
16006 (cond [(and (eq_attr "alternative" "2")
16007 (match_operand:SF 3 "mult_operator" ""))
16008 (const_string "ssemul")
16009 (and (eq_attr "alternative" "2")
16010 (match_operand:SF 3 "div_operator" ""))
16011 (const_string "ssediv")
16012 (eq_attr "alternative" "2")
16013 (const_string "sseadd")
16014 (match_operand:SF 3 "mult_operator" "")
16015 (const_string "fmul")
16016 (match_operand:SF 3 "div_operator" "")
16017 (const_string "fdiv")
16019 (const_string "fop")))
16020 (set_attr "mode" "SF")])
16022 (define_insn "*rcpsf2_sse"
16023 [(set (match_operand:SF 0 "register_operand" "=x")
16024 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16027 "rcpss\t{%1, %0|%0, %1}"
16028 [(set_attr "type" "sse")
16029 (set_attr "mode" "SF")])
16031 (define_insn "*fop_sf_1_sse"
16032 [(set (match_operand:SF 0 "register_operand" "=x")
16033 (match_operator:SF 3 "binary_fp_operator"
16034 [(match_operand:SF 1 "register_operand" "0")
16035 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16037 && !COMMUTATIVE_ARITH_P (operands[3])"
16038 "* return output_387_binary_op (insn, operands);"
16039 [(set (attr "type")
16040 (cond [(match_operand:SF 3 "mult_operator" "")
16041 (const_string "ssemul")
16042 (match_operand:SF 3 "div_operator" "")
16043 (const_string "ssediv")
16045 (const_string "sseadd")))
16046 (set_attr "mode" "SF")])
16048 ;; This pattern is not fully shadowed by the pattern above.
16049 (define_insn "*fop_sf_1_i387"
16050 [(set (match_operand:SF 0 "register_operand" "=f,f")
16051 (match_operator:SF 3 "binary_fp_operator"
16052 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16053 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16054 "TARGET_80387 && !TARGET_SSE_MATH
16055 && !COMMUTATIVE_ARITH_P (operands[3])
16056 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16057 "* return output_387_binary_op (insn, operands);"
16058 [(set (attr "type")
16059 (cond [(match_operand:SF 3 "mult_operator" "")
16060 (const_string "fmul")
16061 (match_operand:SF 3 "div_operator" "")
16062 (const_string "fdiv")
16064 (const_string "fop")))
16065 (set_attr "mode" "SF")])
16067 ;; ??? Add SSE splitters for these!
16068 (define_insn "*fop_sf_2<mode>_i387"
16069 [(set (match_operand:SF 0 "register_operand" "=f,f")
16070 (match_operator:SF 3 "binary_fp_operator"
16071 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16072 (match_operand:SF 2 "register_operand" "0,0")]))]
16073 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16074 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16075 [(set (attr "type")
16076 (cond [(match_operand:SF 3 "mult_operator" "")
16077 (const_string "fmul")
16078 (match_operand:SF 3 "div_operator" "")
16079 (const_string "fdiv")
16081 (const_string "fop")))
16082 (set_attr "fp_int_src" "true")
16083 (set_attr "mode" "<MODE>")])
16085 (define_insn "*fop_sf_3<mode>_i387"
16086 [(set (match_operand:SF 0 "register_operand" "=f,f")
16087 (match_operator:SF 3 "binary_fp_operator"
16088 [(match_operand:SF 1 "register_operand" "0,0")
16089 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16090 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16091 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16092 [(set (attr "type")
16093 (cond [(match_operand:SF 3 "mult_operator" "")
16094 (const_string "fmul")
16095 (match_operand:SF 3 "div_operator" "")
16096 (const_string "fdiv")
16098 (const_string "fop")))
16099 (set_attr "fp_int_src" "true")
16100 (set_attr "mode" "<MODE>")])
16102 (define_insn "*fop_df_comm_mixed"
16103 [(set (match_operand:DF 0 "register_operand" "=f,x")
16104 (match_operator:DF 3 "binary_fp_operator"
16105 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16106 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16107 "TARGET_SSE2 && TARGET_MIX_SSE_I387
16108 && COMMUTATIVE_ARITH_P (operands[3])
16109 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16110 "* return output_387_binary_op (insn, operands);"
16111 [(set (attr "type")
16112 (if_then_else (eq_attr "alternative" "1")
16113 (if_then_else (match_operand:DF 3 "mult_operator" "")
16114 (const_string "ssemul")
16115 (const_string "sseadd"))
16116 (if_then_else (match_operand:DF 3 "mult_operator" "")
16117 (const_string "fmul")
16118 (const_string "fop"))))
16119 (set_attr "mode" "DF")])
16121 (define_insn "*fop_df_comm_sse"
16122 [(set (match_operand:DF 0 "register_operand" "=x")
16123 (match_operator:DF 3 "binary_fp_operator"
16124 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16125 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16126 "TARGET_SSE2 && TARGET_SSE_MATH
16127 && COMMUTATIVE_ARITH_P (operands[3])
16128 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16129 "* return output_387_binary_op (insn, operands);"
16130 [(set (attr "type")
16131 (if_then_else (match_operand:DF 3 "mult_operator" "")
16132 (const_string "ssemul")
16133 (const_string "sseadd")))
16134 (set_attr "mode" "DF")])
16136 (define_insn "*fop_df_comm_i387"
16137 [(set (match_operand:DF 0 "register_operand" "=f")
16138 (match_operator:DF 3 "binary_fp_operator"
16139 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16140 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16142 && COMMUTATIVE_ARITH_P (operands[3])
16143 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16144 "* return output_387_binary_op (insn, operands);"
16145 [(set (attr "type")
16146 (if_then_else (match_operand:DF 3 "mult_operator" "")
16147 (const_string "fmul")
16148 (const_string "fop")))
16149 (set_attr "mode" "DF")])
16151 (define_insn "*fop_df_1_mixed"
16152 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16153 (match_operator:DF 3 "binary_fp_operator"
16154 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16155 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16156 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16157 && !COMMUTATIVE_ARITH_P (operands[3])
16158 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16159 "* return output_387_binary_op (insn, operands);"
16160 [(set (attr "type")
16161 (cond [(and (eq_attr "alternative" "2")
16162 (match_operand:DF 3 "mult_operator" ""))
16163 (const_string "ssemul")
16164 (and (eq_attr "alternative" "2")
16165 (match_operand:DF 3 "div_operator" ""))
16166 (const_string "ssediv")
16167 (eq_attr "alternative" "2")
16168 (const_string "sseadd")
16169 (match_operand:DF 3 "mult_operator" "")
16170 (const_string "fmul")
16171 (match_operand:DF 3 "div_operator" "")
16172 (const_string "fdiv")
16174 (const_string "fop")))
16175 (set_attr "mode" "DF")])
16177 (define_insn "*fop_df_1_sse"
16178 [(set (match_operand:DF 0 "register_operand" "=x")
16179 (match_operator:DF 3 "binary_fp_operator"
16180 [(match_operand:DF 1 "register_operand" "0")
16181 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16182 "TARGET_SSE2 && TARGET_SSE_MATH
16183 && !COMMUTATIVE_ARITH_P (operands[3])"
16184 "* return output_387_binary_op (insn, operands);"
16185 [(set_attr "mode" "DF")
16187 (cond [(match_operand:DF 3 "mult_operator" "")
16188 (const_string "ssemul")
16189 (match_operand:DF 3 "div_operator" "")
16190 (const_string "ssediv")
16192 (const_string "sseadd")))])
16194 ;; This pattern is not fully shadowed by the pattern above.
16195 (define_insn "*fop_df_1_i387"
16196 [(set (match_operand:DF 0 "register_operand" "=f,f")
16197 (match_operator:DF 3 "binary_fp_operator"
16198 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16199 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16200 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16201 && !COMMUTATIVE_ARITH_P (operands[3])
16202 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16203 "* return 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 "mode" "DF")])
16213 ;; ??? Add SSE splitters for these!
16214 (define_insn "*fop_df_2<mode>_i387"
16215 [(set (match_operand:DF 0 "register_operand" "=f,f")
16216 (match_operator:DF 3 "binary_fp_operator"
16217 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16218 (match_operand:DF 2 "register_operand" "0,0")]))]
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_3<mode>_i387"
16233 [(set (match_operand:DF 0 "register_operand" "=f,f")
16234 (match_operator:DF 3 "binary_fp_operator"
16235 [(match_operand:DF 1 "register_operand" "0,0")
16236 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16237 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16238 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16239 "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
16248 (set_attr "mode" "<MODE>")])
16250 (define_insn "*fop_df_4_i387"
16251 [(set (match_operand:DF 0 "register_operand" "=f,f")
16252 (match_operator:DF 3 "binary_fp_operator"
16253 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16254 (match_operand:DF 2 "register_operand" "0,f")]))]
16255 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16256 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16257 "* return output_387_binary_op (insn, operands);"
16258 [(set (attr "type")
16259 (cond [(match_operand:DF 3 "mult_operator" "")
16260 (const_string "fmul")
16261 (match_operand:DF 3 "div_operator" "")
16262 (const_string "fdiv")
16264 (const_string "fop")))
16265 (set_attr "mode" "SF")])
16267 (define_insn "*fop_df_5_i387"
16268 [(set (match_operand:DF 0 "register_operand" "=f,f")
16269 (match_operator:DF 3 "binary_fp_operator"
16270 [(match_operand:DF 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_df_6_i387"
16285 [(set (match_operand:DF 0 "register_operand" "=f,f")
16286 (match_operator:DF 3 "binary_fp_operator"
16288 (match_operand:SF 1 "register_operand" "0,f"))
16290 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16291 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16292 "* return output_387_binary_op (insn, operands);"
16293 [(set (attr "type")
16294 (cond [(match_operand:DF 3 "mult_operator" "")
16295 (const_string "fmul")
16296 (match_operand:DF 3 "div_operator" "")
16297 (const_string "fdiv")
16299 (const_string "fop")))
16300 (set_attr "mode" "SF")])
16302 (define_insn "*fop_xf_comm_i387"
16303 [(set (match_operand:XF 0 "register_operand" "=f")
16304 (match_operator:XF 3 "binary_fp_operator"
16305 [(match_operand:XF 1 "register_operand" "%0")
16306 (match_operand:XF 2 "register_operand" "f")]))]
16308 && COMMUTATIVE_ARITH_P (operands[3])"
16309 "* return output_387_binary_op (insn, operands);"
16310 [(set (attr "type")
16311 (if_then_else (match_operand:XF 3 "mult_operator" "")
16312 (const_string "fmul")
16313 (const_string "fop")))
16314 (set_attr "mode" "XF")])
16316 (define_insn "*fop_xf_1_i387"
16317 [(set (match_operand:XF 0 "register_operand" "=f,f")
16318 (match_operator:XF 3 "binary_fp_operator"
16319 [(match_operand:XF 1 "register_operand" "0,f")
16320 (match_operand:XF 2 "register_operand" "f,0")]))]
16322 && !COMMUTATIVE_ARITH_P (operands[3])"
16323 "* return output_387_binary_op (insn, operands);"
16324 [(set (attr "type")
16325 (cond [(match_operand:XF 3 "mult_operator" "")
16326 (const_string "fmul")
16327 (match_operand:XF 3 "div_operator" "")
16328 (const_string "fdiv")
16330 (const_string "fop")))
16331 (set_attr "mode" "XF")])
16333 (define_insn "*fop_xf_2<mode>_i387"
16334 [(set (match_operand:XF 0 "register_operand" "=f,f")
16335 (match_operator:XF 3 "binary_fp_operator"
16336 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16337 (match_operand:XF 2 "register_operand" "0,0")]))]
16338 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16339 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16340 [(set (attr "type")
16341 (cond [(match_operand:XF 3 "mult_operator" "")
16342 (const_string "fmul")
16343 (match_operand:XF 3 "div_operator" "")
16344 (const_string "fdiv")
16346 (const_string "fop")))
16347 (set_attr "fp_int_src" "true")
16348 (set_attr "mode" "<MODE>")])
16350 (define_insn "*fop_xf_3<mode>_i387"
16351 [(set (match_operand:XF 0 "register_operand" "=f,f")
16352 (match_operator:XF 3 "binary_fp_operator"
16353 [(match_operand:XF 1 "register_operand" "0,0")
16354 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16355 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16356 "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
16365 (set_attr "mode" "<MODE>")])
16367 (define_insn "*fop_xf_4_i387"
16368 [(set (match_operand:XF 0 "register_operand" "=f,f")
16369 (match_operator:XF 3 "binary_fp_operator"
16371 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16372 (match_operand:XF 2 "register_operand" "0,f")]))]
16374 "* return output_387_binary_op (insn, operands);"
16375 [(set (attr "type")
16376 (cond [(match_operand:XF 3 "mult_operator" "")
16377 (const_string "fmul")
16378 (match_operand:XF 3 "div_operator" "")
16379 (const_string "fdiv")
16381 (const_string "fop")))
16382 (set_attr "mode" "SF")])
16384 (define_insn "*fop_xf_5_i387"
16385 [(set (match_operand:XF 0 "register_operand" "=f,f")
16386 (match_operator:XF 3 "binary_fp_operator"
16387 [(match_operand:XF 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")])
16401 (define_insn "*fop_xf_6_i387"
16402 [(set (match_operand:XF 0 "register_operand" "=f,f")
16403 (match_operator:XF 3 "binary_fp_operator"
16405 (match_operand:MODEF 1 "register_operand" "0,f"))
16407 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16409 "* return output_387_binary_op (insn, operands);"
16410 [(set (attr "type")
16411 (cond [(match_operand:XF 3 "mult_operator" "")
16412 (const_string "fmul")
16413 (match_operand:XF 3 "div_operator" "")
16414 (const_string "fdiv")
16416 (const_string "fop")))
16417 (set_attr "mode" "SF")])
16420 [(set (match_operand 0 "register_operand" "")
16421 (match_operator 3 "binary_fp_operator"
16422 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16423 (match_operand 2 "register_operand" "")]))]
16425 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16428 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16429 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16430 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16431 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16432 GET_MODE (operands[3]),
16435 ix86_free_from_memory (GET_MODE (operands[1]));
16440 [(set (match_operand 0 "register_operand" "")
16441 (match_operator 3 "binary_fp_operator"
16442 [(match_operand 1 "register_operand" "")
16443 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16445 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16448 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16449 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16450 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16451 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16452 GET_MODE (operands[3]),
16455 ix86_free_from_memory (GET_MODE (operands[2]));
16459 ;; FPU special functions.
16461 ;; This pattern implements a no-op XFmode truncation for
16462 ;; all fancy i386 XFmode math functions.
16464 (define_insn "truncxf<mode>2_i387_noop_unspec"
16465 [(set (match_operand:MODEF 0 "register_operand" "=f")
16466 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16467 UNSPEC_TRUNC_NOOP))]
16468 "TARGET_USE_FANCY_MATH_387"
16469 "* return output_387_reg_move (insn, operands);"
16470 [(set_attr "type" "fmov")
16471 (set_attr "mode" "<MODE>")])
16473 (define_insn "sqrtxf2"
16474 [(set (match_operand:XF 0 "register_operand" "=f")
16475 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16476 "TARGET_USE_FANCY_MATH_387"
16478 [(set_attr "type" "fpspc")
16479 (set_attr "mode" "XF")
16480 (set_attr "athlon_decode" "direct")
16481 (set_attr "amdfam10_decode" "direct")])
16483 (define_insn "sqrt_extend<mode>xf2_i387"
16484 [(set (match_operand:XF 0 "register_operand" "=f")
16487 (match_operand:MODEF 1 "register_operand" "0"))))]
16488 "TARGET_USE_FANCY_MATH_387"
16490 [(set_attr "type" "fpspc")
16491 (set_attr "mode" "XF")
16492 (set_attr "athlon_decode" "direct")
16493 (set_attr "amdfam10_decode" "direct")])
16495 (define_insn "*rsqrtsf2_sse"
16496 [(set (match_operand:SF 0 "register_operand" "=x")
16497 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16500 "rsqrtss\t{%1, %0|%0, %1}"
16501 [(set_attr "type" "sse")
16502 (set_attr "mode" "SF")])
16504 (define_expand "rsqrtsf2"
16505 [(set (match_operand:SF 0 "register_operand" "")
16506 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16510 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16514 (define_insn "*sqrt<mode>2_sse"
16515 [(set (match_operand:MODEF 0 "register_operand" "=x")
16517 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16518 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16519 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16520 [(set_attr "type" "sse")
16521 (set_attr "mode" "<MODE>")
16522 (set_attr "athlon_decode" "*")
16523 (set_attr "amdfam10_decode" "*")])
16525 (define_expand "sqrt<mode>2"
16526 [(set (match_operand:MODEF 0 "register_operand" "")
16528 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16529 "TARGET_USE_FANCY_MATH_387
16530 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16532 if (<MODE>mode == SFmode
16533 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16534 && flag_finite_math_only && !flag_trapping_math
16535 && flag_unsafe_math_optimizations)
16537 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16541 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16543 rtx op0 = gen_reg_rtx (XFmode);
16544 rtx op1 = force_reg (<MODE>mode, operands[1]);
16546 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16547 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16552 (define_insn "fpremxf4_i387"
16553 [(set (match_operand:XF 0 "register_operand" "=f")
16554 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16555 (match_operand:XF 3 "register_operand" "1")]
16557 (set (match_operand:XF 1 "register_operand" "=u")
16558 (unspec:XF [(match_dup 2) (match_dup 3)]
16560 (set (reg:CCFP FPSR_REG)
16561 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16563 "TARGET_USE_FANCY_MATH_387"
16565 [(set_attr "type" "fpspc")
16566 (set_attr "mode" "XF")])
16568 (define_expand "fmodxf3"
16569 [(use (match_operand:XF 0 "register_operand" ""))
16570 (use (match_operand:XF 1 "register_operand" ""))
16571 (use (match_operand:XF 2 "register_operand" ""))]
16572 "TARGET_USE_FANCY_MATH_387"
16574 rtx label = gen_label_rtx ();
16578 if (rtx_equal_p (operands[1], operands[2]))
16580 op2 = gen_reg_rtx (XFmode);
16581 emit_move_insn (op2, operands[2]);
16586 emit_label (label);
16587 emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16588 ix86_emit_fp_unordered_jump (label);
16589 LABEL_NUSES (label) = 1;
16591 emit_move_insn (operands[0], operands[1]);
16595 (define_expand "fmod<mode>3"
16596 [(use (match_operand:MODEF 0 "register_operand" ""))
16597 (use (match_operand:MODEF 1 "general_operand" ""))
16598 (use (match_operand:MODEF 2 "general_operand" ""))]
16599 "TARGET_USE_FANCY_MATH_387"
16601 rtx label = gen_label_rtx ();
16603 rtx op1 = gen_reg_rtx (XFmode);
16604 rtx op2 = gen_reg_rtx (XFmode);
16606 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16607 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16609 emit_label (label);
16610 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16611 ix86_emit_fp_unordered_jump (label);
16612 LABEL_NUSES (label) = 1;
16614 /* Truncate the result properly for strict SSE math. */
16615 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16616 && !TARGET_MIX_SSE_I387)
16617 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16619 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16624 (define_insn "fprem1xf4_i387"
16625 [(set (match_operand:XF 0 "register_operand" "=f")
16626 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16627 (match_operand:XF 3 "register_operand" "1")]
16629 (set (match_operand:XF 1 "register_operand" "=u")
16630 (unspec:XF [(match_dup 2) (match_dup 3)]
16632 (set (reg:CCFP FPSR_REG)
16633 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16635 "TARGET_USE_FANCY_MATH_387"
16637 [(set_attr "type" "fpspc")
16638 (set_attr "mode" "XF")])
16640 (define_expand "remainderxf3"
16641 [(use (match_operand:XF 0 "register_operand" ""))
16642 (use (match_operand:XF 1 "register_operand" ""))
16643 (use (match_operand:XF 2 "register_operand" ""))]
16644 "TARGET_USE_FANCY_MATH_387"
16646 rtx label = gen_label_rtx ();
16650 if (rtx_equal_p (operands[1], operands[2]))
16652 op2 = gen_reg_rtx (XFmode);
16653 emit_move_insn (op2, operands[2]);
16658 emit_label (label);
16659 emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16660 ix86_emit_fp_unordered_jump (label);
16661 LABEL_NUSES (label) = 1;
16663 emit_move_insn (operands[0], operands[1]);
16667 (define_expand "remainder<mode>3"
16668 [(use (match_operand:MODEF 0 "register_operand" ""))
16669 (use (match_operand:MODEF 1 "general_operand" ""))
16670 (use (match_operand:MODEF 2 "general_operand" ""))]
16671 "TARGET_USE_FANCY_MATH_387"
16673 rtx label = gen_label_rtx ();
16675 rtx op1 = gen_reg_rtx (XFmode);
16676 rtx op2 = gen_reg_rtx (XFmode);
16678 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16679 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16681 emit_label (label);
16683 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16684 ix86_emit_fp_unordered_jump (label);
16685 LABEL_NUSES (label) = 1;
16687 /* Truncate the result properly for strict SSE math. */
16688 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16689 && !TARGET_MIX_SSE_I387)
16690 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16692 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16697 (define_insn "*sinxf2_i387"
16698 [(set (match_operand:XF 0 "register_operand" "=f")
16699 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16700 "TARGET_USE_FANCY_MATH_387
16701 && flag_unsafe_math_optimizations"
16703 [(set_attr "type" "fpspc")
16704 (set_attr "mode" "XF")])
16706 (define_insn "*sin_extend<mode>xf2_i387"
16707 [(set (match_operand:XF 0 "register_operand" "=f")
16708 (unspec:XF [(float_extend:XF
16709 (match_operand:MODEF 1 "register_operand" "0"))]
16711 "TARGET_USE_FANCY_MATH_387
16712 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16713 || TARGET_MIX_SSE_I387)
16714 && flag_unsafe_math_optimizations"
16716 [(set_attr "type" "fpspc")
16717 (set_attr "mode" "XF")])
16719 (define_insn "*cosxf2_i387"
16720 [(set (match_operand:XF 0 "register_operand" "=f")
16721 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16722 "TARGET_USE_FANCY_MATH_387
16723 && flag_unsafe_math_optimizations"
16725 [(set_attr "type" "fpspc")
16726 (set_attr "mode" "XF")])
16728 (define_insn "*cos_extend<mode>xf2_i387"
16729 [(set (match_operand:XF 0 "register_operand" "=f")
16730 (unspec:XF [(float_extend:XF
16731 (match_operand:MODEF 1 "register_operand" "0"))]
16733 "TARGET_USE_FANCY_MATH_387
16734 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16735 || TARGET_MIX_SSE_I387)
16736 && flag_unsafe_math_optimizations"
16738 [(set_attr "type" "fpspc")
16739 (set_attr "mode" "XF")])
16741 ;; When sincos pattern is defined, sin and cos builtin functions will be
16742 ;; expanded to sincos pattern with one of its outputs left unused.
16743 ;; CSE pass will figure out if two sincos patterns can be combined,
16744 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16745 ;; depending on the unused output.
16747 (define_insn "sincosxf3"
16748 [(set (match_operand:XF 0 "register_operand" "=f")
16749 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16750 UNSPEC_SINCOS_COS))
16751 (set (match_operand:XF 1 "register_operand" "=u")
16752 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16753 "TARGET_USE_FANCY_MATH_387
16754 && flag_unsafe_math_optimizations"
16756 [(set_attr "type" "fpspc")
16757 (set_attr "mode" "XF")])
16760 [(set (match_operand:XF 0 "register_operand" "")
16761 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16762 UNSPEC_SINCOS_COS))
16763 (set (match_operand:XF 1 "register_operand" "")
16764 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16765 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16766 && !(reload_completed || reload_in_progress)"
16767 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16771 [(set (match_operand:XF 0 "register_operand" "")
16772 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16773 UNSPEC_SINCOS_COS))
16774 (set (match_operand:XF 1 "register_operand" "")
16775 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16776 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16777 && !(reload_completed || reload_in_progress)"
16778 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16781 (define_insn "sincos_extend<mode>xf3_i387"
16782 [(set (match_operand:XF 0 "register_operand" "=f")
16783 (unspec:XF [(float_extend:XF
16784 (match_operand:MODEF 2 "register_operand" "0"))]
16785 UNSPEC_SINCOS_COS))
16786 (set (match_operand:XF 1 "register_operand" "=u")
16787 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16788 "TARGET_USE_FANCY_MATH_387
16789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16790 || TARGET_MIX_SSE_I387)
16791 && flag_unsafe_math_optimizations"
16793 [(set_attr "type" "fpspc")
16794 (set_attr "mode" "XF")])
16797 [(set (match_operand:XF 0 "register_operand" "")
16798 (unspec:XF [(float_extend:XF
16799 (match_operand:MODEF 2 "register_operand" ""))]
16800 UNSPEC_SINCOS_COS))
16801 (set (match_operand:XF 1 "register_operand" "")
16802 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16803 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16804 && !(reload_completed || reload_in_progress)"
16805 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16809 [(set (match_operand:XF 0 "register_operand" "")
16810 (unspec:XF [(float_extend:XF
16811 (match_operand:MODEF 2 "register_operand" ""))]
16812 UNSPEC_SINCOS_COS))
16813 (set (match_operand:XF 1 "register_operand" "")
16814 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16815 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16816 && !(reload_completed || reload_in_progress)"
16817 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16820 (define_expand "sincos<mode>3"
16821 [(use (match_operand:MODEF 0 "register_operand" ""))
16822 (use (match_operand:MODEF 1 "register_operand" ""))
16823 (use (match_operand:MODEF 2 "register_operand" ""))]
16824 "TARGET_USE_FANCY_MATH_387
16825 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16826 || TARGET_MIX_SSE_I387)
16827 && flag_unsafe_math_optimizations"
16829 rtx op0 = gen_reg_rtx (XFmode);
16830 rtx op1 = gen_reg_rtx (XFmode);
16832 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16833 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16834 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16838 (define_insn "fptanxf4_i387"
16839 [(set (match_operand:XF 0 "register_operand" "=f")
16840 (match_operand:XF 3 "const_double_operand" "F"))
16841 (set (match_operand:XF 1 "register_operand" "=u")
16842 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16844 "TARGET_USE_FANCY_MATH_387
16845 && flag_unsafe_math_optimizations
16846 && standard_80387_constant_p (operands[3]) == 2"
16848 [(set_attr "type" "fpspc")
16849 (set_attr "mode" "XF")])
16851 (define_insn "fptan_extend<mode>xf4_i387"
16852 [(set (match_operand:MODEF 0 "register_operand" "=f")
16853 (match_operand:MODEF 3 "const_double_operand" "F"))
16854 (set (match_operand:XF 1 "register_operand" "=u")
16855 (unspec:XF [(float_extend:XF
16856 (match_operand:MODEF 2 "register_operand" "0"))]
16858 "TARGET_USE_FANCY_MATH_387
16859 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16860 || TARGET_MIX_SSE_I387)
16861 && flag_unsafe_math_optimizations
16862 && standard_80387_constant_p (operands[3]) == 2"
16864 [(set_attr "type" "fpspc")
16865 (set_attr "mode" "XF")])
16867 (define_expand "tanxf2"
16868 [(use (match_operand:XF 0 "register_operand" ""))
16869 (use (match_operand:XF 1 "register_operand" ""))]
16870 "TARGET_USE_FANCY_MATH_387
16871 && flag_unsafe_math_optimizations"
16873 rtx one = gen_reg_rtx (XFmode);
16874 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16876 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16880 (define_expand "tan<mode>2"
16881 [(use (match_operand:MODEF 0 "register_operand" ""))
16882 (use (match_operand:MODEF 1 "register_operand" ""))]
16883 "TARGET_USE_FANCY_MATH_387
16884 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16885 || TARGET_MIX_SSE_I387)
16886 && flag_unsafe_math_optimizations"
16888 rtx op0 = gen_reg_rtx (XFmode);
16890 rtx one = gen_reg_rtx (<MODE>mode);
16891 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16893 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16894 operands[1], op2));
16895 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16899 (define_insn "*fpatanxf3_i387"
16900 [(set (match_operand:XF 0 "register_operand" "=f")
16901 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16902 (match_operand:XF 2 "register_operand" "u")]
16904 (clobber (match_scratch:XF 3 "=2"))]
16905 "TARGET_USE_FANCY_MATH_387
16906 && flag_unsafe_math_optimizations"
16908 [(set_attr "type" "fpspc")
16909 (set_attr "mode" "XF")])
16911 (define_insn "fpatan_extend<mode>xf3_i387"
16912 [(set (match_operand:XF 0 "register_operand" "=f")
16913 (unspec:XF [(float_extend:XF
16914 (match_operand:MODEF 1 "register_operand" "0"))
16916 (match_operand:MODEF 2 "register_operand" "u"))]
16918 (clobber (match_scratch:XF 3 "=2"))]
16919 "TARGET_USE_FANCY_MATH_387
16920 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16921 || TARGET_MIX_SSE_I387)
16922 && flag_unsafe_math_optimizations"
16924 [(set_attr "type" "fpspc")
16925 (set_attr "mode" "XF")])
16927 (define_expand "atan2xf3"
16928 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16929 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16930 (match_operand:XF 1 "register_operand" "")]
16932 (clobber (match_scratch:XF 3 ""))])]
16933 "TARGET_USE_FANCY_MATH_387
16934 && flag_unsafe_math_optimizations"
16937 (define_expand "atan2<mode>3"
16938 [(use (match_operand:MODEF 0 "register_operand" ""))
16939 (use (match_operand:MODEF 1 "register_operand" ""))
16940 (use (match_operand:MODEF 2 "register_operand" ""))]
16941 "TARGET_USE_FANCY_MATH_387
16942 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16943 || TARGET_MIX_SSE_I387)
16944 && flag_unsafe_math_optimizations"
16946 rtx op0 = gen_reg_rtx (XFmode);
16948 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16949 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16953 (define_expand "atanxf2"
16954 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16955 (unspec:XF [(match_dup 2)
16956 (match_operand:XF 1 "register_operand" "")]
16958 (clobber (match_scratch:XF 3 ""))])]
16959 "TARGET_USE_FANCY_MATH_387
16960 && flag_unsafe_math_optimizations"
16962 operands[2] = gen_reg_rtx (XFmode);
16963 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16966 (define_expand "atan<mode>2"
16967 [(use (match_operand:MODEF 0 "register_operand" ""))
16968 (use (match_operand:MODEF 1 "register_operand" ""))]
16969 "TARGET_USE_FANCY_MATH_387
16970 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16971 || TARGET_MIX_SSE_I387)
16972 && flag_unsafe_math_optimizations"
16974 rtx op0 = gen_reg_rtx (XFmode);
16976 rtx op2 = gen_reg_rtx (<MODE>mode);
16977 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16979 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16980 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16984 (define_expand "asinxf2"
16985 [(set (match_dup 2)
16986 (mult:XF (match_operand:XF 1 "register_operand" "")
16988 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16989 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16990 (parallel [(set (match_operand:XF 0 "register_operand" "")
16991 (unspec:XF [(match_dup 5) (match_dup 1)]
16993 (clobber (match_scratch:XF 6 ""))])]
16994 "TARGET_USE_FANCY_MATH_387
16995 && flag_unsafe_math_optimizations && !optimize_size"
16999 for (i = 2; i < 6; i++)
17000 operands[i] = gen_reg_rtx (XFmode);
17002 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17005 (define_expand "asin<mode>2"
17006 [(use (match_operand:MODEF 0 "register_operand" ""))
17007 (use (match_operand:MODEF 1 "general_operand" ""))]
17008 "TARGET_USE_FANCY_MATH_387
17009 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17010 || TARGET_MIX_SSE_I387)
17011 && flag_unsafe_math_optimizations && !optimize_size"
17013 rtx op0 = gen_reg_rtx (XFmode);
17014 rtx op1 = gen_reg_rtx (XFmode);
17016 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17017 emit_insn (gen_asinxf2 (op0, op1));
17018 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17022 (define_expand "acosxf2"
17023 [(set (match_dup 2)
17024 (mult:XF (match_operand:XF 1 "register_operand" "")
17026 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17027 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17028 (parallel [(set (match_operand:XF 0 "register_operand" "")
17029 (unspec:XF [(match_dup 1) (match_dup 5)]
17031 (clobber (match_scratch:XF 6 ""))])]
17032 "TARGET_USE_FANCY_MATH_387
17033 && flag_unsafe_math_optimizations && !optimize_size"
17037 for (i = 2; i < 6; i++)
17038 operands[i] = gen_reg_rtx (XFmode);
17040 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17043 (define_expand "acos<mode>2"
17044 [(use (match_operand:MODEF 0 "register_operand" ""))
17045 (use (match_operand:MODEF 1 "general_operand" ""))]
17046 "TARGET_USE_FANCY_MATH_387
17047 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17048 || TARGET_MIX_SSE_I387)
17049 && flag_unsafe_math_optimizations && !optimize_size"
17051 rtx op0 = gen_reg_rtx (XFmode);
17052 rtx op1 = gen_reg_rtx (XFmode);
17054 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17055 emit_insn (gen_acosxf2 (op0, op1));
17056 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17060 (define_insn "fyl2xxf3_i387"
17061 [(set (match_operand:XF 0 "register_operand" "=f")
17062 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17063 (match_operand:XF 2 "register_operand" "u")]
17065 (clobber (match_scratch:XF 3 "=2"))]
17066 "TARGET_USE_FANCY_MATH_387
17067 && flag_unsafe_math_optimizations"
17069 [(set_attr "type" "fpspc")
17070 (set_attr "mode" "XF")])
17072 (define_insn "fyl2x_extend<mode>xf3_i387"
17073 [(set (match_operand:XF 0 "register_operand" "=f")
17074 (unspec:XF [(float_extend:XF
17075 (match_operand:MODEF 1 "register_operand" "0"))
17076 (match_operand:XF 2 "register_operand" "u")]
17078 (clobber (match_scratch:XF 3 "=2"))]
17079 "TARGET_USE_FANCY_MATH_387
17080 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17081 || TARGET_MIX_SSE_I387)
17082 && flag_unsafe_math_optimizations"
17084 [(set_attr "type" "fpspc")
17085 (set_attr "mode" "XF")])
17087 (define_expand "logxf2"
17088 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17089 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17090 (match_dup 2)] UNSPEC_FYL2X))
17091 (clobber (match_scratch:XF 3 ""))])]
17092 "TARGET_USE_FANCY_MATH_387
17093 && flag_unsafe_math_optimizations"
17095 operands[2] = gen_reg_rtx (XFmode);
17096 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17099 (define_expand "log<mode>2"
17100 [(use (match_operand:MODEF 0 "register_operand" ""))
17101 (use (match_operand:MODEF 1 "register_operand" ""))]
17102 "TARGET_USE_FANCY_MATH_387
17103 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17104 || TARGET_MIX_SSE_I387)
17105 && flag_unsafe_math_optimizations"
17107 rtx op0 = gen_reg_rtx (XFmode);
17109 rtx op2 = gen_reg_rtx (XFmode);
17110 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17112 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17113 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17117 (define_expand "log10xf2"
17118 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17119 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17120 (match_dup 2)] UNSPEC_FYL2X))
17121 (clobber (match_scratch:XF 3 ""))])]
17122 "TARGET_USE_FANCY_MATH_387
17123 && flag_unsafe_math_optimizations"
17125 operands[2] = gen_reg_rtx (XFmode);
17126 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17129 (define_expand "log10<mode>2"
17130 [(use (match_operand:MODEF 0 "register_operand" ""))
17131 (use (match_operand:MODEF 1 "register_operand" ""))]
17132 "TARGET_USE_FANCY_MATH_387
17133 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17134 || TARGET_MIX_SSE_I387)
17135 && flag_unsafe_math_optimizations"
17137 rtx op0 = gen_reg_rtx (XFmode);
17139 rtx op2 = gen_reg_rtx (XFmode);
17140 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17142 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17143 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17147 (define_expand "log2xf2"
17148 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17149 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17150 (match_dup 2)] UNSPEC_FYL2X))
17151 (clobber (match_scratch:XF 3 ""))])]
17152 "TARGET_USE_FANCY_MATH_387
17153 && flag_unsafe_math_optimizations"
17155 operands[2] = gen_reg_rtx (XFmode);
17156 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17159 (define_expand "log2<mode>2"
17160 [(use (match_operand:MODEF 0 "register_operand" ""))
17161 (use (match_operand:MODEF 1 "register_operand" ""))]
17162 "TARGET_USE_FANCY_MATH_387
17163 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17164 || TARGET_MIX_SSE_I387)
17165 && flag_unsafe_math_optimizations"
17167 rtx op0 = gen_reg_rtx (XFmode);
17169 rtx op2 = gen_reg_rtx (XFmode);
17170 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17172 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17173 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17177 (define_insn "fyl2xp1xf3_i387"
17178 [(set (match_operand:XF 0 "register_operand" "=f")
17179 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17180 (match_operand:XF 2 "register_operand" "u")]
17182 (clobber (match_scratch:XF 3 "=2"))]
17183 "TARGET_USE_FANCY_MATH_387
17184 && flag_unsafe_math_optimizations"
17186 [(set_attr "type" "fpspc")
17187 (set_attr "mode" "XF")])
17189 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17190 [(set (match_operand:XF 0 "register_operand" "=f")
17191 (unspec:XF [(float_extend:XF
17192 (match_operand:MODEF 1 "register_operand" "0"))
17193 (match_operand:XF 2 "register_operand" "u")]
17195 (clobber (match_scratch:XF 3 "=2"))]
17196 "TARGET_USE_FANCY_MATH_387
17197 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17198 || TARGET_MIX_SSE_I387)
17199 && flag_unsafe_math_optimizations"
17201 [(set_attr "type" "fpspc")
17202 (set_attr "mode" "XF")])
17204 (define_expand "log1pxf2"
17205 [(use (match_operand:XF 0 "register_operand" ""))
17206 (use (match_operand:XF 1 "register_operand" ""))]
17207 "TARGET_USE_FANCY_MATH_387
17208 && flag_unsafe_math_optimizations && !optimize_size"
17210 ix86_emit_i387_log1p (operands[0], operands[1]);
17214 (define_expand "log1p<mode>2"
17215 [(use (match_operand:MODEF 0 "register_operand" ""))
17216 (use (match_operand:MODEF 1 "register_operand" ""))]
17217 "TARGET_USE_FANCY_MATH_387
17218 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17219 || TARGET_MIX_SSE_I387)
17220 && flag_unsafe_math_optimizations && !optimize_size"
17222 rtx op0 = gen_reg_rtx (XFmode);
17224 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17226 ix86_emit_i387_log1p (op0, operands[1]);
17227 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17231 (define_insn "fxtractxf3_i387"
17232 [(set (match_operand:XF 0 "register_operand" "=f")
17233 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17234 UNSPEC_XTRACT_FRACT))
17235 (set (match_operand:XF 1 "register_operand" "=u")
17236 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17237 "TARGET_USE_FANCY_MATH_387
17238 && flag_unsafe_math_optimizations"
17240 [(set_attr "type" "fpspc")
17241 (set_attr "mode" "XF")])
17243 (define_insn "fxtract_extend<mode>xf3_i387"
17244 [(set (match_operand:XF 0 "register_operand" "=f")
17245 (unspec:XF [(float_extend:XF
17246 (match_operand:MODEF 2 "register_operand" "0"))]
17247 UNSPEC_XTRACT_FRACT))
17248 (set (match_operand:XF 1 "register_operand" "=u")
17249 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17250 "TARGET_USE_FANCY_MATH_387
17251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17252 || TARGET_MIX_SSE_I387)
17253 && flag_unsafe_math_optimizations"
17255 [(set_attr "type" "fpspc")
17256 (set_attr "mode" "XF")])
17258 (define_expand "logbxf2"
17259 [(parallel [(set (match_dup 2)
17260 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17261 UNSPEC_XTRACT_FRACT))
17262 (set (match_operand:XF 0 "register_operand" "")
17263 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17264 "TARGET_USE_FANCY_MATH_387
17265 && flag_unsafe_math_optimizations"
17267 operands[2] = gen_reg_rtx (XFmode);
17270 (define_expand "logb<mode>2"
17271 [(use (match_operand:MODEF 0 "register_operand" ""))
17272 (use (match_operand:MODEF 1 "register_operand" ""))]
17273 "TARGET_USE_FANCY_MATH_387
17274 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17275 || TARGET_MIX_SSE_I387)
17276 && flag_unsafe_math_optimizations"
17278 rtx op0 = gen_reg_rtx (XFmode);
17279 rtx op1 = gen_reg_rtx (XFmode);
17281 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17282 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17286 (define_expand "ilogbxf2"
17287 [(use (match_operand:SI 0 "register_operand" ""))
17288 (use (match_operand:XF 1 "register_operand" ""))]
17289 "TARGET_USE_FANCY_MATH_387
17290 && flag_unsafe_math_optimizations && !optimize_size"
17292 rtx op0 = gen_reg_rtx (XFmode);
17293 rtx op1 = gen_reg_rtx (XFmode);
17295 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17296 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17300 (define_expand "ilogb<mode>2"
17301 [(use (match_operand:SI 0 "register_operand" ""))
17302 (use (match_operand:MODEF 1 "register_operand" ""))]
17303 "TARGET_USE_FANCY_MATH_387
17304 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17305 || TARGET_MIX_SSE_I387)
17306 && flag_unsafe_math_optimizations && !optimize_size"
17308 rtx op0 = gen_reg_rtx (XFmode);
17309 rtx op1 = gen_reg_rtx (XFmode);
17311 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17312 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17316 (define_insn "*f2xm1xf2_i387"
17317 [(set (match_operand:XF 0 "register_operand" "=f")
17318 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17320 "TARGET_USE_FANCY_MATH_387
17321 && flag_unsafe_math_optimizations"
17323 [(set_attr "type" "fpspc")
17324 (set_attr "mode" "XF")])
17326 (define_insn "*fscalexf4_i387"
17327 [(set (match_operand:XF 0 "register_operand" "=f")
17328 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17329 (match_operand:XF 3 "register_operand" "1")]
17330 UNSPEC_FSCALE_FRACT))
17331 (set (match_operand:XF 1 "register_operand" "=u")
17332 (unspec:XF [(match_dup 2) (match_dup 3)]
17333 UNSPEC_FSCALE_EXP))]
17334 "TARGET_USE_FANCY_MATH_387
17335 && flag_unsafe_math_optimizations"
17337 [(set_attr "type" "fpspc")
17338 (set_attr "mode" "XF")])
17340 (define_expand "expNcorexf3"
17341 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17342 (match_operand:XF 2 "register_operand" "")))
17343 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17344 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17345 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17346 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17347 (parallel [(set (match_operand:XF 0 "register_operand" "")
17348 (unspec:XF [(match_dup 8) (match_dup 4)]
17349 UNSPEC_FSCALE_FRACT))
17351 (unspec:XF [(match_dup 8) (match_dup 4)]
17352 UNSPEC_FSCALE_EXP))])]
17353 "TARGET_USE_FANCY_MATH_387
17354 && flag_unsafe_math_optimizations && !optimize_size"
17358 for (i = 3; i < 10; i++)
17359 operands[i] = gen_reg_rtx (XFmode);
17361 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17364 (define_expand "expxf2"
17365 [(use (match_operand:XF 0 "register_operand" ""))
17366 (use (match_operand:XF 1 "register_operand" ""))]
17367 "TARGET_USE_FANCY_MATH_387
17368 && flag_unsafe_math_optimizations && !optimize_size"
17370 rtx op2 = gen_reg_rtx (XFmode);
17371 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17373 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17377 (define_expand "exp<mode>2"
17378 [(use (match_operand:MODEF 0 "register_operand" ""))
17379 (use (match_operand:MODEF 1 "general_operand" ""))]
17380 "TARGET_USE_FANCY_MATH_387
17381 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17382 || TARGET_MIX_SSE_I387)
17383 && flag_unsafe_math_optimizations && !optimize_size"
17385 rtx op0 = gen_reg_rtx (XFmode);
17386 rtx op1 = gen_reg_rtx (XFmode);
17388 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17389 emit_insn (gen_expxf2 (op0, op1));
17390 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17394 (define_expand "exp10xf2"
17395 [(use (match_operand:XF 0 "register_operand" ""))
17396 (use (match_operand:XF 1 "register_operand" ""))]
17397 "TARGET_USE_FANCY_MATH_387
17398 && flag_unsafe_math_optimizations && !optimize_size"
17400 rtx op2 = gen_reg_rtx (XFmode);
17401 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17403 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17407 (define_expand "exp10<mode>2"
17408 [(use (match_operand:MODEF 0 "register_operand" ""))
17409 (use (match_operand:MODEF 1 "general_operand" ""))]
17410 "TARGET_USE_FANCY_MATH_387
17411 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17412 || TARGET_MIX_SSE_I387)
17413 && flag_unsafe_math_optimizations && !optimize_size"
17415 rtx op0 = gen_reg_rtx (XFmode);
17416 rtx op1 = gen_reg_rtx (XFmode);
17418 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17419 emit_insn (gen_exp10xf2 (op0, op1));
17420 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17424 (define_expand "exp2xf2"
17425 [(use (match_operand:XF 0 "register_operand" ""))
17426 (use (match_operand:XF 1 "register_operand" ""))]
17427 "TARGET_USE_FANCY_MATH_387
17428 && flag_unsafe_math_optimizations && !optimize_size"
17430 rtx op2 = gen_reg_rtx (XFmode);
17431 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17433 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17437 (define_expand "exp2<mode>2"
17438 [(use (match_operand:MODEF 0 "register_operand" ""))
17439 (use (match_operand:MODEF 1 "general_operand" ""))]
17440 "TARGET_USE_FANCY_MATH_387
17441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17442 || TARGET_MIX_SSE_I387)
17443 && flag_unsafe_math_optimizations && !optimize_size"
17445 rtx op0 = gen_reg_rtx (XFmode);
17446 rtx op1 = gen_reg_rtx (XFmode);
17448 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17449 emit_insn (gen_exp2xf2 (op0, op1));
17450 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17454 (define_expand "expm1xf2"
17455 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17457 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17458 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17459 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17460 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17461 (parallel [(set (match_dup 7)
17462 (unspec:XF [(match_dup 6) (match_dup 4)]
17463 UNSPEC_FSCALE_FRACT))
17465 (unspec:XF [(match_dup 6) (match_dup 4)]
17466 UNSPEC_FSCALE_EXP))])
17467 (parallel [(set (match_dup 10)
17468 (unspec:XF [(match_dup 9) (match_dup 8)]
17469 UNSPEC_FSCALE_FRACT))
17470 (set (match_dup 11)
17471 (unspec:XF [(match_dup 9) (match_dup 8)]
17472 UNSPEC_FSCALE_EXP))])
17473 (set (match_dup 12) (minus:XF (match_dup 10)
17474 (float_extend:XF (match_dup 13))))
17475 (set (match_operand:XF 0 "register_operand" "")
17476 (plus:XF (match_dup 12) (match_dup 7)))]
17477 "TARGET_USE_FANCY_MATH_387
17478 && flag_unsafe_math_optimizations && !optimize_size"
17482 for (i = 2; i < 13; i++)
17483 operands[i] = gen_reg_rtx (XFmode);
17486 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17488 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17491 (define_expand "expm1<mode>2"
17492 [(use (match_operand:MODEF 0 "register_operand" ""))
17493 (use (match_operand:MODEF 1 "general_operand" ""))]
17494 "TARGET_USE_FANCY_MATH_387
17495 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17496 || TARGET_MIX_SSE_I387)
17497 && flag_unsafe_math_optimizations && !optimize_size"
17499 rtx op0 = gen_reg_rtx (XFmode);
17500 rtx op1 = gen_reg_rtx (XFmode);
17502 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17503 emit_insn (gen_expm1xf2 (op0, op1));
17504 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17508 (define_expand "ldexpxf3"
17509 [(set (match_dup 3)
17510 (float:XF (match_operand:SI 2 "register_operand" "")))
17511 (parallel [(set (match_operand:XF 0 " register_operand" "")
17512 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17514 UNSPEC_FSCALE_FRACT))
17516 (unspec:XF [(match_dup 1) (match_dup 3)]
17517 UNSPEC_FSCALE_EXP))])]
17518 "TARGET_USE_FANCY_MATH_387
17519 && flag_unsafe_math_optimizations && !optimize_size"
17521 operands[3] = gen_reg_rtx (XFmode);
17522 operands[4] = gen_reg_rtx (XFmode);
17525 (define_expand "ldexp<mode>3"
17526 [(use (match_operand:MODEF 0 "register_operand" ""))
17527 (use (match_operand:MODEF 1 "general_operand" ""))
17528 (use (match_operand:SI 2 "register_operand" ""))]
17529 "TARGET_USE_FANCY_MATH_387
17530 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17531 || TARGET_MIX_SSE_I387)
17532 && flag_unsafe_math_optimizations && !optimize_size"
17534 rtx op0 = gen_reg_rtx (XFmode);
17535 rtx op1 = gen_reg_rtx (XFmode);
17537 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17538 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17539 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17543 (define_expand "scalbxf3"
17544 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17545 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17546 (match_operand:XF 2 "register_operand" "")]
17547 UNSPEC_FSCALE_FRACT))
17549 (unspec:XF [(match_dup 1) (match_dup 2)]
17550 UNSPEC_FSCALE_EXP))])]
17551 "TARGET_USE_FANCY_MATH_387
17552 && flag_unsafe_math_optimizations && !optimize_size"
17554 operands[3] = gen_reg_rtx (XFmode);
17557 (define_expand "scalb<mode>3"
17558 [(use (match_operand:MODEF 0 "register_operand" ""))
17559 (use (match_operand:MODEF 1 "general_operand" ""))
17560 (use (match_operand:MODEF 2 "register_operand" ""))]
17561 "TARGET_USE_FANCY_MATH_387
17562 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17563 || TARGET_MIX_SSE_I387)
17564 && flag_unsafe_math_optimizations && !optimize_size"
17566 rtx op0 = gen_reg_rtx (XFmode);
17567 rtx op1 = gen_reg_rtx (XFmode);
17568 rtx op2 = gen_reg_rtx (XFmode);
17570 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17571 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17572 emit_insn (gen_scalbxf3 (op0, op1, op2));
17573 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17578 (define_insn "sse4_1_round<mode>2"
17579 [(set (match_operand:MODEF 0 "register_operand" "=x")
17580 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17581 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17584 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17585 [(set_attr "type" "ssecvt")
17586 (set_attr "prefix_extra" "1")
17587 (set_attr "mode" "<MODE>")])
17589 (define_insn "rintxf2"
17590 [(set (match_operand:XF 0 "register_operand" "=f")
17591 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17593 "TARGET_USE_FANCY_MATH_387
17594 && flag_unsafe_math_optimizations"
17596 [(set_attr "type" "fpspc")
17597 (set_attr "mode" "XF")])
17599 (define_expand "rint<mode>2"
17600 [(use (match_operand:MODEF 0 "register_operand" ""))
17601 (use (match_operand:MODEF 1 "register_operand" ""))]
17602 "(TARGET_USE_FANCY_MATH_387
17603 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17604 || TARGET_MIX_SSE_I387)
17605 && flag_unsafe_math_optimizations)
17606 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17607 && !flag_trapping_math
17608 && (TARGET_ROUND || !optimize_size))"
17610 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17611 && !flag_trapping_math
17612 && (TARGET_ROUND || !optimize_size))
17615 emit_insn (gen_sse4_1_round<mode>2
17616 (operands[0], operands[1], GEN_INT (0x04)));
17618 ix86_expand_rint (operand0, operand1);
17622 rtx op0 = gen_reg_rtx (XFmode);
17623 rtx op1 = gen_reg_rtx (XFmode);
17625 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17626 emit_insn (gen_rintxf2 (op0, op1));
17628 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17633 (define_expand "round<mode>2"
17634 [(match_operand:MODEF 0 "register_operand" "")
17635 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17636 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17637 && !flag_trapping_math && !flag_rounding_math
17640 if (TARGET_64BIT || (<MODE>mode != DFmode))
17641 ix86_expand_round (operand0, operand1);
17643 ix86_expand_rounddf_32 (operand0, operand1);
17647 (define_insn_and_split "*fistdi2_1"
17648 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17649 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17651 "TARGET_USE_FANCY_MATH_387
17652 && !(reload_completed || reload_in_progress)"
17657 if (memory_operand (operands[0], VOIDmode))
17658 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17661 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17662 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17667 [(set_attr "type" "fpspc")
17668 (set_attr "mode" "DI")])
17670 (define_insn "fistdi2"
17671 [(set (match_operand:DI 0 "memory_operand" "=m")
17672 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17674 (clobber (match_scratch:XF 2 "=&1f"))]
17675 "TARGET_USE_FANCY_MATH_387"
17676 "* return output_fix_trunc (insn, operands, 0);"
17677 [(set_attr "type" "fpspc")
17678 (set_attr "mode" "DI")])
17680 (define_insn "fistdi2_with_temp"
17681 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17682 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17684 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17685 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17686 "TARGET_USE_FANCY_MATH_387"
17688 [(set_attr "type" "fpspc")
17689 (set_attr "mode" "DI")])
17692 [(set (match_operand:DI 0 "register_operand" "")
17693 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17695 (clobber (match_operand:DI 2 "memory_operand" ""))
17696 (clobber (match_scratch 3 ""))]
17698 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17699 (clobber (match_dup 3))])
17700 (set (match_dup 0) (match_dup 2))]
17704 [(set (match_operand:DI 0 "memory_operand" "")
17705 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17707 (clobber (match_operand:DI 2 "memory_operand" ""))
17708 (clobber (match_scratch 3 ""))]
17710 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17711 (clobber (match_dup 3))])]
17714 (define_insn_and_split "*fist<mode>2_1"
17715 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17716 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17718 "TARGET_USE_FANCY_MATH_387
17719 && !(reload_completed || reload_in_progress)"
17724 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17725 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17729 [(set_attr "type" "fpspc")
17730 (set_attr "mode" "<MODE>")])
17732 (define_insn "fist<mode>2"
17733 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17734 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17736 "TARGET_USE_FANCY_MATH_387"
17737 "* return output_fix_trunc (insn, operands, 0);"
17738 [(set_attr "type" "fpspc")
17739 (set_attr "mode" "<MODE>")])
17741 (define_insn "fist<mode>2_with_temp"
17742 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17743 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17745 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17746 "TARGET_USE_FANCY_MATH_387"
17748 [(set_attr "type" "fpspc")
17749 (set_attr "mode" "<MODE>")])
17752 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17753 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17755 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17757 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17758 (set (match_dup 0) (match_dup 2))]
17762 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17763 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17765 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17767 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17770 (define_expand "lrintxf<mode>2"
17771 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17772 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17774 "TARGET_USE_FANCY_MATH_387"
17777 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17778 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17779 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17780 UNSPEC_FIX_NOTRUNC))]
17781 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17782 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17785 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17786 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17787 (match_operand:MODEF 1 "register_operand" "")]
17788 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17789 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17790 && !flag_trapping_math && !flag_rounding_math
17793 ix86_expand_lround (operand0, operand1);
17797 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17798 (define_insn_and_split "frndintxf2_floor"
17799 [(set (match_operand:XF 0 "register_operand" "")
17800 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17801 UNSPEC_FRNDINT_FLOOR))
17802 (clobber (reg:CC FLAGS_REG))]
17803 "TARGET_USE_FANCY_MATH_387
17804 && flag_unsafe_math_optimizations
17805 && !(reload_completed || reload_in_progress)"
17810 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17812 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17813 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17815 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17816 operands[2], operands[3]));
17819 [(set_attr "type" "frndint")
17820 (set_attr "i387_cw" "floor")
17821 (set_attr "mode" "XF")])
17823 (define_insn "frndintxf2_floor_i387"
17824 [(set (match_operand:XF 0 "register_operand" "=f")
17825 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17826 UNSPEC_FRNDINT_FLOOR))
17827 (use (match_operand:HI 2 "memory_operand" "m"))
17828 (use (match_operand:HI 3 "memory_operand" "m"))]
17829 "TARGET_USE_FANCY_MATH_387
17830 && flag_unsafe_math_optimizations"
17831 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17832 [(set_attr "type" "frndint")
17833 (set_attr "i387_cw" "floor")
17834 (set_attr "mode" "XF")])
17836 (define_expand "floorxf2"
17837 [(use (match_operand:XF 0 "register_operand" ""))
17838 (use (match_operand:XF 1 "register_operand" ""))]
17839 "TARGET_USE_FANCY_MATH_387
17840 && flag_unsafe_math_optimizations && !optimize_size"
17842 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17846 (define_expand "floor<mode>2"
17847 [(use (match_operand:MODEF 0 "register_operand" ""))
17848 (use (match_operand:MODEF 1 "register_operand" ""))]
17849 "(TARGET_USE_FANCY_MATH_387
17850 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17851 || TARGET_MIX_SSE_I387)
17852 && flag_unsafe_math_optimizations && !optimize_size)
17853 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17854 && !flag_trapping_math
17855 && (TARGET_ROUND || !optimize_size))"
17857 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17858 && !flag_trapping_math
17859 && (TARGET_ROUND || !optimize_size))
17862 emit_insn (gen_sse4_1_round<mode>2
17863 (operands[0], operands[1], GEN_INT (0x01)));
17864 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17865 ix86_expand_floorceil (operand0, operand1, true);
17867 ix86_expand_floorceildf_32 (operand0, operand1, true);
17871 rtx op0 = gen_reg_rtx (XFmode);
17872 rtx op1 = gen_reg_rtx (XFmode);
17874 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17875 emit_insn (gen_frndintxf2_floor (op0, op1));
17877 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17882 (define_insn_and_split "*fist<mode>2_floor_1"
17883 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17884 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17885 UNSPEC_FIST_FLOOR))
17886 (clobber (reg:CC FLAGS_REG))]
17887 "TARGET_USE_FANCY_MATH_387
17888 && flag_unsafe_math_optimizations
17889 && !(reload_completed || reload_in_progress)"
17894 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17896 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17897 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17898 if (memory_operand (operands[0], VOIDmode))
17899 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17900 operands[2], operands[3]));
17903 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17904 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17905 operands[2], operands[3],
17910 [(set_attr "type" "fistp")
17911 (set_attr "i387_cw" "floor")
17912 (set_attr "mode" "<MODE>")])
17914 (define_insn "fistdi2_floor"
17915 [(set (match_operand:DI 0 "memory_operand" "=m")
17916 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17917 UNSPEC_FIST_FLOOR))
17918 (use (match_operand:HI 2 "memory_operand" "m"))
17919 (use (match_operand:HI 3 "memory_operand" "m"))
17920 (clobber (match_scratch:XF 4 "=&1f"))]
17921 "TARGET_USE_FANCY_MATH_387
17922 && flag_unsafe_math_optimizations"
17923 "* return output_fix_trunc (insn, operands, 0);"
17924 [(set_attr "type" "fistp")
17925 (set_attr "i387_cw" "floor")
17926 (set_attr "mode" "DI")])
17928 (define_insn "fistdi2_floor_with_temp"
17929 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17930 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17931 UNSPEC_FIST_FLOOR))
17932 (use (match_operand:HI 2 "memory_operand" "m,m"))
17933 (use (match_operand:HI 3 "memory_operand" "m,m"))
17934 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17935 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17936 "TARGET_USE_FANCY_MATH_387
17937 && flag_unsafe_math_optimizations"
17939 [(set_attr "type" "fistp")
17940 (set_attr "i387_cw" "floor")
17941 (set_attr "mode" "DI")])
17944 [(set (match_operand:DI 0 "register_operand" "")
17945 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17946 UNSPEC_FIST_FLOOR))
17947 (use (match_operand:HI 2 "memory_operand" ""))
17948 (use (match_operand:HI 3 "memory_operand" ""))
17949 (clobber (match_operand:DI 4 "memory_operand" ""))
17950 (clobber (match_scratch 5 ""))]
17952 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17953 (use (match_dup 2))
17954 (use (match_dup 3))
17955 (clobber (match_dup 5))])
17956 (set (match_dup 0) (match_dup 4))]
17960 [(set (match_operand:DI 0 "memory_operand" "")
17961 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17962 UNSPEC_FIST_FLOOR))
17963 (use (match_operand:HI 2 "memory_operand" ""))
17964 (use (match_operand:HI 3 "memory_operand" ""))
17965 (clobber (match_operand:DI 4 "memory_operand" ""))
17966 (clobber (match_scratch 5 ""))]
17968 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17969 (use (match_dup 2))
17970 (use (match_dup 3))
17971 (clobber (match_dup 5))])]
17974 (define_insn "fist<mode>2_floor"
17975 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17976 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17977 UNSPEC_FIST_FLOOR))
17978 (use (match_operand:HI 2 "memory_operand" "m"))
17979 (use (match_operand:HI 3 "memory_operand" "m"))]
17980 "TARGET_USE_FANCY_MATH_387
17981 && flag_unsafe_math_optimizations"
17982 "* return output_fix_trunc (insn, operands, 0);"
17983 [(set_attr "type" "fistp")
17984 (set_attr "i387_cw" "floor")
17985 (set_attr "mode" "<MODE>")])
17987 (define_insn "fist<mode>2_floor_with_temp"
17988 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17989 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17990 UNSPEC_FIST_FLOOR))
17991 (use (match_operand:HI 2 "memory_operand" "m,m"))
17992 (use (match_operand:HI 3 "memory_operand" "m,m"))
17993 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17994 "TARGET_USE_FANCY_MATH_387
17995 && flag_unsafe_math_optimizations"
17997 [(set_attr "type" "fistp")
17998 (set_attr "i387_cw" "floor")
17999 (set_attr "mode" "<MODE>")])
18002 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18003 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18004 UNSPEC_FIST_FLOOR))
18005 (use (match_operand:HI 2 "memory_operand" ""))
18006 (use (match_operand:HI 3 "memory_operand" ""))
18007 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18009 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18010 UNSPEC_FIST_FLOOR))
18011 (use (match_dup 2))
18012 (use (match_dup 3))])
18013 (set (match_dup 0) (match_dup 4))]
18017 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18018 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18019 UNSPEC_FIST_FLOOR))
18020 (use (match_operand:HI 2 "memory_operand" ""))
18021 (use (match_operand:HI 3 "memory_operand" ""))
18022 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18024 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18025 UNSPEC_FIST_FLOOR))
18026 (use (match_dup 2))
18027 (use (match_dup 3))])]
18030 (define_expand "lfloorxf<mode>2"
18031 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18032 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18033 UNSPEC_FIST_FLOOR))
18034 (clobber (reg:CC FLAGS_REG))])]
18035 "TARGET_USE_FANCY_MATH_387
18036 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18037 && flag_unsafe_math_optimizations"
18040 (define_expand "lfloor<mode>di2"
18041 [(match_operand:DI 0 "nonimmediate_operand" "")
18042 (match_operand:MODEF 1 "register_operand" "")]
18043 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18044 && !flag_trapping_math
18047 ix86_expand_lfloorceil (operand0, operand1, true);
18051 (define_expand "lfloor<mode>si2"
18052 [(match_operand:SI 0 "nonimmediate_operand" "")
18053 (match_operand:MODEF 1 "register_operand" "")]
18054 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18055 && !flag_trapping_math
18056 && (!optimize_size || !TARGET_64BIT)"
18058 ix86_expand_lfloorceil (operand0, operand1, true);
18062 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18063 (define_insn_and_split "frndintxf2_ceil"
18064 [(set (match_operand:XF 0 "register_operand" "")
18065 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18066 UNSPEC_FRNDINT_CEIL))
18067 (clobber (reg:CC FLAGS_REG))]
18068 "TARGET_USE_FANCY_MATH_387
18069 && flag_unsafe_math_optimizations
18070 && !(reload_completed || reload_in_progress)"
18075 ix86_optimize_mode_switching[I387_CEIL] = 1;
18077 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18078 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18080 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18081 operands[2], operands[3]));
18084 [(set_attr "type" "frndint")
18085 (set_attr "i387_cw" "ceil")
18086 (set_attr "mode" "XF")])
18088 (define_insn "frndintxf2_ceil_i387"
18089 [(set (match_operand:XF 0 "register_operand" "=f")
18090 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18091 UNSPEC_FRNDINT_CEIL))
18092 (use (match_operand:HI 2 "memory_operand" "m"))
18093 (use (match_operand:HI 3 "memory_operand" "m"))]
18094 "TARGET_USE_FANCY_MATH_387
18095 && flag_unsafe_math_optimizations"
18096 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18097 [(set_attr "type" "frndint")
18098 (set_attr "i387_cw" "ceil")
18099 (set_attr "mode" "XF")])
18101 (define_expand "ceilxf2"
18102 [(use (match_operand:XF 0 "register_operand" ""))
18103 (use (match_operand:XF 1 "register_operand" ""))]
18104 "TARGET_USE_FANCY_MATH_387
18105 && flag_unsafe_math_optimizations && !optimize_size"
18107 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18111 (define_expand "ceil<mode>2"
18112 [(use (match_operand:MODEF 0 "register_operand" ""))
18113 (use (match_operand:MODEF 1 "register_operand" ""))]
18114 "(TARGET_USE_FANCY_MATH_387
18115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18116 || TARGET_MIX_SSE_I387)
18117 && flag_unsafe_math_optimizations && !optimize_size)
18118 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18119 && !flag_trapping_math
18120 && (TARGET_ROUND || !optimize_size))"
18122 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18123 && !flag_trapping_math
18124 && (TARGET_ROUND || !optimize_size))
18127 emit_insn (gen_sse4_1_round<mode>2
18128 (operands[0], operands[1], GEN_INT (0x02)));
18129 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18130 ix86_expand_floorceil (operand0, operand1, false);
18132 ix86_expand_floorceildf_32 (operand0, operand1, false);
18136 rtx op0 = gen_reg_rtx (XFmode);
18137 rtx op1 = gen_reg_rtx (XFmode);
18139 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18140 emit_insn (gen_frndintxf2_ceil (op0, op1));
18142 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18147 (define_insn_and_split "*fist<mode>2_ceil_1"
18148 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18149 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18151 (clobber (reg:CC FLAGS_REG))]
18152 "TARGET_USE_FANCY_MATH_387
18153 && flag_unsafe_math_optimizations
18154 && !(reload_completed || reload_in_progress)"
18159 ix86_optimize_mode_switching[I387_CEIL] = 1;
18161 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18162 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18163 if (memory_operand (operands[0], VOIDmode))
18164 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18165 operands[2], operands[3]));
18168 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18169 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18170 operands[2], operands[3],
18175 [(set_attr "type" "fistp")
18176 (set_attr "i387_cw" "ceil")
18177 (set_attr "mode" "<MODE>")])
18179 (define_insn "fistdi2_ceil"
18180 [(set (match_operand:DI 0 "memory_operand" "=m")
18181 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18183 (use (match_operand:HI 2 "memory_operand" "m"))
18184 (use (match_operand:HI 3 "memory_operand" "m"))
18185 (clobber (match_scratch:XF 4 "=&1f"))]
18186 "TARGET_USE_FANCY_MATH_387
18187 && flag_unsafe_math_optimizations"
18188 "* return output_fix_trunc (insn, operands, 0);"
18189 [(set_attr "type" "fistp")
18190 (set_attr "i387_cw" "ceil")
18191 (set_attr "mode" "DI")])
18193 (define_insn "fistdi2_ceil_with_temp"
18194 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18195 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18197 (use (match_operand:HI 2 "memory_operand" "m,m"))
18198 (use (match_operand:HI 3 "memory_operand" "m,m"))
18199 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18200 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18201 "TARGET_USE_FANCY_MATH_387
18202 && flag_unsafe_math_optimizations"
18204 [(set_attr "type" "fistp")
18205 (set_attr "i387_cw" "ceil")
18206 (set_attr "mode" "DI")])
18209 [(set (match_operand:DI 0 "register_operand" "")
18210 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18212 (use (match_operand:HI 2 "memory_operand" ""))
18213 (use (match_operand:HI 3 "memory_operand" ""))
18214 (clobber (match_operand:DI 4 "memory_operand" ""))
18215 (clobber (match_scratch 5 ""))]
18217 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18218 (use (match_dup 2))
18219 (use (match_dup 3))
18220 (clobber (match_dup 5))])
18221 (set (match_dup 0) (match_dup 4))]
18225 [(set (match_operand:DI 0 "memory_operand" "")
18226 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18228 (use (match_operand:HI 2 "memory_operand" ""))
18229 (use (match_operand:HI 3 "memory_operand" ""))
18230 (clobber (match_operand:DI 4 "memory_operand" ""))
18231 (clobber (match_scratch 5 ""))]
18233 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18234 (use (match_dup 2))
18235 (use (match_dup 3))
18236 (clobber (match_dup 5))])]
18239 (define_insn "fist<mode>2_ceil"
18240 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18241 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18243 (use (match_operand:HI 2 "memory_operand" "m"))
18244 (use (match_operand:HI 3 "memory_operand" "m"))]
18245 "TARGET_USE_FANCY_MATH_387
18246 && flag_unsafe_math_optimizations"
18247 "* return output_fix_trunc (insn, operands, 0);"
18248 [(set_attr "type" "fistp")
18249 (set_attr "i387_cw" "ceil")
18250 (set_attr "mode" "<MODE>")])
18252 (define_insn "fist<mode>2_ceil_with_temp"
18253 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18254 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18256 (use (match_operand:HI 2 "memory_operand" "m,m"))
18257 (use (match_operand:HI 3 "memory_operand" "m,m"))
18258 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18259 "TARGET_USE_FANCY_MATH_387
18260 && flag_unsafe_math_optimizations"
18262 [(set_attr "type" "fistp")
18263 (set_attr "i387_cw" "ceil")
18264 (set_attr "mode" "<MODE>")])
18267 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18268 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18270 (use (match_operand:HI 2 "memory_operand" ""))
18271 (use (match_operand:HI 3 "memory_operand" ""))
18272 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18274 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18276 (use (match_dup 2))
18277 (use (match_dup 3))])
18278 (set (match_dup 0) (match_dup 4))]
18282 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18283 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18285 (use (match_operand:HI 2 "memory_operand" ""))
18286 (use (match_operand:HI 3 "memory_operand" ""))
18287 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18289 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18291 (use (match_dup 2))
18292 (use (match_dup 3))])]
18295 (define_expand "lceilxf<mode>2"
18296 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18297 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18299 (clobber (reg:CC FLAGS_REG))])]
18300 "TARGET_USE_FANCY_MATH_387
18301 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18302 && flag_unsafe_math_optimizations"
18305 (define_expand "lceil<mode>di2"
18306 [(match_operand:DI 0 "nonimmediate_operand" "")
18307 (match_operand:MODEF 1 "register_operand" "")]
18308 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18309 && !flag_trapping_math"
18311 ix86_expand_lfloorceil (operand0, operand1, false);
18315 (define_expand "lceil<mode>si2"
18316 [(match_operand:SI 0 "nonimmediate_operand" "")
18317 (match_operand:MODEF 1 "register_operand" "")]
18318 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18319 && !flag_trapping_math"
18321 ix86_expand_lfloorceil (operand0, operand1, false);
18325 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18326 (define_insn_and_split "frndintxf2_trunc"
18327 [(set (match_operand:XF 0 "register_operand" "")
18328 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18329 UNSPEC_FRNDINT_TRUNC))
18330 (clobber (reg:CC FLAGS_REG))]
18331 "TARGET_USE_FANCY_MATH_387
18332 && flag_unsafe_math_optimizations
18333 && !(reload_completed || reload_in_progress)"
18338 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18340 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18341 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18343 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18344 operands[2], operands[3]));
18347 [(set_attr "type" "frndint")
18348 (set_attr "i387_cw" "trunc")
18349 (set_attr "mode" "XF")])
18351 (define_insn "frndintxf2_trunc_i387"
18352 [(set (match_operand:XF 0 "register_operand" "=f")
18353 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18354 UNSPEC_FRNDINT_TRUNC))
18355 (use (match_operand:HI 2 "memory_operand" "m"))
18356 (use (match_operand:HI 3 "memory_operand" "m"))]
18357 "TARGET_USE_FANCY_MATH_387
18358 && flag_unsafe_math_optimizations"
18359 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18360 [(set_attr "type" "frndint")
18361 (set_attr "i387_cw" "trunc")
18362 (set_attr "mode" "XF")])
18364 (define_expand "btruncxf2"
18365 [(use (match_operand:XF 0 "register_operand" ""))
18366 (use (match_operand:XF 1 "register_operand" ""))]
18367 "TARGET_USE_FANCY_MATH_387
18368 && flag_unsafe_math_optimizations && !optimize_size"
18370 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18374 (define_expand "btrunc<mode>2"
18375 [(use (match_operand:MODEF 0 "register_operand" ""))
18376 (use (match_operand:MODEF 1 "register_operand" ""))]
18377 "(TARGET_USE_FANCY_MATH_387
18378 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18379 || TARGET_MIX_SSE_I387)
18380 && flag_unsafe_math_optimizations && !optimize_size)
18381 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18382 && !flag_trapping_math
18383 && (TARGET_ROUND || !optimize_size))"
18385 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18386 && !flag_trapping_math
18387 && (TARGET_ROUND || !optimize_size))
18390 emit_insn (gen_sse4_1_round<mode>2
18391 (operands[0], operands[1], GEN_INT (0x03)));
18392 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18393 ix86_expand_trunc (operand0, operand1);
18395 ix86_expand_truncdf_32 (operand0, operand1);
18399 rtx op0 = gen_reg_rtx (XFmode);
18400 rtx op1 = gen_reg_rtx (XFmode);
18402 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18403 emit_insn (gen_frndintxf2_trunc (op0, op1));
18405 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18410 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18411 (define_insn_and_split "frndintxf2_mask_pm"
18412 [(set (match_operand:XF 0 "register_operand" "")
18413 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18414 UNSPEC_FRNDINT_MASK_PM))
18415 (clobber (reg:CC FLAGS_REG))]
18416 "TARGET_USE_FANCY_MATH_387
18417 && flag_unsafe_math_optimizations
18418 && !(reload_completed || reload_in_progress)"
18423 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18425 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18426 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18428 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18429 operands[2], operands[3]));
18432 [(set_attr "type" "frndint")
18433 (set_attr "i387_cw" "mask_pm")
18434 (set_attr "mode" "XF")])
18436 (define_insn "frndintxf2_mask_pm_i387"
18437 [(set (match_operand:XF 0 "register_operand" "=f")
18438 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18439 UNSPEC_FRNDINT_MASK_PM))
18440 (use (match_operand:HI 2 "memory_operand" "m"))
18441 (use (match_operand:HI 3 "memory_operand" "m"))]
18442 "TARGET_USE_FANCY_MATH_387
18443 && flag_unsafe_math_optimizations"
18444 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18445 [(set_attr "type" "frndint")
18446 (set_attr "i387_cw" "mask_pm")
18447 (set_attr "mode" "XF")])
18449 (define_expand "nearbyintxf2"
18450 [(use (match_operand:XF 0 "register_operand" ""))
18451 (use (match_operand:XF 1 "register_operand" ""))]
18452 "TARGET_USE_FANCY_MATH_387
18453 && flag_unsafe_math_optimizations"
18455 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18460 (define_expand "nearbyint<mode>2"
18461 [(use (match_operand:MODEF 0 "register_operand" ""))
18462 (use (match_operand:MODEF 1 "register_operand" ""))]
18463 "TARGET_USE_FANCY_MATH_387
18464 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18465 || TARGET_MIX_SSE_I387)
18466 && flag_unsafe_math_optimizations"
18468 rtx op0 = gen_reg_rtx (XFmode);
18469 rtx op1 = gen_reg_rtx (XFmode);
18471 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18472 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18474 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18478 (define_insn "fxam<mode>2_i387"
18479 [(set (match_operand:HI 0 "register_operand" "=a")
18481 [(match_operand:X87MODEF 1 "register_operand" "f")]
18483 "TARGET_USE_FANCY_MATH_387"
18484 "fxam\n\tfnstsw\t%0"
18485 [(set_attr "type" "multi")
18486 (set_attr "unit" "i387")
18487 (set_attr "mode" "<MODE>")])
18489 (define_expand "isinf<mode>2"
18490 [(use (match_operand:SI 0 "register_operand" ""))
18491 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18492 "TARGET_USE_FANCY_MATH_387
18493 && TARGET_C99_FUNCTIONS
18494 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18496 rtx mask = GEN_INT (0x45);
18497 rtx val = GEN_INT (0x05);
18501 rtx scratch = gen_reg_rtx (HImode);
18502 rtx res = gen_reg_rtx (QImode);
18504 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18505 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18506 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18507 cond = gen_rtx_fmt_ee (EQ, QImode,
18508 gen_rtx_REG (CCmode, FLAGS_REG),
18510 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18511 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18515 (define_expand "signbit<mode>2"
18516 [(use (match_operand:SI 0 "register_operand" ""))
18517 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18518 "TARGET_USE_FANCY_MATH_387
18519 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18521 rtx mask = GEN_INT (0x0200);
18523 rtx scratch = gen_reg_rtx (HImode);
18525 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18526 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18530 ;; Block operation instructions
18532 (define_expand "movmemsi"
18533 [(use (match_operand:BLK 0 "memory_operand" ""))
18534 (use (match_operand:BLK 1 "memory_operand" ""))
18535 (use (match_operand:SI 2 "nonmemory_operand" ""))
18536 (use (match_operand:SI 3 "const_int_operand" ""))
18537 (use (match_operand:SI 4 "const_int_operand" ""))
18538 (use (match_operand:SI 5 "const_int_operand" ""))]
18541 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18542 operands[4], operands[5]))
18548 (define_expand "movmemdi"
18549 [(use (match_operand:BLK 0 "memory_operand" ""))
18550 (use (match_operand:BLK 1 "memory_operand" ""))
18551 (use (match_operand:DI 2 "nonmemory_operand" ""))
18552 (use (match_operand:DI 3 "const_int_operand" ""))
18553 (use (match_operand:SI 4 "const_int_operand" ""))
18554 (use (match_operand:SI 5 "const_int_operand" ""))]
18557 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18558 operands[4], operands[5]))
18564 ;; Most CPUs don't like single string operations
18565 ;; Handle this case here to simplify previous expander.
18567 (define_expand "strmov"
18568 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18569 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18570 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18571 (clobber (reg:CC FLAGS_REG))])
18572 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18573 (clobber (reg:CC FLAGS_REG))])]
18576 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18578 /* If .md ever supports :P for Pmode, these can be directly
18579 in the pattern above. */
18580 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18581 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18583 /* Can't use this if the user has appropriated esi or edi. */
18584 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18585 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18587 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18588 operands[2], operands[3],
18589 operands[5], operands[6]));
18593 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18596 (define_expand "strmov_singleop"
18597 [(parallel [(set (match_operand 1 "memory_operand" "")
18598 (match_operand 3 "memory_operand" ""))
18599 (set (match_operand 0 "register_operand" "")
18600 (match_operand 4 "" ""))
18601 (set (match_operand 2 "register_operand" "")
18602 (match_operand 5 "" ""))])]
18603 "TARGET_SINGLE_STRINGOP || optimize_size"
18606 (define_insn "*strmovdi_rex_1"
18607 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18608 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18609 (set (match_operand:DI 0 "register_operand" "=D")
18610 (plus:DI (match_dup 2)
18612 (set (match_operand:DI 1 "register_operand" "=S")
18613 (plus:DI (match_dup 3)
18615 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18617 [(set_attr "type" "str")
18618 (set_attr "mode" "DI")
18619 (set_attr "memory" "both")])
18621 (define_insn "*strmovsi_1"
18622 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18623 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18624 (set (match_operand:SI 0 "register_operand" "=D")
18625 (plus:SI (match_dup 2)
18627 (set (match_operand:SI 1 "register_operand" "=S")
18628 (plus:SI (match_dup 3)
18630 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18632 [(set_attr "type" "str")
18633 (set_attr "mode" "SI")
18634 (set_attr "memory" "both")])
18636 (define_insn "*strmovsi_rex_1"
18637 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18638 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18639 (set (match_operand:DI 0 "register_operand" "=D")
18640 (plus:DI (match_dup 2)
18642 (set (match_operand:DI 1 "register_operand" "=S")
18643 (plus:DI (match_dup 3)
18645 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18647 [(set_attr "type" "str")
18648 (set_attr "mode" "SI")
18649 (set_attr "memory" "both")])
18651 (define_insn "*strmovhi_1"
18652 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18653 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18654 (set (match_operand:SI 0 "register_operand" "=D")
18655 (plus:SI (match_dup 2)
18657 (set (match_operand:SI 1 "register_operand" "=S")
18658 (plus:SI (match_dup 3)
18660 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18662 [(set_attr "type" "str")
18663 (set_attr "memory" "both")
18664 (set_attr "mode" "HI")])
18666 (define_insn "*strmovhi_rex_1"
18667 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18668 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18669 (set (match_operand:DI 0 "register_operand" "=D")
18670 (plus:DI (match_dup 2)
18672 (set (match_operand:DI 1 "register_operand" "=S")
18673 (plus:DI (match_dup 3)
18675 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18677 [(set_attr "type" "str")
18678 (set_attr "memory" "both")
18679 (set_attr "mode" "HI")])
18681 (define_insn "*strmovqi_1"
18682 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18683 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18684 (set (match_operand:SI 0 "register_operand" "=D")
18685 (plus:SI (match_dup 2)
18687 (set (match_operand:SI 1 "register_operand" "=S")
18688 (plus:SI (match_dup 3)
18690 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18692 [(set_attr "type" "str")
18693 (set_attr "memory" "both")
18694 (set_attr "mode" "QI")])
18696 (define_insn "*strmovqi_rex_1"
18697 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18698 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18699 (set (match_operand:DI 0 "register_operand" "=D")
18700 (plus:DI (match_dup 2)
18702 (set (match_operand:DI 1 "register_operand" "=S")
18703 (plus:DI (match_dup 3)
18705 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18707 [(set_attr "type" "str")
18708 (set_attr "memory" "both")
18709 (set_attr "mode" "QI")])
18711 (define_expand "rep_mov"
18712 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18713 (set (match_operand 0 "register_operand" "")
18714 (match_operand 5 "" ""))
18715 (set (match_operand 2 "register_operand" "")
18716 (match_operand 6 "" ""))
18717 (set (match_operand 1 "memory_operand" "")
18718 (match_operand 3 "memory_operand" ""))
18719 (use (match_dup 4))])]
18723 (define_insn "*rep_movdi_rex64"
18724 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18725 (set (match_operand:DI 0 "register_operand" "=D")
18726 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18728 (match_operand:DI 3 "register_operand" "0")))
18729 (set (match_operand:DI 1 "register_operand" "=S")
18730 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18731 (match_operand:DI 4 "register_operand" "1")))
18732 (set (mem:BLK (match_dup 3))
18733 (mem:BLK (match_dup 4)))
18734 (use (match_dup 5))]
18737 [(set_attr "type" "str")
18738 (set_attr "prefix_rep" "1")
18739 (set_attr "memory" "both")
18740 (set_attr "mode" "DI")])
18742 (define_insn "*rep_movsi"
18743 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18744 (set (match_operand:SI 0 "register_operand" "=D")
18745 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18747 (match_operand:SI 3 "register_operand" "0")))
18748 (set (match_operand:SI 1 "register_operand" "=S")
18749 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18750 (match_operand:SI 4 "register_operand" "1")))
18751 (set (mem:BLK (match_dup 3))
18752 (mem:BLK (match_dup 4)))
18753 (use (match_dup 5))]
18756 [(set_attr "type" "str")
18757 (set_attr "prefix_rep" "1")
18758 (set_attr "memory" "both")
18759 (set_attr "mode" "SI")])
18761 (define_insn "*rep_movsi_rex64"
18762 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18763 (set (match_operand:DI 0 "register_operand" "=D")
18764 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18766 (match_operand:DI 3 "register_operand" "0")))
18767 (set (match_operand:DI 1 "register_operand" "=S")
18768 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18769 (match_operand:DI 4 "register_operand" "1")))
18770 (set (mem:BLK (match_dup 3))
18771 (mem:BLK (match_dup 4)))
18772 (use (match_dup 5))]
18775 [(set_attr "type" "str")
18776 (set_attr "prefix_rep" "1")
18777 (set_attr "memory" "both")
18778 (set_attr "mode" "SI")])
18780 (define_insn "*rep_movqi"
18781 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18782 (set (match_operand:SI 0 "register_operand" "=D")
18783 (plus:SI (match_operand:SI 3 "register_operand" "0")
18784 (match_operand:SI 5 "register_operand" "2")))
18785 (set (match_operand:SI 1 "register_operand" "=S")
18786 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18787 (set (mem:BLK (match_dup 3))
18788 (mem:BLK (match_dup 4)))
18789 (use (match_dup 5))]
18792 [(set_attr "type" "str")
18793 (set_attr "prefix_rep" "1")
18794 (set_attr "memory" "both")
18795 (set_attr "mode" "SI")])
18797 (define_insn "*rep_movqi_rex64"
18798 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18799 (set (match_operand:DI 0 "register_operand" "=D")
18800 (plus:DI (match_operand:DI 3 "register_operand" "0")
18801 (match_operand:DI 5 "register_operand" "2")))
18802 (set (match_operand:DI 1 "register_operand" "=S")
18803 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18804 (set (mem:BLK (match_dup 3))
18805 (mem:BLK (match_dup 4)))
18806 (use (match_dup 5))]
18809 [(set_attr "type" "str")
18810 (set_attr "prefix_rep" "1")
18811 (set_attr "memory" "both")
18812 (set_attr "mode" "SI")])
18814 (define_expand "setmemsi"
18815 [(use (match_operand:BLK 0 "memory_operand" ""))
18816 (use (match_operand:SI 1 "nonmemory_operand" ""))
18817 (use (match_operand 2 "const_int_operand" ""))
18818 (use (match_operand 3 "const_int_operand" ""))
18819 (use (match_operand:SI 4 "const_int_operand" ""))
18820 (use (match_operand:SI 5 "const_int_operand" ""))]
18823 if (ix86_expand_setmem (operands[0], operands[1],
18824 operands[2], operands[3],
18825 operands[4], operands[5]))
18831 (define_expand "setmemdi"
18832 [(use (match_operand:BLK 0 "memory_operand" ""))
18833 (use (match_operand:DI 1 "nonmemory_operand" ""))
18834 (use (match_operand 2 "const_int_operand" ""))
18835 (use (match_operand 3 "const_int_operand" ""))
18836 (use (match_operand 4 "const_int_operand" ""))
18837 (use (match_operand 5 "const_int_operand" ""))]
18840 if (ix86_expand_setmem (operands[0], operands[1],
18841 operands[2], operands[3],
18842 operands[4], operands[5]))
18848 ;; Most CPUs don't like single string operations
18849 ;; Handle this case here to simplify previous expander.
18851 (define_expand "strset"
18852 [(set (match_operand 1 "memory_operand" "")
18853 (match_operand 2 "register_operand" ""))
18854 (parallel [(set (match_operand 0 "register_operand" "")
18856 (clobber (reg:CC FLAGS_REG))])]
18859 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18860 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18862 /* If .md ever supports :P for Pmode, this can be directly
18863 in the pattern above. */
18864 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18865 GEN_INT (GET_MODE_SIZE (GET_MODE
18867 if (TARGET_SINGLE_STRINGOP || optimize_size)
18869 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18875 (define_expand "strset_singleop"
18876 [(parallel [(set (match_operand 1 "memory_operand" "")
18877 (match_operand 2 "register_operand" ""))
18878 (set (match_operand 0 "register_operand" "")
18879 (match_operand 3 "" ""))])]
18880 "TARGET_SINGLE_STRINGOP || optimize_size"
18883 (define_insn "*strsetdi_rex_1"
18884 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18885 (match_operand:DI 2 "register_operand" "a"))
18886 (set (match_operand:DI 0 "register_operand" "=D")
18887 (plus:DI (match_dup 1)
18889 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18891 [(set_attr "type" "str")
18892 (set_attr "memory" "store")
18893 (set_attr "mode" "DI")])
18895 (define_insn "*strsetsi_1"
18896 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18897 (match_operand:SI 2 "register_operand" "a"))
18898 (set (match_operand:SI 0 "register_operand" "=D")
18899 (plus:SI (match_dup 1)
18901 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18903 [(set_attr "type" "str")
18904 (set_attr "memory" "store")
18905 (set_attr "mode" "SI")])
18907 (define_insn "*strsetsi_rex_1"
18908 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18909 (match_operand:SI 2 "register_operand" "a"))
18910 (set (match_operand:DI 0 "register_operand" "=D")
18911 (plus:DI (match_dup 1)
18913 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18915 [(set_attr "type" "str")
18916 (set_attr "memory" "store")
18917 (set_attr "mode" "SI")])
18919 (define_insn "*strsethi_1"
18920 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18921 (match_operand:HI 2 "register_operand" "a"))
18922 (set (match_operand:SI 0 "register_operand" "=D")
18923 (plus:SI (match_dup 1)
18925 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18927 [(set_attr "type" "str")
18928 (set_attr "memory" "store")
18929 (set_attr "mode" "HI")])
18931 (define_insn "*strsethi_rex_1"
18932 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18933 (match_operand:HI 2 "register_operand" "a"))
18934 (set (match_operand:DI 0 "register_operand" "=D")
18935 (plus:DI (match_dup 1)
18937 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18939 [(set_attr "type" "str")
18940 (set_attr "memory" "store")
18941 (set_attr "mode" "HI")])
18943 (define_insn "*strsetqi_1"
18944 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18945 (match_operand:QI 2 "register_operand" "a"))
18946 (set (match_operand:SI 0 "register_operand" "=D")
18947 (plus:SI (match_dup 1)
18949 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18951 [(set_attr "type" "str")
18952 (set_attr "memory" "store")
18953 (set_attr "mode" "QI")])
18955 (define_insn "*strsetqi_rex_1"
18956 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18957 (match_operand:QI 2 "register_operand" "a"))
18958 (set (match_operand:DI 0 "register_operand" "=D")
18959 (plus:DI (match_dup 1)
18961 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18963 [(set_attr "type" "str")
18964 (set_attr "memory" "store")
18965 (set_attr "mode" "QI")])
18967 (define_expand "rep_stos"
18968 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18969 (set (match_operand 0 "register_operand" "")
18970 (match_operand 4 "" ""))
18971 (set (match_operand 2 "memory_operand" "") (const_int 0))
18972 (use (match_operand 3 "register_operand" ""))
18973 (use (match_dup 1))])]
18977 (define_insn "*rep_stosdi_rex64"
18978 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18979 (set (match_operand:DI 0 "register_operand" "=D")
18980 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18982 (match_operand:DI 3 "register_operand" "0")))
18983 (set (mem:BLK (match_dup 3))
18985 (use (match_operand:DI 2 "register_operand" "a"))
18986 (use (match_dup 4))]
18989 [(set_attr "type" "str")
18990 (set_attr "prefix_rep" "1")
18991 (set_attr "memory" "store")
18992 (set_attr "mode" "DI")])
18994 (define_insn "*rep_stossi"
18995 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18996 (set (match_operand:SI 0 "register_operand" "=D")
18997 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18999 (match_operand:SI 3 "register_operand" "0")))
19000 (set (mem:BLK (match_dup 3))
19002 (use (match_operand:SI 2 "register_operand" "a"))
19003 (use (match_dup 4))]
19006 [(set_attr "type" "str")
19007 (set_attr "prefix_rep" "1")
19008 (set_attr "memory" "store")
19009 (set_attr "mode" "SI")])
19011 (define_insn "*rep_stossi_rex64"
19012 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19013 (set (match_operand:DI 0 "register_operand" "=D")
19014 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19016 (match_operand:DI 3 "register_operand" "0")))
19017 (set (mem:BLK (match_dup 3))
19019 (use (match_operand:SI 2 "register_operand" "a"))
19020 (use (match_dup 4))]
19023 [(set_attr "type" "str")
19024 (set_attr "prefix_rep" "1")
19025 (set_attr "memory" "store")
19026 (set_attr "mode" "SI")])
19028 (define_insn "*rep_stosqi"
19029 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19030 (set (match_operand:SI 0 "register_operand" "=D")
19031 (plus:SI (match_operand:SI 3 "register_operand" "0")
19032 (match_operand:SI 4 "register_operand" "1")))
19033 (set (mem:BLK (match_dup 3))
19035 (use (match_operand:QI 2 "register_operand" "a"))
19036 (use (match_dup 4))]
19039 [(set_attr "type" "str")
19040 (set_attr "prefix_rep" "1")
19041 (set_attr "memory" "store")
19042 (set_attr "mode" "QI")])
19044 (define_insn "*rep_stosqi_rex64"
19045 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19046 (set (match_operand:DI 0 "register_operand" "=D")
19047 (plus:DI (match_operand:DI 3 "register_operand" "0")
19048 (match_operand:DI 4 "register_operand" "1")))
19049 (set (mem:BLK (match_dup 3))
19051 (use (match_operand:QI 2 "register_operand" "a"))
19052 (use (match_dup 4))]
19055 [(set_attr "type" "str")
19056 (set_attr "prefix_rep" "1")
19057 (set_attr "memory" "store")
19058 (set_attr "mode" "QI")])
19060 (define_expand "cmpstrnsi"
19061 [(set (match_operand:SI 0 "register_operand" "")
19062 (compare:SI (match_operand:BLK 1 "general_operand" "")
19063 (match_operand:BLK 2 "general_operand" "")))
19064 (use (match_operand 3 "general_operand" ""))
19065 (use (match_operand 4 "immediate_operand" ""))]
19066 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19068 rtx addr1, addr2, out, outlow, count, countreg, align;
19070 /* Can't use this if the user has appropriated esi or edi. */
19071 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19076 out = gen_reg_rtx (SImode);
19078 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19079 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19080 if (addr1 != XEXP (operands[1], 0))
19081 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19082 if (addr2 != XEXP (operands[2], 0))
19083 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19085 count = operands[3];
19086 countreg = ix86_zero_extend_to_Pmode (count);
19088 /* %%% Iff we are testing strict equality, we can use known alignment
19089 to good advantage. This may be possible with combine, particularly
19090 once cc0 is dead. */
19091 align = operands[4];
19093 if (CONST_INT_P (count))
19095 if (INTVAL (count) == 0)
19097 emit_move_insn (operands[0], const0_rtx);
19100 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19101 operands[1], operands[2]));
19106 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19108 emit_insn (gen_cmpsi_1 (countreg, countreg));
19109 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19110 operands[1], operands[2]));
19113 outlow = gen_lowpart (QImode, out);
19114 emit_insn (gen_cmpintqi (outlow));
19115 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19117 if (operands[0] != out)
19118 emit_move_insn (operands[0], out);
19123 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19125 (define_expand "cmpintqi"
19126 [(set (match_dup 1)
19127 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19129 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19130 (parallel [(set (match_operand:QI 0 "register_operand" "")
19131 (minus:QI (match_dup 1)
19133 (clobber (reg:CC FLAGS_REG))])]
19135 "operands[1] = gen_reg_rtx (QImode);
19136 operands[2] = gen_reg_rtx (QImode);")
19138 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19139 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19141 (define_expand "cmpstrnqi_nz_1"
19142 [(parallel [(set (reg:CC FLAGS_REG)
19143 (compare:CC (match_operand 4 "memory_operand" "")
19144 (match_operand 5 "memory_operand" "")))
19145 (use (match_operand 2 "register_operand" ""))
19146 (use (match_operand:SI 3 "immediate_operand" ""))
19147 (clobber (match_operand 0 "register_operand" ""))
19148 (clobber (match_operand 1 "register_operand" ""))
19149 (clobber (match_dup 2))])]
19153 (define_insn "*cmpstrnqi_nz_1"
19154 [(set (reg:CC FLAGS_REG)
19155 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19156 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19157 (use (match_operand:SI 6 "register_operand" "2"))
19158 (use (match_operand:SI 3 "immediate_operand" "i"))
19159 (clobber (match_operand:SI 0 "register_operand" "=S"))
19160 (clobber (match_operand:SI 1 "register_operand" "=D"))
19161 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19164 [(set_attr "type" "str")
19165 (set_attr "mode" "QI")
19166 (set_attr "prefix_rep" "1")])
19168 (define_insn "*cmpstrnqi_nz_rex_1"
19169 [(set (reg:CC FLAGS_REG)
19170 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19171 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19172 (use (match_operand:DI 6 "register_operand" "2"))
19173 (use (match_operand:SI 3 "immediate_operand" "i"))
19174 (clobber (match_operand:DI 0 "register_operand" "=S"))
19175 (clobber (match_operand:DI 1 "register_operand" "=D"))
19176 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19179 [(set_attr "type" "str")
19180 (set_attr "mode" "QI")
19181 (set_attr "prefix_rep" "1")])
19183 ;; The same, but the count is not known to not be zero.
19185 (define_expand "cmpstrnqi_1"
19186 [(parallel [(set (reg:CC FLAGS_REG)
19187 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19189 (compare:CC (match_operand 4 "memory_operand" "")
19190 (match_operand 5 "memory_operand" ""))
19192 (use (match_operand:SI 3 "immediate_operand" ""))
19193 (use (reg:CC FLAGS_REG))
19194 (clobber (match_operand 0 "register_operand" ""))
19195 (clobber (match_operand 1 "register_operand" ""))
19196 (clobber (match_dup 2))])]
19200 (define_insn "*cmpstrnqi_1"
19201 [(set (reg:CC FLAGS_REG)
19202 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19204 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19205 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19207 (use (match_operand:SI 3 "immediate_operand" "i"))
19208 (use (reg:CC FLAGS_REG))
19209 (clobber (match_operand:SI 0 "register_operand" "=S"))
19210 (clobber (match_operand:SI 1 "register_operand" "=D"))
19211 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19214 [(set_attr "type" "str")
19215 (set_attr "mode" "QI")
19216 (set_attr "prefix_rep" "1")])
19218 (define_insn "*cmpstrnqi_rex_1"
19219 [(set (reg:CC FLAGS_REG)
19220 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19222 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19223 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19225 (use (match_operand:SI 3 "immediate_operand" "i"))
19226 (use (reg:CC FLAGS_REG))
19227 (clobber (match_operand:DI 0 "register_operand" "=S"))
19228 (clobber (match_operand:DI 1 "register_operand" "=D"))
19229 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19232 [(set_attr "type" "str")
19233 (set_attr "mode" "QI")
19234 (set_attr "prefix_rep" "1")])
19236 (define_expand "strlensi"
19237 [(set (match_operand:SI 0 "register_operand" "")
19238 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19239 (match_operand:QI 2 "immediate_operand" "")
19240 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19243 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19249 (define_expand "strlendi"
19250 [(set (match_operand:DI 0 "register_operand" "")
19251 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19252 (match_operand:QI 2 "immediate_operand" "")
19253 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19256 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19262 (define_expand "strlenqi_1"
19263 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19264 (clobber (match_operand 1 "register_operand" ""))
19265 (clobber (reg:CC FLAGS_REG))])]
19269 (define_insn "*strlenqi_1"
19270 [(set (match_operand:SI 0 "register_operand" "=&c")
19271 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19272 (match_operand:QI 2 "register_operand" "a")
19273 (match_operand:SI 3 "immediate_operand" "i")
19274 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19275 (clobber (match_operand:SI 1 "register_operand" "=D"))
19276 (clobber (reg:CC FLAGS_REG))]
19279 [(set_attr "type" "str")
19280 (set_attr "mode" "QI")
19281 (set_attr "prefix_rep" "1")])
19283 (define_insn "*strlenqi_rex_1"
19284 [(set (match_operand:DI 0 "register_operand" "=&c")
19285 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19286 (match_operand:QI 2 "register_operand" "a")
19287 (match_operand:DI 3 "immediate_operand" "i")
19288 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19289 (clobber (match_operand:DI 1 "register_operand" "=D"))
19290 (clobber (reg:CC FLAGS_REG))]
19293 [(set_attr "type" "str")
19294 (set_attr "mode" "QI")
19295 (set_attr "prefix_rep" "1")])
19297 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19298 ;; handled in combine, but it is not currently up to the task.
19299 ;; When used for their truth value, the cmpstrn* expanders generate
19308 ;; The intermediate three instructions are unnecessary.
19310 ;; This one handles cmpstrn*_nz_1...
19313 (set (reg:CC FLAGS_REG)
19314 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19315 (mem:BLK (match_operand 5 "register_operand" ""))))
19316 (use (match_operand 6 "register_operand" ""))
19317 (use (match_operand:SI 3 "immediate_operand" ""))
19318 (clobber (match_operand 0 "register_operand" ""))
19319 (clobber (match_operand 1 "register_operand" ""))
19320 (clobber (match_operand 2 "register_operand" ""))])
19321 (set (match_operand:QI 7 "register_operand" "")
19322 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19323 (set (match_operand:QI 8 "register_operand" "")
19324 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19325 (set (reg FLAGS_REG)
19326 (compare (match_dup 7) (match_dup 8)))
19328 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19330 (set (reg:CC FLAGS_REG)
19331 (compare:CC (mem:BLK (match_dup 4))
19332 (mem:BLK (match_dup 5))))
19333 (use (match_dup 6))
19334 (use (match_dup 3))
19335 (clobber (match_dup 0))
19336 (clobber (match_dup 1))
19337 (clobber (match_dup 2))])]
19340 ;; ...and this one handles cmpstrn*_1.
19343 (set (reg:CC FLAGS_REG)
19344 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19346 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19347 (mem:BLK (match_operand 5 "register_operand" "")))
19349 (use (match_operand:SI 3 "immediate_operand" ""))
19350 (use (reg:CC FLAGS_REG))
19351 (clobber (match_operand 0 "register_operand" ""))
19352 (clobber (match_operand 1 "register_operand" ""))
19353 (clobber (match_operand 2 "register_operand" ""))])
19354 (set (match_operand:QI 7 "register_operand" "")
19355 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19356 (set (match_operand:QI 8 "register_operand" "")
19357 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19358 (set (reg FLAGS_REG)
19359 (compare (match_dup 7) (match_dup 8)))
19361 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19363 (set (reg:CC FLAGS_REG)
19364 (if_then_else:CC (ne (match_dup 6)
19366 (compare:CC (mem:BLK (match_dup 4))
19367 (mem:BLK (match_dup 5)))
19369 (use (match_dup 3))
19370 (use (reg:CC FLAGS_REG))
19371 (clobber (match_dup 0))
19372 (clobber (match_dup 1))
19373 (clobber (match_dup 2))])]
19378 ;; Conditional move instructions.
19380 (define_expand "movdicc"
19381 [(set (match_operand:DI 0 "register_operand" "")
19382 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19383 (match_operand:DI 2 "general_operand" "")
19384 (match_operand:DI 3 "general_operand" "")))]
19386 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19388 (define_insn "x86_movdicc_0_m1_rex64"
19389 [(set (match_operand:DI 0 "register_operand" "=r")
19390 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19393 (clobber (reg:CC FLAGS_REG))]
19396 ; Since we don't have the proper number of operands for an alu insn,
19397 ; fill in all the blanks.
19398 [(set_attr "type" "alu")
19399 (set_attr "pent_pair" "pu")
19400 (set_attr "memory" "none")
19401 (set_attr "imm_disp" "false")
19402 (set_attr "mode" "DI")
19403 (set_attr "length_immediate" "0")])
19405 (define_insn "*movdicc_c_rex64"
19406 [(set (match_operand:DI 0 "register_operand" "=r,r")
19407 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19408 [(reg FLAGS_REG) (const_int 0)])
19409 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19410 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19411 "TARGET_64BIT && TARGET_CMOVE
19412 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19414 cmov%O2%C1\t{%2, %0|%0, %2}
19415 cmov%O2%c1\t{%3, %0|%0, %3}"
19416 [(set_attr "type" "icmov")
19417 (set_attr "mode" "DI")])
19419 (define_expand "movsicc"
19420 [(set (match_operand:SI 0 "register_operand" "")
19421 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19422 (match_operand:SI 2 "general_operand" "")
19423 (match_operand:SI 3 "general_operand" "")))]
19425 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19427 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19428 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19429 ;; So just document what we're doing explicitly.
19431 (define_insn "x86_movsicc_0_m1"
19432 [(set (match_operand:SI 0 "register_operand" "=r")
19433 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19436 (clobber (reg:CC FLAGS_REG))]
19439 ; Since we don't have the proper number of operands for an alu insn,
19440 ; fill in all the blanks.
19441 [(set_attr "type" "alu")
19442 (set_attr "pent_pair" "pu")
19443 (set_attr "memory" "none")
19444 (set_attr "imm_disp" "false")
19445 (set_attr "mode" "SI")
19446 (set_attr "length_immediate" "0")])
19448 (define_insn "*movsicc_noc"
19449 [(set (match_operand:SI 0 "register_operand" "=r,r")
19450 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19451 [(reg FLAGS_REG) (const_int 0)])
19452 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19453 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19455 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19457 cmov%O2%C1\t{%2, %0|%0, %2}
19458 cmov%O2%c1\t{%3, %0|%0, %3}"
19459 [(set_attr "type" "icmov")
19460 (set_attr "mode" "SI")])
19462 (define_expand "movhicc"
19463 [(set (match_operand:HI 0 "register_operand" "")
19464 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19465 (match_operand:HI 2 "general_operand" "")
19466 (match_operand:HI 3 "general_operand" "")))]
19467 "TARGET_HIMODE_MATH"
19468 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19470 (define_insn "*movhicc_noc"
19471 [(set (match_operand:HI 0 "register_operand" "=r,r")
19472 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19473 [(reg FLAGS_REG) (const_int 0)])
19474 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19475 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19477 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19479 cmov%O2%C1\t{%2, %0|%0, %2}
19480 cmov%O2%c1\t{%3, %0|%0, %3}"
19481 [(set_attr "type" "icmov")
19482 (set_attr "mode" "HI")])
19484 (define_expand "movqicc"
19485 [(set (match_operand:QI 0 "register_operand" "")
19486 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19487 (match_operand:QI 2 "general_operand" "")
19488 (match_operand:QI 3 "general_operand" "")))]
19489 "TARGET_QIMODE_MATH"
19490 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19492 (define_insn_and_split "*movqicc_noc"
19493 [(set (match_operand:QI 0 "register_operand" "=r,r")
19494 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19495 [(match_operand 4 "flags_reg_operand" "")
19497 (match_operand:QI 2 "register_operand" "r,0")
19498 (match_operand:QI 3 "register_operand" "0,r")))]
19499 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19501 "&& reload_completed"
19502 [(set (match_dup 0)
19503 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19506 "operands[0] = gen_lowpart (SImode, operands[0]);
19507 operands[2] = gen_lowpart (SImode, operands[2]);
19508 operands[3] = gen_lowpart (SImode, operands[3]);"
19509 [(set_attr "type" "icmov")
19510 (set_attr "mode" "SI")])
19512 (define_expand "movsfcc"
19513 [(set (match_operand:SF 0 "register_operand" "")
19514 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19515 (match_operand:SF 2 "register_operand" "")
19516 (match_operand:SF 3 "register_operand" "")))]
19517 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19518 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19520 (define_insn "*movsfcc_1_387"
19521 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19522 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19523 [(reg FLAGS_REG) (const_int 0)])
19524 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19525 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19526 "TARGET_80387 && TARGET_CMOVE
19527 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19529 fcmov%F1\t{%2, %0|%0, %2}
19530 fcmov%f1\t{%3, %0|%0, %3}
19531 cmov%O2%C1\t{%2, %0|%0, %2}
19532 cmov%O2%c1\t{%3, %0|%0, %3}"
19533 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19534 (set_attr "mode" "SF,SF,SI,SI")])
19536 (define_expand "movdfcc"
19537 [(set (match_operand:DF 0 "register_operand" "")
19538 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19539 (match_operand:DF 2 "register_operand" "")
19540 (match_operand:DF 3 "register_operand" "")))]
19541 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19542 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19544 (define_insn "*movdfcc_1"
19545 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19546 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19547 [(reg FLAGS_REG) (const_int 0)])
19548 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19549 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19550 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19551 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19553 fcmov%F1\t{%2, %0|%0, %2}
19554 fcmov%f1\t{%3, %0|%0, %3}
19557 [(set_attr "type" "fcmov,fcmov,multi,multi")
19558 (set_attr "mode" "DF")])
19560 (define_insn "*movdfcc_1_rex64"
19561 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19562 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19563 [(reg FLAGS_REG) (const_int 0)])
19564 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19565 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19566 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19567 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19569 fcmov%F1\t{%2, %0|%0, %2}
19570 fcmov%f1\t{%3, %0|%0, %3}
19571 cmov%O2%C1\t{%2, %0|%0, %2}
19572 cmov%O2%c1\t{%3, %0|%0, %3}"
19573 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19574 (set_attr "mode" "DF")])
19577 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19578 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19579 [(match_operand 4 "flags_reg_operand" "")
19581 (match_operand:DF 2 "nonimmediate_operand" "")
19582 (match_operand:DF 3 "nonimmediate_operand" "")))]
19583 "!TARGET_64BIT && reload_completed"
19584 [(set (match_dup 2)
19585 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19589 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19592 "split_di (operands+2, 1, operands+5, operands+6);
19593 split_di (operands+3, 1, operands+7, operands+8);
19594 split_di (operands, 1, operands+2, operands+3);")
19596 (define_expand "movxfcc"
19597 [(set (match_operand:XF 0 "register_operand" "")
19598 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19599 (match_operand:XF 2 "register_operand" "")
19600 (match_operand:XF 3 "register_operand" "")))]
19601 "TARGET_80387 && TARGET_CMOVE"
19602 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19604 (define_insn "*movxfcc_1"
19605 [(set (match_operand:XF 0 "register_operand" "=f,f")
19606 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19607 [(reg FLAGS_REG) (const_int 0)])
19608 (match_operand:XF 2 "register_operand" "f,0")
19609 (match_operand:XF 3 "register_operand" "0,f")))]
19610 "TARGET_80387 && TARGET_CMOVE"
19612 fcmov%F1\t{%2, %0|%0, %2}
19613 fcmov%f1\t{%3, %0|%0, %3}"
19614 [(set_attr "type" "fcmov")
19615 (set_attr "mode" "XF")])
19617 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19618 ;; the scalar versions to have only XMM registers as operands.
19620 ;; SSE5 conditional move
19621 (define_insn "*sse5_pcmov_<mode>"
19622 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19623 (if_then_else:MODEF
19624 (match_operand:MODEF 1 "register_operand" "x,0")
19625 (match_operand:MODEF 2 "register_operand" "0,x")
19626 (match_operand:MODEF 3 "register_operand" "x,x")))]
19627 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19628 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19629 [(set_attr "type" "sse4arg")])
19631 ;; These versions of the min/max patterns are intentionally ignorant of
19632 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19633 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19634 ;; are undefined in this condition, we're certain this is correct.
19636 (define_insn "sminsf3"
19637 [(set (match_operand:SF 0 "register_operand" "=x")
19638 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19639 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19641 "minss\t{%2, %0|%0, %2}"
19642 [(set_attr "type" "sseadd")
19643 (set_attr "mode" "SF")])
19645 (define_insn "smaxsf3"
19646 [(set (match_operand:SF 0 "register_operand" "=x")
19647 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19648 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19650 "maxss\t{%2, %0|%0, %2}"
19651 [(set_attr "type" "sseadd")
19652 (set_attr "mode" "SF")])
19654 (define_insn "smindf3"
19655 [(set (match_operand:DF 0 "register_operand" "=x")
19656 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19657 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19658 "TARGET_SSE2 && TARGET_SSE_MATH"
19659 "minsd\t{%2, %0|%0, %2}"
19660 [(set_attr "type" "sseadd")
19661 (set_attr "mode" "DF")])
19663 (define_insn "smaxdf3"
19664 [(set (match_operand:DF 0 "register_operand" "=x")
19665 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19666 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19667 "TARGET_SSE2 && TARGET_SSE_MATH"
19668 "maxsd\t{%2, %0|%0, %2}"
19669 [(set_attr "type" "sseadd")
19670 (set_attr "mode" "DF")])
19672 ;; These versions of the min/max patterns implement exactly the operations
19673 ;; min = (op1 < op2 ? op1 : op2)
19674 ;; max = (!(op1 < op2) ? op1 : op2)
19675 ;; Their operands are not commutative, and thus they may be used in the
19676 ;; presence of -0.0 and NaN.
19678 (define_insn "*ieee_sminsf3"
19679 [(set (match_operand:SF 0 "register_operand" "=x")
19680 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19681 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19684 "minss\t{%2, %0|%0, %2}"
19685 [(set_attr "type" "sseadd")
19686 (set_attr "mode" "SF")])
19688 (define_insn "*ieee_smaxsf3"
19689 [(set (match_operand:SF 0 "register_operand" "=x")
19690 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19691 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19694 "maxss\t{%2, %0|%0, %2}"
19695 [(set_attr "type" "sseadd")
19696 (set_attr "mode" "SF")])
19698 (define_insn "*ieee_smindf3"
19699 [(set (match_operand:DF 0 "register_operand" "=x")
19700 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19701 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19703 "TARGET_SSE2 && TARGET_SSE_MATH"
19704 "minsd\t{%2, %0|%0, %2}"
19705 [(set_attr "type" "sseadd")
19706 (set_attr "mode" "DF")])
19708 (define_insn "*ieee_smaxdf3"
19709 [(set (match_operand:DF 0 "register_operand" "=x")
19710 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19711 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19713 "TARGET_SSE2 && TARGET_SSE_MATH"
19714 "maxsd\t{%2, %0|%0, %2}"
19715 [(set_attr "type" "sseadd")
19716 (set_attr "mode" "DF")])
19718 ;; Make two stack loads independent:
19720 ;; fld %st(0) -> fld bb
19721 ;; fmul bb fmul %st(1), %st
19723 ;; Actually we only match the last two instructions for simplicity.
19725 [(set (match_operand 0 "fp_register_operand" "")
19726 (match_operand 1 "fp_register_operand" ""))
19728 (match_operator 2 "binary_fp_operator"
19730 (match_operand 3 "memory_operand" "")]))]
19731 "REGNO (operands[0]) != REGNO (operands[1])"
19732 [(set (match_dup 0) (match_dup 3))
19733 (set (match_dup 0) (match_dup 4))]
19735 ;; The % modifier is not operational anymore in peephole2's, so we have to
19736 ;; swap the operands manually in the case of addition and multiplication.
19737 "if (COMMUTATIVE_ARITH_P (operands[2]))
19738 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19739 operands[0], operands[1]);
19741 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19742 operands[1], operands[0]);")
19744 ;; Conditional addition patterns
19745 (define_expand "addqicc"
19746 [(match_operand:QI 0 "register_operand" "")
19747 (match_operand 1 "comparison_operator" "")
19748 (match_operand:QI 2 "register_operand" "")
19749 (match_operand:QI 3 "const_int_operand" "")]
19751 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19753 (define_expand "addhicc"
19754 [(match_operand:HI 0 "register_operand" "")
19755 (match_operand 1 "comparison_operator" "")
19756 (match_operand:HI 2 "register_operand" "")
19757 (match_operand:HI 3 "const_int_operand" "")]
19759 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19761 (define_expand "addsicc"
19762 [(match_operand:SI 0 "register_operand" "")
19763 (match_operand 1 "comparison_operator" "")
19764 (match_operand:SI 2 "register_operand" "")
19765 (match_operand:SI 3 "const_int_operand" "")]
19767 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19769 (define_expand "adddicc"
19770 [(match_operand:DI 0 "register_operand" "")
19771 (match_operand 1 "comparison_operator" "")
19772 (match_operand:DI 2 "register_operand" "")
19773 (match_operand:DI 3 "const_int_operand" "")]
19775 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19778 ;; Misc patterns (?)
19780 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19781 ;; Otherwise there will be nothing to keep
19783 ;; [(set (reg ebp) (reg esp))]
19784 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19785 ;; (clobber (eflags)]
19786 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19788 ;; in proper program order.
19789 (define_insn "pro_epilogue_adjust_stack_1"
19790 [(set (match_operand:SI 0 "register_operand" "=r,r")
19791 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19792 (match_operand:SI 2 "immediate_operand" "i,i")))
19793 (clobber (reg:CC FLAGS_REG))
19794 (clobber (mem:BLK (scratch)))]
19797 switch (get_attr_type (insn))
19800 return "mov{l}\t{%1, %0|%0, %1}";
19803 if (CONST_INT_P (operands[2])
19804 && (INTVAL (operands[2]) == 128
19805 || (INTVAL (operands[2]) < 0
19806 && INTVAL (operands[2]) != -128)))
19808 operands[2] = GEN_INT (-INTVAL (operands[2]));
19809 return "sub{l}\t{%2, %0|%0, %2}";
19811 return "add{l}\t{%2, %0|%0, %2}";
19814 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19815 return "lea{l}\t{%a2, %0|%0, %a2}";
19818 gcc_unreachable ();
19821 [(set (attr "type")
19822 (cond [(eq_attr "alternative" "0")
19823 (const_string "alu")
19824 (match_operand:SI 2 "const0_operand" "")
19825 (const_string "imov")
19827 (const_string "lea")))
19828 (set_attr "mode" "SI")])
19830 (define_insn "pro_epilogue_adjust_stack_rex64"
19831 [(set (match_operand:DI 0 "register_operand" "=r,r")
19832 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19833 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19834 (clobber (reg:CC FLAGS_REG))
19835 (clobber (mem:BLK (scratch)))]
19838 switch (get_attr_type (insn))
19841 return "mov{q}\t{%1, %0|%0, %1}";
19844 if (CONST_INT_P (operands[2])
19845 /* Avoid overflows. */
19846 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19847 && (INTVAL (operands[2]) == 128
19848 || (INTVAL (operands[2]) < 0
19849 && INTVAL (operands[2]) != -128)))
19851 operands[2] = GEN_INT (-INTVAL (operands[2]));
19852 return "sub{q}\t{%2, %0|%0, %2}";
19854 return "add{q}\t{%2, %0|%0, %2}";
19857 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19858 return "lea{q}\t{%a2, %0|%0, %a2}";
19861 gcc_unreachable ();
19864 [(set (attr "type")
19865 (cond [(eq_attr "alternative" "0")
19866 (const_string "alu")
19867 (match_operand:DI 2 "const0_operand" "")
19868 (const_string "imov")
19870 (const_string "lea")))
19871 (set_attr "mode" "DI")])
19873 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19874 [(set (match_operand:DI 0 "register_operand" "=r,r")
19875 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19876 (match_operand:DI 3 "immediate_operand" "i,i")))
19877 (use (match_operand:DI 2 "register_operand" "r,r"))
19878 (clobber (reg:CC FLAGS_REG))
19879 (clobber (mem:BLK (scratch)))]
19882 switch (get_attr_type (insn))
19885 return "add{q}\t{%2, %0|%0, %2}";
19888 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19889 return "lea{q}\t{%a2, %0|%0, %a2}";
19892 gcc_unreachable ();
19895 [(set_attr "type" "alu,lea")
19896 (set_attr "mode" "DI")])
19898 (define_insn "allocate_stack_worker_32"
19899 [(set (match_operand:SI 0 "register_operand" "+a")
19900 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19901 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19902 (clobber (reg:CC FLAGS_REG))]
19903 "!TARGET_64BIT && TARGET_STACK_PROBE"
19905 [(set_attr "type" "multi")
19906 (set_attr "length" "5")])
19908 (define_insn "allocate_stack_worker_64"
19909 [(set (match_operand:DI 0 "register_operand" "=a")
19910 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19911 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19912 (clobber (reg:DI R10_REG))
19913 (clobber (reg:DI R11_REG))
19914 (clobber (reg:CC FLAGS_REG))]
19915 "TARGET_64BIT && TARGET_STACK_PROBE"
19917 [(set_attr "type" "multi")
19918 (set_attr "length" "5")])
19920 (define_expand "allocate_stack"
19921 [(match_operand 0 "register_operand" "")
19922 (match_operand 1 "general_operand" "")]
19923 "TARGET_STACK_PROBE"
19927 #ifndef CHECK_STACK_LIMIT
19928 #define CHECK_STACK_LIMIT 0
19931 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19932 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19934 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19935 stack_pointer_rtx, 0, OPTAB_DIRECT);
19936 if (x != stack_pointer_rtx)
19937 emit_move_insn (stack_pointer_rtx, x);
19941 x = copy_to_mode_reg (Pmode, operands[1]);
19943 x = gen_allocate_stack_worker_64 (x);
19945 x = gen_allocate_stack_worker_32 (x);
19949 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19953 (define_expand "builtin_setjmp_receiver"
19954 [(label_ref (match_operand 0 "" ""))]
19955 "!TARGET_64BIT && flag_pic"
19960 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19961 rtx label_rtx = gen_label_rtx ();
19962 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19963 xops[0] = xops[1] = picreg;
19964 xops[2] = gen_rtx_CONST (SImode,
19965 gen_rtx_MINUS (SImode,
19966 gen_rtx_LABEL_REF (SImode, label_rtx),
19967 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19968 ix86_expand_binary_operator (MINUS, SImode, xops);
19971 emit_insn (gen_set_got (pic_offset_table_rtx));
19975 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19978 [(set (match_operand 0 "register_operand" "")
19979 (match_operator 3 "promotable_binary_operator"
19980 [(match_operand 1 "register_operand" "")
19981 (match_operand 2 "aligned_operand" "")]))
19982 (clobber (reg:CC FLAGS_REG))]
19983 "! TARGET_PARTIAL_REG_STALL && reload_completed
19984 && ((GET_MODE (operands[0]) == HImode
19985 && ((!optimize_size && !TARGET_FAST_PREFIX)
19986 /* ??? next two lines just !satisfies_constraint_K (...) */
19987 || !CONST_INT_P (operands[2])
19988 || satisfies_constraint_K (operands[2])))
19989 || (GET_MODE (operands[0]) == QImode
19990 && (TARGET_PROMOTE_QImode || optimize_size)))"
19991 [(parallel [(set (match_dup 0)
19992 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19993 (clobber (reg:CC FLAGS_REG))])]
19994 "operands[0] = gen_lowpart (SImode, operands[0]);
19995 operands[1] = gen_lowpart (SImode, operands[1]);
19996 if (GET_CODE (operands[3]) != ASHIFT)
19997 operands[2] = gen_lowpart (SImode, operands[2]);
19998 PUT_MODE (operands[3], SImode);")
20000 ; Promote the QImode tests, as i386 has encoding of the AND
20001 ; instruction with 32-bit sign-extended immediate and thus the
20002 ; instruction size is unchanged, except in the %eax case for
20003 ; which it is increased by one byte, hence the ! optimize_size.
20005 [(set (match_operand 0 "flags_reg_operand" "")
20006 (match_operator 2 "compare_operator"
20007 [(and (match_operand 3 "aligned_operand" "")
20008 (match_operand 4 "const_int_operand" ""))
20010 (set (match_operand 1 "register_operand" "")
20011 (and (match_dup 3) (match_dup 4)))]
20012 "! TARGET_PARTIAL_REG_STALL && reload_completed
20014 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20015 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20016 /* Ensure that the operand will remain sign-extended immediate. */
20017 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20018 [(parallel [(set (match_dup 0)
20019 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20022 (and:SI (match_dup 3) (match_dup 4)))])]
20025 = gen_int_mode (INTVAL (operands[4])
20026 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20027 operands[1] = gen_lowpart (SImode, operands[1]);
20028 operands[3] = gen_lowpart (SImode, operands[3]);
20031 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20032 ; the TEST instruction with 32-bit sign-extended immediate and thus
20033 ; the instruction size would at least double, which is not what we
20034 ; want even with ! optimize_size.
20036 [(set (match_operand 0 "flags_reg_operand" "")
20037 (match_operator 1 "compare_operator"
20038 [(and (match_operand:HI 2 "aligned_operand" "")
20039 (match_operand:HI 3 "const_int_operand" ""))
20041 "! TARGET_PARTIAL_REG_STALL && reload_completed
20042 && ! TARGET_FAST_PREFIX
20044 /* Ensure that the operand will remain sign-extended immediate. */
20045 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20046 [(set (match_dup 0)
20047 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20051 = gen_int_mode (INTVAL (operands[3])
20052 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20053 operands[2] = gen_lowpart (SImode, operands[2]);
20057 [(set (match_operand 0 "register_operand" "")
20058 (neg (match_operand 1 "register_operand" "")))
20059 (clobber (reg:CC FLAGS_REG))]
20060 "! TARGET_PARTIAL_REG_STALL && reload_completed
20061 && (GET_MODE (operands[0]) == HImode
20062 || (GET_MODE (operands[0]) == QImode
20063 && (TARGET_PROMOTE_QImode || optimize_size)))"
20064 [(parallel [(set (match_dup 0)
20065 (neg:SI (match_dup 1)))
20066 (clobber (reg:CC FLAGS_REG))])]
20067 "operands[0] = gen_lowpart (SImode, operands[0]);
20068 operands[1] = gen_lowpart (SImode, operands[1]);")
20071 [(set (match_operand 0 "register_operand" "")
20072 (not (match_operand 1 "register_operand" "")))]
20073 "! TARGET_PARTIAL_REG_STALL && reload_completed
20074 && (GET_MODE (operands[0]) == HImode
20075 || (GET_MODE (operands[0]) == QImode
20076 && (TARGET_PROMOTE_QImode || optimize_size)))"
20077 [(set (match_dup 0)
20078 (not:SI (match_dup 1)))]
20079 "operands[0] = gen_lowpart (SImode, operands[0]);
20080 operands[1] = gen_lowpart (SImode, operands[1]);")
20083 [(set (match_operand 0 "register_operand" "")
20084 (if_then_else (match_operator 1 "comparison_operator"
20085 [(reg FLAGS_REG) (const_int 0)])
20086 (match_operand 2 "register_operand" "")
20087 (match_operand 3 "register_operand" "")))]
20088 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20089 && (GET_MODE (operands[0]) == HImode
20090 || (GET_MODE (operands[0]) == QImode
20091 && (TARGET_PROMOTE_QImode || optimize_size)))"
20092 [(set (match_dup 0)
20093 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20094 "operands[0] = gen_lowpart (SImode, operands[0]);
20095 operands[2] = gen_lowpart (SImode, operands[2]);
20096 operands[3] = gen_lowpart (SImode, operands[3]);")
20099 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20100 ;; transform a complex memory operation into two memory to register operations.
20102 ;; Don't push memory operands
20104 [(set (match_operand:SI 0 "push_operand" "")
20105 (match_operand:SI 1 "memory_operand" ""))
20106 (match_scratch:SI 2 "r")]
20107 "!optimize_size && !TARGET_PUSH_MEMORY
20108 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20109 [(set (match_dup 2) (match_dup 1))
20110 (set (match_dup 0) (match_dup 2))]
20114 [(set (match_operand:DI 0 "push_operand" "")
20115 (match_operand:DI 1 "memory_operand" ""))
20116 (match_scratch:DI 2 "r")]
20117 "!optimize_size && !TARGET_PUSH_MEMORY
20118 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20119 [(set (match_dup 2) (match_dup 1))
20120 (set (match_dup 0) (match_dup 2))]
20123 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20126 [(set (match_operand:SF 0 "push_operand" "")
20127 (match_operand:SF 1 "memory_operand" ""))
20128 (match_scratch:SF 2 "r")]
20129 "!optimize_size && !TARGET_PUSH_MEMORY
20130 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20131 [(set (match_dup 2) (match_dup 1))
20132 (set (match_dup 0) (match_dup 2))]
20136 [(set (match_operand:HI 0 "push_operand" "")
20137 (match_operand:HI 1 "memory_operand" ""))
20138 (match_scratch:HI 2 "r")]
20139 "!optimize_size && !TARGET_PUSH_MEMORY
20140 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20141 [(set (match_dup 2) (match_dup 1))
20142 (set (match_dup 0) (match_dup 2))]
20146 [(set (match_operand:QI 0 "push_operand" "")
20147 (match_operand:QI 1 "memory_operand" ""))
20148 (match_scratch:QI 2 "q")]
20149 "!optimize_size && !TARGET_PUSH_MEMORY
20150 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20151 [(set (match_dup 2) (match_dup 1))
20152 (set (match_dup 0) (match_dup 2))]
20155 ;; Don't move an immediate directly to memory when the instruction
20158 [(match_scratch:SI 1 "r")
20159 (set (match_operand:SI 0 "memory_operand" "")
20162 && ! TARGET_USE_MOV0
20163 && TARGET_SPLIT_LONG_MOVES
20164 && get_attr_length (insn) >= ix86_cost->large_insn
20165 && peep2_regno_dead_p (0, FLAGS_REG)"
20166 [(parallel [(set (match_dup 1) (const_int 0))
20167 (clobber (reg:CC FLAGS_REG))])
20168 (set (match_dup 0) (match_dup 1))]
20172 [(match_scratch:HI 1 "r")
20173 (set (match_operand:HI 0 "memory_operand" "")
20176 && ! TARGET_USE_MOV0
20177 && TARGET_SPLIT_LONG_MOVES
20178 && get_attr_length (insn) >= ix86_cost->large_insn
20179 && peep2_regno_dead_p (0, FLAGS_REG)"
20180 [(parallel [(set (match_dup 2) (const_int 0))
20181 (clobber (reg:CC FLAGS_REG))])
20182 (set (match_dup 0) (match_dup 1))]
20183 "operands[2] = gen_lowpart (SImode, operands[1]);")
20186 [(match_scratch:QI 1 "q")
20187 (set (match_operand:QI 0 "memory_operand" "")
20190 && ! TARGET_USE_MOV0
20191 && TARGET_SPLIT_LONG_MOVES
20192 && get_attr_length (insn) >= ix86_cost->large_insn
20193 && peep2_regno_dead_p (0, FLAGS_REG)"
20194 [(parallel [(set (match_dup 2) (const_int 0))
20195 (clobber (reg:CC FLAGS_REG))])
20196 (set (match_dup 0) (match_dup 1))]
20197 "operands[2] = gen_lowpart (SImode, operands[1]);")
20200 [(match_scratch:SI 2 "r")
20201 (set (match_operand:SI 0 "memory_operand" "")
20202 (match_operand:SI 1 "immediate_operand" ""))]
20204 && TARGET_SPLIT_LONG_MOVES
20205 && get_attr_length (insn) >= ix86_cost->large_insn"
20206 [(set (match_dup 2) (match_dup 1))
20207 (set (match_dup 0) (match_dup 2))]
20211 [(match_scratch:HI 2 "r")
20212 (set (match_operand:HI 0 "memory_operand" "")
20213 (match_operand:HI 1 "immediate_operand" ""))]
20215 && TARGET_SPLIT_LONG_MOVES
20216 && get_attr_length (insn) >= ix86_cost->large_insn"
20217 [(set (match_dup 2) (match_dup 1))
20218 (set (match_dup 0) (match_dup 2))]
20222 [(match_scratch:QI 2 "q")
20223 (set (match_operand:QI 0 "memory_operand" "")
20224 (match_operand:QI 1 "immediate_operand" ""))]
20226 && TARGET_SPLIT_LONG_MOVES
20227 && get_attr_length (insn) >= ix86_cost->large_insn"
20228 [(set (match_dup 2) (match_dup 1))
20229 (set (match_dup 0) (match_dup 2))]
20232 ;; Don't compare memory with zero, load and use a test instead.
20234 [(set (match_operand 0 "flags_reg_operand" "")
20235 (match_operator 1 "compare_operator"
20236 [(match_operand:SI 2 "memory_operand" "")
20238 (match_scratch:SI 3 "r")]
20239 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20240 [(set (match_dup 3) (match_dup 2))
20241 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20244 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20245 ;; Don't split NOTs with a displacement operand, because resulting XOR
20246 ;; will not be pairable anyway.
20248 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20249 ;; represented using a modRM byte. The XOR replacement is long decoded,
20250 ;; so this split helps here as well.
20252 ;; Note: Can't do this as a regular split because we can't get proper
20253 ;; lifetime information then.
20256 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20257 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20259 && ((TARGET_NOT_UNPAIRABLE
20260 && (!MEM_P (operands[0])
20261 || !memory_displacement_operand (operands[0], SImode)))
20262 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20263 && peep2_regno_dead_p (0, FLAGS_REG)"
20264 [(parallel [(set (match_dup 0)
20265 (xor:SI (match_dup 1) (const_int -1)))
20266 (clobber (reg:CC FLAGS_REG))])]
20270 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20271 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20273 && ((TARGET_NOT_UNPAIRABLE
20274 && (!MEM_P (operands[0])
20275 || !memory_displacement_operand (operands[0], HImode)))
20276 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20277 && peep2_regno_dead_p (0, FLAGS_REG)"
20278 [(parallel [(set (match_dup 0)
20279 (xor:HI (match_dup 1) (const_int -1)))
20280 (clobber (reg:CC FLAGS_REG))])]
20284 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20285 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20287 && ((TARGET_NOT_UNPAIRABLE
20288 && (!MEM_P (operands[0])
20289 || !memory_displacement_operand (operands[0], QImode)))
20290 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20291 && peep2_regno_dead_p (0, FLAGS_REG)"
20292 [(parallel [(set (match_dup 0)
20293 (xor:QI (match_dup 1) (const_int -1)))
20294 (clobber (reg:CC FLAGS_REG))])]
20297 ;; Non pairable "test imm, reg" instructions can be translated to
20298 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20299 ;; byte opcode instead of two, have a short form for byte operands),
20300 ;; so do it for other CPUs as well. Given that the value was dead,
20301 ;; this should not create any new dependencies. Pass on the sub-word
20302 ;; versions if we're concerned about partial register stalls.
20305 [(set (match_operand 0 "flags_reg_operand" "")
20306 (match_operator 1 "compare_operator"
20307 [(and:SI (match_operand:SI 2 "register_operand" "")
20308 (match_operand:SI 3 "immediate_operand" ""))
20310 "ix86_match_ccmode (insn, CCNOmode)
20311 && (true_regnum (operands[2]) != AX_REG
20312 || satisfies_constraint_K (operands[3]))
20313 && peep2_reg_dead_p (1, operands[2])"
20315 [(set (match_dup 0)
20316 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20319 (and:SI (match_dup 2) (match_dup 3)))])]
20322 ;; We don't need to handle HImode case, because it will be promoted to SImode
20323 ;; on ! TARGET_PARTIAL_REG_STALL
20326 [(set (match_operand 0 "flags_reg_operand" "")
20327 (match_operator 1 "compare_operator"
20328 [(and:QI (match_operand:QI 2 "register_operand" "")
20329 (match_operand:QI 3 "immediate_operand" ""))
20331 "! TARGET_PARTIAL_REG_STALL
20332 && ix86_match_ccmode (insn, CCNOmode)
20333 && true_regnum (operands[2]) != AX_REG
20334 && peep2_reg_dead_p (1, operands[2])"
20336 [(set (match_dup 0)
20337 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20340 (and:QI (match_dup 2) (match_dup 3)))])]
20344 [(set (match_operand 0 "flags_reg_operand" "")
20345 (match_operator 1 "compare_operator"
20348 (match_operand 2 "ext_register_operand" "")
20351 (match_operand 3 "const_int_operand" ""))
20353 "! TARGET_PARTIAL_REG_STALL
20354 && ix86_match_ccmode (insn, CCNOmode)
20355 && true_regnum (operands[2]) != AX_REG
20356 && peep2_reg_dead_p (1, operands[2])"
20357 [(parallel [(set (match_dup 0)
20366 (set (zero_extract:SI (match_dup 2)
20377 ;; Don't do logical operations with memory inputs.
20379 [(match_scratch:SI 2 "r")
20380 (parallel [(set (match_operand:SI 0 "register_operand" "")
20381 (match_operator:SI 3 "arith_or_logical_operator"
20383 (match_operand:SI 1 "memory_operand" "")]))
20384 (clobber (reg:CC FLAGS_REG))])]
20385 "! optimize_size && ! TARGET_READ_MODIFY"
20386 [(set (match_dup 2) (match_dup 1))
20387 (parallel [(set (match_dup 0)
20388 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20389 (clobber (reg:CC FLAGS_REG))])]
20393 [(match_scratch:SI 2 "r")
20394 (parallel [(set (match_operand:SI 0 "register_operand" "")
20395 (match_operator:SI 3 "arith_or_logical_operator"
20396 [(match_operand:SI 1 "memory_operand" "")
20398 (clobber (reg:CC FLAGS_REG))])]
20399 "! optimize_size && ! TARGET_READ_MODIFY"
20400 [(set (match_dup 2) (match_dup 1))
20401 (parallel [(set (match_dup 0)
20402 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20403 (clobber (reg:CC FLAGS_REG))])]
20406 ; Don't do logical operations with memory outputs
20408 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20409 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20410 ; the same decoder scheduling characteristics as the original.
20413 [(match_scratch:SI 2 "r")
20414 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20415 (match_operator:SI 3 "arith_or_logical_operator"
20417 (match_operand:SI 1 "nonmemory_operand" "")]))
20418 (clobber (reg:CC FLAGS_REG))])]
20419 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20420 [(set (match_dup 2) (match_dup 0))
20421 (parallel [(set (match_dup 2)
20422 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20423 (clobber (reg:CC FLAGS_REG))])
20424 (set (match_dup 0) (match_dup 2))]
20428 [(match_scratch:SI 2 "r")
20429 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20430 (match_operator:SI 3 "arith_or_logical_operator"
20431 [(match_operand:SI 1 "nonmemory_operand" "")
20433 (clobber (reg:CC FLAGS_REG))])]
20434 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20435 [(set (match_dup 2) (match_dup 0))
20436 (parallel [(set (match_dup 2)
20437 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20438 (clobber (reg:CC FLAGS_REG))])
20439 (set (match_dup 0) (match_dup 2))]
20442 ;; Attempt to always use XOR for zeroing registers.
20444 [(set (match_operand 0 "register_operand" "")
20445 (match_operand 1 "const0_operand" ""))]
20446 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20447 && (! TARGET_USE_MOV0 || optimize_size)
20448 && GENERAL_REG_P (operands[0])
20449 && peep2_regno_dead_p (0, FLAGS_REG)"
20450 [(parallel [(set (match_dup 0) (const_int 0))
20451 (clobber (reg:CC FLAGS_REG))])]
20453 operands[0] = gen_lowpart (word_mode, operands[0]);
20457 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20459 "(GET_MODE (operands[0]) == QImode
20460 || GET_MODE (operands[0]) == HImode)
20461 && (! TARGET_USE_MOV0 || optimize_size)
20462 && peep2_regno_dead_p (0, FLAGS_REG)"
20463 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20464 (clobber (reg:CC FLAGS_REG))])])
20466 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20468 [(set (match_operand 0 "register_operand" "")
20470 "(GET_MODE (operands[0]) == HImode
20471 || GET_MODE (operands[0]) == SImode
20472 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20473 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20474 && peep2_regno_dead_p (0, FLAGS_REG)"
20475 [(parallel [(set (match_dup 0) (const_int -1))
20476 (clobber (reg:CC FLAGS_REG))])]
20477 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20480 ;; Attempt to convert simple leas to adds. These can be created by
20483 [(set (match_operand:SI 0 "register_operand" "")
20484 (plus:SI (match_dup 0)
20485 (match_operand:SI 1 "nonmemory_operand" "")))]
20486 "peep2_regno_dead_p (0, FLAGS_REG)"
20487 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20488 (clobber (reg:CC FLAGS_REG))])]
20492 [(set (match_operand:SI 0 "register_operand" "")
20493 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20494 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20495 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20496 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20497 (clobber (reg:CC FLAGS_REG))])]
20498 "operands[2] = gen_lowpart (SImode, operands[2]);")
20501 [(set (match_operand:DI 0 "register_operand" "")
20502 (plus:DI (match_dup 0)
20503 (match_operand:DI 1 "x86_64_general_operand" "")))]
20504 "peep2_regno_dead_p (0, FLAGS_REG)"
20505 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20506 (clobber (reg:CC FLAGS_REG))])]
20510 [(set (match_operand:SI 0 "register_operand" "")
20511 (mult:SI (match_dup 0)
20512 (match_operand:SI 1 "const_int_operand" "")))]
20513 "exact_log2 (INTVAL (operands[1])) >= 0
20514 && peep2_regno_dead_p (0, FLAGS_REG)"
20515 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20516 (clobber (reg:CC FLAGS_REG))])]
20517 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20520 [(set (match_operand:DI 0 "register_operand" "")
20521 (mult:DI (match_dup 0)
20522 (match_operand:DI 1 "const_int_operand" "")))]
20523 "exact_log2 (INTVAL (operands[1])) >= 0
20524 && peep2_regno_dead_p (0, FLAGS_REG)"
20525 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20526 (clobber (reg:CC FLAGS_REG))])]
20527 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20530 [(set (match_operand:SI 0 "register_operand" "")
20531 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20532 (match_operand:DI 2 "const_int_operand" "")) 0))]
20533 "exact_log2 (INTVAL (operands[2])) >= 0
20534 && REGNO (operands[0]) == REGNO (operands[1])
20535 && peep2_regno_dead_p (0, FLAGS_REG)"
20536 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20537 (clobber (reg:CC FLAGS_REG))])]
20538 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20540 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20541 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20542 ;; many CPUs it is also faster, since special hardware to avoid esp
20543 ;; dependencies is present.
20545 ;; While some of these conversions may be done using splitters, we use peepholes
20546 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20548 ;; Convert prologue esp subtractions to push.
20549 ;; We need register to push. In order to keep verify_flow_info happy we have
20551 ;; - use scratch and clobber it in order to avoid dependencies
20552 ;; - use already live register
20553 ;; We can't use the second way right now, since there is no reliable way how to
20554 ;; verify that given register is live. First choice will also most likely in
20555 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20556 ;; call clobbered registers are dead. We may want to use base pointer as an
20557 ;; alternative when no register is available later.
20560 [(match_scratch:SI 0 "r")
20561 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20562 (clobber (reg:CC FLAGS_REG))
20563 (clobber (mem:BLK (scratch)))])]
20564 "optimize_size || !TARGET_SUB_ESP_4"
20565 [(clobber (match_dup 0))
20566 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20567 (clobber (mem:BLK (scratch)))])])
20570 [(match_scratch:SI 0 "r")
20571 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20572 (clobber (reg:CC FLAGS_REG))
20573 (clobber (mem:BLK (scratch)))])]
20574 "optimize_size || !TARGET_SUB_ESP_8"
20575 [(clobber (match_dup 0))
20576 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20577 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20578 (clobber (mem:BLK (scratch)))])])
20580 ;; Convert esp subtractions to push.
20582 [(match_scratch:SI 0 "r")
20583 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20584 (clobber (reg:CC FLAGS_REG))])]
20585 "optimize_size || !TARGET_SUB_ESP_4"
20586 [(clobber (match_dup 0))
20587 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20590 [(match_scratch:SI 0 "r")
20591 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20592 (clobber (reg:CC FLAGS_REG))])]
20593 "optimize_size || !TARGET_SUB_ESP_8"
20594 [(clobber (match_dup 0))
20595 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20596 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20598 ;; Convert epilogue deallocator to pop.
20600 [(match_scratch:SI 0 "r")
20601 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20602 (clobber (reg:CC FLAGS_REG))
20603 (clobber (mem:BLK (scratch)))])]
20604 "optimize_size || !TARGET_ADD_ESP_4"
20605 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20606 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20607 (clobber (mem:BLK (scratch)))])]
20610 ;; Two pops case is tricky, since pop causes dependency on destination register.
20611 ;; We use two registers if available.
20613 [(match_scratch:SI 0 "r")
20614 (match_scratch:SI 1 "r")
20615 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20616 (clobber (reg:CC FLAGS_REG))
20617 (clobber (mem:BLK (scratch)))])]
20618 "optimize_size || !TARGET_ADD_ESP_8"
20619 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20620 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20621 (clobber (mem:BLK (scratch)))])
20622 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20623 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20627 [(match_scratch:SI 0 "r")
20628 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20629 (clobber (reg:CC FLAGS_REG))
20630 (clobber (mem:BLK (scratch)))])]
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 (clobber (mem:BLK (scratch)))])
20635 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20636 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20639 ;; Convert esp additions to pop.
20641 [(match_scratch:SI 0 "r")
20642 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20643 (clobber (reg:CC FLAGS_REG))])]
20645 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20646 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20649 ;; Two pops case is tricky, since pop causes dependency on destination register.
20650 ;; We use two registers if available.
20652 [(match_scratch:SI 0 "r")
20653 (match_scratch:SI 1 "r")
20654 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20655 (clobber (reg:CC FLAGS_REG))])]
20657 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20658 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20659 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20660 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20664 [(match_scratch:SI 0 "r")
20665 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20666 (clobber (reg:CC FLAGS_REG))])]
20668 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20669 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20670 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20671 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20674 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20675 ;; required and register dies. Similarly for 128 to plus -128.
20677 [(set (match_operand 0 "flags_reg_operand" "")
20678 (match_operator 1 "compare_operator"
20679 [(match_operand 2 "register_operand" "")
20680 (match_operand 3 "const_int_operand" "")]))]
20681 "(INTVAL (operands[3]) == -1
20682 || INTVAL (operands[3]) == 1
20683 || INTVAL (operands[3]) == 128)
20684 && ix86_match_ccmode (insn, CCGCmode)
20685 && peep2_reg_dead_p (1, operands[2])"
20686 [(parallel [(set (match_dup 0)
20687 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20688 (clobber (match_dup 2))])]
20692 [(match_scratch:DI 0 "r")
20693 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20694 (clobber (reg:CC FLAGS_REG))
20695 (clobber (mem:BLK (scratch)))])]
20696 "optimize_size || !TARGET_SUB_ESP_4"
20697 [(clobber (match_dup 0))
20698 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20699 (clobber (mem:BLK (scratch)))])])
20702 [(match_scratch:DI 0 "r")
20703 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20704 (clobber (reg:CC FLAGS_REG))
20705 (clobber (mem:BLK (scratch)))])]
20706 "optimize_size || !TARGET_SUB_ESP_8"
20707 [(clobber (match_dup 0))
20708 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20709 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20710 (clobber (mem:BLK (scratch)))])])
20712 ;; Convert esp subtractions to push.
20714 [(match_scratch:DI 0 "r")
20715 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20716 (clobber (reg:CC FLAGS_REG))])]
20717 "optimize_size || !TARGET_SUB_ESP_4"
20718 [(clobber (match_dup 0))
20719 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20722 [(match_scratch:DI 0 "r")
20723 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20724 (clobber (reg:CC FLAGS_REG))])]
20725 "optimize_size || !TARGET_SUB_ESP_8"
20726 [(clobber (match_dup 0))
20727 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20728 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20730 ;; Convert epilogue deallocator to pop.
20732 [(match_scratch:DI 0 "r")
20733 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20734 (clobber (reg:CC FLAGS_REG))
20735 (clobber (mem:BLK (scratch)))])]
20736 "optimize_size || !TARGET_ADD_ESP_4"
20737 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20738 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20739 (clobber (mem:BLK (scratch)))])]
20742 ;; Two pops case is tricky, since pop causes dependency on destination register.
20743 ;; We use two registers if available.
20745 [(match_scratch:DI 0 "r")
20746 (match_scratch:DI 1 "r")
20747 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20748 (clobber (reg:CC FLAGS_REG))
20749 (clobber (mem:BLK (scratch)))])]
20750 "optimize_size || !TARGET_ADD_ESP_8"
20751 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20752 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20753 (clobber (mem:BLK (scratch)))])
20754 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20755 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20759 [(match_scratch:DI 0 "r")
20760 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20761 (clobber (reg:CC FLAGS_REG))
20762 (clobber (mem:BLK (scratch)))])]
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 (clobber (mem:BLK (scratch)))])
20767 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20768 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20771 ;; Convert esp additions to pop.
20773 [(match_scratch:DI 0 "r")
20774 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20775 (clobber (reg:CC FLAGS_REG))])]
20777 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20778 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20781 ;; Two pops case is tricky, since pop causes dependency on destination register.
20782 ;; We use two registers if available.
20784 [(match_scratch:DI 0 "r")
20785 (match_scratch:DI 1 "r")
20786 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20787 (clobber (reg:CC FLAGS_REG))])]
20789 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20790 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20791 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20792 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20796 [(match_scratch:DI 0 "r")
20797 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20798 (clobber (reg:CC FLAGS_REG))])]
20800 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20801 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20802 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20803 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20806 ;; Convert imul by three, five and nine into lea
20809 [(set (match_operand:SI 0 "register_operand" "")
20810 (mult:SI (match_operand:SI 1 "register_operand" "")
20811 (match_operand:SI 2 "const_int_operand" "")))
20812 (clobber (reg:CC FLAGS_REG))])]
20813 "INTVAL (operands[2]) == 3
20814 || INTVAL (operands[2]) == 5
20815 || INTVAL (operands[2]) == 9"
20816 [(set (match_dup 0)
20817 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20819 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20823 [(set (match_operand:SI 0 "register_operand" "")
20824 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20825 (match_operand:SI 2 "const_int_operand" "")))
20826 (clobber (reg:CC FLAGS_REG))])]
20828 && (INTVAL (operands[2]) == 3
20829 || INTVAL (operands[2]) == 5
20830 || INTVAL (operands[2]) == 9)"
20831 [(set (match_dup 0) (match_dup 1))
20833 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20835 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20839 [(set (match_operand:DI 0 "register_operand" "")
20840 (mult:DI (match_operand:DI 1 "register_operand" "")
20841 (match_operand:DI 2 "const_int_operand" "")))
20842 (clobber (reg:CC FLAGS_REG))])]
20844 && (INTVAL (operands[2]) == 3
20845 || INTVAL (operands[2]) == 5
20846 || INTVAL (operands[2]) == 9)"
20847 [(set (match_dup 0)
20848 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20850 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20854 [(set (match_operand:DI 0 "register_operand" "")
20855 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20856 (match_operand:DI 2 "const_int_operand" "")))
20857 (clobber (reg:CC FLAGS_REG))])]
20860 && (INTVAL (operands[2]) == 3
20861 || INTVAL (operands[2]) == 5
20862 || INTVAL (operands[2]) == 9)"
20863 [(set (match_dup 0) (match_dup 1))
20865 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20867 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20869 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20870 ;; imul $32bit_imm, reg, reg is direct decoded.
20872 [(match_scratch:DI 3 "r")
20873 (parallel [(set (match_operand:DI 0 "register_operand" "")
20874 (mult:DI (match_operand:DI 1 "memory_operand" "")
20875 (match_operand:DI 2 "immediate_operand" "")))
20876 (clobber (reg:CC FLAGS_REG))])]
20877 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20878 && !satisfies_constraint_K (operands[2])"
20879 [(set (match_dup 3) (match_dup 1))
20880 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20881 (clobber (reg:CC FLAGS_REG))])]
20885 [(match_scratch:SI 3 "r")
20886 (parallel [(set (match_operand:SI 0 "register_operand" "")
20887 (mult:SI (match_operand:SI 1 "memory_operand" "")
20888 (match_operand:SI 2 "immediate_operand" "")))
20889 (clobber (reg:CC FLAGS_REG))])]
20890 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20891 && !satisfies_constraint_K (operands[2])"
20892 [(set (match_dup 3) (match_dup 1))
20893 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20894 (clobber (reg:CC FLAGS_REG))])]
20898 [(match_scratch:SI 3 "r")
20899 (parallel [(set (match_operand:DI 0 "register_operand" "")
20901 (mult:SI (match_operand:SI 1 "memory_operand" "")
20902 (match_operand:SI 2 "immediate_operand" ""))))
20903 (clobber (reg:CC FLAGS_REG))])]
20904 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20905 && !satisfies_constraint_K (operands[2])"
20906 [(set (match_dup 3) (match_dup 1))
20907 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20908 (clobber (reg:CC FLAGS_REG))])]
20911 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20912 ;; Convert it into imul reg, reg
20913 ;; It would be better to force assembler to encode instruction using long
20914 ;; immediate, but there is apparently no way to do so.
20916 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20917 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20918 (match_operand:DI 2 "const_int_operand" "")))
20919 (clobber (reg:CC FLAGS_REG))])
20920 (match_scratch:DI 3 "r")]
20921 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20922 && satisfies_constraint_K (operands[2])"
20923 [(set (match_dup 3) (match_dup 2))
20924 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20925 (clobber (reg:CC FLAGS_REG))])]
20927 if (!rtx_equal_p (operands[0], operands[1]))
20928 emit_move_insn (operands[0], operands[1]);
20932 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20933 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20934 (match_operand:SI 2 "const_int_operand" "")))
20935 (clobber (reg:CC FLAGS_REG))])
20936 (match_scratch:SI 3 "r")]
20937 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20938 && satisfies_constraint_K (operands[2])"
20939 [(set (match_dup 3) (match_dup 2))
20940 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20941 (clobber (reg:CC FLAGS_REG))])]
20943 if (!rtx_equal_p (operands[0], operands[1]))
20944 emit_move_insn (operands[0], operands[1]);
20948 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20949 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20950 (match_operand:HI 2 "immediate_operand" "")))
20951 (clobber (reg:CC FLAGS_REG))])
20952 (match_scratch:HI 3 "r")]
20953 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20954 [(set (match_dup 3) (match_dup 2))
20955 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20956 (clobber (reg:CC FLAGS_REG))])]
20958 if (!rtx_equal_p (operands[0], operands[1]))
20959 emit_move_insn (operands[0], operands[1]);
20962 ;; After splitting up read-modify operations, array accesses with memory
20963 ;; operands might end up in form:
20965 ;; movl 4(%esp), %edx
20967 ;; instead of pre-splitting:
20969 ;; addl 4(%esp), %eax
20971 ;; movl 4(%esp), %edx
20972 ;; leal (%edx,%eax,4), %eax
20975 [(parallel [(set (match_operand 0 "register_operand" "")
20976 (ashift (match_operand 1 "register_operand" "")
20977 (match_operand 2 "const_int_operand" "")))
20978 (clobber (reg:CC FLAGS_REG))])
20979 (set (match_operand 3 "register_operand")
20980 (match_operand 4 "x86_64_general_operand" ""))
20981 (parallel [(set (match_operand 5 "register_operand" "")
20982 (plus (match_operand 6 "register_operand" "")
20983 (match_operand 7 "register_operand" "")))
20984 (clobber (reg:CC FLAGS_REG))])]
20985 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20986 /* Validate MODE for lea. */
20987 && ((!TARGET_PARTIAL_REG_STALL
20988 && (GET_MODE (operands[0]) == QImode
20989 || GET_MODE (operands[0]) == HImode))
20990 || GET_MODE (operands[0]) == SImode
20991 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20992 /* We reorder load and the shift. */
20993 && !rtx_equal_p (operands[1], operands[3])
20994 && !reg_overlap_mentioned_p (operands[0], operands[4])
20995 /* Last PLUS must consist of operand 0 and 3. */
20996 && !rtx_equal_p (operands[0], operands[3])
20997 && (rtx_equal_p (operands[3], operands[6])
20998 || rtx_equal_p (operands[3], operands[7]))
20999 && (rtx_equal_p (operands[0], operands[6])
21000 || rtx_equal_p (operands[0], operands[7]))
21001 /* The intermediate operand 0 must die or be same as output. */
21002 && (rtx_equal_p (operands[0], operands[5])
21003 || peep2_reg_dead_p (3, operands[0]))"
21004 [(set (match_dup 3) (match_dup 4))
21005 (set (match_dup 0) (match_dup 1))]
21007 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21008 int scale = 1 << INTVAL (operands[2]);
21009 rtx index = gen_lowpart (Pmode, operands[1]);
21010 rtx base = gen_lowpart (Pmode, operands[3]);
21011 rtx dest = gen_lowpart (mode, operands[5]);
21013 operands[1] = gen_rtx_PLUS (Pmode, base,
21014 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21016 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21017 operands[0] = dest;
21020 ;; Call-value patterns last so that the wildcard operand does not
21021 ;; disrupt insn-recog's switch tables.
21023 (define_insn "*call_value_pop_0"
21024 [(set (match_operand 0 "" "")
21025 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21026 (match_operand:SI 2 "" "")))
21027 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21028 (match_operand:SI 3 "immediate_operand" "")))]
21031 if (SIBLING_CALL_P (insn))
21034 return "call\t%P1";
21036 [(set_attr "type" "callv")])
21038 (define_insn "*call_value_pop_1"
21039 [(set (match_operand 0 "" "")
21040 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21041 (match_operand:SI 2 "" "")))
21042 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21043 (match_operand:SI 3 "immediate_operand" "i")))]
21046 if (constant_call_address_operand (operands[1], Pmode))
21048 if (SIBLING_CALL_P (insn))
21051 return "call\t%P1";
21053 if (SIBLING_CALL_P (insn))
21056 return "call\t%A1";
21058 [(set_attr "type" "callv")])
21060 (define_insn "*call_value_0"
21061 [(set (match_operand 0 "" "")
21062 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21063 (match_operand:SI 2 "" "")))]
21066 if (SIBLING_CALL_P (insn))
21069 return "call\t%P1";
21071 [(set_attr "type" "callv")])
21073 (define_insn "*call_value_0_rex64"
21074 [(set (match_operand 0 "" "")
21075 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21076 (match_operand:DI 2 "const_int_operand" "")))]
21079 if (SIBLING_CALL_P (insn))
21082 return "call\t%P1";
21084 [(set_attr "type" "callv")])
21086 (define_insn "*call_value_1"
21087 [(set (match_operand 0 "" "")
21088 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21089 (match_operand:SI 2 "" "")))]
21090 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21092 if (constant_call_address_operand (operands[1], Pmode))
21093 return "call\t%P1";
21094 return "call\t%A1";
21096 [(set_attr "type" "callv")])
21098 (define_insn "*sibcall_value_1"
21099 [(set (match_operand 0 "" "")
21100 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21101 (match_operand:SI 2 "" "")))]
21102 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21104 if (constant_call_address_operand (operands[1], Pmode))
21108 [(set_attr "type" "callv")])
21110 (define_insn "*call_value_1_rex64"
21111 [(set (match_operand 0 "" "")
21112 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21113 (match_operand:DI 2 "" "")))]
21114 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21115 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21117 if (constant_call_address_operand (operands[1], Pmode))
21118 return "call\t%P1";
21119 return "call\t%A1";
21121 [(set_attr "type" "callv")])
21123 (define_insn "*call_value_1_rex64_large"
21124 [(set (match_operand 0 "" "")
21125 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21126 (match_operand:DI 2 "" "")))]
21127 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21129 [(set_attr "type" "callv")])
21131 (define_insn "*sibcall_value_1_rex64"
21132 [(set (match_operand 0 "" "")
21133 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21134 (match_operand:DI 2 "" "")))]
21135 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21137 [(set_attr "type" "callv")])
21139 (define_insn "*sibcall_value_1_rex64_v"
21140 [(set (match_operand 0 "" "")
21141 (call (mem:QI (reg:DI R11_REG))
21142 (match_operand:DI 1 "" "")))]
21143 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21145 [(set_attr "type" "callv")])
21147 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21148 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21149 ;; caught for use by garbage collectors and the like. Using an insn that
21150 ;; maps to SIGILL makes it more likely the program will rightfully die.
21151 ;; Keeping with tradition, "6" is in honor of #UD.
21152 (define_insn "trap"
21153 [(trap_if (const_int 1) (const_int 6))]
21155 { return ASM_SHORT "0x0b0f"; }
21156 [(set_attr "length" "2")])
21158 (define_expand "sse_prologue_save"
21159 [(parallel [(set (match_operand:BLK 0 "" "")
21160 (unspec:BLK [(reg:DI 21)
21167 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21168 (use (match_operand:DI 1 "register_operand" ""))
21169 (use (match_operand:DI 2 "immediate_operand" ""))
21170 (use (label_ref:DI (match_operand 3 "" "")))])]
21174 (define_insn "*sse_prologue_save_insn"
21175 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21176 (match_operand:DI 4 "const_int_operand" "n")))
21177 (unspec:BLK [(reg:DI 21)
21184 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21185 (use (match_operand:DI 1 "register_operand" "r"))
21186 (use (match_operand:DI 2 "const_int_operand" "i"))
21187 (use (label_ref:DI (match_operand 3 "" "X")))]
21189 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21190 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21194 operands[0] = gen_rtx_MEM (Pmode,
21195 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21196 output_asm_insn (\"jmp\\t%A1\", operands);
21197 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21199 operands[4] = adjust_address (operands[0], DImode, i*16);
21200 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21201 PUT_MODE (operands[4], TImode);
21202 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21203 output_asm_insn (\"rex\", operands);
21204 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21206 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21207 CODE_LABEL_NUMBER (operands[3]));
21211 [(set_attr "type" "other")
21212 (set_attr "length_immediate" "0")
21213 (set_attr "length_address" "0")
21214 (set_attr "length" "135")
21215 (set_attr "memory" "store")
21216 (set_attr "modrm" "0")
21217 (set_attr "mode" "DI")])
21219 (define_expand "prefetch"
21220 [(prefetch (match_operand 0 "address_operand" "")
21221 (match_operand:SI 1 "const_int_operand" "")
21222 (match_operand:SI 2 "const_int_operand" ""))]
21223 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21225 int rw = INTVAL (operands[1]);
21226 int locality = INTVAL (operands[2]);
21228 gcc_assert (rw == 0 || rw == 1);
21229 gcc_assert (locality >= 0 && locality <= 3);
21230 gcc_assert (GET_MODE (operands[0]) == Pmode
21231 || GET_MODE (operands[0]) == VOIDmode);
21233 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21234 supported by SSE counterpart or the SSE prefetch is not available
21235 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21237 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21238 operands[2] = GEN_INT (3);
21240 operands[1] = const0_rtx;
21243 (define_insn "*prefetch_sse"
21244 [(prefetch (match_operand:SI 0 "address_operand" "p")
21246 (match_operand:SI 1 "const_int_operand" ""))]
21247 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21249 static const char * const patterns[4] = {
21250 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21253 int locality = INTVAL (operands[1]);
21254 gcc_assert (locality >= 0 && locality <= 3);
21256 return patterns[locality];
21258 [(set_attr "type" "sse")
21259 (set_attr "memory" "none")])
21261 (define_insn "*prefetch_sse_rex"
21262 [(prefetch (match_operand:DI 0 "address_operand" "p")
21264 (match_operand:SI 1 "const_int_operand" ""))]
21265 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21267 static const char * const patterns[4] = {
21268 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21271 int locality = INTVAL (operands[1]);
21272 gcc_assert (locality >= 0 && locality <= 3);
21274 return patterns[locality];
21276 [(set_attr "type" "sse")
21277 (set_attr "memory" "none")])
21279 (define_insn "*prefetch_3dnow"
21280 [(prefetch (match_operand:SI 0 "address_operand" "p")
21281 (match_operand:SI 1 "const_int_operand" "n")
21283 "TARGET_3DNOW && !TARGET_64BIT"
21285 if (INTVAL (operands[1]) == 0)
21286 return "prefetch\t%a0";
21288 return "prefetchw\t%a0";
21290 [(set_attr "type" "mmx")
21291 (set_attr "memory" "none")])
21293 (define_insn "*prefetch_3dnow_rex"
21294 [(prefetch (match_operand:DI 0 "address_operand" "p")
21295 (match_operand:SI 1 "const_int_operand" "n")
21297 "TARGET_3DNOW && TARGET_64BIT"
21299 if (INTVAL (operands[1]) == 0)
21300 return "prefetch\t%a0";
21302 return "prefetchw\t%a0";
21304 [(set_attr "type" "mmx")
21305 (set_attr "memory" "none")])
21307 (define_expand "stack_protect_set"
21308 [(match_operand 0 "memory_operand" "")
21309 (match_operand 1 "memory_operand" "")]
21312 #ifdef TARGET_THREAD_SSP_OFFSET
21314 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21315 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21317 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21318 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21321 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21323 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21328 (define_insn "stack_protect_set_si"
21329 [(set (match_operand:SI 0 "memory_operand" "=m")
21330 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21331 (set (match_scratch:SI 2 "=&r") (const_int 0))
21332 (clobber (reg:CC FLAGS_REG))]
21334 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21335 [(set_attr "type" "multi")])
21337 (define_insn "stack_protect_set_di"
21338 [(set (match_operand:DI 0 "memory_operand" "=m")
21339 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21340 (set (match_scratch:DI 2 "=&r") (const_int 0))
21341 (clobber (reg:CC FLAGS_REG))]
21343 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21344 [(set_attr "type" "multi")])
21346 (define_insn "stack_tls_protect_set_si"
21347 [(set (match_operand:SI 0 "memory_operand" "=m")
21348 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21349 (set (match_scratch:SI 2 "=&r") (const_int 0))
21350 (clobber (reg:CC FLAGS_REG))]
21352 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21353 [(set_attr "type" "multi")])
21355 (define_insn "stack_tls_protect_set_di"
21356 [(set (match_operand:DI 0 "memory_operand" "=m")
21357 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21358 (set (match_scratch:DI 2 "=&r") (const_int 0))
21359 (clobber (reg:CC FLAGS_REG))]
21362 /* The kernel uses a different segment register for performance reasons; a
21363 system call would not have to trash the userspace segment register,
21364 which would be expensive */
21365 if (ix86_cmodel != CM_KERNEL)
21366 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21368 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21370 [(set_attr "type" "multi")])
21372 (define_expand "stack_protect_test"
21373 [(match_operand 0 "memory_operand" "")
21374 (match_operand 1 "memory_operand" "")
21375 (match_operand 2 "" "")]
21378 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21379 ix86_compare_op0 = operands[0];
21380 ix86_compare_op1 = operands[1];
21381 ix86_compare_emitted = flags;
21383 #ifdef TARGET_THREAD_SSP_OFFSET
21385 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21386 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21388 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21389 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21392 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21394 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21396 emit_jump_insn (gen_beq (operands[2]));
21400 (define_insn "stack_protect_test_si"
21401 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21402 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21403 (match_operand:SI 2 "memory_operand" "m")]
21405 (clobber (match_scratch:SI 3 "=&r"))]
21407 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21408 [(set_attr "type" "multi")])
21410 (define_insn "stack_protect_test_di"
21411 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21412 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21413 (match_operand:DI 2 "memory_operand" "m")]
21415 (clobber (match_scratch:DI 3 "=&r"))]
21417 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21418 [(set_attr "type" "multi")])
21420 (define_insn "stack_tls_protect_test_si"
21421 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21422 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21423 (match_operand:SI 2 "const_int_operand" "i")]
21424 UNSPEC_SP_TLS_TEST))
21425 (clobber (match_scratch:SI 3 "=r"))]
21427 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21428 [(set_attr "type" "multi")])
21430 (define_insn "stack_tls_protect_test_di"
21431 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21432 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21433 (match_operand:DI 2 "const_int_operand" "i")]
21434 UNSPEC_SP_TLS_TEST))
21435 (clobber (match_scratch:DI 3 "=r"))]
21438 /* The kernel uses a different segment register for performance reasons; a
21439 system call would not have to trash the userspace segment register,
21440 which would be expensive */
21441 if (ix86_cmodel != CM_KERNEL)
21442 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21444 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21446 [(set_attr "type" "multi")])
21448 (define_mode_iterator CRC32MODE [QI HI SI])
21449 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21450 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21452 (define_insn "sse4_2_crc32<mode>"
21453 [(set (match_operand:SI 0 "register_operand" "=r")
21455 [(match_operand:SI 1 "register_operand" "0")
21456 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21459 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21460 [(set_attr "type" "sselog1")
21461 (set_attr "prefix_rep" "1")
21462 (set_attr "prefix_extra" "1")
21463 (set_attr "mode" "SI")])
21465 (define_insn "sse4_2_crc32di"
21466 [(set (match_operand:DI 0 "register_operand" "=r")
21468 [(match_operand:DI 1 "register_operand" "0")
21469 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21471 "TARGET_SSE4_2 && TARGET_64BIT"
21472 "crc32q\t{%2, %0|%0, %2}"
21473 [(set_attr "type" "sselog1")
21474 (set_attr "prefix_rep" "1")
21475 (set_attr "prefix_extra" "1")
21476 (set_attr "mode" "DI")])
21480 (include "sync.md")