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
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 2, 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 COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; The special asm out single letter directives following a '%' are:
31 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
33 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
34 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
35 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
36 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
37 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
38 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
39 ;; 'J' Print the appropriate jump operand.
41 ;; 'b' Print the QImode name of the register for the indicated operand.
42 ;; %b0 would print %al if operands[0] is reg 0.
43 ;; 'w' Likewise, print the HImode name of the register.
44 ;; 'k' Likewise, print the SImode name of the register.
45 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
46 ;; 'y' Print "st(0)" instead of "st" as a register.
51 [; Relocation specifiers
64 (UNSPEC_STACK_ALLOC 11)
66 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70 (UNSPEC_SET_GOT_OFFSET 17)
75 (UNSPEC_TLS_LD_BASE 20)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 39)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 40)
99 (UNSPEC_NOP 48) ; prevents combiner cleverness
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
128 (UNSPEC_FRNDINT_FLOOR 70)
129 (UNSPEC_FRNDINT_CEIL 71)
130 (UNSPEC_FRNDINT_TRUNC 72)
131 (UNSPEC_FRNDINT_MASK_PM 73)
132 (UNSPEC_FIST_FLOOR 74)
133 (UNSPEC_FIST_CEIL 75)
135 ; x87 Double output FP
136 (UNSPEC_SINCOS_COS 80)
137 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
152 (UNSPEC_SP_TLS_SET 102)
153 (UNSPEC_SP_TLS_TEST 103)
163 (UNSPEC_INSERTQI 132)
168 (UNSPEC_INSERTPS 135)
170 (UNSPEC_MOVNTDQA 137)
172 (UNSPEC_PHMINPOSUW 139)
179 [(UNSPECV_BLOCKAGE 0)
180 (UNSPECV_STACK_PROBE 1)
189 (UNSPECV_CMPXCHG_1 10)
190 (UNSPECV_CMPXCHG_2 11)
195 ;; Registers by name.
206 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
209 ;; In C guard expressions, put expressions which may be compile-time
210 ;; constants first. This allows for better optimization. For
211 ;; example, write "TARGET_64BIT && reload_completed", not
212 ;; "reload_completed && TARGET_64BIT".
215 ;; Processor type. This attribute must exactly match the processor_type
216 ;; enumeration in i386.h.
217 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
218 nocona,core2,generic32,generic64,amdfam10"
219 (const (symbol_ref "ix86_tune")))
221 ;; A basic instruction type. Refinements due to arguments to be
222 ;; provided in other attributes.
225 alu,alu1,negnot,imov,imovx,lea,
226 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
227 icmp,test,ibr,setcc,icmov,
228 push,pop,call,callv,leave,
230 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
231 sselog,sselog1,sseiadd,sseishft,sseimul,
232 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
233 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
234 (const_string "other"))
236 ;; Main data type used by the insn
238 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
239 (const_string "unknown"))
241 ;; The CPU unit operations uses.
242 (define_attr "unit" "integer,i387,sse,mmx,unknown"
243 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
244 (const_string "i387")
245 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
246 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
248 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
250 (eq_attr "type" "other")
251 (const_string "unknown")]
252 (const_string "integer")))
254 ;; The (bounding maximum) length of an instruction immediate.
255 (define_attr "length_immediate" ""
256 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
259 (eq_attr "unit" "i387,sse,mmx")
261 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
263 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
264 (eq_attr "type" "imov,test")
265 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
266 (eq_attr "type" "call")
267 (if_then_else (match_operand 0 "constant_call_address_operand" "")
270 (eq_attr "type" "callv")
271 (if_then_else (match_operand 1 "constant_call_address_operand" "")
274 ;; We don't know the size before shorten_branches. Expect
275 ;; the instruction to fit for better scheduling.
276 (eq_attr "type" "ibr")
279 (symbol_ref "/* Update immediate_length and other attributes! */
280 gcc_unreachable (),1")))
282 ;; The (bounding maximum) length of an instruction address.
283 (define_attr "length_address" ""
284 (cond [(eq_attr "type" "str,other,multi,fxch")
286 (and (eq_attr "type" "call")
287 (match_operand 0 "constant_call_address_operand" ""))
289 (and (eq_attr "type" "callv")
290 (match_operand 1 "constant_call_address_operand" ""))
293 (symbol_ref "ix86_attr_length_address_default (insn)")))
295 ;; Set when length prefix is used.
296 (define_attr "prefix_data16" ""
297 (if_then_else (ior (eq_attr "mode" "HI")
298 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
302 ;; Set when string REP prefix is used.
303 (define_attr "prefix_rep" ""
304 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
308 ;; Set when 0f opcode prefix is used.
309 (define_attr "prefix_0f" ""
311 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
312 (eq_attr "unit" "sse,mmx"))
316 ;; Set when REX opcode prefix is used.
317 (define_attr "prefix_rex" ""
318 (cond [(and (eq_attr "mode" "DI")
319 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
321 (and (eq_attr "mode" "QI")
322 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
325 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
331 ;; There are also additional prefixes in SSSE3.
332 (define_attr "prefix_extra" "" (const_int 0))
334 ;; Set when modrm byte is used.
335 (define_attr "modrm" ""
336 (cond [(eq_attr "type" "str,leave")
338 (eq_attr "unit" "i387")
340 (and (eq_attr "type" "incdec")
341 (ior (match_operand:SI 1 "register_operand" "")
342 (match_operand:HI 1 "register_operand" "")))
344 (and (eq_attr "type" "push")
345 (not (match_operand 1 "memory_operand" "")))
347 (and (eq_attr "type" "pop")
348 (not (match_operand 0 "memory_operand" "")))
350 (and (eq_attr "type" "imov")
351 (ior (and (match_operand 0 "register_operand" "")
352 (match_operand 1 "immediate_operand" ""))
353 (ior (and (match_operand 0 "ax_reg_operand" "")
354 (match_operand 1 "memory_displacement_only_operand" ""))
355 (and (match_operand 0 "memory_displacement_only_operand" "")
356 (match_operand 1 "ax_reg_operand" "")))))
358 (and (eq_attr "type" "call")
359 (match_operand 0 "constant_call_address_operand" ""))
361 (and (eq_attr "type" "callv")
362 (match_operand 1 "constant_call_address_operand" ""))
367 ;; The (bounding maximum) length of an instruction in bytes.
368 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
369 ;; Later we may want to split them and compute proper length as for
371 (define_attr "length" ""
372 (cond [(eq_attr "type" "other,multi,fistp,frndint")
374 (eq_attr "type" "fcmp")
376 (eq_attr "unit" "i387")
378 (plus (attr "prefix_data16")
379 (attr "length_address")))]
380 (plus (plus (attr "modrm")
381 (plus (attr "prefix_0f")
382 (plus (attr "prefix_rex")
383 (plus (attr "prefix_extra")
385 (plus (attr "prefix_rep")
386 (plus (attr "prefix_data16")
387 (plus (attr "length_immediate")
388 (attr "length_address")))))))
390 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
391 ;; `store' if there is a simple memory reference therein, or `unknown'
392 ;; if the instruction is complex.
394 (define_attr "memory" "none,load,store,both,unknown"
395 (cond [(eq_attr "type" "other,multi,str")
396 (const_string "unknown")
397 (eq_attr "type" "lea,fcmov,fpspc")
398 (const_string "none")
399 (eq_attr "type" "fistp,leave")
400 (const_string "both")
401 (eq_attr "type" "frndint")
402 (const_string "load")
403 (eq_attr "type" "push")
404 (if_then_else (match_operand 1 "memory_operand" "")
405 (const_string "both")
406 (const_string "store"))
407 (eq_attr "type" "pop")
408 (if_then_else (match_operand 0 "memory_operand" "")
409 (const_string "both")
410 (const_string "load"))
411 (eq_attr "type" "setcc")
412 (if_then_else (match_operand 0 "memory_operand" "")
413 (const_string "store")
414 (const_string "none"))
415 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
416 (if_then_else (ior (match_operand 0 "memory_operand" "")
417 (match_operand 1 "memory_operand" ""))
418 (const_string "load")
419 (const_string "none"))
420 (eq_attr "type" "ibr")
421 (if_then_else (match_operand 0 "memory_operand" "")
422 (const_string "load")
423 (const_string "none"))
424 (eq_attr "type" "call")
425 (if_then_else (match_operand 0 "constant_call_address_operand" "")
426 (const_string "none")
427 (const_string "load"))
428 (eq_attr "type" "callv")
429 (if_then_else (match_operand 1 "constant_call_address_operand" "")
430 (const_string "none")
431 (const_string "load"))
432 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
433 (match_operand 1 "memory_operand" ""))
434 (const_string "both")
435 (and (match_operand 0 "memory_operand" "")
436 (match_operand 1 "memory_operand" ""))
437 (const_string "both")
438 (match_operand 0 "memory_operand" "")
439 (const_string "store")
440 (match_operand 1 "memory_operand" "")
441 (const_string "load")
443 "!alu1,negnot,ishift1,
444 imov,imovx,icmp,test,bitmanip,
446 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
447 mmx,mmxmov,mmxcmp,mmxcvt")
448 (match_operand 2 "memory_operand" ""))
449 (const_string "load")
450 (and (eq_attr "type" "icmov")
451 (match_operand 3 "memory_operand" ""))
452 (const_string "load")
454 (const_string "none")))
456 ;; Indicates if an instruction has both an immediate and a displacement.
458 (define_attr "imm_disp" "false,true,unknown"
459 (cond [(eq_attr "type" "other,multi")
460 (const_string "unknown")
461 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
462 (and (match_operand 0 "memory_displacement_operand" "")
463 (match_operand 1 "immediate_operand" "")))
464 (const_string "true")
465 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
466 (and (match_operand 0 "memory_displacement_operand" "")
467 (match_operand 2 "immediate_operand" "")))
468 (const_string "true")
470 (const_string "false")))
472 ;; Indicates if an FP operation has an integer source.
474 (define_attr "fp_int_src" "false,true"
475 (const_string "false"))
477 ;; Defines rounding mode of an FP operation.
479 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
480 (const_string "any"))
482 ;; Describe a user's asm statement.
483 (define_asm_attributes
484 [(set_attr "length" "128")
485 (set_attr "type" "multi")])
487 ;; All x87 floating point modes
488 (define_mode_macro X87MODEF [SF DF XF])
490 ;; x87 SFmode and DFMode floating point modes
491 (define_mode_macro X87MODEF12 [SF DF])
493 ;; All integer modes handled by x87 fisttp operator.
494 (define_mode_macro X87MODEI [HI SI DI])
496 ;; All integer modes handled by integer x87 operators.
497 (define_mode_macro X87MODEI12 [HI SI])
499 ;; All SSE floating point modes
500 (define_mode_macro SSEMODEF [SF DF])
502 ;; All integer modes handled by SSE cvtts?2si* operators.
503 (define_mode_macro SSEMODEI24 [SI DI])
505 ;; SSE asm suffix for floating point modes
506 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
508 ;; SSE vector mode corresponding to a scalar mode
509 (define_mode_attr ssevecmode
510 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
512 ;; Scheduling descriptions
514 (include "pentium.md")
517 (include "athlon.md")
521 ;; Operand and operator predicates and constraints
523 (include "predicates.md")
524 (include "constraints.md")
527 ;; Compare instructions.
529 ;; All compare insns have expanders that save the operands away without
530 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
531 ;; after the cmp) will actually emit the cmpM.
533 (define_expand "cmpti"
534 [(set (reg:CC FLAGS_REG)
535 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
536 (match_operand:TI 1 "x86_64_general_operand" "")))]
539 if (MEM_P (operands[0]) && MEM_P (operands[1]))
540 operands[0] = force_reg (TImode, operands[0]);
541 ix86_compare_op0 = operands[0];
542 ix86_compare_op1 = operands[1];
546 (define_expand "cmpdi"
547 [(set (reg:CC FLAGS_REG)
548 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
549 (match_operand:DI 1 "x86_64_general_operand" "")))]
552 if (MEM_P (operands[0]) && MEM_P (operands[1]))
553 operands[0] = force_reg (DImode, operands[0]);
554 ix86_compare_op0 = operands[0];
555 ix86_compare_op1 = operands[1];
559 (define_expand "cmpsi"
560 [(set (reg:CC FLAGS_REG)
561 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
562 (match_operand:SI 1 "general_operand" "")))]
565 if (MEM_P (operands[0]) && MEM_P (operands[1]))
566 operands[0] = force_reg (SImode, operands[0]);
567 ix86_compare_op0 = operands[0];
568 ix86_compare_op1 = operands[1];
572 (define_expand "cmphi"
573 [(set (reg:CC FLAGS_REG)
574 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
575 (match_operand:HI 1 "general_operand" "")))]
578 if (MEM_P (operands[0]) && MEM_P (operands[1]))
579 operands[0] = force_reg (HImode, operands[0]);
580 ix86_compare_op0 = operands[0];
581 ix86_compare_op1 = operands[1];
585 (define_expand "cmpqi"
586 [(set (reg:CC FLAGS_REG)
587 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
588 (match_operand:QI 1 "general_operand" "")))]
591 if (MEM_P (operands[0]) && MEM_P (operands[1]))
592 operands[0] = force_reg (QImode, operands[0]);
593 ix86_compare_op0 = operands[0];
594 ix86_compare_op1 = operands[1];
598 (define_insn "cmpdi_ccno_1_rex64"
599 [(set (reg FLAGS_REG)
600 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
601 (match_operand:DI 1 "const0_operand" "n,n")))]
602 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
605 cmp{q}\t{%1, %0|%0, %1}"
606 [(set_attr "type" "test,icmp")
607 (set_attr "length_immediate" "0,1")
608 (set_attr "mode" "DI")])
610 (define_insn "*cmpdi_minus_1_rex64"
611 [(set (reg FLAGS_REG)
612 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
613 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
615 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
616 "cmp{q}\t{%1, %0|%0, %1}"
617 [(set_attr "type" "icmp")
618 (set_attr "mode" "DI")])
620 (define_expand "cmpdi_1_rex64"
621 [(set (reg:CC FLAGS_REG)
622 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
623 (match_operand:DI 1 "general_operand" "")))]
627 (define_insn "cmpdi_1_insn_rex64"
628 [(set (reg FLAGS_REG)
629 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
630 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
631 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
632 "cmp{q}\t{%1, %0|%0, %1}"
633 [(set_attr "type" "icmp")
634 (set_attr "mode" "DI")])
637 (define_insn "*cmpsi_ccno_1"
638 [(set (reg FLAGS_REG)
639 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
640 (match_operand:SI 1 "const0_operand" "n,n")))]
641 "ix86_match_ccmode (insn, CCNOmode)"
644 cmp{l}\t{%1, %0|%0, %1}"
645 [(set_attr "type" "test,icmp")
646 (set_attr "length_immediate" "0,1")
647 (set_attr "mode" "SI")])
649 (define_insn "*cmpsi_minus_1"
650 [(set (reg FLAGS_REG)
651 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
652 (match_operand:SI 1 "general_operand" "ri,mr"))
654 "ix86_match_ccmode (insn, CCGOCmode)"
655 "cmp{l}\t{%1, %0|%0, %1}"
656 [(set_attr "type" "icmp")
657 (set_attr "mode" "SI")])
659 (define_expand "cmpsi_1"
660 [(set (reg:CC FLAGS_REG)
661 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
662 (match_operand:SI 1 "general_operand" "ri,mr")))]
666 (define_insn "*cmpsi_1_insn"
667 [(set (reg FLAGS_REG)
668 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
669 (match_operand:SI 1 "general_operand" "ri,mr")))]
670 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
671 && ix86_match_ccmode (insn, CCmode)"
672 "cmp{l}\t{%1, %0|%0, %1}"
673 [(set_attr "type" "icmp")
674 (set_attr "mode" "SI")])
676 (define_insn "*cmphi_ccno_1"
677 [(set (reg FLAGS_REG)
678 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
679 (match_operand:HI 1 "const0_operand" "n,n")))]
680 "ix86_match_ccmode (insn, CCNOmode)"
683 cmp{w}\t{%1, %0|%0, %1}"
684 [(set_attr "type" "test,icmp")
685 (set_attr "length_immediate" "0,1")
686 (set_attr "mode" "HI")])
688 (define_insn "*cmphi_minus_1"
689 [(set (reg FLAGS_REG)
690 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
691 (match_operand:HI 1 "general_operand" "ri,mr"))
693 "ix86_match_ccmode (insn, CCGOCmode)"
694 "cmp{w}\t{%1, %0|%0, %1}"
695 [(set_attr "type" "icmp")
696 (set_attr "mode" "HI")])
698 (define_insn "*cmphi_1"
699 [(set (reg FLAGS_REG)
700 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
701 (match_operand:HI 1 "general_operand" "ri,mr")))]
702 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
703 && ix86_match_ccmode (insn, CCmode)"
704 "cmp{w}\t{%1, %0|%0, %1}"
705 [(set_attr "type" "icmp")
706 (set_attr "mode" "HI")])
708 (define_insn "*cmpqi_ccno_1"
709 [(set (reg FLAGS_REG)
710 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
711 (match_operand:QI 1 "const0_operand" "n,n")))]
712 "ix86_match_ccmode (insn, CCNOmode)"
715 cmp{b}\t{$0, %0|%0, 0}"
716 [(set_attr "type" "test,icmp")
717 (set_attr "length_immediate" "0,1")
718 (set_attr "mode" "QI")])
720 (define_insn "*cmpqi_1"
721 [(set (reg FLAGS_REG)
722 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
723 (match_operand:QI 1 "general_operand" "qi,mq")))]
724 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
725 && ix86_match_ccmode (insn, CCmode)"
726 "cmp{b}\t{%1, %0|%0, %1}"
727 [(set_attr "type" "icmp")
728 (set_attr "mode" "QI")])
730 (define_insn "*cmpqi_minus_1"
731 [(set (reg FLAGS_REG)
732 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
733 (match_operand:QI 1 "general_operand" "qi,mq"))
735 "ix86_match_ccmode (insn, CCGOCmode)"
736 "cmp{b}\t{%1, %0|%0, %1}"
737 [(set_attr "type" "icmp")
738 (set_attr "mode" "QI")])
740 (define_insn "*cmpqi_ext_1"
741 [(set (reg FLAGS_REG)
743 (match_operand:QI 0 "general_operand" "Qm")
746 (match_operand 1 "ext_register_operand" "Q")
749 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
750 "cmp{b}\t{%h1, %0|%0, %h1}"
751 [(set_attr "type" "icmp")
752 (set_attr "mode" "QI")])
754 (define_insn "*cmpqi_ext_1_rex64"
755 [(set (reg FLAGS_REG)
757 (match_operand:QI 0 "register_operand" "Q")
760 (match_operand 1 "ext_register_operand" "Q")
763 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
764 "cmp{b}\t{%h1, %0|%0, %h1}"
765 [(set_attr "type" "icmp")
766 (set_attr "mode" "QI")])
768 (define_insn "*cmpqi_ext_2"
769 [(set (reg FLAGS_REG)
773 (match_operand 0 "ext_register_operand" "Q")
776 (match_operand:QI 1 "const0_operand" "n")))]
777 "ix86_match_ccmode (insn, CCNOmode)"
779 [(set_attr "type" "test")
780 (set_attr "length_immediate" "0")
781 (set_attr "mode" "QI")])
783 (define_expand "cmpqi_ext_3"
784 [(set (reg:CC FLAGS_REG)
788 (match_operand 0 "ext_register_operand" "")
791 (match_operand:QI 1 "general_operand" "")))]
795 (define_insn "cmpqi_ext_3_insn"
796 [(set (reg FLAGS_REG)
800 (match_operand 0 "ext_register_operand" "Q")
803 (match_operand:QI 1 "general_operand" "Qmn")))]
804 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
805 "cmp{b}\t{%1, %h0|%h0, %1}"
806 [(set_attr "type" "icmp")
807 (set_attr "mode" "QI")])
809 (define_insn "cmpqi_ext_3_insn_rex64"
810 [(set (reg FLAGS_REG)
814 (match_operand 0 "ext_register_operand" "Q")
817 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
818 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
819 "cmp{b}\t{%1, %h0|%h0, %1}"
820 [(set_attr "type" "icmp")
821 (set_attr "mode" "QI")])
823 (define_insn "*cmpqi_ext_4"
824 [(set (reg FLAGS_REG)
828 (match_operand 0 "ext_register_operand" "Q")
833 (match_operand 1 "ext_register_operand" "Q")
836 "ix86_match_ccmode (insn, CCmode)"
837 "cmp{b}\t{%h1, %h0|%h0, %h1}"
838 [(set_attr "type" "icmp")
839 (set_attr "mode" "QI")])
841 ;; These implement float point compares.
842 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
843 ;; which would allow mix and match FP modes on the compares. Which is what
844 ;; the old patterns did, but with many more of them.
846 (define_expand "cmpxf"
847 [(set (reg:CC FLAGS_REG)
848 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
849 (match_operand:XF 1 "nonmemory_operand" "")))]
852 ix86_compare_op0 = operands[0];
853 ix86_compare_op1 = operands[1];
857 (define_expand "cmp<mode>"
858 [(set (reg:CC FLAGS_REG)
859 (compare:CC (match_operand:SSEMODEF 0 "cmp_fp_expander_operand" "")
860 (match_operand:SSEMODEF 1 "cmp_fp_expander_operand" "")))]
861 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
863 ix86_compare_op0 = operands[0];
864 ix86_compare_op1 = operands[1];
868 ;; FP compares, step 1:
869 ;; Set the FP condition codes.
871 ;; CCFPmode compare with exceptions
872 ;; CCFPUmode compare with no exceptions
874 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
875 ;; used to manage the reg stack popping would not be preserved.
877 (define_insn "*cmpfp_0"
878 [(set (match_operand:HI 0 "register_operand" "=a")
881 (match_operand 1 "register_operand" "f")
882 (match_operand 2 "const0_operand" "X"))]
884 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
885 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
886 "* return output_fp_compare (insn, operands, 0, 0);"
887 [(set_attr "type" "multi")
888 (set_attr "unit" "i387")
890 (cond [(match_operand:SF 1 "" "")
892 (match_operand:DF 1 "" "")
895 (const_string "XF")))])
897 (define_insn "*cmpfp_xf"
898 [(set (match_operand:HI 0 "register_operand" "=a")
901 (match_operand:XF 1 "register_operand" "f")
902 (match_operand:XF 2 "register_operand" "f"))]
905 "* return output_fp_compare (insn, operands, 0, 0);"
906 [(set_attr "type" "multi")
907 (set_attr "unit" "i387")
908 (set_attr "mode" "XF")])
910 (define_insn "*cmpfp_<mode>"
911 [(set (match_operand:HI 0 "register_operand" "=a")
914 (match_operand:X87MODEF12 1 "register_operand" "f")
915 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm"))]
918 "* return output_fp_compare (insn, operands, 0, 0);"
919 [(set_attr "type" "multi")
920 (set_attr "unit" "i387")
921 (set_attr "mode" "<MODE>")])
923 (define_insn "*cmpfp_u"
924 [(set (match_operand:HI 0 "register_operand" "=a")
927 (match_operand 1 "register_operand" "f")
928 (match_operand 2 "register_operand" "f"))]
930 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
931 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
932 "* return output_fp_compare (insn, operands, 0, 1);"
933 [(set_attr "type" "multi")
934 (set_attr "unit" "i387")
936 (cond [(match_operand:SF 1 "" "")
938 (match_operand:DF 1 "" "")
941 (const_string "XF")))])
943 (define_insn "*cmpfp_<mode>"
944 [(set (match_operand:HI 0 "register_operand" "=a")
947 (match_operand 1 "register_operand" "f")
948 (match_operator 3 "float_operator"
949 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
951 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
952 && TARGET_USE_<MODE>MODE_FIOP
953 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
954 "* return output_fp_compare (insn, operands, 0, 0);"
955 [(set_attr "type" "multi")
956 (set_attr "unit" "i387")
957 (set_attr "fp_int_src" "true")
958 (set_attr "mode" "<MODE>")])
960 ;; FP compares, step 2
961 ;; Move the fpsw to ax.
963 (define_insn "x86_fnstsw_1"
964 [(set (match_operand:HI 0 "register_operand" "=a")
965 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
968 [(set_attr "length" "2")
969 (set_attr "mode" "SI")
970 (set_attr "unit" "i387")])
972 ;; FP compares, step 3
973 ;; Get ax into flags, general case.
975 (define_insn "x86_sahf_1"
976 [(set (reg:CC FLAGS_REG)
977 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
981 #ifdef HAVE_AS_IX86_SAHF
984 return ".byte\t0x9e";
987 [(set_attr "length" "1")
988 (set_attr "athlon_decode" "vector")
989 (set_attr "amdfam10_decode" "direct")
990 (set_attr "mode" "SI")])
992 ;; Pentium Pro can do steps 1 through 3 in one go.
993 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
994 (define_insn "*cmpfp_i_mixed"
995 [(set (reg:CCFP FLAGS_REG)
996 (compare:CCFP (match_operand 0 "register_operand" "f,x")
997 (match_operand 1 "nonimmediate_operand" "f,xm")))]
999 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1000 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1001 "* return output_fp_compare (insn, operands, 1, 0);"
1002 [(set_attr "type" "fcmp,ssecomi")
1004 (if_then_else (match_operand:SF 1 "" "")
1006 (const_string "DF")))
1007 (set_attr "athlon_decode" "vector")
1008 (set_attr "amdfam10_decode" "direct")])
1010 (define_insn "*cmpfp_i_sse"
1011 [(set (reg:CCFP FLAGS_REG)
1012 (compare:CCFP (match_operand 0 "register_operand" "x")
1013 (match_operand 1 "nonimmediate_operand" "xm")))]
1015 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1016 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1017 "* return output_fp_compare (insn, operands, 1, 0);"
1018 [(set_attr "type" "ssecomi")
1020 (if_then_else (match_operand:SF 1 "" "")
1022 (const_string "DF")))
1023 (set_attr "athlon_decode" "vector")
1024 (set_attr "amdfam10_decode" "direct")])
1026 (define_insn "*cmpfp_i_i387"
1027 [(set (reg:CCFP FLAGS_REG)
1028 (compare:CCFP (match_operand 0 "register_operand" "f")
1029 (match_operand 1 "register_operand" "f")))]
1030 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1032 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1033 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034 "* return output_fp_compare (insn, operands, 1, 0);"
1035 [(set_attr "type" "fcmp")
1037 (cond [(match_operand:SF 1 "" "")
1039 (match_operand:DF 1 "" "")
1042 (const_string "XF")))
1043 (set_attr "athlon_decode" "vector")
1044 (set_attr "amdfam10_decode" "direct")])
1046 (define_insn "*cmpfp_iu_mixed"
1047 [(set (reg:CCFPU FLAGS_REG)
1048 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1049 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1050 "TARGET_MIX_SSE_I387
1051 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1052 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1053 "* return output_fp_compare (insn, operands, 1, 1);"
1054 [(set_attr "type" "fcmp,ssecomi")
1056 (if_then_else (match_operand:SF 1 "" "")
1058 (const_string "DF")))
1059 (set_attr "athlon_decode" "vector")
1060 (set_attr "amdfam10_decode" "direct")])
1062 (define_insn "*cmpfp_iu_sse"
1063 [(set (reg:CCFPU FLAGS_REG)
1064 (compare:CCFPU (match_operand 0 "register_operand" "x")
1065 (match_operand 1 "nonimmediate_operand" "xm")))]
1067 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1068 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1069 "* return output_fp_compare (insn, operands, 1, 1);"
1070 [(set_attr "type" "ssecomi")
1072 (if_then_else (match_operand:SF 1 "" "")
1074 (const_string "DF")))
1075 (set_attr "athlon_decode" "vector")
1076 (set_attr "amdfam10_decode" "direct")])
1078 (define_insn "*cmpfp_iu_387"
1079 [(set (reg:CCFPU FLAGS_REG)
1080 (compare:CCFPU (match_operand 0 "register_operand" "f")
1081 (match_operand 1 "register_operand" "f")))]
1082 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1084 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1085 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1086 "* return output_fp_compare (insn, operands, 1, 1);"
1087 [(set_attr "type" "fcmp")
1089 (cond [(match_operand:SF 1 "" "")
1091 (match_operand:DF 1 "" "")
1094 (const_string "XF")))
1095 (set_attr "athlon_decode" "vector")
1096 (set_attr "amdfam10_decode" "direct")])
1098 ;; Move instructions.
1100 ;; General case of fullword move.
1102 (define_expand "movsi"
1103 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1104 (match_operand:SI 1 "general_operand" ""))]
1106 "ix86_expand_move (SImode, operands); DONE;")
1108 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1111 ;; %%% We don't use a post-inc memory reference because x86 is not a
1112 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1113 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1114 ;; targets without our curiosities, and it is just as easy to represent
1115 ;; this differently.
1117 (define_insn "*pushsi2"
1118 [(set (match_operand:SI 0 "push_operand" "=<")
1119 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1122 [(set_attr "type" "push")
1123 (set_attr "mode" "SI")])
1125 ;; For 64BIT abi we always round up to 8 bytes.
1126 (define_insn "*pushsi2_rex64"
1127 [(set (match_operand:SI 0 "push_operand" "=X")
1128 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1131 [(set_attr "type" "push")
1132 (set_attr "mode" "SI")])
1134 (define_insn "*pushsi2_prologue"
1135 [(set (match_operand:SI 0 "push_operand" "=<")
1136 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1137 (clobber (mem:BLK (scratch)))]
1140 [(set_attr "type" "push")
1141 (set_attr "mode" "SI")])
1143 (define_insn "*popsi1_epilogue"
1144 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1145 (mem:SI (reg:SI SP_REG)))
1146 (set (reg:SI SP_REG)
1147 (plus:SI (reg:SI SP_REG) (const_int 4)))
1148 (clobber (mem:BLK (scratch)))]
1151 [(set_attr "type" "pop")
1152 (set_attr "mode" "SI")])
1154 (define_insn "popsi1"
1155 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1156 (mem:SI (reg:SI SP_REG)))
1157 (set (reg:SI SP_REG)
1158 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1161 [(set_attr "type" "pop")
1162 (set_attr "mode" "SI")])
1164 (define_insn "*movsi_xor"
1165 [(set (match_operand:SI 0 "register_operand" "=r")
1166 (match_operand:SI 1 "const0_operand" "i"))
1167 (clobber (reg:CC FLAGS_REG))]
1168 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1170 [(set_attr "type" "alu1")
1171 (set_attr "mode" "SI")
1172 (set_attr "length_immediate" "0")])
1174 (define_insn "*movsi_or"
1175 [(set (match_operand:SI 0 "register_operand" "=r")
1176 (match_operand:SI 1 "immediate_operand" "i"))
1177 (clobber (reg:CC FLAGS_REG))]
1179 && operands[1] == constm1_rtx
1180 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1182 operands[1] = constm1_rtx;
1183 return "or{l}\t{%1, %0|%0, %1}";
1185 [(set_attr "type" "alu1")
1186 (set_attr "mode" "SI")
1187 (set_attr "length_immediate" "1")])
1189 (define_insn "*movsi_1"
1190 [(set (match_operand:SI 0 "nonimmediate_operand"
1191 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1192 (match_operand:SI 1 "general_operand"
1193 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1194 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1196 switch (get_attr_type (insn))
1199 if (get_attr_mode (insn) == MODE_TI)
1200 return "pxor\t%0, %0";
1201 return "xorps\t%0, %0";
1204 switch (get_attr_mode (insn))
1207 return "movdqa\t{%1, %0|%0, %1}";
1209 return "movaps\t{%1, %0|%0, %1}";
1211 return "movd\t{%1, %0|%0, %1}";
1213 return "movss\t{%1, %0|%0, %1}";
1219 return "pxor\t%0, %0";
1222 if (get_attr_mode (insn) == MODE_DI)
1223 return "movq\t{%1, %0|%0, %1}";
1224 return "movd\t{%1, %0|%0, %1}";
1227 return "lea{l}\t{%1, %0|%0, %1}";
1230 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1231 return "mov{l}\t{%1, %0|%0, %1}";
1235 (cond [(eq_attr "alternative" "2")
1236 (const_string "mmxadd")
1237 (eq_attr "alternative" "3,4,5")
1238 (const_string "mmxmov")
1239 (eq_attr "alternative" "6")
1240 (const_string "sselog1")
1241 (eq_attr "alternative" "7,8,9,10,11")
1242 (const_string "ssemov")
1243 (match_operand:DI 1 "pic_32bit_operand" "")
1244 (const_string "lea")
1246 (const_string "imov")))
1248 (cond [(eq_attr "alternative" "2,3")
1250 (eq_attr "alternative" "6,7")
1252 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1253 (const_string "V4SF")
1254 (const_string "TI"))
1255 (and (eq_attr "alternative" "8,9,10,11")
1256 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1259 (const_string "SI")))])
1261 ;; Stores and loads of ax to arbitrary constant address.
1262 ;; We fake an second form of instruction to force reload to load address
1263 ;; into register when rax is not available
1264 (define_insn "*movabssi_1_rex64"
1265 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1266 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1267 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1269 movabs{l}\t{%1, %P0|%P0, %1}
1270 mov{l}\t{%1, %a0|%a0, %1}"
1271 [(set_attr "type" "imov")
1272 (set_attr "modrm" "0,*")
1273 (set_attr "length_address" "8,0")
1274 (set_attr "length_immediate" "0,*")
1275 (set_attr "memory" "store")
1276 (set_attr "mode" "SI")])
1278 (define_insn "*movabssi_2_rex64"
1279 [(set (match_operand:SI 0 "register_operand" "=a,r")
1280 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1281 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1283 movabs{l}\t{%P1, %0|%0, %P1}
1284 mov{l}\t{%a1, %0|%0, %a1}"
1285 [(set_attr "type" "imov")
1286 (set_attr "modrm" "0,*")
1287 (set_attr "length_address" "8,0")
1288 (set_attr "length_immediate" "0")
1289 (set_attr "memory" "load")
1290 (set_attr "mode" "SI")])
1292 (define_insn "*swapsi"
1293 [(set (match_operand:SI 0 "register_operand" "+r")
1294 (match_operand:SI 1 "register_operand" "+r"))
1299 [(set_attr "type" "imov")
1300 (set_attr "mode" "SI")
1301 (set_attr "pent_pair" "np")
1302 (set_attr "athlon_decode" "vector")
1303 (set_attr "amdfam10_decode" "double")])
1305 (define_expand "movhi"
1306 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1307 (match_operand:HI 1 "general_operand" ""))]
1309 "ix86_expand_move (HImode, operands); DONE;")
1311 (define_insn "*pushhi2"
1312 [(set (match_operand:HI 0 "push_operand" "=X")
1313 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1316 [(set_attr "type" "push")
1317 (set_attr "mode" "SI")])
1319 ;; For 64BIT abi we always round up to 8 bytes.
1320 (define_insn "*pushhi2_rex64"
1321 [(set (match_operand:HI 0 "push_operand" "=X")
1322 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1325 [(set_attr "type" "push")
1326 (set_attr "mode" "DI")])
1328 (define_insn "*movhi_1"
1329 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1330 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1331 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1333 switch (get_attr_type (insn))
1336 /* movzwl is faster than movw on p2 due to partial word stalls,
1337 though not as fast as an aligned movl. */
1338 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1340 if (get_attr_mode (insn) == MODE_SI)
1341 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1343 return "mov{w}\t{%1, %0|%0, %1}";
1347 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1348 (const_string "imov")
1349 (and (eq_attr "alternative" "0")
1350 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1352 (eq (symbol_ref "TARGET_HIMODE_MATH")
1354 (const_string "imov")
1355 (and (eq_attr "alternative" "1,2")
1356 (match_operand:HI 1 "aligned_operand" ""))
1357 (const_string "imov")
1358 (and (ne (symbol_ref "TARGET_MOVX")
1360 (eq_attr "alternative" "0,2"))
1361 (const_string "imovx")
1363 (const_string "imov")))
1365 (cond [(eq_attr "type" "imovx")
1367 (and (eq_attr "alternative" "1,2")
1368 (match_operand:HI 1 "aligned_operand" ""))
1370 (and (eq_attr "alternative" "0")
1371 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1373 (eq (symbol_ref "TARGET_HIMODE_MATH")
1377 (const_string "HI")))])
1379 ;; Stores and loads of ax to arbitrary constant address.
1380 ;; We fake an second form of instruction to force reload to load address
1381 ;; into register when rax is not available
1382 (define_insn "*movabshi_1_rex64"
1383 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1384 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1385 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1387 movabs{w}\t{%1, %P0|%P0, %1}
1388 mov{w}\t{%1, %a0|%a0, %1}"
1389 [(set_attr "type" "imov")
1390 (set_attr "modrm" "0,*")
1391 (set_attr "length_address" "8,0")
1392 (set_attr "length_immediate" "0,*")
1393 (set_attr "memory" "store")
1394 (set_attr "mode" "HI")])
1396 (define_insn "*movabshi_2_rex64"
1397 [(set (match_operand:HI 0 "register_operand" "=a,r")
1398 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1399 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1401 movabs{w}\t{%P1, %0|%0, %P1}
1402 mov{w}\t{%a1, %0|%0, %a1}"
1403 [(set_attr "type" "imov")
1404 (set_attr "modrm" "0,*")
1405 (set_attr "length_address" "8,0")
1406 (set_attr "length_immediate" "0")
1407 (set_attr "memory" "load")
1408 (set_attr "mode" "HI")])
1410 (define_insn "*swaphi_1"
1411 [(set (match_operand:HI 0 "register_operand" "+r")
1412 (match_operand:HI 1 "register_operand" "+r"))
1415 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1417 [(set_attr "type" "imov")
1418 (set_attr "mode" "SI")
1419 (set_attr "pent_pair" "np")
1420 (set_attr "athlon_decode" "vector")
1421 (set_attr "amdfam10_decode" "double")])
1423 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1424 (define_insn "*swaphi_2"
1425 [(set (match_operand:HI 0 "register_operand" "+r")
1426 (match_operand:HI 1 "register_operand" "+r"))
1429 "TARGET_PARTIAL_REG_STALL"
1431 [(set_attr "type" "imov")
1432 (set_attr "mode" "HI")
1433 (set_attr "pent_pair" "np")
1434 (set_attr "athlon_decode" "vector")])
1436 (define_expand "movstricthi"
1437 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1438 (match_operand:HI 1 "general_operand" ""))]
1439 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1441 /* Don't generate memory->memory moves, go through a register */
1442 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1443 operands[1] = force_reg (HImode, operands[1]);
1446 (define_insn "*movstricthi_1"
1447 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1448 (match_operand:HI 1 "general_operand" "rn,m"))]
1449 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1450 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1451 "mov{w}\t{%1, %0|%0, %1}"
1452 [(set_attr "type" "imov")
1453 (set_attr "mode" "HI")])
1455 (define_insn "*movstricthi_xor"
1456 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1457 (match_operand:HI 1 "const0_operand" "i"))
1458 (clobber (reg:CC FLAGS_REG))]
1460 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1462 [(set_attr "type" "alu1")
1463 (set_attr "mode" "HI")
1464 (set_attr "length_immediate" "0")])
1466 (define_expand "movqi"
1467 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1468 (match_operand:QI 1 "general_operand" ""))]
1470 "ix86_expand_move (QImode, operands); DONE;")
1472 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1473 ;; "push a byte". But actually we use pushl, which has the effect
1474 ;; of rounding the amount pushed up to a word.
1476 (define_insn "*pushqi2"
1477 [(set (match_operand:QI 0 "push_operand" "=X")
1478 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1481 [(set_attr "type" "push")
1482 (set_attr "mode" "SI")])
1484 ;; For 64BIT abi we always round up to 8 bytes.
1485 (define_insn "*pushqi2_rex64"
1486 [(set (match_operand:QI 0 "push_operand" "=X")
1487 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1490 [(set_attr "type" "push")
1491 (set_attr "mode" "DI")])
1493 ;; Situation is quite tricky about when to choose full sized (SImode) move
1494 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1495 ;; partial register dependency machines (such as AMD Athlon), where QImode
1496 ;; moves issue extra dependency and for partial register stalls machines
1497 ;; that don't use QImode patterns (and QImode move cause stall on the next
1500 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1501 ;; register stall machines with, where we use QImode instructions, since
1502 ;; partial register stall can be caused there. Then we use movzx.
1503 (define_insn "*movqi_1"
1504 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1505 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1506 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1508 switch (get_attr_type (insn))
1511 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1512 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1514 if (get_attr_mode (insn) == MODE_SI)
1515 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1517 return "mov{b}\t{%1, %0|%0, %1}";
1521 (cond [(and (eq_attr "alternative" "5")
1522 (not (match_operand:QI 1 "aligned_operand" "")))
1523 (const_string "imovx")
1524 (ne (symbol_ref "optimize_size") (const_int 0))
1525 (const_string "imov")
1526 (and (eq_attr "alternative" "3")
1527 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1529 (eq (symbol_ref "TARGET_QIMODE_MATH")
1531 (const_string "imov")
1532 (eq_attr "alternative" "3,5")
1533 (const_string "imovx")
1534 (and (ne (symbol_ref "TARGET_MOVX")
1536 (eq_attr "alternative" "2"))
1537 (const_string "imovx")
1539 (const_string "imov")))
1541 (cond [(eq_attr "alternative" "3,4,5")
1543 (eq_attr "alternative" "6")
1545 (eq_attr "type" "imovx")
1547 (and (eq_attr "type" "imov")
1548 (and (eq_attr "alternative" "0,1")
1549 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1551 (and (eq (symbol_ref "optimize_size")
1553 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1556 ;; Avoid partial register stalls when not using QImode arithmetic
1557 (and (eq_attr "type" "imov")
1558 (and (eq_attr "alternative" "0,1")
1559 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1561 (eq (symbol_ref "TARGET_QIMODE_MATH")
1565 (const_string "QI")))])
1567 (define_expand "reload_outqi"
1568 [(parallel [(match_operand:QI 0 "" "=m")
1569 (match_operand:QI 1 "register_operand" "r")
1570 (match_operand:QI 2 "register_operand" "=&q")])]
1574 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1576 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1577 if (! q_regs_operand (op1, QImode))
1579 emit_insn (gen_movqi (op2, op1));
1582 emit_insn (gen_movqi (op0, op1));
1586 (define_insn "*swapqi_1"
1587 [(set (match_operand:QI 0 "register_operand" "+r")
1588 (match_operand:QI 1 "register_operand" "+r"))
1591 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1593 [(set_attr "type" "imov")
1594 (set_attr "mode" "SI")
1595 (set_attr "pent_pair" "np")
1596 (set_attr "athlon_decode" "vector")
1597 (set_attr "amdfam10_decode" "vector")])
1599 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1600 (define_insn "*swapqi_2"
1601 [(set (match_operand:QI 0 "register_operand" "+q")
1602 (match_operand:QI 1 "register_operand" "+q"))
1605 "TARGET_PARTIAL_REG_STALL"
1607 [(set_attr "type" "imov")
1608 (set_attr "mode" "QI")
1609 (set_attr "pent_pair" "np")
1610 (set_attr "athlon_decode" "vector")])
1612 (define_expand "movstrictqi"
1613 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1614 (match_operand:QI 1 "general_operand" ""))]
1615 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1617 /* Don't generate memory->memory moves, go through a register. */
1618 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1619 operands[1] = force_reg (QImode, operands[1]);
1622 (define_insn "*movstrictqi_1"
1623 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1624 (match_operand:QI 1 "general_operand" "*qn,m"))]
1625 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1626 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1627 "mov{b}\t{%1, %0|%0, %1}"
1628 [(set_attr "type" "imov")
1629 (set_attr "mode" "QI")])
1631 (define_insn "*movstrictqi_xor"
1632 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1633 (match_operand:QI 1 "const0_operand" "i"))
1634 (clobber (reg:CC FLAGS_REG))]
1635 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1637 [(set_attr "type" "alu1")
1638 (set_attr "mode" "QI")
1639 (set_attr "length_immediate" "0")])
1641 (define_insn "*movsi_extv_1"
1642 [(set (match_operand:SI 0 "register_operand" "=R")
1643 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1647 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1648 [(set_attr "type" "imovx")
1649 (set_attr "mode" "SI")])
1651 (define_insn "*movhi_extv_1"
1652 [(set (match_operand:HI 0 "register_operand" "=R")
1653 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1657 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1658 [(set_attr "type" "imovx")
1659 (set_attr "mode" "SI")])
1661 (define_insn "*movqi_extv_1"
1662 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1663 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1668 switch (get_attr_type (insn))
1671 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1673 return "mov{b}\t{%h1, %0|%0, %h1}";
1677 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1678 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1679 (ne (symbol_ref "TARGET_MOVX")
1681 (const_string "imovx")
1682 (const_string "imov")))
1684 (if_then_else (eq_attr "type" "imovx")
1686 (const_string "QI")))])
1688 (define_insn "*movqi_extv_1_rex64"
1689 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1690 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1695 switch (get_attr_type (insn))
1698 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1700 return "mov{b}\t{%h1, %0|%0, %h1}";
1704 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1705 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1706 (ne (symbol_ref "TARGET_MOVX")
1708 (const_string "imovx")
1709 (const_string "imov")))
1711 (if_then_else (eq_attr "type" "imovx")
1713 (const_string "QI")))])
1715 ;; Stores and loads of ax to arbitrary constant address.
1716 ;; We fake an second form of instruction to force reload to load address
1717 ;; into register when rax is not available
1718 (define_insn "*movabsqi_1_rex64"
1719 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1720 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1721 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1723 movabs{b}\t{%1, %P0|%P0, %1}
1724 mov{b}\t{%1, %a0|%a0, %1}"
1725 [(set_attr "type" "imov")
1726 (set_attr "modrm" "0,*")
1727 (set_attr "length_address" "8,0")
1728 (set_attr "length_immediate" "0,*")
1729 (set_attr "memory" "store")
1730 (set_attr "mode" "QI")])
1732 (define_insn "*movabsqi_2_rex64"
1733 [(set (match_operand:QI 0 "register_operand" "=a,r")
1734 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1735 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1737 movabs{b}\t{%P1, %0|%0, %P1}
1738 mov{b}\t{%a1, %0|%0, %a1}"
1739 [(set_attr "type" "imov")
1740 (set_attr "modrm" "0,*")
1741 (set_attr "length_address" "8,0")
1742 (set_attr "length_immediate" "0")
1743 (set_attr "memory" "load")
1744 (set_attr "mode" "QI")])
1746 (define_insn "*movdi_extzv_1"
1747 [(set (match_operand:DI 0 "register_operand" "=R")
1748 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1752 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1753 [(set_attr "type" "imovx")
1754 (set_attr "mode" "DI")])
1756 (define_insn "*movsi_extzv_1"
1757 [(set (match_operand:SI 0 "register_operand" "=R")
1758 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1762 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1763 [(set_attr "type" "imovx")
1764 (set_attr "mode" "SI")])
1766 (define_insn "*movqi_extzv_2"
1767 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1768 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1773 switch (get_attr_type (insn))
1776 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1778 return "mov{b}\t{%h1, %0|%0, %h1}";
1782 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1783 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1784 (ne (symbol_ref "TARGET_MOVX")
1786 (const_string "imovx")
1787 (const_string "imov")))
1789 (if_then_else (eq_attr "type" "imovx")
1791 (const_string "QI")))])
1793 (define_insn "*movqi_extzv_2_rex64"
1794 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1795 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1800 switch (get_attr_type (insn))
1803 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1805 return "mov{b}\t{%h1, %0|%0, %h1}";
1809 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1810 (ne (symbol_ref "TARGET_MOVX")
1812 (const_string "imovx")
1813 (const_string "imov")))
1815 (if_then_else (eq_attr "type" "imovx")
1817 (const_string "QI")))])
1819 (define_insn "movsi_insv_1"
1820 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1823 (match_operand:SI 1 "general_operand" "Qmn"))]
1825 "mov{b}\t{%b1, %h0|%h0, %b1}"
1826 [(set_attr "type" "imov")
1827 (set_attr "mode" "QI")])
1829 (define_insn "*movsi_insv_1_rex64"
1830 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1833 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1835 "mov{b}\t{%b1, %h0|%h0, %b1}"
1836 [(set_attr "type" "imov")
1837 (set_attr "mode" "QI")])
1839 (define_insn "movdi_insv_1_rex64"
1840 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1843 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1845 "mov{b}\t{%b1, %h0|%h0, %b1}"
1846 [(set_attr "type" "imov")
1847 (set_attr "mode" "QI")])
1849 (define_insn "*movqi_insv_2"
1850 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1853 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1856 "mov{b}\t{%h1, %h0|%h0, %h1}"
1857 [(set_attr "type" "imov")
1858 (set_attr "mode" "QI")])
1860 (define_expand "movdi"
1861 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1862 (match_operand:DI 1 "general_operand" ""))]
1864 "ix86_expand_move (DImode, operands); DONE;")
1866 (define_insn "*pushdi"
1867 [(set (match_operand:DI 0 "push_operand" "=<")
1868 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1872 (define_insn "*pushdi2_rex64"
1873 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1874 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1879 [(set_attr "type" "push,multi")
1880 (set_attr "mode" "DI")])
1882 ;; Convert impossible pushes of immediate to existing instructions.
1883 ;; First try to get scratch register and go through it. In case this
1884 ;; fails, push sign extended lower part first and then overwrite
1885 ;; upper part by 32bit move.
1887 [(match_scratch:DI 2 "r")
1888 (set (match_operand:DI 0 "push_operand" "")
1889 (match_operand:DI 1 "immediate_operand" ""))]
1890 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1891 && !x86_64_immediate_operand (operands[1], DImode)"
1892 [(set (match_dup 2) (match_dup 1))
1893 (set (match_dup 0) (match_dup 2))]
1896 ;; We need to define this as both peepholer and splitter for case
1897 ;; peephole2 pass is not run.
1898 ;; "&& 1" is needed to keep it from matching the previous pattern.
1900 [(set (match_operand:DI 0 "push_operand" "")
1901 (match_operand:DI 1 "immediate_operand" ""))]
1902 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1903 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1904 [(set (match_dup 0) (match_dup 1))
1905 (set (match_dup 2) (match_dup 3))]
1906 "split_di (operands + 1, 1, operands + 2, operands + 3);
1907 operands[1] = gen_lowpart (DImode, operands[2]);
1908 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1913 [(set (match_operand:DI 0 "push_operand" "")
1914 (match_operand:DI 1 "immediate_operand" ""))]
1915 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1916 ? flow2_completed : reload_completed)
1917 && !symbolic_operand (operands[1], DImode)
1918 && !x86_64_immediate_operand (operands[1], DImode)"
1919 [(set (match_dup 0) (match_dup 1))
1920 (set (match_dup 2) (match_dup 3))]
1921 "split_di (operands + 1, 1, operands + 2, operands + 3);
1922 operands[1] = gen_lowpart (DImode, operands[2]);
1923 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1927 (define_insn "*pushdi2_prologue_rex64"
1928 [(set (match_operand:DI 0 "push_operand" "=<")
1929 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1930 (clobber (mem:BLK (scratch)))]
1933 [(set_attr "type" "push")
1934 (set_attr "mode" "DI")])
1936 (define_insn "*popdi1_epilogue_rex64"
1937 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1938 (mem:DI (reg:DI SP_REG)))
1939 (set (reg:DI SP_REG)
1940 (plus:DI (reg:DI SP_REG) (const_int 8)))
1941 (clobber (mem:BLK (scratch)))]
1944 [(set_attr "type" "pop")
1945 (set_attr "mode" "DI")])
1947 (define_insn "popdi1"
1948 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1949 (mem:DI (reg:DI SP_REG)))
1950 (set (reg:DI SP_REG)
1951 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1954 [(set_attr "type" "pop")
1955 (set_attr "mode" "DI")])
1957 (define_insn "*movdi_xor_rex64"
1958 [(set (match_operand:DI 0 "register_operand" "=r")
1959 (match_operand:DI 1 "const0_operand" "i"))
1960 (clobber (reg:CC FLAGS_REG))]
1961 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1962 && reload_completed"
1964 [(set_attr "type" "alu1")
1965 (set_attr "mode" "SI")
1966 (set_attr "length_immediate" "0")])
1968 (define_insn "*movdi_or_rex64"
1969 [(set (match_operand:DI 0 "register_operand" "=r")
1970 (match_operand:DI 1 "const_int_operand" "i"))
1971 (clobber (reg:CC FLAGS_REG))]
1972 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
1974 && operands[1] == constm1_rtx"
1976 operands[1] = constm1_rtx;
1977 return "or{q}\t{%1, %0|%0, %1}";
1979 [(set_attr "type" "alu1")
1980 (set_attr "mode" "DI")
1981 (set_attr "length_immediate" "1")])
1983 (define_insn "*movdi_2"
1984 [(set (match_operand:DI 0 "nonimmediate_operand"
1985 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
1986 (match_operand:DI 1 "general_operand"
1987 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
1988 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1993 movq\t{%1, %0|%0, %1}
1994 movq\t{%1, %0|%0, %1}
1996 movq\t{%1, %0|%0, %1}
1997 movdqa\t{%1, %0|%0, %1}
1998 movq\t{%1, %0|%0, %1}
2000 movlps\t{%1, %0|%0, %1}
2001 movaps\t{%1, %0|%0, %1}
2002 movlps\t{%1, %0|%0, %1}"
2003 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2004 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2007 [(set (match_operand:DI 0 "push_operand" "")
2008 (match_operand:DI 1 "general_operand" ""))]
2009 "!TARGET_64BIT && reload_completed
2010 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2012 "ix86_split_long_move (operands); DONE;")
2014 ;; %%% This multiword shite has got to go.
2016 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2017 (match_operand:DI 1 "general_operand" ""))]
2018 "!TARGET_64BIT && reload_completed
2019 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2020 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2022 "ix86_split_long_move (operands); DONE;")
2024 (define_insn "*movdi_1_rex64"
2025 [(set (match_operand:DI 0 "nonimmediate_operand"
2026 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2027 (match_operand:DI 1 "general_operand"
2028 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2029 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2031 switch (get_attr_type (insn))
2034 if (SSE_REG_P (operands[0]))
2035 return "movq2dq\t{%1, %0|%0, %1}";
2037 return "movdq2q\t{%1, %0|%0, %1}";
2040 if (get_attr_mode (insn) == MODE_TI)
2041 return "movdqa\t{%1, %0|%0, %1}";
2045 /* Moves from and into integer register is done using movd
2046 opcode with REX prefix. */
2047 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2048 return "movd\t{%1, %0|%0, %1}";
2049 return "movq\t{%1, %0|%0, %1}";
2053 return "pxor\t%0, %0";
2059 return "lea{q}\t{%a1, %0|%0, %a1}";
2062 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2063 if (get_attr_mode (insn) == MODE_SI)
2064 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2065 else if (which_alternative == 2)
2066 return "movabs{q}\t{%1, %0|%0, %1}";
2068 return "mov{q}\t{%1, %0|%0, %1}";
2072 (cond [(eq_attr "alternative" "5")
2073 (const_string "mmxadd")
2074 (eq_attr "alternative" "6,7,8,9,10")
2075 (const_string "mmxmov")
2076 (eq_attr "alternative" "11")
2077 (const_string "sselog1")
2078 (eq_attr "alternative" "12,13,14,15,16")
2079 (const_string "ssemov")
2080 (eq_attr "alternative" "17,18")
2081 (const_string "ssecvt")
2082 (eq_attr "alternative" "4")
2083 (const_string "multi")
2084 (match_operand:DI 1 "pic_32bit_operand" "")
2085 (const_string "lea")
2087 (const_string "imov")))
2088 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2090 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2092 ;; Stores and loads of ax to arbitrary constant address.
2093 ;; We fake an second form of instruction to force reload to load address
2094 ;; into register when rax is not available
2095 (define_insn "*movabsdi_1_rex64"
2096 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2097 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2098 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2100 movabs{q}\t{%1, %P0|%P0, %1}
2101 mov{q}\t{%1, %a0|%a0, %1}"
2102 [(set_attr "type" "imov")
2103 (set_attr "modrm" "0,*")
2104 (set_attr "length_address" "8,0")
2105 (set_attr "length_immediate" "0,*")
2106 (set_attr "memory" "store")
2107 (set_attr "mode" "DI")])
2109 (define_insn "*movabsdi_2_rex64"
2110 [(set (match_operand:DI 0 "register_operand" "=a,r")
2111 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2112 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2114 movabs{q}\t{%P1, %0|%0, %P1}
2115 mov{q}\t{%a1, %0|%0, %a1}"
2116 [(set_attr "type" "imov")
2117 (set_attr "modrm" "0,*")
2118 (set_attr "length_address" "8,0")
2119 (set_attr "length_immediate" "0")
2120 (set_attr "memory" "load")
2121 (set_attr "mode" "DI")])
2123 ;; Convert impossible stores of immediate to existing instructions.
2124 ;; First try to get scratch register and go through it. In case this
2125 ;; fails, move by 32bit parts.
2127 [(match_scratch:DI 2 "r")
2128 (set (match_operand:DI 0 "memory_operand" "")
2129 (match_operand:DI 1 "immediate_operand" ""))]
2130 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2131 && !x86_64_immediate_operand (operands[1], DImode)"
2132 [(set (match_dup 2) (match_dup 1))
2133 (set (match_dup 0) (match_dup 2))]
2136 ;; We need to define this as both peepholer and splitter for case
2137 ;; peephole2 pass is not run.
2138 ;; "&& 1" is needed to keep it from matching the previous pattern.
2140 [(set (match_operand:DI 0 "memory_operand" "")
2141 (match_operand:DI 1 "immediate_operand" ""))]
2142 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2143 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2144 [(set (match_dup 2) (match_dup 3))
2145 (set (match_dup 4) (match_dup 5))]
2146 "split_di (operands, 2, operands + 2, operands + 4);")
2149 [(set (match_operand:DI 0 "memory_operand" "")
2150 (match_operand:DI 1 "immediate_operand" ""))]
2151 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2152 ? flow2_completed : reload_completed)
2153 && !symbolic_operand (operands[1], DImode)
2154 && !x86_64_immediate_operand (operands[1], DImode)"
2155 [(set (match_dup 2) (match_dup 3))
2156 (set (match_dup 4) (match_dup 5))]
2157 "split_di (operands, 2, operands + 2, operands + 4);")
2159 (define_insn "*swapdi_rex64"
2160 [(set (match_operand:DI 0 "register_operand" "+r")
2161 (match_operand:DI 1 "register_operand" "+r"))
2166 [(set_attr "type" "imov")
2167 (set_attr "mode" "DI")
2168 (set_attr "pent_pair" "np")
2169 (set_attr "athlon_decode" "vector")
2170 (set_attr "amdfam10_decode" "double")])
2172 (define_expand "movti"
2173 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2174 (match_operand:TI 1 "nonimmediate_operand" ""))]
2175 "TARGET_SSE || TARGET_64BIT"
2178 ix86_expand_move (TImode, operands);
2179 else if (push_operand (operands[0], TImode))
2180 ix86_expand_push (TImode, operands[1]);
2182 ix86_expand_vector_move (TImode, operands);
2186 (define_insn "*movti_internal"
2187 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2188 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2189 "TARGET_SSE && !TARGET_64BIT
2190 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2192 switch (which_alternative)
2195 if (get_attr_mode (insn) == MODE_V4SF)
2196 return "xorps\t%0, %0";
2198 return "pxor\t%0, %0";
2201 if (get_attr_mode (insn) == MODE_V4SF)
2202 return "movaps\t{%1, %0|%0, %1}";
2204 return "movdqa\t{%1, %0|%0, %1}";
2209 [(set_attr "type" "sselog1,ssemov,ssemov")
2211 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2212 (ne (symbol_ref "optimize_size") (const_int 0)))
2213 (const_string "V4SF")
2214 (and (eq_attr "alternative" "2")
2215 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2217 (const_string "V4SF")]
2218 (const_string "TI")))])
2220 (define_insn "*movti_rex64"
2221 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2222 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2224 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2226 switch (which_alternative)
2232 if (get_attr_mode (insn) == MODE_V4SF)
2233 return "xorps\t%0, %0";
2235 return "pxor\t%0, %0";
2238 if (get_attr_mode (insn) == MODE_V4SF)
2239 return "movaps\t{%1, %0|%0, %1}";
2241 return "movdqa\t{%1, %0|%0, %1}";
2246 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2248 (cond [(eq_attr "alternative" "2,3")
2250 (ne (symbol_ref "optimize_size")
2252 (const_string "V4SF")
2253 (const_string "TI"))
2254 (eq_attr "alternative" "4")
2256 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2258 (ne (symbol_ref "optimize_size")
2260 (const_string "V4SF")
2261 (const_string "TI"))]
2262 (const_string "DI")))])
2265 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2266 (match_operand:TI 1 "general_operand" ""))]
2267 "reload_completed && !SSE_REG_P (operands[0])
2268 && !SSE_REG_P (operands[1])"
2270 "ix86_split_long_move (operands); DONE;")
2272 ;; This expands to what emit_move_complex would generate if we didn't
2273 ;; have a movti pattern. Having this avoids problems with reload on
2274 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2275 ;; to have around all the time.
2276 (define_expand "movcdi"
2277 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2278 (match_operand:CDI 1 "general_operand" ""))]
2281 if (push_operand (operands[0], CDImode))
2282 emit_move_complex_push (CDImode, operands[0], operands[1]);
2284 emit_move_complex_parts (operands[0], operands[1]);
2288 (define_expand "movsf"
2289 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2290 (match_operand:SF 1 "general_operand" ""))]
2292 "ix86_expand_move (SFmode, operands); DONE;")
2294 (define_insn "*pushsf"
2295 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2296 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2299 /* Anything else should be already split before reg-stack. */
2300 gcc_assert (which_alternative == 1);
2301 return "push{l}\t%1";
2303 [(set_attr "type" "multi,push,multi")
2304 (set_attr "unit" "i387,*,*")
2305 (set_attr "mode" "SF,SI,SF")])
2307 (define_insn "*pushsf_rex64"
2308 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2309 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2312 /* Anything else should be already split before reg-stack. */
2313 gcc_assert (which_alternative == 1);
2314 return "push{q}\t%q1";
2316 [(set_attr "type" "multi,push,multi")
2317 (set_attr "unit" "i387,*,*")
2318 (set_attr "mode" "SF,DI,SF")])
2321 [(set (match_operand:SF 0 "push_operand" "")
2322 (match_operand:SF 1 "memory_operand" ""))]
2324 && MEM_P (operands[1])
2325 && (operands[2] = find_constant_src (insn))"
2330 ;; %%% Kill this when call knows how to work this out.
2332 [(set (match_operand:SF 0 "push_operand" "")
2333 (match_operand:SF 1 "any_fp_register_operand" ""))]
2335 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2336 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2339 [(set (match_operand:SF 0 "push_operand" "")
2340 (match_operand:SF 1 "any_fp_register_operand" ""))]
2342 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2343 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2345 (define_insn "*movsf_1"
2346 [(set (match_operand:SF 0 "nonimmediate_operand"
2347 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2348 (match_operand:SF 1 "general_operand"
2349 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2350 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2351 && (reload_in_progress || reload_completed
2352 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2353 || (!TARGET_SSE_MATH && optimize_size
2354 && standard_80387_constant_p (operands[1]))
2355 || GET_CODE (operands[1]) != CONST_DOUBLE
2356 || memory_operand (operands[0], SFmode))"
2358 switch (which_alternative)
2362 return output_387_reg_move (insn, operands);
2365 return standard_80387_constant_opcode (operands[1]);
2369 return "mov{l}\t{%1, %0|%0, %1}";
2371 if (get_attr_mode (insn) == MODE_TI)
2372 return "pxor\t%0, %0";
2374 return "xorps\t%0, %0";
2376 if (get_attr_mode (insn) == MODE_V4SF)
2377 return "movaps\t{%1, %0|%0, %1}";
2379 return "movss\t{%1, %0|%0, %1}";
2381 return "movss\t{%1, %0|%0, %1}";
2384 case 12: case 13: case 14: case 15:
2385 return "movd\t{%1, %0|%0, %1}";
2388 return "movq\t{%1, %0|%0, %1}";
2394 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2396 (cond [(eq_attr "alternative" "3,4,9,10")
2398 (eq_attr "alternative" "5")
2400 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2402 (ne (symbol_ref "TARGET_SSE2")
2404 (eq (symbol_ref "optimize_size")
2407 (const_string "V4SF"))
2408 /* For architectures resolving dependencies on
2409 whole SSE registers use APS move to break dependency
2410 chains, otherwise use short move to avoid extra work.
2412 Do the same for architectures resolving dependencies on
2413 the parts. While in DF mode it is better to always handle
2414 just register parts, the SF mode is different due to lack
2415 of instructions to load just part of the register. It is
2416 better to maintain the whole registers in single format
2417 to avoid problems on using packed logical operations. */
2418 (eq_attr "alternative" "6")
2420 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2422 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2424 (const_string "V4SF")
2425 (const_string "SF"))
2426 (eq_attr "alternative" "11")
2427 (const_string "DI")]
2428 (const_string "SF")))])
2430 (define_insn "*swapsf"
2431 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2432 (match_operand:SF 1 "fp_register_operand" "+f"))
2435 "reload_completed || TARGET_80387"
2437 if (STACK_TOP_P (operands[0]))
2442 [(set_attr "type" "fxch")
2443 (set_attr "mode" "SF")])
2445 (define_expand "movdf"
2446 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2447 (match_operand:DF 1 "general_operand" ""))]
2449 "ix86_expand_move (DFmode, operands); DONE;")
2451 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2452 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2453 ;; On the average, pushdf using integers can be still shorter. Allow this
2454 ;; pattern for optimize_size too.
2456 (define_insn "*pushdf_nointeger"
2457 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2458 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2459 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2461 /* This insn should be already split before reg-stack. */
2464 [(set_attr "type" "multi")
2465 (set_attr "unit" "i387,*,*,*")
2466 (set_attr "mode" "DF,SI,SI,DF")])
2468 (define_insn "*pushdf_integer"
2469 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2470 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2471 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2473 /* This insn should be already split before reg-stack. */
2476 [(set_attr "type" "multi")
2477 (set_attr "unit" "i387,*,*")
2478 (set_attr "mode" "DF,SI,DF")])
2480 ;; %%% Kill this when call knows how to work this out.
2482 [(set (match_operand:DF 0 "push_operand" "")
2483 (match_operand:DF 1 "any_fp_register_operand" ""))]
2484 "!TARGET_64BIT && reload_completed"
2485 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2486 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2490 [(set (match_operand:DF 0 "push_operand" "")
2491 (match_operand:DF 1 "any_fp_register_operand" ""))]
2492 "TARGET_64BIT && reload_completed"
2493 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2494 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2498 [(set (match_operand:DF 0 "push_operand" "")
2499 (match_operand:DF 1 "general_operand" ""))]
2502 "ix86_split_long_move (operands); DONE;")
2504 ;; Moving is usually shorter when only FP registers are used. This separate
2505 ;; movdf pattern avoids the use of integer registers for FP operations
2506 ;; when optimizing for size.
2508 (define_insn "*movdf_nointeger"
2509 [(set (match_operand:DF 0 "nonimmediate_operand"
2510 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2511 (match_operand:DF 1 "general_operand"
2512 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
2513 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2514 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2515 && (reload_in_progress || reload_completed
2516 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2517 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2518 && standard_80387_constant_p (operands[1]))
2519 || GET_CODE (operands[1]) != CONST_DOUBLE
2520 || memory_operand (operands[0], DFmode))"
2522 switch (which_alternative)
2526 return output_387_reg_move (insn, operands);
2529 return standard_80387_constant_opcode (operands[1]);
2535 switch (get_attr_mode (insn))
2538 return "xorps\t%0, %0";
2540 return "xorpd\t%0, %0";
2542 return "pxor\t%0, %0";
2549 switch (get_attr_mode (insn))
2552 return "movaps\t{%1, %0|%0, %1}";
2554 return "movapd\t{%1, %0|%0, %1}";
2556 return "movdqa\t{%1, %0|%0, %1}";
2558 return "movq\t{%1, %0|%0, %1}";
2560 return "movsd\t{%1, %0|%0, %1}";
2562 return "movlpd\t{%1, %0|%0, %1}";
2564 return "movlps\t{%1, %0|%0, %1}";
2573 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2575 (cond [(eq_attr "alternative" "0,1,2")
2577 (eq_attr "alternative" "3,4")
2580 /* For SSE1, we have many fewer alternatives. */
2581 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2582 (cond [(eq_attr "alternative" "5,6")
2583 (const_string "V4SF")
2585 (const_string "V2SF"))
2587 /* xorps is one byte shorter. */
2588 (eq_attr "alternative" "5")
2589 (cond [(ne (symbol_ref "optimize_size")
2591 (const_string "V4SF")
2592 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2596 (const_string "V2DF"))
2598 /* For architectures resolving dependencies on
2599 whole SSE registers use APD move to break dependency
2600 chains, otherwise use short move to avoid extra work.
2602 movaps encodes one byte shorter. */
2603 (eq_attr "alternative" "6")
2605 [(ne (symbol_ref "optimize_size")
2607 (const_string "V4SF")
2608 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2610 (const_string "V2DF")
2612 (const_string "DF"))
2613 /* For architectures resolving dependencies on register
2614 parts we may avoid extra work to zero out upper part
2616 (eq_attr "alternative" "7")
2618 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2620 (const_string "V1DF")
2621 (const_string "DF"))
2623 (const_string "DF")))])
2625 (define_insn "*movdf_integer_rex64"
2626 [(set (match_operand:DF 0 "nonimmediate_operand"
2627 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2628 (match_operand:DF 1 "general_operand"
2629 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2630 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2631 && (reload_in_progress || reload_completed
2632 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2633 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2634 && standard_80387_constant_p (operands[1]))
2635 || GET_CODE (operands[1]) != CONST_DOUBLE
2636 || memory_operand (operands[0], DFmode))"
2638 switch (which_alternative)
2642 return output_387_reg_move (insn, operands);
2645 return standard_80387_constant_opcode (operands[1]);
2652 switch (get_attr_mode (insn))
2655 return "xorps\t%0, %0";
2657 return "xorpd\t%0, %0";
2659 return "pxor\t%0, %0";
2666 switch (get_attr_mode (insn))
2669 return "movaps\t{%1, %0|%0, %1}";
2671 return "movapd\t{%1, %0|%0, %1}";
2673 return "movdqa\t{%1, %0|%0, %1}";
2675 return "movq\t{%1, %0|%0, %1}";
2677 return "movsd\t{%1, %0|%0, %1}";
2679 return "movlpd\t{%1, %0|%0, %1}";
2681 return "movlps\t{%1, %0|%0, %1}";
2688 return "movd\t{%1, %0|%0, %1}";
2694 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2696 (cond [(eq_attr "alternative" "0,1,2")
2698 (eq_attr "alternative" "3,4,9,10")
2701 /* For SSE1, we have many fewer alternatives. */
2702 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2703 (cond [(eq_attr "alternative" "5,6")
2704 (const_string "V4SF")
2706 (const_string "V2SF"))
2708 /* xorps is one byte shorter. */
2709 (eq_attr "alternative" "5")
2710 (cond [(ne (symbol_ref "optimize_size")
2712 (const_string "V4SF")
2713 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2717 (const_string "V2DF"))
2719 /* For architectures resolving dependencies on
2720 whole SSE registers use APD move to break dependency
2721 chains, otherwise use short move to avoid extra work.
2723 movaps encodes one byte shorter. */
2724 (eq_attr "alternative" "6")
2726 [(ne (symbol_ref "optimize_size")
2728 (const_string "V4SF")
2729 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2731 (const_string "V2DF")
2733 (const_string "DF"))
2734 /* For architectures resolving dependencies on register
2735 parts we may avoid extra work to zero out upper part
2737 (eq_attr "alternative" "7")
2739 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2741 (const_string "V1DF")
2742 (const_string "DF"))
2744 (const_string "DF")))])
2746 (define_insn "*movdf_integer"
2747 [(set (match_operand:DF 0 "nonimmediate_operand"
2748 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2749 (match_operand:DF 1 "general_operand"
2750 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2751 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2752 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2753 && (reload_in_progress || reload_completed
2754 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2755 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2756 && standard_80387_constant_p (operands[1]))
2757 || GET_CODE (operands[1]) != CONST_DOUBLE
2758 || memory_operand (operands[0], DFmode))"
2760 switch (which_alternative)
2764 return output_387_reg_move (insn, operands);
2767 return standard_80387_constant_opcode (operands[1]);
2774 switch (get_attr_mode (insn))
2777 return "xorps\t%0, %0";
2779 return "xorpd\t%0, %0";
2781 return "pxor\t%0, %0";
2788 switch (get_attr_mode (insn))
2791 return "movaps\t{%1, %0|%0, %1}";
2793 return "movapd\t{%1, %0|%0, %1}";
2795 return "movdqa\t{%1, %0|%0, %1}";
2797 return "movq\t{%1, %0|%0, %1}";
2799 return "movsd\t{%1, %0|%0, %1}";
2801 return "movlpd\t{%1, %0|%0, %1}";
2803 return "movlps\t{%1, %0|%0, %1}";
2812 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2814 (cond [(eq_attr "alternative" "0,1,2")
2816 (eq_attr "alternative" "3,4")
2819 /* For SSE1, we have many fewer alternatives. */
2820 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2821 (cond [(eq_attr "alternative" "5,6")
2822 (const_string "V4SF")
2824 (const_string "V2SF"))
2826 /* xorps is one byte shorter. */
2827 (eq_attr "alternative" "5")
2828 (cond [(ne (symbol_ref "optimize_size")
2830 (const_string "V4SF")
2831 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2835 (const_string "V2DF"))
2837 /* For architectures resolving dependencies on
2838 whole SSE registers use APD move to break dependency
2839 chains, otherwise use short move to avoid extra work.
2841 movaps encodes one byte shorter. */
2842 (eq_attr "alternative" "6")
2844 [(ne (symbol_ref "optimize_size")
2846 (const_string "V4SF")
2847 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2849 (const_string "V2DF")
2851 (const_string "DF"))
2852 /* For architectures resolving dependencies on register
2853 parts we may avoid extra work to zero out upper part
2855 (eq_attr "alternative" "7")
2857 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2859 (const_string "V1DF")
2860 (const_string "DF"))
2862 (const_string "DF")))])
2865 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2866 (match_operand:DF 1 "general_operand" ""))]
2868 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2869 && ! (ANY_FP_REG_P (operands[0]) ||
2870 (GET_CODE (operands[0]) == SUBREG
2871 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2872 && ! (ANY_FP_REG_P (operands[1]) ||
2873 (GET_CODE (operands[1]) == SUBREG
2874 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2876 "ix86_split_long_move (operands); DONE;")
2878 (define_insn "*swapdf"
2879 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2880 (match_operand:DF 1 "fp_register_operand" "+f"))
2883 "reload_completed || TARGET_80387"
2885 if (STACK_TOP_P (operands[0]))
2890 [(set_attr "type" "fxch")
2891 (set_attr "mode" "DF")])
2893 (define_expand "movxf"
2894 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2895 (match_operand:XF 1 "general_operand" ""))]
2897 "ix86_expand_move (XFmode, operands); DONE;")
2899 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2900 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2901 ;; Pushing using integer instructions is longer except for constants
2902 ;; and direct memory references.
2903 ;; (assuming that any given constant is pushed only once, but this ought to be
2904 ;; handled elsewhere).
2906 (define_insn "*pushxf_nointeger"
2907 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2908 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2911 /* This insn should be already split before reg-stack. */
2914 [(set_attr "type" "multi")
2915 (set_attr "unit" "i387,*,*")
2916 (set_attr "mode" "XF,SI,SI")])
2918 (define_insn "*pushxf_integer"
2919 [(set (match_operand:XF 0 "push_operand" "=<,<")
2920 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2923 /* This insn should be already split before reg-stack. */
2926 [(set_attr "type" "multi")
2927 (set_attr "unit" "i387,*")
2928 (set_attr "mode" "XF,SI")])
2931 [(set (match_operand 0 "push_operand" "")
2932 (match_operand 1 "general_operand" ""))]
2934 && (GET_MODE (operands[0]) == XFmode
2935 || GET_MODE (operands[0]) == DFmode)
2936 && !ANY_FP_REG_P (operands[1])"
2938 "ix86_split_long_move (operands); DONE;")
2941 [(set (match_operand:XF 0 "push_operand" "")
2942 (match_operand:XF 1 "any_fp_register_operand" ""))]
2944 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2945 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2946 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2949 [(set (match_operand:XF 0 "push_operand" "")
2950 (match_operand:XF 1 "any_fp_register_operand" ""))]
2952 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2953 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2954 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2956 ;; Do not use integer registers when optimizing for size
2957 (define_insn "*movxf_nointeger"
2958 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2959 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2961 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2962 && (reload_in_progress || reload_completed
2963 || (optimize_size && standard_80387_constant_p (operands[1]))
2964 || GET_CODE (operands[1]) != CONST_DOUBLE
2965 || memory_operand (operands[0], XFmode))"
2967 switch (which_alternative)
2971 return output_387_reg_move (insn, operands);
2974 return standard_80387_constant_opcode (operands[1]);
2982 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2983 (set_attr "mode" "XF,XF,XF,SI,SI")])
2985 (define_insn "*movxf_integer"
2986 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2987 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2989 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2990 && (reload_in_progress || reload_completed
2991 || (optimize_size && standard_80387_constant_p (operands[1]))
2992 || GET_CODE (operands[1]) != CONST_DOUBLE
2993 || memory_operand (operands[0], XFmode))"
2995 switch (which_alternative)
2999 return output_387_reg_move (insn, operands);
3002 return standard_80387_constant_opcode (operands[1]);
3011 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3012 (set_attr "mode" "XF,XF,XF,SI,SI")])
3015 [(set (match_operand 0 "nonimmediate_operand" "")
3016 (match_operand 1 "general_operand" ""))]
3018 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3019 && GET_MODE (operands[0]) == XFmode
3020 && ! (ANY_FP_REG_P (operands[0]) ||
3021 (GET_CODE (operands[0]) == SUBREG
3022 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3023 && ! (ANY_FP_REG_P (operands[1]) ||
3024 (GET_CODE (operands[1]) == SUBREG
3025 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3027 "ix86_split_long_move (operands); DONE;")
3030 [(set (match_operand 0 "register_operand" "")
3031 (match_operand 1 "memory_operand" ""))]
3033 && MEM_P (operands[1])
3034 && (GET_MODE (operands[0]) == XFmode
3035 || GET_MODE (operands[0]) == SFmode
3036 || GET_MODE (operands[0]) == DFmode)
3037 && (operands[2] = find_constant_src (insn))"
3038 [(set (match_dup 0) (match_dup 2))]
3040 rtx c = operands[2];
3041 rtx r = operands[0];
3043 if (GET_CODE (r) == SUBREG)
3048 if (!standard_sse_constant_p (c))
3051 else if (FP_REG_P (r))
3053 if (!standard_80387_constant_p (c))
3056 else if (MMX_REG_P (r))
3061 [(set (match_operand 0 "register_operand" "")
3062 (float_extend (match_operand 1 "memory_operand" "")))]
3064 && MEM_P (operands[1])
3065 && (GET_MODE (operands[0]) == XFmode
3066 || GET_MODE (operands[0]) == SFmode
3067 || GET_MODE (operands[0]) == DFmode)
3068 && (operands[2] = find_constant_src (insn))"
3069 [(set (match_dup 0) (match_dup 2))]
3071 rtx c = operands[2];
3072 rtx r = operands[0];
3074 if (GET_CODE (r) == SUBREG)
3079 if (!standard_sse_constant_p (c))
3082 else if (FP_REG_P (r))
3084 if (!standard_80387_constant_p (c))
3087 else if (MMX_REG_P (r))
3091 (define_insn "swapxf"
3092 [(set (match_operand:XF 0 "register_operand" "+f")
3093 (match_operand:XF 1 "register_operand" "+f"))
3098 if (STACK_TOP_P (operands[0]))
3103 [(set_attr "type" "fxch")
3104 (set_attr "mode" "XF")])
3106 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3108 [(set (match_operand:X87MODEF 0 "register_operand" "")
3109 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3110 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3111 && (standard_80387_constant_p (operands[1]) == 8
3112 || standard_80387_constant_p (operands[1]) == 9)"
3113 [(set (match_dup 0)(match_dup 1))
3115 (neg:X87MODEF (match_dup 0)))]
3119 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3120 if (real_isnegzero (&r))
3121 operands[1] = CONST0_RTX (<MODE>mode);
3123 operands[1] = CONST1_RTX (<MODE>mode);
3126 (define_expand "movtf"
3127 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3128 (match_operand:TF 1 "nonimmediate_operand" ""))]
3131 ix86_expand_move (TFmode, operands);
3135 (define_insn "*movtf_internal"
3136 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3137 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3139 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3141 switch (which_alternative)
3147 if (get_attr_mode (insn) == MODE_V4SF)
3148 return "xorps\t%0, %0";
3150 return "pxor\t%0, %0";
3153 if (get_attr_mode (insn) == MODE_V4SF)
3154 return "movaps\t{%1, %0|%0, %1}";
3156 return "movdqa\t{%1, %0|%0, %1}";
3161 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3163 (cond [(eq_attr "alternative" "2,3")
3165 (ne (symbol_ref "optimize_size")
3167 (const_string "V4SF")
3168 (const_string "TI"))
3169 (eq_attr "alternative" "4")
3171 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3173 (ne (symbol_ref "optimize_size")
3175 (const_string "V4SF")
3176 (const_string "TI"))]
3177 (const_string "DI")))])
3180 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3181 (match_operand:TF 1 "general_operand" ""))]
3182 "reload_completed && !SSE_REG_P (operands[0])
3183 && !SSE_REG_P (operands[1])"
3185 "ix86_split_long_move (operands); DONE;")
3187 ;; Zero extension instructions
3189 (define_expand "zero_extendhisi2"
3190 [(set (match_operand:SI 0 "register_operand" "")
3191 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3194 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3196 operands[1] = force_reg (HImode, operands[1]);
3197 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3202 (define_insn "zero_extendhisi2_and"
3203 [(set (match_operand:SI 0 "register_operand" "=r")
3204 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3205 (clobber (reg:CC FLAGS_REG))]
3206 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3208 [(set_attr "type" "alu1")
3209 (set_attr "mode" "SI")])
3212 [(set (match_operand:SI 0 "register_operand" "")
3213 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3214 (clobber (reg:CC FLAGS_REG))]
3215 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3216 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3217 (clobber (reg:CC FLAGS_REG))])]
3220 (define_insn "*zero_extendhisi2_movzwl"
3221 [(set (match_operand:SI 0 "register_operand" "=r")
3222 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3223 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3224 "movz{wl|x}\t{%1, %0|%0, %1}"
3225 [(set_attr "type" "imovx")
3226 (set_attr "mode" "SI")])
3228 (define_expand "zero_extendqihi2"
3230 [(set (match_operand:HI 0 "register_operand" "")
3231 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3232 (clobber (reg:CC FLAGS_REG))])]
3236 (define_insn "*zero_extendqihi2_and"
3237 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3238 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3239 (clobber (reg:CC FLAGS_REG))]
3240 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3242 [(set_attr "type" "alu1")
3243 (set_attr "mode" "HI")])
3245 (define_insn "*zero_extendqihi2_movzbw_and"
3246 [(set (match_operand:HI 0 "register_operand" "=r,r")
3247 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3248 (clobber (reg:CC FLAGS_REG))]
3249 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3251 [(set_attr "type" "imovx,alu1")
3252 (set_attr "mode" "HI")])
3254 ; zero extend to SImode here to avoid partial register stalls
3255 (define_insn "*zero_extendqihi2_movzbl"
3256 [(set (match_operand:HI 0 "register_operand" "=r")
3257 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3258 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3259 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3260 [(set_attr "type" "imovx")
3261 (set_attr "mode" "SI")])
3263 ;; For the movzbw case strip only the clobber
3265 [(set (match_operand:HI 0 "register_operand" "")
3266 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3267 (clobber (reg:CC FLAGS_REG))]
3269 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3270 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3271 [(set (match_operand:HI 0 "register_operand" "")
3272 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3274 ;; When source and destination does not overlap, clear destination
3275 ;; first and then do the movb
3277 [(set (match_operand:HI 0 "register_operand" "")
3278 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3279 (clobber (reg:CC FLAGS_REG))]
3281 && ANY_QI_REG_P (operands[0])
3282 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3283 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3284 [(set (match_dup 0) (const_int 0))
3285 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3286 "operands[2] = gen_lowpart (QImode, operands[0]);")
3288 ;; Rest is handled by single and.
3290 [(set (match_operand:HI 0 "register_operand" "")
3291 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3292 (clobber (reg:CC FLAGS_REG))]
3294 && true_regnum (operands[0]) == true_regnum (operands[1])"
3295 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3296 (clobber (reg:CC FLAGS_REG))])]
3299 (define_expand "zero_extendqisi2"
3301 [(set (match_operand:SI 0 "register_operand" "")
3302 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3303 (clobber (reg:CC FLAGS_REG))])]
3307 (define_insn "*zero_extendqisi2_and"
3308 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3309 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3310 (clobber (reg:CC FLAGS_REG))]
3311 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3313 [(set_attr "type" "alu1")
3314 (set_attr "mode" "SI")])
3316 (define_insn "*zero_extendqisi2_movzbw_and"
3317 [(set (match_operand:SI 0 "register_operand" "=r,r")
3318 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3319 (clobber (reg:CC FLAGS_REG))]
3320 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3322 [(set_attr "type" "imovx,alu1")
3323 (set_attr "mode" "SI")])
3325 (define_insn "*zero_extendqisi2_movzbw"
3326 [(set (match_operand:SI 0 "register_operand" "=r")
3327 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3328 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3329 "movz{bl|x}\t{%1, %0|%0, %1}"
3330 [(set_attr "type" "imovx")
3331 (set_attr "mode" "SI")])
3333 ;; For the movzbl case strip only the clobber
3335 [(set (match_operand:SI 0 "register_operand" "")
3336 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3337 (clobber (reg:CC FLAGS_REG))]
3339 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3340 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3342 (zero_extend:SI (match_dup 1)))])
3344 ;; When source and destination does not overlap, clear destination
3345 ;; first and then do the movb
3347 [(set (match_operand:SI 0 "register_operand" "")
3348 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3349 (clobber (reg:CC FLAGS_REG))]
3351 && ANY_QI_REG_P (operands[0])
3352 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3353 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3354 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3355 [(set (match_dup 0) (const_int 0))
3356 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3357 "operands[2] = gen_lowpart (QImode, operands[0]);")
3359 ;; Rest is handled by single and.
3361 [(set (match_operand:SI 0 "register_operand" "")
3362 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3363 (clobber (reg:CC FLAGS_REG))]
3365 && true_regnum (operands[0]) == true_regnum (operands[1])"
3366 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3367 (clobber (reg:CC FLAGS_REG))])]
3370 ;; %%% Kill me once multi-word ops are sane.
3371 (define_expand "zero_extendsidi2"
3372 [(set (match_operand:DI 0 "register_operand" "=r")
3373 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3378 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3383 (define_insn "zero_extendsidi2_32"
3384 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3386 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3387 (clobber (reg:CC FLAGS_REG))]
3393 movd\t{%1, %0|%0, %1}
3394 movd\t{%1, %0|%0, %1}
3395 movd\t{%1, %0|%0, %1}
3396 movd\t{%1, %0|%0, %1}"
3397 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3398 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3400 (define_insn "zero_extendsidi2_rex64"
3401 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3403 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3406 mov\t{%k1, %k0|%k0, %k1}
3408 movd\t{%1, %0|%0, %1}
3409 movd\t{%1, %0|%0, %1}
3410 movd\t{%1, %0|%0, %1}
3411 movd\t{%1, %0|%0, %1}"
3412 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3413 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3416 [(set (match_operand:DI 0 "memory_operand" "")
3417 (zero_extend:DI (match_dup 0)))]
3419 [(set (match_dup 4) (const_int 0))]
3420 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3423 [(set (match_operand:DI 0 "register_operand" "")
3424 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3425 (clobber (reg:CC FLAGS_REG))]
3426 "!TARGET_64BIT && reload_completed
3427 && true_regnum (operands[0]) == true_regnum (operands[1])"
3428 [(set (match_dup 4) (const_int 0))]
3429 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3432 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3433 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3434 (clobber (reg:CC FLAGS_REG))]
3435 "!TARGET_64BIT && reload_completed
3436 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3437 [(set (match_dup 3) (match_dup 1))
3438 (set (match_dup 4) (const_int 0))]
3439 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3441 (define_insn "zero_extendhidi2"
3442 [(set (match_operand:DI 0 "register_operand" "=r")
3443 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3445 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3446 [(set_attr "type" "imovx")
3447 (set_attr "mode" "DI")])
3449 (define_insn "zero_extendqidi2"
3450 [(set (match_operand:DI 0 "register_operand" "=r")
3451 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3453 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3454 [(set_attr "type" "imovx")
3455 (set_attr "mode" "DI")])
3457 ;; Sign extension instructions
3459 (define_expand "extendsidi2"
3460 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3461 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3462 (clobber (reg:CC FLAGS_REG))
3463 (clobber (match_scratch:SI 2 ""))])]
3468 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3473 (define_insn "*extendsidi2_1"
3474 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3475 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3476 (clobber (reg:CC FLAGS_REG))
3477 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3481 (define_insn "extendsidi2_rex64"
3482 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3483 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3487 movs{lq|x}\t{%1,%0|%0, %1}"
3488 [(set_attr "type" "imovx")
3489 (set_attr "mode" "DI")
3490 (set_attr "prefix_0f" "0")
3491 (set_attr "modrm" "0,1")])
3493 (define_insn "extendhidi2"
3494 [(set (match_operand:DI 0 "register_operand" "=r")
3495 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3497 "movs{wq|x}\t{%1,%0|%0, %1}"
3498 [(set_attr "type" "imovx")
3499 (set_attr "mode" "DI")])
3501 (define_insn "extendqidi2"
3502 [(set (match_operand:DI 0 "register_operand" "=r")
3503 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3505 "movs{bq|x}\t{%1,%0|%0, %1}"
3506 [(set_attr "type" "imovx")
3507 (set_attr "mode" "DI")])
3509 ;; Extend to memory case when source register does die.
3511 [(set (match_operand:DI 0 "memory_operand" "")
3512 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3513 (clobber (reg:CC FLAGS_REG))
3514 (clobber (match_operand:SI 2 "register_operand" ""))]
3516 && dead_or_set_p (insn, operands[1])
3517 && !reg_mentioned_p (operands[1], operands[0]))"
3518 [(set (match_dup 3) (match_dup 1))
3519 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3520 (clobber (reg:CC FLAGS_REG))])
3521 (set (match_dup 4) (match_dup 1))]
3522 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3524 ;; Extend to memory case when source register does not die.
3526 [(set (match_operand:DI 0 "memory_operand" "")
3527 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3528 (clobber (reg:CC FLAGS_REG))
3529 (clobber (match_operand:SI 2 "register_operand" ""))]
3533 split_di (&operands[0], 1, &operands[3], &operands[4]);
3535 emit_move_insn (operands[3], operands[1]);
3537 /* Generate a cltd if possible and doing so it profitable. */
3538 if (true_regnum (operands[1]) == 0
3539 && true_regnum (operands[2]) == 1
3540 && (optimize_size || TARGET_USE_CLTD))
3542 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3546 emit_move_insn (operands[2], operands[1]);
3547 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3549 emit_move_insn (operands[4], operands[2]);
3553 ;; Extend to register case. Optimize case where source and destination
3554 ;; registers match and cases where we can use cltd.
3556 [(set (match_operand:DI 0 "register_operand" "")
3557 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3558 (clobber (reg:CC FLAGS_REG))
3559 (clobber (match_scratch:SI 2 ""))]
3563 split_di (&operands[0], 1, &operands[3], &operands[4]);
3565 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3566 emit_move_insn (operands[3], operands[1]);
3568 /* Generate a cltd if possible and doing so it profitable. */
3569 if (true_regnum (operands[3]) == 0
3570 && (optimize_size || TARGET_USE_CLTD))
3572 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3576 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3577 emit_move_insn (operands[4], operands[1]);
3579 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3583 (define_insn "extendhisi2"
3584 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3585 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3588 switch (get_attr_prefix_0f (insn))
3591 return "{cwtl|cwde}";
3593 return "movs{wl|x}\t{%1,%0|%0, %1}";
3596 [(set_attr "type" "imovx")
3597 (set_attr "mode" "SI")
3598 (set (attr "prefix_0f")
3599 ;; movsx is short decodable while cwtl is vector decoded.
3600 (if_then_else (and (eq_attr "cpu" "!k6")
3601 (eq_attr "alternative" "0"))
3603 (const_string "1")))
3605 (if_then_else (eq_attr "prefix_0f" "0")
3607 (const_string "1")))])
3609 (define_insn "*extendhisi2_zext"
3610 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3612 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3615 switch (get_attr_prefix_0f (insn))
3618 return "{cwtl|cwde}";
3620 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3623 [(set_attr "type" "imovx")
3624 (set_attr "mode" "SI")
3625 (set (attr "prefix_0f")
3626 ;; movsx is short decodable while cwtl is vector decoded.
3627 (if_then_else (and (eq_attr "cpu" "!k6")
3628 (eq_attr "alternative" "0"))
3630 (const_string "1")))
3632 (if_then_else (eq_attr "prefix_0f" "0")
3634 (const_string "1")))])
3636 (define_insn "extendqihi2"
3637 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3638 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3641 switch (get_attr_prefix_0f (insn))
3644 return "{cbtw|cbw}";
3646 return "movs{bw|x}\t{%1,%0|%0, %1}";
3649 [(set_attr "type" "imovx")
3650 (set_attr "mode" "HI")
3651 (set (attr "prefix_0f")
3652 ;; movsx is short decodable while cwtl is vector decoded.
3653 (if_then_else (and (eq_attr "cpu" "!k6")
3654 (eq_attr "alternative" "0"))
3656 (const_string "1")))
3658 (if_then_else (eq_attr "prefix_0f" "0")
3660 (const_string "1")))])
3662 (define_insn "extendqisi2"
3663 [(set (match_operand:SI 0 "register_operand" "=r")
3664 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3666 "movs{bl|x}\t{%1,%0|%0, %1}"
3667 [(set_attr "type" "imovx")
3668 (set_attr "mode" "SI")])
3670 (define_insn "*extendqisi2_zext"
3671 [(set (match_operand:DI 0 "register_operand" "=r")
3673 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3675 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3676 [(set_attr "type" "imovx")
3677 (set_attr "mode" "SI")])
3679 ;; Conversions between float and double.
3681 ;; These are all no-ops in the model used for the 80387. So just
3684 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3685 (define_insn "*dummy_extendsfdf2"
3686 [(set (match_operand:DF 0 "push_operand" "=<")
3687 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3692 [(set (match_operand:DF 0 "push_operand" "")
3693 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3695 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3696 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3699 [(set (match_operand:DF 0 "push_operand" "")
3700 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3702 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3703 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3705 (define_insn "*dummy_extendsfxf2"
3706 [(set (match_operand:XF 0 "push_operand" "=<")
3707 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3712 [(set (match_operand:XF 0 "push_operand" "")
3713 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3715 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3716 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3717 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3720 [(set (match_operand:XF 0 "push_operand" "")
3721 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3723 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3724 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3725 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3728 [(set (match_operand:XF 0 "push_operand" "")
3729 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3731 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3732 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3733 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3736 [(set (match_operand:XF 0 "push_operand" "")
3737 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3739 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3740 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3741 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3743 (define_expand "extendsfdf2"
3744 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3745 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3746 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3748 /* ??? Needed for compress_float_constant since all fp constants
3749 are LEGITIMATE_CONSTANT_P. */
3750 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3752 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3753 && standard_80387_constant_p (operands[1]) > 0)
3755 operands[1] = simplify_const_unary_operation
3756 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3757 emit_move_insn_1 (operands[0], operands[1]);
3760 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3764 (define_insn "*extendsfdf2_mixed"
3765 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3767 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3768 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3770 switch (which_alternative)
3774 return output_387_reg_move (insn, operands);
3777 return "cvtss2sd\t{%1, %0|%0, %1}";
3783 [(set_attr "type" "fmov,fmov,ssecvt")
3784 (set_attr "mode" "SF,XF,DF")])
3786 (define_insn "*extendsfdf2_sse"
3787 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3788 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3789 "TARGET_SSE2 && TARGET_SSE_MATH"
3790 "cvtss2sd\t{%1, %0|%0, %1}"
3791 [(set_attr "type" "ssecvt")
3792 (set_attr "mode" "DF")])
3794 (define_insn "*extendsfdf2_i387"
3795 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3796 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3798 "* return output_387_reg_move (insn, operands);"
3799 [(set_attr "type" "fmov")
3800 (set_attr "mode" "SF,XF")])
3802 (define_expand "extend<mode>xf2"
3803 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3804 (float_extend:XF (match_operand:X87MODEF12 1 "general_operand" "")))]
3807 /* ??? Needed for compress_float_constant since all fp constants
3808 are LEGITIMATE_CONSTANT_P. */
3809 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3811 if (standard_80387_constant_p (operands[1]) > 0)
3813 operands[1] = simplify_const_unary_operation
3814 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3815 emit_move_insn_1 (operands[0], operands[1]);
3818 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3822 (define_insn "*extend<mode>xf2_i387"
3823 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3825 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,f")))]
3827 "* return output_387_reg_move (insn, operands);"
3828 [(set_attr "type" "fmov")
3829 (set_attr "mode" "<MODE>,XF")])
3831 ;; %%% This seems bad bad news.
3832 ;; This cannot output into an f-reg because there is no way to be sure
3833 ;; of truncating in that case. Otherwise this is just like a simple move
3834 ;; insn. So we pretend we can output to a reg in order to get better
3835 ;; register preferencing, but we really use a stack slot.
3837 ;; Conversion from DFmode to SFmode.
3839 (define_expand "truncdfsf2"
3840 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3842 (match_operand:DF 1 "nonimmediate_operand" "")))]
3843 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3845 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3847 else if (flag_unsafe_math_optimizations)
3851 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3852 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3857 (define_expand "truncdfsf2_with_temp"
3858 [(parallel [(set (match_operand:SF 0 "" "")
3859 (float_truncate:SF (match_operand:DF 1 "" "")))
3860 (clobber (match_operand:SF 2 "" ""))])]
3863 (define_insn "*truncdfsf_fast_mixed"
3864 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
3866 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3867 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3869 switch (which_alternative)
3873 return output_387_reg_move (insn, operands);
3875 return "cvtsd2ss\t{%1, %0|%0, %1}";
3880 [(set_attr "type" "fmov,fmov,ssecvt")
3881 (set_attr "mode" "SF")])
3883 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3884 ;; because nothing we do here is unsafe.
3885 (define_insn "*truncdfsf_fast_sse"
3886 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3888 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3889 "TARGET_SSE2 && TARGET_SSE_MATH"
3890 "cvtsd2ss\t{%1, %0|%0, %1}"
3891 [(set_attr "type" "ssecvt")
3892 (set_attr "mode" "SF")])
3894 (define_insn "*truncdfsf_fast_i387"
3895 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3897 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3898 "TARGET_80387 && flag_unsafe_math_optimizations"
3899 "* return output_387_reg_move (insn, operands);"
3900 [(set_attr "type" "fmov")
3901 (set_attr "mode" "SF")])
3903 (define_insn "*truncdfsf_mixed"
3904 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
3906 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
3907 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3908 "TARGET_MIX_SSE_I387"
3910 switch (which_alternative)
3913 return output_387_reg_move (insn, operands);
3918 return "cvtsd2ss\t{%1, %0|%0, %1}";
3923 [(set_attr "type" "fmov,multi,ssecvt")
3924 (set_attr "unit" "*,i387,*")
3925 (set_attr "mode" "SF")])
3927 (define_insn "*truncdfsf_i387"
3928 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3930 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3931 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3934 switch (which_alternative)
3937 return output_387_reg_move (insn, operands);
3945 [(set_attr "type" "fmov,multi")
3946 (set_attr "unit" "*,i387")
3947 (set_attr "mode" "SF")])
3949 (define_insn "*truncdfsf2_i387_1"
3950 [(set (match_operand:SF 0 "memory_operand" "=m")
3952 (match_operand:DF 1 "register_operand" "f")))]
3954 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3955 && !TARGET_MIX_SSE_I387"
3956 "* return output_387_reg_move (insn, operands);"
3957 [(set_attr "type" "fmov")
3958 (set_attr "mode" "SF")])
3961 [(set (match_operand:SF 0 "register_operand" "")
3963 (match_operand:DF 1 "fp_register_operand" "")))
3964 (clobber (match_operand 2 "" ""))]
3966 [(set (match_dup 2) (match_dup 1))
3967 (set (match_dup 0) (match_dup 2))]
3969 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3972 ;; Conversion from XFmode to {SF,DF}mode
3974 (define_expand "truncxf<mode>2"
3975 [(parallel [(set (match_operand:X87MODEF12 0 "nonimmediate_operand" "")
3976 (float_truncate:X87MODEF12
3977 (match_operand:XF 1 "register_operand" "")))
3978 (clobber (match_dup 2))])]
3981 if (flag_unsafe_math_optimizations)
3983 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3984 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3985 if (reg != operands[0])
3986 emit_move_insn (operands[0], reg);
3990 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3993 (define_insn "*truncxfsf2_mixed"
3994 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3996 (match_operand:XF 1 "register_operand" "f,f")))
3997 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4000 gcc_assert (!which_alternative);
4001 return output_387_reg_move (insn, operands);
4003 [(set_attr "type" "fmov,multi")
4004 (set_attr "unit" "*,i387")
4005 (set_attr "mode" "SF")])
4007 (define_insn "*truncxfdf2_mixed"
4008 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4010 (match_operand:XF 1 "register_operand" "f,f")))
4011 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4014 gcc_assert (!which_alternative);
4015 return output_387_reg_move (insn, operands);
4017 [(set_attr "type" "fmov,multi")
4018 (set_attr "unit" "*,i387")
4019 (set_attr "mode" "DF")])
4021 (define_insn "truncxf<mode>2_i387_noop"
4022 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
4023 (float_truncate:X87MODEF12
4024 (match_operand:XF 1 "register_operand" "f")))]
4025 "TARGET_80387 && flag_unsafe_math_optimizations"
4026 "* return output_387_reg_move (insn, operands);"
4027 [(set_attr "type" "fmov")
4028 (set_attr "mode" "<MODE>")])
4030 (define_insn "*truncxf<mode>2_i387"
4031 [(set (match_operand:X87MODEF12 0 "memory_operand" "=m")
4032 (float_truncate:X87MODEF12
4033 (match_operand:XF 1 "register_operand" "f")))]
4035 "* return output_387_reg_move (insn, operands);"
4036 [(set_attr "type" "fmov")
4037 (set_attr "mode" "<MODE>")])
4040 [(set (match_operand:X87MODEF12 0 "register_operand" "")
4041 (float_truncate:X87MODEF12
4042 (match_operand:XF 1 "register_operand" "")))
4043 (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4044 "TARGET_80387 && reload_completed"
4045 [(set (match_dup 2) (float_truncate:X87MODEF12 (match_dup 1)))
4046 (set (match_dup 0) (match_dup 2))]
4050 [(set (match_operand:X87MODEF12 0 "memory_operand" "")
4051 (float_truncate:X87MODEF12
4052 (match_operand:XF 1 "register_operand" "")))
4053 (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4055 [(set (match_dup 0) (float_truncate:X87MODEF12 (match_dup 1)))]
4058 ;; Signed conversion to DImode.
4060 (define_expand "fix_truncxfdi2"
4061 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4062 (fix:DI (match_operand:XF 1 "register_operand" "")))
4063 (clobber (reg:CC FLAGS_REG))])]
4068 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4073 (define_expand "fix_trunc<mode>di2"
4074 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4075 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4076 (clobber (reg:CC FLAGS_REG))])]
4077 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4080 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4082 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4085 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4087 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4088 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4089 if (out != operands[0])
4090 emit_move_insn (operands[0], out);
4095 ;; Signed conversion to SImode.
4097 (define_expand "fix_truncxfsi2"
4098 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4099 (fix:SI (match_operand:XF 1 "register_operand" "")))
4100 (clobber (reg:CC FLAGS_REG))])]
4105 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4110 (define_expand "fix_trunc<mode>si2"
4111 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4112 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4113 (clobber (reg:CC FLAGS_REG))])]
4114 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4117 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4119 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4122 if (SSE_FLOAT_MODE_P (<MODE>mode))
4124 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4125 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4126 if (out != operands[0])
4127 emit_move_insn (operands[0], out);
4132 ;; Signed conversion to HImode.
4134 (define_expand "fix_trunc<mode>hi2"
4135 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4136 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4137 (clobber (reg:CC FLAGS_REG))])]
4139 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4143 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4148 ;; Unsigned conversion to SImode.
4150 (define_expand "fixuns_trunc<mode>si2"
4152 [(set (match_operand:SI 0 "register_operand" "")
4154 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4156 (clobber (match_scratch:<ssevecmode> 3 ""))
4157 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4158 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4160 enum machine_mode mode = <MODE>mode;
4161 enum machine_mode vecmode = <ssevecmode>mode;
4162 REAL_VALUE_TYPE TWO31r;
4165 real_ldexp (&TWO31r, &dconst1, 31);
4166 two31 = const_double_from_real_value (TWO31r, mode);
4167 two31 = ix86_build_const_vector (mode, true, two31);
4168 operands[2] = force_reg (vecmode, two31);
4171 (define_insn_and_split "*fixuns_trunc<mode>_1"
4172 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4174 (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4175 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4176 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4177 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4178 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4180 "&& reload_completed"
4183 ix86_split_convert_uns_si_sse (operands);
4187 ;; Unsigned conversion to HImode.
4188 ;; Without these patterns, we'll try the unsigned SI conversion which
4189 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4191 (define_expand "fixuns_trunc<mode>hi2"
4193 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4194 (set (match_operand:HI 0 "nonimmediate_operand" "")
4195 (subreg:HI (match_dup 2) 0))]
4196 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4197 "operands[2] = gen_reg_rtx (SImode);")
4199 ;; When SSE is available, it is always faster to use it!
4200 (define_insn "fix_trunc<mode>di_sse"
4201 [(set (match_operand:DI 0 "register_operand" "=r,r")
4202 (fix:DI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4203 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4204 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4205 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4206 [(set_attr "type" "sseicvt")
4207 (set_attr "mode" "<MODE>")
4208 (set_attr "athlon_decode" "double,vector")
4209 (set_attr "amdfam10_decode" "double,double")])
4211 (define_insn "fix_trunc<mode>si_sse"
4212 [(set (match_operand:SI 0 "register_operand" "=r,r")
4213 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4214 "SSE_FLOAT_MODE_P (<MODE>mode)
4215 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4216 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4217 [(set_attr "type" "sseicvt")
4218 (set_attr "mode" "<MODE>")
4219 (set_attr "athlon_decode" "double,vector")
4220 (set_attr "amdfam10_decode" "double,double")])
4222 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4224 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4225 (match_operand:SSEMODEF 1 "memory_operand" ""))
4226 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4227 (fix:SSEMODEI24 (match_dup 0)))]
4228 "TARGET_SHORTEN_X87_SSE
4229 && peep2_reg_dead_p (2, operands[0])"
4230 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4233 ;; Avoid vector decoded forms of the instruction.
4235 [(match_scratch:DF 2 "Y2")
4236 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4237 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4238 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4239 [(set (match_dup 2) (match_dup 1))
4240 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4244 [(match_scratch:SF 2 "x")
4245 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4246 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4247 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4248 [(set (match_dup 2) (match_dup 1))
4249 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4252 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4253 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4254 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4255 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4257 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4258 && (TARGET_64BIT || <MODE>mode != DImode))
4260 && !(reload_completed || reload_in_progress)"
4265 if (memory_operand (operands[0], VOIDmode))
4266 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4269 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4270 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4276 [(set_attr "type" "fisttp")
4277 (set_attr "mode" "<MODE>")])
4279 (define_insn "fix_trunc<mode>_i387_fisttp"
4280 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4281 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4282 (clobber (match_scratch:XF 2 "=&1f"))]
4283 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4285 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4286 && (TARGET_64BIT || <MODE>mode != DImode))
4287 && TARGET_SSE_MATH)"
4288 "* return output_fix_trunc (insn, operands, 1);"
4289 [(set_attr "type" "fisttp")
4290 (set_attr "mode" "<MODE>")])
4292 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4293 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4294 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4295 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4296 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4297 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4299 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4300 && (TARGET_64BIT || <MODE>mode != DImode))
4301 && TARGET_SSE_MATH)"
4303 [(set_attr "type" "fisttp")
4304 (set_attr "mode" "<MODE>")])
4307 [(set (match_operand:X87MODEI 0 "register_operand" "")
4308 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4309 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4310 (clobber (match_scratch 3 ""))]
4312 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4313 (clobber (match_dup 3))])
4314 (set (match_dup 0) (match_dup 2))]
4318 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4319 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4320 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4321 (clobber (match_scratch 3 ""))]
4323 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4324 (clobber (match_dup 3))])]
4327 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4328 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4329 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4330 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4331 ;; function in i386.c.
4332 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4333 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4334 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4335 (clobber (reg:CC FLAGS_REG))]
4336 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4338 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4339 && (TARGET_64BIT || <MODE>mode != DImode))
4340 && !(reload_completed || reload_in_progress)"
4345 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4347 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4348 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4349 if (memory_operand (operands[0], VOIDmode))
4350 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4351 operands[2], operands[3]));
4354 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4355 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4356 operands[2], operands[3],
4361 [(set_attr "type" "fistp")
4362 (set_attr "i387_cw" "trunc")
4363 (set_attr "mode" "<MODE>")])
4365 (define_insn "fix_truncdi_i387"
4366 [(set (match_operand:DI 0 "memory_operand" "=m")
4367 (fix:DI (match_operand 1 "register_operand" "f")))
4368 (use (match_operand:HI 2 "memory_operand" "m"))
4369 (use (match_operand:HI 3 "memory_operand" "m"))
4370 (clobber (match_scratch:XF 4 "=&1f"))]
4371 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4373 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4374 "* return output_fix_trunc (insn, operands, 0);"
4375 [(set_attr "type" "fistp")
4376 (set_attr "i387_cw" "trunc")
4377 (set_attr "mode" "DI")])
4379 (define_insn "fix_truncdi_i387_with_temp"
4380 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4381 (fix:DI (match_operand 1 "register_operand" "f,f")))
4382 (use (match_operand:HI 2 "memory_operand" "m,m"))
4383 (use (match_operand:HI 3 "memory_operand" "m,m"))
4384 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4385 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4386 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4388 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4390 [(set_attr "type" "fistp")
4391 (set_attr "i387_cw" "trunc")
4392 (set_attr "mode" "DI")])
4395 [(set (match_operand:DI 0 "register_operand" "")
4396 (fix:DI (match_operand 1 "register_operand" "")))
4397 (use (match_operand:HI 2 "memory_operand" ""))
4398 (use (match_operand:HI 3 "memory_operand" ""))
4399 (clobber (match_operand:DI 4 "memory_operand" ""))
4400 (clobber (match_scratch 5 ""))]
4402 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4405 (clobber (match_dup 5))])
4406 (set (match_dup 0) (match_dup 4))]
4410 [(set (match_operand:DI 0 "memory_operand" "")
4411 (fix:DI (match_operand 1 "register_operand" "")))
4412 (use (match_operand:HI 2 "memory_operand" ""))
4413 (use (match_operand:HI 3 "memory_operand" ""))
4414 (clobber (match_operand:DI 4 "memory_operand" ""))
4415 (clobber (match_scratch 5 ""))]
4417 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4420 (clobber (match_dup 5))])]
4423 (define_insn "fix_trunc<mode>_i387"
4424 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4425 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4426 (use (match_operand:HI 2 "memory_operand" "m"))
4427 (use (match_operand:HI 3 "memory_operand" "m"))]
4428 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4430 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4431 "* return output_fix_trunc (insn, operands, 0);"
4432 [(set_attr "type" "fistp")
4433 (set_attr "i387_cw" "trunc")
4434 (set_attr "mode" "<MODE>")])
4436 (define_insn "fix_trunc<mode>_i387_with_temp"
4437 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4438 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4439 (use (match_operand:HI 2 "memory_operand" "m,m"))
4440 (use (match_operand:HI 3 "memory_operand" "m,m"))
4441 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4442 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4446 [(set_attr "type" "fistp")
4447 (set_attr "i387_cw" "trunc")
4448 (set_attr "mode" "<MODE>")])
4451 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4452 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4453 (use (match_operand:HI 2 "memory_operand" ""))
4454 (use (match_operand:HI 3 "memory_operand" ""))
4455 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4457 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4459 (use (match_dup 3))])
4460 (set (match_dup 0) (match_dup 4))]
4464 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4465 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4466 (use (match_operand:HI 2 "memory_operand" ""))
4467 (use (match_operand:HI 3 "memory_operand" ""))
4468 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4470 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4472 (use (match_dup 3))])]
4475 (define_insn "x86_fnstcw_1"
4476 [(set (match_operand:HI 0 "memory_operand" "=m")
4477 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4480 [(set_attr "length" "2")
4481 (set_attr "mode" "HI")
4482 (set_attr "unit" "i387")])
4484 (define_insn "x86_fldcw_1"
4485 [(set (reg:HI FPCR_REG)
4486 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4489 [(set_attr "length" "2")
4490 (set_attr "mode" "HI")
4491 (set_attr "unit" "i387")
4492 (set_attr "athlon_decode" "vector")
4493 (set_attr "amdfam10_decode" "vector")])
4495 ;; Conversion between fixed point and floating point.
4497 ;; Even though we only accept memory inputs, the backend _really_
4498 ;; wants to be able to do this between registers.
4500 (define_expand "floathi<mode>2"
4501 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4502 (float:SSEMODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4503 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4505 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4508 (gen_floatsi<mode>2 (operands[0],
4509 convert_to_mode (SImode, operands[1], 0)));
4514 (define_insn "*floathi<mode>2_i387"
4515 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4517 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4519 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4520 || TARGET_MIX_SSE_I387)"
4524 [(set_attr "type" "fmov,multi")
4525 (set_attr "mode" "<MODE>")
4526 (set_attr "unit" "*,i387")
4527 (set_attr "fp_int_src" "true")])
4529 (define_expand "floatsi<mode>2"
4530 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4531 (float:SSEMODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4532 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4535 (define_insn "*floatsisf2_mixed"
4536 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4537 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4538 "TARGET_MIX_SSE_I387"
4542 cvtsi2ss\t{%1, %0|%0, %1}
4543 cvtsi2ss\t{%1, %0|%0, %1}"
4544 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4545 (set_attr "mode" "SF")
4546 (set_attr "unit" "*,i387,*,*")
4547 (set_attr "athlon_decode" "*,*,vector,double")
4548 (set_attr "amdfam10_decode" "*,*,vector,double")
4549 (set_attr "fp_int_src" "true")])
4551 (define_insn "*floatsisf2_sse"
4552 [(set (match_operand:SF 0 "register_operand" "=x,x")
4553 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4555 "cvtsi2ss\t{%1, %0|%0, %1}"
4556 [(set_attr "type" "sseicvt")
4557 (set_attr "mode" "SF")
4558 (set_attr "athlon_decode" "vector,double")
4559 (set_attr "amdfam10_decode" "vector,double")
4560 (set_attr "fp_int_src" "true")])
4562 (define_insn "*floatsidf2_mixed"
4563 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4564 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4565 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4569 cvtsi2sd\t{%1, %0|%0, %1}
4570 cvtsi2sd\t{%1, %0|%0, %1}"
4571 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4572 (set_attr "mode" "DF")
4573 (set_attr "unit" "*,i387,*,*")
4574 (set_attr "athlon_decode" "*,*,double,direct")
4575 (set_attr "amdfam10_decode" "*,*,vector,double")
4576 (set_attr "fp_int_src" "true")])
4578 (define_insn "*floatsidf2_sse"
4579 [(set (match_operand:DF 0 "register_operand" "=x,x")
4580 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4581 "TARGET_SSE2 && TARGET_SSE_MATH"
4582 "cvtsi2sd\t{%1, %0|%0, %1}"
4583 [(set_attr "type" "sseicvt")
4584 (set_attr "mode" "DF")
4585 (set_attr "athlon_decode" "double,direct")
4586 (set_attr "amdfam10_decode" "vector,double")
4587 (set_attr "fp_int_src" "true")])
4589 (define_insn "*floatsi<mode>2_i387"
4590 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4592 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4597 [(set_attr "type" "fmov,multi")
4598 (set_attr "mode" "<MODE>")
4599 (set_attr "unit" "*,i387")
4600 (set_attr "fp_int_src" "true")])
4602 (define_expand "floatdisf2"
4603 [(set (match_operand:SF 0 "register_operand" "")
4604 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4605 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4608 (define_insn "*floatdisf2_mixed"
4609 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4610 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4611 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4615 cvtsi2ss{q}\t{%1, %0|%0, %1}
4616 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4617 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4618 (set_attr "mode" "SF")
4619 (set_attr "unit" "*,i387,*,*")
4620 (set_attr "athlon_decode" "*,*,vector,double")
4621 (set_attr "amdfam10_decode" "*,*,vector,double")
4622 (set_attr "fp_int_src" "true")])
4624 (define_insn "*floatdisf2_sse"
4625 [(set (match_operand:SF 0 "register_operand" "=x,x")
4626 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4627 "TARGET_64BIT && TARGET_SSE_MATH"
4628 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4629 [(set_attr "type" "sseicvt")
4630 (set_attr "mode" "SF")
4631 (set_attr "athlon_decode" "vector,double")
4632 (set_attr "amdfam10_decode" "vector,double")
4633 (set_attr "fp_int_src" "true")])
4635 (define_expand "floatdidf2"
4636 [(set (match_operand:DF 0 "register_operand" "")
4637 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4638 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4640 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4642 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4647 (define_insn "*floatdidf2_mixed"
4648 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4649 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4650 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4654 cvtsi2sd{q}\t{%1, %0|%0, %1}
4655 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4656 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4657 (set_attr "mode" "DF")
4658 (set_attr "unit" "*,i387,*,*")
4659 (set_attr "athlon_decode" "*,*,double,direct")
4660 (set_attr "amdfam10_decode" "*,*,vector,double")
4661 (set_attr "fp_int_src" "true")])
4663 (define_insn "*floatdidf2_sse"
4664 [(set (match_operand:DF 0 "register_operand" "=x,x")
4665 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4666 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4667 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4668 [(set_attr "type" "sseicvt")
4669 (set_attr "mode" "DF")
4670 (set_attr "athlon_decode" "double,direct")
4671 (set_attr "amdfam10_decode" "vector,double")
4672 (set_attr "fp_int_src" "true")])
4674 (define_insn "*floatdi<mode>2_i387"
4675 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4677 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4682 [(set_attr "type" "fmov,multi")
4683 (set_attr "mode" "<MODE>")
4684 (set_attr "unit" "*,i387")
4685 (set_attr "fp_int_src" "true")])
4687 (define_insn "float<mode>xf2"
4688 [(set (match_operand:XF 0 "register_operand" "=f,f")
4689 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
4694 [(set_attr "type" "fmov,multi")
4695 (set_attr "mode" "XF")
4696 (set_attr "unit" "*,i387")
4697 (set_attr "fp_int_src" "true")])
4699 ;; %%% Kill these when reload knows how to do it.
4701 [(set (match_operand 0 "fp_register_operand" "")
4702 (float (match_operand 1 "register_operand" "")))]
4704 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
4707 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4708 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4709 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4710 ix86_free_from_memory (GET_MODE (operands[1]));
4714 (define_expand "floatunssisf2"
4715 [(use (match_operand:SF 0 "register_operand" ""))
4716 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4719 if (TARGET_SSE_MATH && TARGET_SSE2)
4720 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4722 x86_emit_floatuns (operands);
4726 (define_expand "floatunssidf2"
4727 [(use (match_operand:DF 0 "register_operand" ""))
4728 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4729 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4730 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
4732 (define_expand "floatunsdisf2"
4733 [(use (match_operand:SF 0 "register_operand" ""))
4734 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4735 "TARGET_64BIT && TARGET_SSE_MATH"
4736 "x86_emit_floatuns (operands); DONE;")
4738 (define_expand "floatunsdidf2"
4739 [(use (match_operand:DF 0 "register_operand" ""))
4740 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4741 "TARGET_SSE_MATH && TARGET_SSE2
4742 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
4745 x86_emit_floatuns (operands);
4747 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
4753 ;; %%% splits for addditi3
4755 (define_expand "addti3"
4756 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4757 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4758 (match_operand:TI 2 "x86_64_general_operand" "")))
4759 (clobber (reg:CC FLAGS_REG))]
4761 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4763 (define_insn "*addti3_1"
4764 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4765 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4766 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4767 (clobber (reg:CC FLAGS_REG))]
4768 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4772 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4773 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4774 (match_operand:TI 2 "x86_64_general_operand" "")))
4775 (clobber (reg:CC FLAGS_REG))]
4776 "TARGET_64BIT && reload_completed"
4777 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4779 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4780 (parallel [(set (match_dup 3)
4781 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4784 (clobber (reg:CC FLAGS_REG))])]
4785 "split_ti (operands+0, 1, operands+0, operands+3);
4786 split_ti (operands+1, 1, operands+1, operands+4);
4787 split_ti (operands+2, 1, operands+2, operands+5);")
4789 ;; %%% splits for addsidi3
4790 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4791 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4792 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4794 (define_expand "adddi3"
4795 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4796 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4797 (match_operand:DI 2 "x86_64_general_operand" "")))
4798 (clobber (reg:CC FLAGS_REG))]
4800 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4802 (define_insn "*adddi3_1"
4803 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4804 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4805 (match_operand:DI 2 "general_operand" "roiF,riF")))
4806 (clobber (reg:CC FLAGS_REG))]
4807 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4811 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4812 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4813 (match_operand:DI 2 "general_operand" "")))
4814 (clobber (reg:CC FLAGS_REG))]
4815 "!TARGET_64BIT && reload_completed"
4816 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4818 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4819 (parallel [(set (match_dup 3)
4820 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4823 (clobber (reg:CC FLAGS_REG))])]
4824 "split_di (operands+0, 1, operands+0, operands+3);
4825 split_di (operands+1, 1, operands+1, operands+4);
4826 split_di (operands+2, 1, operands+2, operands+5);")
4828 (define_insn "adddi3_carry_rex64"
4829 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4830 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4831 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4832 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4833 (clobber (reg:CC FLAGS_REG))]
4834 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4835 "adc{q}\t{%2, %0|%0, %2}"
4836 [(set_attr "type" "alu")
4837 (set_attr "pent_pair" "pu")
4838 (set_attr "mode" "DI")])
4840 (define_insn "*adddi3_cc_rex64"
4841 [(set (reg:CC FLAGS_REG)
4842 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4843 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4845 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4846 (plus:DI (match_dup 1) (match_dup 2)))]
4847 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4848 "add{q}\t{%2, %0|%0, %2}"
4849 [(set_attr "type" "alu")
4850 (set_attr "mode" "DI")])
4852 (define_insn "addqi3_carry"
4853 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4854 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4855 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4856 (match_operand:QI 2 "general_operand" "qi,qm")))
4857 (clobber (reg:CC FLAGS_REG))]
4858 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4859 "adc{b}\t{%2, %0|%0, %2}"
4860 [(set_attr "type" "alu")
4861 (set_attr "pent_pair" "pu")
4862 (set_attr "mode" "QI")])
4864 (define_insn "addhi3_carry"
4865 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4866 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4867 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4868 (match_operand:HI 2 "general_operand" "ri,rm")))
4869 (clobber (reg:CC FLAGS_REG))]
4870 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4871 "adc{w}\t{%2, %0|%0, %2}"
4872 [(set_attr "type" "alu")
4873 (set_attr "pent_pair" "pu")
4874 (set_attr "mode" "HI")])
4876 (define_insn "addsi3_carry"
4877 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4878 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4879 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4880 (match_operand:SI 2 "general_operand" "ri,rm")))
4881 (clobber (reg:CC FLAGS_REG))]
4882 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4883 "adc{l}\t{%2, %0|%0, %2}"
4884 [(set_attr "type" "alu")
4885 (set_attr "pent_pair" "pu")
4886 (set_attr "mode" "SI")])
4888 (define_insn "*addsi3_carry_zext"
4889 [(set (match_operand:DI 0 "register_operand" "=r")
4891 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4892 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4893 (match_operand:SI 2 "general_operand" "rim"))))
4894 (clobber (reg:CC FLAGS_REG))]
4895 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4896 "adc{l}\t{%2, %k0|%k0, %2}"
4897 [(set_attr "type" "alu")
4898 (set_attr "pent_pair" "pu")
4899 (set_attr "mode" "SI")])
4901 (define_insn "*addsi3_cc"
4902 [(set (reg:CC FLAGS_REG)
4903 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4904 (match_operand:SI 2 "general_operand" "ri,rm")]
4906 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4907 (plus:SI (match_dup 1) (match_dup 2)))]
4908 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4909 "add{l}\t{%2, %0|%0, %2}"
4910 [(set_attr "type" "alu")
4911 (set_attr "mode" "SI")])
4913 (define_insn "addqi3_cc"
4914 [(set (reg:CC FLAGS_REG)
4915 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4916 (match_operand:QI 2 "general_operand" "qi,qm")]
4918 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4919 (plus:QI (match_dup 1) (match_dup 2)))]
4920 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4921 "add{b}\t{%2, %0|%0, %2}"
4922 [(set_attr "type" "alu")
4923 (set_attr "mode" "QI")])
4925 (define_expand "addsi3"
4926 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4927 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4928 (match_operand:SI 2 "general_operand" "")))
4929 (clobber (reg:CC FLAGS_REG))])]
4931 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4933 (define_insn "*lea_1"
4934 [(set (match_operand:SI 0 "register_operand" "=r")
4935 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4937 "lea{l}\t{%a1, %0|%0, %a1}"
4938 [(set_attr "type" "lea")
4939 (set_attr "mode" "SI")])
4941 (define_insn "*lea_1_rex64"
4942 [(set (match_operand:SI 0 "register_operand" "=r")
4943 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4945 "lea{l}\t{%a1, %0|%0, %a1}"
4946 [(set_attr "type" "lea")
4947 (set_attr "mode" "SI")])
4949 (define_insn "*lea_1_zext"
4950 [(set (match_operand:DI 0 "register_operand" "=r")
4952 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4954 "lea{l}\t{%a1, %k0|%k0, %a1}"
4955 [(set_attr "type" "lea")
4956 (set_attr "mode" "SI")])
4958 (define_insn "*lea_2_rex64"
4959 [(set (match_operand:DI 0 "register_operand" "=r")
4960 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4962 "lea{q}\t{%a1, %0|%0, %a1}"
4963 [(set_attr "type" "lea")
4964 (set_attr "mode" "DI")])
4966 ;; The lea patterns for non-Pmodes needs to be matched by several
4967 ;; insns converted to real lea by splitters.
4969 (define_insn_and_split "*lea_general_1"
4970 [(set (match_operand 0 "register_operand" "=r")
4971 (plus (plus (match_operand 1 "index_register_operand" "l")
4972 (match_operand 2 "register_operand" "r"))
4973 (match_operand 3 "immediate_operand" "i")))]
4974 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4975 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4976 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4977 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4978 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4979 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4980 || GET_MODE (operands[3]) == VOIDmode)"
4982 "&& reload_completed"
4986 operands[0] = gen_lowpart (SImode, operands[0]);
4987 operands[1] = gen_lowpart (Pmode, operands[1]);
4988 operands[2] = gen_lowpart (Pmode, operands[2]);
4989 operands[3] = gen_lowpart (Pmode, operands[3]);
4990 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4992 if (Pmode != SImode)
4993 pat = gen_rtx_SUBREG (SImode, pat, 0);
4994 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4997 [(set_attr "type" "lea")
4998 (set_attr "mode" "SI")])
5000 (define_insn_and_split "*lea_general_1_zext"
5001 [(set (match_operand:DI 0 "register_operand" "=r")
5003 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5004 (match_operand:SI 2 "register_operand" "r"))
5005 (match_operand:SI 3 "immediate_operand" "i"))))]
5008 "&& reload_completed"
5010 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5012 (match_dup 3)) 0)))]
5014 operands[1] = gen_lowpart (Pmode, operands[1]);
5015 operands[2] = gen_lowpart (Pmode, operands[2]);
5016 operands[3] = gen_lowpart (Pmode, operands[3]);
5018 [(set_attr "type" "lea")
5019 (set_attr "mode" "SI")])
5021 (define_insn_and_split "*lea_general_2"
5022 [(set (match_operand 0 "register_operand" "=r")
5023 (plus (mult (match_operand 1 "index_register_operand" "l")
5024 (match_operand 2 "const248_operand" "i"))
5025 (match_operand 3 "nonmemory_operand" "ri")))]
5026 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5027 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5028 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5029 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5030 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5031 || GET_MODE (operands[3]) == VOIDmode)"
5033 "&& reload_completed"
5037 operands[0] = gen_lowpart (SImode, operands[0]);
5038 operands[1] = gen_lowpart (Pmode, operands[1]);
5039 operands[3] = gen_lowpart (Pmode, operands[3]);
5040 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5042 if (Pmode != SImode)
5043 pat = gen_rtx_SUBREG (SImode, pat, 0);
5044 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5047 [(set_attr "type" "lea")
5048 (set_attr "mode" "SI")])
5050 (define_insn_and_split "*lea_general_2_zext"
5051 [(set (match_operand:DI 0 "register_operand" "=r")
5053 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5054 (match_operand:SI 2 "const248_operand" "n"))
5055 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5058 "&& reload_completed"
5060 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5062 (match_dup 3)) 0)))]
5064 operands[1] = gen_lowpart (Pmode, operands[1]);
5065 operands[3] = gen_lowpart (Pmode, operands[3]);
5067 [(set_attr "type" "lea")
5068 (set_attr "mode" "SI")])
5070 (define_insn_and_split "*lea_general_3"
5071 [(set (match_operand 0 "register_operand" "=r")
5072 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5073 (match_operand 2 "const248_operand" "i"))
5074 (match_operand 3 "register_operand" "r"))
5075 (match_operand 4 "immediate_operand" "i")))]
5076 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5077 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5078 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5079 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5080 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5082 "&& reload_completed"
5086 operands[0] = gen_lowpart (SImode, operands[0]);
5087 operands[1] = gen_lowpart (Pmode, operands[1]);
5088 operands[3] = gen_lowpart (Pmode, operands[3]);
5089 operands[4] = gen_lowpart (Pmode, operands[4]);
5090 pat = gen_rtx_PLUS (Pmode,
5091 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5095 if (Pmode != SImode)
5096 pat = gen_rtx_SUBREG (SImode, pat, 0);
5097 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5100 [(set_attr "type" "lea")
5101 (set_attr "mode" "SI")])
5103 (define_insn_and_split "*lea_general_3_zext"
5104 [(set (match_operand:DI 0 "register_operand" "=r")
5106 (plus:SI (plus:SI (mult:SI
5107 (match_operand:SI 1 "index_register_operand" "l")
5108 (match_operand:SI 2 "const248_operand" "n"))
5109 (match_operand:SI 3 "register_operand" "r"))
5110 (match_operand:SI 4 "immediate_operand" "i"))))]
5113 "&& reload_completed"
5115 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5118 (match_dup 4)) 0)))]
5120 operands[1] = gen_lowpart (Pmode, operands[1]);
5121 operands[3] = gen_lowpart (Pmode, operands[3]);
5122 operands[4] = gen_lowpart (Pmode, operands[4]);
5124 [(set_attr "type" "lea")
5125 (set_attr "mode" "SI")])
5127 (define_insn "*adddi_1_rex64"
5128 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5129 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5130 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5131 (clobber (reg:CC FLAGS_REG))]
5132 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5134 switch (get_attr_type (insn))
5137 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5138 return "lea{q}\t{%a2, %0|%0, %a2}";
5141 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5142 if (operands[2] == const1_rtx)
5143 return "inc{q}\t%0";
5146 gcc_assert (operands[2] == constm1_rtx);
5147 return "dec{q}\t%0";
5151 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5153 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5154 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5155 if (CONST_INT_P (operands[2])
5156 /* Avoid overflows. */
5157 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5158 && (INTVAL (operands[2]) == 128
5159 || (INTVAL (operands[2]) < 0
5160 && INTVAL (operands[2]) != -128)))
5162 operands[2] = GEN_INT (-INTVAL (operands[2]));
5163 return "sub{q}\t{%2, %0|%0, %2}";
5165 return "add{q}\t{%2, %0|%0, %2}";
5169 (cond [(eq_attr "alternative" "2")
5170 (const_string "lea")
5171 ; Current assemblers are broken and do not allow @GOTOFF in
5172 ; ought but a memory context.
5173 (match_operand:DI 2 "pic_symbolic_operand" "")
5174 (const_string "lea")
5175 (match_operand:DI 2 "incdec_operand" "")
5176 (const_string "incdec")
5178 (const_string "alu")))
5179 (set_attr "mode" "DI")])
5181 ;; Convert lea to the lea pattern to avoid flags dependency.
5183 [(set (match_operand:DI 0 "register_operand" "")
5184 (plus:DI (match_operand:DI 1 "register_operand" "")
5185 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5186 (clobber (reg:CC FLAGS_REG))]
5187 "TARGET_64BIT && reload_completed
5188 && true_regnum (operands[0]) != true_regnum (operands[1])"
5190 (plus:DI (match_dup 1)
5194 (define_insn "*adddi_2_rex64"
5195 [(set (reg FLAGS_REG)
5197 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5198 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5200 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5201 (plus:DI (match_dup 1) (match_dup 2)))]
5202 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5203 && ix86_binary_operator_ok (PLUS, DImode, operands)
5204 /* Current assemblers are broken and do not allow @GOTOFF in
5205 ought but a memory context. */
5206 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5208 switch (get_attr_type (insn))
5211 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5212 if (operands[2] == const1_rtx)
5213 return "inc{q}\t%0";
5216 gcc_assert (operands[2] == constm1_rtx);
5217 return "dec{q}\t%0";
5221 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5222 /* ???? We ought to handle there the 32bit case too
5223 - do we need new constraint? */
5224 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5225 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5226 if (CONST_INT_P (operands[2])
5227 /* Avoid overflows. */
5228 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5229 && (INTVAL (operands[2]) == 128
5230 || (INTVAL (operands[2]) < 0
5231 && INTVAL (operands[2]) != -128)))
5233 operands[2] = GEN_INT (-INTVAL (operands[2]));
5234 return "sub{q}\t{%2, %0|%0, %2}";
5236 return "add{q}\t{%2, %0|%0, %2}";
5240 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5241 (const_string "incdec")
5242 (const_string "alu")))
5243 (set_attr "mode" "DI")])
5245 (define_insn "*adddi_3_rex64"
5246 [(set (reg FLAGS_REG)
5247 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5248 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5249 (clobber (match_scratch:DI 0 "=r"))]
5251 && ix86_match_ccmode (insn, CCZmode)
5252 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5253 /* Current assemblers are broken and do not allow @GOTOFF in
5254 ought but a memory context. */
5255 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5257 switch (get_attr_type (insn))
5260 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5261 if (operands[2] == const1_rtx)
5262 return "inc{q}\t%0";
5265 gcc_assert (operands[2] == constm1_rtx);
5266 return "dec{q}\t%0";
5270 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5271 /* ???? We ought to handle there the 32bit case too
5272 - do we need new constraint? */
5273 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5274 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5275 if (CONST_INT_P (operands[2])
5276 /* Avoid overflows. */
5277 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5278 && (INTVAL (operands[2]) == 128
5279 || (INTVAL (operands[2]) < 0
5280 && INTVAL (operands[2]) != -128)))
5282 operands[2] = GEN_INT (-INTVAL (operands[2]));
5283 return "sub{q}\t{%2, %0|%0, %2}";
5285 return "add{q}\t{%2, %0|%0, %2}";
5289 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5290 (const_string "incdec")
5291 (const_string "alu")))
5292 (set_attr "mode" "DI")])
5294 ; For comparisons against 1, -1 and 128, we may generate better code
5295 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5296 ; is matched then. We can't accept general immediate, because for
5297 ; case of overflows, the result is messed up.
5298 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5300 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5301 ; only for comparisons not depending on it.
5302 (define_insn "*adddi_4_rex64"
5303 [(set (reg FLAGS_REG)
5304 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5305 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5306 (clobber (match_scratch:DI 0 "=rm"))]
5308 && ix86_match_ccmode (insn, CCGCmode)"
5310 switch (get_attr_type (insn))
5313 if (operands[2] == constm1_rtx)
5314 return "inc{q}\t%0";
5317 gcc_assert (operands[2] == const1_rtx);
5318 return "dec{q}\t%0";
5322 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5323 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5324 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5325 if ((INTVAL (operands[2]) == -128
5326 || (INTVAL (operands[2]) > 0
5327 && INTVAL (operands[2]) != 128))
5328 /* Avoid overflows. */
5329 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5330 return "sub{q}\t{%2, %0|%0, %2}";
5331 operands[2] = GEN_INT (-INTVAL (operands[2]));
5332 return "add{q}\t{%2, %0|%0, %2}";
5336 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5337 (const_string "incdec")
5338 (const_string "alu")))
5339 (set_attr "mode" "DI")])
5341 (define_insn "*adddi_5_rex64"
5342 [(set (reg FLAGS_REG)
5344 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5345 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5347 (clobber (match_scratch:DI 0 "=r"))]
5349 && ix86_match_ccmode (insn, CCGOCmode)
5350 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5351 /* Current assemblers are broken and do not allow @GOTOFF in
5352 ought but a memory context. */
5353 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5355 switch (get_attr_type (insn))
5358 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5359 if (operands[2] == const1_rtx)
5360 return "inc{q}\t%0";
5363 gcc_assert (operands[2] == constm1_rtx);
5364 return "dec{q}\t%0";
5368 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5369 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5370 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5371 if (CONST_INT_P (operands[2])
5372 /* Avoid overflows. */
5373 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5374 && (INTVAL (operands[2]) == 128
5375 || (INTVAL (operands[2]) < 0
5376 && INTVAL (operands[2]) != -128)))
5378 operands[2] = GEN_INT (-INTVAL (operands[2]));
5379 return "sub{q}\t{%2, %0|%0, %2}";
5381 return "add{q}\t{%2, %0|%0, %2}";
5385 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5386 (const_string "incdec")
5387 (const_string "alu")))
5388 (set_attr "mode" "DI")])
5391 (define_insn "*addsi_1"
5392 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5393 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5394 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5395 (clobber (reg:CC FLAGS_REG))]
5396 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5398 switch (get_attr_type (insn))
5401 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5402 return "lea{l}\t{%a2, %0|%0, %a2}";
5405 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5406 if (operands[2] == const1_rtx)
5407 return "inc{l}\t%0";
5410 gcc_assert (operands[2] == constm1_rtx);
5411 return "dec{l}\t%0";
5415 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5417 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5418 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5419 if (CONST_INT_P (operands[2])
5420 && (INTVAL (operands[2]) == 128
5421 || (INTVAL (operands[2]) < 0
5422 && INTVAL (operands[2]) != -128)))
5424 operands[2] = GEN_INT (-INTVAL (operands[2]));
5425 return "sub{l}\t{%2, %0|%0, %2}";
5427 return "add{l}\t{%2, %0|%0, %2}";
5431 (cond [(eq_attr "alternative" "2")
5432 (const_string "lea")
5433 ; Current assemblers are broken and do not allow @GOTOFF in
5434 ; ought but a memory context.
5435 (match_operand:SI 2 "pic_symbolic_operand" "")
5436 (const_string "lea")
5437 (match_operand:SI 2 "incdec_operand" "")
5438 (const_string "incdec")
5440 (const_string "alu")))
5441 (set_attr "mode" "SI")])
5443 ;; Convert lea to the lea pattern to avoid flags dependency.
5445 [(set (match_operand 0 "register_operand" "")
5446 (plus (match_operand 1 "register_operand" "")
5447 (match_operand 2 "nonmemory_operand" "")))
5448 (clobber (reg:CC FLAGS_REG))]
5450 && true_regnum (operands[0]) != true_regnum (operands[1])"
5454 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5455 may confuse gen_lowpart. */
5456 if (GET_MODE (operands[0]) != Pmode)
5458 operands[1] = gen_lowpart (Pmode, operands[1]);
5459 operands[2] = gen_lowpart (Pmode, operands[2]);
5461 operands[0] = gen_lowpart (SImode, operands[0]);
5462 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5463 if (Pmode != SImode)
5464 pat = gen_rtx_SUBREG (SImode, pat, 0);
5465 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5469 ;; It may seem that nonimmediate operand is proper one for operand 1.
5470 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5471 ;; we take care in ix86_binary_operator_ok to not allow two memory
5472 ;; operands so proper swapping will be done in reload. This allow
5473 ;; patterns constructed from addsi_1 to match.
5474 (define_insn "addsi_1_zext"
5475 [(set (match_operand:DI 0 "register_operand" "=r,r")
5477 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5478 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5479 (clobber (reg:CC FLAGS_REG))]
5480 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5482 switch (get_attr_type (insn))
5485 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5486 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5489 if (operands[2] == const1_rtx)
5490 return "inc{l}\t%k0";
5493 gcc_assert (operands[2] == constm1_rtx);
5494 return "dec{l}\t%k0";
5498 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5499 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5500 if (CONST_INT_P (operands[2])
5501 && (INTVAL (operands[2]) == 128
5502 || (INTVAL (operands[2]) < 0
5503 && INTVAL (operands[2]) != -128)))
5505 operands[2] = GEN_INT (-INTVAL (operands[2]));
5506 return "sub{l}\t{%2, %k0|%k0, %2}";
5508 return "add{l}\t{%2, %k0|%k0, %2}";
5512 (cond [(eq_attr "alternative" "1")
5513 (const_string "lea")
5514 ; Current assemblers are broken and do not allow @GOTOFF in
5515 ; ought but a memory context.
5516 (match_operand:SI 2 "pic_symbolic_operand" "")
5517 (const_string "lea")
5518 (match_operand:SI 2 "incdec_operand" "")
5519 (const_string "incdec")
5521 (const_string "alu")))
5522 (set_attr "mode" "SI")])
5524 ;; Convert lea to the lea pattern to avoid flags dependency.
5526 [(set (match_operand:DI 0 "register_operand" "")
5528 (plus:SI (match_operand:SI 1 "register_operand" "")
5529 (match_operand:SI 2 "nonmemory_operand" ""))))
5530 (clobber (reg:CC FLAGS_REG))]
5531 "TARGET_64BIT && reload_completed
5532 && true_regnum (operands[0]) != true_regnum (operands[1])"
5534 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5536 operands[1] = gen_lowpart (Pmode, operands[1]);
5537 operands[2] = gen_lowpart (Pmode, operands[2]);
5540 (define_insn "*addsi_2"
5541 [(set (reg FLAGS_REG)
5543 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5544 (match_operand:SI 2 "general_operand" "rmni,rni"))
5546 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5547 (plus:SI (match_dup 1) (match_dup 2)))]
5548 "ix86_match_ccmode (insn, CCGOCmode)
5549 && ix86_binary_operator_ok (PLUS, SImode, operands)
5550 /* Current assemblers are broken and do not allow @GOTOFF in
5551 ought but a memory context. */
5552 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5554 switch (get_attr_type (insn))
5557 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5558 if (operands[2] == const1_rtx)
5559 return "inc{l}\t%0";
5562 gcc_assert (operands[2] == constm1_rtx);
5563 return "dec{l}\t%0";
5567 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5568 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5569 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5570 if (CONST_INT_P (operands[2])
5571 && (INTVAL (operands[2]) == 128
5572 || (INTVAL (operands[2]) < 0
5573 && INTVAL (operands[2]) != -128)))
5575 operands[2] = GEN_INT (-INTVAL (operands[2]));
5576 return "sub{l}\t{%2, %0|%0, %2}";
5578 return "add{l}\t{%2, %0|%0, %2}";
5582 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5583 (const_string "incdec")
5584 (const_string "alu")))
5585 (set_attr "mode" "SI")])
5587 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5588 (define_insn "*addsi_2_zext"
5589 [(set (reg FLAGS_REG)
5591 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5592 (match_operand:SI 2 "general_operand" "rmni"))
5594 (set (match_operand:DI 0 "register_operand" "=r")
5595 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5596 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5597 && ix86_binary_operator_ok (PLUS, SImode, operands)
5598 /* Current assemblers are broken and do not allow @GOTOFF in
5599 ought but a memory context. */
5600 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5602 switch (get_attr_type (insn))
5605 if (operands[2] == const1_rtx)
5606 return "inc{l}\t%k0";
5609 gcc_assert (operands[2] == constm1_rtx);
5610 return "dec{l}\t%k0";
5614 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5615 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5616 if (CONST_INT_P (operands[2])
5617 && (INTVAL (operands[2]) == 128
5618 || (INTVAL (operands[2]) < 0
5619 && INTVAL (operands[2]) != -128)))
5621 operands[2] = GEN_INT (-INTVAL (operands[2]));
5622 return "sub{l}\t{%2, %k0|%k0, %2}";
5624 return "add{l}\t{%2, %k0|%k0, %2}";
5628 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5629 (const_string "incdec")
5630 (const_string "alu")))
5631 (set_attr "mode" "SI")])
5633 (define_insn "*addsi_3"
5634 [(set (reg FLAGS_REG)
5635 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5636 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5637 (clobber (match_scratch:SI 0 "=r"))]
5638 "ix86_match_ccmode (insn, CCZmode)
5639 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5640 /* Current assemblers are broken and do not allow @GOTOFF in
5641 ought but a memory context. */
5642 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5644 switch (get_attr_type (insn))
5647 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5648 if (operands[2] == const1_rtx)
5649 return "inc{l}\t%0";
5652 gcc_assert (operands[2] == constm1_rtx);
5653 return "dec{l}\t%0";
5657 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5659 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5660 if (CONST_INT_P (operands[2])
5661 && (INTVAL (operands[2]) == 128
5662 || (INTVAL (operands[2]) < 0
5663 && INTVAL (operands[2]) != -128)))
5665 operands[2] = GEN_INT (-INTVAL (operands[2]));
5666 return "sub{l}\t{%2, %0|%0, %2}";
5668 return "add{l}\t{%2, %0|%0, %2}";
5672 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5673 (const_string "incdec")
5674 (const_string "alu")))
5675 (set_attr "mode" "SI")])
5677 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5678 (define_insn "*addsi_3_zext"
5679 [(set (reg FLAGS_REG)
5680 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5681 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5682 (set (match_operand:DI 0 "register_operand" "=r")
5683 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5684 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5685 && ix86_binary_operator_ok (PLUS, SImode, operands)
5686 /* Current assemblers are broken and do not allow @GOTOFF in
5687 ought but a memory context. */
5688 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5690 switch (get_attr_type (insn))
5693 if (operands[2] == const1_rtx)
5694 return "inc{l}\t%k0";
5697 gcc_assert (operands[2] == constm1_rtx);
5698 return "dec{l}\t%k0";
5702 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5703 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5704 if (CONST_INT_P (operands[2])
5705 && (INTVAL (operands[2]) == 128
5706 || (INTVAL (operands[2]) < 0
5707 && INTVAL (operands[2]) != -128)))
5709 operands[2] = GEN_INT (-INTVAL (operands[2]));
5710 return "sub{l}\t{%2, %k0|%k0, %2}";
5712 return "add{l}\t{%2, %k0|%k0, %2}";
5716 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5717 (const_string "incdec")
5718 (const_string "alu")))
5719 (set_attr "mode" "SI")])
5721 ; For comparisons against 1, -1 and 128, we may generate better code
5722 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5723 ; is matched then. We can't accept general immediate, because for
5724 ; case of overflows, the result is messed up.
5725 ; This pattern also don't hold of 0x80000000, since the value overflows
5727 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5728 ; only for comparisons not depending on it.
5729 (define_insn "*addsi_4"
5730 [(set (reg FLAGS_REG)
5731 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5732 (match_operand:SI 2 "const_int_operand" "n")))
5733 (clobber (match_scratch:SI 0 "=rm"))]
5734 "ix86_match_ccmode (insn, CCGCmode)
5735 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5737 switch (get_attr_type (insn))
5740 if (operands[2] == constm1_rtx)
5741 return "inc{l}\t%0";
5744 gcc_assert (operands[2] == const1_rtx);
5745 return "dec{l}\t%0";
5749 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5750 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5751 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5752 if ((INTVAL (operands[2]) == -128
5753 || (INTVAL (operands[2]) > 0
5754 && INTVAL (operands[2]) != 128)))
5755 return "sub{l}\t{%2, %0|%0, %2}";
5756 operands[2] = GEN_INT (-INTVAL (operands[2]));
5757 return "add{l}\t{%2, %0|%0, %2}";
5761 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5762 (const_string "incdec")
5763 (const_string "alu")))
5764 (set_attr "mode" "SI")])
5766 (define_insn "*addsi_5"
5767 [(set (reg FLAGS_REG)
5769 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5770 (match_operand:SI 2 "general_operand" "rmni"))
5772 (clobber (match_scratch:SI 0 "=r"))]
5773 "ix86_match_ccmode (insn, CCGOCmode)
5774 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5775 /* Current assemblers are broken and do not allow @GOTOFF in
5776 ought but a memory context. */
5777 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5779 switch (get_attr_type (insn))
5782 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5783 if (operands[2] == const1_rtx)
5784 return "inc{l}\t%0";
5787 gcc_assert (operands[2] == constm1_rtx);
5788 return "dec{l}\t%0";
5792 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5793 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5794 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5795 if (CONST_INT_P (operands[2])
5796 && (INTVAL (operands[2]) == 128
5797 || (INTVAL (operands[2]) < 0
5798 && INTVAL (operands[2]) != -128)))
5800 operands[2] = GEN_INT (-INTVAL (operands[2]));
5801 return "sub{l}\t{%2, %0|%0, %2}";
5803 return "add{l}\t{%2, %0|%0, %2}";
5807 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5808 (const_string "incdec")
5809 (const_string "alu")))
5810 (set_attr "mode" "SI")])
5812 (define_expand "addhi3"
5813 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5814 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5815 (match_operand:HI 2 "general_operand" "")))
5816 (clobber (reg:CC FLAGS_REG))])]
5817 "TARGET_HIMODE_MATH"
5818 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5820 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5821 ;; type optimizations enabled by define-splits. This is not important
5822 ;; for PII, and in fact harmful because of partial register stalls.
5824 (define_insn "*addhi_1_lea"
5825 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5826 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5827 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5828 (clobber (reg:CC FLAGS_REG))]
5829 "!TARGET_PARTIAL_REG_STALL
5830 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5832 switch (get_attr_type (insn))
5837 if (operands[2] == const1_rtx)
5838 return "inc{w}\t%0";
5841 gcc_assert (operands[2] == constm1_rtx);
5842 return "dec{w}\t%0";
5846 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5847 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5848 if (CONST_INT_P (operands[2])
5849 && (INTVAL (operands[2]) == 128
5850 || (INTVAL (operands[2]) < 0
5851 && INTVAL (operands[2]) != -128)))
5853 operands[2] = GEN_INT (-INTVAL (operands[2]));
5854 return "sub{w}\t{%2, %0|%0, %2}";
5856 return "add{w}\t{%2, %0|%0, %2}";
5860 (if_then_else (eq_attr "alternative" "2")
5861 (const_string "lea")
5862 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5863 (const_string "incdec")
5864 (const_string "alu"))))
5865 (set_attr "mode" "HI,HI,SI")])
5867 (define_insn "*addhi_1"
5868 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5869 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5870 (match_operand:HI 2 "general_operand" "ri,rm")))
5871 (clobber (reg:CC FLAGS_REG))]
5872 "TARGET_PARTIAL_REG_STALL
5873 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5875 switch (get_attr_type (insn))
5878 if (operands[2] == const1_rtx)
5879 return "inc{w}\t%0";
5882 gcc_assert (operands[2] == constm1_rtx);
5883 return "dec{w}\t%0";
5887 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5888 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5889 if (CONST_INT_P (operands[2])
5890 && (INTVAL (operands[2]) == 128
5891 || (INTVAL (operands[2]) < 0
5892 && INTVAL (operands[2]) != -128)))
5894 operands[2] = GEN_INT (-INTVAL (operands[2]));
5895 return "sub{w}\t{%2, %0|%0, %2}";
5897 return "add{w}\t{%2, %0|%0, %2}";
5901 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5902 (const_string "incdec")
5903 (const_string "alu")))
5904 (set_attr "mode" "HI")])
5906 (define_insn "*addhi_2"
5907 [(set (reg FLAGS_REG)
5909 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5910 (match_operand:HI 2 "general_operand" "rmni,rni"))
5912 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5913 (plus:HI (match_dup 1) (match_dup 2)))]
5914 "ix86_match_ccmode (insn, CCGOCmode)
5915 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5917 switch (get_attr_type (insn))
5920 if (operands[2] == const1_rtx)
5921 return "inc{w}\t%0";
5924 gcc_assert (operands[2] == constm1_rtx);
5925 return "dec{w}\t%0";
5929 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5930 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5931 if (CONST_INT_P (operands[2])
5932 && (INTVAL (operands[2]) == 128
5933 || (INTVAL (operands[2]) < 0
5934 && INTVAL (operands[2]) != -128)))
5936 operands[2] = GEN_INT (-INTVAL (operands[2]));
5937 return "sub{w}\t{%2, %0|%0, %2}";
5939 return "add{w}\t{%2, %0|%0, %2}";
5943 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5944 (const_string "incdec")
5945 (const_string "alu")))
5946 (set_attr "mode" "HI")])
5948 (define_insn "*addhi_3"
5949 [(set (reg FLAGS_REG)
5950 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5951 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5952 (clobber (match_scratch:HI 0 "=r"))]
5953 "ix86_match_ccmode (insn, CCZmode)
5954 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5956 switch (get_attr_type (insn))
5959 if (operands[2] == const1_rtx)
5960 return "inc{w}\t%0";
5963 gcc_assert (operands[2] == constm1_rtx);
5964 return "dec{w}\t%0";
5968 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5969 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5970 if (CONST_INT_P (operands[2])
5971 && (INTVAL (operands[2]) == 128
5972 || (INTVAL (operands[2]) < 0
5973 && INTVAL (operands[2]) != -128)))
5975 operands[2] = GEN_INT (-INTVAL (operands[2]));
5976 return "sub{w}\t{%2, %0|%0, %2}";
5978 return "add{w}\t{%2, %0|%0, %2}";
5982 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5983 (const_string "incdec")
5984 (const_string "alu")))
5985 (set_attr "mode" "HI")])
5987 ; See comments above addsi_4 for details.
5988 (define_insn "*addhi_4"
5989 [(set (reg FLAGS_REG)
5990 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5991 (match_operand:HI 2 "const_int_operand" "n")))
5992 (clobber (match_scratch:HI 0 "=rm"))]
5993 "ix86_match_ccmode (insn, CCGCmode)
5994 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5996 switch (get_attr_type (insn))
5999 if (operands[2] == constm1_rtx)
6000 return "inc{w}\t%0";
6003 gcc_assert (operands[2] == const1_rtx);
6004 return "dec{w}\t%0";
6008 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6009 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6011 if ((INTVAL (operands[2]) == -128
6012 || (INTVAL (operands[2]) > 0
6013 && INTVAL (operands[2]) != 128)))
6014 return "sub{w}\t{%2, %0|%0, %2}";
6015 operands[2] = GEN_INT (-INTVAL (operands[2]));
6016 return "add{w}\t{%2, %0|%0, %2}";
6020 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6021 (const_string "incdec")
6022 (const_string "alu")))
6023 (set_attr "mode" "SI")])
6026 (define_insn "*addhi_5"
6027 [(set (reg FLAGS_REG)
6029 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6030 (match_operand:HI 2 "general_operand" "rmni"))
6032 (clobber (match_scratch:HI 0 "=r"))]
6033 "ix86_match_ccmode (insn, CCGOCmode)
6034 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6036 switch (get_attr_type (insn))
6039 if (operands[2] == const1_rtx)
6040 return "inc{w}\t%0";
6043 gcc_assert (operands[2] == constm1_rtx);
6044 return "dec{w}\t%0";
6048 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6049 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6050 if (CONST_INT_P (operands[2])
6051 && (INTVAL (operands[2]) == 128
6052 || (INTVAL (operands[2]) < 0
6053 && INTVAL (operands[2]) != -128)))
6055 operands[2] = GEN_INT (-INTVAL (operands[2]));
6056 return "sub{w}\t{%2, %0|%0, %2}";
6058 return "add{w}\t{%2, %0|%0, %2}";
6062 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6063 (const_string "incdec")
6064 (const_string "alu")))
6065 (set_attr "mode" "HI")])
6067 (define_expand "addqi3"
6068 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6069 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6070 (match_operand:QI 2 "general_operand" "")))
6071 (clobber (reg:CC FLAGS_REG))])]
6072 "TARGET_QIMODE_MATH"
6073 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6075 ;; %%% Potential partial reg stall on alternative 2. What to do?
6076 (define_insn "*addqi_1_lea"
6077 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6078 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6079 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6080 (clobber (reg:CC FLAGS_REG))]
6081 "!TARGET_PARTIAL_REG_STALL
6082 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6084 int widen = (which_alternative == 2);
6085 switch (get_attr_type (insn))
6090 if (operands[2] == const1_rtx)
6091 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6094 gcc_assert (operands[2] == constm1_rtx);
6095 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6099 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6100 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6101 if (CONST_INT_P (operands[2])
6102 && (INTVAL (operands[2]) == 128
6103 || (INTVAL (operands[2]) < 0
6104 && INTVAL (operands[2]) != -128)))
6106 operands[2] = GEN_INT (-INTVAL (operands[2]));
6108 return "sub{l}\t{%2, %k0|%k0, %2}";
6110 return "sub{b}\t{%2, %0|%0, %2}";
6113 return "add{l}\t{%k2, %k0|%k0, %k2}";
6115 return "add{b}\t{%2, %0|%0, %2}";
6119 (if_then_else (eq_attr "alternative" "3")
6120 (const_string "lea")
6121 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6122 (const_string "incdec")
6123 (const_string "alu"))))
6124 (set_attr "mode" "QI,QI,SI,SI")])
6126 (define_insn "*addqi_1"
6127 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6128 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6129 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6130 (clobber (reg:CC FLAGS_REG))]
6131 "TARGET_PARTIAL_REG_STALL
6132 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6134 int widen = (which_alternative == 2);
6135 switch (get_attr_type (insn))
6138 if (operands[2] == const1_rtx)
6139 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6142 gcc_assert (operands[2] == constm1_rtx);
6143 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6147 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6148 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6149 if (CONST_INT_P (operands[2])
6150 && (INTVAL (operands[2]) == 128
6151 || (INTVAL (operands[2]) < 0
6152 && INTVAL (operands[2]) != -128)))
6154 operands[2] = GEN_INT (-INTVAL (operands[2]));
6156 return "sub{l}\t{%2, %k0|%k0, %2}";
6158 return "sub{b}\t{%2, %0|%0, %2}";
6161 return "add{l}\t{%k2, %k0|%k0, %k2}";
6163 return "add{b}\t{%2, %0|%0, %2}";
6167 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6168 (const_string "incdec")
6169 (const_string "alu")))
6170 (set_attr "mode" "QI,QI,SI")])
6172 (define_insn "*addqi_1_slp"
6173 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6174 (plus:QI (match_dup 0)
6175 (match_operand:QI 1 "general_operand" "qn,qnm")))
6176 (clobber (reg:CC FLAGS_REG))]
6177 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6178 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6180 switch (get_attr_type (insn))
6183 if (operands[1] == const1_rtx)
6184 return "inc{b}\t%0";
6187 gcc_assert (operands[1] == constm1_rtx);
6188 return "dec{b}\t%0";
6192 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6193 if (CONST_INT_P (operands[1])
6194 && INTVAL (operands[1]) < 0)
6196 operands[1] = GEN_INT (-INTVAL (operands[1]));
6197 return "sub{b}\t{%1, %0|%0, %1}";
6199 return "add{b}\t{%1, %0|%0, %1}";
6203 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6204 (const_string "incdec")
6205 (const_string "alu1")))
6206 (set (attr "memory")
6207 (if_then_else (match_operand 1 "memory_operand" "")
6208 (const_string "load")
6209 (const_string "none")))
6210 (set_attr "mode" "QI")])
6212 (define_insn "*addqi_2"
6213 [(set (reg FLAGS_REG)
6215 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6216 (match_operand:QI 2 "general_operand" "qmni,qni"))
6218 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6219 (plus:QI (match_dup 1) (match_dup 2)))]
6220 "ix86_match_ccmode (insn, CCGOCmode)
6221 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6223 switch (get_attr_type (insn))
6226 if (operands[2] == const1_rtx)
6227 return "inc{b}\t%0";
6230 gcc_assert (operands[2] == constm1_rtx
6231 || (CONST_INT_P (operands[2])
6232 && INTVAL (operands[2]) == 255));
6233 return "dec{b}\t%0";
6237 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6238 if (CONST_INT_P (operands[2])
6239 && INTVAL (operands[2]) < 0)
6241 operands[2] = GEN_INT (-INTVAL (operands[2]));
6242 return "sub{b}\t{%2, %0|%0, %2}";
6244 return "add{b}\t{%2, %0|%0, %2}";
6248 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6249 (const_string "incdec")
6250 (const_string "alu")))
6251 (set_attr "mode" "QI")])
6253 (define_insn "*addqi_3"
6254 [(set (reg FLAGS_REG)
6255 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6256 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6257 (clobber (match_scratch:QI 0 "=q"))]
6258 "ix86_match_ccmode (insn, CCZmode)
6259 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6261 switch (get_attr_type (insn))
6264 if (operands[2] == const1_rtx)
6265 return "inc{b}\t%0";
6268 gcc_assert (operands[2] == constm1_rtx
6269 || (CONST_INT_P (operands[2])
6270 && INTVAL (operands[2]) == 255));
6271 return "dec{b}\t%0";
6275 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6276 if (CONST_INT_P (operands[2])
6277 && INTVAL (operands[2]) < 0)
6279 operands[2] = GEN_INT (-INTVAL (operands[2]));
6280 return "sub{b}\t{%2, %0|%0, %2}";
6282 return "add{b}\t{%2, %0|%0, %2}";
6286 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6287 (const_string "incdec")
6288 (const_string "alu")))
6289 (set_attr "mode" "QI")])
6291 ; See comments above addsi_4 for details.
6292 (define_insn "*addqi_4"
6293 [(set (reg FLAGS_REG)
6294 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6295 (match_operand:QI 2 "const_int_operand" "n")))
6296 (clobber (match_scratch:QI 0 "=qm"))]
6297 "ix86_match_ccmode (insn, CCGCmode)
6298 && (INTVAL (operands[2]) & 0xff) != 0x80"
6300 switch (get_attr_type (insn))
6303 if (operands[2] == constm1_rtx
6304 || (CONST_INT_P (operands[2])
6305 && INTVAL (operands[2]) == 255))
6306 return "inc{b}\t%0";
6309 gcc_assert (operands[2] == const1_rtx);
6310 return "dec{b}\t%0";
6314 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6315 if (INTVAL (operands[2]) < 0)
6317 operands[2] = GEN_INT (-INTVAL (operands[2]));
6318 return "add{b}\t{%2, %0|%0, %2}";
6320 return "sub{b}\t{%2, %0|%0, %2}";
6324 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6325 (const_string "incdec")
6326 (const_string "alu")))
6327 (set_attr "mode" "QI")])
6330 (define_insn "*addqi_5"
6331 [(set (reg FLAGS_REG)
6333 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6334 (match_operand:QI 2 "general_operand" "qmni"))
6336 (clobber (match_scratch:QI 0 "=q"))]
6337 "ix86_match_ccmode (insn, CCGOCmode)
6338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6340 switch (get_attr_type (insn))
6343 if (operands[2] == const1_rtx)
6344 return "inc{b}\t%0";
6347 gcc_assert (operands[2] == constm1_rtx
6348 || (CONST_INT_P (operands[2])
6349 && INTVAL (operands[2]) == 255));
6350 return "dec{b}\t%0";
6354 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6355 if (CONST_INT_P (operands[2])
6356 && INTVAL (operands[2]) < 0)
6358 operands[2] = GEN_INT (-INTVAL (operands[2]));
6359 return "sub{b}\t{%2, %0|%0, %2}";
6361 return "add{b}\t{%2, %0|%0, %2}";
6365 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6366 (const_string "incdec")
6367 (const_string "alu")))
6368 (set_attr "mode" "QI")])
6371 (define_insn "addqi_ext_1"
6372 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6377 (match_operand 1 "ext_register_operand" "0")
6380 (match_operand:QI 2 "general_operand" "Qmn")))
6381 (clobber (reg:CC FLAGS_REG))]
6384 switch (get_attr_type (insn))
6387 if (operands[2] == const1_rtx)
6388 return "inc{b}\t%h0";
6391 gcc_assert (operands[2] == constm1_rtx
6392 || (CONST_INT_P (operands[2])
6393 && INTVAL (operands[2]) == 255));
6394 return "dec{b}\t%h0";
6398 return "add{b}\t{%2, %h0|%h0, %2}";
6402 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6403 (const_string "incdec")
6404 (const_string "alu")))
6405 (set_attr "mode" "QI")])
6407 (define_insn "*addqi_ext_1_rex64"
6408 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6413 (match_operand 1 "ext_register_operand" "0")
6416 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6417 (clobber (reg:CC FLAGS_REG))]
6420 switch (get_attr_type (insn))
6423 if (operands[2] == const1_rtx)
6424 return "inc{b}\t%h0";
6427 gcc_assert (operands[2] == constm1_rtx
6428 || (CONST_INT_P (operands[2])
6429 && INTVAL (operands[2]) == 255));
6430 return "dec{b}\t%h0";
6434 return "add{b}\t{%2, %h0|%h0, %2}";
6438 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6439 (const_string "incdec")
6440 (const_string "alu")))
6441 (set_attr "mode" "QI")])
6443 (define_insn "*addqi_ext_2"
6444 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6449 (match_operand 1 "ext_register_operand" "%0")
6453 (match_operand 2 "ext_register_operand" "Q")
6456 (clobber (reg:CC FLAGS_REG))]
6458 "add{b}\t{%h2, %h0|%h0, %h2}"
6459 [(set_attr "type" "alu")
6460 (set_attr "mode" "QI")])
6462 ;; The patterns that match these are at the end of this file.
6464 (define_expand "addxf3"
6465 [(set (match_operand:XF 0 "register_operand" "")
6466 (plus:XF (match_operand:XF 1 "register_operand" "")
6467 (match_operand:XF 2 "register_operand" "")))]
6471 (define_expand "adddf3"
6472 [(set (match_operand:DF 0 "register_operand" "")
6473 (plus:DF (match_operand:DF 1 "register_operand" "")
6474 (match_operand:DF 2 "nonimmediate_operand" "")))]
6475 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6478 (define_expand "addsf3"
6479 [(set (match_operand:SF 0 "register_operand" "")
6480 (plus:SF (match_operand:SF 1 "register_operand" "")
6481 (match_operand:SF 2 "nonimmediate_operand" "")))]
6482 "TARGET_80387 || TARGET_SSE_MATH"
6485 ;; Subtract instructions
6487 ;; %%% splits for subditi3
6489 (define_expand "subti3"
6490 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6491 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6492 (match_operand:TI 2 "x86_64_general_operand" "")))
6493 (clobber (reg:CC FLAGS_REG))])]
6495 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6497 (define_insn "*subti3_1"
6498 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6499 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6500 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6501 (clobber (reg:CC FLAGS_REG))]
6502 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6506 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6507 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6508 (match_operand:TI 2 "x86_64_general_operand" "")))
6509 (clobber (reg:CC FLAGS_REG))]
6510 "TARGET_64BIT && reload_completed"
6511 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6512 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6513 (parallel [(set (match_dup 3)
6514 (minus:DI (match_dup 4)
6515 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6517 (clobber (reg:CC FLAGS_REG))])]
6518 "split_ti (operands+0, 1, operands+0, operands+3);
6519 split_ti (operands+1, 1, operands+1, operands+4);
6520 split_ti (operands+2, 1, operands+2, operands+5);")
6522 ;; %%% splits for subsidi3
6524 (define_expand "subdi3"
6525 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6526 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6527 (match_operand:DI 2 "x86_64_general_operand" "")))
6528 (clobber (reg:CC FLAGS_REG))])]
6530 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6532 (define_insn "*subdi3_1"
6533 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6534 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6535 (match_operand:DI 2 "general_operand" "roiF,riF")))
6536 (clobber (reg:CC FLAGS_REG))]
6537 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6541 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6542 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6543 (match_operand:DI 2 "general_operand" "")))
6544 (clobber (reg:CC FLAGS_REG))]
6545 "!TARGET_64BIT && reload_completed"
6546 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6547 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6548 (parallel [(set (match_dup 3)
6549 (minus:SI (match_dup 4)
6550 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6552 (clobber (reg:CC FLAGS_REG))])]
6553 "split_di (operands+0, 1, operands+0, operands+3);
6554 split_di (operands+1, 1, operands+1, operands+4);
6555 split_di (operands+2, 1, operands+2, operands+5);")
6557 (define_insn "subdi3_carry_rex64"
6558 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6559 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6560 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6561 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6562 (clobber (reg:CC FLAGS_REG))]
6563 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6564 "sbb{q}\t{%2, %0|%0, %2}"
6565 [(set_attr "type" "alu")
6566 (set_attr "pent_pair" "pu")
6567 (set_attr "mode" "DI")])
6569 (define_insn "*subdi_1_rex64"
6570 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6571 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6572 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6573 (clobber (reg:CC FLAGS_REG))]
6574 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6575 "sub{q}\t{%2, %0|%0, %2}"
6576 [(set_attr "type" "alu")
6577 (set_attr "mode" "DI")])
6579 (define_insn "*subdi_2_rex64"
6580 [(set (reg FLAGS_REG)
6582 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6583 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6585 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6586 (minus:DI (match_dup 1) (match_dup 2)))]
6587 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6588 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6589 "sub{q}\t{%2, %0|%0, %2}"
6590 [(set_attr "type" "alu")
6591 (set_attr "mode" "DI")])
6593 (define_insn "*subdi_3_rex63"
6594 [(set (reg FLAGS_REG)
6595 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6596 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6597 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6598 (minus:DI (match_dup 1) (match_dup 2)))]
6599 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6600 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6601 "sub{q}\t{%2, %0|%0, %2}"
6602 [(set_attr "type" "alu")
6603 (set_attr "mode" "DI")])
6605 (define_insn "subqi3_carry"
6606 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6607 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6608 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6609 (match_operand:QI 2 "general_operand" "qi,qm"))))
6610 (clobber (reg:CC FLAGS_REG))]
6611 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6612 "sbb{b}\t{%2, %0|%0, %2}"
6613 [(set_attr "type" "alu")
6614 (set_attr "pent_pair" "pu")
6615 (set_attr "mode" "QI")])
6617 (define_insn "subhi3_carry"
6618 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6619 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6620 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6621 (match_operand:HI 2 "general_operand" "ri,rm"))))
6622 (clobber (reg:CC FLAGS_REG))]
6623 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6624 "sbb{w}\t{%2, %0|%0, %2}"
6625 [(set_attr "type" "alu")
6626 (set_attr "pent_pair" "pu")
6627 (set_attr "mode" "HI")])
6629 (define_insn "subsi3_carry"
6630 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6631 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6632 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6633 (match_operand:SI 2 "general_operand" "ri,rm"))))
6634 (clobber (reg:CC FLAGS_REG))]
6635 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6636 "sbb{l}\t{%2, %0|%0, %2}"
6637 [(set_attr "type" "alu")
6638 (set_attr "pent_pair" "pu")
6639 (set_attr "mode" "SI")])
6641 (define_insn "subsi3_carry_zext"
6642 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6644 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6645 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6646 (match_operand:SI 2 "general_operand" "ri,rm")))))
6647 (clobber (reg:CC FLAGS_REG))]
6648 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6649 "sbb{l}\t{%2, %k0|%k0, %2}"
6650 [(set_attr "type" "alu")
6651 (set_attr "pent_pair" "pu")
6652 (set_attr "mode" "SI")])
6654 (define_expand "subsi3"
6655 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6656 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6657 (match_operand:SI 2 "general_operand" "")))
6658 (clobber (reg:CC FLAGS_REG))])]
6660 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6662 (define_insn "*subsi_1"
6663 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6664 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6665 (match_operand:SI 2 "general_operand" "ri,rm")))
6666 (clobber (reg:CC FLAGS_REG))]
6667 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6668 "sub{l}\t{%2, %0|%0, %2}"
6669 [(set_attr "type" "alu")
6670 (set_attr "mode" "SI")])
6672 (define_insn "*subsi_1_zext"
6673 [(set (match_operand:DI 0 "register_operand" "=r")
6675 (minus:SI (match_operand:SI 1 "register_operand" "0")
6676 (match_operand:SI 2 "general_operand" "rim"))))
6677 (clobber (reg:CC FLAGS_REG))]
6678 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6679 "sub{l}\t{%2, %k0|%k0, %2}"
6680 [(set_attr "type" "alu")
6681 (set_attr "mode" "SI")])
6683 (define_insn "*subsi_2"
6684 [(set (reg FLAGS_REG)
6686 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6687 (match_operand:SI 2 "general_operand" "ri,rm"))
6689 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6690 (minus:SI (match_dup 1) (match_dup 2)))]
6691 "ix86_match_ccmode (insn, CCGOCmode)
6692 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6693 "sub{l}\t{%2, %0|%0, %2}"
6694 [(set_attr "type" "alu")
6695 (set_attr "mode" "SI")])
6697 (define_insn "*subsi_2_zext"
6698 [(set (reg FLAGS_REG)
6700 (minus:SI (match_operand:SI 1 "register_operand" "0")
6701 (match_operand:SI 2 "general_operand" "rim"))
6703 (set (match_operand:DI 0 "register_operand" "=r")
6705 (minus:SI (match_dup 1)
6707 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6708 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6709 "sub{l}\t{%2, %k0|%k0, %2}"
6710 [(set_attr "type" "alu")
6711 (set_attr "mode" "SI")])
6713 (define_insn "*subsi_3"
6714 [(set (reg FLAGS_REG)
6715 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6716 (match_operand:SI 2 "general_operand" "ri,rm")))
6717 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6718 (minus:SI (match_dup 1) (match_dup 2)))]
6719 "ix86_match_ccmode (insn, CCmode)
6720 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721 "sub{l}\t{%2, %0|%0, %2}"
6722 [(set_attr "type" "alu")
6723 (set_attr "mode" "SI")])
6725 (define_insn "*subsi_3_zext"
6726 [(set (reg FLAGS_REG)
6727 (compare (match_operand:SI 1 "register_operand" "0")
6728 (match_operand:SI 2 "general_operand" "rim")))
6729 (set (match_operand:DI 0 "register_operand" "=r")
6731 (minus:SI (match_dup 1)
6733 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6734 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735 "sub{l}\t{%2, %1|%1, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "mode" "DI")])
6739 (define_expand "subhi3"
6740 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6741 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6742 (match_operand:HI 2 "general_operand" "")))
6743 (clobber (reg:CC FLAGS_REG))])]
6744 "TARGET_HIMODE_MATH"
6745 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6747 (define_insn "*subhi_1"
6748 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6749 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6750 (match_operand:HI 2 "general_operand" "ri,rm")))
6751 (clobber (reg:CC FLAGS_REG))]
6752 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6753 "sub{w}\t{%2, %0|%0, %2}"
6754 [(set_attr "type" "alu")
6755 (set_attr "mode" "HI")])
6757 (define_insn "*subhi_2"
6758 [(set (reg FLAGS_REG)
6760 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6761 (match_operand:HI 2 "general_operand" "ri,rm"))
6763 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6764 (minus:HI (match_dup 1) (match_dup 2)))]
6765 "ix86_match_ccmode (insn, CCGOCmode)
6766 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6767 "sub{w}\t{%2, %0|%0, %2}"
6768 [(set_attr "type" "alu")
6769 (set_attr "mode" "HI")])
6771 (define_insn "*subhi_3"
6772 [(set (reg FLAGS_REG)
6773 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6774 (match_operand:HI 2 "general_operand" "ri,rm")))
6775 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6776 (minus:HI (match_dup 1) (match_dup 2)))]
6777 "ix86_match_ccmode (insn, CCmode)
6778 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6779 "sub{w}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "HI")])
6783 (define_expand "subqi3"
6784 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6785 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6786 (match_operand:QI 2 "general_operand" "")))
6787 (clobber (reg:CC FLAGS_REG))])]
6788 "TARGET_QIMODE_MATH"
6789 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6791 (define_insn "*subqi_1"
6792 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6793 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6794 (match_operand:QI 2 "general_operand" "qn,qmn")))
6795 (clobber (reg:CC FLAGS_REG))]
6796 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6797 "sub{b}\t{%2, %0|%0, %2}"
6798 [(set_attr "type" "alu")
6799 (set_attr "mode" "QI")])
6801 (define_insn "*subqi_1_slp"
6802 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6803 (minus:QI (match_dup 0)
6804 (match_operand:QI 1 "general_operand" "qn,qmn")))
6805 (clobber (reg:CC FLAGS_REG))]
6806 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6808 "sub{b}\t{%1, %0|%0, %1}"
6809 [(set_attr "type" "alu1")
6810 (set_attr "mode" "QI")])
6812 (define_insn "*subqi_2"
6813 [(set (reg FLAGS_REG)
6815 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6816 (match_operand:QI 2 "general_operand" "qi,qm"))
6818 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6819 (minus:HI (match_dup 1) (match_dup 2)))]
6820 "ix86_match_ccmode (insn, CCGOCmode)
6821 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6822 "sub{b}\t{%2, %0|%0, %2}"
6823 [(set_attr "type" "alu")
6824 (set_attr "mode" "QI")])
6826 (define_insn "*subqi_3"
6827 [(set (reg FLAGS_REG)
6828 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6829 (match_operand:QI 2 "general_operand" "qi,qm")))
6830 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6831 (minus:HI (match_dup 1) (match_dup 2)))]
6832 "ix86_match_ccmode (insn, CCmode)
6833 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6834 "sub{b}\t{%2, %0|%0, %2}"
6835 [(set_attr "type" "alu")
6836 (set_attr "mode" "QI")])
6838 ;; The patterns that match these are at the end of this file.
6840 (define_expand "subxf3"
6841 [(set (match_operand:XF 0 "register_operand" "")
6842 (minus:XF (match_operand:XF 1 "register_operand" "")
6843 (match_operand:XF 2 "register_operand" "")))]
6847 (define_expand "subdf3"
6848 [(set (match_operand:DF 0 "register_operand" "")
6849 (minus:DF (match_operand:DF 1 "register_operand" "")
6850 (match_operand:DF 2 "nonimmediate_operand" "")))]
6851 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6854 (define_expand "subsf3"
6855 [(set (match_operand:SF 0 "register_operand" "")
6856 (minus:SF (match_operand:SF 1 "register_operand" "")
6857 (match_operand:SF 2 "nonimmediate_operand" "")))]
6858 "TARGET_80387 || TARGET_SSE_MATH"
6861 ;; Multiply instructions
6863 (define_expand "muldi3"
6864 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6865 (mult:DI (match_operand:DI 1 "register_operand" "")
6866 (match_operand:DI 2 "x86_64_general_operand" "")))
6867 (clobber (reg:CC FLAGS_REG))])]
6872 ;; IMUL reg64, reg64, imm8 Direct
6873 ;; IMUL reg64, mem64, imm8 VectorPath
6874 ;; IMUL reg64, reg64, imm32 Direct
6875 ;; IMUL reg64, mem64, imm32 VectorPath
6876 ;; IMUL reg64, reg64 Direct
6877 ;; IMUL reg64, mem64 Direct
6879 (define_insn "*muldi3_1_rex64"
6880 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6881 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6882 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6883 (clobber (reg:CC FLAGS_REG))]
6885 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6887 imul{q}\t{%2, %1, %0|%0, %1, %2}
6888 imul{q}\t{%2, %1, %0|%0, %1, %2}
6889 imul{q}\t{%2, %0|%0, %2}"
6890 [(set_attr "type" "imul")
6891 (set_attr "prefix_0f" "0,0,1")
6892 (set (attr "athlon_decode")
6893 (cond [(eq_attr "cpu" "athlon")
6894 (const_string "vector")
6895 (eq_attr "alternative" "1")
6896 (const_string "vector")
6897 (and (eq_attr "alternative" "2")
6898 (match_operand 1 "memory_operand" ""))
6899 (const_string "vector")]
6900 (const_string "direct")))
6901 (set (attr "amdfam10_decode")
6902 (cond [(and (eq_attr "alternative" "0,1")
6903 (match_operand 1 "memory_operand" ""))
6904 (const_string "vector")]
6905 (const_string "direct")))
6906 (set_attr "mode" "DI")])
6908 (define_expand "mulsi3"
6909 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6910 (mult:SI (match_operand:SI 1 "register_operand" "")
6911 (match_operand:SI 2 "general_operand" "")))
6912 (clobber (reg:CC FLAGS_REG))])]
6917 ;; IMUL reg32, reg32, imm8 Direct
6918 ;; IMUL reg32, mem32, imm8 VectorPath
6919 ;; IMUL reg32, reg32, imm32 Direct
6920 ;; IMUL reg32, mem32, imm32 VectorPath
6921 ;; IMUL reg32, reg32 Direct
6922 ;; IMUL reg32, mem32 Direct
6924 (define_insn "*mulsi3_1"
6925 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6926 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6927 (match_operand:SI 2 "general_operand" "K,i,mr")))
6928 (clobber (reg:CC FLAGS_REG))]
6929 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6931 imul{l}\t{%2, %1, %0|%0, %1, %2}
6932 imul{l}\t{%2, %1, %0|%0, %1, %2}
6933 imul{l}\t{%2, %0|%0, %2}"
6934 [(set_attr "type" "imul")
6935 (set_attr "prefix_0f" "0,0,1")
6936 (set (attr "athlon_decode")
6937 (cond [(eq_attr "cpu" "athlon")
6938 (const_string "vector")
6939 (eq_attr "alternative" "1")
6940 (const_string "vector")
6941 (and (eq_attr "alternative" "2")
6942 (match_operand 1 "memory_operand" ""))
6943 (const_string "vector")]
6944 (const_string "direct")))
6945 (set (attr "amdfam10_decode")
6946 (cond [(and (eq_attr "alternative" "0,1")
6947 (match_operand 1 "memory_operand" ""))
6948 (const_string "vector")]
6949 (const_string "direct")))
6950 (set_attr "mode" "SI")])
6952 (define_insn "*mulsi3_1_zext"
6953 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6955 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6956 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6957 (clobber (reg:CC FLAGS_REG))]
6959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6961 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6962 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6963 imul{l}\t{%2, %k0|%k0, %2}"
6964 [(set_attr "type" "imul")
6965 (set_attr "prefix_0f" "0,0,1")
6966 (set (attr "athlon_decode")
6967 (cond [(eq_attr "cpu" "athlon")
6968 (const_string "vector")
6969 (eq_attr "alternative" "1")
6970 (const_string "vector")
6971 (and (eq_attr "alternative" "2")
6972 (match_operand 1 "memory_operand" ""))
6973 (const_string "vector")]
6974 (const_string "direct")))
6975 (set (attr "amdfam10_decode")
6976 (cond [(and (eq_attr "alternative" "0,1")
6977 (match_operand 1 "memory_operand" ""))
6978 (const_string "vector")]
6979 (const_string "direct")))
6980 (set_attr "mode" "SI")])
6982 (define_expand "mulhi3"
6983 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6984 (mult:HI (match_operand:HI 1 "register_operand" "")
6985 (match_operand:HI 2 "general_operand" "")))
6986 (clobber (reg:CC FLAGS_REG))])]
6987 "TARGET_HIMODE_MATH"
6991 ;; IMUL reg16, reg16, imm8 VectorPath
6992 ;; IMUL reg16, mem16, imm8 VectorPath
6993 ;; IMUL reg16, reg16, imm16 VectorPath
6994 ;; IMUL reg16, mem16, imm16 VectorPath
6995 ;; IMUL reg16, reg16 Direct
6996 ;; IMUL reg16, mem16 Direct
6997 (define_insn "*mulhi3_1"
6998 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6999 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7000 (match_operand:HI 2 "general_operand" "K,i,mr")))
7001 (clobber (reg:CC FLAGS_REG))]
7002 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7004 imul{w}\t{%2, %1, %0|%0, %1, %2}
7005 imul{w}\t{%2, %1, %0|%0, %1, %2}
7006 imul{w}\t{%2, %0|%0, %2}"
7007 [(set_attr "type" "imul")
7008 (set_attr "prefix_0f" "0,0,1")
7009 (set (attr "athlon_decode")
7010 (cond [(eq_attr "cpu" "athlon")
7011 (const_string "vector")
7012 (eq_attr "alternative" "1,2")
7013 (const_string "vector")]
7014 (const_string "direct")))
7015 (set (attr "amdfam10_decode")
7016 (cond [(eq_attr "alternative" "0,1")
7017 (const_string "vector")]
7018 (const_string "direct")))
7019 (set_attr "mode" "HI")])
7021 (define_expand "mulqi3"
7022 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7023 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7024 (match_operand:QI 2 "register_operand" "")))
7025 (clobber (reg:CC FLAGS_REG))])]
7026 "TARGET_QIMODE_MATH"
7033 (define_insn "*mulqi3_1"
7034 [(set (match_operand:QI 0 "register_operand" "=a")
7035 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7036 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7037 (clobber (reg:CC FLAGS_REG))]
7039 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7041 [(set_attr "type" "imul")
7042 (set_attr "length_immediate" "0")
7043 (set (attr "athlon_decode")
7044 (if_then_else (eq_attr "cpu" "athlon")
7045 (const_string "vector")
7046 (const_string "direct")))
7047 (set_attr "amdfam10_decode" "direct")
7048 (set_attr "mode" "QI")])
7050 (define_expand "umulqihi3"
7051 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7052 (mult:HI (zero_extend:HI
7053 (match_operand:QI 1 "nonimmediate_operand" ""))
7055 (match_operand:QI 2 "register_operand" ""))))
7056 (clobber (reg:CC FLAGS_REG))])]
7057 "TARGET_QIMODE_MATH"
7060 (define_insn "*umulqihi3_1"
7061 [(set (match_operand:HI 0 "register_operand" "=a")
7062 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7063 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7064 (clobber (reg:CC FLAGS_REG))]
7066 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7068 [(set_attr "type" "imul")
7069 (set_attr "length_immediate" "0")
7070 (set (attr "athlon_decode")
7071 (if_then_else (eq_attr "cpu" "athlon")
7072 (const_string "vector")
7073 (const_string "direct")))
7074 (set_attr "amdfam10_decode" "direct")
7075 (set_attr "mode" "QI")])
7077 (define_expand "mulqihi3"
7078 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7079 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7080 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7081 (clobber (reg:CC FLAGS_REG))])]
7082 "TARGET_QIMODE_MATH"
7085 (define_insn "*mulqihi3_insn"
7086 [(set (match_operand:HI 0 "register_operand" "=a")
7087 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7088 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7089 (clobber (reg:CC FLAGS_REG))]
7091 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7093 [(set_attr "type" "imul")
7094 (set_attr "length_immediate" "0")
7095 (set (attr "athlon_decode")
7096 (if_then_else (eq_attr "cpu" "athlon")
7097 (const_string "vector")
7098 (const_string "direct")))
7099 (set_attr "amdfam10_decode" "direct")
7100 (set_attr "mode" "QI")])
7102 (define_expand "umulditi3"
7103 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7104 (mult:TI (zero_extend:TI
7105 (match_operand:DI 1 "nonimmediate_operand" ""))
7107 (match_operand:DI 2 "register_operand" ""))))
7108 (clobber (reg:CC FLAGS_REG))])]
7112 (define_insn "*umulditi3_insn"
7113 [(set (match_operand:TI 0 "register_operand" "=A")
7114 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7115 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7116 (clobber (reg:CC FLAGS_REG))]
7118 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7120 [(set_attr "type" "imul")
7121 (set_attr "length_immediate" "0")
7122 (set (attr "athlon_decode")
7123 (if_then_else (eq_attr "cpu" "athlon")
7124 (const_string "vector")
7125 (const_string "double")))
7126 (set_attr "amdfam10_decode" "double")
7127 (set_attr "mode" "DI")])
7129 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7130 (define_expand "umulsidi3"
7131 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7132 (mult:DI (zero_extend:DI
7133 (match_operand:SI 1 "nonimmediate_operand" ""))
7135 (match_operand:SI 2 "register_operand" ""))))
7136 (clobber (reg:CC FLAGS_REG))])]
7140 (define_insn "*umulsidi3_insn"
7141 [(set (match_operand:DI 0 "register_operand" "=A")
7142 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7143 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7144 (clobber (reg:CC FLAGS_REG))]
7146 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7148 [(set_attr "type" "imul")
7149 (set_attr "length_immediate" "0")
7150 (set (attr "athlon_decode")
7151 (if_then_else (eq_attr "cpu" "athlon")
7152 (const_string "vector")
7153 (const_string "double")))
7154 (set_attr "amdfam10_decode" "double")
7155 (set_attr "mode" "SI")])
7157 (define_expand "mulditi3"
7158 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7159 (mult:TI (sign_extend:TI
7160 (match_operand:DI 1 "nonimmediate_operand" ""))
7162 (match_operand:DI 2 "register_operand" ""))))
7163 (clobber (reg:CC FLAGS_REG))])]
7167 (define_insn "*mulditi3_insn"
7168 [(set (match_operand:TI 0 "register_operand" "=A")
7169 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7170 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7171 (clobber (reg:CC FLAGS_REG))]
7173 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7175 [(set_attr "type" "imul")
7176 (set_attr "length_immediate" "0")
7177 (set (attr "athlon_decode")
7178 (if_then_else (eq_attr "cpu" "athlon")
7179 (const_string "vector")
7180 (const_string "double")))
7181 (set_attr "amdfam10_decode" "double")
7182 (set_attr "mode" "DI")])
7184 (define_expand "mulsidi3"
7185 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7186 (mult:DI (sign_extend:DI
7187 (match_operand:SI 1 "nonimmediate_operand" ""))
7189 (match_operand:SI 2 "register_operand" ""))))
7190 (clobber (reg:CC FLAGS_REG))])]
7194 (define_insn "*mulsidi3_insn"
7195 [(set (match_operand:DI 0 "register_operand" "=A")
7196 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7197 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7198 (clobber (reg:CC FLAGS_REG))]
7200 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7202 [(set_attr "type" "imul")
7203 (set_attr "length_immediate" "0")
7204 (set (attr "athlon_decode")
7205 (if_then_else (eq_attr "cpu" "athlon")
7206 (const_string "vector")
7207 (const_string "double")))
7208 (set_attr "amdfam10_decode" "double")
7209 (set_attr "mode" "SI")])
7211 (define_expand "umuldi3_highpart"
7212 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7215 (mult:TI (zero_extend:TI
7216 (match_operand:DI 1 "nonimmediate_operand" ""))
7218 (match_operand:DI 2 "register_operand" "")))
7220 (clobber (match_scratch:DI 3 ""))
7221 (clobber (reg:CC FLAGS_REG))])]
7225 (define_insn "*umuldi3_highpart_rex64"
7226 [(set (match_operand:DI 0 "register_operand" "=d")
7229 (mult:TI (zero_extend:TI
7230 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7232 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7234 (clobber (match_scratch:DI 3 "=1"))
7235 (clobber (reg:CC FLAGS_REG))]
7237 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7239 [(set_attr "type" "imul")
7240 (set_attr "length_immediate" "0")
7241 (set (attr "athlon_decode")
7242 (if_then_else (eq_attr "cpu" "athlon")
7243 (const_string "vector")
7244 (const_string "double")))
7245 (set_attr "amdfam10_decode" "double")
7246 (set_attr "mode" "DI")])
7248 (define_expand "umulsi3_highpart"
7249 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7252 (mult:DI (zero_extend:DI
7253 (match_operand:SI 1 "nonimmediate_operand" ""))
7255 (match_operand:SI 2 "register_operand" "")))
7257 (clobber (match_scratch:SI 3 ""))
7258 (clobber (reg:CC FLAGS_REG))])]
7262 (define_insn "*umulsi3_highpart_insn"
7263 [(set (match_operand:SI 0 "register_operand" "=d")
7266 (mult:DI (zero_extend:DI
7267 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7269 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7271 (clobber (match_scratch:SI 3 "=1"))
7272 (clobber (reg:CC FLAGS_REG))]
7273 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7275 [(set_attr "type" "imul")
7276 (set_attr "length_immediate" "0")
7277 (set (attr "athlon_decode")
7278 (if_then_else (eq_attr "cpu" "athlon")
7279 (const_string "vector")
7280 (const_string "double")))
7281 (set_attr "amdfam10_decode" "double")
7282 (set_attr "mode" "SI")])
7284 (define_insn "*umulsi3_highpart_zext"
7285 [(set (match_operand:DI 0 "register_operand" "=d")
7286 (zero_extend:DI (truncate:SI
7288 (mult:DI (zero_extend:DI
7289 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7291 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7293 (clobber (match_scratch:SI 3 "=1"))
7294 (clobber (reg:CC FLAGS_REG))]
7296 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7298 [(set_attr "type" "imul")
7299 (set_attr "length_immediate" "0")
7300 (set (attr "athlon_decode")
7301 (if_then_else (eq_attr "cpu" "athlon")
7302 (const_string "vector")
7303 (const_string "double")))
7304 (set_attr "amdfam10_decode" "double")
7305 (set_attr "mode" "SI")])
7307 (define_expand "smuldi3_highpart"
7308 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7311 (mult:TI (sign_extend:TI
7312 (match_operand:DI 1 "nonimmediate_operand" ""))
7314 (match_operand:DI 2 "register_operand" "")))
7316 (clobber (match_scratch:DI 3 ""))
7317 (clobber (reg:CC FLAGS_REG))])]
7321 (define_insn "*smuldi3_highpart_rex64"
7322 [(set (match_operand:DI 0 "register_operand" "=d")
7325 (mult:TI (sign_extend:TI
7326 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7328 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7330 (clobber (match_scratch:DI 3 "=1"))
7331 (clobber (reg:CC FLAGS_REG))]
7333 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7335 [(set_attr "type" "imul")
7336 (set (attr "athlon_decode")
7337 (if_then_else (eq_attr "cpu" "athlon")
7338 (const_string "vector")
7339 (const_string "double")))
7340 (set_attr "amdfam10_decode" "double")
7341 (set_attr "mode" "DI")])
7343 (define_expand "smulsi3_highpart"
7344 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7347 (mult:DI (sign_extend:DI
7348 (match_operand:SI 1 "nonimmediate_operand" ""))
7350 (match_operand:SI 2 "register_operand" "")))
7352 (clobber (match_scratch:SI 3 ""))
7353 (clobber (reg:CC FLAGS_REG))])]
7357 (define_insn "*smulsi3_highpart_insn"
7358 [(set (match_operand:SI 0 "register_operand" "=d")
7361 (mult:DI (sign_extend:DI
7362 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7364 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7366 (clobber (match_scratch:SI 3 "=1"))
7367 (clobber (reg:CC FLAGS_REG))]
7368 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7370 [(set_attr "type" "imul")
7371 (set (attr "athlon_decode")
7372 (if_then_else (eq_attr "cpu" "athlon")
7373 (const_string "vector")
7374 (const_string "double")))
7375 (set_attr "amdfam10_decode" "double")
7376 (set_attr "mode" "SI")])
7378 (define_insn "*smulsi3_highpart_zext"
7379 [(set (match_operand:DI 0 "register_operand" "=d")
7380 (zero_extend:DI (truncate:SI
7382 (mult:DI (sign_extend:DI
7383 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7385 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7387 (clobber (match_scratch:SI 3 "=1"))
7388 (clobber (reg:CC FLAGS_REG))]
7390 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7392 [(set_attr "type" "imul")
7393 (set (attr "athlon_decode")
7394 (if_then_else (eq_attr "cpu" "athlon")
7395 (const_string "vector")
7396 (const_string "double")))
7397 (set_attr "amdfam10_decode" "double")
7398 (set_attr "mode" "SI")])
7400 ;; The patterns that match these are at the end of this file.
7402 (define_expand "mulxf3"
7403 [(set (match_operand:XF 0 "register_operand" "")
7404 (mult:XF (match_operand:XF 1 "register_operand" "")
7405 (match_operand:XF 2 "register_operand" "")))]
7409 (define_expand "muldf3"
7410 [(set (match_operand:DF 0 "register_operand" "")
7411 (mult:DF (match_operand:DF 1 "register_operand" "")
7412 (match_operand:DF 2 "nonimmediate_operand" "")))]
7413 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7416 (define_expand "mulsf3"
7417 [(set (match_operand:SF 0 "register_operand" "")
7418 (mult:SF (match_operand:SF 1 "register_operand" "")
7419 (match_operand:SF 2 "nonimmediate_operand" "")))]
7420 "TARGET_80387 || TARGET_SSE_MATH"
7423 ;; Divide instructions
7425 (define_insn "divqi3"
7426 [(set (match_operand:QI 0 "register_operand" "=a")
7427 (div:QI (match_operand:HI 1 "register_operand" "0")
7428 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7429 (clobber (reg:CC FLAGS_REG))]
7430 "TARGET_QIMODE_MATH"
7432 [(set_attr "type" "idiv")
7433 (set_attr "mode" "QI")])
7435 (define_insn "udivqi3"
7436 [(set (match_operand:QI 0 "register_operand" "=a")
7437 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7438 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7439 (clobber (reg:CC FLAGS_REG))]
7440 "TARGET_QIMODE_MATH"
7442 [(set_attr "type" "idiv")
7443 (set_attr "mode" "QI")])
7445 ;; The patterns that match these are at the end of this file.
7447 (define_expand "divxf3"
7448 [(set (match_operand:XF 0 "register_operand" "")
7449 (div:XF (match_operand:XF 1 "register_operand" "")
7450 (match_operand:XF 2 "register_operand" "")))]
7454 (define_expand "divdf3"
7455 [(set (match_operand:DF 0 "register_operand" "")
7456 (div:DF (match_operand:DF 1 "register_operand" "")
7457 (match_operand:DF 2 "nonimmediate_operand" "")))]
7458 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7461 (define_expand "divsf3"
7462 [(set (match_operand:SF 0 "register_operand" "")
7463 (div:SF (match_operand:SF 1 "register_operand" "")
7464 (match_operand:SF 2 "nonimmediate_operand" "")))]
7465 "TARGET_80387 || TARGET_SSE_MATH"
7468 ;; Remainder instructions.
7470 (define_expand "divmoddi4"
7471 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7472 (div:DI (match_operand:DI 1 "register_operand" "")
7473 (match_operand:DI 2 "nonimmediate_operand" "")))
7474 (set (match_operand:DI 3 "register_operand" "")
7475 (mod:DI (match_dup 1) (match_dup 2)))
7476 (clobber (reg:CC FLAGS_REG))])]
7480 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7481 ;; Penalize eax case slightly because it results in worse scheduling
7483 (define_insn "*divmoddi4_nocltd_rex64"
7484 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7485 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7486 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7487 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7488 (mod:DI (match_dup 2) (match_dup 3)))
7489 (clobber (reg:CC FLAGS_REG))]
7490 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7492 [(set_attr "type" "multi")])
7494 (define_insn "*divmoddi4_cltd_rex64"
7495 [(set (match_operand:DI 0 "register_operand" "=a")
7496 (div:DI (match_operand:DI 2 "register_operand" "a")
7497 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7498 (set (match_operand:DI 1 "register_operand" "=&d")
7499 (mod:DI (match_dup 2) (match_dup 3)))
7500 (clobber (reg:CC FLAGS_REG))]
7501 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7503 [(set_attr "type" "multi")])
7505 (define_insn "*divmoddi_noext_rex64"
7506 [(set (match_operand:DI 0 "register_operand" "=a")
7507 (div:DI (match_operand:DI 1 "register_operand" "0")
7508 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7509 (set (match_operand:DI 3 "register_operand" "=d")
7510 (mod:DI (match_dup 1) (match_dup 2)))
7511 (use (match_operand:DI 4 "register_operand" "3"))
7512 (clobber (reg:CC FLAGS_REG))]
7515 [(set_attr "type" "idiv")
7516 (set_attr "mode" "DI")])
7519 [(set (match_operand:DI 0 "register_operand" "")
7520 (div:DI (match_operand:DI 1 "register_operand" "")
7521 (match_operand:DI 2 "nonimmediate_operand" "")))
7522 (set (match_operand:DI 3 "register_operand" "")
7523 (mod:DI (match_dup 1) (match_dup 2)))
7524 (clobber (reg:CC FLAGS_REG))]
7525 "TARGET_64BIT && reload_completed"
7526 [(parallel [(set (match_dup 3)
7527 (ashiftrt:DI (match_dup 4) (const_int 63)))
7528 (clobber (reg:CC FLAGS_REG))])
7529 (parallel [(set (match_dup 0)
7530 (div:DI (reg:DI 0) (match_dup 2)))
7532 (mod:DI (reg:DI 0) (match_dup 2)))
7534 (clobber (reg:CC FLAGS_REG))])]
7536 /* Avoid use of cltd in favor of a mov+shift. */
7537 if (!TARGET_USE_CLTD && !optimize_size)
7539 if (true_regnum (operands[1]))
7540 emit_move_insn (operands[0], operands[1]);
7542 emit_move_insn (operands[3], operands[1]);
7543 operands[4] = operands[3];
7547 gcc_assert (!true_regnum (operands[1]));
7548 operands[4] = operands[1];
7553 (define_expand "divmodsi4"
7554 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7555 (div:SI (match_operand:SI 1 "register_operand" "")
7556 (match_operand:SI 2 "nonimmediate_operand" "")))
7557 (set (match_operand:SI 3 "register_operand" "")
7558 (mod:SI (match_dup 1) (match_dup 2)))
7559 (clobber (reg:CC FLAGS_REG))])]
7563 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7564 ;; Penalize eax case slightly because it results in worse scheduling
7566 (define_insn "*divmodsi4_nocltd"
7567 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7568 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7569 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7570 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7571 (mod:SI (match_dup 2) (match_dup 3)))
7572 (clobber (reg:CC FLAGS_REG))]
7573 "!optimize_size && !TARGET_USE_CLTD"
7575 [(set_attr "type" "multi")])
7577 (define_insn "*divmodsi4_cltd"
7578 [(set (match_operand:SI 0 "register_operand" "=a")
7579 (div:SI (match_operand:SI 2 "register_operand" "a")
7580 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7581 (set (match_operand:SI 1 "register_operand" "=&d")
7582 (mod:SI (match_dup 2) (match_dup 3)))
7583 (clobber (reg:CC FLAGS_REG))]
7584 "optimize_size || TARGET_USE_CLTD"
7586 [(set_attr "type" "multi")])
7588 (define_insn "*divmodsi_noext"
7589 [(set (match_operand:SI 0 "register_operand" "=a")
7590 (div:SI (match_operand:SI 1 "register_operand" "0")
7591 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7592 (set (match_operand:SI 3 "register_operand" "=d")
7593 (mod:SI (match_dup 1) (match_dup 2)))
7594 (use (match_operand:SI 4 "register_operand" "3"))
7595 (clobber (reg:CC FLAGS_REG))]
7598 [(set_attr "type" "idiv")
7599 (set_attr "mode" "SI")])
7602 [(set (match_operand:SI 0 "register_operand" "")
7603 (div:SI (match_operand:SI 1 "register_operand" "")
7604 (match_operand:SI 2 "nonimmediate_operand" "")))
7605 (set (match_operand:SI 3 "register_operand" "")
7606 (mod:SI (match_dup 1) (match_dup 2)))
7607 (clobber (reg:CC FLAGS_REG))]
7609 [(parallel [(set (match_dup 3)
7610 (ashiftrt:SI (match_dup 4) (const_int 31)))
7611 (clobber (reg:CC FLAGS_REG))])
7612 (parallel [(set (match_dup 0)
7613 (div:SI (reg:SI 0) (match_dup 2)))
7615 (mod:SI (reg:SI 0) (match_dup 2)))
7617 (clobber (reg:CC FLAGS_REG))])]
7619 /* Avoid use of cltd in favor of a mov+shift. */
7620 if (!TARGET_USE_CLTD && !optimize_size)
7622 if (true_regnum (operands[1]))
7623 emit_move_insn (operands[0], operands[1]);
7625 emit_move_insn (operands[3], operands[1]);
7626 operands[4] = operands[3];
7630 gcc_assert (!true_regnum (operands[1]));
7631 operands[4] = operands[1];
7635 (define_insn "divmodhi4"
7636 [(set (match_operand:HI 0 "register_operand" "=a")
7637 (div:HI (match_operand:HI 1 "register_operand" "0")
7638 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7639 (set (match_operand:HI 3 "register_operand" "=&d")
7640 (mod:HI (match_dup 1) (match_dup 2)))
7641 (clobber (reg:CC FLAGS_REG))]
7642 "TARGET_HIMODE_MATH"
7644 [(set_attr "type" "multi")
7645 (set_attr "length_immediate" "0")
7646 (set_attr "mode" "SI")])
7648 (define_insn "udivmoddi4"
7649 [(set (match_operand:DI 0 "register_operand" "=a")
7650 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7651 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7652 (set (match_operand:DI 3 "register_operand" "=&d")
7653 (umod:DI (match_dup 1) (match_dup 2)))
7654 (clobber (reg:CC FLAGS_REG))]
7656 "xor{q}\t%3, %3\;div{q}\t%2"
7657 [(set_attr "type" "multi")
7658 (set_attr "length_immediate" "0")
7659 (set_attr "mode" "DI")])
7661 (define_insn "*udivmoddi4_noext"
7662 [(set (match_operand:DI 0 "register_operand" "=a")
7663 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7664 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7665 (set (match_operand:DI 3 "register_operand" "=d")
7666 (umod:DI (match_dup 1) (match_dup 2)))
7668 (clobber (reg:CC FLAGS_REG))]
7671 [(set_attr "type" "idiv")
7672 (set_attr "mode" "DI")])
7675 [(set (match_operand:DI 0 "register_operand" "")
7676 (udiv:DI (match_operand:DI 1 "register_operand" "")
7677 (match_operand:DI 2 "nonimmediate_operand" "")))
7678 (set (match_operand:DI 3 "register_operand" "")
7679 (umod:DI (match_dup 1) (match_dup 2)))
7680 (clobber (reg:CC FLAGS_REG))]
7681 "TARGET_64BIT && reload_completed"
7682 [(set (match_dup 3) (const_int 0))
7683 (parallel [(set (match_dup 0)
7684 (udiv:DI (match_dup 1) (match_dup 2)))
7686 (umod:DI (match_dup 1) (match_dup 2)))
7688 (clobber (reg:CC FLAGS_REG))])]
7691 (define_insn "udivmodsi4"
7692 [(set (match_operand:SI 0 "register_operand" "=a")
7693 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7694 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7695 (set (match_operand:SI 3 "register_operand" "=&d")
7696 (umod:SI (match_dup 1) (match_dup 2)))
7697 (clobber (reg:CC FLAGS_REG))]
7699 "xor{l}\t%3, %3\;div{l}\t%2"
7700 [(set_attr "type" "multi")
7701 (set_attr "length_immediate" "0")
7702 (set_attr "mode" "SI")])
7704 (define_insn "*udivmodsi4_noext"
7705 [(set (match_operand:SI 0 "register_operand" "=a")
7706 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7707 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7708 (set (match_operand:SI 3 "register_operand" "=d")
7709 (umod:SI (match_dup 1) (match_dup 2)))
7711 (clobber (reg:CC FLAGS_REG))]
7714 [(set_attr "type" "idiv")
7715 (set_attr "mode" "SI")])
7718 [(set (match_operand:SI 0 "register_operand" "")
7719 (udiv:SI (match_operand:SI 1 "register_operand" "")
7720 (match_operand:SI 2 "nonimmediate_operand" "")))
7721 (set (match_operand:SI 3 "register_operand" "")
7722 (umod:SI (match_dup 1) (match_dup 2)))
7723 (clobber (reg:CC FLAGS_REG))]
7725 [(set (match_dup 3) (const_int 0))
7726 (parallel [(set (match_dup 0)
7727 (udiv:SI (match_dup 1) (match_dup 2)))
7729 (umod:SI (match_dup 1) (match_dup 2)))
7731 (clobber (reg:CC FLAGS_REG))])]
7734 (define_expand "udivmodhi4"
7735 [(set (match_dup 4) (const_int 0))
7736 (parallel [(set (match_operand:HI 0 "register_operand" "")
7737 (udiv:HI (match_operand:HI 1 "register_operand" "")
7738 (match_operand:HI 2 "nonimmediate_operand" "")))
7739 (set (match_operand:HI 3 "register_operand" "")
7740 (umod:HI (match_dup 1) (match_dup 2)))
7742 (clobber (reg:CC FLAGS_REG))])]
7743 "TARGET_HIMODE_MATH"
7744 "operands[4] = gen_reg_rtx (HImode);")
7746 (define_insn "*udivmodhi_noext"
7747 [(set (match_operand:HI 0 "register_operand" "=a")
7748 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7749 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7750 (set (match_operand:HI 3 "register_operand" "=d")
7751 (umod:HI (match_dup 1) (match_dup 2)))
7752 (use (match_operand:HI 4 "register_operand" "3"))
7753 (clobber (reg:CC FLAGS_REG))]
7756 [(set_attr "type" "idiv")
7757 (set_attr "mode" "HI")])
7759 ;; We cannot use div/idiv for double division, because it causes
7760 ;; "division by zero" on the overflow and that's not what we expect
7761 ;; from truncate. Because true (non truncating) double division is
7762 ;; never generated, we can't create this insn anyway.
7765 ; [(set (match_operand:SI 0 "register_operand" "=a")
7767 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7769 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7770 ; (set (match_operand:SI 3 "register_operand" "=d")
7772 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7773 ; (clobber (reg:CC FLAGS_REG))]
7775 ; "div{l}\t{%2, %0|%0, %2}"
7776 ; [(set_attr "type" "idiv")])
7778 ;;- Logical AND instructions
7780 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7781 ;; Note that this excludes ah.
7783 (define_insn "*testdi_1_rex64"
7784 [(set (reg FLAGS_REG)
7786 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7787 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7789 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7790 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7792 test{l}\t{%k1, %k0|%k0, %k1}
7793 test{l}\t{%k1, %k0|%k0, %k1}
7794 test{q}\t{%1, %0|%0, %1}
7795 test{q}\t{%1, %0|%0, %1}
7796 test{q}\t{%1, %0|%0, %1}"
7797 [(set_attr "type" "test")
7798 (set_attr "modrm" "0,1,0,1,1")
7799 (set_attr "mode" "SI,SI,DI,DI,DI")
7800 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7802 (define_insn "testsi_1"
7803 [(set (reg FLAGS_REG)
7805 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7806 (match_operand:SI 1 "general_operand" "in,in,rin"))
7808 "ix86_match_ccmode (insn, CCNOmode)
7809 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7810 "test{l}\t{%1, %0|%0, %1}"
7811 [(set_attr "type" "test")
7812 (set_attr "modrm" "0,1,1")
7813 (set_attr "mode" "SI")
7814 (set_attr "pent_pair" "uv,np,uv")])
7816 (define_expand "testsi_ccno_1"
7817 [(set (reg:CCNO FLAGS_REG)
7819 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7820 (match_operand:SI 1 "nonmemory_operand" ""))
7825 (define_insn "*testhi_1"
7826 [(set (reg FLAGS_REG)
7827 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7828 (match_operand:HI 1 "general_operand" "n,n,rn"))
7830 "ix86_match_ccmode (insn, CCNOmode)
7831 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7832 "test{w}\t{%1, %0|%0, %1}"
7833 [(set_attr "type" "test")
7834 (set_attr "modrm" "0,1,1")
7835 (set_attr "mode" "HI")
7836 (set_attr "pent_pair" "uv,np,uv")])
7838 (define_expand "testqi_ccz_1"
7839 [(set (reg:CCZ FLAGS_REG)
7840 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7841 (match_operand:QI 1 "nonmemory_operand" ""))
7846 (define_insn "*testqi_1_maybe_si"
7847 [(set (reg FLAGS_REG)
7850 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7851 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7853 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7854 && ix86_match_ccmode (insn,
7855 CONST_INT_P (operands[1])
7856 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7858 if (which_alternative == 3)
7860 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7861 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7862 return "test{l}\t{%1, %k0|%k0, %1}";
7864 return "test{b}\t{%1, %0|%0, %1}";
7866 [(set_attr "type" "test")
7867 (set_attr "modrm" "0,1,1,1")
7868 (set_attr "mode" "QI,QI,QI,SI")
7869 (set_attr "pent_pair" "uv,np,uv,np")])
7871 (define_insn "*testqi_1"
7872 [(set (reg FLAGS_REG)
7875 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7876 (match_operand:QI 1 "general_operand" "n,n,qn"))
7878 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7879 && ix86_match_ccmode (insn, CCNOmode)"
7880 "test{b}\t{%1, %0|%0, %1}"
7881 [(set_attr "type" "test")
7882 (set_attr "modrm" "0,1,1")
7883 (set_attr "mode" "QI")
7884 (set_attr "pent_pair" "uv,np,uv")])
7886 (define_expand "testqi_ext_ccno_0"
7887 [(set (reg:CCNO FLAGS_REG)
7891 (match_operand 0 "ext_register_operand" "")
7894 (match_operand 1 "const_int_operand" ""))
7899 (define_insn "*testqi_ext_0"
7900 [(set (reg FLAGS_REG)
7904 (match_operand 0 "ext_register_operand" "Q")
7907 (match_operand 1 "const_int_operand" "n"))
7909 "ix86_match_ccmode (insn, CCNOmode)"
7910 "test{b}\t{%1, %h0|%h0, %1}"
7911 [(set_attr "type" "test")
7912 (set_attr "mode" "QI")
7913 (set_attr "length_immediate" "1")
7914 (set_attr "pent_pair" "np")])
7916 (define_insn "*testqi_ext_1"
7917 [(set (reg FLAGS_REG)
7921 (match_operand 0 "ext_register_operand" "Q")
7925 (match_operand:QI 1 "general_operand" "Qm")))
7927 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7928 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7929 "test{b}\t{%1, %h0|%h0, %1}"
7930 [(set_attr "type" "test")
7931 (set_attr "mode" "QI")])
7933 (define_insn "*testqi_ext_1_rex64"
7934 [(set (reg FLAGS_REG)
7938 (match_operand 0 "ext_register_operand" "Q")
7942 (match_operand:QI 1 "register_operand" "Q")))
7944 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7945 "test{b}\t{%1, %h0|%h0, %1}"
7946 [(set_attr "type" "test")
7947 (set_attr "mode" "QI")])
7949 (define_insn "*testqi_ext_2"
7950 [(set (reg FLAGS_REG)
7954 (match_operand 0 "ext_register_operand" "Q")
7958 (match_operand 1 "ext_register_operand" "Q")
7962 "ix86_match_ccmode (insn, CCNOmode)"
7963 "test{b}\t{%h1, %h0|%h0, %h1}"
7964 [(set_attr "type" "test")
7965 (set_attr "mode" "QI")])
7967 ;; Combine likes to form bit extractions for some tests. Humor it.
7968 (define_insn "*testqi_ext_3"
7969 [(set (reg FLAGS_REG)
7970 (compare (zero_extract:SI
7971 (match_operand 0 "nonimmediate_operand" "rm")
7972 (match_operand:SI 1 "const_int_operand" "")
7973 (match_operand:SI 2 "const_int_operand" ""))
7975 "ix86_match_ccmode (insn, CCNOmode)
7976 && INTVAL (operands[1]) > 0
7977 && INTVAL (operands[2]) >= 0
7978 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7979 && (GET_MODE (operands[0]) == SImode
7980 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7981 || GET_MODE (operands[0]) == HImode
7982 || GET_MODE (operands[0]) == QImode)"
7985 (define_insn "*testqi_ext_3_rex64"
7986 [(set (reg FLAGS_REG)
7987 (compare (zero_extract:DI
7988 (match_operand 0 "nonimmediate_operand" "rm")
7989 (match_operand:DI 1 "const_int_operand" "")
7990 (match_operand:DI 2 "const_int_operand" ""))
7993 && ix86_match_ccmode (insn, CCNOmode)
7994 && INTVAL (operands[1]) > 0
7995 && INTVAL (operands[2]) >= 0
7996 /* Ensure that resulting mask is zero or sign extended operand. */
7997 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7998 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7999 && INTVAL (operands[1]) > 32))
8000 && (GET_MODE (operands[0]) == SImode
8001 || GET_MODE (operands[0]) == DImode
8002 || GET_MODE (operands[0]) == HImode
8003 || GET_MODE (operands[0]) == QImode)"
8007 [(set (match_operand 0 "flags_reg_operand" "")
8008 (match_operator 1 "compare_operator"
8010 (match_operand 2 "nonimmediate_operand" "")
8011 (match_operand 3 "const_int_operand" "")
8012 (match_operand 4 "const_int_operand" ""))
8014 "ix86_match_ccmode (insn, CCNOmode)"
8015 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8017 rtx val = operands[2];
8018 HOST_WIDE_INT len = INTVAL (operands[3]);
8019 HOST_WIDE_INT pos = INTVAL (operands[4]);
8021 enum machine_mode mode, submode;
8023 mode = GET_MODE (val);
8026 /* ??? Combine likes to put non-volatile mem extractions in QImode
8027 no matter the size of the test. So find a mode that works. */
8028 if (! MEM_VOLATILE_P (val))
8030 mode = smallest_mode_for_size (pos + len, MODE_INT);
8031 val = adjust_address (val, mode, 0);
8034 else if (GET_CODE (val) == SUBREG
8035 && (submode = GET_MODE (SUBREG_REG (val)),
8036 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8037 && pos + len <= GET_MODE_BITSIZE (submode))
8039 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8041 val = SUBREG_REG (val);
8043 else if (mode == HImode && pos + len <= 8)
8045 /* Small HImode tests can be converted to QImode. */
8047 val = gen_lowpart (QImode, val);
8050 if (len == HOST_BITS_PER_WIDE_INT)
8053 mask = ((HOST_WIDE_INT)1 << len) - 1;
8056 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8059 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8060 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8061 ;; this is relatively important trick.
8062 ;; Do the conversion only post-reload to avoid limiting of the register class
8065 [(set (match_operand 0 "flags_reg_operand" "")
8066 (match_operator 1 "compare_operator"
8067 [(and (match_operand 2 "register_operand" "")
8068 (match_operand 3 "const_int_operand" ""))
8071 && QI_REG_P (operands[2])
8072 && GET_MODE (operands[2]) != QImode
8073 && ((ix86_match_ccmode (insn, CCZmode)
8074 && !(INTVAL (operands[3]) & ~(255 << 8)))
8075 || (ix86_match_ccmode (insn, CCNOmode)
8076 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8079 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8082 "operands[2] = gen_lowpart (SImode, operands[2]);
8083 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8086 [(set (match_operand 0 "flags_reg_operand" "")
8087 (match_operator 1 "compare_operator"
8088 [(and (match_operand 2 "nonimmediate_operand" "")
8089 (match_operand 3 "const_int_operand" ""))
8092 && GET_MODE (operands[2]) != QImode
8093 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8094 && ((ix86_match_ccmode (insn, CCZmode)
8095 && !(INTVAL (operands[3]) & ~255))
8096 || (ix86_match_ccmode (insn, CCNOmode)
8097 && !(INTVAL (operands[3]) & ~127)))"
8099 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8101 "operands[2] = gen_lowpart (QImode, operands[2]);
8102 operands[3] = gen_lowpart (QImode, operands[3]);")
8105 ;; %%% This used to optimize known byte-wide and operations to memory,
8106 ;; and sometimes to QImode registers. If this is considered useful,
8107 ;; it should be done with splitters.
8109 (define_expand "anddi3"
8110 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8111 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8112 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8113 (clobber (reg:CC FLAGS_REG))]
8115 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8117 (define_insn "*anddi_1_rex64"
8118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8119 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8120 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8121 (clobber (reg:CC FLAGS_REG))]
8122 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8124 switch (get_attr_type (insn))
8128 enum machine_mode mode;
8130 gcc_assert (CONST_INT_P (operands[2]));
8131 if (INTVAL (operands[2]) == 0xff)
8135 gcc_assert (INTVAL (operands[2]) == 0xffff);
8139 operands[1] = gen_lowpart (mode, operands[1]);
8141 return "movz{bq|x}\t{%1,%0|%0, %1}";
8143 return "movz{wq|x}\t{%1,%0|%0, %1}";
8147 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8148 if (get_attr_mode (insn) == MODE_SI)
8149 return "and{l}\t{%k2, %k0|%k0, %k2}";
8151 return "and{q}\t{%2, %0|%0, %2}";
8154 [(set_attr "type" "alu,alu,alu,imovx")
8155 (set_attr "length_immediate" "*,*,*,0")
8156 (set_attr "mode" "SI,DI,DI,DI")])
8158 (define_insn "*anddi_2"
8159 [(set (reg FLAGS_REG)
8160 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8161 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8163 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8164 (and:DI (match_dup 1) (match_dup 2)))]
8165 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8166 && ix86_binary_operator_ok (AND, DImode, operands)"
8168 and{l}\t{%k2, %k0|%k0, %k2}
8169 and{q}\t{%2, %0|%0, %2}
8170 and{q}\t{%2, %0|%0, %2}"
8171 [(set_attr "type" "alu")
8172 (set_attr "mode" "SI,DI,DI")])
8174 (define_expand "andsi3"
8175 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8176 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8177 (match_operand:SI 2 "general_operand" "")))
8178 (clobber (reg:CC FLAGS_REG))]
8180 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8182 (define_insn "*andsi_1"
8183 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8184 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8185 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8186 (clobber (reg:CC FLAGS_REG))]
8187 "ix86_binary_operator_ok (AND, SImode, operands)"
8189 switch (get_attr_type (insn))
8193 enum machine_mode mode;
8195 gcc_assert (CONST_INT_P (operands[2]));
8196 if (INTVAL (operands[2]) == 0xff)
8200 gcc_assert (INTVAL (operands[2]) == 0xffff);
8204 operands[1] = gen_lowpart (mode, operands[1]);
8206 return "movz{bl|x}\t{%1,%0|%0, %1}";
8208 return "movz{wl|x}\t{%1,%0|%0, %1}";
8212 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8213 return "and{l}\t{%2, %0|%0, %2}";
8216 [(set_attr "type" "alu,alu,imovx")
8217 (set_attr "length_immediate" "*,*,0")
8218 (set_attr "mode" "SI")])
8221 [(set (match_operand 0 "register_operand" "")
8223 (const_int -65536)))
8224 (clobber (reg:CC FLAGS_REG))]
8225 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8226 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8227 "operands[1] = gen_lowpart (HImode, operands[0]);")
8230 [(set (match_operand 0 "ext_register_operand" "")
8233 (clobber (reg:CC FLAGS_REG))]
8234 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8235 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8236 "operands[1] = gen_lowpart (QImode, operands[0]);")
8239 [(set (match_operand 0 "ext_register_operand" "")
8241 (const_int -65281)))
8242 (clobber (reg:CC FLAGS_REG))]
8243 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8244 [(parallel [(set (zero_extract:SI (match_dup 0)
8248 (zero_extract:SI (match_dup 0)
8251 (zero_extract:SI (match_dup 0)
8254 (clobber (reg:CC FLAGS_REG))])]
8255 "operands[0] = gen_lowpart (SImode, operands[0]);")
8257 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8258 (define_insn "*andsi_1_zext"
8259 [(set (match_operand:DI 0 "register_operand" "=r")
8261 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8262 (match_operand:SI 2 "general_operand" "rim"))))
8263 (clobber (reg:CC FLAGS_REG))]
8264 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8265 "and{l}\t{%2, %k0|%k0, %2}"
8266 [(set_attr "type" "alu")
8267 (set_attr "mode" "SI")])
8269 (define_insn "*andsi_2"
8270 [(set (reg FLAGS_REG)
8271 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8272 (match_operand:SI 2 "general_operand" "rim,ri"))
8274 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8275 (and:SI (match_dup 1) (match_dup 2)))]
8276 "ix86_match_ccmode (insn, CCNOmode)
8277 && ix86_binary_operator_ok (AND, SImode, operands)"
8278 "and{l}\t{%2, %0|%0, %2}"
8279 [(set_attr "type" "alu")
8280 (set_attr "mode" "SI")])
8282 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8283 (define_insn "*andsi_2_zext"
8284 [(set (reg FLAGS_REG)
8285 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8286 (match_operand:SI 2 "general_operand" "rim"))
8288 (set (match_operand:DI 0 "register_operand" "=r")
8289 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8290 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8291 && ix86_binary_operator_ok (AND, SImode, operands)"
8292 "and{l}\t{%2, %k0|%k0, %2}"
8293 [(set_attr "type" "alu")
8294 (set_attr "mode" "SI")])
8296 (define_expand "andhi3"
8297 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8298 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8299 (match_operand:HI 2 "general_operand" "")))
8300 (clobber (reg:CC FLAGS_REG))]
8301 "TARGET_HIMODE_MATH"
8302 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8304 (define_insn "*andhi_1"
8305 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8306 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8307 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8308 (clobber (reg:CC FLAGS_REG))]
8309 "ix86_binary_operator_ok (AND, HImode, operands)"
8311 switch (get_attr_type (insn))
8314 gcc_assert (CONST_INT_P (operands[2]));
8315 gcc_assert (INTVAL (operands[2]) == 0xff);
8316 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8319 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8321 return "and{w}\t{%2, %0|%0, %2}";
8324 [(set_attr "type" "alu,alu,imovx")
8325 (set_attr "length_immediate" "*,*,0")
8326 (set_attr "mode" "HI,HI,SI")])
8328 (define_insn "*andhi_2"
8329 [(set (reg FLAGS_REG)
8330 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8331 (match_operand:HI 2 "general_operand" "rim,ri"))
8333 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8334 (and:HI (match_dup 1) (match_dup 2)))]
8335 "ix86_match_ccmode (insn, CCNOmode)
8336 && ix86_binary_operator_ok (AND, HImode, operands)"
8337 "and{w}\t{%2, %0|%0, %2}"
8338 [(set_attr "type" "alu")
8339 (set_attr "mode" "HI")])
8341 (define_expand "andqi3"
8342 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8343 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8344 (match_operand:QI 2 "general_operand" "")))
8345 (clobber (reg:CC FLAGS_REG))]
8346 "TARGET_QIMODE_MATH"
8347 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8349 ;; %%% Potential partial reg stall on alternative 2. What to do?
8350 (define_insn "*andqi_1"
8351 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8352 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8353 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8354 (clobber (reg:CC FLAGS_REG))]
8355 "ix86_binary_operator_ok (AND, QImode, operands)"
8357 and{b}\t{%2, %0|%0, %2}
8358 and{b}\t{%2, %0|%0, %2}
8359 and{l}\t{%k2, %k0|%k0, %k2}"
8360 [(set_attr "type" "alu")
8361 (set_attr "mode" "QI,QI,SI")])
8363 (define_insn "*andqi_1_slp"
8364 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8365 (and:QI (match_dup 0)
8366 (match_operand:QI 1 "general_operand" "qi,qmi")))
8367 (clobber (reg:CC FLAGS_REG))]
8368 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8369 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8370 "and{b}\t{%1, %0|%0, %1}"
8371 [(set_attr "type" "alu1")
8372 (set_attr "mode" "QI")])
8374 (define_insn "*andqi_2_maybe_si"
8375 [(set (reg FLAGS_REG)
8377 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8378 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8380 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8381 (and:QI (match_dup 1) (match_dup 2)))]
8382 "ix86_binary_operator_ok (AND, QImode, operands)
8383 && ix86_match_ccmode (insn,
8384 CONST_INT_P (operands[2])
8385 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8387 if (which_alternative == 2)
8389 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8390 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8391 return "and{l}\t{%2, %k0|%k0, %2}";
8393 return "and{b}\t{%2, %0|%0, %2}";
8395 [(set_attr "type" "alu")
8396 (set_attr "mode" "QI,QI,SI")])
8398 (define_insn "*andqi_2"
8399 [(set (reg FLAGS_REG)
8401 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8402 (match_operand:QI 2 "general_operand" "qim,qi"))
8404 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8405 (and:QI (match_dup 1) (match_dup 2)))]
8406 "ix86_match_ccmode (insn, CCNOmode)
8407 && ix86_binary_operator_ok (AND, QImode, operands)"
8408 "and{b}\t{%2, %0|%0, %2}"
8409 [(set_attr "type" "alu")
8410 (set_attr "mode" "QI")])
8412 (define_insn "*andqi_2_slp"
8413 [(set (reg FLAGS_REG)
8415 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8416 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8418 (set (strict_low_part (match_dup 0))
8419 (and:QI (match_dup 0) (match_dup 1)))]
8420 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8421 && ix86_match_ccmode (insn, CCNOmode)
8422 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8423 "and{b}\t{%1, %0|%0, %1}"
8424 [(set_attr "type" "alu1")
8425 (set_attr "mode" "QI")])
8427 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8428 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8429 ;; for a QImode operand, which of course failed.
8431 (define_insn "andqi_ext_0"
8432 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8437 (match_operand 1 "ext_register_operand" "0")
8440 (match_operand 2 "const_int_operand" "n")))
8441 (clobber (reg:CC FLAGS_REG))]
8443 "and{b}\t{%2, %h0|%h0, %2}"
8444 [(set_attr "type" "alu")
8445 (set_attr "length_immediate" "1")
8446 (set_attr "mode" "QI")])
8448 ;; Generated by peephole translating test to and. This shows up
8449 ;; often in fp comparisons.
8451 (define_insn "*andqi_ext_0_cc"
8452 [(set (reg FLAGS_REG)
8456 (match_operand 1 "ext_register_operand" "0")
8459 (match_operand 2 "const_int_operand" "n"))
8461 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8470 "ix86_match_ccmode (insn, CCNOmode)"
8471 "and{b}\t{%2, %h0|%h0, %2}"
8472 [(set_attr "type" "alu")
8473 (set_attr "length_immediate" "1")
8474 (set_attr "mode" "QI")])
8476 (define_insn "*andqi_ext_1"
8477 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8482 (match_operand 1 "ext_register_operand" "0")
8486 (match_operand:QI 2 "general_operand" "Qm"))))
8487 (clobber (reg:CC FLAGS_REG))]
8489 "and{b}\t{%2, %h0|%h0, %2}"
8490 [(set_attr "type" "alu")
8491 (set_attr "length_immediate" "0")
8492 (set_attr "mode" "QI")])
8494 (define_insn "*andqi_ext_1_rex64"
8495 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8500 (match_operand 1 "ext_register_operand" "0")
8504 (match_operand 2 "ext_register_operand" "Q"))))
8505 (clobber (reg:CC FLAGS_REG))]
8507 "and{b}\t{%2, %h0|%h0, %2}"
8508 [(set_attr "type" "alu")
8509 (set_attr "length_immediate" "0")
8510 (set_attr "mode" "QI")])
8512 (define_insn "*andqi_ext_2"
8513 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8518 (match_operand 1 "ext_register_operand" "%0")
8522 (match_operand 2 "ext_register_operand" "Q")
8525 (clobber (reg:CC FLAGS_REG))]
8527 "and{b}\t{%h2, %h0|%h0, %h2}"
8528 [(set_attr "type" "alu")
8529 (set_attr "length_immediate" "0")
8530 (set_attr "mode" "QI")])
8532 ;; Convert wide AND instructions with immediate operand to shorter QImode
8533 ;; equivalents when possible.
8534 ;; Don't do the splitting with memory operands, since it introduces risk
8535 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8536 ;; for size, but that can (should?) be handled by generic code instead.
8538 [(set (match_operand 0 "register_operand" "")
8539 (and (match_operand 1 "register_operand" "")
8540 (match_operand 2 "const_int_operand" "")))
8541 (clobber (reg:CC FLAGS_REG))]
8543 && QI_REG_P (operands[0])
8544 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8545 && !(~INTVAL (operands[2]) & ~(255 << 8))
8546 && GET_MODE (operands[0]) != QImode"
8547 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8548 (and:SI (zero_extract:SI (match_dup 1)
8549 (const_int 8) (const_int 8))
8551 (clobber (reg:CC FLAGS_REG))])]
8552 "operands[0] = gen_lowpart (SImode, operands[0]);
8553 operands[1] = gen_lowpart (SImode, operands[1]);
8554 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8556 ;; Since AND can be encoded with sign extended immediate, this is only
8557 ;; profitable when 7th bit is not set.
8559 [(set (match_operand 0 "register_operand" "")
8560 (and (match_operand 1 "general_operand" "")
8561 (match_operand 2 "const_int_operand" "")))
8562 (clobber (reg:CC FLAGS_REG))]
8564 && ANY_QI_REG_P (operands[0])
8565 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8566 && !(~INTVAL (operands[2]) & ~255)
8567 && !(INTVAL (operands[2]) & 128)
8568 && GET_MODE (operands[0]) != QImode"
8569 [(parallel [(set (strict_low_part (match_dup 0))
8570 (and:QI (match_dup 1)
8572 (clobber (reg:CC FLAGS_REG))])]
8573 "operands[0] = gen_lowpart (QImode, operands[0]);
8574 operands[1] = gen_lowpart (QImode, operands[1]);
8575 operands[2] = gen_lowpart (QImode, operands[2]);")
8577 ;; Logical inclusive OR instructions
8579 ;; %%% This used to optimize known byte-wide and operations to memory.
8580 ;; If this is considered useful, it should be done with splitters.
8582 (define_expand "iordi3"
8583 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8584 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8585 (match_operand:DI 2 "x86_64_general_operand" "")))
8586 (clobber (reg:CC FLAGS_REG))]
8588 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8590 (define_insn "*iordi_1_rex64"
8591 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8592 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8593 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8594 (clobber (reg:CC FLAGS_REG))]
8596 && ix86_binary_operator_ok (IOR, DImode, operands)"
8597 "or{q}\t{%2, %0|%0, %2}"
8598 [(set_attr "type" "alu")
8599 (set_attr "mode" "DI")])
8601 (define_insn "*iordi_2_rex64"
8602 [(set (reg FLAGS_REG)
8603 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8604 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8606 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8607 (ior:DI (match_dup 1) (match_dup 2)))]
8609 && ix86_match_ccmode (insn, CCNOmode)
8610 && ix86_binary_operator_ok (IOR, DImode, operands)"
8611 "or{q}\t{%2, %0|%0, %2}"
8612 [(set_attr "type" "alu")
8613 (set_attr "mode" "DI")])
8615 (define_insn "*iordi_3_rex64"
8616 [(set (reg FLAGS_REG)
8617 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8618 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8620 (clobber (match_scratch:DI 0 "=r"))]
8622 && ix86_match_ccmode (insn, CCNOmode)
8623 && ix86_binary_operator_ok (IOR, DImode, operands)"
8624 "or{q}\t{%2, %0|%0, %2}"
8625 [(set_attr "type" "alu")
8626 (set_attr "mode" "DI")])
8629 (define_expand "iorsi3"
8630 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8631 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8632 (match_operand:SI 2 "general_operand" "")))
8633 (clobber (reg:CC FLAGS_REG))]
8635 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8637 (define_insn "*iorsi_1"
8638 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8639 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8640 (match_operand:SI 2 "general_operand" "ri,rmi")))
8641 (clobber (reg:CC FLAGS_REG))]
8642 "ix86_binary_operator_ok (IOR, SImode, operands)"
8643 "or{l}\t{%2, %0|%0, %2}"
8644 [(set_attr "type" "alu")
8645 (set_attr "mode" "SI")])
8647 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8648 (define_insn "*iorsi_1_zext"
8649 [(set (match_operand:DI 0 "register_operand" "=rm")
8651 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8652 (match_operand:SI 2 "general_operand" "rim"))))
8653 (clobber (reg:CC FLAGS_REG))]
8654 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8655 "or{l}\t{%2, %k0|%k0, %2}"
8656 [(set_attr "type" "alu")
8657 (set_attr "mode" "SI")])
8659 (define_insn "*iorsi_1_zext_imm"
8660 [(set (match_operand:DI 0 "register_operand" "=rm")
8661 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8662 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8663 (clobber (reg:CC FLAGS_REG))]
8665 "or{l}\t{%2, %k0|%k0, %2}"
8666 [(set_attr "type" "alu")
8667 (set_attr "mode" "SI")])
8669 (define_insn "*iorsi_2"
8670 [(set (reg FLAGS_REG)
8671 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8672 (match_operand:SI 2 "general_operand" "rim,ri"))
8674 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8675 (ior:SI (match_dup 1) (match_dup 2)))]
8676 "ix86_match_ccmode (insn, CCNOmode)
8677 && ix86_binary_operator_ok (IOR, SImode, operands)"
8678 "or{l}\t{%2, %0|%0, %2}"
8679 [(set_attr "type" "alu")
8680 (set_attr "mode" "SI")])
8682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8683 ;; ??? Special case for immediate operand is missing - it is tricky.
8684 (define_insn "*iorsi_2_zext"
8685 [(set (reg FLAGS_REG)
8686 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8687 (match_operand:SI 2 "general_operand" "rim"))
8689 (set (match_operand:DI 0 "register_operand" "=r")
8690 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8691 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8692 && ix86_binary_operator_ok (IOR, SImode, operands)"
8693 "or{l}\t{%2, %k0|%k0, %2}"
8694 [(set_attr "type" "alu")
8695 (set_attr "mode" "SI")])
8697 (define_insn "*iorsi_2_zext_imm"
8698 [(set (reg FLAGS_REG)
8699 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8700 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8702 (set (match_operand:DI 0 "register_operand" "=r")
8703 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8704 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8705 && ix86_binary_operator_ok (IOR, SImode, operands)"
8706 "or{l}\t{%2, %k0|%k0, %2}"
8707 [(set_attr "type" "alu")
8708 (set_attr "mode" "SI")])
8710 (define_insn "*iorsi_3"
8711 [(set (reg FLAGS_REG)
8712 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8713 (match_operand:SI 2 "general_operand" "rim"))
8715 (clobber (match_scratch:SI 0 "=r"))]
8716 "ix86_match_ccmode (insn, CCNOmode)
8717 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8718 "or{l}\t{%2, %0|%0, %2}"
8719 [(set_attr "type" "alu")
8720 (set_attr "mode" "SI")])
8722 (define_expand "iorhi3"
8723 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8724 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8725 (match_operand:HI 2 "general_operand" "")))
8726 (clobber (reg:CC FLAGS_REG))]
8727 "TARGET_HIMODE_MATH"
8728 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8730 (define_insn "*iorhi_1"
8731 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8732 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8733 (match_operand:HI 2 "general_operand" "rmi,ri")))
8734 (clobber (reg:CC FLAGS_REG))]
8735 "ix86_binary_operator_ok (IOR, HImode, operands)"
8736 "or{w}\t{%2, %0|%0, %2}"
8737 [(set_attr "type" "alu")
8738 (set_attr "mode" "HI")])
8740 (define_insn "*iorhi_2"
8741 [(set (reg FLAGS_REG)
8742 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8743 (match_operand:HI 2 "general_operand" "rim,ri"))
8745 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8746 (ior:HI (match_dup 1) (match_dup 2)))]
8747 "ix86_match_ccmode (insn, CCNOmode)
8748 && ix86_binary_operator_ok (IOR, HImode, operands)"
8749 "or{w}\t{%2, %0|%0, %2}"
8750 [(set_attr "type" "alu")
8751 (set_attr "mode" "HI")])
8753 (define_insn "*iorhi_3"
8754 [(set (reg FLAGS_REG)
8755 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8756 (match_operand:HI 2 "general_operand" "rim"))
8758 (clobber (match_scratch:HI 0 "=r"))]
8759 "ix86_match_ccmode (insn, CCNOmode)
8760 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8761 "or{w}\t{%2, %0|%0, %2}"
8762 [(set_attr "type" "alu")
8763 (set_attr "mode" "HI")])
8765 (define_expand "iorqi3"
8766 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8767 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8768 (match_operand:QI 2 "general_operand" "")))
8769 (clobber (reg:CC FLAGS_REG))]
8770 "TARGET_QIMODE_MATH"
8771 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8773 ;; %%% Potential partial reg stall on alternative 2. What to do?
8774 (define_insn "*iorqi_1"
8775 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8776 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8777 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8778 (clobber (reg:CC FLAGS_REG))]
8779 "ix86_binary_operator_ok (IOR, QImode, operands)"
8781 or{b}\t{%2, %0|%0, %2}
8782 or{b}\t{%2, %0|%0, %2}
8783 or{l}\t{%k2, %k0|%k0, %k2}"
8784 [(set_attr "type" "alu")
8785 (set_attr "mode" "QI,QI,SI")])
8787 (define_insn "*iorqi_1_slp"
8788 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8789 (ior:QI (match_dup 0)
8790 (match_operand:QI 1 "general_operand" "qmi,qi")))
8791 (clobber (reg:CC FLAGS_REG))]
8792 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8793 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8794 "or{b}\t{%1, %0|%0, %1}"
8795 [(set_attr "type" "alu1")
8796 (set_attr "mode" "QI")])
8798 (define_insn "*iorqi_2"
8799 [(set (reg FLAGS_REG)
8800 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8801 (match_operand:QI 2 "general_operand" "qim,qi"))
8803 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8804 (ior:QI (match_dup 1) (match_dup 2)))]
8805 "ix86_match_ccmode (insn, CCNOmode)
8806 && ix86_binary_operator_ok (IOR, QImode, operands)"
8807 "or{b}\t{%2, %0|%0, %2}"
8808 [(set_attr "type" "alu")
8809 (set_attr "mode" "QI")])
8811 (define_insn "*iorqi_2_slp"
8812 [(set (reg FLAGS_REG)
8813 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8814 (match_operand:QI 1 "general_operand" "qim,qi"))
8816 (set (strict_low_part (match_dup 0))
8817 (ior:QI (match_dup 0) (match_dup 1)))]
8818 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8819 && ix86_match_ccmode (insn, CCNOmode)
8820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8821 "or{b}\t{%1, %0|%0, %1}"
8822 [(set_attr "type" "alu1")
8823 (set_attr "mode" "QI")])
8825 (define_insn "*iorqi_3"
8826 [(set (reg FLAGS_REG)
8827 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8828 (match_operand:QI 2 "general_operand" "qim"))
8830 (clobber (match_scratch:QI 0 "=q"))]
8831 "ix86_match_ccmode (insn, CCNOmode)
8832 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8833 "or{b}\t{%2, %0|%0, %2}"
8834 [(set_attr "type" "alu")
8835 (set_attr "mode" "QI")])
8837 (define_insn "iorqi_ext_0"
8838 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8843 (match_operand 1 "ext_register_operand" "0")
8846 (match_operand 2 "const_int_operand" "n")))
8847 (clobber (reg:CC FLAGS_REG))]
8848 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8849 "or{b}\t{%2, %h0|%h0, %2}"
8850 [(set_attr "type" "alu")
8851 (set_attr "length_immediate" "1")
8852 (set_attr "mode" "QI")])
8854 (define_insn "*iorqi_ext_1"
8855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8860 (match_operand 1 "ext_register_operand" "0")
8864 (match_operand:QI 2 "general_operand" "Qm"))))
8865 (clobber (reg:CC FLAGS_REG))]
8867 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8868 "or{b}\t{%2, %h0|%h0, %2}"
8869 [(set_attr "type" "alu")
8870 (set_attr "length_immediate" "0")
8871 (set_attr "mode" "QI")])
8873 (define_insn "*iorqi_ext_1_rex64"
8874 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8879 (match_operand 1 "ext_register_operand" "0")
8883 (match_operand 2 "ext_register_operand" "Q"))))
8884 (clobber (reg:CC FLAGS_REG))]
8886 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8887 "or{b}\t{%2, %h0|%h0, %2}"
8888 [(set_attr "type" "alu")
8889 (set_attr "length_immediate" "0")
8890 (set_attr "mode" "QI")])
8892 (define_insn "*iorqi_ext_2"
8893 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8897 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8900 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8903 (clobber (reg:CC FLAGS_REG))]
8904 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8905 "ior{b}\t{%h2, %h0|%h0, %h2}"
8906 [(set_attr "type" "alu")
8907 (set_attr "length_immediate" "0")
8908 (set_attr "mode" "QI")])
8911 [(set (match_operand 0 "register_operand" "")
8912 (ior (match_operand 1 "register_operand" "")
8913 (match_operand 2 "const_int_operand" "")))
8914 (clobber (reg:CC FLAGS_REG))]
8916 && QI_REG_P (operands[0])
8917 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8918 && !(INTVAL (operands[2]) & ~(255 << 8))
8919 && GET_MODE (operands[0]) != QImode"
8920 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8921 (ior:SI (zero_extract:SI (match_dup 1)
8922 (const_int 8) (const_int 8))
8924 (clobber (reg:CC FLAGS_REG))])]
8925 "operands[0] = gen_lowpart (SImode, operands[0]);
8926 operands[1] = gen_lowpart (SImode, operands[1]);
8927 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8929 ;; Since OR can be encoded with sign extended immediate, this is only
8930 ;; profitable when 7th bit is set.
8932 [(set (match_operand 0 "register_operand" "")
8933 (ior (match_operand 1 "general_operand" "")
8934 (match_operand 2 "const_int_operand" "")))
8935 (clobber (reg:CC FLAGS_REG))]
8937 && ANY_QI_REG_P (operands[0])
8938 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8939 && !(INTVAL (operands[2]) & ~255)
8940 && (INTVAL (operands[2]) & 128)
8941 && GET_MODE (operands[0]) != QImode"
8942 [(parallel [(set (strict_low_part (match_dup 0))
8943 (ior:QI (match_dup 1)
8945 (clobber (reg:CC FLAGS_REG))])]
8946 "operands[0] = gen_lowpart (QImode, operands[0]);
8947 operands[1] = gen_lowpart (QImode, operands[1]);
8948 operands[2] = gen_lowpart (QImode, operands[2]);")
8950 ;; Logical XOR instructions
8952 ;; %%% This used to optimize known byte-wide and operations to memory.
8953 ;; If this is considered useful, it should be done with splitters.
8955 (define_expand "xordi3"
8956 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8957 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8958 (match_operand:DI 2 "x86_64_general_operand" "")))
8959 (clobber (reg:CC FLAGS_REG))]
8961 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8963 (define_insn "*xordi_1_rex64"
8964 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8965 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8966 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8967 (clobber (reg:CC FLAGS_REG))]
8969 && ix86_binary_operator_ok (XOR, DImode, operands)"
8971 xor{q}\t{%2, %0|%0, %2}
8972 xor{q}\t{%2, %0|%0, %2}"
8973 [(set_attr "type" "alu")
8974 (set_attr "mode" "DI,DI")])
8976 (define_insn "*xordi_2_rex64"
8977 [(set (reg FLAGS_REG)
8978 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8979 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8981 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8982 (xor:DI (match_dup 1) (match_dup 2)))]
8984 && ix86_match_ccmode (insn, CCNOmode)
8985 && ix86_binary_operator_ok (XOR, DImode, operands)"
8987 xor{q}\t{%2, %0|%0, %2}
8988 xor{q}\t{%2, %0|%0, %2}"
8989 [(set_attr "type" "alu")
8990 (set_attr "mode" "DI,DI")])
8992 (define_insn "*xordi_3_rex64"
8993 [(set (reg FLAGS_REG)
8994 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8995 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8997 (clobber (match_scratch:DI 0 "=r"))]
8999 && ix86_match_ccmode (insn, CCNOmode)
9000 && ix86_binary_operator_ok (XOR, DImode, operands)"
9001 "xor{q}\t{%2, %0|%0, %2}"
9002 [(set_attr "type" "alu")
9003 (set_attr "mode" "DI")])
9005 (define_expand "xorsi3"
9006 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9007 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9008 (match_operand:SI 2 "general_operand" "")))
9009 (clobber (reg:CC FLAGS_REG))]
9011 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9013 (define_insn "*xorsi_1"
9014 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9015 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9016 (match_operand:SI 2 "general_operand" "ri,rm")))
9017 (clobber (reg:CC FLAGS_REG))]
9018 "ix86_binary_operator_ok (XOR, SImode, operands)"
9019 "xor{l}\t{%2, %0|%0, %2}"
9020 [(set_attr "type" "alu")
9021 (set_attr "mode" "SI")])
9023 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9024 ;; Add speccase for immediates
9025 (define_insn "*xorsi_1_zext"
9026 [(set (match_operand:DI 0 "register_operand" "=r")
9028 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9029 (match_operand:SI 2 "general_operand" "rim"))))
9030 (clobber (reg:CC FLAGS_REG))]
9031 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9032 "xor{l}\t{%2, %k0|%k0, %2}"
9033 [(set_attr "type" "alu")
9034 (set_attr "mode" "SI")])
9036 (define_insn "*xorsi_1_zext_imm"
9037 [(set (match_operand:DI 0 "register_operand" "=r")
9038 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9039 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9040 (clobber (reg:CC FLAGS_REG))]
9041 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9042 "xor{l}\t{%2, %k0|%k0, %2}"
9043 [(set_attr "type" "alu")
9044 (set_attr "mode" "SI")])
9046 (define_insn "*xorsi_2"
9047 [(set (reg FLAGS_REG)
9048 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9049 (match_operand:SI 2 "general_operand" "rim,ri"))
9051 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9052 (xor:SI (match_dup 1) (match_dup 2)))]
9053 "ix86_match_ccmode (insn, CCNOmode)
9054 && ix86_binary_operator_ok (XOR, SImode, operands)"
9055 "xor{l}\t{%2, %0|%0, %2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "mode" "SI")])
9059 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9060 ;; ??? Special case for immediate operand is missing - it is tricky.
9061 (define_insn "*xorsi_2_zext"
9062 [(set (reg FLAGS_REG)
9063 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9064 (match_operand:SI 2 "general_operand" "rim"))
9066 (set (match_operand:DI 0 "register_operand" "=r")
9067 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9068 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9069 && ix86_binary_operator_ok (XOR, SImode, operands)"
9070 "xor{l}\t{%2, %k0|%k0, %2}"
9071 [(set_attr "type" "alu")
9072 (set_attr "mode" "SI")])
9074 (define_insn "*xorsi_2_zext_imm"
9075 [(set (reg FLAGS_REG)
9076 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9077 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9079 (set (match_operand:DI 0 "register_operand" "=r")
9080 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9081 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9082 && ix86_binary_operator_ok (XOR, SImode, operands)"
9083 "xor{l}\t{%2, %k0|%k0, %2}"
9084 [(set_attr "type" "alu")
9085 (set_attr "mode" "SI")])
9087 (define_insn "*xorsi_3"
9088 [(set (reg FLAGS_REG)
9089 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9090 (match_operand:SI 2 "general_operand" "rim"))
9092 (clobber (match_scratch:SI 0 "=r"))]
9093 "ix86_match_ccmode (insn, CCNOmode)
9094 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9095 "xor{l}\t{%2, %0|%0, %2}"
9096 [(set_attr "type" "alu")
9097 (set_attr "mode" "SI")])
9099 (define_expand "xorhi3"
9100 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9101 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9102 (match_operand:HI 2 "general_operand" "")))
9103 (clobber (reg:CC FLAGS_REG))]
9104 "TARGET_HIMODE_MATH"
9105 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9107 (define_insn "*xorhi_1"
9108 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9109 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9110 (match_operand:HI 2 "general_operand" "rmi,ri")))
9111 (clobber (reg:CC FLAGS_REG))]
9112 "ix86_binary_operator_ok (XOR, HImode, operands)"
9113 "xor{w}\t{%2, %0|%0, %2}"
9114 [(set_attr "type" "alu")
9115 (set_attr "mode" "HI")])
9117 (define_insn "*xorhi_2"
9118 [(set (reg FLAGS_REG)
9119 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9120 (match_operand:HI 2 "general_operand" "rim,ri"))
9122 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9123 (xor:HI (match_dup 1) (match_dup 2)))]
9124 "ix86_match_ccmode (insn, CCNOmode)
9125 && ix86_binary_operator_ok (XOR, HImode, operands)"
9126 "xor{w}\t{%2, %0|%0, %2}"
9127 [(set_attr "type" "alu")
9128 (set_attr "mode" "HI")])
9130 (define_insn "*xorhi_3"
9131 [(set (reg FLAGS_REG)
9132 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9133 (match_operand:HI 2 "general_operand" "rim"))
9135 (clobber (match_scratch:HI 0 "=r"))]
9136 "ix86_match_ccmode (insn, CCNOmode)
9137 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9138 "xor{w}\t{%2, %0|%0, %2}"
9139 [(set_attr "type" "alu")
9140 (set_attr "mode" "HI")])
9142 (define_expand "xorqi3"
9143 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9144 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9145 (match_operand:QI 2 "general_operand" "")))
9146 (clobber (reg:CC FLAGS_REG))]
9147 "TARGET_QIMODE_MATH"
9148 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9150 ;; %%% Potential partial reg stall on alternative 2. What to do?
9151 (define_insn "*xorqi_1"
9152 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9153 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9154 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9155 (clobber (reg:CC FLAGS_REG))]
9156 "ix86_binary_operator_ok (XOR, QImode, operands)"
9158 xor{b}\t{%2, %0|%0, %2}
9159 xor{b}\t{%2, %0|%0, %2}
9160 xor{l}\t{%k2, %k0|%k0, %k2}"
9161 [(set_attr "type" "alu")
9162 (set_attr "mode" "QI,QI,SI")])
9164 (define_insn "*xorqi_1_slp"
9165 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9166 (xor:QI (match_dup 0)
9167 (match_operand:QI 1 "general_operand" "qi,qmi")))
9168 (clobber (reg:CC FLAGS_REG))]
9169 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9170 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9171 "xor{b}\t{%1, %0|%0, %1}"
9172 [(set_attr "type" "alu1")
9173 (set_attr "mode" "QI")])
9175 (define_insn "xorqi_ext_0"
9176 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9181 (match_operand 1 "ext_register_operand" "0")
9184 (match_operand 2 "const_int_operand" "n")))
9185 (clobber (reg:CC FLAGS_REG))]
9186 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9187 "xor{b}\t{%2, %h0|%h0, %2}"
9188 [(set_attr "type" "alu")
9189 (set_attr "length_immediate" "1")
9190 (set_attr "mode" "QI")])
9192 (define_insn "*xorqi_ext_1"
9193 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9198 (match_operand 1 "ext_register_operand" "0")
9202 (match_operand:QI 2 "general_operand" "Qm"))))
9203 (clobber (reg:CC FLAGS_REG))]
9205 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9206 "xor{b}\t{%2, %h0|%h0, %2}"
9207 [(set_attr "type" "alu")
9208 (set_attr "length_immediate" "0")
9209 (set_attr "mode" "QI")])
9211 (define_insn "*xorqi_ext_1_rex64"
9212 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9217 (match_operand 1 "ext_register_operand" "0")
9221 (match_operand 2 "ext_register_operand" "Q"))))
9222 (clobber (reg:CC FLAGS_REG))]
9224 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9225 "xor{b}\t{%2, %h0|%h0, %2}"
9226 [(set_attr "type" "alu")
9227 (set_attr "length_immediate" "0")
9228 (set_attr "mode" "QI")])
9230 (define_insn "*xorqi_ext_2"
9231 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9235 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9238 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9241 (clobber (reg:CC FLAGS_REG))]
9242 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9243 "xor{b}\t{%h2, %h0|%h0, %h2}"
9244 [(set_attr "type" "alu")
9245 (set_attr "length_immediate" "0")
9246 (set_attr "mode" "QI")])
9248 (define_insn "*xorqi_cc_1"
9249 [(set (reg FLAGS_REG)
9251 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9252 (match_operand:QI 2 "general_operand" "qim,qi"))
9254 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9255 (xor:QI (match_dup 1) (match_dup 2)))]
9256 "ix86_match_ccmode (insn, CCNOmode)
9257 && ix86_binary_operator_ok (XOR, QImode, operands)"
9258 "xor{b}\t{%2, %0|%0, %2}"
9259 [(set_attr "type" "alu")
9260 (set_attr "mode" "QI")])
9262 (define_insn "*xorqi_2_slp"
9263 [(set (reg FLAGS_REG)
9264 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9265 (match_operand:QI 1 "general_operand" "qim,qi"))
9267 (set (strict_low_part (match_dup 0))
9268 (xor:QI (match_dup 0) (match_dup 1)))]
9269 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9270 && ix86_match_ccmode (insn, CCNOmode)
9271 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9272 "xor{b}\t{%1, %0|%0, %1}"
9273 [(set_attr "type" "alu1")
9274 (set_attr "mode" "QI")])
9276 (define_insn "*xorqi_cc_2"
9277 [(set (reg FLAGS_REG)
9279 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9280 (match_operand:QI 2 "general_operand" "qim"))
9282 (clobber (match_scratch:QI 0 "=q"))]
9283 "ix86_match_ccmode (insn, CCNOmode)
9284 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9285 "xor{b}\t{%2, %0|%0, %2}"
9286 [(set_attr "type" "alu")
9287 (set_attr "mode" "QI")])
9289 (define_insn "*xorqi_cc_ext_1"
9290 [(set (reg FLAGS_REG)
9294 (match_operand 1 "ext_register_operand" "0")
9297 (match_operand:QI 2 "general_operand" "qmn"))
9299 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9303 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9305 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9306 "xor{b}\t{%2, %h0|%h0, %2}"
9307 [(set_attr "type" "alu")
9308 (set_attr "mode" "QI")])
9310 (define_insn "*xorqi_cc_ext_1_rex64"
9311 [(set (reg FLAGS_REG)
9315 (match_operand 1 "ext_register_operand" "0")
9318 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9320 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9324 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9326 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9327 "xor{b}\t{%2, %h0|%h0, %2}"
9328 [(set_attr "type" "alu")
9329 (set_attr "mode" "QI")])
9331 (define_expand "xorqi_cc_ext_1"
9333 (set (reg:CCNO FLAGS_REG)
9337 (match_operand 1 "ext_register_operand" "")
9340 (match_operand:QI 2 "general_operand" ""))
9342 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9346 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9352 [(set (match_operand 0 "register_operand" "")
9353 (xor (match_operand 1 "register_operand" "")
9354 (match_operand 2 "const_int_operand" "")))
9355 (clobber (reg:CC FLAGS_REG))]
9357 && QI_REG_P (operands[0])
9358 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9359 && !(INTVAL (operands[2]) & ~(255 << 8))
9360 && GET_MODE (operands[0]) != QImode"
9361 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9362 (xor:SI (zero_extract:SI (match_dup 1)
9363 (const_int 8) (const_int 8))
9365 (clobber (reg:CC FLAGS_REG))])]
9366 "operands[0] = gen_lowpart (SImode, operands[0]);
9367 operands[1] = gen_lowpart (SImode, operands[1]);
9368 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9370 ;; Since XOR can be encoded with sign extended immediate, this is only
9371 ;; profitable when 7th bit is set.
9373 [(set (match_operand 0 "register_operand" "")
9374 (xor (match_operand 1 "general_operand" "")
9375 (match_operand 2 "const_int_operand" "")))
9376 (clobber (reg:CC FLAGS_REG))]
9378 && ANY_QI_REG_P (operands[0])
9379 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9380 && !(INTVAL (operands[2]) & ~255)
9381 && (INTVAL (operands[2]) & 128)
9382 && GET_MODE (operands[0]) != QImode"
9383 [(parallel [(set (strict_low_part (match_dup 0))
9384 (xor:QI (match_dup 1)
9386 (clobber (reg:CC FLAGS_REG))])]
9387 "operands[0] = gen_lowpart (QImode, operands[0]);
9388 operands[1] = gen_lowpart (QImode, operands[1]);
9389 operands[2] = gen_lowpart (QImode, operands[2]);")
9391 ;; Negation instructions
9393 (define_expand "negti2"
9394 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9395 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9396 (clobber (reg:CC FLAGS_REG))])]
9398 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9400 (define_insn "*negti2_1"
9401 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9402 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9403 (clobber (reg:CC FLAGS_REG))]
9405 && ix86_unary_operator_ok (NEG, TImode, operands)"
9409 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9410 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9411 (clobber (reg:CC FLAGS_REG))]
9412 "TARGET_64BIT && reload_completed"
9414 [(set (reg:CCZ FLAGS_REG)
9415 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9416 (set (match_dup 0) (neg:DI (match_dup 2)))])
9419 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9422 (clobber (reg:CC FLAGS_REG))])
9425 (neg:DI (match_dup 1)))
9426 (clobber (reg:CC FLAGS_REG))])]
9427 "split_ti (operands+1, 1, operands+2, operands+3);
9428 split_ti (operands+0, 1, operands+0, operands+1);")
9430 (define_expand "negdi2"
9431 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9432 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9433 (clobber (reg:CC FLAGS_REG))])]
9435 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9437 (define_insn "*negdi2_1"
9438 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9439 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9440 (clobber (reg:CC FLAGS_REG))]
9442 && ix86_unary_operator_ok (NEG, DImode, operands)"
9446 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9447 (neg:DI (match_operand:DI 1 "general_operand" "")))
9448 (clobber (reg:CC FLAGS_REG))]
9449 "!TARGET_64BIT && reload_completed"
9451 [(set (reg:CCZ FLAGS_REG)
9452 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9453 (set (match_dup 0) (neg:SI (match_dup 2)))])
9456 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9459 (clobber (reg:CC FLAGS_REG))])
9462 (neg:SI (match_dup 1)))
9463 (clobber (reg:CC FLAGS_REG))])]
9464 "split_di (operands+1, 1, operands+2, operands+3);
9465 split_di (operands+0, 1, operands+0, operands+1);")
9467 (define_insn "*negdi2_1_rex64"
9468 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9469 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9470 (clobber (reg:CC FLAGS_REG))]
9471 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9473 [(set_attr "type" "negnot")
9474 (set_attr "mode" "DI")])
9476 ;; The problem with neg is that it does not perform (compare x 0),
9477 ;; it really performs (compare 0 x), which leaves us with the zero
9478 ;; flag being the only useful item.
9480 (define_insn "*negdi2_cmpz_rex64"
9481 [(set (reg:CCZ FLAGS_REG)
9482 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9484 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9485 (neg:DI (match_dup 1)))]
9486 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9488 [(set_attr "type" "negnot")
9489 (set_attr "mode" "DI")])
9492 (define_expand "negsi2"
9493 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9494 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9495 (clobber (reg:CC FLAGS_REG))])]
9497 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9499 (define_insn "*negsi2_1"
9500 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9501 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9502 (clobber (reg:CC FLAGS_REG))]
9503 "ix86_unary_operator_ok (NEG, SImode, operands)"
9505 [(set_attr "type" "negnot")
9506 (set_attr "mode" "SI")])
9508 ;; Combine is quite creative about this pattern.
9509 (define_insn "*negsi2_1_zext"
9510 [(set (match_operand:DI 0 "register_operand" "=r")
9511 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9514 (clobber (reg:CC FLAGS_REG))]
9515 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9517 [(set_attr "type" "negnot")
9518 (set_attr "mode" "SI")])
9520 ;; The problem with neg is that it does not perform (compare x 0),
9521 ;; it really performs (compare 0 x), which leaves us with the zero
9522 ;; flag being the only useful item.
9524 (define_insn "*negsi2_cmpz"
9525 [(set (reg:CCZ FLAGS_REG)
9526 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9528 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9529 (neg:SI (match_dup 1)))]
9530 "ix86_unary_operator_ok (NEG, SImode, operands)"
9532 [(set_attr "type" "negnot")
9533 (set_attr "mode" "SI")])
9535 (define_insn "*negsi2_cmpz_zext"
9536 [(set (reg:CCZ FLAGS_REG)
9537 (compare:CCZ (lshiftrt:DI
9539 (match_operand:DI 1 "register_operand" "0")
9543 (set (match_operand:DI 0 "register_operand" "=r")
9544 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9547 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9549 [(set_attr "type" "negnot")
9550 (set_attr "mode" "SI")])
9552 (define_expand "neghi2"
9553 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9554 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9555 (clobber (reg:CC FLAGS_REG))])]
9556 "TARGET_HIMODE_MATH"
9557 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9559 (define_insn "*neghi2_1"
9560 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9561 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9562 (clobber (reg:CC FLAGS_REG))]
9563 "ix86_unary_operator_ok (NEG, HImode, operands)"
9565 [(set_attr "type" "negnot")
9566 (set_attr "mode" "HI")])
9568 (define_insn "*neghi2_cmpz"
9569 [(set (reg:CCZ FLAGS_REG)
9570 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9572 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9573 (neg:HI (match_dup 1)))]
9574 "ix86_unary_operator_ok (NEG, HImode, operands)"
9576 [(set_attr "type" "negnot")
9577 (set_attr "mode" "HI")])
9579 (define_expand "negqi2"
9580 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9581 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9582 (clobber (reg:CC FLAGS_REG))])]
9583 "TARGET_QIMODE_MATH"
9584 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9586 (define_insn "*negqi2_1"
9587 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9588 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9589 (clobber (reg:CC FLAGS_REG))]
9590 "ix86_unary_operator_ok (NEG, QImode, operands)"
9592 [(set_attr "type" "negnot")
9593 (set_attr "mode" "QI")])
9595 (define_insn "*negqi2_cmpz"
9596 [(set (reg:CCZ FLAGS_REG)
9597 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9599 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9600 (neg:QI (match_dup 1)))]
9601 "ix86_unary_operator_ok (NEG, QImode, operands)"
9603 [(set_attr "type" "negnot")
9604 (set_attr "mode" "QI")])
9606 ;; Changing of sign for FP values is doable using integer unit too.
9608 (define_expand "negsf2"
9609 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9610 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9611 "TARGET_80387 || TARGET_SSE_MATH"
9612 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9614 (define_expand "abssf2"
9615 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9616 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9617 "TARGET_80387 || TARGET_SSE_MATH"
9618 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9620 (define_insn "*absnegsf2_mixed"
9621 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9622 (match_operator:SF 3 "absneg_operator"
9623 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9624 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9625 (clobber (reg:CC FLAGS_REG))]
9626 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9627 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9630 (define_insn "*absnegsf2_sse"
9631 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9632 (match_operator:SF 3 "absneg_operator"
9633 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9634 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9635 (clobber (reg:CC FLAGS_REG))]
9637 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9640 (define_insn "*absnegsf2_i387"
9641 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9642 (match_operator:SF 3 "absneg_operator"
9643 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9644 (use (match_operand 2 "" ""))
9645 (clobber (reg:CC FLAGS_REG))]
9646 "TARGET_80387 && !TARGET_SSE_MATH
9647 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9650 (define_expand "copysignsf3"
9651 [(match_operand:SF 0 "register_operand" "")
9652 (match_operand:SF 1 "nonmemory_operand" "")
9653 (match_operand:SF 2 "register_operand" "")]
9656 ix86_expand_copysign (operands);
9660 (define_insn_and_split "copysignsf3_const"
9661 [(set (match_operand:SF 0 "register_operand" "=x")
9663 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9664 (match_operand:SF 2 "register_operand" "0")
9665 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9669 "&& reload_completed"
9672 ix86_split_copysign_const (operands);
9676 (define_insn "copysignsf3_var"
9677 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9679 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9680 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9681 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9682 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9684 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9689 [(set (match_operand:SF 0 "register_operand" "")
9691 [(match_operand:SF 2 "register_operand" "")
9692 (match_operand:SF 3 "register_operand" "")
9693 (match_operand:V4SF 4 "" "")
9694 (match_operand:V4SF 5 "" "")]
9696 (clobber (match_scratch:V4SF 1 ""))]
9697 "TARGET_SSE_MATH && reload_completed"
9700 ix86_split_copysign_var (operands);
9704 (define_expand "negdf2"
9705 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9706 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9707 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9708 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9710 (define_expand "absdf2"
9711 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9712 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9713 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9714 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9716 (define_insn "*absnegdf2_mixed"
9717 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
9718 (match_operator:DF 3 "absneg_operator"
9719 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9720 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
9721 (clobber (reg:CC FLAGS_REG))]
9722 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9723 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9726 (define_insn "*absnegdf2_sse"
9727 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
9728 (match_operator:DF 3 "absneg_operator"
9729 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9730 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
9731 (clobber (reg:CC FLAGS_REG))]
9732 "TARGET_SSE2 && TARGET_SSE_MATH
9733 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9736 (define_insn "*absnegdf2_i387"
9737 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9738 (match_operator:DF 3 "absneg_operator"
9739 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9740 (use (match_operand 2 "" ""))
9741 (clobber (reg:CC FLAGS_REG))]
9742 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9743 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9746 (define_expand "copysigndf3"
9747 [(match_operand:DF 0 "register_operand" "")
9748 (match_operand:DF 1 "nonmemory_operand" "")
9749 (match_operand:DF 2 "register_operand" "")]
9750 "TARGET_SSE2 && TARGET_SSE_MATH"
9752 ix86_expand_copysign (operands);
9756 (define_insn_and_split "copysigndf3_const"
9757 [(set (match_operand:DF 0 "register_operand" "=x")
9759 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9760 (match_operand:DF 2 "register_operand" "0")
9761 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9763 "TARGET_SSE2 && TARGET_SSE_MATH"
9765 "&& reload_completed"
9768 ix86_split_copysign_const (operands);
9772 (define_insn "copysigndf3_var"
9773 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9775 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9776 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9777 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9778 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9780 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9781 "TARGET_SSE2 && TARGET_SSE_MATH"
9785 [(set (match_operand:DF 0 "register_operand" "")
9787 [(match_operand:DF 2 "register_operand" "")
9788 (match_operand:DF 3 "register_operand" "")
9789 (match_operand:V2DF 4 "" "")
9790 (match_operand:V2DF 5 "" "")]
9792 (clobber (match_scratch:V2DF 1 ""))]
9793 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9796 ix86_split_copysign_var (operands);
9800 (define_expand "negxf2"
9801 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9802 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9804 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9806 (define_expand "absxf2"
9807 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9808 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9810 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9812 (define_insn "*absnegxf2_i387"
9813 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9814 (match_operator:XF 3 "absneg_operator"
9815 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9816 (use (match_operand 2 "" ""))
9817 (clobber (reg:CC FLAGS_REG))]
9819 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9822 ;; Splitters for fp abs and neg.
9825 [(set (match_operand 0 "fp_register_operand" "")
9826 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9827 (use (match_operand 2 "" ""))
9828 (clobber (reg:CC FLAGS_REG))]
9830 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9833 [(set (match_operand 0 "register_operand" "")
9834 (match_operator 3 "absneg_operator"
9835 [(match_operand 1 "register_operand" "")]))
9836 (use (match_operand 2 "nonimmediate_operand" ""))
9837 (clobber (reg:CC FLAGS_REG))]
9838 "reload_completed && SSE_REG_P (operands[0])"
9839 [(set (match_dup 0) (match_dup 3))]
9841 enum machine_mode mode = GET_MODE (operands[0]);
9842 enum machine_mode vmode = GET_MODE (operands[2]);
9845 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9846 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9847 if (operands_match_p (operands[0], operands[2]))
9850 operands[1] = operands[2];
9853 if (GET_CODE (operands[3]) == ABS)
9854 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9856 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9861 [(set (match_operand:SF 0 "register_operand" "")
9862 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9863 (use (match_operand:V4SF 2 "" ""))
9864 (clobber (reg:CC FLAGS_REG))]
9866 [(parallel [(set (match_dup 0) (match_dup 1))
9867 (clobber (reg:CC FLAGS_REG))])]
9870 operands[0] = gen_lowpart (SImode, operands[0]);
9871 if (GET_CODE (operands[1]) == ABS)
9873 tmp = gen_int_mode (0x7fffffff, SImode);
9874 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9878 tmp = gen_int_mode (0x80000000, SImode);
9879 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9885 [(set (match_operand:DF 0 "register_operand" "")
9886 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9887 (use (match_operand 2 "" ""))
9888 (clobber (reg:CC FLAGS_REG))]
9890 [(parallel [(set (match_dup 0) (match_dup 1))
9891 (clobber (reg:CC FLAGS_REG))])]
9896 tmp = gen_lowpart (DImode, operands[0]);
9897 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9900 if (GET_CODE (operands[1]) == ABS)
9903 tmp = gen_rtx_NOT (DImode, tmp);
9907 operands[0] = gen_highpart (SImode, operands[0]);
9908 if (GET_CODE (operands[1]) == ABS)
9910 tmp = gen_int_mode (0x7fffffff, SImode);
9911 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9915 tmp = gen_int_mode (0x80000000, SImode);
9916 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9923 [(set (match_operand:XF 0 "register_operand" "")
9924 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9925 (use (match_operand 2 "" ""))
9926 (clobber (reg:CC FLAGS_REG))]
9928 [(parallel [(set (match_dup 0) (match_dup 1))
9929 (clobber (reg:CC FLAGS_REG))])]
9932 operands[0] = gen_rtx_REG (SImode,
9933 true_regnum (operands[0])
9934 + (TARGET_64BIT ? 1 : 2));
9935 if (GET_CODE (operands[1]) == ABS)
9937 tmp = GEN_INT (0x7fff);
9938 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9942 tmp = GEN_INT (0x8000);
9943 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9949 [(set (match_operand 0 "memory_operand" "")
9950 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9951 (use (match_operand 2 "" ""))
9952 (clobber (reg:CC FLAGS_REG))]
9954 [(parallel [(set (match_dup 0) (match_dup 1))
9955 (clobber (reg:CC FLAGS_REG))])]
9957 enum machine_mode mode = GET_MODE (operands[0]);
9958 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9961 operands[0] = adjust_address (operands[0], QImode, size - 1);
9962 if (GET_CODE (operands[1]) == ABS)
9964 tmp = gen_int_mode (0x7f, QImode);
9965 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9969 tmp = gen_int_mode (0x80, QImode);
9970 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9975 ;; Conditionalize these after reload. If they match before reload, we
9976 ;; lose the clobber and ability to use integer instructions.
9978 (define_insn "*negsf2_1"
9979 [(set (match_operand:SF 0 "register_operand" "=f")
9980 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9981 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9983 [(set_attr "type" "fsgn")
9984 (set_attr "mode" "SF")])
9986 (define_insn "*negdf2_1"
9987 [(set (match_operand:DF 0 "register_operand" "=f")
9988 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9989 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9991 [(set_attr "type" "fsgn")
9992 (set_attr "mode" "DF")])
9994 (define_insn "*negxf2_1"
9995 [(set (match_operand:XF 0 "register_operand" "=f")
9996 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9999 [(set_attr "type" "fsgn")
10000 (set_attr "mode" "XF")])
10002 (define_insn "*abssf2_1"
10003 [(set (match_operand:SF 0 "register_operand" "=f")
10004 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10005 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10007 [(set_attr "type" "fsgn")
10008 (set_attr "mode" "SF")])
10010 (define_insn "*absdf2_1"
10011 [(set (match_operand:DF 0 "register_operand" "=f")
10012 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10013 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10015 [(set_attr "type" "fsgn")
10016 (set_attr "mode" "DF")])
10018 (define_insn "*absxf2_1"
10019 [(set (match_operand:XF 0 "register_operand" "=f")
10020 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10023 [(set_attr "type" "fsgn")
10024 (set_attr "mode" "DF")])
10026 (define_insn "*negextendsfdf2"
10027 [(set (match_operand:DF 0 "register_operand" "=f")
10028 (neg:DF (float_extend:DF
10029 (match_operand:SF 1 "register_operand" "0"))))]
10030 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10032 [(set_attr "type" "fsgn")
10033 (set_attr "mode" "DF")])
10035 (define_insn "*negextenddfxf2"
10036 [(set (match_operand:XF 0 "register_operand" "=f")
10037 (neg:XF (float_extend:XF
10038 (match_operand:DF 1 "register_operand" "0"))))]
10041 [(set_attr "type" "fsgn")
10042 (set_attr "mode" "XF")])
10044 (define_insn "*negextendsfxf2"
10045 [(set (match_operand:XF 0 "register_operand" "=f")
10046 (neg:XF (float_extend:XF
10047 (match_operand:SF 1 "register_operand" "0"))))]
10050 [(set_attr "type" "fsgn")
10051 (set_attr "mode" "XF")])
10053 (define_insn "*absextendsfdf2"
10054 [(set (match_operand:DF 0 "register_operand" "=f")
10055 (abs:DF (float_extend:DF
10056 (match_operand:SF 1 "register_operand" "0"))))]
10057 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10059 [(set_attr "type" "fsgn")
10060 (set_attr "mode" "DF")])
10062 (define_insn "*absextenddfxf2"
10063 [(set (match_operand:XF 0 "register_operand" "=f")
10064 (abs:XF (float_extend:XF
10065 (match_operand:DF 1 "register_operand" "0"))))]
10068 [(set_attr "type" "fsgn")
10069 (set_attr "mode" "XF")])
10071 (define_insn "*absextendsfxf2"
10072 [(set (match_operand:XF 0 "register_operand" "=f")
10073 (abs:XF (float_extend:XF
10074 (match_operand:SF 1 "register_operand" "0"))))]
10077 [(set_attr "type" "fsgn")
10078 (set_attr "mode" "XF")])
10080 ;; One complement instructions
10082 (define_expand "one_cmpldi2"
10083 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10084 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10086 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10088 (define_insn "*one_cmpldi2_1_rex64"
10089 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10090 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10091 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10093 [(set_attr "type" "negnot")
10094 (set_attr "mode" "DI")])
10096 (define_insn "*one_cmpldi2_2_rex64"
10097 [(set (reg FLAGS_REG)
10098 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10100 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10101 (not:DI (match_dup 1)))]
10102 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10103 && ix86_unary_operator_ok (NOT, DImode, operands)"
10105 [(set_attr "type" "alu1")
10106 (set_attr "mode" "DI")])
10109 [(set (match_operand 0 "flags_reg_operand" "")
10110 (match_operator 2 "compare_operator"
10111 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10113 (set (match_operand:DI 1 "nonimmediate_operand" "")
10114 (not:DI (match_dup 3)))]
10115 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10116 [(parallel [(set (match_dup 0)
10118 [(xor:DI (match_dup 3) (const_int -1))
10121 (xor:DI (match_dup 3) (const_int -1)))])]
10124 (define_expand "one_cmplsi2"
10125 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10126 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10128 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10130 (define_insn "*one_cmplsi2_1"
10131 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10132 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10133 "ix86_unary_operator_ok (NOT, SImode, operands)"
10135 [(set_attr "type" "negnot")
10136 (set_attr "mode" "SI")])
10138 ;; ??? Currently never generated - xor is used instead.
10139 (define_insn "*one_cmplsi2_1_zext"
10140 [(set (match_operand:DI 0 "register_operand" "=r")
10141 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10142 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10144 [(set_attr "type" "negnot")
10145 (set_attr "mode" "SI")])
10147 (define_insn "*one_cmplsi2_2"
10148 [(set (reg FLAGS_REG)
10149 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10151 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10152 (not:SI (match_dup 1)))]
10153 "ix86_match_ccmode (insn, CCNOmode)
10154 && ix86_unary_operator_ok (NOT, SImode, operands)"
10156 [(set_attr "type" "alu1")
10157 (set_attr "mode" "SI")])
10160 [(set (match_operand 0 "flags_reg_operand" "")
10161 (match_operator 2 "compare_operator"
10162 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10164 (set (match_operand:SI 1 "nonimmediate_operand" "")
10165 (not:SI (match_dup 3)))]
10166 "ix86_match_ccmode (insn, CCNOmode)"
10167 [(parallel [(set (match_dup 0)
10168 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10171 (xor:SI (match_dup 3) (const_int -1)))])]
10174 ;; ??? Currently never generated - xor is used instead.
10175 (define_insn "*one_cmplsi2_2_zext"
10176 [(set (reg FLAGS_REG)
10177 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10179 (set (match_operand:DI 0 "register_operand" "=r")
10180 (zero_extend:DI (not:SI (match_dup 1))))]
10181 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10182 && ix86_unary_operator_ok (NOT, SImode, operands)"
10184 [(set_attr "type" "alu1")
10185 (set_attr "mode" "SI")])
10188 [(set (match_operand 0 "flags_reg_operand" "")
10189 (match_operator 2 "compare_operator"
10190 [(not:SI (match_operand:SI 3 "register_operand" ""))
10192 (set (match_operand:DI 1 "register_operand" "")
10193 (zero_extend:DI (not:SI (match_dup 3))))]
10194 "ix86_match_ccmode (insn, CCNOmode)"
10195 [(parallel [(set (match_dup 0)
10196 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10199 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10202 (define_expand "one_cmplhi2"
10203 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10204 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10205 "TARGET_HIMODE_MATH"
10206 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10208 (define_insn "*one_cmplhi2_1"
10209 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10210 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10211 "ix86_unary_operator_ok (NOT, HImode, operands)"
10213 [(set_attr "type" "negnot")
10214 (set_attr "mode" "HI")])
10216 (define_insn "*one_cmplhi2_2"
10217 [(set (reg FLAGS_REG)
10218 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10220 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10221 (not:HI (match_dup 1)))]
10222 "ix86_match_ccmode (insn, CCNOmode)
10223 && ix86_unary_operator_ok (NEG, HImode, operands)"
10225 [(set_attr "type" "alu1")
10226 (set_attr "mode" "HI")])
10229 [(set (match_operand 0 "flags_reg_operand" "")
10230 (match_operator 2 "compare_operator"
10231 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10233 (set (match_operand:HI 1 "nonimmediate_operand" "")
10234 (not:HI (match_dup 3)))]
10235 "ix86_match_ccmode (insn, CCNOmode)"
10236 [(parallel [(set (match_dup 0)
10237 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10240 (xor:HI (match_dup 3) (const_int -1)))])]
10243 ;; %%% Potential partial reg stall on alternative 1. What to do?
10244 (define_expand "one_cmplqi2"
10245 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10246 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10247 "TARGET_QIMODE_MATH"
10248 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10250 (define_insn "*one_cmplqi2_1"
10251 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10252 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10253 "ix86_unary_operator_ok (NOT, QImode, operands)"
10257 [(set_attr "type" "negnot")
10258 (set_attr "mode" "QI,SI")])
10260 (define_insn "*one_cmplqi2_2"
10261 [(set (reg FLAGS_REG)
10262 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10264 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10265 (not:QI (match_dup 1)))]
10266 "ix86_match_ccmode (insn, CCNOmode)
10267 && ix86_unary_operator_ok (NOT, QImode, operands)"
10269 [(set_attr "type" "alu1")
10270 (set_attr "mode" "QI")])
10273 [(set (match_operand 0 "flags_reg_operand" "")
10274 (match_operator 2 "compare_operator"
10275 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10277 (set (match_operand:QI 1 "nonimmediate_operand" "")
10278 (not:QI (match_dup 3)))]
10279 "ix86_match_ccmode (insn, CCNOmode)"
10280 [(parallel [(set (match_dup 0)
10281 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10284 (xor:QI (match_dup 3) (const_int -1)))])]
10287 ;; Arithmetic shift instructions
10289 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10290 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10291 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10292 ;; from the assembler input.
10294 ;; This instruction shifts the target reg/mem as usual, but instead of
10295 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10296 ;; is a left shift double, bits are taken from the high order bits of
10297 ;; reg, else if the insn is a shift right double, bits are taken from the
10298 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10299 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10301 ;; Since sh[lr]d does not change the `reg' operand, that is done
10302 ;; separately, making all shifts emit pairs of shift double and normal
10303 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10304 ;; support a 63 bit shift, each shift where the count is in a reg expands
10305 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10307 ;; If the shift count is a constant, we need never emit more than one
10308 ;; shift pair, instead using moves and sign extension for counts greater
10311 (define_expand "ashlti3"
10312 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10313 (ashift:TI (match_operand:TI 1 "register_operand" "")
10314 (match_operand:QI 2 "nonmemory_operand" "")))
10315 (clobber (reg:CC FLAGS_REG))])]
10318 if (! immediate_operand (operands[2], QImode))
10320 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10323 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10327 (define_insn "ashlti3_1"
10328 [(set (match_operand:TI 0 "register_operand" "=r")
10329 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10330 (match_operand:QI 2 "register_operand" "c")))
10331 (clobber (match_scratch:DI 3 "=&r"))
10332 (clobber (reg:CC FLAGS_REG))]
10335 [(set_attr "type" "multi")])
10337 (define_insn "*ashlti3_2"
10338 [(set (match_operand:TI 0 "register_operand" "=r")
10339 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10340 (match_operand:QI 2 "immediate_operand" "O")))
10341 (clobber (reg:CC FLAGS_REG))]
10344 [(set_attr "type" "multi")])
10347 [(set (match_operand:TI 0 "register_operand" "")
10348 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10349 (match_operand:QI 2 "register_operand" "")))
10350 (clobber (match_scratch:DI 3 ""))
10351 (clobber (reg:CC FLAGS_REG))]
10352 "TARGET_64BIT && reload_completed"
10354 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10357 [(set (match_operand:TI 0 "register_operand" "")
10358 (ashift:TI (match_operand:TI 1 "register_operand" "")
10359 (match_operand:QI 2 "immediate_operand" "")))
10360 (clobber (reg:CC FLAGS_REG))]
10361 "TARGET_64BIT && reload_completed"
10363 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10365 (define_insn "x86_64_shld"
10366 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10367 (ior:DI (ashift:DI (match_dup 0)
10368 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10369 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10370 (minus:QI (const_int 64) (match_dup 2)))))
10371 (clobber (reg:CC FLAGS_REG))]
10374 shld{q}\t{%2, %1, %0|%0, %1, %2}
10375 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10376 [(set_attr "type" "ishift")
10377 (set_attr "prefix_0f" "1")
10378 (set_attr "mode" "DI")
10379 (set_attr "athlon_decode" "vector")
10380 (set_attr "amdfam10_decode" "vector")])
10382 (define_expand "x86_64_shift_adj"
10383 [(set (reg:CCZ FLAGS_REG)
10384 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10387 (set (match_operand:DI 0 "register_operand" "")
10388 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10389 (match_operand:DI 1 "register_operand" "")
10392 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10393 (match_operand:DI 3 "register_operand" "r")
10398 (define_expand "ashldi3"
10399 [(set (match_operand:DI 0 "shiftdi_operand" "")
10400 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10401 (match_operand:QI 2 "nonmemory_operand" "")))]
10403 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10405 (define_insn "*ashldi3_1_rex64"
10406 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10407 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10408 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10409 (clobber (reg:CC FLAGS_REG))]
10410 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10412 switch (get_attr_type (insn))
10415 gcc_assert (operands[2] == const1_rtx);
10416 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10417 return "add{q}\t%0, %0";
10420 gcc_assert (CONST_INT_P (operands[2]));
10421 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10422 operands[1] = gen_rtx_MULT (DImode, operands[1],
10423 GEN_INT (1 << INTVAL (operands[2])));
10424 return "lea{q}\t{%a1, %0|%0, %a1}";
10427 if (REG_P (operands[2]))
10428 return "sal{q}\t{%b2, %0|%0, %b2}";
10429 else if (operands[2] == const1_rtx
10430 && (TARGET_SHIFT1 || optimize_size))
10431 return "sal{q}\t%0";
10433 return "sal{q}\t{%2, %0|%0, %2}";
10436 [(set (attr "type")
10437 (cond [(eq_attr "alternative" "1")
10438 (const_string "lea")
10439 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10441 (match_operand 0 "register_operand" ""))
10442 (match_operand 2 "const1_operand" ""))
10443 (const_string "alu")
10445 (const_string "ishift")))
10446 (set_attr "mode" "DI")])
10448 ;; Convert lea to the lea pattern to avoid flags dependency.
10450 [(set (match_operand:DI 0 "register_operand" "")
10451 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10452 (match_operand:QI 2 "immediate_operand" "")))
10453 (clobber (reg:CC FLAGS_REG))]
10454 "TARGET_64BIT && reload_completed
10455 && true_regnum (operands[0]) != true_regnum (operands[1])"
10456 [(set (match_dup 0)
10457 (mult:DI (match_dup 1)
10459 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10461 ;; This pattern can't accept a variable shift count, since shifts by
10462 ;; zero don't affect the flags. We assume that shifts by constant
10463 ;; zero are optimized away.
10464 (define_insn "*ashldi3_cmp_rex64"
10465 [(set (reg FLAGS_REG)
10467 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10468 (match_operand:QI 2 "immediate_operand" "e"))
10470 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10471 (ashift:DI (match_dup 1) (match_dup 2)))]
10472 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10473 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10475 || !TARGET_PARTIAL_FLAG_REG_STALL
10476 || (operands[2] == const1_rtx
10478 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10480 switch (get_attr_type (insn))
10483 gcc_assert (operands[2] == const1_rtx);
10484 return "add{q}\t%0, %0";
10487 if (REG_P (operands[2]))
10488 return "sal{q}\t{%b2, %0|%0, %b2}";
10489 else if (operands[2] == const1_rtx
10490 && (TARGET_SHIFT1 || optimize_size))
10491 return "sal{q}\t%0";
10493 return "sal{q}\t{%2, %0|%0, %2}";
10496 [(set (attr "type")
10497 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10499 (match_operand 0 "register_operand" ""))
10500 (match_operand 2 "const1_operand" ""))
10501 (const_string "alu")
10503 (const_string "ishift")))
10504 (set_attr "mode" "DI")])
10506 (define_insn "*ashldi3_cconly_rex64"
10507 [(set (reg FLAGS_REG)
10509 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10510 (match_operand:QI 2 "immediate_operand" "e"))
10512 (clobber (match_scratch:DI 0 "=r"))]
10513 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10514 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10516 || !TARGET_PARTIAL_FLAG_REG_STALL
10517 || (operands[2] == const1_rtx
10519 || TARGET_DOUBLE_WITH_ADD)))"
10521 switch (get_attr_type (insn))
10524 gcc_assert (operands[2] == const1_rtx);
10525 return "add{q}\t%0, %0";
10528 if (REG_P (operands[2]))
10529 return "sal{q}\t{%b2, %0|%0, %b2}";
10530 else if (operands[2] == const1_rtx
10531 && (TARGET_SHIFT1 || optimize_size))
10532 return "sal{q}\t%0";
10534 return "sal{q}\t{%2, %0|%0, %2}";
10537 [(set (attr "type")
10538 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10540 (match_operand 0 "register_operand" ""))
10541 (match_operand 2 "const1_operand" ""))
10542 (const_string "alu")
10544 (const_string "ishift")))
10545 (set_attr "mode" "DI")])
10547 (define_insn "*ashldi3_1"
10548 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10549 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10550 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10551 (clobber (reg:CC FLAGS_REG))]
10554 [(set_attr "type" "multi")])
10556 ;; By default we don't ask for a scratch register, because when DImode
10557 ;; values are manipulated, registers are already at a premium. But if
10558 ;; we have one handy, we won't turn it away.
10560 [(match_scratch:SI 3 "r")
10561 (parallel [(set (match_operand:DI 0 "register_operand" "")
10562 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10563 (match_operand:QI 2 "nonmemory_operand" "")))
10564 (clobber (reg:CC FLAGS_REG))])
10566 "!TARGET_64BIT && TARGET_CMOVE"
10568 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10571 [(set (match_operand:DI 0 "register_operand" "")
10572 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10573 (match_operand:QI 2 "nonmemory_operand" "")))
10574 (clobber (reg:CC FLAGS_REG))]
10575 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10576 ? flow2_completed : reload_completed)"
10578 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10580 (define_insn "x86_shld_1"
10581 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10582 (ior:SI (ashift:SI (match_dup 0)
10583 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10584 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10585 (minus:QI (const_int 32) (match_dup 2)))))
10586 (clobber (reg:CC FLAGS_REG))]
10589 shld{l}\t{%2, %1, %0|%0, %1, %2}
10590 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10591 [(set_attr "type" "ishift")
10592 (set_attr "prefix_0f" "1")
10593 (set_attr "mode" "SI")
10594 (set_attr "pent_pair" "np")
10595 (set_attr "athlon_decode" "vector")
10596 (set_attr "amdfam10_decode" "vector")])
10598 (define_expand "x86_shift_adj_1"
10599 [(set (reg:CCZ FLAGS_REG)
10600 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10603 (set (match_operand:SI 0 "register_operand" "")
10604 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10605 (match_operand:SI 1 "register_operand" "")
10608 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10609 (match_operand:SI 3 "register_operand" "r")
10614 (define_expand "x86_shift_adj_2"
10615 [(use (match_operand:SI 0 "register_operand" ""))
10616 (use (match_operand:SI 1 "register_operand" ""))
10617 (use (match_operand:QI 2 "register_operand" ""))]
10620 rtx label = gen_label_rtx ();
10623 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10625 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10626 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10627 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10628 gen_rtx_LABEL_REF (VOIDmode, label),
10630 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10631 JUMP_LABEL (tmp) = label;
10633 emit_move_insn (operands[0], operands[1]);
10634 ix86_expand_clear (operands[1]);
10636 emit_label (label);
10637 LABEL_NUSES (label) = 1;
10642 (define_expand "ashlsi3"
10643 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10644 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10645 (match_operand:QI 2 "nonmemory_operand" "")))
10646 (clobber (reg:CC FLAGS_REG))]
10648 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10650 (define_insn "*ashlsi3_1"
10651 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10652 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10653 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10654 (clobber (reg:CC FLAGS_REG))]
10655 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10657 switch (get_attr_type (insn))
10660 gcc_assert (operands[2] == const1_rtx);
10661 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10662 return "add{l}\t%0, %0";
10668 if (REG_P (operands[2]))
10669 return "sal{l}\t{%b2, %0|%0, %b2}";
10670 else if (operands[2] == const1_rtx
10671 && (TARGET_SHIFT1 || optimize_size))
10672 return "sal{l}\t%0";
10674 return "sal{l}\t{%2, %0|%0, %2}";
10677 [(set (attr "type")
10678 (cond [(eq_attr "alternative" "1")
10679 (const_string "lea")
10680 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10682 (match_operand 0 "register_operand" ""))
10683 (match_operand 2 "const1_operand" ""))
10684 (const_string "alu")
10686 (const_string "ishift")))
10687 (set_attr "mode" "SI")])
10689 ;; Convert lea to the lea pattern to avoid flags dependency.
10691 [(set (match_operand 0 "register_operand" "")
10692 (ashift (match_operand 1 "index_register_operand" "")
10693 (match_operand:QI 2 "const_int_operand" "")))
10694 (clobber (reg:CC FLAGS_REG))]
10696 && true_regnum (operands[0]) != true_regnum (operands[1])
10697 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10701 enum machine_mode mode = GET_MODE (operands[0]);
10703 if (GET_MODE_SIZE (mode) < 4)
10704 operands[0] = gen_lowpart (SImode, operands[0]);
10706 operands[1] = gen_lowpart (Pmode, operands[1]);
10707 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10709 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10710 if (Pmode != SImode)
10711 pat = gen_rtx_SUBREG (SImode, pat, 0);
10712 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10716 ;; Rare case of shifting RSP is handled by generating move and shift
10718 [(set (match_operand 0 "register_operand" "")
10719 (ashift (match_operand 1 "register_operand" "")
10720 (match_operand:QI 2 "const_int_operand" "")))
10721 (clobber (reg:CC FLAGS_REG))]
10723 && true_regnum (operands[0]) != true_regnum (operands[1])"
10727 emit_move_insn (operands[0], operands[1]);
10728 pat = gen_rtx_SET (VOIDmode, operands[0],
10729 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10730 operands[0], operands[2]));
10731 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10732 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10736 (define_insn "*ashlsi3_1_zext"
10737 [(set (match_operand:DI 0 "register_operand" "=r,r")
10738 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10739 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10740 (clobber (reg:CC FLAGS_REG))]
10741 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10743 switch (get_attr_type (insn))
10746 gcc_assert (operands[2] == const1_rtx);
10747 return "add{l}\t%k0, %k0";
10753 if (REG_P (operands[2]))
10754 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10755 else if (operands[2] == const1_rtx
10756 && (TARGET_SHIFT1 || optimize_size))
10757 return "sal{l}\t%k0";
10759 return "sal{l}\t{%2, %k0|%k0, %2}";
10762 [(set (attr "type")
10763 (cond [(eq_attr "alternative" "1")
10764 (const_string "lea")
10765 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10767 (match_operand 2 "const1_operand" ""))
10768 (const_string "alu")
10770 (const_string "ishift")))
10771 (set_attr "mode" "SI")])
10773 ;; Convert lea to the lea pattern to avoid flags dependency.
10775 [(set (match_operand:DI 0 "register_operand" "")
10776 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10777 (match_operand:QI 2 "const_int_operand" ""))))
10778 (clobber (reg:CC FLAGS_REG))]
10779 "TARGET_64BIT && reload_completed
10780 && true_regnum (operands[0]) != true_regnum (operands[1])"
10781 [(set (match_dup 0) (zero_extend:DI
10782 (subreg:SI (mult:SI (match_dup 1)
10783 (match_dup 2)) 0)))]
10785 operands[1] = gen_lowpart (Pmode, operands[1]);
10786 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10789 ;; This pattern can't accept a variable shift count, since shifts by
10790 ;; zero don't affect the flags. We assume that shifts by constant
10791 ;; zero are optimized away.
10792 (define_insn "*ashlsi3_cmp"
10793 [(set (reg FLAGS_REG)
10795 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10796 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10798 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10799 (ashift:SI (match_dup 1) (match_dup 2)))]
10800 "ix86_match_ccmode (insn, CCGOCmode)
10801 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10803 || !TARGET_PARTIAL_FLAG_REG_STALL
10804 || (operands[2] == const1_rtx
10806 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10808 switch (get_attr_type (insn))
10811 gcc_assert (operands[2] == const1_rtx);
10812 return "add{l}\t%0, %0";
10815 if (REG_P (operands[2]))
10816 return "sal{l}\t{%b2, %0|%0, %b2}";
10817 else if (operands[2] == const1_rtx
10818 && (TARGET_SHIFT1 || optimize_size))
10819 return "sal{l}\t%0";
10821 return "sal{l}\t{%2, %0|%0, %2}";
10824 [(set (attr "type")
10825 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10827 (match_operand 0 "register_operand" ""))
10828 (match_operand 2 "const1_operand" ""))
10829 (const_string "alu")
10831 (const_string "ishift")))
10832 (set_attr "mode" "SI")])
10834 (define_insn "*ashlsi3_cconly"
10835 [(set (reg FLAGS_REG)
10837 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10838 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10840 (clobber (match_scratch:SI 0 "=r"))]
10841 "ix86_match_ccmode (insn, CCGOCmode)
10842 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10844 || !TARGET_PARTIAL_FLAG_REG_STALL
10845 || (operands[2] == const1_rtx
10847 || TARGET_DOUBLE_WITH_ADD)))"
10849 switch (get_attr_type (insn))
10852 gcc_assert (operands[2] == const1_rtx);
10853 return "add{l}\t%0, %0";
10856 if (REG_P (operands[2]))
10857 return "sal{l}\t{%b2, %0|%0, %b2}";
10858 else if (operands[2] == const1_rtx
10859 && (TARGET_SHIFT1 || optimize_size))
10860 return "sal{l}\t%0";
10862 return "sal{l}\t{%2, %0|%0, %2}";
10865 [(set (attr "type")
10866 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10868 (match_operand 0 "register_operand" ""))
10869 (match_operand 2 "const1_operand" ""))
10870 (const_string "alu")
10872 (const_string "ishift")))
10873 (set_attr "mode" "SI")])
10875 (define_insn "*ashlsi3_cmp_zext"
10876 [(set (reg FLAGS_REG)
10878 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10879 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10881 (set (match_operand:DI 0 "register_operand" "=r")
10882 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10883 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10884 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10886 || !TARGET_PARTIAL_FLAG_REG_STALL
10887 || (operands[2] == const1_rtx
10889 || TARGET_DOUBLE_WITH_ADD)))"
10891 switch (get_attr_type (insn))
10894 gcc_assert (operands[2] == const1_rtx);
10895 return "add{l}\t%k0, %k0";
10898 if (REG_P (operands[2]))
10899 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10900 else if (operands[2] == const1_rtx
10901 && (TARGET_SHIFT1 || optimize_size))
10902 return "sal{l}\t%k0";
10904 return "sal{l}\t{%2, %k0|%k0, %2}";
10907 [(set (attr "type")
10908 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10910 (match_operand 2 "const1_operand" ""))
10911 (const_string "alu")
10913 (const_string "ishift")))
10914 (set_attr "mode" "SI")])
10916 (define_expand "ashlhi3"
10917 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10918 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10919 (match_operand:QI 2 "nonmemory_operand" "")))
10920 (clobber (reg:CC FLAGS_REG))]
10921 "TARGET_HIMODE_MATH"
10922 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10924 (define_insn "*ashlhi3_1_lea"
10925 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10926 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10927 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10928 (clobber (reg:CC FLAGS_REG))]
10929 "!TARGET_PARTIAL_REG_STALL
10930 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10932 switch (get_attr_type (insn))
10937 gcc_assert (operands[2] == const1_rtx);
10938 return "add{w}\t%0, %0";
10941 if (REG_P (operands[2]))
10942 return "sal{w}\t{%b2, %0|%0, %b2}";
10943 else if (operands[2] == const1_rtx
10944 && (TARGET_SHIFT1 || optimize_size))
10945 return "sal{w}\t%0";
10947 return "sal{w}\t{%2, %0|%0, %2}";
10950 [(set (attr "type")
10951 (cond [(eq_attr "alternative" "1")
10952 (const_string "lea")
10953 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10955 (match_operand 0 "register_operand" ""))
10956 (match_operand 2 "const1_operand" ""))
10957 (const_string "alu")
10959 (const_string "ishift")))
10960 (set_attr "mode" "HI,SI")])
10962 (define_insn "*ashlhi3_1"
10963 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10964 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10965 (match_operand:QI 2 "nonmemory_operand" "cI")))
10966 (clobber (reg:CC FLAGS_REG))]
10967 "TARGET_PARTIAL_REG_STALL
10968 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10970 switch (get_attr_type (insn))
10973 gcc_assert (operands[2] == const1_rtx);
10974 return "add{w}\t%0, %0";
10977 if (REG_P (operands[2]))
10978 return "sal{w}\t{%b2, %0|%0, %b2}";
10979 else if (operands[2] == const1_rtx
10980 && (TARGET_SHIFT1 || optimize_size))
10981 return "sal{w}\t%0";
10983 return "sal{w}\t{%2, %0|%0, %2}";
10986 [(set (attr "type")
10987 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10989 (match_operand 0 "register_operand" ""))
10990 (match_operand 2 "const1_operand" ""))
10991 (const_string "alu")
10993 (const_string "ishift")))
10994 (set_attr "mode" "HI")])
10996 ;; This pattern can't accept a variable shift count, since shifts by
10997 ;; zero don't affect the flags. We assume that shifts by constant
10998 ;; zero are optimized away.
10999 (define_insn "*ashlhi3_cmp"
11000 [(set (reg FLAGS_REG)
11002 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11003 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11005 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11006 (ashift:HI (match_dup 1) (match_dup 2)))]
11007 "ix86_match_ccmode (insn, CCGOCmode)
11008 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11010 || !TARGET_PARTIAL_FLAG_REG_STALL
11011 || (operands[2] == const1_rtx
11013 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11015 switch (get_attr_type (insn))
11018 gcc_assert (operands[2] == const1_rtx);
11019 return "add{w}\t%0, %0";
11022 if (REG_P (operands[2]))
11023 return "sal{w}\t{%b2, %0|%0, %b2}";
11024 else if (operands[2] == const1_rtx
11025 && (TARGET_SHIFT1 || optimize_size))
11026 return "sal{w}\t%0";
11028 return "sal{w}\t{%2, %0|%0, %2}";
11031 [(set (attr "type")
11032 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11034 (match_operand 0 "register_operand" ""))
11035 (match_operand 2 "const1_operand" ""))
11036 (const_string "alu")
11038 (const_string "ishift")))
11039 (set_attr "mode" "HI")])
11041 (define_insn "*ashlhi3_cconly"
11042 [(set (reg FLAGS_REG)
11044 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11045 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11047 (clobber (match_scratch:HI 0 "=r"))]
11048 "ix86_match_ccmode (insn, CCGOCmode)
11049 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11051 || !TARGET_PARTIAL_FLAG_REG_STALL
11052 || (operands[2] == const1_rtx
11054 || TARGET_DOUBLE_WITH_ADD)))"
11056 switch (get_attr_type (insn))
11059 gcc_assert (operands[2] == const1_rtx);
11060 return "add{w}\t%0, %0";
11063 if (REG_P (operands[2]))
11064 return "sal{w}\t{%b2, %0|%0, %b2}";
11065 else if (operands[2] == const1_rtx
11066 && (TARGET_SHIFT1 || optimize_size))
11067 return "sal{w}\t%0";
11069 return "sal{w}\t{%2, %0|%0, %2}";
11072 [(set (attr "type")
11073 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11075 (match_operand 0 "register_operand" ""))
11076 (match_operand 2 "const1_operand" ""))
11077 (const_string "alu")
11079 (const_string "ishift")))
11080 (set_attr "mode" "HI")])
11082 (define_expand "ashlqi3"
11083 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11084 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11085 (match_operand:QI 2 "nonmemory_operand" "")))
11086 (clobber (reg:CC FLAGS_REG))]
11087 "TARGET_QIMODE_MATH"
11088 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11090 ;; %%% Potential partial reg stall on alternative 2. What to do?
11092 (define_insn "*ashlqi3_1_lea"
11093 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11094 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11095 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11096 (clobber (reg:CC FLAGS_REG))]
11097 "!TARGET_PARTIAL_REG_STALL
11098 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11100 switch (get_attr_type (insn))
11105 gcc_assert (operands[2] == const1_rtx);
11106 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11107 return "add{l}\t%k0, %k0";
11109 return "add{b}\t%0, %0";
11112 if (REG_P (operands[2]))
11114 if (get_attr_mode (insn) == MODE_SI)
11115 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11117 return "sal{b}\t{%b2, %0|%0, %b2}";
11119 else if (operands[2] == const1_rtx
11120 && (TARGET_SHIFT1 || optimize_size))
11122 if (get_attr_mode (insn) == MODE_SI)
11123 return "sal{l}\t%0";
11125 return "sal{b}\t%0";
11129 if (get_attr_mode (insn) == MODE_SI)
11130 return "sal{l}\t{%2, %k0|%k0, %2}";
11132 return "sal{b}\t{%2, %0|%0, %2}";
11136 [(set (attr "type")
11137 (cond [(eq_attr "alternative" "2")
11138 (const_string "lea")
11139 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11141 (match_operand 0 "register_operand" ""))
11142 (match_operand 2 "const1_operand" ""))
11143 (const_string "alu")
11145 (const_string "ishift")))
11146 (set_attr "mode" "QI,SI,SI")])
11148 (define_insn "*ashlqi3_1"
11149 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11150 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11151 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11152 (clobber (reg:CC FLAGS_REG))]
11153 "TARGET_PARTIAL_REG_STALL
11154 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11156 switch (get_attr_type (insn))
11159 gcc_assert (operands[2] == const1_rtx);
11160 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11161 return "add{l}\t%k0, %k0";
11163 return "add{b}\t%0, %0";
11166 if (REG_P (operands[2]))
11168 if (get_attr_mode (insn) == MODE_SI)
11169 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11171 return "sal{b}\t{%b2, %0|%0, %b2}";
11173 else if (operands[2] == const1_rtx
11174 && (TARGET_SHIFT1 || optimize_size))
11176 if (get_attr_mode (insn) == MODE_SI)
11177 return "sal{l}\t%0";
11179 return "sal{b}\t%0";
11183 if (get_attr_mode (insn) == MODE_SI)
11184 return "sal{l}\t{%2, %k0|%k0, %2}";
11186 return "sal{b}\t{%2, %0|%0, %2}";
11190 [(set (attr "type")
11191 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11193 (match_operand 0 "register_operand" ""))
11194 (match_operand 2 "const1_operand" ""))
11195 (const_string "alu")
11197 (const_string "ishift")))
11198 (set_attr "mode" "QI,SI")])
11200 ;; This pattern can't accept a variable shift count, since shifts by
11201 ;; zero don't affect the flags. We assume that shifts by constant
11202 ;; zero are optimized away.
11203 (define_insn "*ashlqi3_cmp"
11204 [(set (reg FLAGS_REG)
11206 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11207 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11209 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11210 (ashift:QI (match_dup 1) (match_dup 2)))]
11211 "ix86_match_ccmode (insn, CCGOCmode)
11212 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11214 || !TARGET_PARTIAL_FLAG_REG_STALL
11215 || (operands[2] == const1_rtx
11217 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11219 switch (get_attr_type (insn))
11222 gcc_assert (operands[2] == const1_rtx);
11223 return "add{b}\t%0, %0";
11226 if (REG_P (operands[2]))
11227 return "sal{b}\t{%b2, %0|%0, %b2}";
11228 else if (operands[2] == const1_rtx
11229 && (TARGET_SHIFT1 || optimize_size))
11230 return "sal{b}\t%0";
11232 return "sal{b}\t{%2, %0|%0, %2}";
11235 [(set (attr "type")
11236 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11238 (match_operand 0 "register_operand" ""))
11239 (match_operand 2 "const1_operand" ""))
11240 (const_string "alu")
11242 (const_string "ishift")))
11243 (set_attr "mode" "QI")])
11245 (define_insn "*ashlqi3_cconly"
11246 [(set (reg FLAGS_REG)
11248 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11249 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11251 (clobber (match_scratch:QI 0 "=q"))]
11252 "ix86_match_ccmode (insn, CCGOCmode)
11253 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11255 || !TARGET_PARTIAL_FLAG_REG_STALL
11256 || (operands[2] == const1_rtx
11258 || TARGET_DOUBLE_WITH_ADD)))"
11260 switch (get_attr_type (insn))
11263 gcc_assert (operands[2] == const1_rtx);
11264 return "add{b}\t%0, %0";
11267 if (REG_P (operands[2]))
11268 return "sal{b}\t{%b2, %0|%0, %b2}";
11269 else if (operands[2] == const1_rtx
11270 && (TARGET_SHIFT1 || optimize_size))
11271 return "sal{b}\t%0";
11273 return "sal{b}\t{%2, %0|%0, %2}";
11276 [(set (attr "type")
11277 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11279 (match_operand 0 "register_operand" ""))
11280 (match_operand 2 "const1_operand" ""))
11281 (const_string "alu")
11283 (const_string "ishift")))
11284 (set_attr "mode" "QI")])
11286 ;; See comment above `ashldi3' about how this works.
11288 (define_expand "ashrti3"
11289 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11290 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11291 (match_operand:QI 2 "nonmemory_operand" "")))
11292 (clobber (reg:CC FLAGS_REG))])]
11295 if (! immediate_operand (operands[2], QImode))
11297 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11300 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11304 (define_insn "ashrti3_1"
11305 [(set (match_operand:TI 0 "register_operand" "=r")
11306 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11307 (match_operand:QI 2 "register_operand" "c")))
11308 (clobber (match_scratch:DI 3 "=&r"))
11309 (clobber (reg:CC FLAGS_REG))]
11312 [(set_attr "type" "multi")])
11314 (define_insn "*ashrti3_2"
11315 [(set (match_operand:TI 0 "register_operand" "=r")
11316 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11317 (match_operand:QI 2 "immediate_operand" "O")))
11318 (clobber (reg:CC FLAGS_REG))]
11321 [(set_attr "type" "multi")])
11324 [(set (match_operand:TI 0 "register_operand" "")
11325 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11326 (match_operand:QI 2 "register_operand" "")))
11327 (clobber (match_scratch:DI 3 ""))
11328 (clobber (reg:CC FLAGS_REG))]
11329 "TARGET_64BIT && reload_completed"
11331 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11334 [(set (match_operand:TI 0 "register_operand" "")
11335 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11336 (match_operand:QI 2 "immediate_operand" "")))
11337 (clobber (reg:CC FLAGS_REG))]
11338 "TARGET_64BIT && reload_completed"
11340 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11342 (define_insn "x86_64_shrd"
11343 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11344 (ior:DI (ashiftrt:DI (match_dup 0)
11345 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11346 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11347 (minus:QI (const_int 64) (match_dup 2)))))
11348 (clobber (reg:CC FLAGS_REG))]
11351 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11352 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11353 [(set_attr "type" "ishift")
11354 (set_attr "prefix_0f" "1")
11355 (set_attr "mode" "DI")
11356 (set_attr "athlon_decode" "vector")
11357 (set_attr "amdfam10_decode" "vector")])
11359 (define_expand "ashrdi3"
11360 [(set (match_operand:DI 0 "shiftdi_operand" "")
11361 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11362 (match_operand:QI 2 "nonmemory_operand" "")))]
11364 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11366 (define_insn "*ashrdi3_63_rex64"
11367 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11368 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11369 (match_operand:DI 2 "const_int_operand" "i,i")))
11370 (clobber (reg:CC FLAGS_REG))]
11371 "TARGET_64BIT && INTVAL (operands[2]) == 63
11372 && (TARGET_USE_CLTD || optimize_size)
11373 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11376 sar{q}\t{%2, %0|%0, %2}"
11377 [(set_attr "type" "imovx,ishift")
11378 (set_attr "prefix_0f" "0,*")
11379 (set_attr "length_immediate" "0,*")
11380 (set_attr "modrm" "0,1")
11381 (set_attr "mode" "DI")])
11383 (define_insn "*ashrdi3_1_one_bit_rex64"
11384 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11385 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11386 (match_operand:QI 2 "const1_operand" "")))
11387 (clobber (reg:CC FLAGS_REG))]
11388 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11389 && (TARGET_SHIFT1 || optimize_size)"
11391 [(set_attr "type" "ishift")
11392 (set (attr "length")
11393 (if_then_else (match_operand:DI 0 "register_operand" "")
11395 (const_string "*")))])
11397 (define_insn "*ashrdi3_1_rex64"
11398 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11399 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11400 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11401 (clobber (reg:CC FLAGS_REG))]
11402 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11404 sar{q}\t{%2, %0|%0, %2}
11405 sar{q}\t{%b2, %0|%0, %b2}"
11406 [(set_attr "type" "ishift")
11407 (set_attr "mode" "DI")])
11409 ;; This pattern can't accept a variable shift count, since shifts by
11410 ;; zero don't affect the flags. We assume that shifts by constant
11411 ;; zero are optimized away.
11412 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11413 [(set (reg FLAGS_REG)
11415 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11416 (match_operand:QI 2 "const1_operand" ""))
11418 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11419 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11420 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11421 && (TARGET_SHIFT1 || optimize_size)
11422 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11424 [(set_attr "type" "ishift")
11425 (set (attr "length")
11426 (if_then_else (match_operand:DI 0 "register_operand" "")
11428 (const_string "*")))])
11430 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11431 [(set (reg FLAGS_REG)
11433 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434 (match_operand:QI 2 "const1_operand" ""))
11436 (clobber (match_scratch:DI 0 "=r"))]
11437 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11438 && (TARGET_SHIFT1 || optimize_size)
11439 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11441 [(set_attr "type" "ishift")
11442 (set_attr "length" "2")])
11444 ;; This pattern can't accept a variable shift count, since shifts by
11445 ;; zero don't affect the flags. We assume that shifts by constant
11446 ;; zero are optimized away.
11447 (define_insn "*ashrdi3_cmp_rex64"
11448 [(set (reg FLAGS_REG)
11450 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11451 (match_operand:QI 2 "const_int_operand" "n"))
11453 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11454 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11455 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11456 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11458 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11459 "sar{q}\t{%2, %0|%0, %2}"
11460 [(set_attr "type" "ishift")
11461 (set_attr "mode" "DI")])
11463 (define_insn "*ashrdi3_cconly_rex64"
11464 [(set (reg FLAGS_REG)
11466 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11467 (match_operand:QI 2 "const_int_operand" "n"))
11469 (clobber (match_scratch:DI 0 "=r"))]
11470 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11471 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11473 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11474 "sar{q}\t{%2, %0|%0, %2}"
11475 [(set_attr "type" "ishift")
11476 (set_attr "mode" "DI")])
11478 (define_insn "*ashrdi3_1"
11479 [(set (match_operand:DI 0 "register_operand" "=r")
11480 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11481 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11482 (clobber (reg:CC FLAGS_REG))]
11485 [(set_attr "type" "multi")])
11487 ;; By default we don't ask for a scratch register, because when DImode
11488 ;; values are manipulated, registers are already at a premium. But if
11489 ;; we have one handy, we won't turn it away.
11491 [(match_scratch:SI 3 "r")
11492 (parallel [(set (match_operand:DI 0 "register_operand" "")
11493 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11494 (match_operand:QI 2 "nonmemory_operand" "")))
11495 (clobber (reg:CC FLAGS_REG))])
11497 "!TARGET_64BIT && TARGET_CMOVE"
11499 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11502 [(set (match_operand:DI 0 "register_operand" "")
11503 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11504 (match_operand:QI 2 "nonmemory_operand" "")))
11505 (clobber (reg:CC FLAGS_REG))]
11506 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11507 ? flow2_completed : reload_completed)"
11509 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11511 (define_insn "x86_shrd_1"
11512 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11513 (ior:SI (ashiftrt:SI (match_dup 0)
11514 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11515 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11516 (minus:QI (const_int 32) (match_dup 2)))))
11517 (clobber (reg:CC FLAGS_REG))]
11520 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11521 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11522 [(set_attr "type" "ishift")
11523 (set_attr "prefix_0f" "1")
11524 (set_attr "pent_pair" "np")
11525 (set_attr "mode" "SI")])
11527 (define_expand "x86_shift_adj_3"
11528 [(use (match_operand:SI 0 "register_operand" ""))
11529 (use (match_operand:SI 1 "register_operand" ""))
11530 (use (match_operand:QI 2 "register_operand" ""))]
11533 rtx label = gen_label_rtx ();
11536 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11538 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11539 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11540 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11541 gen_rtx_LABEL_REF (VOIDmode, label),
11543 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11544 JUMP_LABEL (tmp) = label;
11546 emit_move_insn (operands[0], operands[1]);
11547 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11549 emit_label (label);
11550 LABEL_NUSES (label) = 1;
11555 (define_insn "ashrsi3_31"
11556 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11557 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11558 (match_operand:SI 2 "const_int_operand" "i,i")))
11559 (clobber (reg:CC FLAGS_REG))]
11560 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11561 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11564 sar{l}\t{%2, %0|%0, %2}"
11565 [(set_attr "type" "imovx,ishift")
11566 (set_attr "prefix_0f" "0,*")
11567 (set_attr "length_immediate" "0,*")
11568 (set_attr "modrm" "0,1")
11569 (set_attr "mode" "SI")])
11571 (define_insn "*ashrsi3_31_zext"
11572 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11573 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11574 (match_operand:SI 2 "const_int_operand" "i,i"))))
11575 (clobber (reg:CC FLAGS_REG))]
11576 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11577 && INTVAL (operands[2]) == 31
11578 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11581 sar{l}\t{%2, %k0|%k0, %2}"
11582 [(set_attr "type" "imovx,ishift")
11583 (set_attr "prefix_0f" "0,*")
11584 (set_attr "length_immediate" "0,*")
11585 (set_attr "modrm" "0,1")
11586 (set_attr "mode" "SI")])
11588 (define_expand "ashrsi3"
11589 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11590 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11591 (match_operand:QI 2 "nonmemory_operand" "")))
11592 (clobber (reg:CC FLAGS_REG))]
11594 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11596 (define_insn "*ashrsi3_1_one_bit"
11597 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11598 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11599 (match_operand:QI 2 "const1_operand" "")))
11600 (clobber (reg:CC FLAGS_REG))]
11601 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11602 && (TARGET_SHIFT1 || optimize_size)"
11604 [(set_attr "type" "ishift")
11605 (set (attr "length")
11606 (if_then_else (match_operand:SI 0 "register_operand" "")
11608 (const_string "*")))])
11610 (define_insn "*ashrsi3_1_one_bit_zext"
11611 [(set (match_operand:DI 0 "register_operand" "=r")
11612 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11613 (match_operand:QI 2 "const1_operand" ""))))
11614 (clobber (reg:CC FLAGS_REG))]
11615 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11616 && (TARGET_SHIFT1 || optimize_size)"
11618 [(set_attr "type" "ishift")
11619 (set_attr "length" "2")])
11621 (define_insn "*ashrsi3_1"
11622 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11623 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11624 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11625 (clobber (reg:CC FLAGS_REG))]
11626 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11628 sar{l}\t{%2, %0|%0, %2}
11629 sar{l}\t{%b2, %0|%0, %b2}"
11630 [(set_attr "type" "ishift")
11631 (set_attr "mode" "SI")])
11633 (define_insn "*ashrsi3_1_zext"
11634 [(set (match_operand:DI 0 "register_operand" "=r,r")
11635 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11636 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11637 (clobber (reg:CC FLAGS_REG))]
11638 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11640 sar{l}\t{%2, %k0|%k0, %2}
11641 sar{l}\t{%b2, %k0|%k0, %b2}"
11642 [(set_attr "type" "ishift")
11643 (set_attr "mode" "SI")])
11645 ;; This pattern can't accept a variable shift count, since shifts by
11646 ;; zero don't affect the flags. We assume that shifts by constant
11647 ;; zero are optimized away.
11648 (define_insn "*ashrsi3_one_bit_cmp"
11649 [(set (reg FLAGS_REG)
11651 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11652 (match_operand:QI 2 "const1_operand" ""))
11654 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11655 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11656 "ix86_match_ccmode (insn, CCGOCmode)
11657 && (TARGET_SHIFT1 || optimize_size)
11658 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11660 [(set_attr "type" "ishift")
11661 (set (attr "length")
11662 (if_then_else (match_operand:SI 0 "register_operand" "")
11664 (const_string "*")))])
11666 (define_insn "*ashrsi3_one_bit_cconly"
11667 [(set (reg FLAGS_REG)
11669 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11670 (match_operand:QI 2 "const1_operand" ""))
11672 (clobber (match_scratch:SI 0 "=r"))]
11673 "ix86_match_ccmode (insn, CCGOCmode)
11674 && (TARGET_SHIFT1 || optimize_size)
11675 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11677 [(set_attr "type" "ishift")
11678 (set_attr "length" "2")])
11680 (define_insn "*ashrsi3_one_bit_cmp_zext"
11681 [(set (reg FLAGS_REG)
11683 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11684 (match_operand:QI 2 "const1_operand" ""))
11686 (set (match_operand:DI 0 "register_operand" "=r")
11687 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11688 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11689 && (TARGET_SHIFT1 || optimize_size)
11690 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11692 [(set_attr "type" "ishift")
11693 (set_attr "length" "2")])
11695 ;; This pattern can't accept a variable shift count, since shifts by
11696 ;; zero don't affect the flags. We assume that shifts by constant
11697 ;; zero are optimized away.
11698 (define_insn "*ashrsi3_cmp"
11699 [(set (reg FLAGS_REG)
11701 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11702 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11704 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11705 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11706 "ix86_match_ccmode (insn, CCGOCmode)
11707 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11709 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11710 "sar{l}\t{%2, %0|%0, %2}"
11711 [(set_attr "type" "ishift")
11712 (set_attr "mode" "SI")])
11714 (define_insn "*ashrsi3_cconly"
11715 [(set (reg FLAGS_REG)
11717 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11718 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11720 (clobber (match_scratch:SI 0 "=r"))]
11721 "ix86_match_ccmode (insn, CCGOCmode)
11722 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11724 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11725 "sar{l}\t{%2, %0|%0, %2}"
11726 [(set_attr "type" "ishift")
11727 (set_attr "mode" "SI")])
11729 (define_insn "*ashrsi3_cmp_zext"
11730 [(set (reg FLAGS_REG)
11732 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11733 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11735 (set (match_operand:DI 0 "register_operand" "=r")
11736 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11737 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11738 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11740 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11741 "sar{l}\t{%2, %k0|%k0, %2}"
11742 [(set_attr "type" "ishift")
11743 (set_attr "mode" "SI")])
11745 (define_expand "ashrhi3"
11746 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11747 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11748 (match_operand:QI 2 "nonmemory_operand" "")))
11749 (clobber (reg:CC FLAGS_REG))]
11750 "TARGET_HIMODE_MATH"
11751 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11753 (define_insn "*ashrhi3_1_one_bit"
11754 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11755 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11756 (match_operand:QI 2 "const1_operand" "")))
11757 (clobber (reg:CC FLAGS_REG))]
11758 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11759 && (TARGET_SHIFT1 || optimize_size)"
11761 [(set_attr "type" "ishift")
11762 (set (attr "length")
11763 (if_then_else (match_operand 0 "register_operand" "")
11765 (const_string "*")))])
11767 (define_insn "*ashrhi3_1"
11768 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11769 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11770 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11771 (clobber (reg:CC FLAGS_REG))]
11772 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11774 sar{w}\t{%2, %0|%0, %2}
11775 sar{w}\t{%b2, %0|%0, %b2}"
11776 [(set_attr "type" "ishift")
11777 (set_attr "mode" "HI")])
11779 ;; This pattern can't accept a variable shift count, since shifts by
11780 ;; zero don't affect the flags. We assume that shifts by constant
11781 ;; zero are optimized away.
11782 (define_insn "*ashrhi3_one_bit_cmp"
11783 [(set (reg FLAGS_REG)
11785 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11786 (match_operand:QI 2 "const1_operand" ""))
11788 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11789 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11790 "ix86_match_ccmode (insn, CCGOCmode)
11791 && (TARGET_SHIFT1 || optimize_size)
11792 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11794 [(set_attr "type" "ishift")
11795 (set (attr "length")
11796 (if_then_else (match_operand 0 "register_operand" "")
11798 (const_string "*")))])
11800 (define_insn "*ashrhi3_one_bit_cconly"
11801 [(set (reg FLAGS_REG)
11803 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11804 (match_operand:QI 2 "const1_operand" ""))
11806 (clobber (match_scratch:HI 0 "=r"))]
11807 "ix86_match_ccmode (insn, CCGOCmode)
11808 && (TARGET_SHIFT1 || optimize_size)
11809 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11811 [(set_attr "type" "ishift")
11812 (set_attr "length" "2")])
11814 ;; This pattern can't accept a variable shift count, since shifts by
11815 ;; zero don't affect the flags. We assume that shifts by constant
11816 ;; zero are optimized away.
11817 (define_insn "*ashrhi3_cmp"
11818 [(set (reg FLAGS_REG)
11820 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11821 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11823 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11824 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11825 "ix86_match_ccmode (insn, CCGOCmode)
11826 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11828 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11829 "sar{w}\t{%2, %0|%0, %2}"
11830 [(set_attr "type" "ishift")
11831 (set_attr "mode" "HI")])
11833 (define_insn "*ashrhi3_cconly"
11834 [(set (reg FLAGS_REG)
11836 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11837 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11839 (clobber (match_scratch:HI 0 "=r"))]
11840 "ix86_match_ccmode (insn, CCGOCmode)
11841 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11843 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11844 "sar{w}\t{%2, %0|%0, %2}"
11845 [(set_attr "type" "ishift")
11846 (set_attr "mode" "HI")])
11848 (define_expand "ashrqi3"
11849 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11850 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11851 (match_operand:QI 2 "nonmemory_operand" "")))
11852 (clobber (reg:CC FLAGS_REG))]
11853 "TARGET_QIMODE_MATH"
11854 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11856 (define_insn "*ashrqi3_1_one_bit"
11857 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11858 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11859 (match_operand:QI 2 "const1_operand" "")))
11860 (clobber (reg:CC FLAGS_REG))]
11861 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11862 && (TARGET_SHIFT1 || optimize_size)"
11864 [(set_attr "type" "ishift")
11865 (set (attr "length")
11866 (if_then_else (match_operand 0 "register_operand" "")
11868 (const_string "*")))])
11870 (define_insn "*ashrqi3_1_one_bit_slp"
11871 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11872 (ashiftrt:QI (match_dup 0)
11873 (match_operand:QI 1 "const1_operand" "")))
11874 (clobber (reg:CC FLAGS_REG))]
11875 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11876 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11877 && (TARGET_SHIFT1 || optimize_size)"
11879 [(set_attr "type" "ishift1")
11880 (set (attr "length")
11881 (if_then_else (match_operand 0 "register_operand" "")
11883 (const_string "*")))])
11885 (define_insn "*ashrqi3_1"
11886 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11887 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11888 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11889 (clobber (reg:CC FLAGS_REG))]
11890 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11892 sar{b}\t{%2, %0|%0, %2}
11893 sar{b}\t{%b2, %0|%0, %b2}"
11894 [(set_attr "type" "ishift")
11895 (set_attr "mode" "QI")])
11897 (define_insn "*ashrqi3_1_slp"
11898 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11899 (ashiftrt:QI (match_dup 0)
11900 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11901 (clobber (reg:CC FLAGS_REG))]
11902 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11903 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11905 sar{b}\t{%1, %0|%0, %1}
11906 sar{b}\t{%b1, %0|%0, %b1}"
11907 [(set_attr "type" "ishift1")
11908 (set_attr "mode" "QI")])
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 "*ashrqi3_one_bit_cmp"
11914 [(set (reg FLAGS_REG)
11916 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11917 (match_operand:QI 2 "const1_operand" "I"))
11919 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11920 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11921 "ix86_match_ccmode (insn, CCGOCmode)
11922 && (TARGET_SHIFT1 || optimize_size)
11923 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11925 [(set_attr "type" "ishift")
11926 (set (attr "length")
11927 (if_then_else (match_operand 0 "register_operand" "")
11929 (const_string "*")))])
11931 (define_insn "*ashrqi3_one_bit_cconly"
11932 [(set (reg FLAGS_REG)
11934 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11935 (match_operand:QI 2 "const1_operand" "I"))
11937 (clobber (match_scratch:QI 0 "=q"))]
11938 "ix86_match_ccmode (insn, CCGOCmode)
11939 && (TARGET_SHIFT1 || optimize_size)
11940 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11942 [(set_attr "type" "ishift")
11943 (set_attr "length" "2")])
11945 ;; This pattern can't accept a variable shift count, since shifts by
11946 ;; zero don't affect the flags. We assume that shifts by constant
11947 ;; zero are optimized away.
11948 (define_insn "*ashrqi3_cmp"
11949 [(set (reg FLAGS_REG)
11951 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11952 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11954 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11955 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11956 "ix86_match_ccmode (insn, CCGOCmode)
11957 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11959 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11960 "sar{b}\t{%2, %0|%0, %2}"
11961 [(set_attr "type" "ishift")
11962 (set_attr "mode" "QI")])
11964 (define_insn "*ashrqi3_cconly"
11965 [(set (reg FLAGS_REG)
11967 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11968 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11970 (clobber (match_scratch:QI 0 "=q"))]
11971 "ix86_match_ccmode (insn, CCGOCmode)
11972 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11974 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11975 "sar{b}\t{%2, %0|%0, %2}"
11976 [(set_attr "type" "ishift")
11977 (set_attr "mode" "QI")])
11980 ;; Logical shift instructions
11982 ;; See comment above `ashldi3' about how this works.
11984 (define_expand "lshrti3"
11985 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11986 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11987 (match_operand:QI 2 "nonmemory_operand" "")))
11988 (clobber (reg:CC FLAGS_REG))])]
11991 if (! immediate_operand (operands[2], QImode))
11993 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11996 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12000 (define_insn "lshrti3_1"
12001 [(set (match_operand:TI 0 "register_operand" "=r")
12002 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12003 (match_operand:QI 2 "register_operand" "c")))
12004 (clobber (match_scratch:DI 3 "=&r"))
12005 (clobber (reg:CC FLAGS_REG))]
12008 [(set_attr "type" "multi")])
12010 (define_insn "*lshrti3_2"
12011 [(set (match_operand:TI 0 "register_operand" "=r")
12012 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12013 (match_operand:QI 2 "immediate_operand" "O")))
12014 (clobber (reg:CC FLAGS_REG))]
12017 [(set_attr "type" "multi")])
12020 [(set (match_operand:TI 0 "register_operand" "")
12021 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12022 (match_operand:QI 2 "register_operand" "")))
12023 (clobber (match_scratch:DI 3 ""))
12024 (clobber (reg:CC FLAGS_REG))]
12025 "TARGET_64BIT && reload_completed"
12027 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12030 [(set (match_operand:TI 0 "register_operand" "")
12031 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12032 (match_operand:QI 2 "immediate_operand" "")))
12033 (clobber (reg:CC FLAGS_REG))]
12034 "TARGET_64BIT && reload_completed"
12036 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12038 (define_expand "lshrdi3"
12039 [(set (match_operand:DI 0 "shiftdi_operand" "")
12040 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12041 (match_operand:QI 2 "nonmemory_operand" "")))]
12043 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12045 (define_insn "*lshrdi3_1_one_bit_rex64"
12046 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12047 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12048 (match_operand:QI 2 "const1_operand" "")))
12049 (clobber (reg:CC FLAGS_REG))]
12050 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12051 && (TARGET_SHIFT1 || optimize_size)"
12053 [(set_attr "type" "ishift")
12054 (set (attr "length")
12055 (if_then_else (match_operand:DI 0 "register_operand" "")
12057 (const_string "*")))])
12059 (define_insn "*lshrdi3_1_rex64"
12060 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12061 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12062 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12063 (clobber (reg:CC FLAGS_REG))]
12064 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12066 shr{q}\t{%2, %0|%0, %2}
12067 shr{q}\t{%b2, %0|%0, %b2}"
12068 [(set_attr "type" "ishift")
12069 (set_attr "mode" "DI")])
12071 ;; This pattern can't accept a variable shift count, since shifts by
12072 ;; zero don't affect the flags. We assume that shifts by constant
12073 ;; zero are optimized away.
12074 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12075 [(set (reg FLAGS_REG)
12077 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12078 (match_operand:QI 2 "const1_operand" ""))
12080 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12081 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12082 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12083 && (TARGET_SHIFT1 || optimize_size)
12084 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12086 [(set_attr "type" "ishift")
12087 (set (attr "length")
12088 (if_then_else (match_operand:DI 0 "register_operand" "")
12090 (const_string "*")))])
12092 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12093 [(set (reg FLAGS_REG)
12095 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12096 (match_operand:QI 2 "const1_operand" ""))
12098 (clobber (match_scratch:DI 0 "=r"))]
12099 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12100 && (TARGET_SHIFT1 || optimize_size)
12101 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12103 [(set_attr "type" "ishift")
12104 (set_attr "length" "2")])
12106 ;; This pattern can't accept a variable shift count, since shifts by
12107 ;; zero don't affect the flags. We assume that shifts by constant
12108 ;; zero are optimized away.
12109 (define_insn "*lshrdi3_cmp_rex64"
12110 [(set (reg FLAGS_REG)
12112 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12113 (match_operand:QI 2 "const_int_operand" "e"))
12115 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12116 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12117 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12118 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12120 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12121 "shr{q}\t{%2, %0|%0, %2}"
12122 [(set_attr "type" "ishift")
12123 (set_attr "mode" "DI")])
12125 (define_insn "*lshrdi3_cconly_rex64"
12126 [(set (reg FLAGS_REG)
12128 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12129 (match_operand:QI 2 "const_int_operand" "e"))
12131 (clobber (match_scratch:DI 0 "=r"))]
12132 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12133 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12135 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12136 "shr{q}\t{%2, %0|%0, %2}"
12137 [(set_attr "type" "ishift")
12138 (set_attr "mode" "DI")])
12140 (define_insn "*lshrdi3_1"
12141 [(set (match_operand:DI 0 "register_operand" "=r")
12142 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12143 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12144 (clobber (reg:CC FLAGS_REG))]
12147 [(set_attr "type" "multi")])
12149 ;; By default we don't ask for a scratch register, because when DImode
12150 ;; values are manipulated, registers are already at a premium. But if
12151 ;; we have one handy, we won't turn it away.
12153 [(match_scratch:SI 3 "r")
12154 (parallel [(set (match_operand:DI 0 "register_operand" "")
12155 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12156 (match_operand:QI 2 "nonmemory_operand" "")))
12157 (clobber (reg:CC FLAGS_REG))])
12159 "!TARGET_64BIT && TARGET_CMOVE"
12161 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12164 [(set (match_operand:DI 0 "register_operand" "")
12165 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12166 (match_operand:QI 2 "nonmemory_operand" "")))
12167 (clobber (reg:CC FLAGS_REG))]
12168 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12169 ? flow2_completed : reload_completed)"
12171 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12173 (define_expand "lshrsi3"
12174 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12175 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12176 (match_operand:QI 2 "nonmemory_operand" "")))
12177 (clobber (reg:CC FLAGS_REG))]
12179 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12181 (define_insn "*lshrsi3_1_one_bit"
12182 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12183 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12184 (match_operand:QI 2 "const1_operand" "")))
12185 (clobber (reg:CC FLAGS_REG))]
12186 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12187 && (TARGET_SHIFT1 || optimize_size)"
12189 [(set_attr "type" "ishift")
12190 (set (attr "length")
12191 (if_then_else (match_operand:SI 0 "register_operand" "")
12193 (const_string "*")))])
12195 (define_insn "*lshrsi3_1_one_bit_zext"
12196 [(set (match_operand:DI 0 "register_operand" "=r")
12197 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12198 (match_operand:QI 2 "const1_operand" "")))
12199 (clobber (reg:CC FLAGS_REG))]
12200 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12201 && (TARGET_SHIFT1 || optimize_size)"
12203 [(set_attr "type" "ishift")
12204 (set_attr "length" "2")])
12206 (define_insn "*lshrsi3_1"
12207 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12208 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12209 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12210 (clobber (reg:CC FLAGS_REG))]
12211 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12213 shr{l}\t{%2, %0|%0, %2}
12214 shr{l}\t{%b2, %0|%0, %b2}"
12215 [(set_attr "type" "ishift")
12216 (set_attr "mode" "SI")])
12218 (define_insn "*lshrsi3_1_zext"
12219 [(set (match_operand:DI 0 "register_operand" "=r,r")
12221 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12222 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12223 (clobber (reg:CC FLAGS_REG))]
12224 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12226 shr{l}\t{%2, %k0|%k0, %2}
12227 shr{l}\t{%b2, %k0|%k0, %b2}"
12228 [(set_attr "type" "ishift")
12229 (set_attr "mode" "SI")])
12231 ;; This pattern can't accept a variable shift count, since shifts by
12232 ;; zero don't affect the flags. We assume that shifts by constant
12233 ;; zero are optimized away.
12234 (define_insn "*lshrsi3_one_bit_cmp"
12235 [(set (reg FLAGS_REG)
12237 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12238 (match_operand:QI 2 "const1_operand" ""))
12240 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12241 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12242 "ix86_match_ccmode (insn, CCGOCmode)
12243 && (TARGET_SHIFT1 || optimize_size)
12244 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12246 [(set_attr "type" "ishift")
12247 (set (attr "length")
12248 (if_then_else (match_operand:SI 0 "register_operand" "")
12250 (const_string "*")))])
12252 (define_insn "*lshrsi3_one_bit_cconly"
12253 [(set (reg FLAGS_REG)
12255 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12256 (match_operand:QI 2 "const1_operand" ""))
12258 (clobber (match_scratch:SI 0 "=r"))]
12259 "ix86_match_ccmode (insn, CCGOCmode)
12260 && (TARGET_SHIFT1 || optimize_size)
12261 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12263 [(set_attr "type" "ishift")
12264 (set_attr "length" "2")])
12266 (define_insn "*lshrsi3_cmp_one_bit_zext"
12267 [(set (reg FLAGS_REG)
12269 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12270 (match_operand:QI 2 "const1_operand" ""))
12272 (set (match_operand:DI 0 "register_operand" "=r")
12273 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12274 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12275 && (TARGET_SHIFT1 || optimize_size)
12276 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12278 [(set_attr "type" "ishift")
12279 (set_attr "length" "2")])
12281 ;; This pattern can't accept a variable shift count, since shifts by
12282 ;; zero don't affect the flags. We assume that shifts by constant
12283 ;; zero are optimized away.
12284 (define_insn "*lshrsi3_cmp"
12285 [(set (reg FLAGS_REG)
12287 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12288 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12290 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12291 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12292 "ix86_match_ccmode (insn, CCGOCmode)
12293 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12295 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12296 "shr{l}\t{%2, %0|%0, %2}"
12297 [(set_attr "type" "ishift")
12298 (set_attr "mode" "SI")])
12300 (define_insn "*lshrsi3_cconly"
12301 [(set (reg FLAGS_REG)
12303 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12304 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12306 (clobber (match_scratch:SI 0 "=r"))]
12307 "ix86_match_ccmode (insn, CCGOCmode)
12308 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12310 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12311 "shr{l}\t{%2, %0|%0, %2}"
12312 [(set_attr "type" "ishift")
12313 (set_attr "mode" "SI")])
12315 (define_insn "*lshrsi3_cmp_zext"
12316 [(set (reg FLAGS_REG)
12318 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12319 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12321 (set (match_operand:DI 0 "register_operand" "=r")
12322 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12323 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12324 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12326 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12327 "shr{l}\t{%2, %k0|%k0, %2}"
12328 [(set_attr "type" "ishift")
12329 (set_attr "mode" "SI")])
12331 (define_expand "lshrhi3"
12332 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12333 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12334 (match_operand:QI 2 "nonmemory_operand" "")))
12335 (clobber (reg:CC FLAGS_REG))]
12336 "TARGET_HIMODE_MATH"
12337 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12339 (define_insn "*lshrhi3_1_one_bit"
12340 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12341 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12342 (match_operand:QI 2 "const1_operand" "")))
12343 (clobber (reg:CC FLAGS_REG))]
12344 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12345 && (TARGET_SHIFT1 || optimize_size)"
12347 [(set_attr "type" "ishift")
12348 (set (attr "length")
12349 (if_then_else (match_operand 0 "register_operand" "")
12351 (const_string "*")))])
12353 (define_insn "*lshrhi3_1"
12354 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12355 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12356 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12357 (clobber (reg:CC FLAGS_REG))]
12358 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12360 shr{w}\t{%2, %0|%0, %2}
12361 shr{w}\t{%b2, %0|%0, %b2}"
12362 [(set_attr "type" "ishift")
12363 (set_attr "mode" "HI")])
12365 ;; This pattern can't accept a variable shift count, since shifts by
12366 ;; zero don't affect the flags. We assume that shifts by constant
12367 ;; zero are optimized away.
12368 (define_insn "*lshrhi3_one_bit_cmp"
12369 [(set (reg FLAGS_REG)
12371 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12372 (match_operand:QI 2 "const1_operand" ""))
12374 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12375 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12376 "ix86_match_ccmode (insn, CCGOCmode)
12377 && (TARGET_SHIFT1 || optimize_size)
12378 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12380 [(set_attr "type" "ishift")
12381 (set (attr "length")
12382 (if_then_else (match_operand:SI 0 "register_operand" "")
12384 (const_string "*")))])
12386 (define_insn "*lshrhi3_one_bit_cconly"
12387 [(set (reg FLAGS_REG)
12389 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12390 (match_operand:QI 2 "const1_operand" ""))
12392 (clobber (match_scratch:HI 0 "=r"))]
12393 "ix86_match_ccmode (insn, CCGOCmode)
12394 && (TARGET_SHIFT1 || optimize_size)
12395 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12397 [(set_attr "type" "ishift")
12398 (set_attr "length" "2")])
12400 ;; This pattern can't accept a variable shift count, since shifts by
12401 ;; zero don't affect the flags. We assume that shifts by constant
12402 ;; zero are optimized away.
12403 (define_insn "*lshrhi3_cmp"
12404 [(set (reg FLAGS_REG)
12406 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12407 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12409 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12410 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12411 "ix86_match_ccmode (insn, CCGOCmode)
12412 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12414 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12415 "shr{w}\t{%2, %0|%0, %2}"
12416 [(set_attr "type" "ishift")
12417 (set_attr "mode" "HI")])
12419 (define_insn "*lshrhi3_cconly"
12420 [(set (reg FLAGS_REG)
12422 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12423 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12425 (clobber (match_scratch:HI 0 "=r"))]
12426 "ix86_match_ccmode (insn, CCGOCmode)
12427 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12429 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12430 "shr{w}\t{%2, %0|%0, %2}"
12431 [(set_attr "type" "ishift")
12432 (set_attr "mode" "HI")])
12434 (define_expand "lshrqi3"
12435 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12436 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12437 (match_operand:QI 2 "nonmemory_operand" "")))
12438 (clobber (reg:CC FLAGS_REG))]
12439 "TARGET_QIMODE_MATH"
12440 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12442 (define_insn "*lshrqi3_1_one_bit"
12443 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12444 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12445 (match_operand:QI 2 "const1_operand" "")))
12446 (clobber (reg:CC FLAGS_REG))]
12447 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12448 && (TARGET_SHIFT1 || optimize_size)"
12450 [(set_attr "type" "ishift")
12451 (set (attr "length")
12452 (if_then_else (match_operand 0 "register_operand" "")
12454 (const_string "*")))])
12456 (define_insn "*lshrqi3_1_one_bit_slp"
12457 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12458 (lshiftrt:QI (match_dup 0)
12459 (match_operand:QI 1 "const1_operand" "")))
12460 (clobber (reg:CC FLAGS_REG))]
12461 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12462 && (TARGET_SHIFT1 || optimize_size)"
12464 [(set_attr "type" "ishift1")
12465 (set (attr "length")
12466 (if_then_else (match_operand 0 "register_operand" "")
12468 (const_string "*")))])
12470 (define_insn "*lshrqi3_1"
12471 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12472 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12473 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12474 (clobber (reg:CC FLAGS_REG))]
12475 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12477 shr{b}\t{%2, %0|%0, %2}
12478 shr{b}\t{%b2, %0|%0, %b2}"
12479 [(set_attr "type" "ishift")
12480 (set_attr "mode" "QI")])
12482 (define_insn "*lshrqi3_1_slp"
12483 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12484 (lshiftrt:QI (match_dup 0)
12485 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12486 (clobber (reg:CC FLAGS_REG))]
12487 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12488 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12490 shr{b}\t{%1, %0|%0, %1}
12491 shr{b}\t{%b1, %0|%0, %b1}"
12492 [(set_attr "type" "ishift1")
12493 (set_attr "mode" "QI")])
12495 ;; This pattern can't accept a variable shift count, since shifts by
12496 ;; zero don't affect the flags. We assume that shifts by constant
12497 ;; zero are optimized away.
12498 (define_insn "*lshrqi2_one_bit_cmp"
12499 [(set (reg FLAGS_REG)
12501 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12502 (match_operand:QI 2 "const1_operand" ""))
12504 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12505 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12506 "ix86_match_ccmode (insn, CCGOCmode)
12507 && (TARGET_SHIFT1 || optimize_size)
12508 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12510 [(set_attr "type" "ishift")
12511 (set (attr "length")
12512 (if_then_else (match_operand:SI 0 "register_operand" "")
12514 (const_string "*")))])
12516 (define_insn "*lshrqi2_one_bit_cconly"
12517 [(set (reg FLAGS_REG)
12519 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12520 (match_operand:QI 2 "const1_operand" ""))
12522 (clobber (match_scratch:QI 0 "=q"))]
12523 "ix86_match_ccmode (insn, CCGOCmode)
12524 && (TARGET_SHIFT1 || optimize_size)
12525 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12527 [(set_attr "type" "ishift")
12528 (set_attr "length" "2")])
12530 ;; This pattern can't accept a variable shift count, since shifts by
12531 ;; zero don't affect the flags. We assume that shifts by constant
12532 ;; zero are optimized away.
12533 (define_insn "*lshrqi2_cmp"
12534 [(set (reg FLAGS_REG)
12536 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12537 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12539 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12540 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12541 "ix86_match_ccmode (insn, CCGOCmode)
12542 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12544 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12545 "shr{b}\t{%2, %0|%0, %2}"
12546 [(set_attr "type" "ishift")
12547 (set_attr "mode" "QI")])
12549 (define_insn "*lshrqi2_cconly"
12550 [(set (reg FLAGS_REG)
12552 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12553 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12555 (clobber (match_scratch:QI 0 "=q"))]
12556 "ix86_match_ccmode (insn, CCGOCmode)
12557 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12559 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12560 "shr{b}\t{%2, %0|%0, %2}"
12561 [(set_attr "type" "ishift")
12562 (set_attr "mode" "QI")])
12564 ;; Rotate instructions
12566 (define_expand "rotldi3"
12567 [(set (match_operand:DI 0 "shiftdi_operand" "")
12568 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12569 (match_operand:QI 2 "nonmemory_operand" "")))
12570 (clobber (reg:CC FLAGS_REG))]
12575 ix86_expand_binary_operator (ROTATE, DImode, operands);
12578 if (!const_1_to_31_operand (operands[2], VOIDmode))
12580 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12584 ;; Implement rotation using two double-precision shift instructions
12585 ;; and a scratch register.
12586 (define_insn_and_split "ix86_rotldi3"
12587 [(set (match_operand:DI 0 "register_operand" "=r")
12588 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12589 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12590 (clobber (reg:CC FLAGS_REG))
12591 (clobber (match_scratch:SI 3 "=&r"))]
12594 "&& reload_completed"
12595 [(set (match_dup 3) (match_dup 4))
12597 [(set (match_dup 4)
12598 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12599 (lshiftrt:SI (match_dup 5)
12600 (minus:QI (const_int 32) (match_dup 2)))))
12601 (clobber (reg:CC FLAGS_REG))])
12603 [(set (match_dup 5)
12604 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12605 (lshiftrt:SI (match_dup 3)
12606 (minus:QI (const_int 32) (match_dup 2)))))
12607 (clobber (reg:CC FLAGS_REG))])]
12608 "split_di (operands, 1, operands + 4, operands + 5);")
12610 (define_insn "*rotlsi3_1_one_bit_rex64"
12611 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12612 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12613 (match_operand:QI 2 "const1_operand" "")))
12614 (clobber (reg:CC FLAGS_REG))]
12615 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12616 && (TARGET_SHIFT1 || optimize_size)"
12618 [(set_attr "type" "rotate")
12619 (set (attr "length")
12620 (if_then_else (match_operand:DI 0 "register_operand" "")
12622 (const_string "*")))])
12624 (define_insn "*rotldi3_1_rex64"
12625 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12626 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12627 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12628 (clobber (reg:CC FLAGS_REG))]
12629 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12631 rol{q}\t{%2, %0|%0, %2}
12632 rol{q}\t{%b2, %0|%0, %b2}"
12633 [(set_attr "type" "rotate")
12634 (set_attr "mode" "DI")])
12636 (define_expand "rotlsi3"
12637 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12638 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12639 (match_operand:QI 2 "nonmemory_operand" "")))
12640 (clobber (reg:CC FLAGS_REG))]
12642 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12644 (define_insn "*rotlsi3_1_one_bit"
12645 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12646 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12647 (match_operand:QI 2 "const1_operand" "")))
12648 (clobber (reg:CC FLAGS_REG))]
12649 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12650 && (TARGET_SHIFT1 || optimize_size)"
12652 [(set_attr "type" "rotate")
12653 (set (attr "length")
12654 (if_then_else (match_operand:SI 0 "register_operand" "")
12656 (const_string "*")))])
12658 (define_insn "*rotlsi3_1_one_bit_zext"
12659 [(set (match_operand:DI 0 "register_operand" "=r")
12661 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12662 (match_operand:QI 2 "const1_operand" ""))))
12663 (clobber (reg:CC FLAGS_REG))]
12664 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12665 && (TARGET_SHIFT1 || optimize_size)"
12667 [(set_attr "type" "rotate")
12668 (set_attr "length" "2")])
12670 (define_insn "*rotlsi3_1"
12671 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12672 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12673 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12674 (clobber (reg:CC FLAGS_REG))]
12675 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12677 rol{l}\t{%2, %0|%0, %2}
12678 rol{l}\t{%b2, %0|%0, %b2}"
12679 [(set_attr "type" "rotate")
12680 (set_attr "mode" "SI")])
12682 (define_insn "*rotlsi3_1_zext"
12683 [(set (match_operand:DI 0 "register_operand" "=r,r")
12685 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12686 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12687 (clobber (reg:CC FLAGS_REG))]
12688 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12690 rol{l}\t{%2, %k0|%k0, %2}
12691 rol{l}\t{%b2, %k0|%k0, %b2}"
12692 [(set_attr "type" "rotate")
12693 (set_attr "mode" "SI")])
12695 (define_expand "rotlhi3"
12696 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12697 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12698 (match_operand:QI 2 "nonmemory_operand" "")))
12699 (clobber (reg:CC FLAGS_REG))]
12700 "TARGET_HIMODE_MATH"
12701 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12703 (define_insn "*rotlhi3_1_one_bit"
12704 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12705 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12706 (match_operand:QI 2 "const1_operand" "")))
12707 (clobber (reg:CC FLAGS_REG))]
12708 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12709 && (TARGET_SHIFT1 || optimize_size)"
12711 [(set_attr "type" "rotate")
12712 (set (attr "length")
12713 (if_then_else (match_operand 0 "register_operand" "")
12715 (const_string "*")))])
12717 (define_insn "*rotlhi3_1"
12718 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12719 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12720 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12721 (clobber (reg:CC FLAGS_REG))]
12722 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12724 rol{w}\t{%2, %0|%0, %2}
12725 rol{w}\t{%b2, %0|%0, %b2}"
12726 [(set_attr "type" "rotate")
12727 (set_attr "mode" "HI")])
12730 [(set (match_operand:HI 0 "register_operand" "")
12731 (rotate:HI (match_dup 0) (const_int 8)))
12732 (clobber (reg:CC FLAGS_REG))]
12734 [(parallel [(set (strict_low_part (match_dup 0))
12735 (bswap:HI (match_dup 0)))
12736 (clobber (reg:CC FLAGS_REG))])]
12739 (define_expand "rotlqi3"
12740 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12741 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12742 (match_operand:QI 2 "nonmemory_operand" "")))
12743 (clobber (reg:CC FLAGS_REG))]
12744 "TARGET_QIMODE_MATH"
12745 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12747 (define_insn "*rotlqi3_1_one_bit_slp"
12748 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12749 (rotate:QI (match_dup 0)
12750 (match_operand:QI 1 "const1_operand" "")))
12751 (clobber (reg:CC FLAGS_REG))]
12752 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12753 && (TARGET_SHIFT1 || optimize_size)"
12755 [(set_attr "type" "rotate1")
12756 (set (attr "length")
12757 (if_then_else (match_operand 0 "register_operand" "")
12759 (const_string "*")))])
12761 (define_insn "*rotlqi3_1_one_bit"
12762 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12763 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12764 (match_operand:QI 2 "const1_operand" "")))
12765 (clobber (reg:CC FLAGS_REG))]
12766 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12767 && (TARGET_SHIFT1 || optimize_size)"
12769 [(set_attr "type" "rotate")
12770 (set (attr "length")
12771 (if_then_else (match_operand 0 "register_operand" "")
12773 (const_string "*")))])
12775 (define_insn "*rotlqi3_1_slp"
12776 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12777 (rotate:QI (match_dup 0)
12778 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12779 (clobber (reg:CC FLAGS_REG))]
12780 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12781 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12783 rol{b}\t{%1, %0|%0, %1}
12784 rol{b}\t{%b1, %0|%0, %b1}"
12785 [(set_attr "type" "rotate1")
12786 (set_attr "mode" "QI")])
12788 (define_insn "*rotlqi3_1"
12789 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12790 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12791 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12792 (clobber (reg:CC FLAGS_REG))]
12793 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12795 rol{b}\t{%2, %0|%0, %2}
12796 rol{b}\t{%b2, %0|%0, %b2}"
12797 [(set_attr "type" "rotate")
12798 (set_attr "mode" "QI")])
12800 (define_expand "rotrdi3"
12801 [(set (match_operand:DI 0 "shiftdi_operand" "")
12802 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12803 (match_operand:QI 2 "nonmemory_operand" "")))
12804 (clobber (reg:CC FLAGS_REG))]
12809 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12812 if (!const_1_to_31_operand (operands[2], VOIDmode))
12814 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12818 ;; Implement rotation using two double-precision shift instructions
12819 ;; and a scratch register.
12820 (define_insn_and_split "ix86_rotrdi3"
12821 [(set (match_operand:DI 0 "register_operand" "=r")
12822 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12823 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12824 (clobber (reg:CC FLAGS_REG))
12825 (clobber (match_scratch:SI 3 "=&r"))]
12828 "&& reload_completed"
12829 [(set (match_dup 3) (match_dup 4))
12831 [(set (match_dup 4)
12832 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12833 (ashift:SI (match_dup 5)
12834 (minus:QI (const_int 32) (match_dup 2)))))
12835 (clobber (reg:CC FLAGS_REG))])
12837 [(set (match_dup 5)
12838 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12839 (ashift:SI (match_dup 3)
12840 (minus:QI (const_int 32) (match_dup 2)))))
12841 (clobber (reg:CC FLAGS_REG))])]
12842 "split_di (operands, 1, operands + 4, operands + 5);")
12844 (define_insn "*rotrdi3_1_one_bit_rex64"
12845 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12846 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12847 (match_operand:QI 2 "const1_operand" "")))
12848 (clobber (reg:CC FLAGS_REG))]
12849 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12850 && (TARGET_SHIFT1 || optimize_size)"
12852 [(set_attr "type" "rotate")
12853 (set (attr "length")
12854 (if_then_else (match_operand:DI 0 "register_operand" "")
12856 (const_string "*")))])
12858 (define_insn "*rotrdi3_1_rex64"
12859 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12860 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12861 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12862 (clobber (reg:CC FLAGS_REG))]
12863 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12865 ror{q}\t{%2, %0|%0, %2}
12866 ror{q}\t{%b2, %0|%0, %b2}"
12867 [(set_attr "type" "rotate")
12868 (set_attr "mode" "DI")])
12870 (define_expand "rotrsi3"
12871 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12872 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12873 (match_operand:QI 2 "nonmemory_operand" "")))
12874 (clobber (reg:CC FLAGS_REG))]
12876 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12878 (define_insn "*rotrsi3_1_one_bit"
12879 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12880 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12881 (match_operand:QI 2 "const1_operand" "")))
12882 (clobber (reg:CC FLAGS_REG))]
12883 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12884 && (TARGET_SHIFT1 || optimize_size)"
12886 [(set_attr "type" "rotate")
12887 (set (attr "length")
12888 (if_then_else (match_operand:SI 0 "register_operand" "")
12890 (const_string "*")))])
12892 (define_insn "*rotrsi3_1_one_bit_zext"
12893 [(set (match_operand:DI 0 "register_operand" "=r")
12895 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12896 (match_operand:QI 2 "const1_operand" ""))))
12897 (clobber (reg:CC FLAGS_REG))]
12898 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12899 && (TARGET_SHIFT1 || optimize_size)"
12901 [(set_attr "type" "rotate")
12902 (set (attr "length")
12903 (if_then_else (match_operand:SI 0 "register_operand" "")
12905 (const_string "*")))])
12907 (define_insn "*rotrsi3_1"
12908 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12909 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12910 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12911 (clobber (reg:CC FLAGS_REG))]
12912 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12914 ror{l}\t{%2, %0|%0, %2}
12915 ror{l}\t{%b2, %0|%0, %b2}"
12916 [(set_attr "type" "rotate")
12917 (set_attr "mode" "SI")])
12919 (define_insn "*rotrsi3_1_zext"
12920 [(set (match_operand:DI 0 "register_operand" "=r,r")
12922 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12923 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12924 (clobber (reg:CC FLAGS_REG))]
12925 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12927 ror{l}\t{%2, %k0|%k0, %2}
12928 ror{l}\t{%b2, %k0|%k0, %b2}"
12929 [(set_attr "type" "rotate")
12930 (set_attr "mode" "SI")])
12932 (define_expand "rotrhi3"
12933 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12934 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12935 (match_operand:QI 2 "nonmemory_operand" "")))
12936 (clobber (reg:CC FLAGS_REG))]
12937 "TARGET_HIMODE_MATH"
12938 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12940 (define_insn "*rotrhi3_one_bit"
12941 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12942 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12943 (match_operand:QI 2 "const1_operand" "")))
12944 (clobber (reg:CC FLAGS_REG))]
12945 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12946 && (TARGET_SHIFT1 || optimize_size)"
12948 [(set_attr "type" "rotate")
12949 (set (attr "length")
12950 (if_then_else (match_operand 0 "register_operand" "")
12952 (const_string "*")))])
12954 (define_insn "*rotrhi3_1"
12955 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12956 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12957 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12958 (clobber (reg:CC FLAGS_REG))]
12959 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12961 ror{w}\t{%2, %0|%0, %2}
12962 ror{w}\t{%b2, %0|%0, %b2}"
12963 [(set_attr "type" "rotate")
12964 (set_attr "mode" "HI")])
12967 [(set (match_operand:HI 0 "register_operand" "")
12968 (rotatert:HI (match_dup 0) (const_int 8)))
12969 (clobber (reg:CC FLAGS_REG))]
12971 [(parallel [(set (strict_low_part (match_dup 0))
12972 (bswap:HI (match_dup 0)))
12973 (clobber (reg:CC FLAGS_REG))])]
12976 (define_expand "rotrqi3"
12977 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12978 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12979 (match_operand:QI 2 "nonmemory_operand" "")))
12980 (clobber (reg:CC FLAGS_REG))]
12981 "TARGET_QIMODE_MATH"
12982 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12984 (define_insn "*rotrqi3_1_one_bit"
12985 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12986 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12987 (match_operand:QI 2 "const1_operand" "")))
12988 (clobber (reg:CC FLAGS_REG))]
12989 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12990 && (TARGET_SHIFT1 || optimize_size)"
12992 [(set_attr "type" "rotate")
12993 (set (attr "length")
12994 (if_then_else (match_operand 0 "register_operand" "")
12996 (const_string "*")))])
12998 (define_insn "*rotrqi3_1_one_bit_slp"
12999 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13000 (rotatert:QI (match_dup 0)
13001 (match_operand:QI 1 "const1_operand" "")))
13002 (clobber (reg:CC FLAGS_REG))]
13003 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13004 && (TARGET_SHIFT1 || optimize_size)"
13006 [(set_attr "type" "rotate1")
13007 (set (attr "length")
13008 (if_then_else (match_operand 0 "register_operand" "")
13010 (const_string "*")))])
13012 (define_insn "*rotrqi3_1"
13013 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13014 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13015 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13016 (clobber (reg:CC FLAGS_REG))]
13017 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13019 ror{b}\t{%2, %0|%0, %2}
13020 ror{b}\t{%b2, %0|%0, %b2}"
13021 [(set_attr "type" "rotate")
13022 (set_attr "mode" "QI")])
13024 (define_insn "*rotrqi3_1_slp"
13025 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13026 (rotatert:QI (match_dup 0)
13027 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13028 (clobber (reg:CC FLAGS_REG))]
13029 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13030 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13032 ror{b}\t{%1, %0|%0, %1}
13033 ror{b}\t{%b1, %0|%0, %b1}"
13034 [(set_attr "type" "rotate1")
13035 (set_attr "mode" "QI")])
13037 ;; Bit set / bit test instructions
13039 (define_expand "extv"
13040 [(set (match_operand:SI 0 "register_operand" "")
13041 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13042 (match_operand:SI 2 "const8_operand" "")
13043 (match_operand:SI 3 "const8_operand" "")))]
13046 /* Handle extractions from %ah et al. */
13047 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13050 /* From mips.md: extract_bit_field doesn't verify that our source
13051 matches the predicate, so check it again here. */
13052 if (! ext_register_operand (operands[1], VOIDmode))
13056 (define_expand "extzv"
13057 [(set (match_operand:SI 0 "register_operand" "")
13058 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13059 (match_operand:SI 2 "const8_operand" "")
13060 (match_operand:SI 3 "const8_operand" "")))]
13063 /* Handle extractions from %ah et al. */
13064 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13067 /* From mips.md: extract_bit_field doesn't verify that our source
13068 matches the predicate, so check it again here. */
13069 if (! ext_register_operand (operands[1], VOIDmode))
13073 (define_expand "insv"
13074 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13075 (match_operand 1 "const8_operand" "")
13076 (match_operand 2 "const8_operand" ""))
13077 (match_operand 3 "register_operand" ""))]
13080 /* Handle insertions to %ah et al. */
13081 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13084 /* From mips.md: insert_bit_field doesn't verify that our source
13085 matches the predicate, so check it again here. */
13086 if (! ext_register_operand (operands[0], VOIDmode))
13090 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13092 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13097 ;; %%% bts, btr, btc, bt.
13098 ;; In general these instructions are *slow* when applied to memory,
13099 ;; since they enforce atomic operation. When applied to registers,
13100 ;; it depends on the cpu implementation. They're never faster than
13101 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13102 ;; no point. But in 64-bit, we can't hold the relevant immediates
13103 ;; within the instruction itself, so operating on bits in the high
13104 ;; 32-bits of a register becomes easier.
13106 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13107 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13108 ;; negdf respectively, so they can never be disabled entirely.
13110 (define_insn "*btsq"
13111 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13113 (match_operand:DI 1 "const_0_to_63_operand" ""))
13115 (clobber (reg:CC FLAGS_REG))]
13116 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13118 [(set_attr "type" "alu1")])
13120 (define_insn "*btrq"
13121 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13123 (match_operand:DI 1 "const_0_to_63_operand" ""))
13125 (clobber (reg:CC FLAGS_REG))]
13126 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13128 [(set_attr "type" "alu1")])
13130 (define_insn "*btcq"
13131 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13133 (match_operand:DI 1 "const_0_to_63_operand" ""))
13134 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13135 (clobber (reg:CC FLAGS_REG))]
13136 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13138 [(set_attr "type" "alu1")])
13140 ;; Allow Nocona to avoid these instructions if a register is available.
13143 [(match_scratch:DI 2 "r")
13144 (parallel [(set (zero_extract:DI
13145 (match_operand:DI 0 "register_operand" "")
13147 (match_operand:DI 1 "const_0_to_63_operand" ""))
13149 (clobber (reg:CC FLAGS_REG))])]
13150 "TARGET_64BIT && !TARGET_USE_BT"
13153 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13156 if (HOST_BITS_PER_WIDE_INT >= 64)
13157 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13158 else if (i < HOST_BITS_PER_WIDE_INT)
13159 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13161 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13163 op1 = immed_double_const (lo, hi, DImode);
13166 emit_move_insn (operands[2], op1);
13170 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13175 [(match_scratch:DI 2 "r")
13176 (parallel [(set (zero_extract:DI
13177 (match_operand:DI 0 "register_operand" "")
13179 (match_operand:DI 1 "const_0_to_63_operand" ""))
13181 (clobber (reg:CC FLAGS_REG))])]
13182 "TARGET_64BIT && !TARGET_USE_BT"
13185 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13188 if (HOST_BITS_PER_WIDE_INT >= 64)
13189 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13190 else if (i < HOST_BITS_PER_WIDE_INT)
13191 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13193 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13195 op1 = immed_double_const (~lo, ~hi, DImode);
13198 emit_move_insn (operands[2], op1);
13202 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13207 [(match_scratch:DI 2 "r")
13208 (parallel [(set (zero_extract:DI
13209 (match_operand:DI 0 "register_operand" "")
13211 (match_operand:DI 1 "const_0_to_63_operand" ""))
13212 (not:DI (zero_extract:DI
13213 (match_dup 0) (const_int 1) (match_dup 1))))
13214 (clobber (reg:CC FLAGS_REG))])]
13215 "TARGET_64BIT && !TARGET_USE_BT"
13218 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13221 if (HOST_BITS_PER_WIDE_INT >= 64)
13222 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13223 else if (i < HOST_BITS_PER_WIDE_INT)
13224 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13226 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13228 op1 = immed_double_const (lo, hi, DImode);
13231 emit_move_insn (operands[2], op1);
13235 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13239 ;; Store-flag instructions.
13241 ;; For all sCOND expanders, also expand the compare or test insn that
13242 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13244 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13245 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13246 ;; way, which can later delete the movzx if only QImode is needed.
13248 (define_expand "seq"
13249 [(set (match_operand:QI 0 "register_operand" "")
13250 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13254 (define_expand "sne"
13255 [(set (match_operand:QI 0 "register_operand" "")
13256 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13260 (define_expand "sgt"
13261 [(set (match_operand:QI 0 "register_operand" "")
13262 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13266 (define_expand "sgtu"
13267 [(set (match_operand:QI 0 "register_operand" "")
13268 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13272 (define_expand "slt"
13273 [(set (match_operand:QI 0 "register_operand" "")
13274 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13278 (define_expand "sltu"
13279 [(set (match_operand:QI 0 "register_operand" "")
13280 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13284 (define_expand "sge"
13285 [(set (match_operand:QI 0 "register_operand" "")
13286 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13288 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13290 (define_expand "sgeu"
13291 [(set (match_operand:QI 0 "register_operand" "")
13292 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13296 (define_expand "sle"
13297 [(set (match_operand:QI 0 "register_operand" "")
13298 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13300 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13302 (define_expand "sleu"
13303 [(set (match_operand:QI 0 "register_operand" "")
13304 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13306 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13308 (define_expand "sunordered"
13309 [(set (match_operand:QI 0 "register_operand" "")
13310 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13311 "TARGET_80387 || TARGET_SSE"
13312 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13314 (define_expand "sordered"
13315 [(set (match_operand:QI 0 "register_operand" "")
13316 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13318 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13320 (define_expand "suneq"
13321 [(set (match_operand:QI 0 "register_operand" "")
13322 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13323 "TARGET_80387 || TARGET_SSE"
13324 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13326 (define_expand "sunge"
13327 [(set (match_operand:QI 0 "register_operand" "")
13328 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13329 "TARGET_80387 || TARGET_SSE"
13330 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13332 (define_expand "sungt"
13333 [(set (match_operand:QI 0 "register_operand" "")
13334 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13335 "TARGET_80387 || TARGET_SSE"
13336 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13338 (define_expand "sunle"
13339 [(set (match_operand:QI 0 "register_operand" "")
13340 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13341 "TARGET_80387 || TARGET_SSE"
13342 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13344 (define_expand "sunlt"
13345 [(set (match_operand:QI 0 "register_operand" "")
13346 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13347 "TARGET_80387 || TARGET_SSE"
13348 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13350 (define_expand "sltgt"
13351 [(set (match_operand:QI 0 "register_operand" "")
13352 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13353 "TARGET_80387 || TARGET_SSE"
13354 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13356 (define_insn "*setcc_1"
13357 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13358 (match_operator:QI 1 "ix86_comparison_operator"
13359 [(reg FLAGS_REG) (const_int 0)]))]
13362 [(set_attr "type" "setcc")
13363 (set_attr "mode" "QI")])
13365 (define_insn "*setcc_2"
13366 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13367 (match_operator:QI 1 "ix86_comparison_operator"
13368 [(reg FLAGS_REG) (const_int 0)]))]
13371 [(set_attr "type" "setcc")
13372 (set_attr "mode" "QI")])
13374 ;; In general it is not safe to assume too much about CCmode registers,
13375 ;; so simplify-rtx stops when it sees a second one. Under certain
13376 ;; conditions this is safe on x86, so help combine not create
13383 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13384 (ne:QI (match_operator 1 "ix86_comparison_operator"
13385 [(reg FLAGS_REG) (const_int 0)])
13388 [(set (match_dup 0) (match_dup 1))]
13390 PUT_MODE (operands[1], QImode);
13394 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13395 (ne:QI (match_operator 1 "ix86_comparison_operator"
13396 [(reg FLAGS_REG) (const_int 0)])
13399 [(set (match_dup 0) (match_dup 1))]
13401 PUT_MODE (operands[1], QImode);
13405 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13406 (eq:QI (match_operator 1 "ix86_comparison_operator"
13407 [(reg FLAGS_REG) (const_int 0)])
13410 [(set (match_dup 0) (match_dup 1))]
13412 rtx new_op1 = copy_rtx (operands[1]);
13413 operands[1] = new_op1;
13414 PUT_MODE (new_op1, QImode);
13415 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13416 GET_MODE (XEXP (new_op1, 0))));
13418 /* Make sure that (a) the CCmode we have for the flags is strong
13419 enough for the reversed compare or (b) we have a valid FP compare. */
13420 if (! ix86_comparison_operator (new_op1, VOIDmode))
13425 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13426 (eq:QI (match_operator 1 "ix86_comparison_operator"
13427 [(reg FLAGS_REG) (const_int 0)])
13430 [(set (match_dup 0) (match_dup 1))]
13432 rtx new_op1 = copy_rtx (operands[1]);
13433 operands[1] = new_op1;
13434 PUT_MODE (new_op1, QImode);
13435 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13436 GET_MODE (XEXP (new_op1, 0))));
13438 /* Make sure that (a) the CCmode we have for the flags is strong
13439 enough for the reversed compare or (b) we have a valid FP compare. */
13440 if (! ix86_comparison_operator (new_op1, VOIDmode))
13444 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13445 ;; subsequent logical operations are used to imitate conditional moves.
13446 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13449 (define_insn "*sse_setccsf"
13450 [(set (match_operand:SF 0 "register_operand" "=x")
13451 (match_operator:SF 1 "sse_comparison_operator"
13452 [(match_operand:SF 2 "register_operand" "0")
13453 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13455 "cmp%D1ss\t{%3, %0|%0, %3}"
13456 [(set_attr "type" "ssecmp")
13457 (set_attr "mode" "SF")])
13459 (define_insn "*sse_setccdf"
13460 [(set (match_operand:DF 0 "register_operand" "=x")
13461 (match_operator:DF 1 "sse_comparison_operator"
13462 [(match_operand:DF 2 "register_operand" "0")
13463 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13465 "cmp%D1sd\t{%3, %0|%0, %3}"
13466 [(set_attr "type" "ssecmp")
13467 (set_attr "mode" "DF")])
13469 ;; Basic conditional jump instructions.
13470 ;; We ignore the overflow flag for signed branch instructions.
13472 ;; For all bCOND expanders, also expand the compare or test insn that
13473 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13475 (define_expand "beq"
13477 (if_then_else (match_dup 1)
13478 (label_ref (match_operand 0 "" ""))
13481 "ix86_expand_branch (EQ, operands[0]); DONE;")
13483 (define_expand "bne"
13485 (if_then_else (match_dup 1)
13486 (label_ref (match_operand 0 "" ""))
13489 "ix86_expand_branch (NE, operands[0]); DONE;")
13491 (define_expand "bgt"
13493 (if_then_else (match_dup 1)
13494 (label_ref (match_operand 0 "" ""))
13497 "ix86_expand_branch (GT, operands[0]); DONE;")
13499 (define_expand "bgtu"
13501 (if_then_else (match_dup 1)
13502 (label_ref (match_operand 0 "" ""))
13505 "ix86_expand_branch (GTU, operands[0]); DONE;")
13507 (define_expand "blt"
13509 (if_then_else (match_dup 1)
13510 (label_ref (match_operand 0 "" ""))
13513 "ix86_expand_branch (LT, operands[0]); DONE;")
13515 (define_expand "bltu"
13517 (if_then_else (match_dup 1)
13518 (label_ref (match_operand 0 "" ""))
13521 "ix86_expand_branch (LTU, operands[0]); DONE;")
13523 (define_expand "bge"
13525 (if_then_else (match_dup 1)
13526 (label_ref (match_operand 0 "" ""))
13529 "ix86_expand_branch (GE, operands[0]); DONE;")
13531 (define_expand "bgeu"
13533 (if_then_else (match_dup 1)
13534 (label_ref (match_operand 0 "" ""))
13537 "ix86_expand_branch (GEU, operands[0]); DONE;")
13539 (define_expand "ble"
13541 (if_then_else (match_dup 1)
13542 (label_ref (match_operand 0 "" ""))
13545 "ix86_expand_branch (LE, operands[0]); DONE;")
13547 (define_expand "bleu"
13549 (if_then_else (match_dup 1)
13550 (label_ref (match_operand 0 "" ""))
13553 "ix86_expand_branch (LEU, operands[0]); DONE;")
13555 (define_expand "bunordered"
13557 (if_then_else (match_dup 1)
13558 (label_ref (match_operand 0 "" ""))
13560 "TARGET_80387 || TARGET_SSE_MATH"
13561 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13563 (define_expand "bordered"
13565 (if_then_else (match_dup 1)
13566 (label_ref (match_operand 0 "" ""))
13568 "TARGET_80387 || TARGET_SSE_MATH"
13569 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13571 (define_expand "buneq"
13573 (if_then_else (match_dup 1)
13574 (label_ref (match_operand 0 "" ""))
13576 "TARGET_80387 || TARGET_SSE_MATH"
13577 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13579 (define_expand "bunge"
13581 (if_then_else (match_dup 1)
13582 (label_ref (match_operand 0 "" ""))
13584 "TARGET_80387 || TARGET_SSE_MATH"
13585 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13587 (define_expand "bungt"
13589 (if_then_else (match_dup 1)
13590 (label_ref (match_operand 0 "" ""))
13592 "TARGET_80387 || TARGET_SSE_MATH"
13593 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13595 (define_expand "bunle"
13597 (if_then_else (match_dup 1)
13598 (label_ref (match_operand 0 "" ""))
13600 "TARGET_80387 || TARGET_SSE_MATH"
13601 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13603 (define_expand "bunlt"
13605 (if_then_else (match_dup 1)
13606 (label_ref (match_operand 0 "" ""))
13608 "TARGET_80387 || TARGET_SSE_MATH"
13609 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13611 (define_expand "bltgt"
13613 (if_then_else (match_dup 1)
13614 (label_ref (match_operand 0 "" ""))
13616 "TARGET_80387 || TARGET_SSE_MATH"
13617 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13619 (define_insn "*jcc_1"
13621 (if_then_else (match_operator 1 "ix86_comparison_operator"
13622 [(reg FLAGS_REG) (const_int 0)])
13623 (label_ref (match_operand 0 "" ""))
13627 [(set_attr "type" "ibr")
13628 (set_attr "modrm" "0")
13629 (set (attr "length")
13630 (if_then_else (and (ge (minus (match_dup 0) (pc))
13632 (lt (minus (match_dup 0) (pc))
13637 (define_insn "*jcc_2"
13639 (if_then_else (match_operator 1 "ix86_comparison_operator"
13640 [(reg FLAGS_REG) (const_int 0)])
13642 (label_ref (match_operand 0 "" ""))))]
13645 [(set_attr "type" "ibr")
13646 (set_attr "modrm" "0")
13647 (set (attr "length")
13648 (if_then_else (and (ge (minus (match_dup 0) (pc))
13650 (lt (minus (match_dup 0) (pc))
13655 ;; In general it is not safe to assume too much about CCmode registers,
13656 ;; so simplify-rtx stops when it sees a second one. Under certain
13657 ;; conditions this is safe on x86, so help combine not create
13665 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13666 [(reg FLAGS_REG) (const_int 0)])
13668 (label_ref (match_operand 1 "" ""))
13672 (if_then_else (match_dup 0)
13673 (label_ref (match_dup 1))
13676 PUT_MODE (operands[0], VOIDmode);
13681 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13682 [(reg FLAGS_REG) (const_int 0)])
13684 (label_ref (match_operand 1 "" ""))
13688 (if_then_else (match_dup 0)
13689 (label_ref (match_dup 1))
13692 rtx new_op0 = copy_rtx (operands[0]);
13693 operands[0] = new_op0;
13694 PUT_MODE (new_op0, VOIDmode);
13695 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13696 GET_MODE (XEXP (new_op0, 0))));
13698 /* Make sure that (a) the CCmode we have for the flags is strong
13699 enough for the reversed compare or (b) we have a valid FP compare. */
13700 if (! ix86_comparison_operator (new_op0, VOIDmode))
13704 ;; Define combination compare-and-branch fp compare instructions to use
13705 ;; during early optimization. Splitting the operation apart early makes
13706 ;; for bad code when we want to reverse the operation.
13708 (define_insn "*fp_jcc_1_mixed"
13710 (if_then_else (match_operator 0 "comparison_operator"
13711 [(match_operand 1 "register_operand" "f,x")
13712 (match_operand 2 "nonimmediate_operand" "f,xm")])
13713 (label_ref (match_operand 3 "" ""))
13715 (clobber (reg:CCFP FPSR_REG))
13716 (clobber (reg:CCFP FLAGS_REG))]
13717 "TARGET_MIX_SSE_I387
13718 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13719 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13720 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13723 (define_insn "*fp_jcc_1_sse"
13725 (if_then_else (match_operator 0 "comparison_operator"
13726 [(match_operand 1 "register_operand" "x")
13727 (match_operand 2 "nonimmediate_operand" "xm")])
13728 (label_ref (match_operand 3 "" ""))
13730 (clobber (reg:CCFP FPSR_REG))
13731 (clobber (reg:CCFP FLAGS_REG))]
13733 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13734 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13735 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13738 (define_insn "*fp_jcc_1_387"
13740 (if_then_else (match_operator 0 "comparison_operator"
13741 [(match_operand 1 "register_operand" "f")
13742 (match_operand 2 "register_operand" "f")])
13743 (label_ref (match_operand 3 "" ""))
13745 (clobber (reg:CCFP FPSR_REG))
13746 (clobber (reg:CCFP FLAGS_REG))]
13747 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13749 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13750 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13753 (define_insn "*fp_jcc_2_mixed"
13755 (if_then_else (match_operator 0 "comparison_operator"
13756 [(match_operand 1 "register_operand" "f,x")
13757 (match_operand 2 "nonimmediate_operand" "f,xm")])
13759 (label_ref (match_operand 3 "" ""))))
13760 (clobber (reg:CCFP FPSR_REG))
13761 (clobber (reg:CCFP FLAGS_REG))]
13762 "TARGET_MIX_SSE_I387
13763 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13764 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13765 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13768 (define_insn "*fp_jcc_2_sse"
13770 (if_then_else (match_operator 0 "comparison_operator"
13771 [(match_operand 1 "register_operand" "x")
13772 (match_operand 2 "nonimmediate_operand" "xm")])
13774 (label_ref (match_operand 3 "" ""))))
13775 (clobber (reg:CCFP FPSR_REG))
13776 (clobber (reg:CCFP FLAGS_REG))]
13778 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13779 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13780 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13783 (define_insn "*fp_jcc_2_387"
13785 (if_then_else (match_operator 0 "comparison_operator"
13786 [(match_operand 1 "register_operand" "f")
13787 (match_operand 2 "register_operand" "f")])
13789 (label_ref (match_operand 3 "" ""))))
13790 (clobber (reg:CCFP FPSR_REG))
13791 (clobber (reg:CCFP FLAGS_REG))]
13792 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13794 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13795 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13798 (define_insn "*fp_jcc_3_387"
13800 (if_then_else (match_operator 0 "comparison_operator"
13801 [(match_operand 1 "register_operand" "f")
13802 (match_operand 2 "nonimmediate_operand" "fm")])
13803 (label_ref (match_operand 3 "" ""))
13805 (clobber (reg:CCFP FPSR_REG))
13806 (clobber (reg:CCFP FLAGS_REG))
13807 (clobber (match_scratch:HI 4 "=a"))]
13809 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13810 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13811 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13812 && SELECT_CC_MODE (GET_CODE (operands[0]),
13813 operands[1], operands[2]) == CCFPmode
13814 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13817 (define_insn "*fp_jcc_4_387"
13819 (if_then_else (match_operator 0 "comparison_operator"
13820 [(match_operand 1 "register_operand" "f")
13821 (match_operand 2 "nonimmediate_operand" "fm")])
13823 (label_ref (match_operand 3 "" ""))))
13824 (clobber (reg:CCFP FPSR_REG))
13825 (clobber (reg:CCFP FLAGS_REG))
13826 (clobber (match_scratch:HI 4 "=a"))]
13828 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13829 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13830 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13831 && SELECT_CC_MODE (GET_CODE (operands[0]),
13832 operands[1], operands[2]) == CCFPmode
13833 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13836 (define_insn "*fp_jcc_5_387"
13838 (if_then_else (match_operator 0 "comparison_operator"
13839 [(match_operand 1 "register_operand" "f")
13840 (match_operand 2 "register_operand" "f")])
13841 (label_ref (match_operand 3 "" ""))
13843 (clobber (reg:CCFP FPSR_REG))
13844 (clobber (reg:CCFP FLAGS_REG))
13845 (clobber (match_scratch:HI 4 "=a"))]
13846 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13847 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13848 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13851 (define_insn "*fp_jcc_6_387"
13853 (if_then_else (match_operator 0 "comparison_operator"
13854 [(match_operand 1 "register_operand" "f")
13855 (match_operand 2 "register_operand" "f")])
13857 (label_ref (match_operand 3 "" ""))))
13858 (clobber (reg:CCFP FPSR_REG))
13859 (clobber (reg:CCFP FLAGS_REG))
13860 (clobber (match_scratch:HI 4 "=a"))]
13861 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13862 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13863 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13866 (define_insn "*fp_jcc_7_387"
13868 (if_then_else (match_operator 0 "comparison_operator"
13869 [(match_operand 1 "register_operand" "f")
13870 (match_operand 2 "const0_operand" "X")])
13871 (label_ref (match_operand 3 "" ""))
13873 (clobber (reg:CCFP FPSR_REG))
13874 (clobber (reg:CCFP FLAGS_REG))
13875 (clobber (match_scratch:HI 4 "=a"))]
13876 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13877 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13878 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13879 && SELECT_CC_MODE (GET_CODE (operands[0]),
13880 operands[1], operands[2]) == CCFPmode
13881 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13884 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13885 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13886 ;; with a precedence over other operators and is always put in the first
13887 ;; place. Swap condition and operands to match ficom instruction.
13889 (define_insn "*fp_jcc_8<mode>_387"
13891 (if_then_else (match_operator 0 "comparison_operator"
13892 [(match_operator 1 "float_operator"
13893 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13894 (match_operand 3 "register_operand" "f,f")])
13895 (label_ref (match_operand 4 "" ""))
13897 (clobber (reg:CCFP FPSR_REG))
13898 (clobber (reg:CCFP FLAGS_REG))
13899 (clobber (match_scratch:HI 5 "=a,a"))]
13900 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13901 && TARGET_USE_<MODE>MODE_FIOP
13902 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13903 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13904 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13905 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13910 (if_then_else (match_operator 0 "comparison_operator"
13911 [(match_operand 1 "register_operand" "")
13912 (match_operand 2 "nonimmediate_operand" "")])
13913 (match_operand 3 "" "")
13914 (match_operand 4 "" "")))
13915 (clobber (reg:CCFP FPSR_REG))
13916 (clobber (reg:CCFP FLAGS_REG))]
13920 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13921 operands[3], operands[4], NULL_RTX, NULL_RTX);
13927 (if_then_else (match_operator 0 "comparison_operator"
13928 [(match_operand 1 "register_operand" "")
13929 (match_operand 2 "general_operand" "")])
13930 (match_operand 3 "" "")
13931 (match_operand 4 "" "")))
13932 (clobber (reg:CCFP FPSR_REG))
13933 (clobber (reg:CCFP FLAGS_REG))
13934 (clobber (match_scratch:HI 5 "=a"))]
13938 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13939 operands[3], operands[4], operands[5], NULL_RTX);
13945 (if_then_else (match_operator 0 "comparison_operator"
13946 [(match_operator 1 "float_operator"
13947 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13948 (match_operand 3 "register_operand" "")])
13949 (match_operand 4 "" "")
13950 (match_operand 5 "" "")))
13951 (clobber (reg:CCFP FPSR_REG))
13952 (clobber (reg:CCFP FLAGS_REG))
13953 (clobber (match_scratch:HI 6 "=a"))]
13957 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13958 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13959 operands[3], operands[7],
13960 operands[4], operands[5], operands[6], NULL_RTX);
13964 ;; %%% Kill this when reload knows how to do it.
13967 (if_then_else (match_operator 0 "comparison_operator"
13968 [(match_operator 1 "float_operator"
13969 [(match_operand:X87MODEI12 2 "register_operand" "")])
13970 (match_operand 3 "register_operand" "")])
13971 (match_operand 4 "" "")
13972 (match_operand 5 "" "")))
13973 (clobber (reg:CCFP FPSR_REG))
13974 (clobber (reg:CCFP FLAGS_REG))
13975 (clobber (match_scratch:HI 6 "=a"))]
13979 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13980 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13981 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13982 operands[3], operands[7],
13983 operands[4], operands[5], operands[6], operands[2]);
13987 ;; Unconditional and other jump instructions
13989 (define_insn "jump"
13991 (label_ref (match_operand 0 "" "")))]
13994 [(set_attr "type" "ibr")
13995 (set (attr "length")
13996 (if_then_else (and (ge (minus (match_dup 0) (pc))
13998 (lt (minus (match_dup 0) (pc))
14002 (set_attr "modrm" "0")])
14004 (define_expand "indirect_jump"
14005 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14009 (define_insn "*indirect_jump"
14010 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14013 [(set_attr "type" "ibr")
14014 (set_attr "length_immediate" "0")])
14016 (define_insn "*indirect_jump_rtx64"
14017 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14020 [(set_attr "type" "ibr")
14021 (set_attr "length_immediate" "0")])
14023 (define_expand "tablejump"
14024 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14025 (use (label_ref (match_operand 1 "" "")))])]
14028 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14029 relative. Convert the relative address to an absolute address. */
14033 enum rtx_code code;
14035 /* We can't use @GOTOFF for text labels on VxWorks;
14036 see gotoff_operand. */
14037 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14041 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14043 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14047 op1 = pic_offset_table_rtx;
14052 op0 = pic_offset_table_rtx;
14056 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14061 (define_insn "*tablejump_1"
14062 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14063 (use (label_ref (match_operand 1 "" "")))]
14066 [(set_attr "type" "ibr")
14067 (set_attr "length_immediate" "0")])
14069 (define_insn "*tablejump_1_rtx64"
14070 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14071 (use (label_ref (match_operand 1 "" "")))]
14074 [(set_attr "type" "ibr")
14075 (set_attr "length_immediate" "0")])
14077 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14080 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14081 (set (match_operand:QI 1 "register_operand" "")
14082 (match_operator:QI 2 "ix86_comparison_operator"
14083 [(reg FLAGS_REG) (const_int 0)]))
14084 (set (match_operand 3 "q_regs_operand" "")
14085 (zero_extend (match_dup 1)))]
14086 "(peep2_reg_dead_p (3, operands[1])
14087 || operands_match_p (operands[1], operands[3]))
14088 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14089 [(set (match_dup 4) (match_dup 0))
14090 (set (strict_low_part (match_dup 5))
14093 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14094 operands[5] = gen_lowpart (QImode, operands[3]);
14095 ix86_expand_clear (operands[3]);
14098 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14101 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14102 (set (match_operand:QI 1 "register_operand" "")
14103 (match_operator:QI 2 "ix86_comparison_operator"
14104 [(reg FLAGS_REG) (const_int 0)]))
14105 (parallel [(set (match_operand 3 "q_regs_operand" "")
14106 (zero_extend (match_dup 1)))
14107 (clobber (reg:CC FLAGS_REG))])]
14108 "(peep2_reg_dead_p (3, operands[1])
14109 || operands_match_p (operands[1], operands[3]))
14110 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14111 [(set (match_dup 4) (match_dup 0))
14112 (set (strict_low_part (match_dup 5))
14115 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14116 operands[5] = gen_lowpart (QImode, operands[3]);
14117 ix86_expand_clear (operands[3]);
14120 ;; Call instructions.
14122 ;; The predicates normally associated with named expanders are not properly
14123 ;; checked for calls. This is a bug in the generic code, but it isn't that
14124 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14126 ;; Call subroutine returning no value.
14128 (define_expand "call_pop"
14129 [(parallel [(call (match_operand:QI 0 "" "")
14130 (match_operand:SI 1 "" ""))
14131 (set (reg:SI SP_REG)
14132 (plus:SI (reg:SI SP_REG)
14133 (match_operand:SI 3 "" "")))])]
14136 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14140 (define_insn "*call_pop_0"
14141 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14142 (match_operand:SI 1 "" ""))
14143 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14144 (match_operand:SI 2 "immediate_operand" "")))]
14147 if (SIBLING_CALL_P (insn))
14150 return "call\t%P0";
14152 [(set_attr "type" "call")])
14154 (define_insn "*call_pop_1"
14155 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14156 (match_operand:SI 1 "" ""))
14157 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14158 (match_operand:SI 2 "immediate_operand" "i")))]
14161 if (constant_call_address_operand (operands[0], Pmode))
14163 if (SIBLING_CALL_P (insn))
14166 return "call\t%P0";
14168 if (SIBLING_CALL_P (insn))
14171 return "call\t%A0";
14173 [(set_attr "type" "call")])
14175 (define_expand "call"
14176 [(call (match_operand:QI 0 "" "")
14177 (match_operand 1 "" ""))
14178 (use (match_operand 2 "" ""))]
14181 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14185 (define_expand "sibcall"
14186 [(call (match_operand:QI 0 "" "")
14187 (match_operand 1 "" ""))
14188 (use (match_operand 2 "" ""))]
14191 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14195 (define_insn "*call_0"
14196 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14197 (match_operand 1 "" ""))]
14200 if (SIBLING_CALL_P (insn))
14203 return "call\t%P0";
14205 [(set_attr "type" "call")])
14207 (define_insn "*call_1"
14208 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14209 (match_operand 1 "" ""))]
14210 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14212 if (constant_call_address_operand (operands[0], Pmode))
14213 return "call\t%P0";
14214 return "call\t%A0";
14216 [(set_attr "type" "call")])
14218 (define_insn "*sibcall_1"
14219 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14220 (match_operand 1 "" ""))]
14221 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14223 if (constant_call_address_operand (operands[0], Pmode))
14227 [(set_attr "type" "call")])
14229 (define_insn "*call_1_rex64"
14230 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14231 (match_operand 1 "" ""))]
14232 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14233 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14235 if (constant_call_address_operand (operands[0], Pmode))
14236 return "call\t%P0";
14237 return "call\t%A0";
14239 [(set_attr "type" "call")])
14241 (define_insn "*call_1_rex64_large"
14242 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14243 (match_operand 1 "" ""))]
14244 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14246 [(set_attr "type" "call")])
14248 (define_insn "*sibcall_1_rex64"
14249 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14250 (match_operand 1 "" ""))]
14251 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14253 [(set_attr "type" "call")])
14255 (define_insn "*sibcall_1_rex64_v"
14256 [(call (mem:QI (reg:DI R11_REG))
14257 (match_operand 0 "" ""))]
14258 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14260 [(set_attr "type" "call")])
14263 ;; Call subroutine, returning value in operand 0
14265 (define_expand "call_value_pop"
14266 [(parallel [(set (match_operand 0 "" "")
14267 (call (match_operand:QI 1 "" "")
14268 (match_operand:SI 2 "" "")))
14269 (set (reg:SI SP_REG)
14270 (plus:SI (reg:SI SP_REG)
14271 (match_operand:SI 4 "" "")))])]
14274 ix86_expand_call (operands[0], operands[1], operands[2],
14275 operands[3], operands[4], 0);
14279 (define_expand "call_value"
14280 [(set (match_operand 0 "" "")
14281 (call (match_operand:QI 1 "" "")
14282 (match_operand:SI 2 "" "")))
14283 (use (match_operand:SI 3 "" ""))]
14284 ;; Operand 2 not used on the i386.
14287 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14291 (define_expand "sibcall_value"
14292 [(set (match_operand 0 "" "")
14293 (call (match_operand:QI 1 "" "")
14294 (match_operand:SI 2 "" "")))
14295 (use (match_operand:SI 3 "" ""))]
14296 ;; Operand 2 not used on the i386.
14299 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14303 ;; Call subroutine returning any type.
14305 (define_expand "untyped_call"
14306 [(parallel [(call (match_operand 0 "" "")
14308 (match_operand 1 "" "")
14309 (match_operand 2 "" "")])]
14314 /* In order to give reg-stack an easier job in validating two
14315 coprocessor registers as containing a possible return value,
14316 simply pretend the untyped call returns a complex long double
14319 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14320 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14321 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14324 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14326 rtx set = XVECEXP (operands[2], 0, i);
14327 emit_move_insn (SET_DEST (set), SET_SRC (set));
14330 /* The optimizer does not know that the call sets the function value
14331 registers we stored in the result block. We avoid problems by
14332 claiming that all hard registers are used and clobbered at this
14334 emit_insn (gen_blockage (const0_rtx));
14339 ;; Prologue and epilogue instructions
14341 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14342 ;; all of memory. This blocks insns from being moved across this point.
14344 (define_insn "blockage"
14345 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14348 [(set_attr "length" "0")])
14350 ;; Insn emitted into the body of a function to return from a function.
14351 ;; This is only done if the function's epilogue is known to be simple.
14352 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14354 (define_expand "return"
14356 "ix86_can_use_return_insn_p ()"
14358 if (current_function_pops_args)
14360 rtx popc = GEN_INT (current_function_pops_args);
14361 emit_jump_insn (gen_return_pop_internal (popc));
14366 (define_insn "return_internal"
14370 [(set_attr "length" "1")
14371 (set_attr "length_immediate" "0")
14372 (set_attr "modrm" "0")])
14374 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14375 ;; instruction Athlon and K8 have.
14377 (define_insn "return_internal_long"
14379 (unspec [(const_int 0)] UNSPEC_REP)]
14382 [(set_attr "length" "1")
14383 (set_attr "length_immediate" "0")
14384 (set_attr "prefix_rep" "1")
14385 (set_attr "modrm" "0")])
14387 (define_insn "return_pop_internal"
14389 (use (match_operand:SI 0 "const_int_operand" ""))]
14392 [(set_attr "length" "3")
14393 (set_attr "length_immediate" "2")
14394 (set_attr "modrm" "0")])
14396 (define_insn "return_indirect_internal"
14398 (use (match_operand:SI 0 "register_operand" "r"))]
14401 [(set_attr "type" "ibr")
14402 (set_attr "length_immediate" "0")])
14408 [(set_attr "length" "1")
14409 (set_attr "length_immediate" "0")
14410 (set_attr "modrm" "0")])
14412 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14413 ;; branch prediction penalty for the third jump in a 16-byte
14416 (define_insn "align"
14417 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14420 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14421 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14423 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14424 The align insn is used to avoid 3 jump instructions in the row to improve
14425 branch prediction and the benefits hardly outweigh the cost of extra 8
14426 nops on the average inserted by full alignment pseudo operation. */
14430 [(set_attr "length" "16")])
14432 (define_expand "prologue"
14435 "ix86_expand_prologue (); DONE;")
14437 (define_insn "set_got"
14438 [(set (match_operand:SI 0 "register_operand" "=r")
14439 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14440 (clobber (reg:CC FLAGS_REG))]
14442 { return output_set_got (operands[0], NULL_RTX); }
14443 [(set_attr "type" "multi")
14444 (set_attr "length" "12")])
14446 (define_insn "set_got_labelled"
14447 [(set (match_operand:SI 0 "register_operand" "=r")
14448 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14450 (clobber (reg:CC FLAGS_REG))]
14452 { return output_set_got (operands[0], operands[1]); }
14453 [(set_attr "type" "multi")
14454 (set_attr "length" "12")])
14456 (define_insn "set_got_rex64"
14457 [(set (match_operand:DI 0 "register_operand" "=r")
14458 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14460 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14461 [(set_attr "type" "lea")
14462 (set_attr "length" "6")])
14464 (define_insn "set_rip_rex64"
14465 [(set (match_operand:DI 0 "register_operand" "=r")
14466 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14468 "lea{q}\t%l1(%%rip), %0"
14469 [(set_attr "type" "lea")
14470 (set_attr "length" "6")])
14472 (define_insn "set_got_offset_rex64"
14473 [(set (match_operand:DI 0 "register_operand" "=r")
14474 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14476 "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14477 [(set_attr "type" "imov")
14478 (set_attr "length" "11")])
14480 (define_expand "epilogue"
14483 "ix86_expand_epilogue (1); DONE;")
14485 (define_expand "sibcall_epilogue"
14488 "ix86_expand_epilogue (0); DONE;")
14490 (define_expand "eh_return"
14491 [(use (match_operand 0 "register_operand" ""))]
14494 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14496 /* Tricky bit: we write the address of the handler to which we will
14497 be returning into someone else's stack frame, one word below the
14498 stack address we wish to restore. */
14499 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14500 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14501 tmp = gen_rtx_MEM (Pmode, tmp);
14502 emit_move_insn (tmp, ra);
14504 if (Pmode == SImode)
14505 emit_jump_insn (gen_eh_return_si (sa));
14507 emit_jump_insn (gen_eh_return_di (sa));
14512 (define_insn_and_split "eh_return_si"
14514 (unspec [(match_operand:SI 0 "register_operand" "c")]
14515 UNSPEC_EH_RETURN))]
14520 "ix86_expand_epilogue (2); DONE;")
14522 (define_insn_and_split "eh_return_di"
14524 (unspec [(match_operand:DI 0 "register_operand" "c")]
14525 UNSPEC_EH_RETURN))]
14530 "ix86_expand_epilogue (2); DONE;")
14532 (define_insn "leave"
14533 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14534 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14535 (clobber (mem:BLK (scratch)))]
14538 [(set_attr "type" "leave")])
14540 (define_insn "leave_rex64"
14541 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14542 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14543 (clobber (mem:BLK (scratch)))]
14546 [(set_attr "type" "leave")])
14548 (define_expand "ffssi2"
14550 [(set (match_operand:SI 0 "register_operand" "")
14551 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14552 (clobber (match_scratch:SI 2 ""))
14553 (clobber (reg:CC FLAGS_REG))])]
14557 (define_insn_and_split "*ffs_cmove"
14558 [(set (match_operand:SI 0 "register_operand" "=r")
14559 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14560 (clobber (match_scratch:SI 2 "=&r"))
14561 (clobber (reg:CC FLAGS_REG))]
14564 "&& reload_completed"
14565 [(set (match_dup 2) (const_int -1))
14566 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14567 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14568 (set (match_dup 0) (if_then_else:SI
14569 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14572 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14573 (clobber (reg:CC FLAGS_REG))])]
14576 (define_insn_and_split "*ffs_no_cmove"
14577 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14578 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14579 (clobber (match_scratch:SI 2 "=&q"))
14580 (clobber (reg:CC FLAGS_REG))]
14584 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14585 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14586 (set (strict_low_part (match_dup 3))
14587 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14588 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14589 (clobber (reg:CC FLAGS_REG))])
14590 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14591 (clobber (reg:CC FLAGS_REG))])
14592 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14593 (clobber (reg:CC FLAGS_REG))])]
14595 operands[3] = gen_lowpart (QImode, operands[2]);
14596 ix86_expand_clear (operands[2]);
14599 (define_insn "*ffssi_1"
14600 [(set (reg:CCZ FLAGS_REG)
14601 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14603 (set (match_operand:SI 0 "register_operand" "=r")
14604 (ctz:SI (match_dup 1)))]
14606 "bsf{l}\t{%1, %0|%0, %1}"
14607 [(set_attr "prefix_0f" "1")])
14609 (define_expand "ffsdi2"
14611 [(set (match_operand:DI 0 "register_operand" "")
14612 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14613 (clobber (match_scratch:DI 2 ""))
14614 (clobber (reg:CC FLAGS_REG))])]
14615 "TARGET_64BIT && TARGET_CMOVE"
14618 (define_insn_and_split "*ffs_rex64"
14619 [(set (match_operand:DI 0 "register_operand" "=r")
14620 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14621 (clobber (match_scratch:DI 2 "=&r"))
14622 (clobber (reg:CC FLAGS_REG))]
14623 "TARGET_64BIT && TARGET_CMOVE"
14625 "&& reload_completed"
14626 [(set (match_dup 2) (const_int -1))
14627 (parallel [(set (reg:CCZ FLAGS_REG)
14628 (compare:CCZ (match_dup 1) (const_int 0)))
14629 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14630 (set (match_dup 0) (if_then_else:DI
14631 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14634 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14635 (clobber (reg:CC FLAGS_REG))])]
14638 (define_insn "*ffsdi_1"
14639 [(set (reg:CCZ FLAGS_REG)
14640 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14642 (set (match_operand:DI 0 "register_operand" "=r")
14643 (ctz:DI (match_dup 1)))]
14645 "bsf{q}\t{%1, %0|%0, %1}"
14646 [(set_attr "prefix_0f" "1")])
14648 (define_insn "ctzsi2"
14649 [(set (match_operand:SI 0 "register_operand" "=r")
14650 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14651 (clobber (reg:CC FLAGS_REG))]
14653 "bsf{l}\t{%1, %0|%0, %1}"
14654 [(set_attr "prefix_0f" "1")])
14656 (define_insn "ctzdi2"
14657 [(set (match_operand:DI 0 "register_operand" "=r")
14658 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14659 (clobber (reg:CC FLAGS_REG))]
14661 "bsf{q}\t{%1, %0|%0, %1}"
14662 [(set_attr "prefix_0f" "1")])
14664 (define_expand "clzsi2"
14666 [(set (match_operand:SI 0 "register_operand" "")
14667 (minus:SI (const_int 31)
14668 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14669 (clobber (reg:CC FLAGS_REG))])
14671 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14672 (clobber (reg:CC FLAGS_REG))])]
14677 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14682 (define_insn "clzsi2_abm"
14683 [(set (match_operand:SI 0 "register_operand" "=r")
14684 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14685 (clobber (reg:CC FLAGS_REG))]
14687 "lzcnt{l}\t{%1, %0|%0, %1}"
14688 [(set_attr "prefix_rep" "1")
14689 (set_attr "type" "bitmanip")
14690 (set_attr "mode" "SI")])
14692 (define_insn "*bsr"
14693 [(set (match_operand:SI 0 "register_operand" "=r")
14694 (minus:SI (const_int 31)
14695 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14696 (clobber (reg:CC FLAGS_REG))]
14698 "bsr{l}\t{%1, %0|%0, %1}"
14699 [(set_attr "prefix_0f" "1")
14700 (set_attr "mode" "SI")])
14702 (define_insn "popcountsi2"
14703 [(set (match_operand:SI 0 "register_operand" "=r")
14704 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14705 (clobber (reg:CC FLAGS_REG))]
14707 "popcnt{l}\t{%1, %0|%0, %1}"
14708 [(set_attr "prefix_rep" "1")
14709 (set_attr "type" "bitmanip")
14710 (set_attr "mode" "SI")])
14712 (define_insn "*popcountsi2_cmp"
14713 [(set (reg FLAGS_REG)
14715 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14717 (set (match_operand:SI 0 "register_operand" "=r")
14718 (popcount:SI (match_dup 1)))]
14719 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14720 "popcnt{l}\t{%1, %0|%0, %1}"
14721 [(set_attr "prefix_rep" "1")
14722 (set_attr "type" "bitmanip")
14723 (set_attr "mode" "SI")])
14725 (define_insn "*popcountsi2_cmp_zext"
14726 [(set (reg FLAGS_REG)
14728 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14730 (set (match_operand:DI 0 "register_operand" "=r")
14731 (zero_extend:DI(popcount:SI (match_dup 1))))]
14732 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14733 "popcnt{l}\t{%1, %0|%0, %1}"
14734 [(set_attr "prefix_rep" "1")
14735 (set_attr "type" "bitmanip")
14736 (set_attr "mode" "SI")])
14738 (define_expand "bswapsi2"
14739 [(set (match_operand:SI 0 "register_operand" "")
14740 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14745 rtx x = operands[0];
14747 emit_move_insn (x, operands[1]);
14748 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14749 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14750 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14755 (define_insn "*bswapsi_1"
14756 [(set (match_operand:SI 0 "register_operand" "=r")
14757 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14760 [(set_attr "prefix_0f" "1")
14761 (set_attr "length" "2")])
14763 (define_insn "*bswaphi_lowpart_1"
14764 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14765 (bswap:HI (match_dup 0)))
14766 (clobber (reg:CC FLAGS_REG))]
14767 "TARGET_USE_XCHGB || optimize_size"
14769 xchg{b}\t{%h0, %b0|%b0, %h0}
14770 rol{w}\t{$8, %0|%0, 8}"
14771 [(set_attr "length" "2,4")
14772 (set_attr "mode" "QI,HI")])
14774 (define_insn "bswaphi_lowpart"
14775 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14776 (bswap:HI (match_dup 0)))
14777 (clobber (reg:CC FLAGS_REG))]
14779 "rol{w}\t{$8, %0|%0, 8}"
14780 [(set_attr "length" "4")
14781 (set_attr "mode" "HI")])
14783 (define_insn "bswapdi2"
14784 [(set (match_operand:DI 0 "register_operand" "=r")
14785 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14788 [(set_attr "prefix_0f" "1")
14789 (set_attr "length" "3")])
14791 (define_expand "clzdi2"
14793 [(set (match_operand:DI 0 "register_operand" "")
14794 (minus:DI (const_int 63)
14795 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14796 (clobber (reg:CC FLAGS_REG))])
14798 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14799 (clobber (reg:CC FLAGS_REG))])]
14804 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14809 (define_insn "clzdi2_abm"
14810 [(set (match_operand:DI 0 "register_operand" "=r")
14811 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14812 (clobber (reg:CC FLAGS_REG))]
14813 "TARGET_64BIT && TARGET_ABM"
14814 "lzcnt{q}\t{%1, %0|%0, %1}"
14815 [(set_attr "prefix_rep" "1")
14816 (set_attr "type" "bitmanip")
14817 (set_attr "mode" "DI")])
14819 (define_insn "*bsr_rex64"
14820 [(set (match_operand:DI 0 "register_operand" "=r")
14821 (minus:DI (const_int 63)
14822 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14823 (clobber (reg:CC FLAGS_REG))]
14825 "bsr{q}\t{%1, %0|%0, %1}"
14826 [(set_attr "prefix_0f" "1")
14827 (set_attr "mode" "DI")])
14829 (define_insn "popcountdi2"
14830 [(set (match_operand:DI 0 "register_operand" "=r")
14831 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14832 (clobber (reg:CC FLAGS_REG))]
14833 "TARGET_64BIT && TARGET_POPCNT"
14834 "popcnt{q}\t{%1, %0|%0, %1}"
14835 [(set_attr "prefix_rep" "1")
14836 (set_attr "type" "bitmanip")
14837 (set_attr "mode" "DI")])
14839 (define_insn "*popcountdi2_cmp"
14840 [(set (reg FLAGS_REG)
14842 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14844 (set (match_operand:DI 0 "register_operand" "=r")
14845 (popcount:DI (match_dup 1)))]
14846 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14847 "popcnt{q}\t{%1, %0|%0, %1}"
14848 [(set_attr "prefix_rep" "1")
14849 (set_attr "type" "bitmanip")
14850 (set_attr "mode" "DI")])
14852 (define_expand "clzhi2"
14854 [(set (match_operand:HI 0 "register_operand" "")
14855 (minus:HI (const_int 15)
14856 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14857 (clobber (reg:CC FLAGS_REG))])
14859 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14860 (clobber (reg:CC FLAGS_REG))])]
14865 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14870 (define_insn "clzhi2_abm"
14871 [(set (match_operand:HI 0 "register_operand" "=r")
14872 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14873 (clobber (reg:CC FLAGS_REG))]
14875 "lzcnt{w}\t{%1, %0|%0, %1}"
14876 [(set_attr "prefix_rep" "1")
14877 (set_attr "type" "bitmanip")
14878 (set_attr "mode" "HI")])
14880 (define_insn "*bsrhi"
14881 [(set (match_operand:HI 0 "register_operand" "=r")
14882 (minus:HI (const_int 15)
14883 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14884 (clobber (reg:CC FLAGS_REG))]
14886 "bsr{w}\t{%1, %0|%0, %1}"
14887 [(set_attr "prefix_0f" "1")
14888 (set_attr "mode" "HI")])
14890 (define_insn "popcounthi2"
14891 [(set (match_operand:HI 0 "register_operand" "=r")
14892 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14893 (clobber (reg:CC FLAGS_REG))]
14895 "popcnt{w}\t{%1, %0|%0, %1}"
14896 [(set_attr "prefix_rep" "1")
14897 (set_attr "type" "bitmanip")
14898 (set_attr "mode" "HI")])
14900 (define_insn "*popcounthi2_cmp"
14901 [(set (reg FLAGS_REG)
14903 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14905 (set (match_operand:HI 0 "register_operand" "=r")
14906 (popcount:HI (match_dup 1)))]
14907 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14908 "popcnt{w}\t{%1, %0|%0, %1}"
14909 [(set_attr "prefix_rep" "1")
14910 (set_attr "type" "bitmanip")
14911 (set_attr "mode" "HI")])
14913 (define_expand "paritydi2"
14914 [(set (match_operand:DI 0 "register_operand" "")
14915 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
14918 rtx scratch = gen_reg_rtx (QImode);
14921 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14922 NULL_RTX, operands[1]));
14924 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14925 gen_rtx_REG (CCmode, FLAGS_REG),
14927 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14930 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14933 rtx tmp = gen_reg_rtx (SImode);
14935 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14936 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14941 (define_insn_and_split "paritydi2_cmp"
14942 [(set (reg:CC FLAGS_REG)
14943 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
14944 (clobber (match_scratch:DI 0 "=r,X"))
14945 (clobber (match_scratch:SI 1 "=r,r"))
14946 (clobber (match_scratch:HI 2 "=Q,Q"))]
14949 "&& reload_completed"
14951 [(set (match_dup 1)
14952 (xor:SI (match_dup 1) (match_dup 4)))
14953 (clobber (reg:CC FLAGS_REG))])
14955 [(set (reg:CC FLAGS_REG)
14956 (parity:CC (match_dup 1)))
14957 (clobber (match_dup 1))
14958 (clobber (match_dup 2))])]
14960 operands[4] = gen_lowpart (SImode, operands[3]);
14962 if (MEM_P (operands[3]))
14963 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
14964 else if (! TARGET_64BIT)
14965 operands[1] = gen_highpart (SImode, operands[3]);
14968 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14969 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14973 (define_expand "paritysi2"
14974 [(set (match_operand:SI 0 "register_operand" "")
14975 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
14978 rtx scratch = gen_reg_rtx (QImode);
14981 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14983 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14984 gen_rtx_REG (CCmode, FLAGS_REG),
14986 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14988 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14992 (define_insn_and_split "paritysi2_cmp"
14993 [(set (reg:CC FLAGS_REG)
14994 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
14995 (clobber (match_scratch:SI 0 "=r,X"))
14996 (clobber (match_scratch:HI 1 "=Q,Q"))]
14999 "&& reload_completed"
15001 [(set (match_dup 1)
15002 (xor:HI (match_dup 1) (match_dup 3)))
15003 (clobber (reg:CC FLAGS_REG))])
15005 [(set (reg:CC FLAGS_REG)
15006 (parity:CC (match_dup 1)))
15007 (clobber (match_dup 1))])]
15009 operands[3] = gen_lowpart (HImode, operands[2]);
15011 if (MEM_P (operands[2]))
15012 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15015 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15016 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15020 (define_insn "*parityhi2_cmp"
15021 [(set (reg:CC FLAGS_REG)
15022 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15023 (clobber (match_scratch:HI 0 "=Q"))]
15025 "xor{b}\t{%h0, %b0|%b0, %h0}"
15026 [(set_attr "length" "2")
15027 (set_attr "mode" "HI")])
15029 (define_insn "*parityqi2_cmp"
15030 [(set (reg:CC FLAGS_REG)
15031 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15034 [(set_attr "length" "2")
15035 (set_attr "mode" "QI")])
15037 ;; Thread-local storage patterns for ELF.
15039 ;; Note that these code sequences must appear exactly as shown
15040 ;; in order to allow linker relaxation.
15042 (define_insn "*tls_global_dynamic_32_gnu"
15043 [(set (match_operand:SI 0 "register_operand" "=a")
15044 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15045 (match_operand:SI 2 "tls_symbolic_operand" "")
15046 (match_operand:SI 3 "call_insn_operand" "")]
15048 (clobber (match_scratch:SI 4 "=d"))
15049 (clobber (match_scratch:SI 5 "=c"))
15050 (clobber (reg:CC FLAGS_REG))]
15051 "!TARGET_64BIT && TARGET_GNU_TLS"
15052 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15053 [(set_attr "type" "multi")
15054 (set_attr "length" "12")])
15056 (define_insn "*tls_global_dynamic_32_sun"
15057 [(set (match_operand:SI 0 "register_operand" "=a")
15058 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15059 (match_operand:SI 2 "tls_symbolic_operand" "")
15060 (match_operand:SI 3 "call_insn_operand" "")]
15062 (clobber (match_scratch:SI 4 "=d"))
15063 (clobber (match_scratch:SI 5 "=c"))
15064 (clobber (reg:CC FLAGS_REG))]
15065 "!TARGET_64BIT && TARGET_SUN_TLS"
15066 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15067 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15068 [(set_attr "type" "multi")
15069 (set_attr "length" "14")])
15071 (define_expand "tls_global_dynamic_32"
15072 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15075 (match_operand:SI 1 "tls_symbolic_operand" "")
15078 (clobber (match_scratch:SI 4 ""))
15079 (clobber (match_scratch:SI 5 ""))
15080 (clobber (reg:CC FLAGS_REG))])]
15084 operands[2] = pic_offset_table_rtx;
15087 operands[2] = gen_reg_rtx (Pmode);
15088 emit_insn (gen_set_got (operands[2]));
15090 if (TARGET_GNU2_TLS)
15092 emit_insn (gen_tls_dynamic_gnu2_32
15093 (operands[0], operands[1], operands[2]));
15096 operands[3] = ix86_tls_get_addr ();
15099 (define_insn "*tls_global_dynamic_64"
15100 [(set (match_operand:DI 0 "register_operand" "=a")
15101 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15102 (match_operand:DI 3 "" "")))
15103 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15106 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15107 [(set_attr "type" "multi")
15108 (set_attr "length" "16")])
15110 (define_expand "tls_global_dynamic_64"
15111 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15112 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15113 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15117 if (TARGET_GNU2_TLS)
15119 emit_insn (gen_tls_dynamic_gnu2_64
15120 (operands[0], operands[1]));
15123 operands[2] = ix86_tls_get_addr ();
15126 (define_insn "*tls_local_dynamic_base_32_gnu"
15127 [(set (match_operand:SI 0 "register_operand" "=a")
15128 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15129 (match_operand:SI 2 "call_insn_operand" "")]
15130 UNSPEC_TLS_LD_BASE))
15131 (clobber (match_scratch:SI 3 "=d"))
15132 (clobber (match_scratch:SI 4 "=c"))
15133 (clobber (reg:CC FLAGS_REG))]
15134 "!TARGET_64BIT && TARGET_GNU_TLS"
15135 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15136 [(set_attr "type" "multi")
15137 (set_attr "length" "11")])
15139 (define_insn "*tls_local_dynamic_base_32_sun"
15140 [(set (match_operand:SI 0 "register_operand" "=a")
15141 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15142 (match_operand:SI 2 "call_insn_operand" "")]
15143 UNSPEC_TLS_LD_BASE))
15144 (clobber (match_scratch:SI 3 "=d"))
15145 (clobber (match_scratch:SI 4 "=c"))
15146 (clobber (reg:CC FLAGS_REG))]
15147 "!TARGET_64BIT && TARGET_SUN_TLS"
15148 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15149 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15150 [(set_attr "type" "multi")
15151 (set_attr "length" "13")])
15153 (define_expand "tls_local_dynamic_base_32"
15154 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15155 (unspec:SI [(match_dup 1) (match_dup 2)]
15156 UNSPEC_TLS_LD_BASE))
15157 (clobber (match_scratch:SI 3 ""))
15158 (clobber (match_scratch:SI 4 ""))
15159 (clobber (reg:CC FLAGS_REG))])]
15163 operands[1] = pic_offset_table_rtx;
15166 operands[1] = gen_reg_rtx (Pmode);
15167 emit_insn (gen_set_got (operands[1]));
15169 if (TARGET_GNU2_TLS)
15171 emit_insn (gen_tls_dynamic_gnu2_32
15172 (operands[0], ix86_tls_module_base (), operands[1]));
15175 operands[2] = ix86_tls_get_addr ();
15178 (define_insn "*tls_local_dynamic_base_64"
15179 [(set (match_operand:DI 0 "register_operand" "=a")
15180 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15181 (match_operand:DI 2 "" "")))
15182 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15184 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15185 [(set_attr "type" "multi")
15186 (set_attr "length" "12")])
15188 (define_expand "tls_local_dynamic_base_64"
15189 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15190 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15191 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15194 if (TARGET_GNU2_TLS)
15196 emit_insn (gen_tls_dynamic_gnu2_64
15197 (operands[0], ix86_tls_module_base ()));
15200 operands[1] = ix86_tls_get_addr ();
15203 ;; Local dynamic of a single variable is a lose. Show combine how
15204 ;; to convert that back to global dynamic.
15206 (define_insn_and_split "*tls_local_dynamic_32_once"
15207 [(set (match_operand:SI 0 "register_operand" "=a")
15208 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15209 (match_operand:SI 2 "call_insn_operand" "")]
15210 UNSPEC_TLS_LD_BASE)
15211 (const:SI (unspec:SI
15212 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15214 (clobber (match_scratch:SI 4 "=d"))
15215 (clobber (match_scratch:SI 5 "=c"))
15216 (clobber (reg:CC FLAGS_REG))]
15220 [(parallel [(set (match_dup 0)
15221 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15223 (clobber (match_dup 4))
15224 (clobber (match_dup 5))
15225 (clobber (reg:CC FLAGS_REG))])]
15228 ;; Load and add the thread base pointer from %gs:0.
15230 (define_insn "*load_tp_si"
15231 [(set (match_operand:SI 0 "register_operand" "=r")
15232 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15234 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15235 [(set_attr "type" "imov")
15236 (set_attr "modrm" "0")
15237 (set_attr "length" "7")
15238 (set_attr "memory" "load")
15239 (set_attr "imm_disp" "false")])
15241 (define_insn "*add_tp_si"
15242 [(set (match_operand:SI 0 "register_operand" "=r")
15243 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15244 (match_operand:SI 1 "register_operand" "0")))
15245 (clobber (reg:CC FLAGS_REG))]
15247 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15248 [(set_attr "type" "alu")
15249 (set_attr "modrm" "0")
15250 (set_attr "length" "7")
15251 (set_attr "memory" "load")
15252 (set_attr "imm_disp" "false")])
15254 (define_insn "*load_tp_di"
15255 [(set (match_operand:DI 0 "register_operand" "=r")
15256 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15258 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15259 [(set_attr "type" "imov")
15260 (set_attr "modrm" "0")
15261 (set_attr "length" "7")
15262 (set_attr "memory" "load")
15263 (set_attr "imm_disp" "false")])
15265 (define_insn "*add_tp_di"
15266 [(set (match_operand:DI 0 "register_operand" "=r")
15267 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15268 (match_operand:DI 1 "register_operand" "0")))
15269 (clobber (reg:CC FLAGS_REG))]
15271 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15272 [(set_attr "type" "alu")
15273 (set_attr "modrm" "0")
15274 (set_attr "length" "7")
15275 (set_attr "memory" "load")
15276 (set_attr "imm_disp" "false")])
15278 ;; GNU2 TLS patterns can be split.
15280 (define_expand "tls_dynamic_gnu2_32"
15281 [(set (match_dup 3)
15282 (plus:SI (match_operand:SI 2 "register_operand" "")
15284 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15287 [(set (match_operand:SI 0 "register_operand" "")
15288 (unspec:SI [(match_dup 1) (match_dup 3)
15289 (match_dup 2) (reg:SI SP_REG)]
15291 (clobber (reg:CC FLAGS_REG))])]
15292 "!TARGET_64BIT && TARGET_GNU2_TLS"
15294 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15295 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15298 (define_insn "*tls_dynamic_lea_32"
15299 [(set (match_operand:SI 0 "register_operand" "=r")
15300 (plus:SI (match_operand:SI 1 "register_operand" "b")
15302 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15303 UNSPEC_TLSDESC))))]
15304 "!TARGET_64BIT && TARGET_GNU2_TLS"
15305 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15306 [(set_attr "type" "lea")
15307 (set_attr "mode" "SI")
15308 (set_attr "length" "6")
15309 (set_attr "length_address" "4")])
15311 (define_insn "*tls_dynamic_call_32"
15312 [(set (match_operand:SI 0 "register_operand" "=a")
15313 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15314 (match_operand:SI 2 "register_operand" "0")
15315 ;; we have to make sure %ebx still points to the GOT
15316 (match_operand:SI 3 "register_operand" "b")
15319 (clobber (reg:CC FLAGS_REG))]
15320 "!TARGET_64BIT && TARGET_GNU2_TLS"
15321 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15322 [(set_attr "type" "call")
15323 (set_attr "length" "2")
15324 (set_attr "length_address" "0")])
15326 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15327 [(set (match_operand:SI 0 "register_operand" "=&a")
15329 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15330 (match_operand:SI 4 "" "")
15331 (match_operand:SI 2 "register_operand" "b")
15334 (const:SI (unspec:SI
15335 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15337 (clobber (reg:CC FLAGS_REG))]
15338 "!TARGET_64BIT && TARGET_GNU2_TLS"
15341 [(set (match_dup 0) (match_dup 5))]
15343 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15344 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15347 (define_expand "tls_dynamic_gnu2_64"
15348 [(set (match_dup 2)
15349 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15352 [(set (match_operand:DI 0 "register_operand" "")
15353 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15355 (clobber (reg:CC FLAGS_REG))])]
15356 "TARGET_64BIT && TARGET_GNU2_TLS"
15358 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15359 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15362 (define_insn "*tls_dynamic_lea_64"
15363 [(set (match_operand:DI 0 "register_operand" "=r")
15364 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15366 "TARGET_64BIT && TARGET_GNU2_TLS"
15367 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15368 [(set_attr "type" "lea")
15369 (set_attr "mode" "DI")
15370 (set_attr "length" "7")
15371 (set_attr "length_address" "4")])
15373 (define_insn "*tls_dynamic_call_64"
15374 [(set (match_operand:DI 0 "register_operand" "=a")
15375 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15376 (match_operand:DI 2 "register_operand" "0")
15379 (clobber (reg:CC FLAGS_REG))]
15380 "TARGET_64BIT && TARGET_GNU2_TLS"
15381 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15382 [(set_attr "type" "call")
15383 (set_attr "length" "2")
15384 (set_attr "length_address" "0")])
15386 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15387 [(set (match_operand:DI 0 "register_operand" "=&a")
15389 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15390 (match_operand:DI 3 "" "")
15393 (const:DI (unspec:DI
15394 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15396 (clobber (reg:CC FLAGS_REG))]
15397 "TARGET_64BIT && TARGET_GNU2_TLS"
15400 [(set (match_dup 0) (match_dup 4))]
15402 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15403 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15408 ;; These patterns match the binary 387 instructions for addM3, subM3,
15409 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15410 ;; SFmode. The first is the normal insn, the second the same insn but
15411 ;; with one operand a conversion, and the third the same insn but with
15412 ;; the other operand a conversion. The conversion may be SFmode or
15413 ;; SImode if the target mode DFmode, but only SImode if the target mode
15416 ;; Gcc is slightly more smart about handling normal two address instructions
15417 ;; so use special patterns for add and mull.
15419 (define_insn "*fop_sf_comm_mixed"
15420 [(set (match_operand:SF 0 "register_operand" "=f,x")
15421 (match_operator:SF 3 "binary_fp_operator"
15422 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15423 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15424 "TARGET_MIX_SSE_I387
15425 && COMMUTATIVE_ARITH_P (operands[3])
15426 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15427 "* return output_387_binary_op (insn, operands);"
15428 [(set (attr "type")
15429 (if_then_else (eq_attr "alternative" "1")
15430 (if_then_else (match_operand:SF 3 "mult_operator" "")
15431 (const_string "ssemul")
15432 (const_string "sseadd"))
15433 (if_then_else (match_operand:SF 3 "mult_operator" "")
15434 (const_string "fmul")
15435 (const_string "fop"))))
15436 (set_attr "mode" "SF")])
15438 (define_insn "*fop_sf_comm_sse"
15439 [(set (match_operand:SF 0 "register_operand" "=x")
15440 (match_operator:SF 3 "binary_fp_operator"
15441 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15442 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15444 && COMMUTATIVE_ARITH_P (operands[3])
15445 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15446 "* return output_387_binary_op (insn, operands);"
15447 [(set (attr "type")
15448 (if_then_else (match_operand:SF 3 "mult_operator" "")
15449 (const_string "ssemul")
15450 (const_string "sseadd")))
15451 (set_attr "mode" "SF")])
15453 (define_insn "*fop_sf_comm_i387"
15454 [(set (match_operand:SF 0 "register_operand" "=f")
15455 (match_operator:SF 3 "binary_fp_operator"
15456 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15457 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15459 && COMMUTATIVE_ARITH_P (operands[3])
15460 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15461 "* return output_387_binary_op (insn, operands);"
15462 [(set (attr "type")
15463 (if_then_else (match_operand:SF 3 "mult_operator" "")
15464 (const_string "fmul")
15465 (const_string "fop")))
15466 (set_attr "mode" "SF")])
15468 (define_insn "*fop_sf_1_mixed"
15469 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15470 (match_operator:SF 3 "binary_fp_operator"
15471 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15472 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15473 "TARGET_MIX_SSE_I387
15474 && !COMMUTATIVE_ARITH_P (operands[3])
15475 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15476 "* return output_387_binary_op (insn, operands);"
15477 [(set (attr "type")
15478 (cond [(and (eq_attr "alternative" "2")
15479 (match_operand:SF 3 "mult_operator" ""))
15480 (const_string "ssemul")
15481 (and (eq_attr "alternative" "2")
15482 (match_operand:SF 3 "div_operator" ""))
15483 (const_string "ssediv")
15484 (eq_attr "alternative" "2")
15485 (const_string "sseadd")
15486 (match_operand:SF 3 "mult_operator" "")
15487 (const_string "fmul")
15488 (match_operand:SF 3 "div_operator" "")
15489 (const_string "fdiv")
15491 (const_string "fop")))
15492 (set_attr "mode" "SF")])
15494 (define_insn "*fop_sf_1_sse"
15495 [(set (match_operand:SF 0 "register_operand" "=x")
15496 (match_operator:SF 3 "binary_fp_operator"
15497 [(match_operand:SF 1 "register_operand" "0")
15498 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15500 && !COMMUTATIVE_ARITH_P (operands[3])"
15501 "* return output_387_binary_op (insn, operands);"
15502 [(set (attr "type")
15503 (cond [(match_operand:SF 3 "mult_operator" "")
15504 (const_string "ssemul")
15505 (match_operand:SF 3 "div_operator" "")
15506 (const_string "ssediv")
15508 (const_string "sseadd")))
15509 (set_attr "mode" "SF")])
15511 ;; This pattern is not fully shadowed by the pattern above.
15512 (define_insn "*fop_sf_1_i387"
15513 [(set (match_operand:SF 0 "register_operand" "=f,f")
15514 (match_operator:SF 3 "binary_fp_operator"
15515 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15516 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15517 "TARGET_80387 && !TARGET_SSE_MATH
15518 && !COMMUTATIVE_ARITH_P (operands[3])
15519 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15520 "* return output_387_binary_op (insn, operands);"
15521 [(set (attr "type")
15522 (cond [(match_operand:SF 3 "mult_operator" "")
15523 (const_string "fmul")
15524 (match_operand:SF 3 "div_operator" "")
15525 (const_string "fdiv")
15527 (const_string "fop")))
15528 (set_attr "mode" "SF")])
15530 ;; ??? Add SSE splitters for these!
15531 (define_insn "*fop_sf_2<mode>_i387"
15532 [(set (match_operand:SF 0 "register_operand" "=f,f")
15533 (match_operator:SF 3 "binary_fp_operator"
15534 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15535 (match_operand:SF 2 "register_operand" "0,0")]))]
15536 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15537 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15538 [(set (attr "type")
15539 (cond [(match_operand:SF 3 "mult_operator" "")
15540 (const_string "fmul")
15541 (match_operand:SF 3 "div_operator" "")
15542 (const_string "fdiv")
15544 (const_string "fop")))
15545 (set_attr "fp_int_src" "true")
15546 (set_attr "mode" "<MODE>")])
15548 (define_insn "*fop_sf_3<mode>_i387"
15549 [(set (match_operand:SF 0 "register_operand" "=f,f")
15550 (match_operator:SF 3 "binary_fp_operator"
15551 [(match_operand:SF 1 "register_operand" "0,0")
15552 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15553 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15554 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15555 [(set (attr "type")
15556 (cond [(match_operand:SF 3 "mult_operator" "")
15557 (const_string "fmul")
15558 (match_operand:SF 3 "div_operator" "")
15559 (const_string "fdiv")
15561 (const_string "fop")))
15562 (set_attr "fp_int_src" "true")
15563 (set_attr "mode" "<MODE>")])
15565 (define_insn "*fop_df_comm_mixed"
15566 [(set (match_operand:DF 0 "register_operand" "=f,x")
15567 (match_operator:DF 3 "binary_fp_operator"
15568 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15569 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15570 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15571 && COMMUTATIVE_ARITH_P (operands[3])
15572 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15573 "* return output_387_binary_op (insn, operands);"
15574 [(set (attr "type")
15575 (if_then_else (eq_attr "alternative" "1")
15576 (if_then_else (match_operand:DF 3 "mult_operator" "")
15577 (const_string "ssemul")
15578 (const_string "sseadd"))
15579 (if_then_else (match_operand:DF 3 "mult_operator" "")
15580 (const_string "fmul")
15581 (const_string "fop"))))
15582 (set_attr "mode" "DF")])
15584 (define_insn "*fop_df_comm_sse"
15585 [(set (match_operand:DF 0 "register_operand" "=x")
15586 (match_operator:DF 3 "binary_fp_operator"
15587 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15588 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15589 "TARGET_SSE2 && TARGET_SSE_MATH
15590 && COMMUTATIVE_ARITH_P (operands[3])
15591 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15592 "* return output_387_binary_op (insn, operands);"
15593 [(set (attr "type")
15594 (if_then_else (match_operand:DF 3 "mult_operator" "")
15595 (const_string "ssemul")
15596 (const_string "sseadd")))
15597 (set_attr "mode" "DF")])
15599 (define_insn "*fop_df_comm_i387"
15600 [(set (match_operand:DF 0 "register_operand" "=f")
15601 (match_operator:DF 3 "binary_fp_operator"
15602 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15603 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15605 && COMMUTATIVE_ARITH_P (operands[3])
15606 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15607 "* return output_387_binary_op (insn, operands);"
15608 [(set (attr "type")
15609 (if_then_else (match_operand:DF 3 "mult_operator" "")
15610 (const_string "fmul")
15611 (const_string "fop")))
15612 (set_attr "mode" "DF")])
15614 (define_insn "*fop_df_1_mixed"
15615 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15616 (match_operator:DF 3 "binary_fp_operator"
15617 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15618 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15619 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15620 && !COMMUTATIVE_ARITH_P (operands[3])
15621 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15622 "* return output_387_binary_op (insn, operands);"
15623 [(set (attr "type")
15624 (cond [(and (eq_attr "alternative" "2")
15625 (match_operand:DF 3 "mult_operator" ""))
15626 (const_string "ssemul")
15627 (and (eq_attr "alternative" "2")
15628 (match_operand:DF 3 "div_operator" ""))
15629 (const_string "ssediv")
15630 (eq_attr "alternative" "2")
15631 (const_string "sseadd")
15632 (match_operand:DF 3 "mult_operator" "")
15633 (const_string "fmul")
15634 (match_operand:DF 3 "div_operator" "")
15635 (const_string "fdiv")
15637 (const_string "fop")))
15638 (set_attr "mode" "DF")])
15640 (define_insn "*fop_df_1_sse"
15641 [(set (match_operand:DF 0 "register_operand" "=x")
15642 (match_operator:DF 3 "binary_fp_operator"
15643 [(match_operand:DF 1 "register_operand" "0")
15644 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15645 "TARGET_SSE2 && TARGET_SSE_MATH
15646 && !COMMUTATIVE_ARITH_P (operands[3])"
15647 "* return output_387_binary_op (insn, operands);"
15648 [(set_attr "mode" "DF")
15650 (cond [(match_operand:DF 3 "mult_operator" "")
15651 (const_string "ssemul")
15652 (match_operand:DF 3 "div_operator" "")
15653 (const_string "ssediv")
15655 (const_string "sseadd")))])
15657 ;; This pattern is not fully shadowed by the pattern above.
15658 (define_insn "*fop_df_1_i387"
15659 [(set (match_operand:DF 0 "register_operand" "=f,f")
15660 (match_operator:DF 3 "binary_fp_operator"
15661 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15662 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15663 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15664 && !COMMUTATIVE_ARITH_P (operands[3])
15665 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15666 "* return output_387_binary_op (insn, operands);"
15667 [(set (attr "type")
15668 (cond [(match_operand:DF 3 "mult_operator" "")
15669 (const_string "fmul")
15670 (match_operand:DF 3 "div_operator" "")
15671 (const_string "fdiv")
15673 (const_string "fop")))
15674 (set_attr "mode" "DF")])
15676 ;; ??? Add SSE splitters for these!
15677 (define_insn "*fop_df_2<mode>_i387"
15678 [(set (match_operand:DF 0 "register_operand" "=f,f")
15679 (match_operator:DF 3 "binary_fp_operator"
15680 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15681 (match_operand:DF 2 "register_operand" "0,0")]))]
15682 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15683 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15684 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15685 [(set (attr "type")
15686 (cond [(match_operand:DF 3 "mult_operator" "")
15687 (const_string "fmul")
15688 (match_operand:DF 3 "div_operator" "")
15689 (const_string "fdiv")
15691 (const_string "fop")))
15692 (set_attr "fp_int_src" "true")
15693 (set_attr "mode" "<MODE>")])
15695 (define_insn "*fop_df_3<mode>_i387"
15696 [(set (match_operand:DF 0 "register_operand" "=f,f")
15697 (match_operator:DF 3 "binary_fp_operator"
15698 [(match_operand:DF 1 "register_operand" "0,0")
15699 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15700 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15701 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15702 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15703 [(set (attr "type")
15704 (cond [(match_operand:DF 3 "mult_operator" "")
15705 (const_string "fmul")
15706 (match_operand:DF 3 "div_operator" "")
15707 (const_string "fdiv")
15709 (const_string "fop")))
15710 (set_attr "fp_int_src" "true")
15711 (set_attr "mode" "<MODE>")])
15713 (define_insn "*fop_df_4_i387"
15714 [(set (match_operand:DF 0 "register_operand" "=f,f")
15715 (match_operator:DF 3 "binary_fp_operator"
15716 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15717 (match_operand:DF 2 "register_operand" "0,f")]))]
15718 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15719 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15720 "* return output_387_binary_op (insn, operands);"
15721 [(set (attr "type")
15722 (cond [(match_operand:DF 3 "mult_operator" "")
15723 (const_string "fmul")
15724 (match_operand:DF 3 "div_operator" "")
15725 (const_string "fdiv")
15727 (const_string "fop")))
15728 (set_attr "mode" "SF")])
15730 (define_insn "*fop_df_5_i387"
15731 [(set (match_operand:DF 0 "register_operand" "=f,f")
15732 (match_operator:DF 3 "binary_fp_operator"
15733 [(match_operand:DF 1 "register_operand" "0,f")
15735 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15736 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15737 "* return output_387_binary_op (insn, operands);"
15738 [(set (attr "type")
15739 (cond [(match_operand:DF 3 "mult_operator" "")
15740 (const_string "fmul")
15741 (match_operand:DF 3 "div_operator" "")
15742 (const_string "fdiv")
15744 (const_string "fop")))
15745 (set_attr "mode" "SF")])
15747 (define_insn "*fop_df_6_i387"
15748 [(set (match_operand:DF 0 "register_operand" "=f,f")
15749 (match_operator:DF 3 "binary_fp_operator"
15751 (match_operand:SF 1 "register_operand" "0,f"))
15753 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15754 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15755 "* return output_387_binary_op (insn, operands);"
15756 [(set (attr "type")
15757 (cond [(match_operand:DF 3 "mult_operator" "")
15758 (const_string "fmul")
15759 (match_operand:DF 3 "div_operator" "")
15760 (const_string "fdiv")
15762 (const_string "fop")))
15763 (set_attr "mode" "SF")])
15765 (define_insn "*fop_xf_comm_i387"
15766 [(set (match_operand:XF 0 "register_operand" "=f")
15767 (match_operator:XF 3 "binary_fp_operator"
15768 [(match_operand:XF 1 "register_operand" "%0")
15769 (match_operand:XF 2 "register_operand" "f")]))]
15771 && COMMUTATIVE_ARITH_P (operands[3])"
15772 "* return output_387_binary_op (insn, operands);"
15773 [(set (attr "type")
15774 (if_then_else (match_operand:XF 3 "mult_operator" "")
15775 (const_string "fmul")
15776 (const_string "fop")))
15777 (set_attr "mode" "XF")])
15779 (define_insn "*fop_xf_1_i387"
15780 [(set (match_operand:XF 0 "register_operand" "=f,f")
15781 (match_operator:XF 3 "binary_fp_operator"
15782 [(match_operand:XF 1 "register_operand" "0,f")
15783 (match_operand:XF 2 "register_operand" "f,0")]))]
15785 && !COMMUTATIVE_ARITH_P (operands[3])"
15786 "* return output_387_binary_op (insn, operands);"
15787 [(set (attr "type")
15788 (cond [(match_operand:XF 3 "mult_operator" "")
15789 (const_string "fmul")
15790 (match_operand:XF 3 "div_operator" "")
15791 (const_string "fdiv")
15793 (const_string "fop")))
15794 (set_attr "mode" "XF")])
15796 (define_insn "*fop_xf_2<mode>_i387"
15797 [(set (match_operand:XF 0 "register_operand" "=f,f")
15798 (match_operator:XF 3 "binary_fp_operator"
15799 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15800 (match_operand:XF 2 "register_operand" "0,0")]))]
15801 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15802 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15803 [(set (attr "type")
15804 (cond [(match_operand:XF 3 "mult_operator" "")
15805 (const_string "fmul")
15806 (match_operand:XF 3 "div_operator" "")
15807 (const_string "fdiv")
15809 (const_string "fop")))
15810 (set_attr "fp_int_src" "true")
15811 (set_attr "mode" "<MODE>")])
15813 (define_insn "*fop_xf_3<mode>_i387"
15814 [(set (match_operand:XF 0 "register_operand" "=f,f")
15815 (match_operator:XF 3 "binary_fp_operator"
15816 [(match_operand:XF 1 "register_operand" "0,0")
15817 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15818 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15819 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15820 [(set (attr "type")
15821 (cond [(match_operand:XF 3 "mult_operator" "")
15822 (const_string "fmul")
15823 (match_operand:XF 3 "div_operator" "")
15824 (const_string "fdiv")
15826 (const_string "fop")))
15827 (set_attr "fp_int_src" "true")
15828 (set_attr "mode" "<MODE>")])
15830 (define_insn "*fop_xf_4_i387"
15831 [(set (match_operand:XF 0 "register_operand" "=f,f")
15832 (match_operator:XF 3 "binary_fp_operator"
15834 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15835 (match_operand:XF 2 "register_operand" "0,f")]))]
15837 "* return output_387_binary_op (insn, operands);"
15838 [(set (attr "type")
15839 (cond [(match_operand:XF 3 "mult_operator" "")
15840 (const_string "fmul")
15841 (match_operand:XF 3 "div_operator" "")
15842 (const_string "fdiv")
15844 (const_string "fop")))
15845 (set_attr "mode" "SF")])
15847 (define_insn "*fop_xf_5_i387"
15848 [(set (match_operand:XF 0 "register_operand" "=f,f")
15849 (match_operator:XF 3 "binary_fp_operator"
15850 [(match_operand:XF 1 "register_operand" "0,f")
15852 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15854 "* return output_387_binary_op (insn, operands);"
15855 [(set (attr "type")
15856 (cond [(match_operand:XF 3 "mult_operator" "")
15857 (const_string "fmul")
15858 (match_operand:XF 3 "div_operator" "")
15859 (const_string "fdiv")
15861 (const_string "fop")))
15862 (set_attr "mode" "SF")])
15864 (define_insn "*fop_xf_6_i387"
15865 [(set (match_operand:XF 0 "register_operand" "=f,f")
15866 (match_operator:XF 3 "binary_fp_operator"
15868 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15870 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15872 "* return output_387_binary_op (insn, operands);"
15873 [(set (attr "type")
15874 (cond [(match_operand:XF 3 "mult_operator" "")
15875 (const_string "fmul")
15876 (match_operand:XF 3 "div_operator" "")
15877 (const_string "fdiv")
15879 (const_string "fop")))
15880 (set_attr "mode" "SF")])
15883 [(set (match_operand 0 "register_operand" "")
15884 (match_operator 3 "binary_fp_operator"
15885 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15886 (match_operand 2 "register_operand" "")]))]
15888 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15891 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15892 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15893 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15894 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15895 GET_MODE (operands[3]),
15898 ix86_free_from_memory (GET_MODE (operands[1]));
15903 [(set (match_operand 0 "register_operand" "")
15904 (match_operator 3 "binary_fp_operator"
15905 [(match_operand 1 "register_operand" "")
15906 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15908 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15911 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15912 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15913 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15914 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15915 GET_MODE (operands[3]),
15918 ix86_free_from_memory (GET_MODE (operands[2]));
15922 ;; FPU special functions.
15924 ;; This pattern implements a no-op XFmode truncation for
15925 ;; all fancy i386 XFmode math functions.
15927 (define_insn "truncxf<mode>2_i387_noop_unspec"
15928 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15929 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15930 UNSPEC_TRUNC_NOOP))]
15931 "TARGET_USE_FANCY_MATH_387"
15932 "* return output_387_reg_move (insn, operands);"
15933 [(set_attr "type" "fmov")
15934 (set_attr "mode" "<MODE>")])
15936 (define_insn "sqrtxf2"
15937 [(set (match_operand:XF 0 "register_operand" "=f")
15938 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15939 "TARGET_USE_FANCY_MATH_387"
15941 [(set_attr "type" "fpspc")
15942 (set_attr "mode" "XF")
15943 (set_attr "athlon_decode" "direct")
15944 (set_attr "amdfam10_decode" "direct")])
15946 (define_insn "sqrt_extend<mode>xf2_i387"
15947 [(set (match_operand:XF 0 "register_operand" "=f")
15950 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15951 "TARGET_USE_FANCY_MATH_387"
15953 [(set_attr "type" "fpspc")
15954 (set_attr "mode" "XF")
15955 (set_attr "athlon_decode" "direct")
15956 (set_attr "amdfam10_decode" "direct")])
15958 (define_insn "*sqrt<mode>2_sse"
15959 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15961 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15962 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15963 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15964 [(set_attr "type" "sse")
15965 (set_attr "mode" "<MODE>")
15966 (set_attr "athlon_decode" "*")
15967 (set_attr "amdfam10_decode" "*")])
15969 (define_expand "sqrt<mode>2"
15970 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15972 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15973 "TARGET_USE_FANCY_MATH_387
15974 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15976 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15978 rtx op0 = gen_reg_rtx (XFmode);
15979 rtx op1 = force_reg (<MODE>mode, operands[1]);
15981 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15982 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15987 (define_insn "fpremxf4_i387"
15988 [(set (match_operand:XF 0 "register_operand" "=f")
15989 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15990 (match_operand:XF 3 "register_operand" "1")]
15992 (set (match_operand:XF 1 "register_operand" "=u")
15993 (unspec:XF [(match_dup 2) (match_dup 3)]
15995 (set (reg:CCFP FPSR_REG)
15996 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15998 "TARGET_USE_FANCY_MATH_387"
16000 [(set_attr "type" "fpspc")
16001 (set_attr "mode" "XF")])
16003 (define_expand "fmodxf3"
16004 [(use (match_operand:XF 0 "register_operand" ""))
16005 (use (match_operand:XF 1 "register_operand" ""))
16006 (use (match_operand:XF 2 "register_operand" ""))]
16007 "TARGET_USE_FANCY_MATH_387"
16009 rtx label = gen_label_rtx ();
16011 emit_label (label);
16013 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16014 operands[1], operands[2]));
16015 ix86_emit_fp_unordered_jump (label);
16016 LABEL_NUSES (label) = 1;
16018 emit_move_insn (operands[0], operands[1]);
16022 (define_expand "fmod<mode>3"
16023 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16024 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16025 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16026 "TARGET_USE_FANCY_MATH_387"
16028 rtx label = gen_label_rtx ();
16030 rtx op1 = gen_reg_rtx (XFmode);
16031 rtx op2 = gen_reg_rtx (XFmode);
16033 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16034 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16036 emit_label (label);
16037 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16038 ix86_emit_fp_unordered_jump (label);
16039 LABEL_NUSES (label) = 1;
16041 /* Truncate the result properly for strict SSE math. */
16042 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16043 && !TARGET_MIX_SSE_I387)
16044 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16046 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16051 (define_insn "fprem1xf4_i387"
16052 [(set (match_operand:XF 0 "register_operand" "=f")
16053 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16054 (match_operand:XF 3 "register_operand" "1")]
16056 (set (match_operand:XF 1 "register_operand" "=u")
16057 (unspec:XF [(match_dup 2) (match_dup 3)]
16059 (set (reg:CCFP FPSR_REG)
16060 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16062 "TARGET_USE_FANCY_MATH_387"
16064 [(set_attr "type" "fpspc")
16065 (set_attr "mode" "XF")])
16067 (define_expand "remainderxf3"
16068 [(use (match_operand:XF 0 "register_operand" ""))
16069 (use (match_operand:XF 1 "register_operand" ""))
16070 (use (match_operand:XF 2 "register_operand" ""))]
16071 "TARGET_USE_FANCY_MATH_387"
16073 rtx label = gen_label_rtx ();
16075 emit_label (label);
16077 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16078 operands[1], operands[2]));
16079 ix86_emit_fp_unordered_jump (label);
16080 LABEL_NUSES (label) = 1;
16082 emit_move_insn (operands[0], operands[1]);
16086 (define_expand "remainder<mode>3"
16087 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16088 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16089 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16090 "TARGET_USE_FANCY_MATH_387"
16092 rtx label = gen_label_rtx ();
16094 rtx op1 = gen_reg_rtx (XFmode);
16095 rtx op2 = gen_reg_rtx (XFmode);
16097 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16098 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16100 emit_label (label);
16102 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16103 ix86_emit_fp_unordered_jump (label);
16104 LABEL_NUSES (label) = 1;
16106 /* Truncate the result properly for strict SSE math. */
16107 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16108 && !TARGET_MIX_SSE_I387)
16109 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16111 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16116 (define_insn "*sinxf2_i387"
16117 [(set (match_operand:XF 0 "register_operand" "=f")
16118 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16119 "TARGET_USE_FANCY_MATH_387
16120 && flag_unsafe_math_optimizations"
16122 [(set_attr "type" "fpspc")
16123 (set_attr "mode" "XF")])
16125 (define_insn "*sin_extend<mode>xf2_i387"
16126 [(set (match_operand:XF 0 "register_operand" "=f")
16127 (unspec:XF [(float_extend:XF
16128 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16130 "TARGET_USE_FANCY_MATH_387
16131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16132 || TARGET_MIX_SSE_I387)
16133 && flag_unsafe_math_optimizations"
16135 [(set_attr "type" "fpspc")
16136 (set_attr "mode" "XF")])
16138 (define_insn "*cosxf2_i387"
16139 [(set (match_operand:XF 0 "register_operand" "=f")
16140 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16141 "TARGET_USE_FANCY_MATH_387
16142 && flag_unsafe_math_optimizations"
16144 [(set_attr "type" "fpspc")
16145 (set_attr "mode" "XF")])
16147 (define_insn "*cos_extend<mode>xf2_i387"
16148 [(set (match_operand:XF 0 "register_operand" "=f")
16149 (unspec:XF [(float_extend:XF
16150 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16152 "TARGET_USE_FANCY_MATH_387
16153 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16154 || TARGET_MIX_SSE_I387)
16155 && flag_unsafe_math_optimizations"
16157 [(set_attr "type" "fpspc")
16158 (set_attr "mode" "XF")])
16160 ;; When sincos pattern is defined, sin and cos builtin functions will be
16161 ;; expanded to sincos pattern with one of its outputs left unused.
16162 ;; CSE pass will figure out if two sincos patterns can be combined,
16163 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16164 ;; depending on the unused output.
16166 (define_insn "sincosxf3"
16167 [(set (match_operand:XF 0 "register_operand" "=f")
16168 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16169 UNSPEC_SINCOS_COS))
16170 (set (match_operand:XF 1 "register_operand" "=u")
16171 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16172 "TARGET_USE_FANCY_MATH_387
16173 && flag_unsafe_math_optimizations"
16175 [(set_attr "type" "fpspc")
16176 (set_attr "mode" "XF")])
16179 [(set (match_operand:XF 0 "register_operand" "")
16180 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16181 UNSPEC_SINCOS_COS))
16182 (set (match_operand:XF 1 "register_operand" "")
16183 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16184 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16185 && !reload_completed && !reload_in_progress"
16186 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16190 [(set (match_operand:XF 0 "register_operand" "")
16191 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16192 UNSPEC_SINCOS_COS))
16193 (set (match_operand:XF 1 "register_operand" "")
16194 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16195 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16196 && !reload_completed && !reload_in_progress"
16197 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16200 (define_insn "sincos_extend<mode>xf3_i387"
16201 [(set (match_operand:XF 0 "register_operand" "=f")
16202 (unspec:XF [(float_extend:XF
16203 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16204 UNSPEC_SINCOS_COS))
16205 (set (match_operand:XF 1 "register_operand" "=u")
16206 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16207 "TARGET_USE_FANCY_MATH_387
16208 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16209 || TARGET_MIX_SSE_I387)
16210 && flag_unsafe_math_optimizations"
16212 [(set_attr "type" "fpspc")
16213 (set_attr "mode" "XF")])
16216 [(set (match_operand:XF 0 "register_operand" "")
16217 (unspec:XF [(float_extend:XF
16218 (match_operand:X87MODEF12 2 "register_operand" ""))]
16219 UNSPEC_SINCOS_COS))
16220 (set (match_operand:XF 1 "register_operand" "")
16221 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16222 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16223 && !reload_completed && !reload_in_progress"
16224 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16228 [(set (match_operand:XF 0 "register_operand" "")
16229 (unspec:XF [(float_extend:XF
16230 (match_operand:X87MODEF12 2 "register_operand" ""))]
16231 UNSPEC_SINCOS_COS))
16232 (set (match_operand:XF 1 "register_operand" "")
16233 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16234 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16235 && !reload_completed && !reload_in_progress"
16236 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16239 (define_expand "sincos<mode>3"
16240 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16241 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16242 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16243 "TARGET_USE_FANCY_MATH_387
16244 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16245 || TARGET_MIX_SSE_I387)
16246 && flag_unsafe_math_optimizations"
16248 rtx op0 = gen_reg_rtx (XFmode);
16249 rtx op1 = gen_reg_rtx (XFmode);
16251 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16252 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16253 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16257 (define_insn "fptanxf4_i387"
16258 [(set (match_operand:XF 0 "register_operand" "=f")
16259 (match_operand:XF 3 "const_double_operand" "F"))
16260 (set (match_operand:XF 1 "register_operand" "=u")
16261 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16263 "TARGET_USE_FANCY_MATH_387
16264 && flag_unsafe_math_optimizations
16265 && standard_80387_constant_p (operands[3]) == 2"
16267 [(set_attr "type" "fpspc")
16268 (set_attr "mode" "XF")])
16270 (define_insn "fptan_extend<mode>xf4_i387"
16271 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16272 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16273 (set (match_operand:XF 1 "register_operand" "=u")
16274 (unspec:XF [(float_extend:XF
16275 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16277 "TARGET_USE_FANCY_MATH_387
16278 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16279 || TARGET_MIX_SSE_I387)
16280 && flag_unsafe_math_optimizations
16281 && standard_80387_constant_p (operands[3]) == 2"
16283 [(set_attr "type" "fpspc")
16284 (set_attr "mode" "XF")])
16286 (define_expand "tanxf2"
16287 [(use (match_operand:XF 0 "register_operand" ""))
16288 (use (match_operand:XF 1 "register_operand" ""))]
16289 "TARGET_USE_FANCY_MATH_387
16290 && flag_unsafe_math_optimizations"
16292 rtx one = gen_reg_rtx (XFmode);
16293 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16295 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16299 (define_expand "tan<mode>2"
16300 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16301 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16302 "TARGET_USE_FANCY_MATH_387
16303 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16304 || TARGET_MIX_SSE_I387)
16305 && flag_unsafe_math_optimizations"
16307 rtx op0 = gen_reg_rtx (XFmode);
16309 rtx one = gen_reg_rtx (<MODE>mode);
16310 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16312 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16313 operands[1], op2));
16314 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16318 (define_insn "*fpatanxf3_i387"
16319 [(set (match_operand:XF 0 "register_operand" "=f")
16320 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16321 (match_operand:XF 2 "register_operand" "u")]
16323 (clobber (match_scratch:XF 3 "=2"))]
16324 "TARGET_USE_FANCY_MATH_387
16325 && flag_unsafe_math_optimizations"
16327 [(set_attr "type" "fpspc")
16328 (set_attr "mode" "XF")])
16330 (define_insn "fpatan_extend<mode>xf3_i387"
16331 [(set (match_operand:XF 0 "register_operand" "=f")
16332 (unspec:XF [(float_extend:XF
16333 (match_operand:X87MODEF12 1 "register_operand" "0"))
16335 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16337 (clobber (match_scratch:XF 3 "=2"))]
16338 "TARGET_USE_FANCY_MATH_387
16339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16340 || TARGET_MIX_SSE_I387)
16341 && flag_unsafe_math_optimizations"
16343 [(set_attr "type" "fpspc")
16344 (set_attr "mode" "XF")])
16346 (define_expand "atan2xf3"
16347 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16348 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16349 (match_operand:XF 1 "register_operand" "")]
16351 (clobber (match_scratch:XF 3 ""))])]
16352 "TARGET_USE_FANCY_MATH_387
16353 && flag_unsafe_math_optimizations"
16356 (define_expand "atan2<mode>3"
16357 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16358 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16359 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16360 "TARGET_USE_FANCY_MATH_387
16361 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16362 || TARGET_MIX_SSE_I387)
16363 && flag_unsafe_math_optimizations"
16365 rtx op0 = gen_reg_rtx (XFmode);
16367 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16368 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16372 (define_expand "atanxf2"
16373 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16374 (unspec:XF [(match_dup 2)
16375 (match_operand:XF 1 "register_operand" "")]
16377 (clobber (match_scratch:XF 3 ""))])]
16378 "TARGET_USE_FANCY_MATH_387
16379 && flag_unsafe_math_optimizations"
16381 operands[2] = gen_reg_rtx (XFmode);
16382 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16385 (define_expand "atan<mode>2"
16386 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16387 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16388 "TARGET_USE_FANCY_MATH_387
16389 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16390 || TARGET_MIX_SSE_I387)
16391 && flag_unsafe_math_optimizations"
16393 rtx op0 = gen_reg_rtx (XFmode);
16395 rtx op2 = gen_reg_rtx (<MODE>mode);
16396 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16398 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16399 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16403 (define_expand "asinxf2"
16404 [(set (match_dup 2)
16405 (mult:XF (match_operand:XF 1 "register_operand" "")
16407 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16408 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16409 (parallel [(set (match_operand:XF 0 "register_operand" "")
16410 (unspec:XF [(match_dup 5) (match_dup 1)]
16412 (clobber (match_scratch:XF 6 ""))])]
16413 "TARGET_USE_FANCY_MATH_387
16414 && flag_unsafe_math_optimizations && !optimize_size"
16418 for (i = 2; i < 6; i++)
16419 operands[i] = gen_reg_rtx (XFmode);
16421 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16424 (define_expand "asin<mode>2"
16425 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16426 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16427 "TARGET_USE_FANCY_MATH_387
16428 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16429 || TARGET_MIX_SSE_I387)
16430 && flag_unsafe_math_optimizations && !optimize_size"
16432 rtx op0 = gen_reg_rtx (XFmode);
16433 rtx op1 = gen_reg_rtx (XFmode);
16435 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16436 emit_insn (gen_asinxf2 (op0, op1));
16437 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16441 (define_expand "acosxf2"
16442 [(set (match_dup 2)
16443 (mult:XF (match_operand:XF 1 "register_operand" "")
16445 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16446 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16447 (parallel [(set (match_operand:XF 0 "register_operand" "")
16448 (unspec:XF [(match_dup 1) (match_dup 5)]
16450 (clobber (match_scratch:XF 6 ""))])]
16451 "TARGET_USE_FANCY_MATH_387
16452 && flag_unsafe_math_optimizations && !optimize_size"
16456 for (i = 2; i < 6; i++)
16457 operands[i] = gen_reg_rtx (XFmode);
16459 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16462 (define_expand "acos<mode>2"
16463 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16464 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16465 "TARGET_USE_FANCY_MATH_387
16466 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16467 || TARGET_MIX_SSE_I387)
16468 && flag_unsafe_math_optimizations && !optimize_size"
16470 rtx op0 = gen_reg_rtx (XFmode);
16471 rtx op1 = gen_reg_rtx (XFmode);
16473 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16474 emit_insn (gen_acosxf2 (op0, op1));
16475 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16479 (define_insn "fyl2xxf3_i387"
16480 [(set (match_operand:XF 0 "register_operand" "=f")
16481 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16482 (match_operand:XF 2 "register_operand" "u")]
16484 (clobber (match_scratch:XF 3 "=2"))]
16485 "TARGET_USE_FANCY_MATH_387
16486 && flag_unsafe_math_optimizations"
16488 [(set_attr "type" "fpspc")
16489 (set_attr "mode" "XF")])
16491 (define_insn "fyl2x_extend<mode>xf3_i387"
16492 [(set (match_operand:XF 0 "register_operand" "=f")
16493 (unspec:XF [(float_extend:XF
16494 (match_operand:X87MODEF12 1 "register_operand" "0"))
16495 (match_operand:XF 2 "register_operand" "u")]
16497 (clobber (match_scratch:XF 3 "=2"))]
16498 "TARGET_USE_FANCY_MATH_387
16499 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16500 || TARGET_MIX_SSE_I387)
16501 && flag_unsafe_math_optimizations"
16503 [(set_attr "type" "fpspc")
16504 (set_attr "mode" "XF")])
16506 (define_expand "logxf2"
16507 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16508 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16509 (match_dup 2)] UNSPEC_FYL2X))
16510 (clobber (match_scratch:XF 3 ""))])]
16511 "TARGET_USE_FANCY_MATH_387
16512 && flag_unsafe_math_optimizations"
16514 operands[2] = gen_reg_rtx (XFmode);
16515 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16518 (define_expand "log<mode>2"
16519 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16520 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16521 "TARGET_USE_FANCY_MATH_387
16522 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16523 || TARGET_MIX_SSE_I387)
16524 && flag_unsafe_math_optimizations"
16526 rtx op0 = gen_reg_rtx (XFmode);
16528 rtx op2 = gen_reg_rtx (XFmode);
16529 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16531 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16532 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16536 (define_expand "log10xf2"
16537 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16538 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16539 (match_dup 2)] UNSPEC_FYL2X))
16540 (clobber (match_scratch:XF 3 ""))])]
16541 "TARGET_USE_FANCY_MATH_387
16542 && flag_unsafe_math_optimizations"
16544 operands[2] = gen_reg_rtx (XFmode);
16545 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16548 (define_expand "log10<mode>2"
16549 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16550 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16551 "TARGET_USE_FANCY_MATH_387
16552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16553 || TARGET_MIX_SSE_I387)
16554 && flag_unsafe_math_optimizations"
16556 rtx op0 = gen_reg_rtx (XFmode);
16558 rtx op2 = gen_reg_rtx (XFmode);
16559 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16561 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16562 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16566 (define_expand "log2xf2"
16567 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16568 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16569 (match_dup 2)] UNSPEC_FYL2X))
16570 (clobber (match_scratch:XF 3 ""))])]
16571 "TARGET_USE_FANCY_MATH_387
16572 && flag_unsafe_math_optimizations"
16574 operands[2] = gen_reg_rtx (XFmode);
16575 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16578 (define_expand "log2<mode>2"
16579 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16580 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16581 "TARGET_USE_FANCY_MATH_387
16582 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16583 || TARGET_MIX_SSE_I387)
16584 && flag_unsafe_math_optimizations"
16586 rtx op0 = gen_reg_rtx (XFmode);
16588 rtx op2 = gen_reg_rtx (XFmode);
16589 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16591 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16592 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16596 (define_insn "fyl2xp1xf3_i387"
16597 [(set (match_operand:XF 0 "register_operand" "=f")
16598 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16599 (match_operand:XF 2 "register_operand" "u")]
16601 (clobber (match_scratch:XF 3 "=2"))]
16602 "TARGET_USE_FANCY_MATH_387
16603 && flag_unsafe_math_optimizations"
16605 [(set_attr "type" "fpspc")
16606 (set_attr "mode" "XF")])
16608 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16609 [(set (match_operand:XF 0 "register_operand" "=f")
16610 (unspec:XF [(float_extend:XF
16611 (match_operand:X87MODEF12 1 "register_operand" "0"))
16612 (match_operand:XF 2 "register_operand" "u")]
16614 (clobber (match_scratch:XF 3 "=2"))]
16615 "TARGET_USE_FANCY_MATH_387
16616 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16617 || TARGET_MIX_SSE_I387)
16618 && flag_unsafe_math_optimizations"
16620 [(set_attr "type" "fpspc")
16621 (set_attr "mode" "XF")])
16623 (define_expand "log1pxf2"
16624 [(use (match_operand:XF 0 "register_operand" ""))
16625 (use (match_operand:XF 1 "register_operand" ""))]
16626 "TARGET_USE_FANCY_MATH_387
16627 && flag_unsafe_math_optimizations && !optimize_size"
16629 ix86_emit_i387_log1p (operands[0], operands[1]);
16633 (define_expand "log1p<mode>2"
16634 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16635 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16636 "TARGET_USE_FANCY_MATH_387
16637 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16638 || TARGET_MIX_SSE_I387)
16639 && flag_unsafe_math_optimizations && !optimize_size"
16641 rtx op0 = gen_reg_rtx (XFmode);
16643 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16645 ix86_emit_i387_log1p (op0, operands[1]);
16646 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16650 (define_insn "fxtractxf3_i387"
16651 [(set (match_operand:XF 0 "register_operand" "=f")
16652 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16653 UNSPEC_XTRACT_FRACT))
16654 (set (match_operand:XF 1 "register_operand" "=u")
16655 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16656 "TARGET_USE_FANCY_MATH_387
16657 && flag_unsafe_math_optimizations"
16659 [(set_attr "type" "fpspc")
16660 (set_attr "mode" "XF")])
16662 (define_insn "fxtract_extend<mode>xf3_i387"
16663 [(set (match_operand:XF 0 "register_operand" "=f")
16664 (unspec:XF [(float_extend:XF
16665 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16666 UNSPEC_XTRACT_FRACT))
16667 (set (match_operand:XF 1 "register_operand" "=u")
16668 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16669 "TARGET_USE_FANCY_MATH_387
16670 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16671 || TARGET_MIX_SSE_I387)
16672 && flag_unsafe_math_optimizations"
16674 [(set_attr "type" "fpspc")
16675 (set_attr "mode" "XF")])
16677 (define_expand "logbxf2"
16678 [(parallel [(set (match_dup 2)
16679 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16680 UNSPEC_XTRACT_FRACT))
16681 (set (match_operand:XF 0 "register_operand" "")
16682 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16683 "TARGET_USE_FANCY_MATH_387
16684 && flag_unsafe_math_optimizations"
16686 operands[2] = gen_reg_rtx (XFmode);
16689 (define_expand "logb<mode>2"
16690 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16691 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16692 "TARGET_USE_FANCY_MATH_387
16693 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16694 || TARGET_MIX_SSE_I387)
16695 && flag_unsafe_math_optimizations"
16697 rtx op0 = gen_reg_rtx (XFmode);
16698 rtx op1 = gen_reg_rtx (XFmode);
16700 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16701 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16705 (define_expand "ilogbxf2"
16706 [(use (match_operand:SI 0 "register_operand" ""))
16707 (use (match_operand:XF 1 "register_operand" ""))]
16708 "TARGET_USE_FANCY_MATH_387
16709 && flag_unsafe_math_optimizations && !optimize_size"
16711 rtx op0 = gen_reg_rtx (XFmode);
16712 rtx op1 = gen_reg_rtx (XFmode);
16714 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16715 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16719 (define_expand "ilogb<mode>2"
16720 [(use (match_operand:SI 0 "register_operand" ""))
16721 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16722 "TARGET_USE_FANCY_MATH_387
16723 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16724 || TARGET_MIX_SSE_I387)
16725 && flag_unsafe_math_optimizations && !optimize_size"
16727 rtx op0 = gen_reg_rtx (XFmode);
16728 rtx op1 = gen_reg_rtx (XFmode);
16730 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16731 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16735 (define_insn "*f2xm1xf2_i387"
16736 [(set (match_operand:XF 0 "register_operand" "=f")
16737 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16739 "TARGET_USE_FANCY_MATH_387
16740 && flag_unsafe_math_optimizations"
16742 [(set_attr "type" "fpspc")
16743 (set_attr "mode" "XF")])
16745 (define_insn "*fscalexf4_i387"
16746 [(set (match_operand:XF 0 "register_operand" "=f")
16747 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16748 (match_operand:XF 3 "register_operand" "1")]
16749 UNSPEC_FSCALE_FRACT))
16750 (set (match_operand:XF 1 "register_operand" "=u")
16751 (unspec:XF [(match_dup 2) (match_dup 3)]
16752 UNSPEC_FSCALE_EXP))]
16753 "TARGET_USE_FANCY_MATH_387
16754 && flag_unsafe_math_optimizations"
16756 [(set_attr "type" "fpspc")
16757 (set_attr "mode" "XF")])
16759 (define_expand "expNcorexf3"
16760 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16761 (match_operand:XF 2 "register_operand" "")))
16762 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16763 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16764 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16765 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16766 (parallel [(set (match_operand:XF 0 "register_operand" "")
16767 (unspec:XF [(match_dup 8) (match_dup 4)]
16768 UNSPEC_FSCALE_FRACT))
16770 (unspec:XF [(match_dup 8) (match_dup 4)]
16771 UNSPEC_FSCALE_EXP))])]
16772 "TARGET_USE_FANCY_MATH_387
16773 && flag_unsafe_math_optimizations && !optimize_size"
16777 for (i = 3; i < 10; i++)
16778 operands[i] = gen_reg_rtx (XFmode);
16780 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16783 (define_expand "expxf2"
16784 [(use (match_operand:XF 0 "register_operand" ""))
16785 (use (match_operand:XF 1 "register_operand" ""))]
16786 "TARGET_USE_FANCY_MATH_387
16787 && flag_unsafe_math_optimizations && !optimize_size"
16789 rtx op2 = gen_reg_rtx (XFmode);
16790 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16792 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16796 (define_expand "exp<mode>2"
16797 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16798 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16799 "TARGET_USE_FANCY_MATH_387
16800 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16801 || TARGET_MIX_SSE_I387)
16802 && flag_unsafe_math_optimizations && !optimize_size"
16804 rtx op0 = gen_reg_rtx (XFmode);
16805 rtx op1 = gen_reg_rtx (XFmode);
16807 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16808 emit_insn (gen_expxf2 (op0, op1));
16809 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16813 (define_expand "exp10xf2"
16814 [(use (match_operand:XF 0 "register_operand" ""))
16815 (use (match_operand:XF 1 "register_operand" ""))]
16816 "TARGET_USE_FANCY_MATH_387
16817 && flag_unsafe_math_optimizations && !optimize_size"
16819 rtx op2 = gen_reg_rtx (XFmode);
16820 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16822 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16826 (define_expand "exp10<mode>2"
16827 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16828 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16829 "TARGET_USE_FANCY_MATH_387
16830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16831 || TARGET_MIX_SSE_I387)
16832 && flag_unsafe_math_optimizations && !optimize_size"
16834 rtx op0 = gen_reg_rtx (XFmode);
16835 rtx op1 = gen_reg_rtx (XFmode);
16837 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16838 emit_insn (gen_exp10xf2 (op0, op1));
16839 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16843 (define_expand "exp2xf2"
16844 [(use (match_operand:XF 0 "register_operand" ""))
16845 (use (match_operand:XF 1 "register_operand" ""))]
16846 "TARGET_USE_FANCY_MATH_387
16847 && flag_unsafe_math_optimizations && !optimize_size"
16849 rtx op2 = gen_reg_rtx (XFmode);
16850 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16852 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16856 (define_expand "exp2<mode>2"
16857 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16858 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16859 "TARGET_USE_FANCY_MATH_387
16860 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16861 || TARGET_MIX_SSE_I387)
16862 && flag_unsafe_math_optimizations && !optimize_size"
16864 rtx op0 = gen_reg_rtx (XFmode);
16865 rtx op1 = gen_reg_rtx (XFmode);
16867 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16868 emit_insn (gen_exp2xf2 (op0, op1));
16869 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16873 (define_expand "expm1xf2"
16874 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16876 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16877 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16878 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16879 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16880 (parallel [(set (match_dup 7)
16881 (unspec:XF [(match_dup 6) (match_dup 4)]
16882 UNSPEC_FSCALE_FRACT))
16884 (unspec:XF [(match_dup 6) (match_dup 4)]
16885 UNSPEC_FSCALE_EXP))])
16886 (parallel [(set (match_dup 10)
16887 (unspec:XF [(match_dup 9) (match_dup 8)]
16888 UNSPEC_FSCALE_FRACT))
16889 (set (match_dup 11)
16890 (unspec:XF [(match_dup 9) (match_dup 8)]
16891 UNSPEC_FSCALE_EXP))])
16892 (set (match_dup 12) (minus:XF (match_dup 10)
16893 (float_extend:XF (match_dup 13))))
16894 (set (match_operand:XF 0 "register_operand" "")
16895 (plus:XF (match_dup 12) (match_dup 7)))]
16896 "TARGET_USE_FANCY_MATH_387
16897 && flag_unsafe_math_optimizations && !optimize_size"
16901 for (i = 2; i < 13; i++)
16902 operands[i] = gen_reg_rtx (XFmode);
16905 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16907 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16910 (define_expand "expm1<mode>2"
16911 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16912 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16913 "TARGET_USE_FANCY_MATH_387
16914 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16915 || TARGET_MIX_SSE_I387)
16916 && flag_unsafe_math_optimizations && !optimize_size"
16918 rtx op0 = gen_reg_rtx (XFmode);
16919 rtx op1 = gen_reg_rtx (XFmode);
16921 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16922 emit_insn (gen_expm1xf2 (op0, op1));
16923 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16927 (define_expand "ldexpxf3"
16928 [(set (match_dup 3)
16929 (float:XF (match_operand:SI 2 "register_operand" "")))
16930 (parallel [(set (match_operand:XF 0 " register_operand" "")
16931 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16933 UNSPEC_FSCALE_FRACT))
16935 (unspec:XF [(match_dup 1) (match_dup 3)]
16936 UNSPEC_FSCALE_EXP))])]
16937 "TARGET_USE_FANCY_MATH_387
16938 && flag_unsafe_math_optimizations && !optimize_size"
16940 operands[3] = gen_reg_rtx (XFmode);
16941 operands[4] = gen_reg_rtx (XFmode);
16944 (define_expand "ldexp<mode>3"
16945 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16946 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16947 (use (match_operand:SI 2 "register_operand" ""))]
16948 "TARGET_USE_FANCY_MATH_387
16949 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16950 || TARGET_MIX_SSE_I387)
16951 && flag_unsafe_math_optimizations && !optimize_size"
16953 rtx op0 = gen_reg_rtx (XFmode);
16954 rtx op1 = gen_reg_rtx (XFmode);
16956 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16957 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16958 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16962 (define_expand "scalbxf3"
16963 [(parallel [(set (match_operand:XF 0 " register_operand" "")
16964 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16965 (match_operand:XF 2 "register_operand" "")]
16966 UNSPEC_FSCALE_FRACT))
16968 (unspec:XF [(match_dup 1) (match_dup 2)]
16969 UNSPEC_FSCALE_EXP))])]
16970 "TARGET_USE_FANCY_MATH_387
16971 && flag_unsafe_math_optimizations && !optimize_size"
16973 operands[3] = gen_reg_rtx (XFmode);
16976 (define_expand "scalb<mode>3"
16977 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16978 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16979 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16980 "TARGET_USE_FANCY_MATH_387
16981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16982 || TARGET_MIX_SSE_I387)
16983 && flag_unsafe_math_optimizations && !optimize_size"
16985 rtx op0 = gen_reg_rtx (XFmode);
16986 rtx op1 = gen_reg_rtx (XFmode);
16987 rtx op2 = gen_reg_rtx (XFmode);
16989 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16990 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16991 emit_insn (gen_scalbxf3 (op0, op1, op2));
16992 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16997 (define_insn "rintxf2"
16998 [(set (match_operand:XF 0 "register_operand" "=f")
16999 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17001 "TARGET_USE_FANCY_MATH_387
17002 && flag_unsafe_math_optimizations"
17004 [(set_attr "type" "fpspc")
17005 (set_attr "mode" "XF")])
17007 (define_expand "rint<mode>2"
17008 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17009 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17010 "(TARGET_USE_FANCY_MATH_387
17011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17012 || TARGET_MIX_SSE_I387)
17013 && flag_unsafe_math_optimizations)
17014 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17015 && !flag_trapping_math
17016 && !optimize_size)"
17018 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17019 && !flag_trapping_math
17021 ix86_expand_rint (operand0, operand1);
17024 rtx op0 = gen_reg_rtx (XFmode);
17025 rtx op1 = gen_reg_rtx (XFmode);
17027 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17028 emit_insn (gen_rintxf2 (op0, op1));
17030 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17035 (define_expand "round<mode>2"
17036 [(match_operand:SSEMODEF 0 "register_operand" "")
17037 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")]
17038 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17039 && !flag_trapping_math && !flag_rounding_math
17042 if ((<MODE>mode != DFmode) || TARGET_64BIT)
17043 ix86_expand_round (operand0, operand1);
17045 ix86_expand_rounddf_32 (operand0, operand1);
17049 (define_insn_and_split "*fistdi2_1"
17050 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17051 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17053 "TARGET_USE_FANCY_MATH_387
17054 && !(reload_completed || reload_in_progress)"
17059 if (memory_operand (operands[0], VOIDmode))
17060 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17063 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17064 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17069 [(set_attr "type" "fpspc")
17070 (set_attr "mode" "DI")])
17072 (define_insn "fistdi2"
17073 [(set (match_operand:DI 0 "memory_operand" "=m")
17074 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17076 (clobber (match_scratch:XF 2 "=&1f"))]
17077 "TARGET_USE_FANCY_MATH_387"
17078 "* return output_fix_trunc (insn, operands, 0);"
17079 [(set_attr "type" "fpspc")
17080 (set_attr "mode" "DI")])
17082 (define_insn "fistdi2_with_temp"
17083 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17084 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17086 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17087 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17088 "TARGET_USE_FANCY_MATH_387"
17090 [(set_attr "type" "fpspc")
17091 (set_attr "mode" "DI")])
17094 [(set (match_operand:DI 0 "register_operand" "")
17095 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17097 (clobber (match_operand:DI 2 "memory_operand" ""))
17098 (clobber (match_scratch 3 ""))]
17100 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17101 (clobber (match_dup 3))])
17102 (set (match_dup 0) (match_dup 2))]
17106 [(set (match_operand:DI 0 "memory_operand" "")
17107 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17109 (clobber (match_operand:DI 2 "memory_operand" ""))
17110 (clobber (match_scratch 3 ""))]
17112 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17113 (clobber (match_dup 3))])]
17116 (define_insn_and_split "*fist<mode>2_1"
17117 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17118 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17120 "TARGET_USE_FANCY_MATH_387
17121 && !(reload_completed || reload_in_progress)"
17126 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17127 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17131 [(set_attr "type" "fpspc")
17132 (set_attr "mode" "<MODE>")])
17134 (define_insn "fist<mode>2"
17135 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17136 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17138 "TARGET_USE_FANCY_MATH_387"
17139 "* return output_fix_trunc (insn, operands, 0);"
17140 [(set_attr "type" "fpspc")
17141 (set_attr "mode" "<MODE>")])
17143 (define_insn "fist<mode>2_with_temp"
17144 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17145 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17147 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17148 "TARGET_USE_FANCY_MATH_387"
17150 [(set_attr "type" "fpspc")
17151 (set_attr "mode" "<MODE>")])
17154 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17155 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17157 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17159 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17160 (set (match_dup 0) (match_dup 2))]
17164 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17165 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17167 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17169 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17172 (define_expand "lrintxf<mode>2"
17173 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17174 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17176 "TARGET_USE_FANCY_MATH_387"
17179 (define_expand "lrint<SSEMODEF:mode><SSEMODEI24:mode>2"
17180 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17181 (unspec:SSEMODEI24 [(match_operand:SSEMODEF 1 "register_operand" "")]
17182 UNSPEC_FIX_NOTRUNC))]
17183 "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17184 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17187 (define_expand "lround<SSEMODEF:mode><SSEMODEI24:mode>2"
17188 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17189 (match_operand:SSEMODEF 1 "register_operand" "")]
17190 "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17191 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17192 && !flag_trapping_math && !flag_rounding_math
17195 ix86_expand_lround (operand0, operand1);
17199 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17200 (define_insn_and_split "frndintxf2_floor"
17201 [(set (match_operand:XF 0 "register_operand" "=f")
17202 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17203 UNSPEC_FRNDINT_FLOOR))
17204 (clobber (reg:CC FLAGS_REG))]
17205 "TARGET_USE_FANCY_MATH_387
17206 && flag_unsafe_math_optimizations
17207 && !(reload_completed || reload_in_progress)"
17212 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17214 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17215 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17217 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17218 operands[2], operands[3]));
17221 [(set_attr "type" "frndint")
17222 (set_attr "i387_cw" "floor")
17223 (set_attr "mode" "XF")])
17225 (define_insn "frndintxf2_floor_i387"
17226 [(set (match_operand:XF 0 "register_operand" "=f")
17227 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17228 UNSPEC_FRNDINT_FLOOR))
17229 (use (match_operand:HI 2 "memory_operand" "m"))
17230 (use (match_operand:HI 3 "memory_operand" "m"))]
17231 "TARGET_USE_FANCY_MATH_387
17232 && flag_unsafe_math_optimizations"
17233 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17234 [(set_attr "type" "frndint")
17235 (set_attr "i387_cw" "floor")
17236 (set_attr "mode" "XF")])
17238 (define_expand "floorxf2"
17239 [(use (match_operand:XF 0 "register_operand" ""))
17240 (use (match_operand:XF 1 "register_operand" ""))]
17241 "TARGET_USE_FANCY_MATH_387
17242 && flag_unsafe_math_optimizations && !optimize_size"
17244 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17248 (define_expand "floordf2"
17249 [(use (match_operand:DF 0 "register_operand" ""))
17250 (use (match_operand:DF 1 "register_operand" ""))]
17251 "((TARGET_USE_FANCY_MATH_387
17252 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17253 && flag_unsafe_math_optimizations)
17254 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17255 && !flag_trapping_math))
17258 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17259 && !flag_trapping_math)
17262 ix86_expand_floorceil (operand0, operand1, true);
17264 ix86_expand_floorceildf_32 (operand0, operand1, true);
17268 rtx op0 = gen_reg_rtx (XFmode);
17269 rtx op1 = gen_reg_rtx (XFmode);
17271 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17272 emit_insn (gen_frndintxf2_floor (op0, op1));
17274 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17279 (define_expand "floorsf2"
17280 [(use (match_operand:SF 0 "register_operand" ""))
17281 (use (match_operand:SF 1 "register_operand" ""))]
17282 "((TARGET_USE_FANCY_MATH_387
17283 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17284 && flag_unsafe_math_optimizations)
17285 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17286 && !flag_trapping_math))
17289 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17290 && !flag_trapping_math)
17291 ix86_expand_floorceil (operand0, operand1, true);
17294 rtx op0 = gen_reg_rtx (XFmode);
17295 rtx op1 = gen_reg_rtx (XFmode);
17297 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17298 emit_insn (gen_frndintxf2_floor (op0, op1));
17300 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17305 (define_insn_and_split "*fist<mode>2_floor_1"
17306 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17307 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17308 UNSPEC_FIST_FLOOR))
17309 (clobber (reg:CC FLAGS_REG))]
17310 "TARGET_USE_FANCY_MATH_387
17311 && flag_unsafe_math_optimizations
17312 && !(reload_completed || reload_in_progress)"
17317 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17319 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17320 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17321 if (memory_operand (operands[0], VOIDmode))
17322 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17323 operands[2], operands[3]));
17326 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17327 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17328 operands[2], operands[3],
17333 [(set_attr "type" "fistp")
17334 (set_attr "i387_cw" "floor")
17335 (set_attr "mode" "<MODE>")])
17337 (define_insn "fistdi2_floor"
17338 [(set (match_operand:DI 0 "memory_operand" "=m")
17339 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17340 UNSPEC_FIST_FLOOR))
17341 (use (match_operand:HI 2 "memory_operand" "m"))
17342 (use (match_operand:HI 3 "memory_operand" "m"))
17343 (clobber (match_scratch:XF 4 "=&1f"))]
17344 "TARGET_USE_FANCY_MATH_387
17345 && flag_unsafe_math_optimizations"
17346 "* return output_fix_trunc (insn, operands, 0);"
17347 [(set_attr "type" "fistp")
17348 (set_attr "i387_cw" "floor")
17349 (set_attr "mode" "DI")])
17351 (define_insn "fistdi2_floor_with_temp"
17352 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17353 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17354 UNSPEC_FIST_FLOOR))
17355 (use (match_operand:HI 2 "memory_operand" "m,m"))
17356 (use (match_operand:HI 3 "memory_operand" "m,m"))
17357 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17358 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17359 "TARGET_USE_FANCY_MATH_387
17360 && flag_unsafe_math_optimizations"
17362 [(set_attr "type" "fistp")
17363 (set_attr "i387_cw" "floor")
17364 (set_attr "mode" "DI")])
17367 [(set (match_operand:DI 0 "register_operand" "")
17368 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17369 UNSPEC_FIST_FLOOR))
17370 (use (match_operand:HI 2 "memory_operand" ""))
17371 (use (match_operand:HI 3 "memory_operand" ""))
17372 (clobber (match_operand:DI 4 "memory_operand" ""))
17373 (clobber (match_scratch 5 ""))]
17375 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17376 (use (match_dup 2))
17377 (use (match_dup 3))
17378 (clobber (match_dup 5))])
17379 (set (match_dup 0) (match_dup 4))]
17383 [(set (match_operand:DI 0 "memory_operand" "")
17384 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17385 UNSPEC_FIST_FLOOR))
17386 (use (match_operand:HI 2 "memory_operand" ""))
17387 (use (match_operand:HI 3 "memory_operand" ""))
17388 (clobber (match_operand:DI 4 "memory_operand" ""))
17389 (clobber (match_scratch 5 ""))]
17391 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17392 (use (match_dup 2))
17393 (use (match_dup 3))
17394 (clobber (match_dup 5))])]
17397 (define_insn "fist<mode>2_floor"
17398 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17399 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17400 UNSPEC_FIST_FLOOR))
17401 (use (match_operand:HI 2 "memory_operand" "m"))
17402 (use (match_operand:HI 3 "memory_operand" "m"))]
17403 "TARGET_USE_FANCY_MATH_387
17404 && flag_unsafe_math_optimizations"
17405 "* return output_fix_trunc (insn, operands, 0);"
17406 [(set_attr "type" "fistp")
17407 (set_attr "i387_cw" "floor")
17408 (set_attr "mode" "<MODE>")])
17410 (define_insn "fist<mode>2_floor_with_temp"
17411 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17412 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17413 UNSPEC_FIST_FLOOR))
17414 (use (match_operand:HI 2 "memory_operand" "m,m"))
17415 (use (match_operand:HI 3 "memory_operand" "m,m"))
17416 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17417 "TARGET_USE_FANCY_MATH_387
17418 && flag_unsafe_math_optimizations"
17420 [(set_attr "type" "fistp")
17421 (set_attr "i387_cw" "floor")
17422 (set_attr "mode" "<MODE>")])
17425 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17426 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17427 UNSPEC_FIST_FLOOR))
17428 (use (match_operand:HI 2 "memory_operand" ""))
17429 (use (match_operand:HI 3 "memory_operand" ""))
17430 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17432 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17433 UNSPEC_FIST_FLOOR))
17434 (use (match_dup 2))
17435 (use (match_dup 3))])
17436 (set (match_dup 0) (match_dup 4))]
17440 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17441 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17442 UNSPEC_FIST_FLOOR))
17443 (use (match_operand:HI 2 "memory_operand" ""))
17444 (use (match_operand:HI 3 "memory_operand" ""))
17445 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17447 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17448 UNSPEC_FIST_FLOOR))
17449 (use (match_dup 2))
17450 (use (match_dup 3))])]
17453 (define_expand "lfloorxf<mode>2"
17454 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17455 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17456 UNSPEC_FIST_FLOOR))
17457 (clobber (reg:CC FLAGS_REG))])]
17458 "TARGET_USE_FANCY_MATH_387
17459 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17460 && flag_unsafe_math_optimizations"
17463 (define_expand "lfloor<mode>di2"
17464 [(match_operand:DI 0 "nonimmediate_operand" "")
17465 (match_operand:SSEMODEF 1 "register_operand" "")]
17466 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17467 && !flag_trapping_math
17470 ix86_expand_lfloorceil (operand0, operand1, true);
17474 (define_expand "lfloor<mode>si2"
17475 [(match_operand:SI 0 "nonimmediate_operand" "")
17476 (match_operand:SSEMODEF 1 "register_operand" "")]
17477 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17478 && !flag_trapping_math
17479 && (!optimize_size || !TARGET_64BIT)"
17481 ix86_expand_lfloorceil (operand0, operand1, true);
17485 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17486 (define_insn_and_split "frndintxf2_ceil"
17487 [(set (match_operand:XF 0 "register_operand" "=f")
17488 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17489 UNSPEC_FRNDINT_CEIL))
17490 (clobber (reg:CC FLAGS_REG))]
17491 "TARGET_USE_FANCY_MATH_387
17492 && flag_unsafe_math_optimizations
17493 && !(reload_completed || reload_in_progress)"
17498 ix86_optimize_mode_switching[I387_CEIL] = 1;
17500 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17501 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17503 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17504 operands[2], operands[3]));
17507 [(set_attr "type" "frndint")
17508 (set_attr "i387_cw" "ceil")
17509 (set_attr "mode" "XF")])
17511 (define_insn "frndintxf2_ceil_i387"
17512 [(set (match_operand:XF 0 "register_operand" "=f")
17513 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17514 UNSPEC_FRNDINT_CEIL))
17515 (use (match_operand:HI 2 "memory_operand" "m"))
17516 (use (match_operand:HI 3 "memory_operand" "m"))]
17517 "TARGET_USE_FANCY_MATH_387
17518 && flag_unsafe_math_optimizations"
17519 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17520 [(set_attr "type" "frndint")
17521 (set_attr "i387_cw" "ceil")
17522 (set_attr "mode" "XF")])
17524 (define_expand "ceilxf2"
17525 [(use (match_operand:XF 0 "register_operand" ""))
17526 (use (match_operand:XF 1 "register_operand" ""))]
17527 "TARGET_USE_FANCY_MATH_387
17528 && flag_unsafe_math_optimizations && !optimize_size"
17530 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17534 (define_expand "ceildf2"
17535 [(use (match_operand:DF 0 "register_operand" ""))
17536 (use (match_operand:DF 1 "register_operand" ""))]
17537 "((TARGET_USE_FANCY_MATH_387
17538 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17539 && flag_unsafe_math_optimizations)
17540 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17541 && !flag_trapping_math))
17544 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17545 && !flag_trapping_math)
17548 ix86_expand_floorceil (operand0, operand1, false);
17550 ix86_expand_floorceildf_32 (operand0, operand1, false);
17554 rtx op0 = gen_reg_rtx (XFmode);
17555 rtx op1 = gen_reg_rtx (XFmode);
17557 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17558 emit_insn (gen_frndintxf2_ceil (op0, op1));
17560 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17565 (define_expand "ceilsf2"
17566 [(use (match_operand:SF 0 "register_operand" ""))
17567 (use (match_operand:SF 1 "register_operand" ""))]
17568 "((TARGET_USE_FANCY_MATH_387
17569 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17570 && flag_unsafe_math_optimizations)
17571 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17572 && !flag_trapping_math))
17575 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17576 && !flag_trapping_math)
17577 ix86_expand_floorceil (operand0, operand1, false);
17580 rtx op0 = gen_reg_rtx (XFmode);
17581 rtx op1 = gen_reg_rtx (XFmode);
17583 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17584 emit_insn (gen_frndintxf2_ceil (op0, op1));
17586 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17591 (define_insn_and_split "*fist<mode>2_ceil_1"
17592 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17593 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17595 (clobber (reg:CC FLAGS_REG))]
17596 "TARGET_USE_FANCY_MATH_387
17597 && flag_unsafe_math_optimizations
17598 && !(reload_completed || reload_in_progress)"
17603 ix86_optimize_mode_switching[I387_CEIL] = 1;
17605 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17606 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17607 if (memory_operand (operands[0], VOIDmode))
17608 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17609 operands[2], operands[3]));
17612 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17613 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17614 operands[2], operands[3],
17619 [(set_attr "type" "fistp")
17620 (set_attr "i387_cw" "ceil")
17621 (set_attr "mode" "<MODE>")])
17623 (define_insn "fistdi2_ceil"
17624 [(set (match_operand:DI 0 "memory_operand" "=m")
17625 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17627 (use (match_operand:HI 2 "memory_operand" "m"))
17628 (use (match_operand:HI 3 "memory_operand" "m"))
17629 (clobber (match_scratch:XF 4 "=&1f"))]
17630 "TARGET_USE_FANCY_MATH_387
17631 && flag_unsafe_math_optimizations"
17632 "* return output_fix_trunc (insn, operands, 0);"
17633 [(set_attr "type" "fistp")
17634 (set_attr "i387_cw" "ceil")
17635 (set_attr "mode" "DI")])
17637 (define_insn "fistdi2_ceil_with_temp"
17638 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17639 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17641 (use (match_operand:HI 2 "memory_operand" "m,m"))
17642 (use (match_operand:HI 3 "memory_operand" "m,m"))
17643 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17644 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17645 "TARGET_USE_FANCY_MATH_387
17646 && flag_unsafe_math_optimizations"
17648 [(set_attr "type" "fistp")
17649 (set_attr "i387_cw" "ceil")
17650 (set_attr "mode" "DI")])
17653 [(set (match_operand:DI 0 "register_operand" "")
17654 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17656 (use (match_operand:HI 2 "memory_operand" ""))
17657 (use (match_operand:HI 3 "memory_operand" ""))
17658 (clobber (match_operand:DI 4 "memory_operand" ""))
17659 (clobber (match_scratch 5 ""))]
17661 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17662 (use (match_dup 2))
17663 (use (match_dup 3))
17664 (clobber (match_dup 5))])
17665 (set (match_dup 0) (match_dup 4))]
17669 [(set (match_operand:DI 0 "memory_operand" "")
17670 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17672 (use (match_operand:HI 2 "memory_operand" ""))
17673 (use (match_operand:HI 3 "memory_operand" ""))
17674 (clobber (match_operand:DI 4 "memory_operand" ""))
17675 (clobber (match_scratch 5 ""))]
17677 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17678 (use (match_dup 2))
17679 (use (match_dup 3))
17680 (clobber (match_dup 5))])]
17683 (define_insn "fist<mode>2_ceil"
17684 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17685 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17687 (use (match_operand:HI 2 "memory_operand" "m"))
17688 (use (match_operand:HI 3 "memory_operand" "m"))]
17689 "TARGET_USE_FANCY_MATH_387
17690 && flag_unsafe_math_optimizations"
17691 "* return output_fix_trunc (insn, operands, 0);"
17692 [(set_attr "type" "fistp")
17693 (set_attr "i387_cw" "ceil")
17694 (set_attr "mode" "<MODE>")])
17696 (define_insn "fist<mode>2_ceil_with_temp"
17697 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17698 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17700 (use (match_operand:HI 2 "memory_operand" "m,m"))
17701 (use (match_operand:HI 3 "memory_operand" "m,m"))
17702 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17703 "TARGET_USE_FANCY_MATH_387
17704 && flag_unsafe_math_optimizations"
17706 [(set_attr "type" "fistp")
17707 (set_attr "i387_cw" "ceil")
17708 (set_attr "mode" "<MODE>")])
17711 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17712 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17714 (use (match_operand:HI 2 "memory_operand" ""))
17715 (use (match_operand:HI 3 "memory_operand" ""))
17716 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17718 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17720 (use (match_dup 2))
17721 (use (match_dup 3))])
17722 (set (match_dup 0) (match_dup 4))]
17726 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17727 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17729 (use (match_operand:HI 2 "memory_operand" ""))
17730 (use (match_operand:HI 3 "memory_operand" ""))
17731 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17733 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17735 (use (match_dup 2))
17736 (use (match_dup 3))])]
17739 (define_expand "lceilxf<mode>2"
17740 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17741 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17743 (clobber (reg:CC FLAGS_REG))])]
17744 "TARGET_USE_FANCY_MATH_387
17745 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17746 && flag_unsafe_math_optimizations"
17749 (define_expand "lceil<mode>di2"
17750 [(match_operand:DI 0 "nonimmediate_operand" "")
17751 (match_operand:SSEMODEF 1 "register_operand" "")]
17752 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17753 && !flag_trapping_math"
17755 ix86_expand_lfloorceil (operand0, operand1, false);
17759 (define_expand "lceil<mode>si2"
17760 [(match_operand:SI 0 "nonimmediate_operand" "")
17761 (match_operand:SSEMODEF 1 "register_operand" "")]
17762 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17763 && !flag_trapping_math"
17765 ix86_expand_lfloorceil (operand0, operand1, false);
17769 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17770 (define_insn_and_split "frndintxf2_trunc"
17771 [(set (match_operand:XF 0 "register_operand" "=f")
17772 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17773 UNSPEC_FRNDINT_TRUNC))
17774 (clobber (reg:CC FLAGS_REG))]
17775 "TARGET_USE_FANCY_MATH_387
17776 && flag_unsafe_math_optimizations
17777 && !(reload_completed || reload_in_progress)"
17782 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17784 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17785 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17787 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17788 operands[2], operands[3]));
17791 [(set_attr "type" "frndint")
17792 (set_attr "i387_cw" "trunc")
17793 (set_attr "mode" "XF")])
17795 (define_insn "frndintxf2_trunc_i387"
17796 [(set (match_operand:XF 0 "register_operand" "=f")
17797 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17798 UNSPEC_FRNDINT_TRUNC))
17799 (use (match_operand:HI 2 "memory_operand" "m"))
17800 (use (match_operand:HI 3 "memory_operand" "m"))]
17801 "TARGET_USE_FANCY_MATH_387
17802 && flag_unsafe_math_optimizations"
17803 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17804 [(set_attr "type" "frndint")
17805 (set_attr "i387_cw" "trunc")
17806 (set_attr "mode" "XF")])
17808 (define_expand "btruncxf2"
17809 [(use (match_operand:XF 0 "register_operand" ""))
17810 (use (match_operand:XF 1 "register_operand" ""))]
17811 "TARGET_USE_FANCY_MATH_387
17812 && flag_unsafe_math_optimizations && !optimize_size"
17814 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17818 (define_expand "btruncdf2"
17819 [(use (match_operand:DF 0 "register_operand" ""))
17820 (use (match_operand:DF 1 "register_operand" ""))]
17821 "((TARGET_USE_FANCY_MATH_387
17822 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17823 && flag_unsafe_math_optimizations)
17824 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17825 && !flag_trapping_math))
17828 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17829 && !flag_trapping_math)
17832 ix86_expand_trunc (operand0, operand1);
17834 ix86_expand_truncdf_32 (operand0, operand1);
17838 rtx op0 = gen_reg_rtx (XFmode);
17839 rtx op1 = gen_reg_rtx (XFmode);
17841 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17842 emit_insn (gen_frndintxf2_trunc (op0, op1));
17844 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17849 (define_expand "btruncsf2"
17850 [(use (match_operand:SF 0 "register_operand" ""))
17851 (use (match_operand:SF 1 "register_operand" ""))]
17852 "((TARGET_USE_FANCY_MATH_387
17853 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17854 && flag_unsafe_math_optimizations)
17855 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17856 && !flag_trapping_math))
17859 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17860 && !flag_trapping_math)
17861 ix86_expand_trunc (operand0, operand1);
17864 rtx op0 = gen_reg_rtx (XFmode);
17865 rtx op1 = gen_reg_rtx (XFmode);
17867 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17868 emit_insn (gen_frndintxf2_trunc (op0, op1));
17870 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17875 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17876 (define_insn_and_split "frndintxf2_mask_pm"
17877 [(set (match_operand:XF 0 "register_operand" "=f")
17878 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17879 UNSPEC_FRNDINT_MASK_PM))
17880 (clobber (reg:CC FLAGS_REG))]
17881 "TARGET_USE_FANCY_MATH_387
17882 && flag_unsafe_math_optimizations
17883 && !(reload_completed || reload_in_progress)"
17888 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17890 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17891 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17893 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17894 operands[2], operands[3]));
17897 [(set_attr "type" "frndint")
17898 (set_attr "i387_cw" "mask_pm")
17899 (set_attr "mode" "XF")])
17901 (define_insn "frndintxf2_mask_pm_i387"
17902 [(set (match_operand:XF 0 "register_operand" "=f")
17903 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17904 UNSPEC_FRNDINT_MASK_PM))
17905 (use (match_operand:HI 2 "memory_operand" "m"))
17906 (use (match_operand:HI 3 "memory_operand" "m"))]
17907 "TARGET_USE_FANCY_MATH_387
17908 && flag_unsafe_math_optimizations"
17909 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17910 [(set_attr "type" "frndint")
17911 (set_attr "i387_cw" "mask_pm")
17912 (set_attr "mode" "XF")])
17914 (define_expand "nearbyintxf2"
17915 [(use (match_operand:XF 0 "register_operand" ""))
17916 (use (match_operand:XF 1 "register_operand" ""))]
17917 "TARGET_USE_FANCY_MATH_387
17918 && flag_unsafe_math_optimizations"
17920 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17925 (define_expand "nearbyintdf2"
17926 [(use (match_operand:DF 0 "register_operand" ""))
17927 (use (match_operand:DF 1 "register_operand" ""))]
17928 "TARGET_USE_FANCY_MATH_387
17929 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17930 && flag_unsafe_math_optimizations"
17932 rtx op0 = gen_reg_rtx (XFmode);
17933 rtx op1 = gen_reg_rtx (XFmode);
17935 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17936 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17938 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17942 (define_expand "nearbyintsf2"
17943 [(use (match_operand:SF 0 "register_operand" ""))
17944 (use (match_operand:SF 1 "register_operand" ""))]
17945 "TARGET_USE_FANCY_MATH_387
17946 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17947 && flag_unsafe_math_optimizations"
17949 rtx op0 = gen_reg_rtx (XFmode);
17950 rtx op1 = gen_reg_rtx (XFmode);
17952 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17953 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17955 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17959 (define_insn "fxam<mode>2_i387"
17960 [(set (match_operand:HI 0 "register_operand" "=a")
17962 [(match_operand:X87MODEF 1 "register_operand" "f")]
17964 "TARGET_USE_FANCY_MATH_387"
17965 "fxam\n\tfnstsw\t%0"
17966 [(set_attr "type" "multi")
17967 (set_attr "unit" "i387")
17968 (set_attr "mode" "<MODE>")])
17970 (define_expand "isinf<mode>2"
17971 [(use (match_operand:SI 0 "register_operand" ""))
17972 (use (match_operand:X87MODEF 1 "register_operand" ""))]
17973 "TARGET_USE_FANCY_MATH_387
17974 && TARGET_C99_FUNCTIONS
17975 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17976 || TARGET_MIX_SSE_I387)"
17978 rtx mask = GEN_INT (0x45);
17979 rtx val = GEN_INT (0x05);
17983 rtx scratch = gen_reg_rtx (HImode);
17984 rtx res = gen_reg_rtx (QImode);
17986 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17987 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17988 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17989 cond = gen_rtx_fmt_ee (EQ, QImode,
17990 gen_rtx_REG (CCmode, FLAGS_REG),
17992 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17993 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17998 ;; Block operation instructions
18000 (define_expand "movmemsi"
18001 [(use (match_operand:BLK 0 "memory_operand" ""))
18002 (use (match_operand:BLK 1 "memory_operand" ""))
18003 (use (match_operand:SI 2 "nonmemory_operand" ""))
18004 (use (match_operand:SI 3 "const_int_operand" ""))
18005 (use (match_operand:SI 4 "const_int_operand" ""))
18006 (use (match_operand:SI 5 "const_int_operand" ""))]
18009 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18010 operands[4], operands[5]))
18016 (define_expand "movmemdi"
18017 [(use (match_operand:BLK 0 "memory_operand" ""))
18018 (use (match_operand:BLK 1 "memory_operand" ""))
18019 (use (match_operand:DI 2 "nonmemory_operand" ""))
18020 (use (match_operand:DI 3 "const_int_operand" ""))
18021 (use (match_operand:SI 4 "const_int_operand" ""))
18022 (use (match_operand:SI 5 "const_int_operand" ""))]
18025 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18026 operands[4], operands[5]))
18032 ;; Most CPUs don't like single string operations
18033 ;; Handle this case here to simplify previous expander.
18035 (define_expand "strmov"
18036 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18037 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18038 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18039 (clobber (reg:CC FLAGS_REG))])
18040 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18041 (clobber (reg:CC FLAGS_REG))])]
18044 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18046 /* If .md ever supports :P for Pmode, these can be directly
18047 in the pattern above. */
18048 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18049 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18051 if (TARGET_SINGLE_STRINGOP || optimize_size)
18053 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18054 operands[2], operands[3],
18055 operands[5], operands[6]));
18059 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18062 (define_expand "strmov_singleop"
18063 [(parallel [(set (match_operand 1 "memory_operand" "")
18064 (match_operand 3 "memory_operand" ""))
18065 (set (match_operand 0 "register_operand" "")
18066 (match_operand 4 "" ""))
18067 (set (match_operand 2 "register_operand" "")
18068 (match_operand 5 "" ""))])]
18069 "TARGET_SINGLE_STRINGOP || optimize_size"
18072 (define_insn "*strmovdi_rex_1"
18073 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18074 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18075 (set (match_operand:DI 0 "register_operand" "=D")
18076 (plus:DI (match_dup 2)
18078 (set (match_operand:DI 1 "register_operand" "=S")
18079 (plus:DI (match_dup 3)
18081 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18083 [(set_attr "type" "str")
18084 (set_attr "mode" "DI")
18085 (set_attr "memory" "both")])
18087 (define_insn "*strmovsi_1"
18088 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18089 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18090 (set (match_operand:SI 0 "register_operand" "=D")
18091 (plus:SI (match_dup 2)
18093 (set (match_operand:SI 1 "register_operand" "=S")
18094 (plus:SI (match_dup 3)
18096 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18098 [(set_attr "type" "str")
18099 (set_attr "mode" "SI")
18100 (set_attr "memory" "both")])
18102 (define_insn "*strmovsi_rex_1"
18103 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18104 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18105 (set (match_operand:DI 0 "register_operand" "=D")
18106 (plus:DI (match_dup 2)
18108 (set (match_operand:DI 1 "register_operand" "=S")
18109 (plus:DI (match_dup 3)
18111 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18113 [(set_attr "type" "str")
18114 (set_attr "mode" "SI")
18115 (set_attr "memory" "both")])
18117 (define_insn "*strmovhi_1"
18118 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18119 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18120 (set (match_operand:SI 0 "register_operand" "=D")
18121 (plus:SI (match_dup 2)
18123 (set (match_operand:SI 1 "register_operand" "=S")
18124 (plus:SI (match_dup 3)
18126 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18128 [(set_attr "type" "str")
18129 (set_attr "memory" "both")
18130 (set_attr "mode" "HI")])
18132 (define_insn "*strmovhi_rex_1"
18133 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18134 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18135 (set (match_operand:DI 0 "register_operand" "=D")
18136 (plus:DI (match_dup 2)
18138 (set (match_operand:DI 1 "register_operand" "=S")
18139 (plus:DI (match_dup 3)
18141 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18143 [(set_attr "type" "str")
18144 (set_attr "memory" "both")
18145 (set_attr "mode" "HI")])
18147 (define_insn "*strmovqi_1"
18148 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18149 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18150 (set (match_operand:SI 0 "register_operand" "=D")
18151 (plus:SI (match_dup 2)
18153 (set (match_operand:SI 1 "register_operand" "=S")
18154 (plus:SI (match_dup 3)
18156 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18158 [(set_attr "type" "str")
18159 (set_attr "memory" "both")
18160 (set_attr "mode" "QI")])
18162 (define_insn "*strmovqi_rex_1"
18163 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18164 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18165 (set (match_operand:DI 0 "register_operand" "=D")
18166 (plus:DI (match_dup 2)
18168 (set (match_operand:DI 1 "register_operand" "=S")
18169 (plus:DI (match_dup 3)
18171 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18173 [(set_attr "type" "str")
18174 (set_attr "memory" "both")
18175 (set_attr "mode" "QI")])
18177 (define_expand "rep_mov"
18178 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18179 (set (match_operand 0 "register_operand" "")
18180 (match_operand 5 "" ""))
18181 (set (match_operand 2 "register_operand" "")
18182 (match_operand 6 "" ""))
18183 (set (match_operand 1 "memory_operand" "")
18184 (match_operand 3 "memory_operand" ""))
18185 (use (match_dup 4))])]
18189 (define_insn "*rep_movdi_rex64"
18190 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18191 (set (match_operand:DI 0 "register_operand" "=D")
18192 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18194 (match_operand:DI 3 "register_operand" "0")))
18195 (set (match_operand:DI 1 "register_operand" "=S")
18196 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18197 (match_operand:DI 4 "register_operand" "1")))
18198 (set (mem:BLK (match_dup 3))
18199 (mem:BLK (match_dup 4)))
18200 (use (match_dup 5))]
18202 "{rep\;movsq|rep movsq}"
18203 [(set_attr "type" "str")
18204 (set_attr "prefix_rep" "1")
18205 (set_attr "memory" "both")
18206 (set_attr "mode" "DI")])
18208 (define_insn "*rep_movsi"
18209 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18210 (set (match_operand:SI 0 "register_operand" "=D")
18211 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18213 (match_operand:SI 3 "register_operand" "0")))
18214 (set (match_operand:SI 1 "register_operand" "=S")
18215 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18216 (match_operand:SI 4 "register_operand" "1")))
18217 (set (mem:BLK (match_dup 3))
18218 (mem:BLK (match_dup 4)))
18219 (use (match_dup 5))]
18221 "{rep\;movsl|rep movsd}"
18222 [(set_attr "type" "str")
18223 (set_attr "prefix_rep" "1")
18224 (set_attr "memory" "both")
18225 (set_attr "mode" "SI")])
18227 (define_insn "*rep_movsi_rex64"
18228 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18229 (set (match_operand:DI 0 "register_operand" "=D")
18230 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18232 (match_operand:DI 3 "register_operand" "0")))
18233 (set (match_operand:DI 1 "register_operand" "=S")
18234 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18235 (match_operand:DI 4 "register_operand" "1")))
18236 (set (mem:BLK (match_dup 3))
18237 (mem:BLK (match_dup 4)))
18238 (use (match_dup 5))]
18240 "{rep\;movsl|rep movsd}"
18241 [(set_attr "type" "str")
18242 (set_attr "prefix_rep" "1")
18243 (set_attr "memory" "both")
18244 (set_attr "mode" "SI")])
18246 (define_insn "*rep_movqi"
18247 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18248 (set (match_operand:SI 0 "register_operand" "=D")
18249 (plus:SI (match_operand:SI 3 "register_operand" "0")
18250 (match_operand:SI 5 "register_operand" "2")))
18251 (set (match_operand:SI 1 "register_operand" "=S")
18252 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18253 (set (mem:BLK (match_dup 3))
18254 (mem:BLK (match_dup 4)))
18255 (use (match_dup 5))]
18257 "{rep\;movsb|rep movsb}"
18258 [(set_attr "type" "str")
18259 (set_attr "prefix_rep" "1")
18260 (set_attr "memory" "both")
18261 (set_attr "mode" "SI")])
18263 (define_insn "*rep_movqi_rex64"
18264 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18265 (set (match_operand:DI 0 "register_operand" "=D")
18266 (plus:DI (match_operand:DI 3 "register_operand" "0")
18267 (match_operand:DI 5 "register_operand" "2")))
18268 (set (match_operand:DI 1 "register_operand" "=S")
18269 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18270 (set (mem:BLK (match_dup 3))
18271 (mem:BLK (match_dup 4)))
18272 (use (match_dup 5))]
18274 "{rep\;movsb|rep movsb}"
18275 [(set_attr "type" "str")
18276 (set_attr "prefix_rep" "1")
18277 (set_attr "memory" "both")
18278 (set_attr "mode" "SI")])
18280 (define_expand "setmemsi"
18281 [(use (match_operand:BLK 0 "memory_operand" ""))
18282 (use (match_operand:SI 1 "nonmemory_operand" ""))
18283 (use (match_operand 2 "const_int_operand" ""))
18284 (use (match_operand 3 "const_int_operand" ""))
18285 (use (match_operand:SI 4 "const_int_operand" ""))
18286 (use (match_operand:SI 5 "const_int_operand" ""))]
18289 if (ix86_expand_setmem (operands[0], operands[1],
18290 operands[2], operands[3],
18291 operands[4], operands[5]))
18297 (define_expand "setmemdi"
18298 [(use (match_operand:BLK 0 "memory_operand" ""))
18299 (use (match_operand:DI 1 "nonmemory_operand" ""))
18300 (use (match_operand 2 "const_int_operand" ""))
18301 (use (match_operand 3 "const_int_operand" ""))
18302 (use (match_operand 4 "const_int_operand" ""))
18303 (use (match_operand 5 "const_int_operand" ""))]
18306 if (ix86_expand_setmem (operands[0], operands[1],
18307 operands[2], operands[3],
18308 operands[4], operands[5]))
18314 ;; Most CPUs don't like single string operations
18315 ;; Handle this case here to simplify previous expander.
18317 (define_expand "strset"
18318 [(set (match_operand 1 "memory_operand" "")
18319 (match_operand 2 "register_operand" ""))
18320 (parallel [(set (match_operand 0 "register_operand" "")
18322 (clobber (reg:CC FLAGS_REG))])]
18325 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18326 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18328 /* If .md ever supports :P for Pmode, this can be directly
18329 in the pattern above. */
18330 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18331 GEN_INT (GET_MODE_SIZE (GET_MODE
18333 if (TARGET_SINGLE_STRINGOP || optimize_size)
18335 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18341 (define_expand "strset_singleop"
18342 [(parallel [(set (match_operand 1 "memory_operand" "")
18343 (match_operand 2 "register_operand" ""))
18344 (set (match_operand 0 "register_operand" "")
18345 (match_operand 3 "" ""))])]
18346 "TARGET_SINGLE_STRINGOP || optimize_size"
18349 (define_insn "*strsetdi_rex_1"
18350 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18351 (match_operand:DI 2 "register_operand" "a"))
18352 (set (match_operand:DI 0 "register_operand" "=D")
18353 (plus:DI (match_dup 1)
18355 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18357 [(set_attr "type" "str")
18358 (set_attr "memory" "store")
18359 (set_attr "mode" "DI")])
18361 (define_insn "*strsetsi_1"
18362 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18363 (match_operand:SI 2 "register_operand" "a"))
18364 (set (match_operand:SI 0 "register_operand" "=D")
18365 (plus:SI (match_dup 1)
18367 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18369 [(set_attr "type" "str")
18370 (set_attr "memory" "store")
18371 (set_attr "mode" "SI")])
18373 (define_insn "*strsetsi_rex_1"
18374 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18375 (match_operand:SI 2 "register_operand" "a"))
18376 (set (match_operand:DI 0 "register_operand" "=D")
18377 (plus:DI (match_dup 1)
18379 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18381 [(set_attr "type" "str")
18382 (set_attr "memory" "store")
18383 (set_attr "mode" "SI")])
18385 (define_insn "*strsethi_1"
18386 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18387 (match_operand:HI 2 "register_operand" "a"))
18388 (set (match_operand:SI 0 "register_operand" "=D")
18389 (plus:SI (match_dup 1)
18391 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18393 [(set_attr "type" "str")
18394 (set_attr "memory" "store")
18395 (set_attr "mode" "HI")])
18397 (define_insn "*strsethi_rex_1"
18398 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18399 (match_operand:HI 2 "register_operand" "a"))
18400 (set (match_operand:DI 0 "register_operand" "=D")
18401 (plus:DI (match_dup 1)
18403 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18405 [(set_attr "type" "str")
18406 (set_attr "memory" "store")
18407 (set_attr "mode" "HI")])
18409 (define_insn "*strsetqi_1"
18410 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18411 (match_operand:QI 2 "register_operand" "a"))
18412 (set (match_operand:SI 0 "register_operand" "=D")
18413 (plus:SI (match_dup 1)
18415 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18417 [(set_attr "type" "str")
18418 (set_attr "memory" "store")
18419 (set_attr "mode" "QI")])
18421 (define_insn "*strsetqi_rex_1"
18422 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18423 (match_operand:QI 2 "register_operand" "a"))
18424 (set (match_operand:DI 0 "register_operand" "=D")
18425 (plus:DI (match_dup 1)
18427 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18429 [(set_attr "type" "str")
18430 (set_attr "memory" "store")
18431 (set_attr "mode" "QI")])
18433 (define_expand "rep_stos"
18434 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18435 (set (match_operand 0 "register_operand" "")
18436 (match_operand 4 "" ""))
18437 (set (match_operand 2 "memory_operand" "") (const_int 0))
18438 (use (match_operand 3 "register_operand" ""))
18439 (use (match_dup 1))])]
18443 (define_insn "*rep_stosdi_rex64"
18444 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18445 (set (match_operand:DI 0 "register_operand" "=D")
18446 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18448 (match_operand:DI 3 "register_operand" "0")))
18449 (set (mem:BLK (match_dup 3))
18451 (use (match_operand:DI 2 "register_operand" "a"))
18452 (use (match_dup 4))]
18454 "{rep\;stosq|rep stosq}"
18455 [(set_attr "type" "str")
18456 (set_attr "prefix_rep" "1")
18457 (set_attr "memory" "store")
18458 (set_attr "mode" "DI")])
18460 (define_insn "*rep_stossi"
18461 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18462 (set (match_operand:SI 0 "register_operand" "=D")
18463 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18465 (match_operand:SI 3 "register_operand" "0")))
18466 (set (mem:BLK (match_dup 3))
18468 (use (match_operand:SI 2 "register_operand" "a"))
18469 (use (match_dup 4))]
18471 "{rep\;stosl|rep stosd}"
18472 [(set_attr "type" "str")
18473 (set_attr "prefix_rep" "1")
18474 (set_attr "memory" "store")
18475 (set_attr "mode" "SI")])
18477 (define_insn "*rep_stossi_rex64"
18478 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18479 (set (match_operand:DI 0 "register_operand" "=D")
18480 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18482 (match_operand:DI 3 "register_operand" "0")))
18483 (set (mem:BLK (match_dup 3))
18485 (use (match_operand:SI 2 "register_operand" "a"))
18486 (use (match_dup 4))]
18488 "{rep\;stosl|rep stosd}"
18489 [(set_attr "type" "str")
18490 (set_attr "prefix_rep" "1")
18491 (set_attr "memory" "store")
18492 (set_attr "mode" "SI")])
18494 (define_insn "*rep_stosqi"
18495 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18496 (set (match_operand:SI 0 "register_operand" "=D")
18497 (plus:SI (match_operand:SI 3 "register_operand" "0")
18498 (match_operand:SI 4 "register_operand" "1")))
18499 (set (mem:BLK (match_dup 3))
18501 (use (match_operand:QI 2 "register_operand" "a"))
18502 (use (match_dup 4))]
18504 "{rep\;stosb|rep stosb}"
18505 [(set_attr "type" "str")
18506 (set_attr "prefix_rep" "1")
18507 (set_attr "memory" "store")
18508 (set_attr "mode" "QI")])
18510 (define_insn "*rep_stosqi_rex64"
18511 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18512 (set (match_operand:DI 0 "register_operand" "=D")
18513 (plus:DI (match_operand:DI 3 "register_operand" "0")
18514 (match_operand:DI 4 "register_operand" "1")))
18515 (set (mem:BLK (match_dup 3))
18517 (use (match_operand:QI 2 "register_operand" "a"))
18518 (use (match_dup 4))]
18520 "{rep\;stosb|rep stosb}"
18521 [(set_attr "type" "str")
18522 (set_attr "prefix_rep" "1")
18523 (set_attr "memory" "store")
18524 (set_attr "mode" "QI")])
18526 (define_expand "cmpstrnsi"
18527 [(set (match_operand:SI 0 "register_operand" "")
18528 (compare:SI (match_operand:BLK 1 "general_operand" "")
18529 (match_operand:BLK 2 "general_operand" "")))
18530 (use (match_operand 3 "general_operand" ""))
18531 (use (match_operand 4 "immediate_operand" ""))]
18532 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18534 rtx addr1, addr2, out, outlow, count, countreg, align;
18536 /* Can't use this if the user has appropriated esi or edi. */
18537 if (global_regs[4] || global_regs[5])
18542 out = gen_reg_rtx (SImode);
18544 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18545 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18546 if (addr1 != XEXP (operands[1], 0))
18547 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18548 if (addr2 != XEXP (operands[2], 0))
18549 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18551 count = operands[3];
18552 countreg = ix86_zero_extend_to_Pmode (count);
18554 /* %%% Iff we are testing strict equality, we can use known alignment
18555 to good advantage. This may be possible with combine, particularly
18556 once cc0 is dead. */
18557 align = operands[4];
18559 if (CONST_INT_P (count))
18561 if (INTVAL (count) == 0)
18563 emit_move_insn (operands[0], const0_rtx);
18566 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18567 operands[1], operands[2]));
18572 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18574 emit_insn (gen_cmpsi_1 (countreg, countreg));
18575 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18576 operands[1], operands[2]));
18579 outlow = gen_lowpart (QImode, out);
18580 emit_insn (gen_cmpintqi (outlow));
18581 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18583 if (operands[0] != out)
18584 emit_move_insn (operands[0], out);
18589 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18591 (define_expand "cmpintqi"
18592 [(set (match_dup 1)
18593 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18595 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18596 (parallel [(set (match_operand:QI 0 "register_operand" "")
18597 (minus:QI (match_dup 1)
18599 (clobber (reg:CC FLAGS_REG))])]
18601 "operands[1] = gen_reg_rtx (QImode);
18602 operands[2] = gen_reg_rtx (QImode);")
18604 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18605 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18607 (define_expand "cmpstrnqi_nz_1"
18608 [(parallel [(set (reg:CC FLAGS_REG)
18609 (compare:CC (match_operand 4 "memory_operand" "")
18610 (match_operand 5 "memory_operand" "")))
18611 (use (match_operand 2 "register_operand" ""))
18612 (use (match_operand:SI 3 "immediate_operand" ""))
18613 (clobber (match_operand 0 "register_operand" ""))
18614 (clobber (match_operand 1 "register_operand" ""))
18615 (clobber (match_dup 2))])]
18619 (define_insn "*cmpstrnqi_nz_1"
18620 [(set (reg:CC FLAGS_REG)
18621 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18622 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18623 (use (match_operand:SI 6 "register_operand" "2"))
18624 (use (match_operand:SI 3 "immediate_operand" "i"))
18625 (clobber (match_operand:SI 0 "register_operand" "=S"))
18626 (clobber (match_operand:SI 1 "register_operand" "=D"))
18627 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18630 [(set_attr "type" "str")
18631 (set_attr "mode" "QI")
18632 (set_attr "prefix_rep" "1")])
18634 (define_insn "*cmpstrnqi_nz_rex_1"
18635 [(set (reg:CC FLAGS_REG)
18636 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18637 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18638 (use (match_operand:DI 6 "register_operand" "2"))
18639 (use (match_operand:SI 3 "immediate_operand" "i"))
18640 (clobber (match_operand:DI 0 "register_operand" "=S"))
18641 (clobber (match_operand:DI 1 "register_operand" "=D"))
18642 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18645 [(set_attr "type" "str")
18646 (set_attr "mode" "QI")
18647 (set_attr "prefix_rep" "1")])
18649 ;; The same, but the count is not known to not be zero.
18651 (define_expand "cmpstrnqi_1"
18652 [(parallel [(set (reg:CC FLAGS_REG)
18653 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18655 (compare:CC (match_operand 4 "memory_operand" "")
18656 (match_operand 5 "memory_operand" ""))
18658 (use (match_operand:SI 3 "immediate_operand" ""))
18659 (use (reg:CC FLAGS_REG))
18660 (clobber (match_operand 0 "register_operand" ""))
18661 (clobber (match_operand 1 "register_operand" ""))
18662 (clobber (match_dup 2))])]
18666 (define_insn "*cmpstrnqi_1"
18667 [(set (reg:CC FLAGS_REG)
18668 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18670 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18671 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18673 (use (match_operand:SI 3 "immediate_operand" "i"))
18674 (use (reg:CC FLAGS_REG))
18675 (clobber (match_operand:SI 0 "register_operand" "=S"))
18676 (clobber (match_operand:SI 1 "register_operand" "=D"))
18677 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18680 [(set_attr "type" "str")
18681 (set_attr "mode" "QI")
18682 (set_attr "prefix_rep" "1")])
18684 (define_insn "*cmpstrnqi_rex_1"
18685 [(set (reg:CC FLAGS_REG)
18686 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18688 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18689 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18691 (use (match_operand:SI 3 "immediate_operand" "i"))
18692 (use (reg:CC FLAGS_REG))
18693 (clobber (match_operand:DI 0 "register_operand" "=S"))
18694 (clobber (match_operand:DI 1 "register_operand" "=D"))
18695 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18698 [(set_attr "type" "str")
18699 (set_attr "mode" "QI")
18700 (set_attr "prefix_rep" "1")])
18702 (define_expand "strlensi"
18703 [(set (match_operand:SI 0 "register_operand" "")
18704 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18705 (match_operand:QI 2 "immediate_operand" "")
18706 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18709 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18715 (define_expand "strlendi"
18716 [(set (match_operand:DI 0 "register_operand" "")
18717 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18718 (match_operand:QI 2 "immediate_operand" "")
18719 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18722 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18728 (define_expand "strlenqi_1"
18729 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18730 (clobber (match_operand 1 "register_operand" ""))
18731 (clobber (reg:CC FLAGS_REG))])]
18735 (define_insn "*strlenqi_1"
18736 [(set (match_operand:SI 0 "register_operand" "=&c")
18737 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18738 (match_operand:QI 2 "register_operand" "a")
18739 (match_operand:SI 3 "immediate_operand" "i")
18740 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18741 (clobber (match_operand:SI 1 "register_operand" "=D"))
18742 (clobber (reg:CC FLAGS_REG))]
18745 [(set_attr "type" "str")
18746 (set_attr "mode" "QI")
18747 (set_attr "prefix_rep" "1")])
18749 (define_insn "*strlenqi_rex_1"
18750 [(set (match_operand:DI 0 "register_operand" "=&c")
18751 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18752 (match_operand:QI 2 "register_operand" "a")
18753 (match_operand:DI 3 "immediate_operand" "i")
18754 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18755 (clobber (match_operand:DI 1 "register_operand" "=D"))
18756 (clobber (reg:CC FLAGS_REG))]
18759 [(set_attr "type" "str")
18760 (set_attr "mode" "QI")
18761 (set_attr "prefix_rep" "1")])
18763 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18764 ;; handled in combine, but it is not currently up to the task.
18765 ;; When used for their truth value, the cmpstrn* expanders generate
18774 ;; The intermediate three instructions are unnecessary.
18776 ;; This one handles cmpstrn*_nz_1...
18779 (set (reg:CC FLAGS_REG)
18780 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18781 (mem:BLK (match_operand 5 "register_operand" ""))))
18782 (use (match_operand 6 "register_operand" ""))
18783 (use (match_operand:SI 3 "immediate_operand" ""))
18784 (clobber (match_operand 0 "register_operand" ""))
18785 (clobber (match_operand 1 "register_operand" ""))
18786 (clobber (match_operand 2 "register_operand" ""))])
18787 (set (match_operand:QI 7 "register_operand" "")
18788 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18789 (set (match_operand:QI 8 "register_operand" "")
18790 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18791 (set (reg FLAGS_REG)
18792 (compare (match_dup 7) (match_dup 8)))
18794 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18796 (set (reg:CC FLAGS_REG)
18797 (compare:CC (mem:BLK (match_dup 4))
18798 (mem:BLK (match_dup 5))))
18799 (use (match_dup 6))
18800 (use (match_dup 3))
18801 (clobber (match_dup 0))
18802 (clobber (match_dup 1))
18803 (clobber (match_dup 2))])]
18806 ;; ...and this one handles cmpstrn*_1.
18809 (set (reg:CC FLAGS_REG)
18810 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18812 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18813 (mem:BLK (match_operand 5 "register_operand" "")))
18815 (use (match_operand:SI 3 "immediate_operand" ""))
18816 (use (reg:CC FLAGS_REG))
18817 (clobber (match_operand 0 "register_operand" ""))
18818 (clobber (match_operand 1 "register_operand" ""))
18819 (clobber (match_operand 2 "register_operand" ""))])
18820 (set (match_operand:QI 7 "register_operand" "")
18821 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18822 (set (match_operand:QI 8 "register_operand" "")
18823 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18824 (set (reg FLAGS_REG)
18825 (compare (match_dup 7) (match_dup 8)))
18827 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18829 (set (reg:CC FLAGS_REG)
18830 (if_then_else:CC (ne (match_dup 6)
18832 (compare:CC (mem:BLK (match_dup 4))
18833 (mem:BLK (match_dup 5)))
18835 (use (match_dup 3))
18836 (use (reg:CC FLAGS_REG))
18837 (clobber (match_dup 0))
18838 (clobber (match_dup 1))
18839 (clobber (match_dup 2))])]
18844 ;; Conditional move instructions.
18846 (define_expand "movdicc"
18847 [(set (match_operand:DI 0 "register_operand" "")
18848 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18849 (match_operand:DI 2 "general_operand" "")
18850 (match_operand:DI 3 "general_operand" "")))]
18852 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18854 (define_insn "x86_movdicc_0_m1_rex64"
18855 [(set (match_operand:DI 0 "register_operand" "=r")
18856 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18859 (clobber (reg:CC FLAGS_REG))]
18862 ; Since we don't have the proper number of operands for an alu insn,
18863 ; fill in all the blanks.
18864 [(set_attr "type" "alu")
18865 (set_attr "pent_pair" "pu")
18866 (set_attr "memory" "none")
18867 (set_attr "imm_disp" "false")
18868 (set_attr "mode" "DI")
18869 (set_attr "length_immediate" "0")])
18871 (define_insn "*movdicc_c_rex64"
18872 [(set (match_operand:DI 0 "register_operand" "=r,r")
18873 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18874 [(reg FLAGS_REG) (const_int 0)])
18875 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18876 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18877 "TARGET_64BIT && TARGET_CMOVE
18878 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18880 cmov%O2%C1\t{%2, %0|%0, %2}
18881 cmov%O2%c1\t{%3, %0|%0, %3}"
18882 [(set_attr "type" "icmov")
18883 (set_attr "mode" "DI")])
18885 (define_expand "movsicc"
18886 [(set (match_operand:SI 0 "register_operand" "")
18887 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18888 (match_operand:SI 2 "general_operand" "")
18889 (match_operand:SI 3 "general_operand" "")))]
18891 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18893 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18894 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18895 ;; So just document what we're doing explicitly.
18897 (define_insn "x86_movsicc_0_m1"
18898 [(set (match_operand:SI 0 "register_operand" "=r")
18899 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18902 (clobber (reg:CC FLAGS_REG))]
18905 ; Since we don't have the proper number of operands for an alu insn,
18906 ; fill in all the blanks.
18907 [(set_attr "type" "alu")
18908 (set_attr "pent_pair" "pu")
18909 (set_attr "memory" "none")
18910 (set_attr "imm_disp" "false")
18911 (set_attr "mode" "SI")
18912 (set_attr "length_immediate" "0")])
18914 (define_insn "*movsicc_noc"
18915 [(set (match_operand:SI 0 "register_operand" "=r,r")
18916 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18917 [(reg FLAGS_REG) (const_int 0)])
18918 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18919 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18921 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18923 cmov%O2%C1\t{%2, %0|%0, %2}
18924 cmov%O2%c1\t{%3, %0|%0, %3}"
18925 [(set_attr "type" "icmov")
18926 (set_attr "mode" "SI")])
18928 (define_expand "movhicc"
18929 [(set (match_operand:HI 0 "register_operand" "")
18930 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18931 (match_operand:HI 2 "general_operand" "")
18932 (match_operand:HI 3 "general_operand" "")))]
18933 "TARGET_HIMODE_MATH"
18934 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18936 (define_insn "*movhicc_noc"
18937 [(set (match_operand:HI 0 "register_operand" "=r,r")
18938 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18939 [(reg FLAGS_REG) (const_int 0)])
18940 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18941 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18943 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18945 cmov%O2%C1\t{%2, %0|%0, %2}
18946 cmov%O2%c1\t{%3, %0|%0, %3}"
18947 [(set_attr "type" "icmov")
18948 (set_attr "mode" "HI")])
18950 (define_expand "movqicc"
18951 [(set (match_operand:QI 0 "register_operand" "")
18952 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18953 (match_operand:QI 2 "general_operand" "")
18954 (match_operand:QI 3 "general_operand" "")))]
18955 "TARGET_QIMODE_MATH"
18956 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18958 (define_insn_and_split "*movqicc_noc"
18959 [(set (match_operand:QI 0 "register_operand" "=r,r")
18960 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18961 [(match_operand 4 "flags_reg_operand" "")
18963 (match_operand:QI 2 "register_operand" "r,0")
18964 (match_operand:QI 3 "register_operand" "0,r")))]
18965 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18967 "&& reload_completed"
18968 [(set (match_dup 0)
18969 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18972 "operands[0] = gen_lowpart (SImode, operands[0]);
18973 operands[2] = gen_lowpart (SImode, operands[2]);
18974 operands[3] = gen_lowpart (SImode, operands[3]);"
18975 [(set_attr "type" "icmov")
18976 (set_attr "mode" "SI")])
18978 (define_expand "movsfcc"
18979 [(set (match_operand:SF 0 "register_operand" "")
18980 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18981 (match_operand:SF 2 "register_operand" "")
18982 (match_operand:SF 3 "register_operand" "")))]
18983 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18984 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18986 (define_insn "*movsfcc_1_387"
18987 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18988 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18989 [(reg FLAGS_REG) (const_int 0)])
18990 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18991 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18992 "TARGET_80387 && TARGET_CMOVE
18993 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18995 fcmov%F1\t{%2, %0|%0, %2}
18996 fcmov%f1\t{%3, %0|%0, %3}
18997 cmov%O2%C1\t{%2, %0|%0, %2}
18998 cmov%O2%c1\t{%3, %0|%0, %3}"
18999 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19000 (set_attr "mode" "SF,SF,SI,SI")])
19002 (define_expand "movdfcc"
19003 [(set (match_operand:DF 0 "register_operand" "")
19004 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19005 (match_operand:DF 2 "register_operand" "")
19006 (match_operand:DF 3 "register_operand" "")))]
19007 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19008 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19010 (define_insn "*movdfcc_1"
19011 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19012 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19013 [(reg FLAGS_REG) (const_int 0)])
19014 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19015 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19016 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19017 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19019 fcmov%F1\t{%2, %0|%0, %2}
19020 fcmov%f1\t{%3, %0|%0, %3}
19023 [(set_attr "type" "fcmov,fcmov,multi,multi")
19024 (set_attr "mode" "DF")])
19026 (define_insn "*movdfcc_1_rex64"
19027 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19028 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19029 [(reg FLAGS_REG) (const_int 0)])
19030 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19031 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19032 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19033 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19035 fcmov%F1\t{%2, %0|%0, %2}
19036 fcmov%f1\t{%3, %0|%0, %3}
19037 cmov%O2%C1\t{%2, %0|%0, %2}
19038 cmov%O2%c1\t{%3, %0|%0, %3}"
19039 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19040 (set_attr "mode" "DF")])
19043 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19044 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19045 [(match_operand 4 "flags_reg_operand" "")
19047 (match_operand:DF 2 "nonimmediate_operand" "")
19048 (match_operand:DF 3 "nonimmediate_operand" "")))]
19049 "!TARGET_64BIT && reload_completed"
19050 [(set (match_dup 2)
19051 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19055 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19058 "split_di (operands+2, 1, operands+5, operands+6);
19059 split_di (operands+3, 1, operands+7, operands+8);
19060 split_di (operands, 1, operands+2, operands+3);")
19062 (define_expand "movxfcc"
19063 [(set (match_operand:XF 0 "register_operand" "")
19064 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19065 (match_operand:XF 2 "register_operand" "")
19066 (match_operand:XF 3 "register_operand" "")))]
19067 "TARGET_80387 && TARGET_CMOVE"
19068 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19070 (define_insn "*movxfcc_1"
19071 [(set (match_operand:XF 0 "register_operand" "=f,f")
19072 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19073 [(reg FLAGS_REG) (const_int 0)])
19074 (match_operand:XF 2 "register_operand" "f,0")
19075 (match_operand:XF 3 "register_operand" "0,f")))]
19076 "TARGET_80387 && TARGET_CMOVE"
19078 fcmov%F1\t{%2, %0|%0, %2}
19079 fcmov%f1\t{%3, %0|%0, %3}"
19080 [(set_attr "type" "fcmov")
19081 (set_attr "mode" "XF")])
19083 ;; These versions of the min/max patterns are intentionally ignorant of
19084 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19085 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19086 ;; are undefined in this condition, we're certain this is correct.
19088 (define_insn "sminsf3"
19089 [(set (match_operand:SF 0 "register_operand" "=x")
19090 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19091 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19093 "minss\t{%2, %0|%0, %2}"
19094 [(set_attr "type" "sseadd")
19095 (set_attr "mode" "SF")])
19097 (define_insn "smaxsf3"
19098 [(set (match_operand:SF 0 "register_operand" "=x")
19099 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19100 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19102 "maxss\t{%2, %0|%0, %2}"
19103 [(set_attr "type" "sseadd")
19104 (set_attr "mode" "SF")])
19106 (define_insn "smindf3"
19107 [(set (match_operand:DF 0 "register_operand" "=x")
19108 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19109 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19110 "TARGET_SSE2 && TARGET_SSE_MATH"
19111 "minsd\t{%2, %0|%0, %2}"
19112 [(set_attr "type" "sseadd")
19113 (set_attr "mode" "DF")])
19115 (define_insn "smaxdf3"
19116 [(set (match_operand:DF 0 "register_operand" "=x")
19117 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19118 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19119 "TARGET_SSE2 && TARGET_SSE_MATH"
19120 "maxsd\t{%2, %0|%0, %2}"
19121 [(set_attr "type" "sseadd")
19122 (set_attr "mode" "DF")])
19124 ;; These versions of the min/max patterns implement exactly the operations
19125 ;; min = (op1 < op2 ? op1 : op2)
19126 ;; max = (!(op1 < op2) ? op1 : op2)
19127 ;; Their operands are not commutative, and thus they may be used in the
19128 ;; presence of -0.0 and NaN.
19130 (define_insn "*ieee_sminsf3"
19131 [(set (match_operand:SF 0 "register_operand" "=x")
19132 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19133 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19136 "minss\t{%2, %0|%0, %2}"
19137 [(set_attr "type" "sseadd")
19138 (set_attr "mode" "SF")])
19140 (define_insn "*ieee_smaxsf3"
19141 [(set (match_operand:SF 0 "register_operand" "=x")
19142 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19143 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19146 "maxss\t{%2, %0|%0, %2}"
19147 [(set_attr "type" "sseadd")
19148 (set_attr "mode" "SF")])
19150 (define_insn "*ieee_smindf3"
19151 [(set (match_operand:DF 0 "register_operand" "=x")
19152 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19153 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19155 "TARGET_SSE2 && TARGET_SSE_MATH"
19156 "minsd\t{%2, %0|%0, %2}"
19157 [(set_attr "type" "sseadd")
19158 (set_attr "mode" "DF")])
19160 (define_insn "*ieee_smaxdf3"
19161 [(set (match_operand:DF 0 "register_operand" "=x")
19162 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19163 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19165 "TARGET_SSE2 && TARGET_SSE_MATH"
19166 "maxsd\t{%2, %0|%0, %2}"
19167 [(set_attr "type" "sseadd")
19168 (set_attr "mode" "DF")])
19170 ;; Make two stack loads independent:
19172 ;; fld %st(0) -> fld bb
19173 ;; fmul bb fmul %st(1), %st
19175 ;; Actually we only match the last two instructions for simplicity.
19177 [(set (match_operand 0 "fp_register_operand" "")
19178 (match_operand 1 "fp_register_operand" ""))
19180 (match_operator 2 "binary_fp_operator"
19182 (match_operand 3 "memory_operand" "")]))]
19183 "REGNO (operands[0]) != REGNO (operands[1])"
19184 [(set (match_dup 0) (match_dup 3))
19185 (set (match_dup 0) (match_dup 4))]
19187 ;; The % modifier is not operational anymore in peephole2's, so we have to
19188 ;; swap the operands manually in the case of addition and multiplication.
19189 "if (COMMUTATIVE_ARITH_P (operands[2]))
19190 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19191 operands[0], operands[1]);
19193 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19194 operands[1], operands[0]);")
19196 ;; Conditional addition patterns
19197 (define_expand "addqicc"
19198 [(match_operand:QI 0 "register_operand" "")
19199 (match_operand 1 "comparison_operator" "")
19200 (match_operand:QI 2 "register_operand" "")
19201 (match_operand:QI 3 "const_int_operand" "")]
19203 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19205 (define_expand "addhicc"
19206 [(match_operand:HI 0 "register_operand" "")
19207 (match_operand 1 "comparison_operator" "")
19208 (match_operand:HI 2 "register_operand" "")
19209 (match_operand:HI 3 "const_int_operand" "")]
19211 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19213 (define_expand "addsicc"
19214 [(match_operand:SI 0 "register_operand" "")
19215 (match_operand 1 "comparison_operator" "")
19216 (match_operand:SI 2 "register_operand" "")
19217 (match_operand:SI 3 "const_int_operand" "")]
19219 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19221 (define_expand "adddicc"
19222 [(match_operand:DI 0 "register_operand" "")
19223 (match_operand 1 "comparison_operator" "")
19224 (match_operand:DI 2 "register_operand" "")
19225 (match_operand:DI 3 "const_int_operand" "")]
19227 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19230 ;; Misc patterns (?)
19232 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19233 ;; Otherwise there will be nothing to keep
19235 ;; [(set (reg ebp) (reg esp))]
19236 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19237 ;; (clobber (eflags)]
19238 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19240 ;; in proper program order.
19241 (define_insn "pro_epilogue_adjust_stack_1"
19242 [(set (match_operand:SI 0 "register_operand" "=r,r")
19243 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19244 (match_operand:SI 2 "immediate_operand" "i,i")))
19245 (clobber (reg:CC FLAGS_REG))
19246 (clobber (mem:BLK (scratch)))]
19249 switch (get_attr_type (insn))
19252 return "mov{l}\t{%1, %0|%0, %1}";
19255 if (CONST_INT_P (operands[2])
19256 && (INTVAL (operands[2]) == 128
19257 || (INTVAL (operands[2]) < 0
19258 && INTVAL (operands[2]) != -128)))
19260 operands[2] = GEN_INT (-INTVAL (operands[2]));
19261 return "sub{l}\t{%2, %0|%0, %2}";
19263 return "add{l}\t{%2, %0|%0, %2}";
19266 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19267 return "lea{l}\t{%a2, %0|%0, %a2}";
19270 gcc_unreachable ();
19273 [(set (attr "type")
19274 (cond [(eq_attr "alternative" "0")
19275 (const_string "alu")
19276 (match_operand:SI 2 "const0_operand" "")
19277 (const_string "imov")
19279 (const_string "lea")))
19280 (set_attr "mode" "SI")])
19282 (define_insn "pro_epilogue_adjust_stack_rex64"
19283 [(set (match_operand:DI 0 "register_operand" "=r,r")
19284 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19285 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19286 (clobber (reg:CC FLAGS_REG))
19287 (clobber (mem:BLK (scratch)))]
19290 switch (get_attr_type (insn))
19293 return "mov{q}\t{%1, %0|%0, %1}";
19296 if (CONST_INT_P (operands[2])
19297 /* Avoid overflows. */
19298 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19299 && (INTVAL (operands[2]) == 128
19300 || (INTVAL (operands[2]) < 0
19301 && INTVAL (operands[2]) != -128)))
19303 operands[2] = GEN_INT (-INTVAL (operands[2]));
19304 return "sub{q}\t{%2, %0|%0, %2}";
19306 return "add{q}\t{%2, %0|%0, %2}";
19309 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19310 return "lea{q}\t{%a2, %0|%0, %a2}";
19313 gcc_unreachable ();
19316 [(set (attr "type")
19317 (cond [(eq_attr "alternative" "0")
19318 (const_string "alu")
19319 (match_operand:DI 2 "const0_operand" "")
19320 (const_string "imov")
19322 (const_string "lea")))
19323 (set_attr "mode" "DI")])
19325 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19326 [(set (match_operand:DI 0 "register_operand" "=r,r")
19327 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19328 (match_operand:DI 3 "immediate_operand" "i,i")))
19329 (use (match_operand:DI 2 "register_operand" "r,r"))
19330 (clobber (reg:CC FLAGS_REG))
19331 (clobber (mem:BLK (scratch)))]
19334 switch (get_attr_type (insn))
19337 return "add{q}\t{%2, %0|%0, %2}";
19340 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19341 return "lea{q}\t{%a2, %0|%0, %a2}";
19344 gcc_unreachable ();
19347 [(set_attr "type" "alu,lea")
19348 (set_attr "mode" "DI")])
19350 (define_insn "allocate_stack_worker_32"
19351 [(set (match_operand:SI 0 "register_operand" "+a")
19352 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19353 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19354 (clobber (reg:CC FLAGS_REG))]
19355 "!TARGET_64BIT && TARGET_STACK_PROBE"
19357 [(set_attr "type" "multi")
19358 (set_attr "length" "5")])
19360 (define_insn "allocate_stack_worker_64"
19361 [(set (match_operand:DI 0 "register_operand" "=a")
19362 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19363 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19364 (clobber (reg:DI R10_REG))
19365 (clobber (reg:DI R11_REG))
19366 (clobber (reg:CC FLAGS_REG))]
19367 "TARGET_64BIT && TARGET_STACK_PROBE"
19369 [(set_attr "type" "multi")
19370 (set_attr "length" "5")])
19372 (define_expand "allocate_stack"
19373 [(match_operand 0 "register_operand" "")
19374 (match_operand 1 "general_operand" "")]
19375 "TARGET_STACK_PROBE"
19379 #ifndef CHECK_STACK_LIMIT
19380 #define CHECK_STACK_LIMIT 0
19383 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19384 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19386 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19387 stack_pointer_rtx, 0, OPTAB_DIRECT);
19388 if (x != stack_pointer_rtx)
19389 emit_move_insn (stack_pointer_rtx, x);
19393 x = copy_to_mode_reg (Pmode, operands[1]);
19395 x = gen_allocate_stack_worker_64 (x);
19397 x = gen_allocate_stack_worker_32 (x);
19401 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19405 (define_expand "builtin_setjmp_receiver"
19406 [(label_ref (match_operand 0 "" ""))]
19407 "!TARGET_64BIT && flag_pic"
19412 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19413 rtx label_rtx = gen_label_rtx ();
19414 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19415 xops[0] = xops[1] = picreg;
19416 xops[2] = gen_rtx_CONST (SImode,
19417 gen_rtx_MINUS (SImode,
19418 gen_rtx_LABEL_REF (SImode, label_rtx),
19419 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19420 ix86_expand_binary_operator (MINUS, SImode, xops);
19423 emit_insn (gen_set_got (pic_offset_table_rtx));
19427 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19430 [(set (match_operand 0 "register_operand" "")
19431 (match_operator 3 "promotable_binary_operator"
19432 [(match_operand 1 "register_operand" "")
19433 (match_operand 2 "aligned_operand" "")]))
19434 (clobber (reg:CC FLAGS_REG))]
19435 "! TARGET_PARTIAL_REG_STALL && reload_completed
19436 && ((GET_MODE (operands[0]) == HImode
19437 && ((!optimize_size && !TARGET_FAST_PREFIX)
19438 /* ??? next two lines just !satisfies_constraint_K (...) */
19439 || !CONST_INT_P (operands[2])
19440 || satisfies_constraint_K (operands[2])))
19441 || (GET_MODE (operands[0]) == QImode
19442 && (TARGET_PROMOTE_QImode || optimize_size)))"
19443 [(parallel [(set (match_dup 0)
19444 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19445 (clobber (reg:CC FLAGS_REG))])]
19446 "operands[0] = gen_lowpart (SImode, operands[0]);
19447 operands[1] = gen_lowpart (SImode, operands[1]);
19448 if (GET_CODE (operands[3]) != ASHIFT)
19449 operands[2] = gen_lowpart (SImode, operands[2]);
19450 PUT_MODE (operands[3], SImode);")
19452 ; Promote the QImode tests, as i386 has encoding of the AND
19453 ; instruction with 32-bit sign-extended immediate and thus the
19454 ; instruction size is unchanged, except in the %eax case for
19455 ; which it is increased by one byte, hence the ! optimize_size.
19457 [(set (match_operand 0 "flags_reg_operand" "")
19458 (match_operator 2 "compare_operator"
19459 [(and (match_operand 3 "aligned_operand" "")
19460 (match_operand 4 "const_int_operand" ""))
19462 (set (match_operand 1 "register_operand" "")
19463 (and (match_dup 3) (match_dup 4)))]
19464 "! TARGET_PARTIAL_REG_STALL && reload_completed
19465 /* Ensure that the operand will remain sign-extended immediate. */
19466 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19468 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19469 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19470 [(parallel [(set (match_dup 0)
19471 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19474 (and:SI (match_dup 3) (match_dup 4)))])]
19477 = gen_int_mode (INTVAL (operands[4])
19478 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19479 operands[1] = gen_lowpart (SImode, operands[1]);
19480 operands[3] = gen_lowpart (SImode, operands[3]);
19483 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19484 ; the TEST instruction with 32-bit sign-extended immediate and thus
19485 ; the instruction size would at least double, which is not what we
19486 ; want even with ! optimize_size.
19488 [(set (match_operand 0 "flags_reg_operand" "")
19489 (match_operator 1 "compare_operator"
19490 [(and (match_operand:HI 2 "aligned_operand" "")
19491 (match_operand:HI 3 "const_int_operand" ""))
19493 "! TARGET_PARTIAL_REG_STALL && reload_completed
19494 /* Ensure that the operand will remain sign-extended immediate. */
19495 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19496 && ! TARGET_FAST_PREFIX
19497 && ! optimize_size"
19498 [(set (match_dup 0)
19499 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19503 = gen_int_mode (INTVAL (operands[3])
19504 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19505 operands[2] = gen_lowpart (SImode, operands[2]);
19509 [(set (match_operand 0 "register_operand" "")
19510 (neg (match_operand 1 "register_operand" "")))
19511 (clobber (reg:CC FLAGS_REG))]
19512 "! TARGET_PARTIAL_REG_STALL && reload_completed
19513 && (GET_MODE (operands[0]) == HImode
19514 || (GET_MODE (operands[0]) == QImode
19515 && (TARGET_PROMOTE_QImode || optimize_size)))"
19516 [(parallel [(set (match_dup 0)
19517 (neg:SI (match_dup 1)))
19518 (clobber (reg:CC FLAGS_REG))])]
19519 "operands[0] = gen_lowpart (SImode, operands[0]);
19520 operands[1] = gen_lowpart (SImode, operands[1]);")
19523 [(set (match_operand 0 "register_operand" "")
19524 (not (match_operand 1 "register_operand" "")))]
19525 "! TARGET_PARTIAL_REG_STALL && reload_completed
19526 && (GET_MODE (operands[0]) == HImode
19527 || (GET_MODE (operands[0]) == QImode
19528 && (TARGET_PROMOTE_QImode || optimize_size)))"
19529 [(set (match_dup 0)
19530 (not:SI (match_dup 1)))]
19531 "operands[0] = gen_lowpart (SImode, operands[0]);
19532 operands[1] = gen_lowpart (SImode, operands[1]);")
19535 [(set (match_operand 0 "register_operand" "")
19536 (if_then_else (match_operator 1 "comparison_operator"
19537 [(reg FLAGS_REG) (const_int 0)])
19538 (match_operand 2 "register_operand" "")
19539 (match_operand 3 "register_operand" "")))]
19540 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19541 && (GET_MODE (operands[0]) == HImode
19542 || (GET_MODE (operands[0]) == QImode
19543 && (TARGET_PROMOTE_QImode || optimize_size)))"
19544 [(set (match_dup 0)
19545 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19546 "operands[0] = gen_lowpart (SImode, operands[0]);
19547 operands[2] = gen_lowpart (SImode, operands[2]);
19548 operands[3] = gen_lowpart (SImode, operands[3]);")
19551 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19552 ;; transform a complex memory operation into two memory to register operations.
19554 ;; Don't push memory operands
19556 [(set (match_operand:SI 0 "push_operand" "")
19557 (match_operand:SI 1 "memory_operand" ""))
19558 (match_scratch:SI 2 "r")]
19559 "!optimize_size && !TARGET_PUSH_MEMORY
19560 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19561 [(set (match_dup 2) (match_dup 1))
19562 (set (match_dup 0) (match_dup 2))]
19566 [(set (match_operand:DI 0 "push_operand" "")
19567 (match_operand:DI 1 "memory_operand" ""))
19568 (match_scratch:DI 2 "r")]
19569 "!optimize_size && !TARGET_PUSH_MEMORY
19570 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19571 [(set (match_dup 2) (match_dup 1))
19572 (set (match_dup 0) (match_dup 2))]
19575 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19578 [(set (match_operand:SF 0 "push_operand" "")
19579 (match_operand:SF 1 "memory_operand" ""))
19580 (match_scratch:SF 2 "r")]
19581 "!optimize_size && !TARGET_PUSH_MEMORY
19582 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19583 [(set (match_dup 2) (match_dup 1))
19584 (set (match_dup 0) (match_dup 2))]
19588 [(set (match_operand:HI 0 "push_operand" "")
19589 (match_operand:HI 1 "memory_operand" ""))
19590 (match_scratch:HI 2 "r")]
19591 "!optimize_size && !TARGET_PUSH_MEMORY
19592 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19593 [(set (match_dup 2) (match_dup 1))
19594 (set (match_dup 0) (match_dup 2))]
19598 [(set (match_operand:QI 0 "push_operand" "")
19599 (match_operand:QI 1 "memory_operand" ""))
19600 (match_scratch:QI 2 "q")]
19601 "!optimize_size && !TARGET_PUSH_MEMORY
19602 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19603 [(set (match_dup 2) (match_dup 1))
19604 (set (match_dup 0) (match_dup 2))]
19607 ;; Don't move an immediate directly to memory when the instruction
19610 [(match_scratch:SI 1 "r")
19611 (set (match_operand:SI 0 "memory_operand" "")
19614 && ! TARGET_USE_MOV0
19615 && TARGET_SPLIT_LONG_MOVES
19616 && get_attr_length (insn) >= ix86_cost->large_insn
19617 && peep2_regno_dead_p (0, FLAGS_REG)"
19618 [(parallel [(set (match_dup 1) (const_int 0))
19619 (clobber (reg:CC FLAGS_REG))])
19620 (set (match_dup 0) (match_dup 1))]
19624 [(match_scratch:HI 1 "r")
19625 (set (match_operand:HI 0 "memory_operand" "")
19628 && ! TARGET_USE_MOV0
19629 && TARGET_SPLIT_LONG_MOVES
19630 && get_attr_length (insn) >= ix86_cost->large_insn
19631 && peep2_regno_dead_p (0, FLAGS_REG)"
19632 [(parallel [(set (match_dup 2) (const_int 0))
19633 (clobber (reg:CC FLAGS_REG))])
19634 (set (match_dup 0) (match_dup 1))]
19635 "operands[2] = gen_lowpart (SImode, operands[1]);")
19638 [(match_scratch:QI 1 "q")
19639 (set (match_operand:QI 0 "memory_operand" "")
19642 && ! TARGET_USE_MOV0
19643 && TARGET_SPLIT_LONG_MOVES
19644 && get_attr_length (insn) >= ix86_cost->large_insn
19645 && peep2_regno_dead_p (0, FLAGS_REG)"
19646 [(parallel [(set (match_dup 2) (const_int 0))
19647 (clobber (reg:CC FLAGS_REG))])
19648 (set (match_dup 0) (match_dup 1))]
19649 "operands[2] = gen_lowpart (SImode, operands[1]);")
19652 [(match_scratch:SI 2 "r")
19653 (set (match_operand:SI 0 "memory_operand" "")
19654 (match_operand:SI 1 "immediate_operand" ""))]
19656 && get_attr_length (insn) >= ix86_cost->large_insn
19657 && TARGET_SPLIT_LONG_MOVES"
19658 [(set (match_dup 2) (match_dup 1))
19659 (set (match_dup 0) (match_dup 2))]
19663 [(match_scratch:HI 2 "r")
19664 (set (match_operand:HI 0 "memory_operand" "")
19665 (match_operand:HI 1 "immediate_operand" ""))]
19666 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19667 && TARGET_SPLIT_LONG_MOVES"
19668 [(set (match_dup 2) (match_dup 1))
19669 (set (match_dup 0) (match_dup 2))]
19673 [(match_scratch:QI 2 "q")
19674 (set (match_operand:QI 0 "memory_operand" "")
19675 (match_operand:QI 1 "immediate_operand" ""))]
19676 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19677 && TARGET_SPLIT_LONG_MOVES"
19678 [(set (match_dup 2) (match_dup 1))
19679 (set (match_dup 0) (match_dup 2))]
19682 ;; Don't compare memory with zero, load and use a test instead.
19684 [(set (match_operand 0 "flags_reg_operand" "")
19685 (match_operator 1 "compare_operator"
19686 [(match_operand:SI 2 "memory_operand" "")
19688 (match_scratch:SI 3 "r")]
19689 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19690 [(set (match_dup 3) (match_dup 2))
19691 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19694 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19695 ;; Don't split NOTs with a displacement operand, because resulting XOR
19696 ;; will not be pairable anyway.
19698 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19699 ;; represented using a modRM byte. The XOR replacement is long decoded,
19700 ;; so this split helps here as well.
19702 ;; Note: Can't do this as a regular split because we can't get proper
19703 ;; lifetime information then.
19706 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19707 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19709 && peep2_regno_dead_p (0, FLAGS_REG)
19710 && ((TARGET_NOT_UNPAIRABLE
19711 && (!MEM_P (operands[0])
19712 || !memory_displacement_operand (operands[0], SImode)))
19713 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))"
19714 [(parallel [(set (match_dup 0)
19715 (xor:SI (match_dup 1) (const_int -1)))
19716 (clobber (reg:CC FLAGS_REG))])]
19720 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19721 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19723 && peep2_regno_dead_p (0, FLAGS_REG)
19724 && ((TARGET_NOT_UNPAIRABLE
19725 && (!MEM_P (operands[0])
19726 || !memory_displacement_operand (operands[0], HImode)))
19727 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))"
19728 [(parallel [(set (match_dup 0)
19729 (xor:HI (match_dup 1) (const_int -1)))
19730 (clobber (reg:CC FLAGS_REG))])]
19734 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19735 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19737 && peep2_regno_dead_p (0, FLAGS_REG)
19738 && ((TARGET_NOT_UNPAIRABLE
19739 && (!MEM_P (operands[0])
19740 || !memory_displacement_operand (operands[0], QImode)))
19741 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))"
19742 [(parallel [(set (match_dup 0)
19743 (xor:QI (match_dup 1) (const_int -1)))
19744 (clobber (reg:CC FLAGS_REG))])]
19747 ;; Non pairable "test imm, reg" instructions can be translated to
19748 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19749 ;; byte opcode instead of two, have a short form for byte operands),
19750 ;; so do it for other CPUs as well. Given that the value was dead,
19751 ;; this should not create any new dependencies. Pass on the sub-word
19752 ;; versions if we're concerned about partial register stalls.
19755 [(set (match_operand 0 "flags_reg_operand" "")
19756 (match_operator 1 "compare_operator"
19757 [(and:SI (match_operand:SI 2 "register_operand" "")
19758 (match_operand:SI 3 "immediate_operand" ""))
19760 "ix86_match_ccmode (insn, CCNOmode)
19761 && (true_regnum (operands[2]) != 0
19762 || satisfies_constraint_K (operands[3]))
19763 && peep2_reg_dead_p (1, operands[2])"
19765 [(set (match_dup 0)
19766 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19769 (and:SI (match_dup 2) (match_dup 3)))])]
19772 ;; We don't need to handle HImode case, because it will be promoted to SImode
19773 ;; on ! TARGET_PARTIAL_REG_STALL
19776 [(set (match_operand 0 "flags_reg_operand" "")
19777 (match_operator 1 "compare_operator"
19778 [(and:QI (match_operand:QI 2 "register_operand" "")
19779 (match_operand:QI 3 "immediate_operand" ""))
19781 "! TARGET_PARTIAL_REG_STALL
19782 && ix86_match_ccmode (insn, CCNOmode)
19783 && true_regnum (operands[2]) != 0
19784 && peep2_reg_dead_p (1, operands[2])"
19786 [(set (match_dup 0)
19787 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19790 (and:QI (match_dup 2) (match_dup 3)))])]
19794 [(set (match_operand 0 "flags_reg_operand" "")
19795 (match_operator 1 "compare_operator"
19798 (match_operand 2 "ext_register_operand" "")
19801 (match_operand 3 "const_int_operand" ""))
19803 "! TARGET_PARTIAL_REG_STALL
19804 && ix86_match_ccmode (insn, CCNOmode)
19805 && true_regnum (operands[2]) != 0
19806 && peep2_reg_dead_p (1, operands[2])"
19807 [(parallel [(set (match_dup 0)
19816 (set (zero_extract:SI (match_dup 2)
19827 ;; Don't do logical operations with memory inputs.
19829 [(match_scratch:SI 2 "r")
19830 (parallel [(set (match_operand:SI 0 "register_operand" "")
19831 (match_operator:SI 3 "arith_or_logical_operator"
19833 (match_operand:SI 1 "memory_operand" "")]))
19834 (clobber (reg:CC FLAGS_REG))])]
19835 "! optimize_size && ! TARGET_READ_MODIFY"
19836 [(set (match_dup 2) (match_dup 1))
19837 (parallel [(set (match_dup 0)
19838 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19839 (clobber (reg:CC FLAGS_REG))])]
19843 [(match_scratch:SI 2 "r")
19844 (parallel [(set (match_operand:SI 0 "register_operand" "")
19845 (match_operator:SI 3 "arith_or_logical_operator"
19846 [(match_operand:SI 1 "memory_operand" "")
19848 (clobber (reg:CC FLAGS_REG))])]
19849 "! optimize_size && ! TARGET_READ_MODIFY"
19850 [(set (match_dup 2) (match_dup 1))
19851 (parallel [(set (match_dup 0)
19852 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19853 (clobber (reg:CC FLAGS_REG))])]
19856 ; Don't do logical operations with memory outputs
19858 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19859 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19860 ; the same decoder scheduling characteristics as the original.
19863 [(match_scratch:SI 2 "r")
19864 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19865 (match_operator:SI 3 "arith_or_logical_operator"
19867 (match_operand:SI 1 "nonmemory_operand" "")]))
19868 (clobber (reg:CC FLAGS_REG))])]
19869 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19870 [(set (match_dup 2) (match_dup 0))
19871 (parallel [(set (match_dup 2)
19872 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19873 (clobber (reg:CC FLAGS_REG))])
19874 (set (match_dup 0) (match_dup 2))]
19878 [(match_scratch:SI 2 "r")
19879 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19880 (match_operator:SI 3 "arith_or_logical_operator"
19881 [(match_operand:SI 1 "nonmemory_operand" "")
19883 (clobber (reg:CC FLAGS_REG))])]
19884 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19885 [(set (match_dup 2) (match_dup 0))
19886 (parallel [(set (match_dup 2)
19887 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19888 (clobber (reg:CC FLAGS_REG))])
19889 (set (match_dup 0) (match_dup 2))]
19892 ;; Attempt to always use XOR for zeroing registers.
19894 [(set (match_operand 0 "register_operand" "")
19895 (match_operand 1 "const0_operand" ""))]
19896 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19897 && (! TARGET_USE_MOV0 || optimize_size)
19898 && GENERAL_REG_P (operands[0])
19899 && peep2_regno_dead_p (0, FLAGS_REG)"
19900 [(parallel [(set (match_dup 0) (const_int 0))
19901 (clobber (reg:CC FLAGS_REG))])]
19903 operands[0] = gen_lowpart (word_mode, operands[0]);
19907 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19909 "(GET_MODE (operands[0]) == QImode
19910 || GET_MODE (operands[0]) == HImode)
19911 && (! TARGET_USE_MOV0 || optimize_size)
19912 && peep2_regno_dead_p (0, FLAGS_REG)"
19913 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19914 (clobber (reg:CC FLAGS_REG))])])
19916 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19918 [(set (match_operand 0 "register_operand" "")
19920 "(GET_MODE (operands[0]) == HImode
19921 || GET_MODE (operands[0]) == SImode
19922 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19923 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
19924 && peep2_regno_dead_p (0, FLAGS_REG)"
19925 [(parallel [(set (match_dup 0) (const_int -1))
19926 (clobber (reg:CC FLAGS_REG))])]
19927 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19930 ;; Attempt to convert simple leas to adds. These can be created by
19933 [(set (match_operand:SI 0 "register_operand" "")
19934 (plus:SI (match_dup 0)
19935 (match_operand:SI 1 "nonmemory_operand" "")))]
19936 "peep2_regno_dead_p (0, FLAGS_REG)"
19937 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19938 (clobber (reg:CC FLAGS_REG))])]
19942 [(set (match_operand:SI 0 "register_operand" "")
19943 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19944 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19945 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19946 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19947 (clobber (reg:CC FLAGS_REG))])]
19948 "operands[2] = gen_lowpart (SImode, operands[2]);")
19951 [(set (match_operand:DI 0 "register_operand" "")
19952 (plus:DI (match_dup 0)
19953 (match_operand:DI 1 "x86_64_general_operand" "")))]
19954 "peep2_regno_dead_p (0, FLAGS_REG)"
19955 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19956 (clobber (reg:CC FLAGS_REG))])]
19960 [(set (match_operand:SI 0 "register_operand" "")
19961 (mult:SI (match_dup 0)
19962 (match_operand:SI 1 "const_int_operand" "")))]
19963 "exact_log2 (INTVAL (operands[1])) >= 0
19964 && peep2_regno_dead_p (0, FLAGS_REG)"
19965 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19966 (clobber (reg:CC FLAGS_REG))])]
19967 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19970 [(set (match_operand:DI 0 "register_operand" "")
19971 (mult:DI (match_dup 0)
19972 (match_operand:DI 1 "const_int_operand" "")))]
19973 "exact_log2 (INTVAL (operands[1])) >= 0
19974 && peep2_regno_dead_p (0, FLAGS_REG)"
19975 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19976 (clobber (reg:CC FLAGS_REG))])]
19977 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19980 [(set (match_operand:SI 0 "register_operand" "")
19981 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19982 (match_operand:DI 2 "const_int_operand" "")) 0))]
19983 "exact_log2 (INTVAL (operands[2])) >= 0
19984 && REGNO (operands[0]) == REGNO (operands[1])
19985 && peep2_regno_dead_p (0, FLAGS_REG)"
19986 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19987 (clobber (reg:CC FLAGS_REG))])]
19988 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19990 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19991 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19992 ;; many CPUs it is also faster, since special hardware to avoid esp
19993 ;; dependencies is present.
19995 ;; While some of these conversions may be done using splitters, we use peepholes
19996 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19998 ;; Convert prologue esp subtractions to push.
19999 ;; We need register to push. In order to keep verify_flow_info happy we have
20001 ;; - use scratch and clobber it in order to avoid dependencies
20002 ;; - use already live register
20003 ;; We can't use the second way right now, since there is no reliable way how to
20004 ;; verify that given register is live. First choice will also most likely in
20005 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20006 ;; call clobbered registers are dead. We may want to use base pointer as an
20007 ;; alternative when no register is available later.
20010 [(match_scratch:SI 0 "r")
20011 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20012 (clobber (reg:CC FLAGS_REG))
20013 (clobber (mem:BLK (scratch)))])]
20014 "optimize_size || !TARGET_SUB_ESP_4"
20015 [(clobber (match_dup 0))
20016 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20017 (clobber (mem:BLK (scratch)))])])
20020 [(match_scratch:SI 0 "r")
20021 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20022 (clobber (reg:CC FLAGS_REG))
20023 (clobber (mem:BLK (scratch)))])]
20024 "optimize_size || !TARGET_SUB_ESP_8"
20025 [(clobber (match_dup 0))
20026 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20027 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20028 (clobber (mem:BLK (scratch)))])])
20030 ;; Convert esp subtractions to push.
20032 [(match_scratch:SI 0 "r")
20033 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20034 (clobber (reg:CC FLAGS_REG))])]
20035 "optimize_size || !TARGET_SUB_ESP_4"
20036 [(clobber (match_dup 0))
20037 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20040 [(match_scratch:SI 0 "r")
20041 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20042 (clobber (reg:CC FLAGS_REG))])]
20043 "optimize_size || !TARGET_SUB_ESP_8"
20044 [(clobber (match_dup 0))
20045 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20046 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20048 ;; Convert epilogue deallocator to pop.
20050 [(match_scratch:SI 0 "r")
20051 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20052 (clobber (reg:CC FLAGS_REG))
20053 (clobber (mem:BLK (scratch)))])]
20054 "optimize_size || !TARGET_ADD_ESP_4"
20055 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20056 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20057 (clobber (mem:BLK (scratch)))])]
20060 ;; Two pops case is tricky, since pop causes dependency on destination register.
20061 ;; We use two registers if available.
20063 [(match_scratch:SI 0 "r")
20064 (match_scratch:SI 1 "r")
20065 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20066 (clobber (reg:CC FLAGS_REG))
20067 (clobber (mem:BLK (scratch)))])]
20068 "optimize_size || !TARGET_ADD_ESP_8"
20069 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20070 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20071 (clobber (mem:BLK (scratch)))])
20072 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20073 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20077 [(match_scratch:SI 0 "r")
20078 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20079 (clobber (reg:CC FLAGS_REG))
20080 (clobber (mem:BLK (scratch)))])]
20082 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20083 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20084 (clobber (mem:BLK (scratch)))])
20085 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20086 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20089 ;; Convert esp additions to pop.
20091 [(match_scratch:SI 0 "r")
20092 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20093 (clobber (reg:CC FLAGS_REG))])]
20095 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20096 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20099 ;; Two pops case is tricky, since pop causes dependency on destination register.
20100 ;; We use two registers if available.
20102 [(match_scratch:SI 0 "r")
20103 (match_scratch:SI 1 "r")
20104 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20105 (clobber (reg:CC FLAGS_REG))])]
20107 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20108 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20109 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20110 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20114 [(match_scratch:SI 0 "r")
20115 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20116 (clobber (reg:CC FLAGS_REG))])]
20118 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20119 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20120 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20121 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20124 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20125 ;; required and register dies. Similarly for 128 to plus -128.
20127 [(set (match_operand 0 "flags_reg_operand" "")
20128 (match_operator 1 "compare_operator"
20129 [(match_operand 2 "register_operand" "")
20130 (match_operand 3 "const_int_operand" "")]))]
20131 "(INTVAL (operands[3]) == -1
20132 || INTVAL (operands[3]) == 1
20133 || INTVAL (operands[3]) == 128)
20134 && ix86_match_ccmode (insn, CCGCmode)
20135 && peep2_reg_dead_p (1, operands[2])"
20136 [(parallel [(set (match_dup 0)
20137 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20138 (clobber (match_dup 2))])]
20142 [(match_scratch:DI 0 "r")
20143 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20144 (clobber (reg:CC FLAGS_REG))
20145 (clobber (mem:BLK (scratch)))])]
20146 "optimize_size || !TARGET_SUB_ESP_4"
20147 [(clobber (match_dup 0))
20148 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20149 (clobber (mem:BLK (scratch)))])])
20152 [(match_scratch:DI 0 "r")
20153 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20154 (clobber (reg:CC FLAGS_REG))
20155 (clobber (mem:BLK (scratch)))])]
20156 "optimize_size || !TARGET_SUB_ESP_8"
20157 [(clobber (match_dup 0))
20158 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20159 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20160 (clobber (mem:BLK (scratch)))])])
20162 ;; Convert esp subtractions to push.
20164 [(match_scratch:DI 0 "r")
20165 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20166 (clobber (reg:CC FLAGS_REG))])]
20167 "optimize_size || !TARGET_SUB_ESP_4"
20168 [(clobber (match_dup 0))
20169 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20172 [(match_scratch:DI 0 "r")
20173 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20174 (clobber (reg:CC FLAGS_REG))])]
20175 "optimize_size || !TARGET_SUB_ESP_8"
20176 [(clobber (match_dup 0))
20177 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20178 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20180 ;; Convert epilogue deallocator to pop.
20182 [(match_scratch:DI 0 "r")
20183 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20184 (clobber (reg:CC FLAGS_REG))
20185 (clobber (mem:BLK (scratch)))])]
20186 "optimize_size || !TARGET_ADD_ESP_4"
20187 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20188 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20189 (clobber (mem:BLK (scratch)))])]
20192 ;; Two pops case is tricky, since pop causes dependency on destination register.
20193 ;; We use two registers if available.
20195 [(match_scratch:DI 0 "r")
20196 (match_scratch:DI 1 "r")
20197 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20198 (clobber (reg:CC FLAGS_REG))
20199 (clobber (mem:BLK (scratch)))])]
20200 "optimize_size || !TARGET_ADD_ESP_8"
20201 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20202 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20203 (clobber (mem:BLK (scratch)))])
20204 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20205 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20209 [(match_scratch:DI 0 "r")
20210 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20211 (clobber (reg:CC FLAGS_REG))
20212 (clobber (mem:BLK (scratch)))])]
20214 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20215 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20216 (clobber (mem:BLK (scratch)))])
20217 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20218 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20221 ;; Convert esp additions to pop.
20223 [(match_scratch:DI 0 "r")
20224 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20225 (clobber (reg:CC FLAGS_REG))])]
20227 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20228 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20231 ;; Two pops case is tricky, since pop causes dependency on destination register.
20232 ;; We use two registers if available.
20234 [(match_scratch:DI 0 "r")
20235 (match_scratch:DI 1 "r")
20236 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20237 (clobber (reg:CC FLAGS_REG))])]
20239 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20240 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20241 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20242 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20246 [(match_scratch:DI 0 "r")
20247 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20248 (clobber (reg:CC FLAGS_REG))])]
20250 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20251 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20252 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20253 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20256 ;; Convert imul by three, five and nine into lea
20259 [(set (match_operand:SI 0 "register_operand" "")
20260 (mult:SI (match_operand:SI 1 "register_operand" "")
20261 (match_operand:SI 2 "const_int_operand" "")))
20262 (clobber (reg:CC FLAGS_REG))])]
20263 "INTVAL (operands[2]) == 3
20264 || INTVAL (operands[2]) == 5
20265 || INTVAL (operands[2]) == 9"
20266 [(set (match_dup 0)
20267 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20269 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20273 [(set (match_operand:SI 0 "register_operand" "")
20274 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20275 (match_operand:SI 2 "const_int_operand" "")))
20276 (clobber (reg:CC FLAGS_REG))])]
20278 && (INTVAL (operands[2]) == 3
20279 || INTVAL (operands[2]) == 5
20280 || INTVAL (operands[2]) == 9)"
20281 [(set (match_dup 0) (match_dup 1))
20283 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20285 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20289 [(set (match_operand:DI 0 "register_operand" "")
20290 (mult:DI (match_operand:DI 1 "register_operand" "")
20291 (match_operand:DI 2 "const_int_operand" "")))
20292 (clobber (reg:CC FLAGS_REG))])]
20294 && (INTVAL (operands[2]) == 3
20295 || INTVAL (operands[2]) == 5
20296 || INTVAL (operands[2]) == 9)"
20297 [(set (match_dup 0)
20298 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20300 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20304 [(set (match_operand:DI 0 "register_operand" "")
20305 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20306 (match_operand:DI 2 "const_int_operand" "")))
20307 (clobber (reg:CC FLAGS_REG))])]
20310 && (INTVAL (operands[2]) == 3
20311 || INTVAL (operands[2]) == 5
20312 || INTVAL (operands[2]) == 9)"
20313 [(set (match_dup 0) (match_dup 1))
20315 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20317 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20319 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20320 ;; imul $32bit_imm, reg, reg is direct decoded.
20322 [(match_scratch:DI 3 "r")
20323 (parallel [(set (match_operand:DI 0 "register_operand" "")
20324 (mult:DI (match_operand:DI 1 "memory_operand" "")
20325 (match_operand:DI 2 "immediate_operand" "")))
20326 (clobber (reg:CC FLAGS_REG))])]
20327 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20328 && !satisfies_constraint_K (operands[2])"
20329 [(set (match_dup 3) (match_dup 1))
20330 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20331 (clobber (reg:CC FLAGS_REG))])]
20335 [(match_scratch:SI 3 "r")
20336 (parallel [(set (match_operand:SI 0 "register_operand" "")
20337 (mult:SI (match_operand:SI 1 "memory_operand" "")
20338 (match_operand:SI 2 "immediate_operand" "")))
20339 (clobber (reg:CC FLAGS_REG))])]
20340 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20341 && !satisfies_constraint_K (operands[2])"
20342 [(set (match_dup 3) (match_dup 1))
20343 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20344 (clobber (reg:CC FLAGS_REG))])]
20348 [(match_scratch:SI 3 "r")
20349 (parallel [(set (match_operand:DI 0 "register_operand" "")
20351 (mult:SI (match_operand:SI 1 "memory_operand" "")
20352 (match_operand:SI 2 "immediate_operand" ""))))
20353 (clobber (reg:CC FLAGS_REG))])]
20354 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20355 && !satisfies_constraint_K (operands[2])"
20356 [(set (match_dup 3) (match_dup 1))
20357 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20358 (clobber (reg:CC FLAGS_REG))])]
20361 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20362 ;; Convert it into imul reg, reg
20363 ;; It would be better to force assembler to encode instruction using long
20364 ;; immediate, but there is apparently no way to do so.
20366 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20367 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20368 (match_operand:DI 2 "const_int_operand" "")))
20369 (clobber (reg:CC FLAGS_REG))])
20370 (match_scratch:DI 3 "r")]
20371 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20372 && satisfies_constraint_K (operands[2])"
20373 [(set (match_dup 3) (match_dup 2))
20374 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20375 (clobber (reg:CC FLAGS_REG))])]
20377 if (!rtx_equal_p (operands[0], operands[1]))
20378 emit_move_insn (operands[0], operands[1]);
20382 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20383 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20384 (match_operand:SI 2 "const_int_operand" "")))
20385 (clobber (reg:CC FLAGS_REG))])
20386 (match_scratch:SI 3 "r")]
20387 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20388 && satisfies_constraint_K (operands[2])"
20389 [(set (match_dup 3) (match_dup 2))
20390 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20391 (clobber (reg:CC FLAGS_REG))])]
20393 if (!rtx_equal_p (operands[0], operands[1]))
20394 emit_move_insn (operands[0], operands[1]);
20398 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20399 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20400 (match_operand:HI 2 "immediate_operand" "")))
20401 (clobber (reg:CC FLAGS_REG))])
20402 (match_scratch:HI 3 "r")]
20403 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20404 [(set (match_dup 3) (match_dup 2))
20405 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20406 (clobber (reg:CC FLAGS_REG))])]
20408 if (!rtx_equal_p (operands[0], operands[1]))
20409 emit_move_insn (operands[0], operands[1]);
20412 ;; After splitting up read-modify operations, array accesses with memory
20413 ;; operands might end up in form:
20415 ;; movl 4(%esp), %edx
20417 ;; instead of pre-splitting:
20419 ;; addl 4(%esp), %eax
20421 ;; movl 4(%esp), %edx
20422 ;; leal (%edx,%eax,4), %eax
20425 [(parallel [(set (match_operand 0 "register_operand" "")
20426 (ashift (match_operand 1 "register_operand" "")
20427 (match_operand 2 "const_int_operand" "")))
20428 (clobber (reg:CC FLAGS_REG))])
20429 (set (match_operand 3 "register_operand")
20430 (match_operand 4 "x86_64_general_operand" ""))
20431 (parallel [(set (match_operand 5 "register_operand" "")
20432 (plus (match_operand 6 "register_operand" "")
20433 (match_operand 7 "register_operand" "")))
20434 (clobber (reg:CC FLAGS_REG))])]
20435 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20436 /* Validate MODE for lea. */
20437 && ((!TARGET_PARTIAL_REG_STALL
20438 && (GET_MODE (operands[0]) == QImode
20439 || GET_MODE (operands[0]) == HImode))
20440 || GET_MODE (operands[0]) == SImode
20441 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20442 /* We reorder load and the shift. */
20443 && !rtx_equal_p (operands[1], operands[3])
20444 && !reg_overlap_mentioned_p (operands[0], operands[4])
20445 /* Last PLUS must consist of operand 0 and 3. */
20446 && !rtx_equal_p (operands[0], operands[3])
20447 && (rtx_equal_p (operands[3], operands[6])
20448 || rtx_equal_p (operands[3], operands[7]))
20449 && (rtx_equal_p (operands[0], operands[6])
20450 || rtx_equal_p (operands[0], operands[7]))
20451 /* The intermediate operand 0 must die or be same as output. */
20452 && (rtx_equal_p (operands[0], operands[5])
20453 || peep2_reg_dead_p (3, operands[0]))"
20454 [(set (match_dup 3) (match_dup 4))
20455 (set (match_dup 0) (match_dup 1))]
20457 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20458 int scale = 1 << INTVAL (operands[2]);
20459 rtx index = gen_lowpart (Pmode, operands[1]);
20460 rtx base = gen_lowpart (Pmode, operands[3]);
20461 rtx dest = gen_lowpart (mode, operands[5]);
20463 operands[1] = gen_rtx_PLUS (Pmode, base,
20464 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20466 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20467 operands[0] = dest;
20470 ;; Call-value patterns last so that the wildcard operand does not
20471 ;; disrupt insn-recog's switch tables.
20473 (define_insn "*call_value_pop_0"
20474 [(set (match_operand 0 "" "")
20475 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20476 (match_operand:SI 2 "" "")))
20477 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20478 (match_operand:SI 3 "immediate_operand" "")))]
20481 if (SIBLING_CALL_P (insn))
20484 return "call\t%P1";
20486 [(set_attr "type" "callv")])
20488 (define_insn "*call_value_pop_1"
20489 [(set (match_operand 0 "" "")
20490 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20491 (match_operand:SI 2 "" "")))
20492 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20493 (match_operand:SI 3 "immediate_operand" "i")))]
20496 if (constant_call_address_operand (operands[1], Pmode))
20498 if (SIBLING_CALL_P (insn))
20501 return "call\t%P1";
20503 if (SIBLING_CALL_P (insn))
20506 return "call\t%A1";
20508 [(set_attr "type" "callv")])
20510 (define_insn "*call_value_0"
20511 [(set (match_operand 0 "" "")
20512 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20513 (match_operand:SI 2 "" "")))]
20516 if (SIBLING_CALL_P (insn))
20519 return "call\t%P1";
20521 [(set_attr "type" "callv")])
20523 (define_insn "*call_value_0_rex64"
20524 [(set (match_operand 0 "" "")
20525 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20526 (match_operand:DI 2 "const_int_operand" "")))]
20529 if (SIBLING_CALL_P (insn))
20532 return "call\t%P1";
20534 [(set_attr "type" "callv")])
20536 (define_insn "*call_value_1"
20537 [(set (match_operand 0 "" "")
20538 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20539 (match_operand:SI 2 "" "")))]
20540 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20542 if (constant_call_address_operand (operands[1], Pmode))
20543 return "call\t%P1";
20544 return "call\t%A1";
20546 [(set_attr "type" "callv")])
20548 (define_insn "*sibcall_value_1"
20549 [(set (match_operand 0 "" "")
20550 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20551 (match_operand:SI 2 "" "")))]
20552 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20554 if (constant_call_address_operand (operands[1], Pmode))
20558 [(set_attr "type" "callv")])
20560 (define_insn "*call_value_1_rex64"
20561 [(set (match_operand 0 "" "")
20562 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20563 (match_operand:DI 2 "" "")))]
20564 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20565 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20567 if (constant_call_address_operand (operands[1], Pmode))
20568 return "call\t%P1";
20569 return "call\t%A1";
20571 [(set_attr "type" "callv")])
20573 (define_insn "*call_value_1_rex64_large"
20574 [(set (match_operand 0 "" "")
20575 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20576 (match_operand:DI 2 "" "")))]
20577 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20579 [(set_attr "type" "callv")])
20581 (define_insn "*sibcall_value_1_rex64"
20582 [(set (match_operand 0 "" "")
20583 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20584 (match_operand:DI 2 "" "")))]
20585 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20587 [(set_attr "type" "callv")])
20589 (define_insn "*sibcall_value_1_rex64_v"
20590 [(set (match_operand 0 "" "")
20591 (call (mem:QI (reg:DI R11_REG))
20592 (match_operand:DI 1 "" "")))]
20593 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20595 [(set_attr "type" "callv")])
20597 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20598 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20599 ;; caught for use by garbage collectors and the like. Using an insn that
20600 ;; maps to SIGILL makes it more likely the program will rightfully die.
20601 ;; Keeping with tradition, "6" is in honor of #UD.
20602 (define_insn "trap"
20603 [(trap_if (const_int 1) (const_int 6))]
20605 { return ASM_SHORT "0x0b0f"; }
20606 [(set_attr "length" "2")])
20608 (define_expand "sse_prologue_save"
20609 [(parallel [(set (match_operand:BLK 0 "" "")
20610 (unspec:BLK [(reg:DI 21)
20617 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20618 (use (match_operand:DI 1 "register_operand" ""))
20619 (use (match_operand:DI 2 "immediate_operand" ""))
20620 (use (label_ref:DI (match_operand 3 "" "")))])]
20624 (define_insn "*sse_prologue_save_insn"
20625 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20626 (match_operand:DI 4 "const_int_operand" "n")))
20627 (unspec:BLK [(reg:DI 21)
20634 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20635 (use (match_operand:DI 1 "register_operand" "r"))
20636 (use (match_operand:DI 2 "const_int_operand" "i"))
20637 (use (label_ref:DI (match_operand 3 "" "X")))]
20639 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20640 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20644 operands[0] = gen_rtx_MEM (Pmode,
20645 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20646 output_asm_insn (\"jmp\\t%A1\", operands);
20647 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20649 operands[4] = adjust_address (operands[0], DImode, i*16);
20650 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20651 PUT_MODE (operands[4], TImode);
20652 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20653 output_asm_insn (\"rex\", operands);
20654 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20656 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20657 CODE_LABEL_NUMBER (operands[3]));
20661 [(set_attr "type" "other")
20662 (set_attr "length_immediate" "0")
20663 (set_attr "length_address" "0")
20664 (set_attr "length" "135")
20665 (set_attr "memory" "store")
20666 (set_attr "modrm" "0")
20667 (set_attr "mode" "DI")])
20669 (define_expand "prefetch"
20670 [(prefetch (match_operand 0 "address_operand" "")
20671 (match_operand:SI 1 "const_int_operand" "")
20672 (match_operand:SI 2 "const_int_operand" ""))]
20673 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20675 int rw = INTVAL (operands[1]);
20676 int locality = INTVAL (operands[2]);
20678 gcc_assert (rw == 0 || rw == 1);
20679 gcc_assert (locality >= 0 && locality <= 3);
20680 gcc_assert (GET_MODE (operands[0]) == Pmode
20681 || GET_MODE (operands[0]) == VOIDmode);
20683 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20684 supported by SSE counterpart or the SSE prefetch is not available
20685 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20687 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20688 operands[2] = GEN_INT (3);
20690 operands[1] = const0_rtx;
20693 (define_insn "*prefetch_sse"
20694 [(prefetch (match_operand:SI 0 "address_operand" "p")
20696 (match_operand:SI 1 "const_int_operand" ""))]
20697 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20699 static const char * const patterns[4] = {
20700 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20703 int locality = INTVAL (operands[1]);
20704 gcc_assert (locality >= 0 && locality <= 3);
20706 return patterns[locality];
20708 [(set_attr "type" "sse")
20709 (set_attr "memory" "none")])
20711 (define_insn "*prefetch_sse_rex"
20712 [(prefetch (match_operand:DI 0 "address_operand" "p")
20714 (match_operand:SI 1 "const_int_operand" ""))]
20715 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20717 static const char * const patterns[4] = {
20718 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20721 int locality = INTVAL (operands[1]);
20722 gcc_assert (locality >= 0 && locality <= 3);
20724 return patterns[locality];
20726 [(set_attr "type" "sse")
20727 (set_attr "memory" "none")])
20729 (define_insn "*prefetch_3dnow"
20730 [(prefetch (match_operand:SI 0 "address_operand" "p")
20731 (match_operand:SI 1 "const_int_operand" "n")
20733 "TARGET_3DNOW && !TARGET_64BIT"
20735 if (INTVAL (operands[1]) == 0)
20736 return "prefetch\t%a0";
20738 return "prefetchw\t%a0";
20740 [(set_attr "type" "mmx")
20741 (set_attr "memory" "none")])
20743 (define_insn "*prefetch_3dnow_rex"
20744 [(prefetch (match_operand:DI 0 "address_operand" "p")
20745 (match_operand:SI 1 "const_int_operand" "n")
20747 "TARGET_3DNOW && TARGET_64BIT"
20749 if (INTVAL (operands[1]) == 0)
20750 return "prefetch\t%a0";
20752 return "prefetchw\t%a0";
20754 [(set_attr "type" "mmx")
20755 (set_attr "memory" "none")])
20757 (define_expand "stack_protect_set"
20758 [(match_operand 0 "memory_operand" "")
20759 (match_operand 1 "memory_operand" "")]
20762 #ifdef TARGET_THREAD_SSP_OFFSET
20764 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20765 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20767 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20768 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20771 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20773 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20778 (define_insn "stack_protect_set_si"
20779 [(set (match_operand:SI 0 "memory_operand" "=m")
20780 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20781 (set (match_scratch:SI 2 "=&r") (const_int 0))
20782 (clobber (reg:CC FLAGS_REG))]
20784 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20785 [(set_attr "type" "multi")])
20787 (define_insn "stack_protect_set_di"
20788 [(set (match_operand:DI 0 "memory_operand" "=m")
20789 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20790 (set (match_scratch:DI 2 "=&r") (const_int 0))
20791 (clobber (reg:CC FLAGS_REG))]
20793 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20794 [(set_attr "type" "multi")])
20796 (define_insn "stack_tls_protect_set_si"
20797 [(set (match_operand:SI 0 "memory_operand" "=m")
20798 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20799 (set (match_scratch:SI 2 "=&r") (const_int 0))
20800 (clobber (reg:CC FLAGS_REG))]
20802 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20803 [(set_attr "type" "multi")])
20805 (define_insn "stack_tls_protect_set_di"
20806 [(set (match_operand:DI 0 "memory_operand" "=m")
20807 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20808 (set (match_scratch:DI 2 "=&r") (const_int 0))
20809 (clobber (reg:CC FLAGS_REG))]
20812 /* The kernel uses a different segment register for performance reasons; a
20813 system call would not have to trash the userspace segment register,
20814 which would be expensive */
20815 if (ix86_cmodel != CM_KERNEL)
20816 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20818 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20820 [(set_attr "type" "multi")])
20822 (define_expand "stack_protect_test"
20823 [(match_operand 0 "memory_operand" "")
20824 (match_operand 1 "memory_operand" "")
20825 (match_operand 2 "" "")]
20828 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20829 ix86_compare_op0 = operands[0];
20830 ix86_compare_op1 = operands[1];
20831 ix86_compare_emitted = flags;
20833 #ifdef TARGET_THREAD_SSP_OFFSET
20835 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20836 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20838 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20839 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20842 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20844 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20846 emit_jump_insn (gen_beq (operands[2]));
20850 (define_insn "stack_protect_test_si"
20851 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20852 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20853 (match_operand:SI 2 "memory_operand" "m")]
20855 (clobber (match_scratch:SI 3 "=&r"))]
20857 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20858 [(set_attr "type" "multi")])
20860 (define_insn "stack_protect_test_di"
20861 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20862 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20863 (match_operand:DI 2 "memory_operand" "m")]
20865 (clobber (match_scratch:DI 3 "=&r"))]
20867 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20868 [(set_attr "type" "multi")])
20870 (define_insn "stack_tls_protect_test_si"
20871 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20872 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20873 (match_operand:SI 2 "const_int_operand" "i")]
20874 UNSPEC_SP_TLS_TEST))
20875 (clobber (match_scratch:SI 3 "=r"))]
20877 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20878 [(set_attr "type" "multi")])
20880 (define_insn "stack_tls_protect_test_di"
20881 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20882 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20883 (match_operand:DI 2 "const_int_operand" "i")]
20884 UNSPEC_SP_TLS_TEST))
20885 (clobber (match_scratch:DI 3 "=r"))]
20888 /* The kernel uses a different segment register for performance reasons; a
20889 system call would not have to trash the userspace segment register,
20890 which would be expensive */
20891 if (ix86_cmodel != CM_KERNEL)
20892 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20894 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20896 [(set_attr "type" "multi")])
20900 (include "sync.md")