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)
178 (UNSPEC_PCMPESTR 144)
179 (UNSPEC_PCMPISTR 145)
183 [(UNSPECV_BLOCKAGE 0)
184 (UNSPECV_STACK_PROBE 1)
193 (UNSPECV_CMPXCHG_1 10)
194 (UNSPECV_CMPXCHG_2 11)
199 ;; Registers by name.
210 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
213 ;; In C guard expressions, put expressions which may be compile-time
214 ;; constants first. This allows for better optimization. For
215 ;; example, write "TARGET_64BIT && reload_completed", not
216 ;; "reload_completed && TARGET_64BIT".
219 ;; Processor type. This attribute must exactly match the processor_type
220 ;; enumeration in i386.h.
221 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
222 nocona,core2,generic32,generic64,amdfam10"
223 (const (symbol_ref "ix86_tune")))
225 ;; A basic instruction type. Refinements due to arguments to be
226 ;; provided in other attributes.
229 alu,alu1,negnot,imov,imovx,lea,
230 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
231 icmp,test,ibr,setcc,icmov,
232 push,pop,call,callv,leave,
234 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
235 sselog,sselog1,sseiadd,sseishft,sseimul,
236 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
237 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
238 (const_string "other"))
240 ;; Main data type used by the insn
242 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
243 (const_string "unknown"))
245 ;; The CPU unit operations uses.
246 (define_attr "unit" "integer,i387,sse,mmx,unknown"
247 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
248 (const_string "i387")
249 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
250 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
252 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
254 (eq_attr "type" "other")
255 (const_string "unknown")]
256 (const_string "integer")))
258 ;; The (bounding maximum) length of an instruction immediate.
259 (define_attr "length_immediate" ""
260 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
263 (eq_attr "unit" "i387,sse,mmx")
265 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
267 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
268 (eq_attr "type" "imov,test")
269 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
270 (eq_attr "type" "call")
271 (if_then_else (match_operand 0 "constant_call_address_operand" "")
274 (eq_attr "type" "callv")
275 (if_then_else (match_operand 1 "constant_call_address_operand" "")
278 ;; We don't know the size before shorten_branches. Expect
279 ;; the instruction to fit for better scheduling.
280 (eq_attr "type" "ibr")
283 (symbol_ref "/* Update immediate_length and other attributes! */
284 gcc_unreachable (),1")))
286 ;; The (bounding maximum) length of an instruction address.
287 (define_attr "length_address" ""
288 (cond [(eq_attr "type" "str,other,multi,fxch")
290 (and (eq_attr "type" "call")
291 (match_operand 0 "constant_call_address_operand" ""))
293 (and (eq_attr "type" "callv")
294 (match_operand 1 "constant_call_address_operand" ""))
297 (symbol_ref "ix86_attr_length_address_default (insn)")))
299 ;; Set when length prefix is used.
300 (define_attr "prefix_data16" ""
301 (if_then_else (ior (eq_attr "mode" "HI")
302 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
306 ;; Set when string REP prefix is used.
307 (define_attr "prefix_rep" ""
308 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
312 ;; Set when 0f opcode prefix is used.
313 (define_attr "prefix_0f" ""
315 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
316 (eq_attr "unit" "sse,mmx"))
320 ;; Set when REX opcode prefix is used.
321 (define_attr "prefix_rex" ""
322 (cond [(and (eq_attr "mode" "DI")
323 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
325 (and (eq_attr "mode" "QI")
326 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
329 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
335 ;; There are also additional prefixes in SSSE3.
336 (define_attr "prefix_extra" "" (const_int 0))
338 ;; Set when modrm byte is used.
339 (define_attr "modrm" ""
340 (cond [(eq_attr "type" "str,leave")
342 (eq_attr "unit" "i387")
344 (and (eq_attr "type" "incdec")
345 (ior (match_operand:SI 1 "register_operand" "")
346 (match_operand:HI 1 "register_operand" "")))
348 (and (eq_attr "type" "push")
349 (not (match_operand 1 "memory_operand" "")))
351 (and (eq_attr "type" "pop")
352 (not (match_operand 0 "memory_operand" "")))
354 (and (eq_attr "type" "imov")
355 (ior (and (match_operand 0 "register_operand" "")
356 (match_operand 1 "immediate_operand" ""))
357 (ior (and (match_operand 0 "ax_reg_operand" "")
358 (match_operand 1 "memory_displacement_only_operand" ""))
359 (and (match_operand 0 "memory_displacement_only_operand" "")
360 (match_operand 1 "ax_reg_operand" "")))))
362 (and (eq_attr "type" "call")
363 (match_operand 0 "constant_call_address_operand" ""))
365 (and (eq_attr "type" "callv")
366 (match_operand 1 "constant_call_address_operand" ""))
371 ;; The (bounding maximum) length of an instruction in bytes.
372 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
373 ;; Later we may want to split them and compute proper length as for
375 (define_attr "length" ""
376 (cond [(eq_attr "type" "other,multi,fistp,frndint")
378 (eq_attr "type" "fcmp")
380 (eq_attr "unit" "i387")
382 (plus (attr "prefix_data16")
383 (attr "length_address")))]
384 (plus (plus (attr "modrm")
385 (plus (attr "prefix_0f")
386 (plus (attr "prefix_rex")
387 (plus (attr "prefix_extra")
389 (plus (attr "prefix_rep")
390 (plus (attr "prefix_data16")
391 (plus (attr "length_immediate")
392 (attr "length_address")))))))
394 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
395 ;; `store' if there is a simple memory reference therein, or `unknown'
396 ;; if the instruction is complex.
398 (define_attr "memory" "none,load,store,both,unknown"
399 (cond [(eq_attr "type" "other,multi,str")
400 (const_string "unknown")
401 (eq_attr "type" "lea,fcmov,fpspc")
402 (const_string "none")
403 (eq_attr "type" "fistp,leave")
404 (const_string "both")
405 (eq_attr "type" "frndint")
406 (const_string "load")
407 (eq_attr "type" "push")
408 (if_then_else (match_operand 1 "memory_operand" "")
409 (const_string "both")
410 (const_string "store"))
411 (eq_attr "type" "pop")
412 (if_then_else (match_operand 0 "memory_operand" "")
413 (const_string "both")
414 (const_string "load"))
415 (eq_attr "type" "setcc")
416 (if_then_else (match_operand 0 "memory_operand" "")
417 (const_string "store")
418 (const_string "none"))
419 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
420 (if_then_else (ior (match_operand 0 "memory_operand" "")
421 (match_operand 1 "memory_operand" ""))
422 (const_string "load")
423 (const_string "none"))
424 (eq_attr "type" "ibr")
425 (if_then_else (match_operand 0 "memory_operand" "")
426 (const_string "load")
427 (const_string "none"))
428 (eq_attr "type" "call")
429 (if_then_else (match_operand 0 "constant_call_address_operand" "")
430 (const_string "none")
431 (const_string "load"))
432 (eq_attr "type" "callv")
433 (if_then_else (match_operand 1 "constant_call_address_operand" "")
434 (const_string "none")
435 (const_string "load"))
436 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
437 (match_operand 1 "memory_operand" ""))
438 (const_string "both")
439 (and (match_operand 0 "memory_operand" "")
440 (match_operand 1 "memory_operand" ""))
441 (const_string "both")
442 (match_operand 0 "memory_operand" "")
443 (const_string "store")
444 (match_operand 1 "memory_operand" "")
445 (const_string "load")
447 "!alu1,negnot,ishift1,
448 imov,imovx,icmp,test,bitmanip,
450 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
451 mmx,mmxmov,mmxcmp,mmxcvt")
452 (match_operand 2 "memory_operand" ""))
453 (const_string "load")
454 (and (eq_attr "type" "icmov")
455 (match_operand 3 "memory_operand" ""))
456 (const_string "load")
458 (const_string "none")))
460 ;; Indicates if an instruction has both an immediate and a displacement.
462 (define_attr "imm_disp" "false,true,unknown"
463 (cond [(eq_attr "type" "other,multi")
464 (const_string "unknown")
465 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
466 (and (match_operand 0 "memory_displacement_operand" "")
467 (match_operand 1 "immediate_operand" "")))
468 (const_string "true")
469 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
470 (and (match_operand 0 "memory_displacement_operand" "")
471 (match_operand 2 "immediate_operand" "")))
472 (const_string "true")
474 (const_string "false")))
476 ;; Indicates if an FP operation has an integer source.
478 (define_attr "fp_int_src" "false,true"
479 (const_string "false"))
481 ;; Defines rounding mode of an FP operation.
483 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
484 (const_string "any"))
486 ;; Describe a user's asm statement.
487 (define_asm_attributes
488 [(set_attr "length" "128")
489 (set_attr "type" "multi")])
491 ;; All x87 floating point modes
492 (define_mode_macro X87MODEF [SF DF XF])
494 ;; x87 SFmode and DFMode floating point modes
495 (define_mode_macro X87MODEF12 [SF DF])
497 ;; All integer modes handled by x87 fisttp operator.
498 (define_mode_macro X87MODEI [HI SI DI])
500 ;; All integer modes handled by integer x87 operators.
501 (define_mode_macro X87MODEI12 [HI SI])
503 ;; All SSE floating point modes
504 (define_mode_macro SSEMODEF [SF DF])
506 ;; All integer modes handled by SSE cvtts?2si* operators.
507 (define_mode_macro SSEMODEI24 [SI DI])
509 ;; SSE asm suffix for floating point modes
510 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
512 ;; SSE vector mode corresponding to a scalar mode
513 (define_mode_attr ssevecmode
514 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
516 ;; Scheduling descriptions
518 (include "pentium.md")
521 (include "athlon.md")
525 ;; Operand and operator predicates and constraints
527 (include "predicates.md")
528 (include "constraints.md")
531 ;; Compare instructions.
533 ;; All compare insns have expanders that save the operands away without
534 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
535 ;; after the cmp) will actually emit the cmpM.
537 (define_expand "cmpti"
538 [(set (reg:CC FLAGS_REG)
539 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
540 (match_operand:TI 1 "x86_64_general_operand" "")))]
543 if (MEM_P (operands[0]) && MEM_P (operands[1]))
544 operands[0] = force_reg (TImode, operands[0]);
545 ix86_compare_op0 = operands[0];
546 ix86_compare_op1 = operands[1];
550 (define_expand "cmpdi"
551 [(set (reg:CC FLAGS_REG)
552 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
553 (match_operand:DI 1 "x86_64_general_operand" "")))]
556 if (MEM_P (operands[0]) && MEM_P (operands[1]))
557 operands[0] = force_reg (DImode, operands[0]);
558 ix86_compare_op0 = operands[0];
559 ix86_compare_op1 = operands[1];
563 (define_expand "cmpsi"
564 [(set (reg:CC FLAGS_REG)
565 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
566 (match_operand:SI 1 "general_operand" "")))]
569 if (MEM_P (operands[0]) && MEM_P (operands[1]))
570 operands[0] = force_reg (SImode, operands[0]);
571 ix86_compare_op0 = operands[0];
572 ix86_compare_op1 = operands[1];
576 (define_expand "cmphi"
577 [(set (reg:CC FLAGS_REG)
578 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
579 (match_operand:HI 1 "general_operand" "")))]
582 if (MEM_P (operands[0]) && MEM_P (operands[1]))
583 operands[0] = force_reg (HImode, operands[0]);
584 ix86_compare_op0 = operands[0];
585 ix86_compare_op1 = operands[1];
589 (define_expand "cmpqi"
590 [(set (reg:CC FLAGS_REG)
591 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
592 (match_operand:QI 1 "general_operand" "")))]
595 if (MEM_P (operands[0]) && MEM_P (operands[1]))
596 operands[0] = force_reg (QImode, operands[0]);
597 ix86_compare_op0 = operands[0];
598 ix86_compare_op1 = operands[1];
602 (define_insn "cmpdi_ccno_1_rex64"
603 [(set (reg FLAGS_REG)
604 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
605 (match_operand:DI 1 "const0_operand" "n,n")))]
606 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
609 cmp{q}\t{%1, %0|%0, %1}"
610 [(set_attr "type" "test,icmp")
611 (set_attr "length_immediate" "0,1")
612 (set_attr "mode" "DI")])
614 (define_insn "*cmpdi_minus_1_rex64"
615 [(set (reg FLAGS_REG)
616 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
617 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
619 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
620 "cmp{q}\t{%1, %0|%0, %1}"
621 [(set_attr "type" "icmp")
622 (set_attr "mode" "DI")])
624 (define_expand "cmpdi_1_rex64"
625 [(set (reg:CC FLAGS_REG)
626 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
627 (match_operand:DI 1 "general_operand" "")))]
631 (define_insn "cmpdi_1_insn_rex64"
632 [(set (reg FLAGS_REG)
633 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
634 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
635 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
636 "cmp{q}\t{%1, %0|%0, %1}"
637 [(set_attr "type" "icmp")
638 (set_attr "mode" "DI")])
641 (define_insn "*cmpsi_ccno_1"
642 [(set (reg FLAGS_REG)
643 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
644 (match_operand:SI 1 "const0_operand" "n,n")))]
645 "ix86_match_ccmode (insn, CCNOmode)"
648 cmp{l}\t{%1, %0|%0, %1}"
649 [(set_attr "type" "test,icmp")
650 (set_attr "length_immediate" "0,1")
651 (set_attr "mode" "SI")])
653 (define_insn "*cmpsi_minus_1"
654 [(set (reg FLAGS_REG)
655 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
656 (match_operand:SI 1 "general_operand" "ri,mr"))
658 "ix86_match_ccmode (insn, CCGOCmode)"
659 "cmp{l}\t{%1, %0|%0, %1}"
660 [(set_attr "type" "icmp")
661 (set_attr "mode" "SI")])
663 (define_expand "cmpsi_1"
664 [(set (reg:CC FLAGS_REG)
665 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
666 (match_operand:SI 1 "general_operand" "ri,mr")))]
670 (define_insn "*cmpsi_1_insn"
671 [(set (reg FLAGS_REG)
672 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
673 (match_operand:SI 1 "general_operand" "ri,mr")))]
674 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
675 && ix86_match_ccmode (insn, CCmode)"
676 "cmp{l}\t{%1, %0|%0, %1}"
677 [(set_attr "type" "icmp")
678 (set_attr "mode" "SI")])
680 (define_insn "*cmphi_ccno_1"
681 [(set (reg FLAGS_REG)
682 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
683 (match_operand:HI 1 "const0_operand" "n,n")))]
684 "ix86_match_ccmode (insn, CCNOmode)"
687 cmp{w}\t{%1, %0|%0, %1}"
688 [(set_attr "type" "test,icmp")
689 (set_attr "length_immediate" "0,1")
690 (set_attr "mode" "HI")])
692 (define_insn "*cmphi_minus_1"
693 [(set (reg FLAGS_REG)
694 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
695 (match_operand:HI 1 "general_operand" "ri,mr"))
697 "ix86_match_ccmode (insn, CCGOCmode)"
698 "cmp{w}\t{%1, %0|%0, %1}"
699 [(set_attr "type" "icmp")
700 (set_attr "mode" "HI")])
702 (define_insn "*cmphi_1"
703 [(set (reg FLAGS_REG)
704 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
705 (match_operand:HI 1 "general_operand" "ri,mr")))]
706 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
707 && ix86_match_ccmode (insn, CCmode)"
708 "cmp{w}\t{%1, %0|%0, %1}"
709 [(set_attr "type" "icmp")
710 (set_attr "mode" "HI")])
712 (define_insn "*cmpqi_ccno_1"
713 [(set (reg FLAGS_REG)
714 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
715 (match_operand:QI 1 "const0_operand" "n,n")))]
716 "ix86_match_ccmode (insn, CCNOmode)"
719 cmp{b}\t{$0, %0|%0, 0}"
720 [(set_attr "type" "test,icmp")
721 (set_attr "length_immediate" "0,1")
722 (set_attr "mode" "QI")])
724 (define_insn "*cmpqi_1"
725 [(set (reg FLAGS_REG)
726 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
727 (match_operand:QI 1 "general_operand" "qi,mq")))]
728 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
729 && ix86_match_ccmode (insn, CCmode)"
730 "cmp{b}\t{%1, %0|%0, %1}"
731 [(set_attr "type" "icmp")
732 (set_attr "mode" "QI")])
734 (define_insn "*cmpqi_minus_1"
735 [(set (reg FLAGS_REG)
736 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
737 (match_operand:QI 1 "general_operand" "qi,mq"))
739 "ix86_match_ccmode (insn, CCGOCmode)"
740 "cmp{b}\t{%1, %0|%0, %1}"
741 [(set_attr "type" "icmp")
742 (set_attr "mode" "QI")])
744 (define_insn "*cmpqi_ext_1"
745 [(set (reg FLAGS_REG)
747 (match_operand:QI 0 "general_operand" "Qm")
750 (match_operand 1 "ext_register_operand" "Q")
753 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
754 "cmp{b}\t{%h1, %0|%0, %h1}"
755 [(set_attr "type" "icmp")
756 (set_attr "mode" "QI")])
758 (define_insn "*cmpqi_ext_1_rex64"
759 [(set (reg FLAGS_REG)
761 (match_operand:QI 0 "register_operand" "Q")
764 (match_operand 1 "ext_register_operand" "Q")
767 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
768 "cmp{b}\t{%h1, %0|%0, %h1}"
769 [(set_attr "type" "icmp")
770 (set_attr "mode" "QI")])
772 (define_insn "*cmpqi_ext_2"
773 [(set (reg FLAGS_REG)
777 (match_operand 0 "ext_register_operand" "Q")
780 (match_operand:QI 1 "const0_operand" "n")))]
781 "ix86_match_ccmode (insn, CCNOmode)"
783 [(set_attr "type" "test")
784 (set_attr "length_immediate" "0")
785 (set_attr "mode" "QI")])
787 (define_expand "cmpqi_ext_3"
788 [(set (reg:CC FLAGS_REG)
792 (match_operand 0 "ext_register_operand" "")
795 (match_operand:QI 1 "general_operand" "")))]
799 (define_insn "cmpqi_ext_3_insn"
800 [(set (reg FLAGS_REG)
804 (match_operand 0 "ext_register_operand" "Q")
807 (match_operand:QI 1 "general_operand" "Qmn")))]
808 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
809 "cmp{b}\t{%1, %h0|%h0, %1}"
810 [(set_attr "type" "icmp")
811 (set_attr "mode" "QI")])
813 (define_insn "cmpqi_ext_3_insn_rex64"
814 [(set (reg FLAGS_REG)
818 (match_operand 0 "ext_register_operand" "Q")
821 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
822 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
823 "cmp{b}\t{%1, %h0|%h0, %1}"
824 [(set_attr "type" "icmp")
825 (set_attr "mode" "QI")])
827 (define_insn "*cmpqi_ext_4"
828 [(set (reg FLAGS_REG)
832 (match_operand 0 "ext_register_operand" "Q")
837 (match_operand 1 "ext_register_operand" "Q")
840 "ix86_match_ccmode (insn, CCmode)"
841 "cmp{b}\t{%h1, %h0|%h0, %h1}"
842 [(set_attr "type" "icmp")
843 (set_attr "mode" "QI")])
845 ;; These implement float point compares.
846 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
847 ;; which would allow mix and match FP modes on the compares. Which is what
848 ;; the old patterns did, but with many more of them.
850 (define_expand "cmpxf"
851 [(set (reg:CC FLAGS_REG)
852 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
853 (match_operand:XF 1 "nonmemory_operand" "")))]
856 ix86_compare_op0 = operands[0];
857 ix86_compare_op1 = operands[1];
861 (define_expand "cmp<mode>"
862 [(set (reg:CC FLAGS_REG)
863 (compare:CC (match_operand:SSEMODEF 0 "cmp_fp_expander_operand" "")
864 (match_operand:SSEMODEF 1 "cmp_fp_expander_operand" "")))]
865 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
867 ix86_compare_op0 = operands[0];
868 ix86_compare_op1 = operands[1];
872 ;; FP compares, step 1:
873 ;; Set the FP condition codes.
875 ;; CCFPmode compare with exceptions
876 ;; CCFPUmode compare with no exceptions
878 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
879 ;; used to manage the reg stack popping would not be preserved.
881 (define_insn "*cmpfp_0"
882 [(set (match_operand:HI 0 "register_operand" "=a")
885 (match_operand 1 "register_operand" "f")
886 (match_operand 2 "const0_operand" "X"))]
888 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
889 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
890 "* return output_fp_compare (insn, operands, 0, 0);"
891 [(set_attr "type" "multi")
892 (set_attr "unit" "i387")
894 (cond [(match_operand:SF 1 "" "")
896 (match_operand:DF 1 "" "")
899 (const_string "XF")))])
901 (define_insn "*cmpfp_xf"
902 [(set (match_operand:HI 0 "register_operand" "=a")
905 (match_operand:XF 1 "register_operand" "f")
906 (match_operand:XF 2 "register_operand" "f"))]
909 "* return output_fp_compare (insn, operands, 0, 0);"
910 [(set_attr "type" "multi")
911 (set_attr "unit" "i387")
912 (set_attr "mode" "XF")])
914 (define_insn "*cmpfp_<mode>"
915 [(set (match_operand:HI 0 "register_operand" "=a")
918 (match_operand:X87MODEF12 1 "register_operand" "f")
919 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm"))]
922 "* return output_fp_compare (insn, operands, 0, 0);"
923 [(set_attr "type" "multi")
924 (set_attr "unit" "i387")
925 (set_attr "mode" "<MODE>")])
927 (define_insn "*cmpfp_u"
928 [(set (match_operand:HI 0 "register_operand" "=a")
931 (match_operand 1 "register_operand" "f")
932 (match_operand 2 "register_operand" "f"))]
934 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
935 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
936 "* return output_fp_compare (insn, operands, 0, 1);"
937 [(set_attr "type" "multi")
938 (set_attr "unit" "i387")
940 (cond [(match_operand:SF 1 "" "")
942 (match_operand:DF 1 "" "")
945 (const_string "XF")))])
947 (define_insn "*cmpfp_<mode>"
948 [(set (match_operand:HI 0 "register_operand" "=a")
951 (match_operand 1 "register_operand" "f")
952 (match_operator 3 "float_operator"
953 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
955 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
956 && TARGET_USE_<MODE>MODE_FIOP
957 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
958 "* return output_fp_compare (insn, operands, 0, 0);"
959 [(set_attr "type" "multi")
960 (set_attr "unit" "i387")
961 (set_attr "fp_int_src" "true")
962 (set_attr "mode" "<MODE>")])
964 ;; FP compares, step 2
965 ;; Move the fpsw to ax.
967 (define_insn "x86_fnstsw_1"
968 [(set (match_operand:HI 0 "register_operand" "=a")
969 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
972 [(set_attr "length" "2")
973 (set_attr "mode" "SI")
974 (set_attr "unit" "i387")])
976 ;; FP compares, step 3
977 ;; Get ax into flags, general case.
979 (define_insn "x86_sahf_1"
980 [(set (reg:CC FLAGS_REG)
981 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
985 #ifdef HAVE_AS_IX86_SAHF
988 return ".byte\t0x9e";
991 [(set_attr "length" "1")
992 (set_attr "athlon_decode" "vector")
993 (set_attr "amdfam10_decode" "direct")
994 (set_attr "mode" "SI")])
996 ;; Pentium Pro can do steps 1 through 3 in one go.
997 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
998 (define_insn "*cmpfp_i_mixed"
999 [(set (reg:CCFP FLAGS_REG)
1000 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1001 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1002 "TARGET_MIX_SSE_I387
1003 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1004 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1005 "* return output_fp_compare (insn, operands, 1, 0);"
1006 [(set_attr "type" "fcmp,ssecomi")
1008 (if_then_else (match_operand:SF 1 "" "")
1010 (const_string "DF")))
1011 (set_attr "athlon_decode" "vector")
1012 (set_attr "amdfam10_decode" "direct")])
1014 (define_insn "*cmpfp_i_sse"
1015 [(set (reg:CCFP FLAGS_REG)
1016 (compare:CCFP (match_operand 0 "register_operand" "x")
1017 (match_operand 1 "nonimmediate_operand" "xm")))]
1019 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1020 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1021 "* return output_fp_compare (insn, operands, 1, 0);"
1022 [(set_attr "type" "ssecomi")
1024 (if_then_else (match_operand:SF 1 "" "")
1026 (const_string "DF")))
1027 (set_attr "athlon_decode" "vector")
1028 (set_attr "amdfam10_decode" "direct")])
1030 (define_insn "*cmpfp_i_i387"
1031 [(set (reg:CCFP FLAGS_REG)
1032 (compare:CCFP (match_operand 0 "register_operand" "f")
1033 (match_operand 1 "register_operand" "f")))]
1034 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1036 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1037 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1038 "* return output_fp_compare (insn, operands, 1, 0);"
1039 [(set_attr "type" "fcmp")
1041 (cond [(match_operand:SF 1 "" "")
1043 (match_operand:DF 1 "" "")
1046 (const_string "XF")))
1047 (set_attr "athlon_decode" "vector")
1048 (set_attr "amdfam10_decode" "direct")])
1050 (define_insn "*cmpfp_iu_mixed"
1051 [(set (reg:CCFPU FLAGS_REG)
1052 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1053 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1054 "TARGET_MIX_SSE_I387
1055 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1056 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1057 "* return output_fp_compare (insn, operands, 1, 1);"
1058 [(set_attr "type" "fcmp,ssecomi")
1060 (if_then_else (match_operand:SF 1 "" "")
1062 (const_string "DF")))
1063 (set_attr "athlon_decode" "vector")
1064 (set_attr "amdfam10_decode" "direct")])
1066 (define_insn "*cmpfp_iu_sse"
1067 [(set (reg:CCFPU FLAGS_REG)
1068 (compare:CCFPU (match_operand 0 "register_operand" "x")
1069 (match_operand 1 "nonimmediate_operand" "xm")))]
1071 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1072 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1073 "* return output_fp_compare (insn, operands, 1, 1);"
1074 [(set_attr "type" "ssecomi")
1076 (if_then_else (match_operand:SF 1 "" "")
1078 (const_string "DF")))
1079 (set_attr "athlon_decode" "vector")
1080 (set_attr "amdfam10_decode" "direct")])
1082 (define_insn "*cmpfp_iu_387"
1083 [(set (reg:CCFPU FLAGS_REG)
1084 (compare:CCFPU (match_operand 0 "register_operand" "f")
1085 (match_operand 1 "register_operand" "f")))]
1086 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1088 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1089 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1090 "* return output_fp_compare (insn, operands, 1, 1);"
1091 [(set_attr "type" "fcmp")
1093 (cond [(match_operand:SF 1 "" "")
1095 (match_operand:DF 1 "" "")
1098 (const_string "XF")))
1099 (set_attr "athlon_decode" "vector")
1100 (set_attr "amdfam10_decode" "direct")])
1102 ;; Move instructions.
1104 ;; General case of fullword move.
1106 (define_expand "movsi"
1107 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1108 (match_operand:SI 1 "general_operand" ""))]
1110 "ix86_expand_move (SImode, operands); DONE;")
1112 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1115 ;; %%% We don't use a post-inc memory reference because x86 is not a
1116 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1117 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1118 ;; targets without our curiosities, and it is just as easy to represent
1119 ;; this differently.
1121 (define_insn "*pushsi2"
1122 [(set (match_operand:SI 0 "push_operand" "=<")
1123 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1126 [(set_attr "type" "push")
1127 (set_attr "mode" "SI")])
1129 ;; For 64BIT abi we always round up to 8 bytes.
1130 (define_insn "*pushsi2_rex64"
1131 [(set (match_operand:SI 0 "push_operand" "=X")
1132 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1135 [(set_attr "type" "push")
1136 (set_attr "mode" "SI")])
1138 (define_insn "*pushsi2_prologue"
1139 [(set (match_operand:SI 0 "push_operand" "=<")
1140 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1141 (clobber (mem:BLK (scratch)))]
1144 [(set_attr "type" "push")
1145 (set_attr "mode" "SI")])
1147 (define_insn "*popsi1_epilogue"
1148 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1149 (mem:SI (reg:SI SP_REG)))
1150 (set (reg:SI SP_REG)
1151 (plus:SI (reg:SI SP_REG) (const_int 4)))
1152 (clobber (mem:BLK (scratch)))]
1155 [(set_attr "type" "pop")
1156 (set_attr "mode" "SI")])
1158 (define_insn "popsi1"
1159 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1160 (mem:SI (reg:SI SP_REG)))
1161 (set (reg:SI SP_REG)
1162 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1165 [(set_attr "type" "pop")
1166 (set_attr "mode" "SI")])
1168 (define_insn "*movsi_xor"
1169 [(set (match_operand:SI 0 "register_operand" "=r")
1170 (match_operand:SI 1 "const0_operand" "i"))
1171 (clobber (reg:CC FLAGS_REG))]
1172 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1174 [(set_attr "type" "alu1")
1175 (set_attr "mode" "SI")
1176 (set_attr "length_immediate" "0")])
1178 (define_insn "*movsi_or"
1179 [(set (match_operand:SI 0 "register_operand" "=r")
1180 (match_operand:SI 1 "immediate_operand" "i"))
1181 (clobber (reg:CC FLAGS_REG))]
1183 && operands[1] == constm1_rtx
1184 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1186 operands[1] = constm1_rtx;
1187 return "or{l}\t{%1, %0|%0, %1}";
1189 [(set_attr "type" "alu1")
1190 (set_attr "mode" "SI")
1191 (set_attr "length_immediate" "1")])
1193 (define_insn "*movsi_1"
1194 [(set (match_operand:SI 0 "nonimmediate_operand"
1195 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1196 (match_operand:SI 1 "general_operand"
1197 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1198 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1200 switch (get_attr_type (insn))
1203 if (get_attr_mode (insn) == MODE_TI)
1204 return "pxor\t%0, %0";
1205 return "xorps\t%0, %0";
1208 switch (get_attr_mode (insn))
1211 return "movdqa\t{%1, %0|%0, %1}";
1213 return "movaps\t{%1, %0|%0, %1}";
1215 return "movd\t{%1, %0|%0, %1}";
1217 return "movss\t{%1, %0|%0, %1}";
1223 return "pxor\t%0, %0";
1226 if (get_attr_mode (insn) == MODE_DI)
1227 return "movq\t{%1, %0|%0, %1}";
1228 return "movd\t{%1, %0|%0, %1}";
1231 return "lea{l}\t{%1, %0|%0, %1}";
1234 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1235 return "mov{l}\t{%1, %0|%0, %1}";
1239 (cond [(eq_attr "alternative" "2")
1240 (const_string "mmxadd")
1241 (eq_attr "alternative" "3,4,5")
1242 (const_string "mmxmov")
1243 (eq_attr "alternative" "6")
1244 (const_string "sselog1")
1245 (eq_attr "alternative" "7,8,9,10,11")
1246 (const_string "ssemov")
1247 (match_operand:DI 1 "pic_32bit_operand" "")
1248 (const_string "lea")
1250 (const_string "imov")))
1252 (cond [(eq_attr "alternative" "2,3")
1254 (eq_attr "alternative" "6,7")
1256 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1257 (const_string "V4SF")
1258 (const_string "TI"))
1259 (and (eq_attr "alternative" "8,9,10,11")
1260 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1263 (const_string "SI")))])
1265 ;; Stores and loads of ax to arbitrary constant address.
1266 ;; We fake an second form of instruction to force reload to load address
1267 ;; into register when rax is not available
1268 (define_insn "*movabssi_1_rex64"
1269 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1270 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1271 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1273 movabs{l}\t{%1, %P0|%P0, %1}
1274 mov{l}\t{%1, %a0|%a0, %1}"
1275 [(set_attr "type" "imov")
1276 (set_attr "modrm" "0,*")
1277 (set_attr "length_address" "8,0")
1278 (set_attr "length_immediate" "0,*")
1279 (set_attr "memory" "store")
1280 (set_attr "mode" "SI")])
1282 (define_insn "*movabssi_2_rex64"
1283 [(set (match_operand:SI 0 "register_operand" "=a,r")
1284 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1285 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1287 movabs{l}\t{%P1, %0|%0, %P1}
1288 mov{l}\t{%a1, %0|%0, %a1}"
1289 [(set_attr "type" "imov")
1290 (set_attr "modrm" "0,*")
1291 (set_attr "length_address" "8,0")
1292 (set_attr "length_immediate" "0")
1293 (set_attr "memory" "load")
1294 (set_attr "mode" "SI")])
1296 (define_insn "*swapsi"
1297 [(set (match_operand:SI 0 "register_operand" "+r")
1298 (match_operand:SI 1 "register_operand" "+r"))
1303 [(set_attr "type" "imov")
1304 (set_attr "mode" "SI")
1305 (set_attr "pent_pair" "np")
1306 (set_attr "athlon_decode" "vector")
1307 (set_attr "amdfam10_decode" "double")])
1309 (define_expand "movhi"
1310 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1311 (match_operand:HI 1 "general_operand" ""))]
1313 "ix86_expand_move (HImode, operands); DONE;")
1315 (define_insn "*pushhi2"
1316 [(set (match_operand:HI 0 "push_operand" "=X")
1317 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1320 [(set_attr "type" "push")
1321 (set_attr "mode" "SI")])
1323 ;; For 64BIT abi we always round up to 8 bytes.
1324 (define_insn "*pushhi2_rex64"
1325 [(set (match_operand:HI 0 "push_operand" "=X")
1326 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1329 [(set_attr "type" "push")
1330 (set_attr "mode" "DI")])
1332 (define_insn "*movhi_1"
1333 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1334 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1335 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1337 switch (get_attr_type (insn))
1340 /* movzwl is faster than movw on p2 due to partial word stalls,
1341 though not as fast as an aligned movl. */
1342 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1344 if (get_attr_mode (insn) == MODE_SI)
1345 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1347 return "mov{w}\t{%1, %0|%0, %1}";
1351 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1352 (const_string "imov")
1353 (and (eq_attr "alternative" "0")
1354 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1356 (eq (symbol_ref "TARGET_HIMODE_MATH")
1358 (const_string "imov")
1359 (and (eq_attr "alternative" "1,2")
1360 (match_operand:HI 1 "aligned_operand" ""))
1361 (const_string "imov")
1362 (and (ne (symbol_ref "TARGET_MOVX")
1364 (eq_attr "alternative" "0,2"))
1365 (const_string "imovx")
1367 (const_string "imov")))
1369 (cond [(eq_attr "type" "imovx")
1371 (and (eq_attr "alternative" "1,2")
1372 (match_operand:HI 1 "aligned_operand" ""))
1374 (and (eq_attr "alternative" "0")
1375 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1377 (eq (symbol_ref "TARGET_HIMODE_MATH")
1381 (const_string "HI")))])
1383 ;; Stores and loads of ax to arbitrary constant address.
1384 ;; We fake an second form of instruction to force reload to load address
1385 ;; into register when rax is not available
1386 (define_insn "*movabshi_1_rex64"
1387 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1388 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1389 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1391 movabs{w}\t{%1, %P0|%P0, %1}
1392 mov{w}\t{%1, %a0|%a0, %1}"
1393 [(set_attr "type" "imov")
1394 (set_attr "modrm" "0,*")
1395 (set_attr "length_address" "8,0")
1396 (set_attr "length_immediate" "0,*")
1397 (set_attr "memory" "store")
1398 (set_attr "mode" "HI")])
1400 (define_insn "*movabshi_2_rex64"
1401 [(set (match_operand:HI 0 "register_operand" "=a,r")
1402 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1403 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1405 movabs{w}\t{%P1, %0|%0, %P1}
1406 mov{w}\t{%a1, %0|%0, %a1}"
1407 [(set_attr "type" "imov")
1408 (set_attr "modrm" "0,*")
1409 (set_attr "length_address" "8,0")
1410 (set_attr "length_immediate" "0")
1411 (set_attr "memory" "load")
1412 (set_attr "mode" "HI")])
1414 (define_insn "*swaphi_1"
1415 [(set (match_operand:HI 0 "register_operand" "+r")
1416 (match_operand:HI 1 "register_operand" "+r"))
1419 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1421 [(set_attr "type" "imov")
1422 (set_attr "mode" "SI")
1423 (set_attr "pent_pair" "np")
1424 (set_attr "athlon_decode" "vector")
1425 (set_attr "amdfam10_decode" "double")])
1427 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1428 (define_insn "*swaphi_2"
1429 [(set (match_operand:HI 0 "register_operand" "+r")
1430 (match_operand:HI 1 "register_operand" "+r"))
1433 "TARGET_PARTIAL_REG_STALL"
1435 [(set_attr "type" "imov")
1436 (set_attr "mode" "HI")
1437 (set_attr "pent_pair" "np")
1438 (set_attr "athlon_decode" "vector")])
1440 (define_expand "movstricthi"
1441 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1442 (match_operand:HI 1 "general_operand" ""))]
1443 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1445 /* Don't generate memory->memory moves, go through a register */
1446 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1447 operands[1] = force_reg (HImode, operands[1]);
1450 (define_insn "*movstricthi_1"
1451 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1452 (match_operand:HI 1 "general_operand" "rn,m"))]
1453 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1454 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1455 "mov{w}\t{%1, %0|%0, %1}"
1456 [(set_attr "type" "imov")
1457 (set_attr "mode" "HI")])
1459 (define_insn "*movstricthi_xor"
1460 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1461 (match_operand:HI 1 "const0_operand" "i"))
1462 (clobber (reg:CC FLAGS_REG))]
1464 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1466 [(set_attr "type" "alu1")
1467 (set_attr "mode" "HI")
1468 (set_attr "length_immediate" "0")])
1470 (define_expand "movqi"
1471 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1472 (match_operand:QI 1 "general_operand" ""))]
1474 "ix86_expand_move (QImode, operands); DONE;")
1476 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1477 ;; "push a byte". But actually we use pushl, which has the effect
1478 ;; of rounding the amount pushed up to a word.
1480 (define_insn "*pushqi2"
1481 [(set (match_operand:QI 0 "push_operand" "=X")
1482 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1485 [(set_attr "type" "push")
1486 (set_attr "mode" "SI")])
1488 ;; For 64BIT abi we always round up to 8 bytes.
1489 (define_insn "*pushqi2_rex64"
1490 [(set (match_operand:QI 0 "push_operand" "=X")
1491 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1494 [(set_attr "type" "push")
1495 (set_attr "mode" "DI")])
1497 ;; Situation is quite tricky about when to choose full sized (SImode) move
1498 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1499 ;; partial register dependency machines (such as AMD Athlon), where QImode
1500 ;; moves issue extra dependency and for partial register stalls machines
1501 ;; that don't use QImode patterns (and QImode move cause stall on the next
1504 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1505 ;; register stall machines with, where we use QImode instructions, since
1506 ;; partial register stall can be caused there. Then we use movzx.
1507 (define_insn "*movqi_1"
1508 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1509 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1510 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1512 switch (get_attr_type (insn))
1515 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1516 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1518 if (get_attr_mode (insn) == MODE_SI)
1519 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1521 return "mov{b}\t{%1, %0|%0, %1}";
1525 (cond [(and (eq_attr "alternative" "5")
1526 (not (match_operand:QI 1 "aligned_operand" "")))
1527 (const_string "imovx")
1528 (ne (symbol_ref "optimize_size") (const_int 0))
1529 (const_string "imov")
1530 (and (eq_attr "alternative" "3")
1531 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1533 (eq (symbol_ref "TARGET_QIMODE_MATH")
1535 (const_string "imov")
1536 (eq_attr "alternative" "3,5")
1537 (const_string "imovx")
1538 (and (ne (symbol_ref "TARGET_MOVX")
1540 (eq_attr "alternative" "2"))
1541 (const_string "imovx")
1543 (const_string "imov")))
1545 (cond [(eq_attr "alternative" "3,4,5")
1547 (eq_attr "alternative" "6")
1549 (eq_attr "type" "imovx")
1551 (and (eq_attr "type" "imov")
1552 (and (eq_attr "alternative" "0,1")
1553 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1555 (and (eq (symbol_ref "optimize_size")
1557 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1560 ;; Avoid partial register stalls when not using QImode arithmetic
1561 (and (eq_attr "type" "imov")
1562 (and (eq_attr "alternative" "0,1")
1563 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1565 (eq (symbol_ref "TARGET_QIMODE_MATH")
1569 (const_string "QI")))])
1571 (define_expand "reload_outqi"
1572 [(parallel [(match_operand:QI 0 "" "=m")
1573 (match_operand:QI 1 "register_operand" "r")
1574 (match_operand:QI 2 "register_operand" "=&q")])]
1578 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1580 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1581 if (! q_regs_operand (op1, QImode))
1583 emit_insn (gen_movqi (op2, op1));
1586 emit_insn (gen_movqi (op0, op1));
1590 (define_insn "*swapqi_1"
1591 [(set (match_operand:QI 0 "register_operand" "+r")
1592 (match_operand:QI 1 "register_operand" "+r"))
1595 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1597 [(set_attr "type" "imov")
1598 (set_attr "mode" "SI")
1599 (set_attr "pent_pair" "np")
1600 (set_attr "athlon_decode" "vector")
1601 (set_attr "amdfam10_decode" "vector")])
1603 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1604 (define_insn "*swapqi_2"
1605 [(set (match_operand:QI 0 "register_operand" "+q")
1606 (match_operand:QI 1 "register_operand" "+q"))
1609 "TARGET_PARTIAL_REG_STALL"
1611 [(set_attr "type" "imov")
1612 (set_attr "mode" "QI")
1613 (set_attr "pent_pair" "np")
1614 (set_attr "athlon_decode" "vector")])
1616 (define_expand "movstrictqi"
1617 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1618 (match_operand:QI 1 "general_operand" ""))]
1619 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1621 /* Don't generate memory->memory moves, go through a register. */
1622 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1623 operands[1] = force_reg (QImode, operands[1]);
1626 (define_insn "*movstrictqi_1"
1627 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1628 (match_operand:QI 1 "general_operand" "*qn,m"))]
1629 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1630 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1631 "mov{b}\t{%1, %0|%0, %1}"
1632 [(set_attr "type" "imov")
1633 (set_attr "mode" "QI")])
1635 (define_insn "*movstrictqi_xor"
1636 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1637 (match_operand:QI 1 "const0_operand" "i"))
1638 (clobber (reg:CC FLAGS_REG))]
1639 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1641 [(set_attr "type" "alu1")
1642 (set_attr "mode" "QI")
1643 (set_attr "length_immediate" "0")])
1645 (define_insn "*movsi_extv_1"
1646 [(set (match_operand:SI 0 "register_operand" "=R")
1647 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1651 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1652 [(set_attr "type" "imovx")
1653 (set_attr "mode" "SI")])
1655 (define_insn "*movhi_extv_1"
1656 [(set (match_operand:HI 0 "register_operand" "=R")
1657 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1661 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1662 [(set_attr "type" "imovx")
1663 (set_attr "mode" "SI")])
1665 (define_insn "*movqi_extv_1"
1666 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1667 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1672 switch (get_attr_type (insn))
1675 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1677 return "mov{b}\t{%h1, %0|%0, %h1}";
1681 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1682 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1683 (ne (symbol_ref "TARGET_MOVX")
1685 (const_string "imovx")
1686 (const_string "imov")))
1688 (if_then_else (eq_attr "type" "imovx")
1690 (const_string "QI")))])
1692 (define_insn "*movqi_extv_1_rex64"
1693 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1694 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1699 switch (get_attr_type (insn))
1702 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1704 return "mov{b}\t{%h1, %0|%0, %h1}";
1708 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1709 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1710 (ne (symbol_ref "TARGET_MOVX")
1712 (const_string "imovx")
1713 (const_string "imov")))
1715 (if_then_else (eq_attr "type" "imovx")
1717 (const_string "QI")))])
1719 ;; Stores and loads of ax to arbitrary constant address.
1720 ;; We fake an second form of instruction to force reload to load address
1721 ;; into register when rax is not available
1722 (define_insn "*movabsqi_1_rex64"
1723 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1724 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1725 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1727 movabs{b}\t{%1, %P0|%P0, %1}
1728 mov{b}\t{%1, %a0|%a0, %1}"
1729 [(set_attr "type" "imov")
1730 (set_attr "modrm" "0,*")
1731 (set_attr "length_address" "8,0")
1732 (set_attr "length_immediate" "0,*")
1733 (set_attr "memory" "store")
1734 (set_attr "mode" "QI")])
1736 (define_insn "*movabsqi_2_rex64"
1737 [(set (match_operand:QI 0 "register_operand" "=a,r")
1738 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1739 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1741 movabs{b}\t{%P1, %0|%0, %P1}
1742 mov{b}\t{%a1, %0|%0, %a1}"
1743 [(set_attr "type" "imov")
1744 (set_attr "modrm" "0,*")
1745 (set_attr "length_address" "8,0")
1746 (set_attr "length_immediate" "0")
1747 (set_attr "memory" "load")
1748 (set_attr "mode" "QI")])
1750 (define_insn "*movdi_extzv_1"
1751 [(set (match_operand:DI 0 "register_operand" "=R")
1752 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1756 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1757 [(set_attr "type" "imovx")
1758 (set_attr "mode" "DI")])
1760 (define_insn "*movsi_extzv_1"
1761 [(set (match_operand:SI 0 "register_operand" "=R")
1762 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1766 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1767 [(set_attr "type" "imovx")
1768 (set_attr "mode" "SI")])
1770 (define_insn "*movqi_extzv_2"
1771 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1772 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1777 switch (get_attr_type (insn))
1780 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1782 return "mov{b}\t{%h1, %0|%0, %h1}";
1786 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1787 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1788 (ne (symbol_ref "TARGET_MOVX")
1790 (const_string "imovx")
1791 (const_string "imov")))
1793 (if_then_else (eq_attr "type" "imovx")
1795 (const_string "QI")))])
1797 (define_insn "*movqi_extzv_2_rex64"
1798 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1799 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1804 switch (get_attr_type (insn))
1807 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1809 return "mov{b}\t{%h1, %0|%0, %h1}";
1813 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1814 (ne (symbol_ref "TARGET_MOVX")
1816 (const_string "imovx")
1817 (const_string "imov")))
1819 (if_then_else (eq_attr "type" "imovx")
1821 (const_string "QI")))])
1823 (define_insn "movsi_insv_1"
1824 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1827 (match_operand:SI 1 "general_operand" "Qmn"))]
1829 "mov{b}\t{%b1, %h0|%h0, %b1}"
1830 [(set_attr "type" "imov")
1831 (set_attr "mode" "QI")])
1833 (define_insn "*movsi_insv_1_rex64"
1834 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1837 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1839 "mov{b}\t{%b1, %h0|%h0, %b1}"
1840 [(set_attr "type" "imov")
1841 (set_attr "mode" "QI")])
1843 (define_insn "movdi_insv_1_rex64"
1844 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1847 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1849 "mov{b}\t{%b1, %h0|%h0, %b1}"
1850 [(set_attr "type" "imov")
1851 (set_attr "mode" "QI")])
1853 (define_insn "*movqi_insv_2"
1854 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1857 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1860 "mov{b}\t{%h1, %h0|%h0, %h1}"
1861 [(set_attr "type" "imov")
1862 (set_attr "mode" "QI")])
1864 (define_expand "movdi"
1865 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1866 (match_operand:DI 1 "general_operand" ""))]
1868 "ix86_expand_move (DImode, operands); DONE;")
1870 (define_insn "*pushdi"
1871 [(set (match_operand:DI 0 "push_operand" "=<")
1872 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1876 (define_insn "*pushdi2_rex64"
1877 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1878 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1883 [(set_attr "type" "push,multi")
1884 (set_attr "mode" "DI")])
1886 ;; Convert impossible pushes of immediate to existing instructions.
1887 ;; First try to get scratch register and go through it. In case this
1888 ;; fails, push sign extended lower part first and then overwrite
1889 ;; upper part by 32bit move.
1891 [(match_scratch:DI 2 "r")
1892 (set (match_operand:DI 0 "push_operand" "")
1893 (match_operand:DI 1 "immediate_operand" ""))]
1894 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1895 && !x86_64_immediate_operand (operands[1], DImode)"
1896 [(set (match_dup 2) (match_dup 1))
1897 (set (match_dup 0) (match_dup 2))]
1900 ;; We need to define this as both peepholer and splitter for case
1901 ;; peephole2 pass is not run.
1902 ;; "&& 1" is needed to keep it from matching the previous pattern.
1904 [(set (match_operand:DI 0 "push_operand" "")
1905 (match_operand:DI 1 "immediate_operand" ""))]
1906 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1907 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1908 [(set (match_dup 0) (match_dup 1))
1909 (set (match_dup 2) (match_dup 3))]
1910 "split_di (operands + 1, 1, operands + 2, operands + 3);
1911 operands[1] = gen_lowpart (DImode, operands[2]);
1912 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1917 [(set (match_operand:DI 0 "push_operand" "")
1918 (match_operand:DI 1 "immediate_operand" ""))]
1919 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1920 ? flow2_completed : reload_completed)
1921 && !symbolic_operand (operands[1], DImode)
1922 && !x86_64_immediate_operand (operands[1], DImode)"
1923 [(set (match_dup 0) (match_dup 1))
1924 (set (match_dup 2) (match_dup 3))]
1925 "split_di (operands + 1, 1, operands + 2, operands + 3);
1926 operands[1] = gen_lowpart (DImode, operands[2]);
1927 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1931 (define_insn "*pushdi2_prologue_rex64"
1932 [(set (match_operand:DI 0 "push_operand" "=<")
1933 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1934 (clobber (mem:BLK (scratch)))]
1937 [(set_attr "type" "push")
1938 (set_attr "mode" "DI")])
1940 (define_insn "*popdi1_epilogue_rex64"
1941 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1942 (mem:DI (reg:DI SP_REG)))
1943 (set (reg:DI SP_REG)
1944 (plus:DI (reg:DI SP_REG) (const_int 8)))
1945 (clobber (mem:BLK (scratch)))]
1948 [(set_attr "type" "pop")
1949 (set_attr "mode" "DI")])
1951 (define_insn "popdi1"
1952 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1953 (mem:DI (reg:DI SP_REG)))
1954 (set (reg:DI SP_REG)
1955 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1958 [(set_attr "type" "pop")
1959 (set_attr "mode" "DI")])
1961 (define_insn "*movdi_xor_rex64"
1962 [(set (match_operand:DI 0 "register_operand" "=r")
1963 (match_operand:DI 1 "const0_operand" "i"))
1964 (clobber (reg:CC FLAGS_REG))]
1965 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1966 && reload_completed"
1968 [(set_attr "type" "alu1")
1969 (set_attr "mode" "SI")
1970 (set_attr "length_immediate" "0")])
1972 (define_insn "*movdi_or_rex64"
1973 [(set (match_operand:DI 0 "register_operand" "=r")
1974 (match_operand:DI 1 "const_int_operand" "i"))
1975 (clobber (reg:CC FLAGS_REG))]
1976 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
1978 && operands[1] == constm1_rtx"
1980 operands[1] = constm1_rtx;
1981 return "or{q}\t{%1, %0|%0, %1}";
1983 [(set_attr "type" "alu1")
1984 (set_attr "mode" "DI")
1985 (set_attr "length_immediate" "1")])
1987 (define_insn "*movdi_2"
1988 [(set (match_operand:DI 0 "nonimmediate_operand"
1989 "=r ,o ,*y,m*y,*y,*Yt,m ,*Yt,*Yt,*x,m ,*x,*x")
1990 (match_operand:DI 1 "general_operand"
1991 "riFo,riF,C ,*y ,m ,C ,*Yt,*Yt,m ,C ,*x,*x,m "))]
1992 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1997 movq\t{%1, %0|%0, %1}
1998 movq\t{%1, %0|%0, %1}
2000 movq\t{%1, %0|%0, %1}
2001 movdqa\t{%1, %0|%0, %1}
2002 movq\t{%1, %0|%0, %1}
2004 movlps\t{%1, %0|%0, %1}
2005 movaps\t{%1, %0|%0, %1}
2006 movlps\t{%1, %0|%0, %1}"
2007 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2008 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2011 [(set (match_operand:DI 0 "push_operand" "")
2012 (match_operand:DI 1 "general_operand" ""))]
2013 "!TARGET_64BIT && reload_completed
2014 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2016 "ix86_split_long_move (operands); DONE;")
2018 ;; %%% This multiword shite has got to go.
2020 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2021 (match_operand:DI 1 "general_operand" ""))]
2022 "!TARGET_64BIT && reload_completed
2023 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2024 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2026 "ix86_split_long_move (operands); DONE;")
2028 (define_insn "*movdi_1_rex64"
2029 [(set (match_operand:DI 0 "nonimmediate_operand"
2030 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2031 (match_operand:DI 1 "general_operand"
2032 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2033 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2035 switch (get_attr_type (insn))
2038 if (SSE_REG_P (operands[0]))
2039 return "movq2dq\t{%1, %0|%0, %1}";
2041 return "movdq2q\t{%1, %0|%0, %1}";
2044 if (get_attr_mode (insn) == MODE_TI)
2045 return "movdqa\t{%1, %0|%0, %1}";
2049 /* Moves from and into integer register is done using movd
2050 opcode with REX prefix. */
2051 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2052 return "movd\t{%1, %0|%0, %1}";
2053 return "movq\t{%1, %0|%0, %1}";
2057 return "pxor\t%0, %0";
2063 return "lea{q}\t{%a1, %0|%0, %a1}";
2066 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2067 if (get_attr_mode (insn) == MODE_SI)
2068 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2069 else if (which_alternative == 2)
2070 return "movabs{q}\t{%1, %0|%0, %1}";
2072 return "mov{q}\t{%1, %0|%0, %1}";
2076 (cond [(eq_attr "alternative" "5")
2077 (const_string "mmxadd")
2078 (eq_attr "alternative" "6,7,8,9,10")
2079 (const_string "mmxmov")
2080 (eq_attr "alternative" "11")
2081 (const_string "sselog1")
2082 (eq_attr "alternative" "12,13,14,15,16")
2083 (const_string "ssemov")
2084 (eq_attr "alternative" "17,18")
2085 (const_string "ssecvt")
2086 (eq_attr "alternative" "4")
2087 (const_string "multi")
2088 (match_operand:DI 1 "pic_32bit_operand" "")
2089 (const_string "lea")
2091 (const_string "imov")))
2092 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2093 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2094 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2096 ;; Stores and loads of ax to arbitrary constant address.
2097 ;; We fake an second form of instruction to force reload to load address
2098 ;; into register when rax is not available
2099 (define_insn "*movabsdi_1_rex64"
2100 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2101 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2102 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2104 movabs{q}\t{%1, %P0|%P0, %1}
2105 mov{q}\t{%1, %a0|%a0, %1}"
2106 [(set_attr "type" "imov")
2107 (set_attr "modrm" "0,*")
2108 (set_attr "length_address" "8,0")
2109 (set_attr "length_immediate" "0,*")
2110 (set_attr "memory" "store")
2111 (set_attr "mode" "DI")])
2113 (define_insn "*movabsdi_2_rex64"
2114 [(set (match_operand:DI 0 "register_operand" "=a,r")
2115 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2116 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2118 movabs{q}\t{%P1, %0|%0, %P1}
2119 mov{q}\t{%a1, %0|%0, %a1}"
2120 [(set_attr "type" "imov")
2121 (set_attr "modrm" "0,*")
2122 (set_attr "length_address" "8,0")
2123 (set_attr "length_immediate" "0")
2124 (set_attr "memory" "load")
2125 (set_attr "mode" "DI")])
2127 ;; Convert impossible stores of immediate to existing instructions.
2128 ;; First try to get scratch register and go through it. In case this
2129 ;; fails, move by 32bit parts.
2131 [(match_scratch:DI 2 "r")
2132 (set (match_operand:DI 0 "memory_operand" "")
2133 (match_operand:DI 1 "immediate_operand" ""))]
2134 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2135 && !x86_64_immediate_operand (operands[1], DImode)"
2136 [(set (match_dup 2) (match_dup 1))
2137 (set (match_dup 0) (match_dup 2))]
2140 ;; We need to define this as both peepholer and splitter for case
2141 ;; peephole2 pass is not run.
2142 ;; "&& 1" is needed to keep it from matching the previous pattern.
2144 [(set (match_operand:DI 0 "memory_operand" "")
2145 (match_operand:DI 1 "immediate_operand" ""))]
2146 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2147 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2148 [(set (match_dup 2) (match_dup 3))
2149 (set (match_dup 4) (match_dup 5))]
2150 "split_di (operands, 2, operands + 2, operands + 4);")
2153 [(set (match_operand:DI 0 "memory_operand" "")
2154 (match_operand:DI 1 "immediate_operand" ""))]
2155 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2156 ? flow2_completed : reload_completed)
2157 && !symbolic_operand (operands[1], DImode)
2158 && !x86_64_immediate_operand (operands[1], DImode)"
2159 [(set (match_dup 2) (match_dup 3))
2160 (set (match_dup 4) (match_dup 5))]
2161 "split_di (operands, 2, operands + 2, operands + 4);")
2163 (define_insn "*swapdi_rex64"
2164 [(set (match_operand:DI 0 "register_operand" "+r")
2165 (match_operand:DI 1 "register_operand" "+r"))
2170 [(set_attr "type" "imov")
2171 (set_attr "mode" "DI")
2172 (set_attr "pent_pair" "np")
2173 (set_attr "athlon_decode" "vector")
2174 (set_attr "amdfam10_decode" "double")])
2176 (define_expand "movti"
2177 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2178 (match_operand:TI 1 "nonimmediate_operand" ""))]
2179 "TARGET_SSE || TARGET_64BIT"
2182 ix86_expand_move (TImode, operands);
2183 else if (push_operand (operands[0], TImode))
2184 ix86_expand_push (TImode, operands[1]);
2186 ix86_expand_vector_move (TImode, operands);
2190 (define_insn "*movti_internal"
2191 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2192 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2193 "TARGET_SSE && !TARGET_64BIT
2194 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2196 switch (which_alternative)
2199 if (get_attr_mode (insn) == MODE_V4SF)
2200 return "xorps\t%0, %0";
2202 return "pxor\t%0, %0";
2205 if (get_attr_mode (insn) == MODE_V4SF)
2206 return "movaps\t{%1, %0|%0, %1}";
2208 return "movdqa\t{%1, %0|%0, %1}";
2213 [(set_attr "type" "sselog1,ssemov,ssemov")
2215 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2216 (ne (symbol_ref "optimize_size") (const_int 0)))
2217 (const_string "V4SF")
2218 (and (eq_attr "alternative" "2")
2219 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2221 (const_string "V4SF")]
2222 (const_string "TI")))])
2224 (define_insn "*movti_rex64"
2225 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2226 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2228 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2230 switch (which_alternative)
2236 if (get_attr_mode (insn) == MODE_V4SF)
2237 return "xorps\t%0, %0";
2239 return "pxor\t%0, %0";
2242 if (get_attr_mode (insn) == MODE_V4SF)
2243 return "movaps\t{%1, %0|%0, %1}";
2245 return "movdqa\t{%1, %0|%0, %1}";
2250 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2252 (cond [(eq_attr "alternative" "2,3")
2254 (ne (symbol_ref "optimize_size")
2256 (const_string "V4SF")
2257 (const_string "TI"))
2258 (eq_attr "alternative" "4")
2260 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2262 (ne (symbol_ref "optimize_size")
2264 (const_string "V4SF")
2265 (const_string "TI"))]
2266 (const_string "DI")))])
2269 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2270 (match_operand:TI 1 "general_operand" ""))]
2271 "reload_completed && !SSE_REG_P (operands[0])
2272 && !SSE_REG_P (operands[1])"
2274 "ix86_split_long_move (operands); DONE;")
2276 ;; This expands to what emit_move_complex would generate if we didn't
2277 ;; have a movti pattern. Having this avoids problems with reload on
2278 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2279 ;; to have around all the time.
2280 (define_expand "movcdi"
2281 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2282 (match_operand:CDI 1 "general_operand" ""))]
2285 if (push_operand (operands[0], CDImode))
2286 emit_move_complex_push (CDImode, operands[0], operands[1]);
2288 emit_move_complex_parts (operands[0], operands[1]);
2292 (define_expand "movsf"
2293 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2294 (match_operand:SF 1 "general_operand" ""))]
2296 "ix86_expand_move (SFmode, operands); DONE;")
2298 (define_insn "*pushsf"
2299 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2300 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2303 /* Anything else should be already split before reg-stack. */
2304 gcc_assert (which_alternative == 1);
2305 return "push{l}\t%1";
2307 [(set_attr "type" "multi,push,multi")
2308 (set_attr "unit" "i387,*,*")
2309 (set_attr "mode" "SF,SI,SF")])
2311 (define_insn "*pushsf_rex64"
2312 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2313 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2316 /* Anything else should be already split before reg-stack. */
2317 gcc_assert (which_alternative == 1);
2318 return "push{q}\t%q1";
2320 [(set_attr "type" "multi,push,multi")
2321 (set_attr "unit" "i387,*,*")
2322 (set_attr "mode" "SF,DI,SF")])
2325 [(set (match_operand:SF 0 "push_operand" "")
2326 (match_operand:SF 1 "memory_operand" ""))]
2328 && MEM_P (operands[1])
2329 && (operands[2] = find_constant_src (insn))"
2334 ;; %%% Kill this when call knows how to work this out.
2336 [(set (match_operand:SF 0 "push_operand" "")
2337 (match_operand:SF 1 "any_fp_register_operand" ""))]
2339 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2340 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2343 [(set (match_operand:SF 0 "push_operand" "")
2344 (match_operand:SF 1 "any_fp_register_operand" ""))]
2346 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2347 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2349 (define_insn "*movsf_1"
2350 [(set (match_operand:SF 0 "nonimmediate_operand"
2351 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2352 (match_operand:SF 1 "general_operand"
2353 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2354 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2355 && (reload_in_progress || reload_completed
2356 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2357 || (!TARGET_SSE_MATH && optimize_size
2358 && standard_80387_constant_p (operands[1]))
2359 || GET_CODE (operands[1]) != CONST_DOUBLE
2360 || memory_operand (operands[0], SFmode))"
2362 switch (which_alternative)
2366 return output_387_reg_move (insn, operands);
2369 return standard_80387_constant_opcode (operands[1]);
2373 return "mov{l}\t{%1, %0|%0, %1}";
2375 if (get_attr_mode (insn) == MODE_TI)
2376 return "pxor\t%0, %0";
2378 return "xorps\t%0, %0";
2380 if (get_attr_mode (insn) == MODE_V4SF)
2381 return "movaps\t{%1, %0|%0, %1}";
2383 return "movss\t{%1, %0|%0, %1}";
2385 return "movss\t{%1, %0|%0, %1}";
2388 case 12: case 13: case 14: case 15:
2389 return "movd\t{%1, %0|%0, %1}";
2392 return "movq\t{%1, %0|%0, %1}";
2398 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2400 (cond [(eq_attr "alternative" "3,4,9,10")
2402 (eq_attr "alternative" "5")
2404 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2406 (ne (symbol_ref "TARGET_SSE2")
2408 (eq (symbol_ref "optimize_size")
2411 (const_string "V4SF"))
2412 /* For architectures resolving dependencies on
2413 whole SSE registers use APS move to break dependency
2414 chains, otherwise use short move to avoid extra work.
2416 Do the same for architectures resolving dependencies on
2417 the parts. While in DF mode it is better to always handle
2418 just register parts, the SF mode is different due to lack
2419 of instructions to load just part of the register. It is
2420 better to maintain the whole registers in single format
2421 to avoid problems on using packed logical operations. */
2422 (eq_attr "alternative" "6")
2424 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2426 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2428 (const_string "V4SF")
2429 (const_string "SF"))
2430 (eq_attr "alternative" "11")
2431 (const_string "DI")]
2432 (const_string "SF")))])
2434 (define_insn "*swapsf"
2435 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2436 (match_operand:SF 1 "fp_register_operand" "+f"))
2439 "reload_completed || TARGET_80387"
2441 if (STACK_TOP_P (operands[0]))
2446 [(set_attr "type" "fxch")
2447 (set_attr "mode" "SF")])
2449 (define_expand "movdf"
2450 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2451 (match_operand:DF 1 "general_operand" ""))]
2453 "ix86_expand_move (DFmode, operands); DONE;")
2455 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2456 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2457 ;; On the average, pushdf using integers can be still shorter. Allow this
2458 ;; pattern for optimize_size too.
2460 (define_insn "*pushdf_nointeger"
2461 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2462 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Yt"))]
2463 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2465 /* This insn should be already split before reg-stack. */
2468 [(set_attr "type" "multi")
2469 (set_attr "unit" "i387,*,*,*")
2470 (set_attr "mode" "DF,SI,SI,DF")])
2472 (define_insn "*pushdf_integer"
2473 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2474 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Yt"))]
2475 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2477 /* This insn should be already split before reg-stack. */
2480 [(set_attr "type" "multi")
2481 (set_attr "unit" "i387,*,*")
2482 (set_attr "mode" "DF,SI,DF")])
2484 ;; %%% Kill this when call knows how to work this out.
2486 [(set (match_operand:DF 0 "push_operand" "")
2487 (match_operand:DF 1 "any_fp_register_operand" ""))]
2488 "!TARGET_64BIT && reload_completed"
2489 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2490 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2494 [(set (match_operand:DF 0 "push_operand" "")
2495 (match_operand:DF 1 "any_fp_register_operand" ""))]
2496 "TARGET_64BIT && reload_completed"
2497 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2498 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2502 [(set (match_operand:DF 0 "push_operand" "")
2503 (match_operand:DF 1 "general_operand" ""))]
2506 "ix86_split_long_move (operands); DONE;")
2508 ;; Moving is usually shorter when only FP registers are used. This separate
2509 ;; movdf pattern avoids the use of integer registers for FP operations
2510 ;; when optimizing for size.
2512 (define_insn "*movdf_nointeger"
2513 [(set (match_operand:DF 0 "nonimmediate_operand"
2514 "=f,m,f,*r ,o ,Yt*x,Yt*x,Yt*x ,m ")
2515 (match_operand:DF 1 "general_operand"
2516 "fm,f,G,*roF,F*r,C ,Yt*x,mYt*x,Yt*x"))]
2517 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2518 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2519 && (reload_in_progress || reload_completed
2520 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2521 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2522 && standard_80387_constant_p (operands[1]))
2523 || GET_CODE (operands[1]) != CONST_DOUBLE
2524 || memory_operand (operands[0], DFmode))"
2526 switch (which_alternative)
2530 return output_387_reg_move (insn, operands);
2533 return standard_80387_constant_opcode (operands[1]);
2539 switch (get_attr_mode (insn))
2542 return "xorps\t%0, %0";
2544 return "xorpd\t%0, %0";
2546 return "pxor\t%0, %0";
2553 switch (get_attr_mode (insn))
2556 return "movaps\t{%1, %0|%0, %1}";
2558 return "movapd\t{%1, %0|%0, %1}";
2560 return "movdqa\t{%1, %0|%0, %1}";
2562 return "movq\t{%1, %0|%0, %1}";
2564 return "movsd\t{%1, %0|%0, %1}";
2566 return "movlpd\t{%1, %0|%0, %1}";
2568 return "movlps\t{%1, %0|%0, %1}";
2577 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2579 (cond [(eq_attr "alternative" "0,1,2")
2581 (eq_attr "alternative" "3,4")
2584 /* For SSE1, we have many fewer alternatives. */
2585 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2586 (cond [(eq_attr "alternative" "5,6")
2587 (const_string "V4SF")
2589 (const_string "V2SF"))
2591 /* xorps is one byte shorter. */
2592 (eq_attr "alternative" "5")
2593 (cond [(ne (symbol_ref "optimize_size")
2595 (const_string "V4SF")
2596 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2600 (const_string "V2DF"))
2602 /* For architectures resolving dependencies on
2603 whole SSE registers use APD move to break dependency
2604 chains, otherwise use short move to avoid extra work.
2606 movaps encodes one byte shorter. */
2607 (eq_attr "alternative" "6")
2609 [(ne (symbol_ref "optimize_size")
2611 (const_string "V4SF")
2612 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2614 (const_string "V2DF")
2616 (const_string "DF"))
2617 /* For architectures resolving dependencies on register
2618 parts we may avoid extra work to zero out upper part
2620 (eq_attr "alternative" "7")
2622 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2624 (const_string "V1DF")
2625 (const_string "DF"))
2627 (const_string "DF")))])
2629 (define_insn "*movdf_integer_rex64"
2630 [(set (match_operand:DF 0 "nonimmediate_operand"
2631 "=f,m,f,r ,m ,Yt*x,Yt*x,Yt*x,m ,Yi,r ")
2632 (match_operand:DF 1 "general_operand"
2633 "fm,f,G,rmF,Fr,C ,Yt*x,m ,Yt*x,r ,Yi"))]
2634 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2635 && (reload_in_progress || reload_completed
2636 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2637 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2638 && standard_80387_constant_p (operands[1]))
2639 || GET_CODE (operands[1]) != CONST_DOUBLE
2640 || memory_operand (operands[0], DFmode))"
2642 switch (which_alternative)
2646 return output_387_reg_move (insn, operands);
2649 return standard_80387_constant_opcode (operands[1]);
2656 switch (get_attr_mode (insn))
2659 return "xorps\t%0, %0";
2661 return "xorpd\t%0, %0";
2663 return "pxor\t%0, %0";
2670 switch (get_attr_mode (insn))
2673 return "movaps\t{%1, %0|%0, %1}";
2675 return "movapd\t{%1, %0|%0, %1}";
2677 return "movdqa\t{%1, %0|%0, %1}";
2679 return "movq\t{%1, %0|%0, %1}";
2681 return "movsd\t{%1, %0|%0, %1}";
2683 return "movlpd\t{%1, %0|%0, %1}";
2685 return "movlps\t{%1, %0|%0, %1}";
2692 return "movd\t{%1, %0|%0, %1}";
2698 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2700 (cond [(eq_attr "alternative" "0,1,2")
2702 (eq_attr "alternative" "3,4,9,10")
2705 /* For SSE1, we have many fewer alternatives. */
2706 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2707 (cond [(eq_attr "alternative" "5,6")
2708 (const_string "V4SF")
2710 (const_string "V2SF"))
2712 /* xorps is one byte shorter. */
2713 (eq_attr "alternative" "5")
2714 (cond [(ne (symbol_ref "optimize_size")
2716 (const_string "V4SF")
2717 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2721 (const_string "V2DF"))
2723 /* For architectures resolving dependencies on
2724 whole SSE registers use APD move to break dependency
2725 chains, otherwise use short move to avoid extra work.
2727 movaps encodes one byte shorter. */
2728 (eq_attr "alternative" "6")
2730 [(ne (symbol_ref "optimize_size")
2732 (const_string "V4SF")
2733 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2735 (const_string "V2DF")
2737 (const_string "DF"))
2738 /* For architectures resolving dependencies on register
2739 parts we may avoid extra work to zero out upper part
2741 (eq_attr "alternative" "7")
2743 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2745 (const_string "V1DF")
2746 (const_string "DF"))
2748 (const_string "DF")))])
2750 (define_insn "*movdf_integer"
2751 [(set (match_operand:DF 0 "nonimmediate_operand"
2752 "=f,m,f,r ,o ,Yt*x,Yt*x,Yt*x,m ")
2753 (match_operand:DF 1 "general_operand"
2754 "fm,f,G,roF,Fr,C ,Yt*x,m ,Yt*x"))]
2755 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2756 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2757 && (reload_in_progress || reload_completed
2758 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2759 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2760 && standard_80387_constant_p (operands[1]))
2761 || GET_CODE (operands[1]) != CONST_DOUBLE
2762 || memory_operand (operands[0], DFmode))"
2764 switch (which_alternative)
2768 return output_387_reg_move (insn, operands);
2771 return standard_80387_constant_opcode (operands[1]);
2778 switch (get_attr_mode (insn))
2781 return "xorps\t%0, %0";
2783 return "xorpd\t%0, %0";
2785 return "pxor\t%0, %0";
2792 switch (get_attr_mode (insn))
2795 return "movaps\t{%1, %0|%0, %1}";
2797 return "movapd\t{%1, %0|%0, %1}";
2799 return "movdqa\t{%1, %0|%0, %1}";
2801 return "movq\t{%1, %0|%0, %1}";
2803 return "movsd\t{%1, %0|%0, %1}";
2805 return "movlpd\t{%1, %0|%0, %1}";
2807 return "movlps\t{%1, %0|%0, %1}";
2816 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2818 (cond [(eq_attr "alternative" "0,1,2")
2820 (eq_attr "alternative" "3,4")
2823 /* For SSE1, we have many fewer alternatives. */
2824 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2825 (cond [(eq_attr "alternative" "5,6")
2826 (const_string "V4SF")
2828 (const_string "V2SF"))
2830 /* xorps is one byte shorter. */
2831 (eq_attr "alternative" "5")
2832 (cond [(ne (symbol_ref "optimize_size")
2834 (const_string "V4SF")
2835 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2839 (const_string "V2DF"))
2841 /* For architectures resolving dependencies on
2842 whole SSE registers use APD move to break dependency
2843 chains, otherwise use short move to avoid extra work.
2845 movaps encodes one byte shorter. */
2846 (eq_attr "alternative" "6")
2848 [(ne (symbol_ref "optimize_size")
2850 (const_string "V4SF")
2851 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2853 (const_string "V2DF")
2855 (const_string "DF"))
2856 /* For architectures resolving dependencies on register
2857 parts we may avoid extra work to zero out upper part
2859 (eq_attr "alternative" "7")
2861 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2863 (const_string "V1DF")
2864 (const_string "DF"))
2866 (const_string "DF")))])
2869 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2870 (match_operand:DF 1 "general_operand" ""))]
2872 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2873 && ! (ANY_FP_REG_P (operands[0]) ||
2874 (GET_CODE (operands[0]) == SUBREG
2875 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2876 && ! (ANY_FP_REG_P (operands[1]) ||
2877 (GET_CODE (operands[1]) == SUBREG
2878 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2880 "ix86_split_long_move (operands); DONE;")
2882 (define_insn "*swapdf"
2883 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2884 (match_operand:DF 1 "fp_register_operand" "+f"))
2887 "reload_completed || TARGET_80387"
2889 if (STACK_TOP_P (operands[0]))
2894 [(set_attr "type" "fxch")
2895 (set_attr "mode" "DF")])
2897 (define_expand "movxf"
2898 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2899 (match_operand:XF 1 "general_operand" ""))]
2901 "ix86_expand_move (XFmode, operands); DONE;")
2903 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2904 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2905 ;; Pushing using integer instructions is longer except for constants
2906 ;; and direct memory references.
2907 ;; (assuming that any given constant is pushed only once, but this ought to be
2908 ;; handled elsewhere).
2910 (define_insn "*pushxf_nointeger"
2911 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2912 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2915 /* This insn should be already split before reg-stack. */
2918 [(set_attr "type" "multi")
2919 (set_attr "unit" "i387,*,*")
2920 (set_attr "mode" "XF,SI,SI")])
2922 (define_insn "*pushxf_integer"
2923 [(set (match_operand:XF 0 "push_operand" "=<,<")
2924 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2927 /* This insn should be already split before reg-stack. */
2930 [(set_attr "type" "multi")
2931 (set_attr "unit" "i387,*")
2932 (set_attr "mode" "XF,SI")])
2935 [(set (match_operand 0 "push_operand" "")
2936 (match_operand 1 "general_operand" ""))]
2938 && (GET_MODE (operands[0]) == XFmode
2939 || GET_MODE (operands[0]) == DFmode)
2940 && !ANY_FP_REG_P (operands[1])"
2942 "ix86_split_long_move (operands); DONE;")
2945 [(set (match_operand:XF 0 "push_operand" "")
2946 (match_operand:XF 1 "any_fp_register_operand" ""))]
2948 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2949 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2950 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2953 [(set (match_operand:XF 0 "push_operand" "")
2954 (match_operand:XF 1 "any_fp_register_operand" ""))]
2956 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2957 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2958 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2960 ;; Do not use integer registers when optimizing for size
2961 (define_insn "*movxf_nointeger"
2962 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2963 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2965 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2966 && (reload_in_progress || reload_completed
2967 || (optimize_size && standard_80387_constant_p (operands[1]))
2968 || GET_CODE (operands[1]) != CONST_DOUBLE
2969 || memory_operand (operands[0], XFmode))"
2971 switch (which_alternative)
2975 return output_387_reg_move (insn, operands);
2978 return standard_80387_constant_opcode (operands[1]);
2986 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2987 (set_attr "mode" "XF,XF,XF,SI,SI")])
2989 (define_insn "*movxf_integer"
2990 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2991 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2993 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2994 && (reload_in_progress || reload_completed
2995 || (optimize_size && standard_80387_constant_p (operands[1]))
2996 || GET_CODE (operands[1]) != CONST_DOUBLE
2997 || memory_operand (operands[0], XFmode))"
2999 switch (which_alternative)
3003 return output_387_reg_move (insn, operands);
3006 return standard_80387_constant_opcode (operands[1]);
3015 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3016 (set_attr "mode" "XF,XF,XF,SI,SI")])
3019 [(set (match_operand 0 "nonimmediate_operand" "")
3020 (match_operand 1 "general_operand" ""))]
3022 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3023 && GET_MODE (operands[0]) == XFmode
3024 && ! (ANY_FP_REG_P (operands[0]) ||
3025 (GET_CODE (operands[0]) == SUBREG
3026 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3027 && ! (ANY_FP_REG_P (operands[1]) ||
3028 (GET_CODE (operands[1]) == SUBREG
3029 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3031 "ix86_split_long_move (operands); DONE;")
3034 [(set (match_operand 0 "register_operand" "")
3035 (match_operand 1 "memory_operand" ""))]
3037 && MEM_P (operands[1])
3038 && (GET_MODE (operands[0]) == TFmode
3039 || GET_MODE (operands[0]) == XFmode
3040 || GET_MODE (operands[0]) == SFmode
3041 || GET_MODE (operands[0]) == DFmode)
3042 && (operands[2] = find_constant_src (insn))"
3043 [(set (match_dup 0) (match_dup 2))]
3045 rtx c = operands[2];
3046 rtx r = operands[0];
3048 if (GET_CODE (r) == SUBREG)
3053 if (!standard_sse_constant_p (c))
3056 else if (FP_REG_P (r))
3058 if (!standard_80387_constant_p (c))
3061 else if (MMX_REG_P (r))
3066 [(set (match_operand 0 "register_operand" "")
3067 (float_extend (match_operand 1 "memory_operand" "")))]
3069 && MEM_P (operands[1])
3070 && (GET_MODE (operands[0]) == XFmode
3071 || GET_MODE (operands[0]) == SFmode
3072 || GET_MODE (operands[0]) == DFmode)
3073 && (operands[2] = find_constant_src (insn))"
3074 [(set (match_dup 0) (match_dup 2))]
3076 rtx c = operands[2];
3077 rtx r = operands[0];
3079 if (GET_CODE (r) == SUBREG)
3084 if (!standard_sse_constant_p (c))
3087 else if (FP_REG_P (r))
3089 if (!standard_80387_constant_p (c))
3092 else if (MMX_REG_P (r))
3096 (define_insn "swapxf"
3097 [(set (match_operand:XF 0 "register_operand" "+f")
3098 (match_operand:XF 1 "register_operand" "+f"))
3103 if (STACK_TOP_P (operands[0]))
3108 [(set_attr "type" "fxch")
3109 (set_attr "mode" "XF")])
3111 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3113 [(set (match_operand:X87MODEF 0 "register_operand" "")
3114 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3115 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3116 && (standard_80387_constant_p (operands[1]) == 8
3117 || standard_80387_constant_p (operands[1]) == 9)"
3118 [(set (match_dup 0)(match_dup 1))
3120 (neg:X87MODEF (match_dup 0)))]
3124 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3125 if (real_isnegzero (&r))
3126 operands[1] = CONST0_RTX (<MODE>mode);
3128 operands[1] = CONST1_RTX (<MODE>mode);
3131 (define_expand "movtf"
3132 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3133 (match_operand:TF 1 "nonimmediate_operand" ""))]
3136 ix86_expand_move (TFmode, operands);
3140 (define_insn "*movtf_internal"
3141 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3142 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3144 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3146 switch (which_alternative)
3152 if (get_attr_mode (insn) == MODE_V4SF)
3153 return "xorps\t%0, %0";
3155 return "pxor\t%0, %0";
3158 if (get_attr_mode (insn) == MODE_V4SF)
3159 return "movaps\t{%1, %0|%0, %1}";
3161 return "movdqa\t{%1, %0|%0, %1}";
3166 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3168 (cond [(eq_attr "alternative" "2,3")
3170 (ne (symbol_ref "optimize_size")
3172 (const_string "V4SF")
3173 (const_string "TI"))
3174 (eq_attr "alternative" "4")
3176 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3178 (ne (symbol_ref "optimize_size")
3180 (const_string "V4SF")
3181 (const_string "TI"))]
3182 (const_string "DI")))])
3185 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3186 (match_operand:TF 1 "general_operand" ""))]
3187 "reload_completed && !SSE_REG_P (operands[0])
3188 && !SSE_REG_P (operands[1])"
3190 "ix86_split_long_move (operands); DONE;")
3192 ;; Zero extension instructions
3194 (define_expand "zero_extendhisi2"
3195 [(set (match_operand:SI 0 "register_operand" "")
3196 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3199 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3201 operands[1] = force_reg (HImode, operands[1]);
3202 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3207 (define_insn "zero_extendhisi2_and"
3208 [(set (match_operand:SI 0 "register_operand" "=r")
3209 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3210 (clobber (reg:CC FLAGS_REG))]
3211 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3213 [(set_attr "type" "alu1")
3214 (set_attr "mode" "SI")])
3217 [(set (match_operand:SI 0 "register_operand" "")
3218 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3219 (clobber (reg:CC FLAGS_REG))]
3220 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3221 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3222 (clobber (reg:CC FLAGS_REG))])]
3225 (define_insn "*zero_extendhisi2_movzwl"
3226 [(set (match_operand:SI 0 "register_operand" "=r")
3227 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3228 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3229 "movz{wl|x}\t{%1, %0|%0, %1}"
3230 [(set_attr "type" "imovx")
3231 (set_attr "mode" "SI")])
3233 (define_expand "zero_extendqihi2"
3235 [(set (match_operand:HI 0 "register_operand" "")
3236 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3237 (clobber (reg:CC FLAGS_REG))])]
3241 (define_insn "*zero_extendqihi2_and"
3242 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3243 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3244 (clobber (reg:CC FLAGS_REG))]
3245 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3247 [(set_attr "type" "alu1")
3248 (set_attr "mode" "HI")])
3250 (define_insn "*zero_extendqihi2_movzbw_and"
3251 [(set (match_operand:HI 0 "register_operand" "=r,r")
3252 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3253 (clobber (reg:CC FLAGS_REG))]
3254 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3256 [(set_attr "type" "imovx,alu1")
3257 (set_attr "mode" "HI")])
3259 ; zero extend to SImode here to avoid partial register stalls
3260 (define_insn "*zero_extendqihi2_movzbl"
3261 [(set (match_operand:HI 0 "register_operand" "=r")
3262 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3263 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3264 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3265 [(set_attr "type" "imovx")
3266 (set_attr "mode" "SI")])
3268 ;; For the movzbw case strip only the clobber
3270 [(set (match_operand:HI 0 "register_operand" "")
3271 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3272 (clobber (reg:CC FLAGS_REG))]
3274 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3275 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3276 [(set (match_operand:HI 0 "register_operand" "")
3277 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3279 ;; When source and destination does not overlap, clear destination
3280 ;; first and then do the movb
3282 [(set (match_operand:HI 0 "register_operand" "")
3283 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3284 (clobber (reg:CC FLAGS_REG))]
3286 && ANY_QI_REG_P (operands[0])
3287 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3288 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3289 [(set (match_dup 0) (const_int 0))
3290 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3291 "operands[2] = gen_lowpart (QImode, operands[0]);")
3293 ;; Rest is handled by single and.
3295 [(set (match_operand:HI 0 "register_operand" "")
3296 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3297 (clobber (reg:CC FLAGS_REG))]
3299 && true_regnum (operands[0]) == true_regnum (operands[1])"
3300 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3301 (clobber (reg:CC FLAGS_REG))])]
3304 (define_expand "zero_extendqisi2"
3306 [(set (match_operand:SI 0 "register_operand" "")
3307 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3308 (clobber (reg:CC FLAGS_REG))])]
3312 (define_insn "*zero_extendqisi2_and"
3313 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3314 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3315 (clobber (reg:CC FLAGS_REG))]
3316 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3318 [(set_attr "type" "alu1")
3319 (set_attr "mode" "SI")])
3321 (define_insn "*zero_extendqisi2_movzbw_and"
3322 [(set (match_operand:SI 0 "register_operand" "=r,r")
3323 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3324 (clobber (reg:CC FLAGS_REG))]
3325 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3327 [(set_attr "type" "imovx,alu1")
3328 (set_attr "mode" "SI")])
3330 (define_insn "*zero_extendqisi2_movzbw"
3331 [(set (match_operand:SI 0 "register_operand" "=r")
3332 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3333 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3334 "movz{bl|x}\t{%1, %0|%0, %1}"
3335 [(set_attr "type" "imovx")
3336 (set_attr "mode" "SI")])
3338 ;; For the movzbl case strip only the clobber
3340 [(set (match_operand:SI 0 "register_operand" "")
3341 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3342 (clobber (reg:CC FLAGS_REG))]
3344 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3345 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3347 (zero_extend:SI (match_dup 1)))])
3349 ;; When source and destination does not overlap, clear destination
3350 ;; first and then do the movb
3352 [(set (match_operand:SI 0 "register_operand" "")
3353 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3354 (clobber (reg:CC FLAGS_REG))]
3356 && ANY_QI_REG_P (operands[0])
3357 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3358 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3359 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3360 [(set (match_dup 0) (const_int 0))
3361 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3362 "operands[2] = gen_lowpart (QImode, operands[0]);")
3364 ;; Rest is handled by single and.
3366 [(set (match_operand:SI 0 "register_operand" "")
3367 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3368 (clobber (reg:CC FLAGS_REG))]
3370 && true_regnum (operands[0]) == true_regnum (operands[1])"
3371 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3372 (clobber (reg:CC FLAGS_REG))])]
3375 ;; %%% Kill me once multi-word ops are sane.
3376 (define_expand "zero_extendsidi2"
3377 [(set (match_operand:DI 0 "register_operand" "=r")
3378 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3383 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3388 (define_insn "zero_extendsidi2_32"
3389 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Yt")
3391 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3392 (clobber (reg:CC FLAGS_REG))]
3398 movd\t{%1, %0|%0, %1}
3399 movd\t{%1, %0|%0, %1}
3400 movd\t{%1, %0|%0, %1}
3401 movd\t{%1, %0|%0, %1}"
3402 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3403 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3405 (define_insn "zero_extendsidi2_rex64"
3406 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Yt")
3408 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3411 mov\t{%k1, %k0|%k0, %k1}
3413 movd\t{%1, %0|%0, %1}
3414 movd\t{%1, %0|%0, %1}
3415 movd\t{%1, %0|%0, %1}
3416 movd\t{%1, %0|%0, %1}"
3417 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3418 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3421 [(set (match_operand:DI 0 "memory_operand" "")
3422 (zero_extend:DI (match_dup 0)))]
3424 [(set (match_dup 4) (const_int 0))]
3425 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3428 [(set (match_operand:DI 0 "register_operand" "")
3429 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3430 (clobber (reg:CC FLAGS_REG))]
3431 "!TARGET_64BIT && reload_completed
3432 && true_regnum (operands[0]) == true_regnum (operands[1])"
3433 [(set (match_dup 4) (const_int 0))]
3434 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3437 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3438 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3439 (clobber (reg:CC FLAGS_REG))]
3440 "!TARGET_64BIT && reload_completed
3441 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3442 [(set (match_dup 3) (match_dup 1))
3443 (set (match_dup 4) (const_int 0))]
3444 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3446 (define_insn "zero_extendhidi2"
3447 [(set (match_operand:DI 0 "register_operand" "=r")
3448 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3450 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3451 [(set_attr "type" "imovx")
3452 (set_attr "mode" "DI")])
3454 (define_insn "zero_extendqidi2"
3455 [(set (match_operand:DI 0 "register_operand" "=r")
3456 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3458 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3459 [(set_attr "type" "imovx")
3460 (set_attr "mode" "DI")])
3462 ;; Sign extension instructions
3464 (define_expand "extendsidi2"
3465 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3466 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3467 (clobber (reg:CC FLAGS_REG))
3468 (clobber (match_scratch:SI 2 ""))])]
3473 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3478 (define_insn "*extendsidi2_1"
3479 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3480 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3481 (clobber (reg:CC FLAGS_REG))
3482 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3486 (define_insn "extendsidi2_rex64"
3487 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3488 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3492 movs{lq|x}\t{%1,%0|%0, %1}"
3493 [(set_attr "type" "imovx")
3494 (set_attr "mode" "DI")
3495 (set_attr "prefix_0f" "0")
3496 (set_attr "modrm" "0,1")])
3498 (define_insn "extendhidi2"
3499 [(set (match_operand:DI 0 "register_operand" "=r")
3500 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3502 "movs{wq|x}\t{%1,%0|%0, %1}"
3503 [(set_attr "type" "imovx")
3504 (set_attr "mode" "DI")])
3506 (define_insn "extendqidi2"
3507 [(set (match_operand:DI 0 "register_operand" "=r")
3508 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3510 "movs{bq|x}\t{%1,%0|%0, %1}"
3511 [(set_attr "type" "imovx")
3512 (set_attr "mode" "DI")])
3514 ;; Extend to memory case when source register does die.
3516 [(set (match_operand:DI 0 "memory_operand" "")
3517 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3518 (clobber (reg:CC FLAGS_REG))
3519 (clobber (match_operand:SI 2 "register_operand" ""))]
3521 && dead_or_set_p (insn, operands[1])
3522 && !reg_mentioned_p (operands[1], operands[0]))"
3523 [(set (match_dup 3) (match_dup 1))
3524 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3525 (clobber (reg:CC FLAGS_REG))])
3526 (set (match_dup 4) (match_dup 1))]
3527 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3529 ;; Extend to memory case when source register does not die.
3531 [(set (match_operand:DI 0 "memory_operand" "")
3532 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533 (clobber (reg:CC FLAGS_REG))
3534 (clobber (match_operand:SI 2 "register_operand" ""))]
3538 split_di (&operands[0], 1, &operands[3], &operands[4]);
3540 emit_move_insn (operands[3], operands[1]);
3542 /* Generate a cltd if possible and doing so it profitable. */
3543 if (true_regnum (operands[1]) == 0
3544 && true_regnum (operands[2]) == 1
3545 && (optimize_size || TARGET_USE_CLTD))
3547 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3551 emit_move_insn (operands[2], operands[1]);
3552 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3554 emit_move_insn (operands[4], operands[2]);
3558 ;; Extend to register case. Optimize case where source and destination
3559 ;; registers match and cases where we can use cltd.
3561 [(set (match_operand:DI 0 "register_operand" "")
3562 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3563 (clobber (reg:CC FLAGS_REG))
3564 (clobber (match_scratch:SI 2 ""))]
3568 split_di (&operands[0], 1, &operands[3], &operands[4]);
3570 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3571 emit_move_insn (operands[3], operands[1]);
3573 /* Generate a cltd if possible and doing so it profitable. */
3574 if (true_regnum (operands[3]) == 0
3575 && (optimize_size || TARGET_USE_CLTD))
3577 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3581 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3582 emit_move_insn (operands[4], operands[1]);
3584 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3588 (define_insn "extendhisi2"
3589 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3590 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3593 switch (get_attr_prefix_0f (insn))
3596 return "{cwtl|cwde}";
3598 return "movs{wl|x}\t{%1,%0|%0, %1}";
3601 [(set_attr "type" "imovx")
3602 (set_attr "mode" "SI")
3603 (set (attr "prefix_0f")
3604 ;; movsx is short decodable while cwtl is vector decoded.
3605 (if_then_else (and (eq_attr "cpu" "!k6")
3606 (eq_attr "alternative" "0"))
3608 (const_string "1")))
3610 (if_then_else (eq_attr "prefix_0f" "0")
3612 (const_string "1")))])
3614 (define_insn "*extendhisi2_zext"
3615 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3617 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3620 switch (get_attr_prefix_0f (insn))
3623 return "{cwtl|cwde}";
3625 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3628 [(set_attr "type" "imovx")
3629 (set_attr "mode" "SI")
3630 (set (attr "prefix_0f")
3631 ;; movsx is short decodable while cwtl is vector decoded.
3632 (if_then_else (and (eq_attr "cpu" "!k6")
3633 (eq_attr "alternative" "0"))
3635 (const_string "1")))
3637 (if_then_else (eq_attr "prefix_0f" "0")
3639 (const_string "1")))])
3641 (define_insn "extendqihi2"
3642 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3643 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3646 switch (get_attr_prefix_0f (insn))
3649 return "{cbtw|cbw}";
3651 return "movs{bw|x}\t{%1,%0|%0, %1}";
3654 [(set_attr "type" "imovx")
3655 (set_attr "mode" "HI")
3656 (set (attr "prefix_0f")
3657 ;; movsx is short decodable while cwtl is vector decoded.
3658 (if_then_else (and (eq_attr "cpu" "!k6")
3659 (eq_attr "alternative" "0"))
3661 (const_string "1")))
3663 (if_then_else (eq_attr "prefix_0f" "0")
3665 (const_string "1")))])
3667 (define_insn "extendqisi2"
3668 [(set (match_operand:SI 0 "register_operand" "=r")
3669 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3671 "movs{bl|x}\t{%1,%0|%0, %1}"
3672 [(set_attr "type" "imovx")
3673 (set_attr "mode" "SI")])
3675 (define_insn "*extendqisi2_zext"
3676 [(set (match_operand:DI 0 "register_operand" "=r")
3678 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3680 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3681 [(set_attr "type" "imovx")
3682 (set_attr "mode" "SI")])
3684 ;; Conversions between float and double.
3686 ;; These are all no-ops in the model used for the 80387. So just
3689 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3690 (define_insn "*dummy_extendsfdf2"
3691 [(set (match_operand:DF 0 "push_operand" "=<")
3692 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3697 [(set (match_operand:DF 0 "push_operand" "")
3698 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3700 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3701 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3704 [(set (match_operand:DF 0 "push_operand" "")
3705 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3707 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3708 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3710 (define_insn "*dummy_extendsfxf2"
3711 [(set (match_operand:XF 0 "push_operand" "=<")
3712 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3717 [(set (match_operand:XF 0 "push_operand" "")
3718 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3720 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3721 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3722 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3725 [(set (match_operand:XF 0 "push_operand" "")
3726 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3728 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3729 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3730 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3733 [(set (match_operand:XF 0 "push_operand" "")
3734 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3736 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3737 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3738 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3741 [(set (match_operand:XF 0 "push_operand" "")
3742 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3744 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3745 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3746 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3748 (define_expand "extendsfdf2"
3749 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3750 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3751 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3753 /* ??? Needed for compress_float_constant since all fp constants
3754 are LEGITIMATE_CONSTANT_P. */
3755 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3757 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3758 && standard_80387_constant_p (operands[1]) > 0)
3760 operands[1] = simplify_const_unary_operation
3761 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3762 emit_move_insn_1 (operands[0], operands[1]);
3765 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3769 (define_insn "*extendsfdf2_mixed"
3770 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3772 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3773 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3775 switch (which_alternative)
3779 return output_387_reg_move (insn, operands);
3782 return "cvtss2sd\t{%1, %0|%0, %1}";
3788 [(set_attr "type" "fmov,fmov,ssecvt")
3789 (set_attr "mode" "SF,XF,DF")])
3791 (define_insn "*extendsfdf2_sse"
3792 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3793 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3794 "TARGET_SSE2 && TARGET_SSE_MATH"
3795 "cvtss2sd\t{%1, %0|%0, %1}"
3796 [(set_attr "type" "ssecvt")
3797 (set_attr "mode" "DF")])
3799 (define_insn "*extendsfdf2_i387"
3800 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3801 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3803 "* return output_387_reg_move (insn, operands);"
3804 [(set_attr "type" "fmov")
3805 (set_attr "mode" "SF,XF")])
3807 (define_expand "extend<mode>xf2"
3808 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3809 (float_extend:XF (match_operand:X87MODEF12 1 "general_operand" "")))]
3812 /* ??? Needed for compress_float_constant since all fp constants
3813 are LEGITIMATE_CONSTANT_P. */
3814 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3816 if (standard_80387_constant_p (operands[1]) > 0)
3818 operands[1] = simplify_const_unary_operation
3819 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3820 emit_move_insn_1 (operands[0], operands[1]);
3823 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3827 (define_insn "*extend<mode>xf2_i387"
3828 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3830 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,f")))]
3832 "* return output_387_reg_move (insn, operands);"
3833 [(set_attr "type" "fmov")
3834 (set_attr "mode" "<MODE>,XF")])
3836 ;; %%% This seems bad bad news.
3837 ;; This cannot output into an f-reg because there is no way to be sure
3838 ;; of truncating in that case. Otherwise this is just like a simple move
3839 ;; insn. So we pretend we can output to a reg in order to get better
3840 ;; register preferencing, but we really use a stack slot.
3842 ;; Conversion from DFmode to SFmode.
3844 (define_expand "truncdfsf2"
3845 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3847 (match_operand:DF 1 "nonimmediate_operand" "")))]
3848 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3850 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3852 else if (flag_unsafe_math_optimizations)
3856 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3857 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3862 (define_expand "truncdfsf2_with_temp"
3863 [(parallel [(set (match_operand:SF 0 "" "")
3864 (float_truncate:SF (match_operand:DF 1 "" "")))
3865 (clobber (match_operand:SF 2 "" ""))])]
3868 (define_insn "*truncdfsf_fast_mixed"
3869 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
3871 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3872 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3874 switch (which_alternative)
3878 return output_387_reg_move (insn, operands);
3880 return "cvtsd2ss\t{%1, %0|%0, %1}";
3885 [(set_attr "type" "fmov,fmov,ssecvt")
3886 (set_attr "mode" "SF")])
3888 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3889 ;; because nothing we do here is unsafe.
3890 (define_insn "*truncdfsf_fast_sse"
3891 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3893 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3894 "TARGET_SSE2 && TARGET_SSE_MATH"
3895 "cvtsd2ss\t{%1, %0|%0, %1}"
3896 [(set_attr "type" "ssecvt")
3897 (set_attr "mode" "SF")])
3899 (define_insn "*truncdfsf_fast_i387"
3900 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3902 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3903 "TARGET_80387 && flag_unsafe_math_optimizations"
3904 "* return output_387_reg_move (insn, operands);"
3905 [(set_attr "type" "fmov")
3906 (set_attr "mode" "SF")])
3908 (define_insn "*truncdfsf_mixed"
3909 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Yt")
3911 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ytm")))
3912 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3913 "TARGET_MIX_SSE_I387"
3915 switch (which_alternative)
3918 return output_387_reg_move (insn, operands);
3923 return "cvtsd2ss\t{%1, %0|%0, %1}";
3928 [(set_attr "type" "fmov,multi,ssecvt")
3929 (set_attr "unit" "*,i387,*")
3930 (set_attr "mode" "SF")])
3932 (define_insn "*truncdfsf_i387"
3933 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3935 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3936 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3939 switch (which_alternative)
3942 return output_387_reg_move (insn, operands);
3950 [(set_attr "type" "fmov,multi")
3951 (set_attr "unit" "*,i387")
3952 (set_attr "mode" "SF")])
3954 (define_insn "*truncdfsf2_i387_1"
3955 [(set (match_operand:SF 0 "memory_operand" "=m")
3957 (match_operand:DF 1 "register_operand" "f")))]
3959 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3960 && !TARGET_MIX_SSE_I387"
3961 "* return output_387_reg_move (insn, operands);"
3962 [(set_attr "type" "fmov")
3963 (set_attr "mode" "SF")])
3966 [(set (match_operand:SF 0 "register_operand" "")
3968 (match_operand:DF 1 "fp_register_operand" "")))
3969 (clobber (match_operand 2 "" ""))]
3971 [(set (match_dup 2) (match_dup 1))
3972 (set (match_dup 0) (match_dup 2))]
3974 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3977 ;; Conversion from XFmode to {SF,DF}mode
3979 (define_expand "truncxf<mode>2"
3980 [(parallel [(set (match_operand:X87MODEF12 0 "nonimmediate_operand" "")
3981 (float_truncate:X87MODEF12
3982 (match_operand:XF 1 "register_operand" "")))
3983 (clobber (match_dup 2))])]
3986 if (flag_unsafe_math_optimizations)
3988 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3989 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3990 if (reg != operands[0])
3991 emit_move_insn (operands[0], reg);
3995 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3998 (define_insn "*truncxfsf2_mixed"
3999 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4001 (match_operand:XF 1 "register_operand" "f,f")))
4002 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4005 gcc_assert (!which_alternative);
4006 return output_387_reg_move (insn, operands);
4008 [(set_attr "type" "fmov,multi")
4009 (set_attr "unit" "*,i387")
4010 (set_attr "mode" "SF")])
4012 (define_insn "*truncxfdf2_mixed"
4013 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fYt*r")
4015 (match_operand:XF 1 "register_operand" "f,f")))
4016 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4019 gcc_assert (!which_alternative);
4020 return output_387_reg_move (insn, operands);
4022 [(set_attr "type" "fmov,multi")
4023 (set_attr "unit" "*,i387")
4024 (set_attr "mode" "DF")])
4026 (define_insn "truncxf<mode>2_i387_noop"
4027 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
4028 (float_truncate:X87MODEF12
4029 (match_operand:XF 1 "register_operand" "f")))]
4030 "TARGET_80387 && flag_unsafe_math_optimizations"
4031 "* return output_387_reg_move (insn, operands);"
4032 [(set_attr "type" "fmov")
4033 (set_attr "mode" "<MODE>")])
4035 (define_insn "*truncxf<mode>2_i387"
4036 [(set (match_operand:X87MODEF12 0 "memory_operand" "=m")
4037 (float_truncate:X87MODEF12
4038 (match_operand:XF 1 "register_operand" "f")))]
4040 "* return output_387_reg_move (insn, operands);"
4041 [(set_attr "type" "fmov")
4042 (set_attr "mode" "<MODE>")])
4045 [(set (match_operand:X87MODEF12 0 "register_operand" "")
4046 (float_truncate:X87MODEF12
4047 (match_operand:XF 1 "register_operand" "")))
4048 (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4049 "TARGET_80387 && reload_completed"
4050 [(set (match_dup 2) (float_truncate:X87MODEF12 (match_dup 1)))
4051 (set (match_dup 0) (match_dup 2))]
4055 [(set (match_operand:X87MODEF12 0 "memory_operand" "")
4056 (float_truncate:X87MODEF12
4057 (match_operand:XF 1 "register_operand" "")))
4058 (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4060 [(set (match_dup 0) (float_truncate:X87MODEF12 (match_dup 1)))]
4063 ;; Signed conversion to DImode.
4065 (define_expand "fix_truncxfdi2"
4066 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4067 (fix:DI (match_operand:XF 1 "register_operand" "")))
4068 (clobber (reg:CC FLAGS_REG))])]
4073 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4078 (define_expand "fix_trunc<mode>di2"
4079 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4081 (clobber (reg:CC FLAGS_REG))])]
4082 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4085 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4087 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4090 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4092 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4093 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4094 if (out != operands[0])
4095 emit_move_insn (operands[0], out);
4100 ;; Signed conversion to SImode.
4102 (define_expand "fix_truncxfsi2"
4103 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4104 (fix:SI (match_operand:XF 1 "register_operand" "")))
4105 (clobber (reg:CC FLAGS_REG))])]
4110 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4115 (define_expand "fix_trunc<mode>si2"
4116 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4117 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4118 (clobber (reg:CC FLAGS_REG))])]
4119 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4122 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4124 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4127 if (SSE_FLOAT_MODE_P (<MODE>mode))
4129 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4130 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4131 if (out != operands[0])
4132 emit_move_insn (operands[0], out);
4137 ;; Signed conversion to HImode.
4139 (define_expand "fix_trunc<mode>hi2"
4140 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4141 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4142 (clobber (reg:CC FLAGS_REG))])]
4144 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4148 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4153 ;; Unsigned conversion to SImode.
4155 (define_expand "fixuns_trunc<mode>si2"
4157 [(set (match_operand:SI 0 "register_operand" "")
4159 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4161 (clobber (match_scratch:<ssevecmode> 3 ""))
4162 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4163 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4165 enum machine_mode mode = <MODE>mode;
4166 enum machine_mode vecmode = <ssevecmode>mode;
4167 REAL_VALUE_TYPE TWO31r;
4170 real_ldexp (&TWO31r, &dconst1, 31);
4171 two31 = const_double_from_real_value (TWO31r, mode);
4172 two31 = ix86_build_const_vector (mode, true, two31);
4173 operands[2] = force_reg (vecmode, two31);
4176 (define_insn_and_split "*fixuns_trunc<mode>_1"
4177 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4179 (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4180 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4181 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4182 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4183 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4185 "&& reload_completed"
4188 ix86_split_convert_uns_si_sse (operands);
4192 ;; Unsigned conversion to HImode.
4193 ;; Without these patterns, we'll try the unsigned SI conversion which
4194 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4196 (define_expand "fixuns_trunc<mode>hi2"
4198 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4199 (set (match_operand:HI 0 "nonimmediate_operand" "")
4200 (subreg:HI (match_dup 2) 0))]
4201 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4202 "operands[2] = gen_reg_rtx (SImode);")
4204 ;; When SSE is available, it is always faster to use it!
4205 (define_insn "fix_trunc<mode>di_sse"
4206 [(set (match_operand:DI 0 "register_operand" "=r,r")
4207 (fix:DI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4208 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4209 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4210 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4211 [(set_attr "type" "sseicvt")
4212 (set_attr "mode" "<MODE>")
4213 (set_attr "athlon_decode" "double,vector")
4214 (set_attr "amdfam10_decode" "double,double")])
4216 (define_insn "fix_trunc<mode>si_sse"
4217 [(set (match_operand:SI 0 "register_operand" "=r,r")
4218 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4219 "SSE_FLOAT_MODE_P (<MODE>mode)
4220 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4221 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4222 [(set_attr "type" "sseicvt")
4223 (set_attr "mode" "<MODE>")
4224 (set_attr "athlon_decode" "double,vector")
4225 (set_attr "amdfam10_decode" "double,double")])
4227 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4229 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4230 (match_operand:SSEMODEF 1 "memory_operand" ""))
4231 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4232 (fix:SSEMODEI24 (match_dup 0)))]
4233 "TARGET_SHORTEN_X87_SSE
4234 && peep2_reg_dead_p (2, operands[0])"
4235 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4238 ;; Avoid vector decoded forms of the instruction.
4240 [(match_scratch:DF 2 "Yt")
4241 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4242 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4243 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4244 [(set (match_dup 2) (match_dup 1))
4245 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4249 [(match_scratch:SF 2 "x")
4250 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4251 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4252 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4253 [(set (match_dup 2) (match_dup 1))
4254 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4257 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4258 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4259 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4260 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4262 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4263 && (TARGET_64BIT || <MODE>mode != DImode))
4265 && !(reload_completed || reload_in_progress)"
4270 if (memory_operand (operands[0], VOIDmode))
4271 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4274 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4275 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4281 [(set_attr "type" "fisttp")
4282 (set_attr "mode" "<MODE>")])
4284 (define_insn "fix_trunc<mode>_i387_fisttp"
4285 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4286 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4287 (clobber (match_scratch:XF 2 "=&1f"))]
4288 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4290 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4291 && (TARGET_64BIT || <MODE>mode != DImode))
4292 && TARGET_SSE_MATH)"
4293 "* return output_fix_trunc (insn, operands, 1);"
4294 [(set_attr "type" "fisttp")
4295 (set_attr "mode" "<MODE>")])
4297 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4298 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4299 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4300 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4301 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4302 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4304 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4305 && (TARGET_64BIT || <MODE>mode != DImode))
4306 && TARGET_SSE_MATH)"
4308 [(set_attr "type" "fisttp")
4309 (set_attr "mode" "<MODE>")])
4312 [(set (match_operand:X87MODEI 0 "register_operand" "")
4313 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4314 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4315 (clobber (match_scratch 3 ""))]
4317 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4318 (clobber (match_dup 3))])
4319 (set (match_dup 0) (match_dup 2))]
4323 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4324 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4325 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4326 (clobber (match_scratch 3 ""))]
4328 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4329 (clobber (match_dup 3))])]
4332 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4333 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4334 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4335 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4336 ;; function in i386.c.
4337 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4338 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4339 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4340 (clobber (reg:CC FLAGS_REG))]
4341 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4343 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4344 && (TARGET_64BIT || <MODE>mode != DImode))
4345 && !(reload_completed || reload_in_progress)"
4350 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4352 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4353 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4354 if (memory_operand (operands[0], VOIDmode))
4355 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4356 operands[2], operands[3]));
4359 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4360 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4361 operands[2], operands[3],
4366 [(set_attr "type" "fistp")
4367 (set_attr "i387_cw" "trunc")
4368 (set_attr "mode" "<MODE>")])
4370 (define_insn "fix_truncdi_i387"
4371 [(set (match_operand:DI 0 "memory_operand" "=m")
4372 (fix:DI (match_operand 1 "register_operand" "f")))
4373 (use (match_operand:HI 2 "memory_operand" "m"))
4374 (use (match_operand:HI 3 "memory_operand" "m"))
4375 (clobber (match_scratch:XF 4 "=&1f"))]
4376 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4378 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4379 "* return output_fix_trunc (insn, operands, 0);"
4380 [(set_attr "type" "fistp")
4381 (set_attr "i387_cw" "trunc")
4382 (set_attr "mode" "DI")])
4384 (define_insn "fix_truncdi_i387_with_temp"
4385 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4386 (fix:DI (match_operand 1 "register_operand" "f,f")))
4387 (use (match_operand:HI 2 "memory_operand" "m,m"))
4388 (use (match_operand:HI 3 "memory_operand" "m,m"))
4389 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4390 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4391 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4393 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4395 [(set_attr "type" "fistp")
4396 (set_attr "i387_cw" "trunc")
4397 (set_attr "mode" "DI")])
4400 [(set (match_operand:DI 0 "register_operand" "")
4401 (fix:DI (match_operand 1 "register_operand" "")))
4402 (use (match_operand:HI 2 "memory_operand" ""))
4403 (use (match_operand:HI 3 "memory_operand" ""))
4404 (clobber (match_operand:DI 4 "memory_operand" ""))
4405 (clobber (match_scratch 5 ""))]
4407 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4410 (clobber (match_dup 5))])
4411 (set (match_dup 0) (match_dup 4))]
4415 [(set (match_operand:DI 0 "memory_operand" "")
4416 (fix:DI (match_operand 1 "register_operand" "")))
4417 (use (match_operand:HI 2 "memory_operand" ""))
4418 (use (match_operand:HI 3 "memory_operand" ""))
4419 (clobber (match_operand:DI 4 "memory_operand" ""))
4420 (clobber (match_scratch 5 ""))]
4422 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4425 (clobber (match_dup 5))])]
4428 (define_insn "fix_trunc<mode>_i387"
4429 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4430 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4431 (use (match_operand:HI 2 "memory_operand" "m"))
4432 (use (match_operand:HI 3 "memory_operand" "m"))]
4433 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4435 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4436 "* return output_fix_trunc (insn, operands, 0);"
4437 [(set_attr "type" "fistp")
4438 (set_attr "i387_cw" "trunc")
4439 (set_attr "mode" "<MODE>")])
4441 (define_insn "fix_trunc<mode>_i387_with_temp"
4442 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4443 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4444 (use (match_operand:HI 2 "memory_operand" "m,m"))
4445 (use (match_operand:HI 3 "memory_operand" "m,m"))
4446 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4447 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4449 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4451 [(set_attr "type" "fistp")
4452 (set_attr "i387_cw" "trunc")
4453 (set_attr "mode" "<MODE>")])
4456 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4457 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4458 (use (match_operand:HI 2 "memory_operand" ""))
4459 (use (match_operand:HI 3 "memory_operand" ""))
4460 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4462 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4464 (use (match_dup 3))])
4465 (set (match_dup 0) (match_dup 4))]
4469 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4470 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4471 (use (match_operand:HI 2 "memory_operand" ""))
4472 (use (match_operand:HI 3 "memory_operand" ""))
4473 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4475 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4477 (use (match_dup 3))])]
4480 (define_insn "x86_fnstcw_1"
4481 [(set (match_operand:HI 0 "memory_operand" "=m")
4482 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4485 [(set_attr "length" "2")
4486 (set_attr "mode" "HI")
4487 (set_attr "unit" "i387")])
4489 (define_insn "x86_fldcw_1"
4490 [(set (reg:HI FPCR_REG)
4491 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4494 [(set_attr "length" "2")
4495 (set_attr "mode" "HI")
4496 (set_attr "unit" "i387")
4497 (set_attr "athlon_decode" "vector")
4498 (set_attr "amdfam10_decode" "vector")])
4500 ;; Conversion between fixed point and floating point.
4502 ;; Even though we only accept memory inputs, the backend _really_
4503 ;; wants to be able to do this between registers.
4505 (define_expand "floathi<mode>2"
4506 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4507 (float:SSEMODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4508 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4510 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4513 (gen_floatsi<mode>2 (operands[0],
4514 convert_to_mode (SImode, operands[1], 0)));
4519 (define_insn "*floathi<mode>2_i387"
4520 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4522 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4524 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4525 || TARGET_MIX_SSE_I387)"
4529 [(set_attr "type" "fmov,multi")
4530 (set_attr "mode" "<MODE>")
4531 (set_attr "unit" "*,i387")
4532 (set_attr "fp_int_src" "true")])
4534 (define_expand "floatsi<mode>2"
4535 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4536 (float:SSEMODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4537 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4540 (define_insn "*floatsisf2_mixed"
4541 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4542 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4543 "TARGET_MIX_SSE_I387"
4547 cvtsi2ss\t{%1, %0|%0, %1}
4548 cvtsi2ss\t{%1, %0|%0, %1}"
4549 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4550 (set_attr "mode" "SF")
4551 (set_attr "unit" "*,i387,*,*")
4552 (set_attr "athlon_decode" "*,*,vector,double")
4553 (set_attr "amdfam10_decode" "*,*,vector,double")
4554 (set_attr "fp_int_src" "true")])
4556 (define_insn "*floatsisf2_sse"
4557 [(set (match_operand:SF 0 "register_operand" "=x,x")
4558 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4560 "cvtsi2ss\t{%1, %0|%0, %1}"
4561 [(set_attr "type" "sseicvt")
4562 (set_attr "mode" "SF")
4563 (set_attr "athlon_decode" "vector,double")
4564 (set_attr "amdfam10_decode" "vector,double")
4565 (set_attr "fp_int_src" "true")])
4567 (define_insn "*floatsidf2_mixed"
4568 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4569 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4570 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4574 cvtsi2sd\t{%1, %0|%0, %1}
4575 cvtsi2sd\t{%1, %0|%0, %1}"
4576 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4577 (set_attr "mode" "DF")
4578 (set_attr "unit" "*,i387,*,*")
4579 (set_attr "athlon_decode" "*,*,double,direct")
4580 (set_attr "amdfam10_decode" "*,*,vector,double")
4581 (set_attr "fp_int_src" "true")])
4583 (define_insn "*floatsidf2_sse"
4584 [(set (match_operand:DF 0 "register_operand" "=x,x")
4585 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4586 "TARGET_SSE2 && TARGET_SSE_MATH"
4587 "cvtsi2sd\t{%1, %0|%0, %1}"
4588 [(set_attr "type" "sseicvt")
4589 (set_attr "mode" "DF")
4590 (set_attr "athlon_decode" "double,direct")
4591 (set_attr "amdfam10_decode" "vector,double")
4592 (set_attr "fp_int_src" "true")])
4594 (define_insn "*floatsi<mode>2_i387"
4595 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4597 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4602 [(set_attr "type" "fmov,multi")
4603 (set_attr "mode" "<MODE>")
4604 (set_attr "unit" "*,i387")
4605 (set_attr "fp_int_src" "true")])
4607 (define_expand "floatdisf2"
4608 [(set (match_operand:SF 0 "register_operand" "")
4609 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4610 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4613 (define_insn "*floatdisf2_mixed"
4614 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4615 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4616 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4620 cvtsi2ss{q}\t{%1, %0|%0, %1}
4621 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4622 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4623 (set_attr "mode" "SF")
4624 (set_attr "unit" "*,i387,*,*")
4625 (set_attr "athlon_decode" "*,*,vector,double")
4626 (set_attr "amdfam10_decode" "*,*,vector,double")
4627 (set_attr "fp_int_src" "true")])
4629 (define_insn "*floatdisf2_sse"
4630 [(set (match_operand:SF 0 "register_operand" "=x,x")
4631 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4632 "TARGET_64BIT && TARGET_SSE_MATH"
4633 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4634 [(set_attr "type" "sseicvt")
4635 (set_attr "mode" "SF")
4636 (set_attr "athlon_decode" "vector,double")
4637 (set_attr "amdfam10_decode" "vector,double")
4638 (set_attr "fp_int_src" "true")])
4640 (define_expand "floatdidf2"
4641 [(set (match_operand:DF 0 "register_operand" "")
4642 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4643 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4645 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4647 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4652 (define_insn "*floatdidf2_mixed"
4653 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4654 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4655 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4659 cvtsi2sd{q}\t{%1, %0|%0, %1}
4660 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4661 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4662 (set_attr "mode" "DF")
4663 (set_attr "unit" "*,i387,*,*")
4664 (set_attr "athlon_decode" "*,*,double,direct")
4665 (set_attr "amdfam10_decode" "*,*,vector,double")
4666 (set_attr "fp_int_src" "true")])
4668 (define_insn "*floatdidf2_sse"
4669 [(set (match_operand:DF 0 "register_operand" "=x,x")
4670 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4671 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4672 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673 [(set_attr "type" "sseicvt")
4674 (set_attr "mode" "DF")
4675 (set_attr "athlon_decode" "double,direct")
4676 (set_attr "amdfam10_decode" "vector,double")
4677 (set_attr "fp_int_src" "true")])
4679 (define_insn "*floatdi<mode>2_i387"
4680 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4682 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4687 [(set_attr "type" "fmov,multi")
4688 (set_attr "mode" "<MODE>")
4689 (set_attr "unit" "*,i387")
4690 (set_attr "fp_int_src" "true")])
4692 (define_insn "float<mode>xf2"
4693 [(set (match_operand:XF 0 "register_operand" "=f,f")
4694 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
4699 [(set_attr "type" "fmov,multi")
4700 (set_attr "mode" "XF")
4701 (set_attr "unit" "*,i387")
4702 (set_attr "fp_int_src" "true")])
4704 ;; %%% Kill these when reload knows how to do it.
4706 [(set (match_operand 0 "fp_register_operand" "")
4707 (float (match_operand 1 "register_operand" "")))]
4709 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
4712 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4713 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4714 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4715 ix86_free_from_memory (GET_MODE (operands[1]));
4719 (define_expand "floatunssisf2"
4720 [(use (match_operand:SF 0 "register_operand" ""))
4721 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4724 if (TARGET_SSE_MATH && TARGET_SSE2)
4725 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4727 x86_emit_floatuns (operands);
4731 (define_expand "floatunssidf2"
4732 [(use (match_operand:DF 0 "register_operand" ""))
4733 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4734 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4735 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
4737 (define_expand "floatunsdisf2"
4738 [(use (match_operand:SF 0 "register_operand" ""))
4739 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4740 "TARGET_64BIT && TARGET_SSE_MATH"
4741 "x86_emit_floatuns (operands); DONE;")
4743 (define_expand "floatunsdidf2"
4744 [(use (match_operand:DF 0 "register_operand" ""))
4745 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4746 "TARGET_SSE_MATH && TARGET_SSE2
4747 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
4750 x86_emit_floatuns (operands);
4752 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
4758 ;; %%% splits for addditi3
4760 (define_expand "addti3"
4761 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4762 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4763 (match_operand:TI 2 "x86_64_general_operand" "")))
4764 (clobber (reg:CC FLAGS_REG))]
4766 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4768 (define_insn "*addti3_1"
4769 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4770 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4771 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4772 (clobber (reg:CC FLAGS_REG))]
4773 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4777 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4778 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4779 (match_operand:TI 2 "x86_64_general_operand" "")))
4780 (clobber (reg:CC FLAGS_REG))]
4781 "TARGET_64BIT && reload_completed"
4782 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4784 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4785 (parallel [(set (match_dup 3)
4786 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4789 (clobber (reg:CC FLAGS_REG))])]
4790 "split_ti (operands+0, 1, operands+0, operands+3);
4791 split_ti (operands+1, 1, operands+1, operands+4);
4792 split_ti (operands+2, 1, operands+2, operands+5);")
4794 ;; %%% splits for addsidi3
4795 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4796 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4797 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4799 (define_expand "adddi3"
4800 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4801 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4802 (match_operand:DI 2 "x86_64_general_operand" "")))
4803 (clobber (reg:CC FLAGS_REG))]
4805 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4807 (define_insn "*adddi3_1"
4808 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4809 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4810 (match_operand:DI 2 "general_operand" "roiF,riF")))
4811 (clobber (reg:CC FLAGS_REG))]
4812 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4816 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4817 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4818 (match_operand:DI 2 "general_operand" "")))
4819 (clobber (reg:CC FLAGS_REG))]
4820 "!TARGET_64BIT && reload_completed"
4821 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4823 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4824 (parallel [(set (match_dup 3)
4825 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4828 (clobber (reg:CC FLAGS_REG))])]
4829 "split_di (operands+0, 1, operands+0, operands+3);
4830 split_di (operands+1, 1, operands+1, operands+4);
4831 split_di (operands+2, 1, operands+2, operands+5);")
4833 (define_insn "adddi3_carry_rex64"
4834 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4835 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4836 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4837 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4838 (clobber (reg:CC FLAGS_REG))]
4839 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4840 "adc{q}\t{%2, %0|%0, %2}"
4841 [(set_attr "type" "alu")
4842 (set_attr "pent_pair" "pu")
4843 (set_attr "mode" "DI")])
4845 (define_insn "*adddi3_cc_rex64"
4846 [(set (reg:CC FLAGS_REG)
4847 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4848 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4850 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4851 (plus:DI (match_dup 1) (match_dup 2)))]
4852 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4853 "add{q}\t{%2, %0|%0, %2}"
4854 [(set_attr "type" "alu")
4855 (set_attr "mode" "DI")])
4857 (define_insn "addqi3_carry"
4858 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4859 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4860 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4861 (match_operand:QI 2 "general_operand" "qi,qm")))
4862 (clobber (reg:CC FLAGS_REG))]
4863 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4864 "adc{b}\t{%2, %0|%0, %2}"
4865 [(set_attr "type" "alu")
4866 (set_attr "pent_pair" "pu")
4867 (set_attr "mode" "QI")])
4869 (define_insn "addhi3_carry"
4870 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4871 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4872 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4873 (match_operand:HI 2 "general_operand" "ri,rm")))
4874 (clobber (reg:CC FLAGS_REG))]
4875 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4876 "adc{w}\t{%2, %0|%0, %2}"
4877 [(set_attr "type" "alu")
4878 (set_attr "pent_pair" "pu")
4879 (set_attr "mode" "HI")])
4881 (define_insn "addsi3_carry"
4882 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4883 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4884 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4885 (match_operand:SI 2 "general_operand" "ri,rm")))
4886 (clobber (reg:CC FLAGS_REG))]
4887 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4888 "adc{l}\t{%2, %0|%0, %2}"
4889 [(set_attr "type" "alu")
4890 (set_attr "pent_pair" "pu")
4891 (set_attr "mode" "SI")])
4893 (define_insn "*addsi3_carry_zext"
4894 [(set (match_operand:DI 0 "register_operand" "=r")
4896 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4897 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4898 (match_operand:SI 2 "general_operand" "rim"))))
4899 (clobber (reg:CC FLAGS_REG))]
4900 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4901 "adc{l}\t{%2, %k0|%k0, %2}"
4902 [(set_attr "type" "alu")
4903 (set_attr "pent_pair" "pu")
4904 (set_attr "mode" "SI")])
4906 (define_insn "*addsi3_cc"
4907 [(set (reg:CC FLAGS_REG)
4908 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4909 (match_operand:SI 2 "general_operand" "ri,rm")]
4911 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4912 (plus:SI (match_dup 1) (match_dup 2)))]
4913 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4914 "add{l}\t{%2, %0|%0, %2}"
4915 [(set_attr "type" "alu")
4916 (set_attr "mode" "SI")])
4918 (define_insn "addqi3_cc"
4919 [(set (reg:CC FLAGS_REG)
4920 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4921 (match_operand:QI 2 "general_operand" "qi,qm")]
4923 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4924 (plus:QI (match_dup 1) (match_dup 2)))]
4925 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4926 "add{b}\t{%2, %0|%0, %2}"
4927 [(set_attr "type" "alu")
4928 (set_attr "mode" "QI")])
4930 (define_expand "addsi3"
4931 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4932 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4933 (match_operand:SI 2 "general_operand" "")))
4934 (clobber (reg:CC FLAGS_REG))])]
4936 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4938 (define_insn "*lea_1"
4939 [(set (match_operand:SI 0 "register_operand" "=r")
4940 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4942 "lea{l}\t{%a1, %0|%0, %a1}"
4943 [(set_attr "type" "lea")
4944 (set_attr "mode" "SI")])
4946 (define_insn "*lea_1_rex64"
4947 [(set (match_operand:SI 0 "register_operand" "=r")
4948 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4950 "lea{l}\t{%a1, %0|%0, %a1}"
4951 [(set_attr "type" "lea")
4952 (set_attr "mode" "SI")])
4954 (define_insn "*lea_1_zext"
4955 [(set (match_operand:DI 0 "register_operand" "=r")
4957 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4959 "lea{l}\t{%a1, %k0|%k0, %a1}"
4960 [(set_attr "type" "lea")
4961 (set_attr "mode" "SI")])
4963 (define_insn "*lea_2_rex64"
4964 [(set (match_operand:DI 0 "register_operand" "=r")
4965 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4967 "lea{q}\t{%a1, %0|%0, %a1}"
4968 [(set_attr "type" "lea")
4969 (set_attr "mode" "DI")])
4971 ;; The lea patterns for non-Pmodes needs to be matched by several
4972 ;; insns converted to real lea by splitters.
4974 (define_insn_and_split "*lea_general_1"
4975 [(set (match_operand 0 "register_operand" "=r")
4976 (plus (plus (match_operand 1 "index_register_operand" "l")
4977 (match_operand 2 "register_operand" "r"))
4978 (match_operand 3 "immediate_operand" "i")))]
4979 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4980 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4981 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4982 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4983 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4984 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4985 || GET_MODE (operands[3]) == VOIDmode)"
4987 "&& reload_completed"
4991 operands[0] = gen_lowpart (SImode, operands[0]);
4992 operands[1] = gen_lowpart (Pmode, operands[1]);
4993 operands[2] = gen_lowpart (Pmode, operands[2]);
4994 operands[3] = gen_lowpart (Pmode, operands[3]);
4995 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4997 if (Pmode != SImode)
4998 pat = gen_rtx_SUBREG (SImode, pat, 0);
4999 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5002 [(set_attr "type" "lea")
5003 (set_attr "mode" "SI")])
5005 (define_insn_and_split "*lea_general_1_zext"
5006 [(set (match_operand:DI 0 "register_operand" "=r")
5008 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5009 (match_operand:SI 2 "register_operand" "r"))
5010 (match_operand:SI 3 "immediate_operand" "i"))))]
5013 "&& reload_completed"
5015 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5017 (match_dup 3)) 0)))]
5019 operands[1] = gen_lowpart (Pmode, operands[1]);
5020 operands[2] = gen_lowpart (Pmode, operands[2]);
5021 operands[3] = gen_lowpart (Pmode, operands[3]);
5023 [(set_attr "type" "lea")
5024 (set_attr "mode" "SI")])
5026 (define_insn_and_split "*lea_general_2"
5027 [(set (match_operand 0 "register_operand" "=r")
5028 (plus (mult (match_operand 1 "index_register_operand" "l")
5029 (match_operand 2 "const248_operand" "i"))
5030 (match_operand 3 "nonmemory_operand" "ri")))]
5031 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5032 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5033 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5034 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5035 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5036 || GET_MODE (operands[3]) == VOIDmode)"
5038 "&& reload_completed"
5042 operands[0] = gen_lowpart (SImode, operands[0]);
5043 operands[1] = gen_lowpart (Pmode, operands[1]);
5044 operands[3] = gen_lowpart (Pmode, operands[3]);
5045 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5047 if (Pmode != SImode)
5048 pat = gen_rtx_SUBREG (SImode, pat, 0);
5049 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5052 [(set_attr "type" "lea")
5053 (set_attr "mode" "SI")])
5055 (define_insn_and_split "*lea_general_2_zext"
5056 [(set (match_operand:DI 0 "register_operand" "=r")
5058 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5059 (match_operand:SI 2 "const248_operand" "n"))
5060 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5063 "&& reload_completed"
5065 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5067 (match_dup 3)) 0)))]
5069 operands[1] = gen_lowpart (Pmode, operands[1]);
5070 operands[3] = gen_lowpart (Pmode, operands[3]);
5072 [(set_attr "type" "lea")
5073 (set_attr "mode" "SI")])
5075 (define_insn_and_split "*lea_general_3"
5076 [(set (match_operand 0 "register_operand" "=r")
5077 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5078 (match_operand 2 "const248_operand" "i"))
5079 (match_operand 3 "register_operand" "r"))
5080 (match_operand 4 "immediate_operand" "i")))]
5081 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5082 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5083 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5084 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5085 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5087 "&& reload_completed"
5091 operands[0] = gen_lowpart (SImode, operands[0]);
5092 operands[1] = gen_lowpart (Pmode, operands[1]);
5093 operands[3] = gen_lowpart (Pmode, operands[3]);
5094 operands[4] = gen_lowpart (Pmode, operands[4]);
5095 pat = gen_rtx_PLUS (Pmode,
5096 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5100 if (Pmode != SImode)
5101 pat = gen_rtx_SUBREG (SImode, pat, 0);
5102 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5105 [(set_attr "type" "lea")
5106 (set_attr "mode" "SI")])
5108 (define_insn_and_split "*lea_general_3_zext"
5109 [(set (match_operand:DI 0 "register_operand" "=r")
5111 (plus:SI (plus:SI (mult:SI
5112 (match_operand:SI 1 "index_register_operand" "l")
5113 (match_operand:SI 2 "const248_operand" "n"))
5114 (match_operand:SI 3 "register_operand" "r"))
5115 (match_operand:SI 4 "immediate_operand" "i"))))]
5118 "&& reload_completed"
5120 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5123 (match_dup 4)) 0)))]
5125 operands[1] = gen_lowpart (Pmode, operands[1]);
5126 operands[3] = gen_lowpart (Pmode, operands[3]);
5127 operands[4] = gen_lowpart (Pmode, operands[4]);
5129 [(set_attr "type" "lea")
5130 (set_attr "mode" "SI")])
5132 (define_insn "*adddi_1_rex64"
5133 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5134 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5135 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5136 (clobber (reg:CC FLAGS_REG))]
5137 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5139 switch (get_attr_type (insn))
5142 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5143 return "lea{q}\t{%a2, %0|%0, %a2}";
5146 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5147 if (operands[2] == const1_rtx)
5148 return "inc{q}\t%0";
5151 gcc_assert (operands[2] == constm1_rtx);
5152 return "dec{q}\t%0";
5156 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5158 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5159 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5160 if (CONST_INT_P (operands[2])
5161 /* Avoid overflows. */
5162 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5163 && (INTVAL (operands[2]) == 128
5164 || (INTVAL (operands[2]) < 0
5165 && INTVAL (operands[2]) != -128)))
5167 operands[2] = GEN_INT (-INTVAL (operands[2]));
5168 return "sub{q}\t{%2, %0|%0, %2}";
5170 return "add{q}\t{%2, %0|%0, %2}";
5174 (cond [(eq_attr "alternative" "2")
5175 (const_string "lea")
5176 ; Current assemblers are broken and do not allow @GOTOFF in
5177 ; ought but a memory context.
5178 (match_operand:DI 2 "pic_symbolic_operand" "")
5179 (const_string "lea")
5180 (match_operand:DI 2 "incdec_operand" "")
5181 (const_string "incdec")
5183 (const_string "alu")))
5184 (set_attr "mode" "DI")])
5186 ;; Convert lea to the lea pattern to avoid flags dependency.
5188 [(set (match_operand:DI 0 "register_operand" "")
5189 (plus:DI (match_operand:DI 1 "register_operand" "")
5190 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5191 (clobber (reg:CC FLAGS_REG))]
5192 "TARGET_64BIT && reload_completed
5193 && true_regnum (operands[0]) != true_regnum (operands[1])"
5195 (plus:DI (match_dup 1)
5199 (define_insn "*adddi_2_rex64"
5200 [(set (reg FLAGS_REG)
5202 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5203 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5205 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5206 (plus:DI (match_dup 1) (match_dup 2)))]
5207 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5208 && ix86_binary_operator_ok (PLUS, DImode, operands)
5209 /* Current assemblers are broken and do not allow @GOTOFF in
5210 ought but a memory context. */
5211 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5213 switch (get_attr_type (insn))
5216 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5217 if (operands[2] == const1_rtx)
5218 return "inc{q}\t%0";
5221 gcc_assert (operands[2] == constm1_rtx);
5222 return "dec{q}\t%0";
5226 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5227 /* ???? We ought to handle there the 32bit case too
5228 - do we need new constraint? */
5229 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5230 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5231 if (CONST_INT_P (operands[2])
5232 /* Avoid overflows. */
5233 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5234 && (INTVAL (operands[2]) == 128
5235 || (INTVAL (operands[2]) < 0
5236 && INTVAL (operands[2]) != -128)))
5238 operands[2] = GEN_INT (-INTVAL (operands[2]));
5239 return "sub{q}\t{%2, %0|%0, %2}";
5241 return "add{q}\t{%2, %0|%0, %2}";
5245 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5246 (const_string "incdec")
5247 (const_string "alu")))
5248 (set_attr "mode" "DI")])
5250 (define_insn "*adddi_3_rex64"
5251 [(set (reg FLAGS_REG)
5252 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5253 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5254 (clobber (match_scratch:DI 0 "=r"))]
5256 && ix86_match_ccmode (insn, CCZmode)
5257 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5258 /* Current assemblers are broken and do not allow @GOTOFF in
5259 ought but a memory context. */
5260 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5262 switch (get_attr_type (insn))
5265 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5266 if (operands[2] == const1_rtx)
5267 return "inc{q}\t%0";
5270 gcc_assert (operands[2] == constm1_rtx);
5271 return "dec{q}\t%0";
5275 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5276 /* ???? We ought to handle there the 32bit case too
5277 - do we need new constraint? */
5278 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5279 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5280 if (CONST_INT_P (operands[2])
5281 /* Avoid overflows. */
5282 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5283 && (INTVAL (operands[2]) == 128
5284 || (INTVAL (operands[2]) < 0
5285 && INTVAL (operands[2]) != -128)))
5287 operands[2] = GEN_INT (-INTVAL (operands[2]));
5288 return "sub{q}\t{%2, %0|%0, %2}";
5290 return "add{q}\t{%2, %0|%0, %2}";
5294 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5295 (const_string "incdec")
5296 (const_string "alu")))
5297 (set_attr "mode" "DI")])
5299 ; For comparisons against 1, -1 and 128, we may generate better code
5300 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5301 ; is matched then. We can't accept general immediate, because for
5302 ; case of overflows, the result is messed up.
5303 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5305 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5306 ; only for comparisons not depending on it.
5307 (define_insn "*adddi_4_rex64"
5308 [(set (reg FLAGS_REG)
5309 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5310 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5311 (clobber (match_scratch:DI 0 "=rm"))]
5313 && ix86_match_ccmode (insn, CCGCmode)"
5315 switch (get_attr_type (insn))
5318 if (operands[2] == constm1_rtx)
5319 return "inc{q}\t%0";
5322 gcc_assert (operands[2] == const1_rtx);
5323 return "dec{q}\t%0";
5327 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5328 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5329 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5330 if ((INTVAL (operands[2]) == -128
5331 || (INTVAL (operands[2]) > 0
5332 && INTVAL (operands[2]) != 128))
5333 /* Avoid overflows. */
5334 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5335 return "sub{q}\t{%2, %0|%0, %2}";
5336 operands[2] = GEN_INT (-INTVAL (operands[2]));
5337 return "add{q}\t{%2, %0|%0, %2}";
5341 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5342 (const_string "incdec")
5343 (const_string "alu")))
5344 (set_attr "mode" "DI")])
5346 (define_insn "*adddi_5_rex64"
5347 [(set (reg FLAGS_REG)
5349 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5350 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5352 (clobber (match_scratch:DI 0 "=r"))]
5354 && ix86_match_ccmode (insn, CCGOCmode)
5355 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5356 /* Current assemblers are broken and do not allow @GOTOFF in
5357 ought but a memory context. */
5358 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5360 switch (get_attr_type (insn))
5363 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5364 if (operands[2] == const1_rtx)
5365 return "inc{q}\t%0";
5368 gcc_assert (operands[2] == constm1_rtx);
5369 return "dec{q}\t%0";
5373 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5374 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5376 if (CONST_INT_P (operands[2])
5377 /* Avoid overflows. */
5378 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5379 && (INTVAL (operands[2]) == 128
5380 || (INTVAL (operands[2]) < 0
5381 && INTVAL (operands[2]) != -128)))
5383 operands[2] = GEN_INT (-INTVAL (operands[2]));
5384 return "sub{q}\t{%2, %0|%0, %2}";
5386 return "add{q}\t{%2, %0|%0, %2}";
5390 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5391 (const_string "incdec")
5392 (const_string "alu")))
5393 (set_attr "mode" "DI")])
5396 (define_insn "*addsi_1"
5397 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5398 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5399 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5400 (clobber (reg:CC FLAGS_REG))]
5401 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5403 switch (get_attr_type (insn))
5406 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5407 return "lea{l}\t{%a2, %0|%0, %a2}";
5410 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5411 if (operands[2] == const1_rtx)
5412 return "inc{l}\t%0";
5415 gcc_assert (operands[2] == constm1_rtx);
5416 return "dec{l}\t%0";
5420 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5422 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5423 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5424 if (CONST_INT_P (operands[2])
5425 && (INTVAL (operands[2]) == 128
5426 || (INTVAL (operands[2]) < 0
5427 && INTVAL (operands[2]) != -128)))
5429 operands[2] = GEN_INT (-INTVAL (operands[2]));
5430 return "sub{l}\t{%2, %0|%0, %2}";
5432 return "add{l}\t{%2, %0|%0, %2}";
5436 (cond [(eq_attr "alternative" "2")
5437 (const_string "lea")
5438 ; Current assemblers are broken and do not allow @GOTOFF in
5439 ; ought but a memory context.
5440 (match_operand:SI 2 "pic_symbolic_operand" "")
5441 (const_string "lea")
5442 (match_operand:SI 2 "incdec_operand" "")
5443 (const_string "incdec")
5445 (const_string "alu")))
5446 (set_attr "mode" "SI")])
5448 ;; Convert lea to the lea pattern to avoid flags dependency.
5450 [(set (match_operand 0 "register_operand" "")
5451 (plus (match_operand 1 "register_operand" "")
5452 (match_operand 2 "nonmemory_operand" "")))
5453 (clobber (reg:CC FLAGS_REG))]
5455 && true_regnum (operands[0]) != true_regnum (operands[1])"
5459 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5460 may confuse gen_lowpart. */
5461 if (GET_MODE (operands[0]) != Pmode)
5463 operands[1] = gen_lowpart (Pmode, operands[1]);
5464 operands[2] = gen_lowpart (Pmode, operands[2]);
5466 operands[0] = gen_lowpart (SImode, operands[0]);
5467 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5468 if (Pmode != SImode)
5469 pat = gen_rtx_SUBREG (SImode, pat, 0);
5470 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5474 ;; It may seem that nonimmediate operand is proper one for operand 1.
5475 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5476 ;; we take care in ix86_binary_operator_ok to not allow two memory
5477 ;; operands so proper swapping will be done in reload. This allow
5478 ;; patterns constructed from addsi_1 to match.
5479 (define_insn "addsi_1_zext"
5480 [(set (match_operand:DI 0 "register_operand" "=r,r")
5482 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5483 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5484 (clobber (reg:CC FLAGS_REG))]
5485 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5487 switch (get_attr_type (insn))
5490 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5491 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5494 if (operands[2] == const1_rtx)
5495 return "inc{l}\t%k0";
5498 gcc_assert (operands[2] == constm1_rtx);
5499 return "dec{l}\t%k0";
5503 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5504 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5505 if (CONST_INT_P (operands[2])
5506 && (INTVAL (operands[2]) == 128
5507 || (INTVAL (operands[2]) < 0
5508 && INTVAL (operands[2]) != -128)))
5510 operands[2] = GEN_INT (-INTVAL (operands[2]));
5511 return "sub{l}\t{%2, %k0|%k0, %2}";
5513 return "add{l}\t{%2, %k0|%k0, %2}";
5517 (cond [(eq_attr "alternative" "1")
5518 (const_string "lea")
5519 ; Current assemblers are broken and do not allow @GOTOFF in
5520 ; ought but a memory context.
5521 (match_operand:SI 2 "pic_symbolic_operand" "")
5522 (const_string "lea")
5523 (match_operand:SI 2 "incdec_operand" "")
5524 (const_string "incdec")
5526 (const_string "alu")))
5527 (set_attr "mode" "SI")])
5529 ;; Convert lea to the lea pattern to avoid flags dependency.
5531 [(set (match_operand:DI 0 "register_operand" "")
5533 (plus:SI (match_operand:SI 1 "register_operand" "")
5534 (match_operand:SI 2 "nonmemory_operand" ""))))
5535 (clobber (reg:CC FLAGS_REG))]
5536 "TARGET_64BIT && reload_completed
5537 && true_regnum (operands[0]) != true_regnum (operands[1])"
5539 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5541 operands[1] = gen_lowpart (Pmode, operands[1]);
5542 operands[2] = gen_lowpart (Pmode, operands[2]);
5545 (define_insn "*addsi_2"
5546 [(set (reg FLAGS_REG)
5548 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5549 (match_operand:SI 2 "general_operand" "rmni,rni"))
5551 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5552 (plus:SI (match_dup 1) (match_dup 2)))]
5553 "ix86_match_ccmode (insn, CCGOCmode)
5554 && ix86_binary_operator_ok (PLUS, SImode, operands)
5555 /* Current assemblers are broken and do not allow @GOTOFF in
5556 ought but a memory context. */
5557 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5559 switch (get_attr_type (insn))
5562 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5563 if (operands[2] == const1_rtx)
5564 return "inc{l}\t%0";
5567 gcc_assert (operands[2] == constm1_rtx);
5568 return "dec{l}\t%0";
5572 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5573 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5574 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5575 if (CONST_INT_P (operands[2])
5576 && (INTVAL (operands[2]) == 128
5577 || (INTVAL (operands[2]) < 0
5578 && INTVAL (operands[2]) != -128)))
5580 operands[2] = GEN_INT (-INTVAL (operands[2]));
5581 return "sub{l}\t{%2, %0|%0, %2}";
5583 return "add{l}\t{%2, %0|%0, %2}";
5587 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5588 (const_string "incdec")
5589 (const_string "alu")))
5590 (set_attr "mode" "SI")])
5592 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5593 (define_insn "*addsi_2_zext"
5594 [(set (reg FLAGS_REG)
5596 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5597 (match_operand:SI 2 "general_operand" "rmni"))
5599 (set (match_operand:DI 0 "register_operand" "=r")
5600 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5601 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5602 && ix86_binary_operator_ok (PLUS, SImode, operands)
5603 /* Current assemblers are broken and do not allow @GOTOFF in
5604 ought but a memory context. */
5605 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5607 switch (get_attr_type (insn))
5610 if (operands[2] == const1_rtx)
5611 return "inc{l}\t%k0";
5614 gcc_assert (operands[2] == constm1_rtx);
5615 return "dec{l}\t%k0";
5619 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5620 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5621 if (CONST_INT_P (operands[2])
5622 && (INTVAL (operands[2]) == 128
5623 || (INTVAL (operands[2]) < 0
5624 && INTVAL (operands[2]) != -128)))
5626 operands[2] = GEN_INT (-INTVAL (operands[2]));
5627 return "sub{l}\t{%2, %k0|%k0, %2}";
5629 return "add{l}\t{%2, %k0|%k0, %2}";
5633 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5634 (const_string "incdec")
5635 (const_string "alu")))
5636 (set_attr "mode" "SI")])
5638 (define_insn "*addsi_3"
5639 [(set (reg FLAGS_REG)
5640 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5641 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5642 (clobber (match_scratch:SI 0 "=r"))]
5643 "ix86_match_ccmode (insn, CCZmode)
5644 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5645 /* Current assemblers are broken and do not allow @GOTOFF in
5646 ought but a memory context. */
5647 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5649 switch (get_attr_type (insn))
5652 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5653 if (operands[2] == const1_rtx)
5654 return "inc{l}\t%0";
5657 gcc_assert (operands[2] == constm1_rtx);
5658 return "dec{l}\t%0";
5662 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5663 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5664 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5665 if (CONST_INT_P (operands[2])
5666 && (INTVAL (operands[2]) == 128
5667 || (INTVAL (operands[2]) < 0
5668 && INTVAL (operands[2]) != -128)))
5670 operands[2] = GEN_INT (-INTVAL (operands[2]));
5671 return "sub{l}\t{%2, %0|%0, %2}";
5673 return "add{l}\t{%2, %0|%0, %2}";
5677 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5678 (const_string "incdec")
5679 (const_string "alu")))
5680 (set_attr "mode" "SI")])
5682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5683 (define_insn "*addsi_3_zext"
5684 [(set (reg FLAGS_REG)
5685 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5686 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5687 (set (match_operand:DI 0 "register_operand" "=r")
5688 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5689 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5690 && ix86_binary_operator_ok (PLUS, SImode, operands)
5691 /* Current assemblers are broken and do not allow @GOTOFF in
5692 ought but a memory context. */
5693 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5695 switch (get_attr_type (insn))
5698 if (operands[2] == const1_rtx)
5699 return "inc{l}\t%k0";
5702 gcc_assert (operands[2] == constm1_rtx);
5703 return "dec{l}\t%k0";
5707 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5708 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5709 if (CONST_INT_P (operands[2])
5710 && (INTVAL (operands[2]) == 128
5711 || (INTVAL (operands[2]) < 0
5712 && INTVAL (operands[2]) != -128)))
5714 operands[2] = GEN_INT (-INTVAL (operands[2]));
5715 return "sub{l}\t{%2, %k0|%k0, %2}";
5717 return "add{l}\t{%2, %k0|%k0, %2}";
5721 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5722 (const_string "incdec")
5723 (const_string "alu")))
5724 (set_attr "mode" "SI")])
5726 ; For comparisons against 1, -1 and 128, we may generate better code
5727 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5728 ; is matched then. We can't accept general immediate, because for
5729 ; case of overflows, the result is messed up.
5730 ; This pattern also don't hold of 0x80000000, since the value overflows
5732 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5733 ; only for comparisons not depending on it.
5734 (define_insn "*addsi_4"
5735 [(set (reg FLAGS_REG)
5736 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5737 (match_operand:SI 2 "const_int_operand" "n")))
5738 (clobber (match_scratch:SI 0 "=rm"))]
5739 "ix86_match_ccmode (insn, CCGCmode)
5740 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5742 switch (get_attr_type (insn))
5745 if (operands[2] == constm1_rtx)
5746 return "inc{l}\t%0";
5749 gcc_assert (operands[2] == const1_rtx);
5750 return "dec{l}\t%0";
5754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5756 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5757 if ((INTVAL (operands[2]) == -128
5758 || (INTVAL (operands[2]) > 0
5759 && INTVAL (operands[2]) != 128)))
5760 return "sub{l}\t{%2, %0|%0, %2}";
5761 operands[2] = GEN_INT (-INTVAL (operands[2]));
5762 return "add{l}\t{%2, %0|%0, %2}";
5766 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5767 (const_string "incdec")
5768 (const_string "alu")))
5769 (set_attr "mode" "SI")])
5771 (define_insn "*addsi_5"
5772 [(set (reg FLAGS_REG)
5774 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5775 (match_operand:SI 2 "general_operand" "rmni"))
5777 (clobber (match_scratch:SI 0 "=r"))]
5778 "ix86_match_ccmode (insn, CCGOCmode)
5779 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5780 /* Current assemblers are broken and do not allow @GOTOFF in
5781 ought but a memory context. */
5782 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5784 switch (get_attr_type (insn))
5787 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5788 if (operands[2] == const1_rtx)
5789 return "inc{l}\t%0";
5792 gcc_assert (operands[2] == constm1_rtx);
5793 return "dec{l}\t%0";
5797 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5798 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5800 if (CONST_INT_P (operands[2])
5801 && (INTVAL (operands[2]) == 128
5802 || (INTVAL (operands[2]) < 0
5803 && INTVAL (operands[2]) != -128)))
5805 operands[2] = GEN_INT (-INTVAL (operands[2]));
5806 return "sub{l}\t{%2, %0|%0, %2}";
5808 return "add{l}\t{%2, %0|%0, %2}";
5812 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5813 (const_string "incdec")
5814 (const_string "alu")))
5815 (set_attr "mode" "SI")])
5817 (define_expand "addhi3"
5818 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5819 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5820 (match_operand:HI 2 "general_operand" "")))
5821 (clobber (reg:CC FLAGS_REG))])]
5822 "TARGET_HIMODE_MATH"
5823 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5825 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5826 ;; type optimizations enabled by define-splits. This is not important
5827 ;; for PII, and in fact harmful because of partial register stalls.
5829 (define_insn "*addhi_1_lea"
5830 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5831 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5832 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5833 (clobber (reg:CC FLAGS_REG))]
5834 "!TARGET_PARTIAL_REG_STALL
5835 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5837 switch (get_attr_type (insn))
5842 if (operands[2] == const1_rtx)
5843 return "inc{w}\t%0";
5846 gcc_assert (operands[2] == constm1_rtx);
5847 return "dec{w}\t%0";
5851 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5852 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5853 if (CONST_INT_P (operands[2])
5854 && (INTVAL (operands[2]) == 128
5855 || (INTVAL (operands[2]) < 0
5856 && INTVAL (operands[2]) != -128)))
5858 operands[2] = GEN_INT (-INTVAL (operands[2]));
5859 return "sub{w}\t{%2, %0|%0, %2}";
5861 return "add{w}\t{%2, %0|%0, %2}";
5865 (if_then_else (eq_attr "alternative" "2")
5866 (const_string "lea")
5867 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5868 (const_string "incdec")
5869 (const_string "alu"))))
5870 (set_attr "mode" "HI,HI,SI")])
5872 (define_insn "*addhi_1"
5873 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5874 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5875 (match_operand:HI 2 "general_operand" "ri,rm")))
5876 (clobber (reg:CC FLAGS_REG))]
5877 "TARGET_PARTIAL_REG_STALL
5878 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5880 switch (get_attr_type (insn))
5883 if (operands[2] == const1_rtx)
5884 return "inc{w}\t%0";
5887 gcc_assert (operands[2] == constm1_rtx);
5888 return "dec{w}\t%0";
5892 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5893 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5894 if (CONST_INT_P (operands[2])
5895 && (INTVAL (operands[2]) == 128
5896 || (INTVAL (operands[2]) < 0
5897 && INTVAL (operands[2]) != -128)))
5899 operands[2] = GEN_INT (-INTVAL (operands[2]));
5900 return "sub{w}\t{%2, %0|%0, %2}";
5902 return "add{w}\t{%2, %0|%0, %2}";
5906 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5907 (const_string "incdec")
5908 (const_string "alu")))
5909 (set_attr "mode" "HI")])
5911 (define_insn "*addhi_2"
5912 [(set (reg FLAGS_REG)
5914 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5915 (match_operand:HI 2 "general_operand" "rmni,rni"))
5917 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5918 (plus:HI (match_dup 1) (match_dup 2)))]
5919 "ix86_match_ccmode (insn, CCGOCmode)
5920 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5922 switch (get_attr_type (insn))
5925 if (operands[2] == const1_rtx)
5926 return "inc{w}\t%0";
5929 gcc_assert (operands[2] == constm1_rtx);
5930 return "dec{w}\t%0";
5934 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5935 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5936 if (CONST_INT_P (operands[2])
5937 && (INTVAL (operands[2]) == 128
5938 || (INTVAL (operands[2]) < 0
5939 && INTVAL (operands[2]) != -128)))
5941 operands[2] = GEN_INT (-INTVAL (operands[2]));
5942 return "sub{w}\t{%2, %0|%0, %2}";
5944 return "add{w}\t{%2, %0|%0, %2}";
5948 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5949 (const_string "incdec")
5950 (const_string "alu")))
5951 (set_attr "mode" "HI")])
5953 (define_insn "*addhi_3"
5954 [(set (reg FLAGS_REG)
5955 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5956 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5957 (clobber (match_scratch:HI 0 "=r"))]
5958 "ix86_match_ccmode (insn, CCZmode)
5959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5961 switch (get_attr_type (insn))
5964 if (operands[2] == const1_rtx)
5965 return "inc{w}\t%0";
5968 gcc_assert (operands[2] == constm1_rtx);
5969 return "dec{w}\t%0";
5973 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5974 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5975 if (CONST_INT_P (operands[2])
5976 && (INTVAL (operands[2]) == 128
5977 || (INTVAL (operands[2]) < 0
5978 && INTVAL (operands[2]) != -128)))
5980 operands[2] = GEN_INT (-INTVAL (operands[2]));
5981 return "sub{w}\t{%2, %0|%0, %2}";
5983 return "add{w}\t{%2, %0|%0, %2}";
5987 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5988 (const_string "incdec")
5989 (const_string "alu")))
5990 (set_attr "mode" "HI")])
5992 ; See comments above addsi_4 for details.
5993 (define_insn "*addhi_4"
5994 [(set (reg FLAGS_REG)
5995 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5996 (match_operand:HI 2 "const_int_operand" "n")))
5997 (clobber (match_scratch:HI 0 "=rm"))]
5998 "ix86_match_ccmode (insn, CCGCmode)
5999 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6001 switch (get_attr_type (insn))
6004 if (operands[2] == constm1_rtx)
6005 return "inc{w}\t%0";
6008 gcc_assert (operands[2] == const1_rtx);
6009 return "dec{w}\t%0";
6013 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6014 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6015 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6016 if ((INTVAL (operands[2]) == -128
6017 || (INTVAL (operands[2]) > 0
6018 && INTVAL (operands[2]) != 128)))
6019 return "sub{w}\t{%2, %0|%0, %2}";
6020 operands[2] = GEN_INT (-INTVAL (operands[2]));
6021 return "add{w}\t{%2, %0|%0, %2}";
6025 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6026 (const_string "incdec")
6027 (const_string "alu")))
6028 (set_attr "mode" "SI")])
6031 (define_insn "*addhi_5"
6032 [(set (reg FLAGS_REG)
6034 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6035 (match_operand:HI 2 "general_operand" "rmni"))
6037 (clobber (match_scratch:HI 0 "=r"))]
6038 "ix86_match_ccmode (insn, CCGOCmode)
6039 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6041 switch (get_attr_type (insn))
6044 if (operands[2] == const1_rtx)
6045 return "inc{w}\t%0";
6048 gcc_assert (operands[2] == constm1_rtx);
6049 return "dec{w}\t%0";
6053 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6055 if (CONST_INT_P (operands[2])
6056 && (INTVAL (operands[2]) == 128
6057 || (INTVAL (operands[2]) < 0
6058 && INTVAL (operands[2]) != -128)))
6060 operands[2] = GEN_INT (-INTVAL (operands[2]));
6061 return "sub{w}\t{%2, %0|%0, %2}";
6063 return "add{w}\t{%2, %0|%0, %2}";
6067 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6068 (const_string "incdec")
6069 (const_string "alu")))
6070 (set_attr "mode" "HI")])
6072 (define_expand "addqi3"
6073 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6074 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6075 (match_operand:QI 2 "general_operand" "")))
6076 (clobber (reg:CC FLAGS_REG))])]
6077 "TARGET_QIMODE_MATH"
6078 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6080 ;; %%% Potential partial reg stall on alternative 2. What to do?
6081 (define_insn "*addqi_1_lea"
6082 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6083 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6084 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6085 (clobber (reg:CC FLAGS_REG))]
6086 "!TARGET_PARTIAL_REG_STALL
6087 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6089 int widen = (which_alternative == 2);
6090 switch (get_attr_type (insn))
6095 if (operands[2] == const1_rtx)
6096 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6099 gcc_assert (operands[2] == constm1_rtx);
6100 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6104 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6106 if (CONST_INT_P (operands[2])
6107 && (INTVAL (operands[2]) == 128
6108 || (INTVAL (operands[2]) < 0
6109 && INTVAL (operands[2]) != -128)))
6111 operands[2] = GEN_INT (-INTVAL (operands[2]));
6113 return "sub{l}\t{%2, %k0|%k0, %2}";
6115 return "sub{b}\t{%2, %0|%0, %2}";
6118 return "add{l}\t{%k2, %k0|%k0, %k2}";
6120 return "add{b}\t{%2, %0|%0, %2}";
6124 (if_then_else (eq_attr "alternative" "3")
6125 (const_string "lea")
6126 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6127 (const_string "incdec")
6128 (const_string "alu"))))
6129 (set_attr "mode" "QI,QI,SI,SI")])
6131 (define_insn "*addqi_1"
6132 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6133 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6134 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6135 (clobber (reg:CC FLAGS_REG))]
6136 "TARGET_PARTIAL_REG_STALL
6137 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6139 int widen = (which_alternative == 2);
6140 switch (get_attr_type (insn))
6143 if (operands[2] == const1_rtx)
6144 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6147 gcc_assert (operands[2] == constm1_rtx);
6148 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6152 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6153 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6154 if (CONST_INT_P (operands[2])
6155 && (INTVAL (operands[2]) == 128
6156 || (INTVAL (operands[2]) < 0
6157 && INTVAL (operands[2]) != -128)))
6159 operands[2] = GEN_INT (-INTVAL (operands[2]));
6161 return "sub{l}\t{%2, %k0|%k0, %2}";
6163 return "sub{b}\t{%2, %0|%0, %2}";
6166 return "add{l}\t{%k2, %k0|%k0, %k2}";
6168 return "add{b}\t{%2, %0|%0, %2}";
6172 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6173 (const_string "incdec")
6174 (const_string "alu")))
6175 (set_attr "mode" "QI,QI,SI")])
6177 (define_insn "*addqi_1_slp"
6178 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6179 (plus:QI (match_dup 0)
6180 (match_operand:QI 1 "general_operand" "qn,qnm")))
6181 (clobber (reg:CC FLAGS_REG))]
6182 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6183 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6185 switch (get_attr_type (insn))
6188 if (operands[1] == const1_rtx)
6189 return "inc{b}\t%0";
6192 gcc_assert (operands[1] == constm1_rtx);
6193 return "dec{b}\t%0";
6197 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6198 if (CONST_INT_P (operands[1])
6199 && INTVAL (operands[1]) < 0)
6201 operands[1] = GEN_INT (-INTVAL (operands[1]));
6202 return "sub{b}\t{%1, %0|%0, %1}";
6204 return "add{b}\t{%1, %0|%0, %1}";
6208 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6209 (const_string "incdec")
6210 (const_string "alu1")))
6211 (set (attr "memory")
6212 (if_then_else (match_operand 1 "memory_operand" "")
6213 (const_string "load")
6214 (const_string "none")))
6215 (set_attr "mode" "QI")])
6217 (define_insn "*addqi_2"
6218 [(set (reg FLAGS_REG)
6220 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6221 (match_operand:QI 2 "general_operand" "qmni,qni"))
6223 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6224 (plus:QI (match_dup 1) (match_dup 2)))]
6225 "ix86_match_ccmode (insn, CCGOCmode)
6226 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6228 switch (get_attr_type (insn))
6231 if (operands[2] == const1_rtx)
6232 return "inc{b}\t%0";
6235 gcc_assert (operands[2] == constm1_rtx
6236 || (CONST_INT_P (operands[2])
6237 && INTVAL (operands[2]) == 255));
6238 return "dec{b}\t%0";
6242 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6243 if (CONST_INT_P (operands[2])
6244 && INTVAL (operands[2]) < 0)
6246 operands[2] = GEN_INT (-INTVAL (operands[2]));
6247 return "sub{b}\t{%2, %0|%0, %2}";
6249 return "add{b}\t{%2, %0|%0, %2}";
6253 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6254 (const_string "incdec")
6255 (const_string "alu")))
6256 (set_attr "mode" "QI")])
6258 (define_insn "*addqi_3"
6259 [(set (reg FLAGS_REG)
6260 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6261 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6262 (clobber (match_scratch:QI 0 "=q"))]
6263 "ix86_match_ccmode (insn, CCZmode)
6264 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6266 switch (get_attr_type (insn))
6269 if (operands[2] == const1_rtx)
6270 return "inc{b}\t%0";
6273 gcc_assert (operands[2] == constm1_rtx
6274 || (CONST_INT_P (operands[2])
6275 && INTVAL (operands[2]) == 255));
6276 return "dec{b}\t%0";
6280 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6281 if (CONST_INT_P (operands[2])
6282 && INTVAL (operands[2]) < 0)
6284 operands[2] = GEN_INT (-INTVAL (operands[2]));
6285 return "sub{b}\t{%2, %0|%0, %2}";
6287 return "add{b}\t{%2, %0|%0, %2}";
6291 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6292 (const_string "incdec")
6293 (const_string "alu")))
6294 (set_attr "mode" "QI")])
6296 ; See comments above addsi_4 for details.
6297 (define_insn "*addqi_4"
6298 [(set (reg FLAGS_REG)
6299 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6300 (match_operand:QI 2 "const_int_operand" "n")))
6301 (clobber (match_scratch:QI 0 "=qm"))]
6302 "ix86_match_ccmode (insn, CCGCmode)
6303 && (INTVAL (operands[2]) & 0xff) != 0x80"
6305 switch (get_attr_type (insn))
6308 if (operands[2] == constm1_rtx
6309 || (CONST_INT_P (operands[2])
6310 && INTVAL (operands[2]) == 255))
6311 return "inc{b}\t%0";
6314 gcc_assert (operands[2] == const1_rtx);
6315 return "dec{b}\t%0";
6319 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6320 if (INTVAL (operands[2]) < 0)
6322 operands[2] = GEN_INT (-INTVAL (operands[2]));
6323 return "add{b}\t{%2, %0|%0, %2}";
6325 return "sub{b}\t{%2, %0|%0, %2}";
6329 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6330 (const_string "incdec")
6331 (const_string "alu")))
6332 (set_attr "mode" "QI")])
6335 (define_insn "*addqi_5"
6336 [(set (reg FLAGS_REG)
6338 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6339 (match_operand:QI 2 "general_operand" "qmni"))
6341 (clobber (match_scratch:QI 0 "=q"))]
6342 "ix86_match_ccmode (insn, CCGOCmode)
6343 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6345 switch (get_attr_type (insn))
6348 if (operands[2] == const1_rtx)
6349 return "inc{b}\t%0";
6352 gcc_assert (operands[2] == constm1_rtx
6353 || (CONST_INT_P (operands[2])
6354 && INTVAL (operands[2]) == 255));
6355 return "dec{b}\t%0";
6359 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6360 if (CONST_INT_P (operands[2])
6361 && INTVAL (operands[2]) < 0)
6363 operands[2] = GEN_INT (-INTVAL (operands[2]));
6364 return "sub{b}\t{%2, %0|%0, %2}";
6366 return "add{b}\t{%2, %0|%0, %2}";
6370 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6371 (const_string "incdec")
6372 (const_string "alu")))
6373 (set_attr "mode" "QI")])
6376 (define_insn "addqi_ext_1"
6377 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6382 (match_operand 1 "ext_register_operand" "0")
6385 (match_operand:QI 2 "general_operand" "Qmn")))
6386 (clobber (reg:CC FLAGS_REG))]
6389 switch (get_attr_type (insn))
6392 if (operands[2] == const1_rtx)
6393 return "inc{b}\t%h0";
6396 gcc_assert (operands[2] == constm1_rtx
6397 || (CONST_INT_P (operands[2])
6398 && INTVAL (operands[2]) == 255));
6399 return "dec{b}\t%h0";
6403 return "add{b}\t{%2, %h0|%h0, %2}";
6407 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6408 (const_string "incdec")
6409 (const_string "alu")))
6410 (set_attr "mode" "QI")])
6412 (define_insn "*addqi_ext_1_rex64"
6413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6418 (match_operand 1 "ext_register_operand" "0")
6421 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6422 (clobber (reg:CC FLAGS_REG))]
6425 switch (get_attr_type (insn))
6428 if (operands[2] == const1_rtx)
6429 return "inc{b}\t%h0";
6432 gcc_assert (operands[2] == constm1_rtx
6433 || (CONST_INT_P (operands[2])
6434 && INTVAL (operands[2]) == 255));
6435 return "dec{b}\t%h0";
6439 return "add{b}\t{%2, %h0|%h0, %2}";
6443 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6444 (const_string "incdec")
6445 (const_string "alu")))
6446 (set_attr "mode" "QI")])
6448 (define_insn "*addqi_ext_2"
6449 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6454 (match_operand 1 "ext_register_operand" "%0")
6458 (match_operand 2 "ext_register_operand" "Q")
6461 (clobber (reg:CC FLAGS_REG))]
6463 "add{b}\t{%h2, %h0|%h0, %h2}"
6464 [(set_attr "type" "alu")
6465 (set_attr "mode" "QI")])
6467 ;; The patterns that match these are at the end of this file.
6469 (define_expand "addxf3"
6470 [(set (match_operand:XF 0 "register_operand" "")
6471 (plus:XF (match_operand:XF 1 "register_operand" "")
6472 (match_operand:XF 2 "register_operand" "")))]
6476 (define_expand "adddf3"
6477 [(set (match_operand:DF 0 "register_operand" "")
6478 (plus:DF (match_operand:DF 1 "register_operand" "")
6479 (match_operand:DF 2 "nonimmediate_operand" "")))]
6480 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6483 (define_expand "addsf3"
6484 [(set (match_operand:SF 0 "register_operand" "")
6485 (plus:SF (match_operand:SF 1 "register_operand" "")
6486 (match_operand:SF 2 "nonimmediate_operand" "")))]
6487 "TARGET_80387 || TARGET_SSE_MATH"
6490 ;; Subtract instructions
6492 ;; %%% splits for subditi3
6494 (define_expand "subti3"
6495 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6496 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6497 (match_operand:TI 2 "x86_64_general_operand" "")))
6498 (clobber (reg:CC FLAGS_REG))])]
6500 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6502 (define_insn "*subti3_1"
6503 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6504 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6505 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6506 (clobber (reg:CC FLAGS_REG))]
6507 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6511 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6512 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6513 (match_operand:TI 2 "x86_64_general_operand" "")))
6514 (clobber (reg:CC FLAGS_REG))]
6515 "TARGET_64BIT && reload_completed"
6516 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6517 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6518 (parallel [(set (match_dup 3)
6519 (minus:DI (match_dup 4)
6520 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6522 (clobber (reg:CC FLAGS_REG))])]
6523 "split_ti (operands+0, 1, operands+0, operands+3);
6524 split_ti (operands+1, 1, operands+1, operands+4);
6525 split_ti (operands+2, 1, operands+2, operands+5);")
6527 ;; %%% splits for subsidi3
6529 (define_expand "subdi3"
6530 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6531 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6532 (match_operand:DI 2 "x86_64_general_operand" "")))
6533 (clobber (reg:CC FLAGS_REG))])]
6535 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6537 (define_insn "*subdi3_1"
6538 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6539 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6540 (match_operand:DI 2 "general_operand" "roiF,riF")))
6541 (clobber (reg:CC FLAGS_REG))]
6542 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6546 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6547 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6548 (match_operand:DI 2 "general_operand" "")))
6549 (clobber (reg:CC FLAGS_REG))]
6550 "!TARGET_64BIT && reload_completed"
6551 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6552 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6553 (parallel [(set (match_dup 3)
6554 (minus:SI (match_dup 4)
6555 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6557 (clobber (reg:CC FLAGS_REG))])]
6558 "split_di (operands+0, 1, operands+0, operands+3);
6559 split_di (operands+1, 1, operands+1, operands+4);
6560 split_di (operands+2, 1, operands+2, operands+5);")
6562 (define_insn "subdi3_carry_rex64"
6563 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6564 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6565 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6566 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6569 "sbb{q}\t{%2, %0|%0, %2}"
6570 [(set_attr "type" "alu")
6571 (set_attr "pent_pair" "pu")
6572 (set_attr "mode" "DI")])
6574 (define_insn "*subdi_1_rex64"
6575 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6576 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6577 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6578 (clobber (reg:CC FLAGS_REG))]
6579 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6580 "sub{q}\t{%2, %0|%0, %2}"
6581 [(set_attr "type" "alu")
6582 (set_attr "mode" "DI")])
6584 (define_insn "*subdi_2_rex64"
6585 [(set (reg FLAGS_REG)
6587 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6588 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6590 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6591 (minus:DI (match_dup 1) (match_dup 2)))]
6592 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6593 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6594 "sub{q}\t{%2, %0|%0, %2}"
6595 [(set_attr "type" "alu")
6596 (set_attr "mode" "DI")])
6598 (define_insn "*subdi_3_rex63"
6599 [(set (reg FLAGS_REG)
6600 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6601 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6602 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6603 (minus:DI (match_dup 1) (match_dup 2)))]
6604 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6605 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6606 "sub{q}\t{%2, %0|%0, %2}"
6607 [(set_attr "type" "alu")
6608 (set_attr "mode" "DI")])
6610 (define_insn "subqi3_carry"
6611 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6612 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6613 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6614 (match_operand:QI 2 "general_operand" "qi,qm"))))
6615 (clobber (reg:CC FLAGS_REG))]
6616 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6617 "sbb{b}\t{%2, %0|%0, %2}"
6618 [(set_attr "type" "alu")
6619 (set_attr "pent_pair" "pu")
6620 (set_attr "mode" "QI")])
6622 (define_insn "subhi3_carry"
6623 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6624 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6625 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6626 (match_operand:HI 2 "general_operand" "ri,rm"))))
6627 (clobber (reg:CC FLAGS_REG))]
6628 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6629 "sbb{w}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "pent_pair" "pu")
6632 (set_attr "mode" "HI")])
6634 (define_insn "subsi3_carry"
6635 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6636 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6637 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6638 (match_operand:SI 2 "general_operand" "ri,rm"))))
6639 (clobber (reg:CC FLAGS_REG))]
6640 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6641 "sbb{l}\t{%2, %0|%0, %2}"
6642 [(set_attr "type" "alu")
6643 (set_attr "pent_pair" "pu")
6644 (set_attr "mode" "SI")])
6646 (define_insn "subsi3_carry_zext"
6647 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6649 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6650 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6651 (match_operand:SI 2 "general_operand" "ri,rm")))))
6652 (clobber (reg:CC FLAGS_REG))]
6653 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6654 "sbb{l}\t{%2, %k0|%k0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "pent_pair" "pu")
6657 (set_attr "mode" "SI")])
6659 (define_expand "subsi3"
6660 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6661 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6662 (match_operand:SI 2 "general_operand" "")))
6663 (clobber (reg:CC FLAGS_REG))])]
6665 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6667 (define_insn "*subsi_1"
6668 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6669 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6670 (match_operand:SI 2 "general_operand" "ri,rm")))
6671 (clobber (reg:CC FLAGS_REG))]
6672 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6673 "sub{l}\t{%2, %0|%0, %2}"
6674 [(set_attr "type" "alu")
6675 (set_attr "mode" "SI")])
6677 (define_insn "*subsi_1_zext"
6678 [(set (match_operand:DI 0 "register_operand" "=r")
6680 (minus:SI (match_operand:SI 1 "register_operand" "0")
6681 (match_operand:SI 2 "general_operand" "rim"))))
6682 (clobber (reg:CC FLAGS_REG))]
6683 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6684 "sub{l}\t{%2, %k0|%k0, %2}"
6685 [(set_attr "type" "alu")
6686 (set_attr "mode" "SI")])
6688 (define_insn "*subsi_2"
6689 [(set (reg FLAGS_REG)
6691 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6692 (match_operand:SI 2 "general_operand" "ri,rm"))
6694 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6695 (minus:SI (match_dup 1) (match_dup 2)))]
6696 "ix86_match_ccmode (insn, CCGOCmode)
6697 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6698 "sub{l}\t{%2, %0|%0, %2}"
6699 [(set_attr "type" "alu")
6700 (set_attr "mode" "SI")])
6702 (define_insn "*subsi_2_zext"
6703 [(set (reg FLAGS_REG)
6705 (minus:SI (match_operand:SI 1 "register_operand" "0")
6706 (match_operand:SI 2 "general_operand" "rim"))
6708 (set (match_operand:DI 0 "register_operand" "=r")
6710 (minus:SI (match_dup 1)
6712 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6713 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6714 "sub{l}\t{%2, %k0|%k0, %2}"
6715 [(set_attr "type" "alu")
6716 (set_attr "mode" "SI")])
6718 (define_insn "*subsi_3"
6719 [(set (reg FLAGS_REG)
6720 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6721 (match_operand:SI 2 "general_operand" "ri,rm")))
6722 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6723 (minus:SI (match_dup 1) (match_dup 2)))]
6724 "ix86_match_ccmode (insn, CCmode)
6725 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6726 "sub{l}\t{%2, %0|%0, %2}"
6727 [(set_attr "type" "alu")
6728 (set_attr "mode" "SI")])
6730 (define_insn "*subsi_3_zext"
6731 [(set (reg FLAGS_REG)
6732 (compare (match_operand:SI 1 "register_operand" "0")
6733 (match_operand:SI 2 "general_operand" "rim")))
6734 (set (match_operand:DI 0 "register_operand" "=r")
6736 (minus:SI (match_dup 1)
6738 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6739 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6740 "sub{l}\t{%2, %1|%1, %2}"
6741 [(set_attr "type" "alu")
6742 (set_attr "mode" "DI")])
6744 (define_expand "subhi3"
6745 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6746 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6747 (match_operand:HI 2 "general_operand" "")))
6748 (clobber (reg:CC FLAGS_REG))])]
6749 "TARGET_HIMODE_MATH"
6750 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6752 (define_insn "*subhi_1"
6753 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6754 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6755 (match_operand:HI 2 "general_operand" "ri,rm")))
6756 (clobber (reg:CC FLAGS_REG))]
6757 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6758 "sub{w}\t{%2, %0|%0, %2}"
6759 [(set_attr "type" "alu")
6760 (set_attr "mode" "HI")])
6762 (define_insn "*subhi_2"
6763 [(set (reg FLAGS_REG)
6765 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6766 (match_operand:HI 2 "general_operand" "ri,rm"))
6768 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6769 (minus:HI (match_dup 1) (match_dup 2)))]
6770 "ix86_match_ccmode (insn, CCGOCmode)
6771 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6772 "sub{w}\t{%2, %0|%0, %2}"
6773 [(set_attr "type" "alu")
6774 (set_attr "mode" "HI")])
6776 (define_insn "*subhi_3"
6777 [(set (reg FLAGS_REG)
6778 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6779 (match_operand:HI 2 "general_operand" "ri,rm")))
6780 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6781 (minus:HI (match_dup 1) (match_dup 2)))]
6782 "ix86_match_ccmode (insn, CCmode)
6783 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6784 "sub{w}\t{%2, %0|%0, %2}"
6785 [(set_attr "type" "alu")
6786 (set_attr "mode" "HI")])
6788 (define_expand "subqi3"
6789 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6790 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6791 (match_operand:QI 2 "general_operand" "")))
6792 (clobber (reg:CC FLAGS_REG))])]
6793 "TARGET_QIMODE_MATH"
6794 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6796 (define_insn "*subqi_1"
6797 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6798 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6799 (match_operand:QI 2 "general_operand" "qn,qmn")))
6800 (clobber (reg:CC FLAGS_REG))]
6801 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6802 "sub{b}\t{%2, %0|%0, %2}"
6803 [(set_attr "type" "alu")
6804 (set_attr "mode" "QI")])
6806 (define_insn "*subqi_1_slp"
6807 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6808 (minus:QI (match_dup 0)
6809 (match_operand:QI 1 "general_operand" "qn,qmn")))
6810 (clobber (reg:CC FLAGS_REG))]
6811 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6812 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6813 "sub{b}\t{%1, %0|%0, %1}"
6814 [(set_attr "type" "alu1")
6815 (set_attr "mode" "QI")])
6817 (define_insn "*subqi_2"
6818 [(set (reg FLAGS_REG)
6820 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6821 (match_operand:QI 2 "general_operand" "qi,qm"))
6823 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6824 (minus:HI (match_dup 1) (match_dup 2)))]
6825 "ix86_match_ccmode (insn, CCGOCmode)
6826 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6827 "sub{b}\t{%2, %0|%0, %2}"
6828 [(set_attr "type" "alu")
6829 (set_attr "mode" "QI")])
6831 (define_insn "*subqi_3"
6832 [(set (reg FLAGS_REG)
6833 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6834 (match_operand:QI 2 "general_operand" "qi,qm")))
6835 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6836 (minus:HI (match_dup 1) (match_dup 2)))]
6837 "ix86_match_ccmode (insn, CCmode)
6838 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6839 "sub{b}\t{%2, %0|%0, %2}"
6840 [(set_attr "type" "alu")
6841 (set_attr "mode" "QI")])
6843 ;; The patterns that match these are at the end of this file.
6845 (define_expand "subxf3"
6846 [(set (match_operand:XF 0 "register_operand" "")
6847 (minus:XF (match_operand:XF 1 "register_operand" "")
6848 (match_operand:XF 2 "register_operand" "")))]
6852 (define_expand "subdf3"
6853 [(set (match_operand:DF 0 "register_operand" "")
6854 (minus:DF (match_operand:DF 1 "register_operand" "")
6855 (match_operand:DF 2 "nonimmediate_operand" "")))]
6856 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6859 (define_expand "subsf3"
6860 [(set (match_operand:SF 0 "register_operand" "")
6861 (minus:SF (match_operand:SF 1 "register_operand" "")
6862 (match_operand:SF 2 "nonimmediate_operand" "")))]
6863 "TARGET_80387 || TARGET_SSE_MATH"
6866 ;; Multiply instructions
6868 (define_expand "muldi3"
6869 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6870 (mult:DI (match_operand:DI 1 "register_operand" "")
6871 (match_operand:DI 2 "x86_64_general_operand" "")))
6872 (clobber (reg:CC FLAGS_REG))])]
6877 ;; IMUL reg64, reg64, imm8 Direct
6878 ;; IMUL reg64, mem64, imm8 VectorPath
6879 ;; IMUL reg64, reg64, imm32 Direct
6880 ;; IMUL reg64, mem64, imm32 VectorPath
6881 ;; IMUL reg64, reg64 Direct
6882 ;; IMUL reg64, mem64 Direct
6884 (define_insn "*muldi3_1_rex64"
6885 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6886 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6887 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6888 (clobber (reg:CC FLAGS_REG))]
6890 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6892 imul{q}\t{%2, %1, %0|%0, %1, %2}
6893 imul{q}\t{%2, %1, %0|%0, %1, %2}
6894 imul{q}\t{%2, %0|%0, %2}"
6895 [(set_attr "type" "imul")
6896 (set_attr "prefix_0f" "0,0,1")
6897 (set (attr "athlon_decode")
6898 (cond [(eq_attr "cpu" "athlon")
6899 (const_string "vector")
6900 (eq_attr "alternative" "1")
6901 (const_string "vector")
6902 (and (eq_attr "alternative" "2")
6903 (match_operand 1 "memory_operand" ""))
6904 (const_string "vector")]
6905 (const_string "direct")))
6906 (set (attr "amdfam10_decode")
6907 (cond [(and (eq_attr "alternative" "0,1")
6908 (match_operand 1 "memory_operand" ""))
6909 (const_string "vector")]
6910 (const_string "direct")))
6911 (set_attr "mode" "DI")])
6913 (define_expand "mulsi3"
6914 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6915 (mult:SI (match_operand:SI 1 "register_operand" "")
6916 (match_operand:SI 2 "general_operand" "")))
6917 (clobber (reg:CC FLAGS_REG))])]
6922 ;; IMUL reg32, reg32, imm8 Direct
6923 ;; IMUL reg32, mem32, imm8 VectorPath
6924 ;; IMUL reg32, reg32, imm32 Direct
6925 ;; IMUL reg32, mem32, imm32 VectorPath
6926 ;; IMUL reg32, reg32 Direct
6927 ;; IMUL reg32, mem32 Direct
6929 (define_insn "*mulsi3_1"
6930 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6931 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6932 (match_operand:SI 2 "general_operand" "K,i,mr")))
6933 (clobber (reg:CC FLAGS_REG))]
6934 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6936 imul{l}\t{%2, %1, %0|%0, %1, %2}
6937 imul{l}\t{%2, %1, %0|%0, %1, %2}
6938 imul{l}\t{%2, %0|%0, %2}"
6939 [(set_attr "type" "imul")
6940 (set_attr "prefix_0f" "0,0,1")
6941 (set (attr "athlon_decode")
6942 (cond [(eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (eq_attr "alternative" "1")
6945 (const_string "vector")
6946 (and (eq_attr "alternative" "2")
6947 (match_operand 1 "memory_operand" ""))
6948 (const_string "vector")]
6949 (const_string "direct")))
6950 (set (attr "amdfam10_decode")
6951 (cond [(and (eq_attr "alternative" "0,1")
6952 (match_operand 1 "memory_operand" ""))
6953 (const_string "vector")]
6954 (const_string "direct")))
6955 (set_attr "mode" "SI")])
6957 (define_insn "*mulsi3_1_zext"
6958 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6960 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6961 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6962 (clobber (reg:CC FLAGS_REG))]
6964 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6966 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6967 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6968 imul{l}\t{%2, %k0|%k0, %2}"
6969 [(set_attr "type" "imul")
6970 (set_attr "prefix_0f" "0,0,1")
6971 (set (attr "athlon_decode")
6972 (cond [(eq_attr "cpu" "athlon")
6973 (const_string "vector")
6974 (eq_attr "alternative" "1")
6975 (const_string "vector")
6976 (and (eq_attr "alternative" "2")
6977 (match_operand 1 "memory_operand" ""))
6978 (const_string "vector")]
6979 (const_string "direct")))
6980 (set (attr "amdfam10_decode")
6981 (cond [(and (eq_attr "alternative" "0,1")
6982 (match_operand 1 "memory_operand" ""))
6983 (const_string "vector")]
6984 (const_string "direct")))
6985 (set_attr "mode" "SI")])
6987 (define_expand "mulhi3"
6988 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6989 (mult:HI (match_operand:HI 1 "register_operand" "")
6990 (match_operand:HI 2 "general_operand" "")))
6991 (clobber (reg:CC FLAGS_REG))])]
6992 "TARGET_HIMODE_MATH"
6996 ;; IMUL reg16, reg16, imm8 VectorPath
6997 ;; IMUL reg16, mem16, imm8 VectorPath
6998 ;; IMUL reg16, reg16, imm16 VectorPath
6999 ;; IMUL reg16, mem16, imm16 VectorPath
7000 ;; IMUL reg16, reg16 Direct
7001 ;; IMUL reg16, mem16 Direct
7002 (define_insn "*mulhi3_1"
7003 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7004 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7005 (match_operand:HI 2 "general_operand" "K,i,mr")))
7006 (clobber (reg:CC FLAGS_REG))]
7007 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7009 imul{w}\t{%2, %1, %0|%0, %1, %2}
7010 imul{w}\t{%2, %1, %0|%0, %1, %2}
7011 imul{w}\t{%2, %0|%0, %2}"
7012 [(set_attr "type" "imul")
7013 (set_attr "prefix_0f" "0,0,1")
7014 (set (attr "athlon_decode")
7015 (cond [(eq_attr "cpu" "athlon")
7016 (const_string "vector")
7017 (eq_attr "alternative" "1,2")
7018 (const_string "vector")]
7019 (const_string "direct")))
7020 (set (attr "amdfam10_decode")
7021 (cond [(eq_attr "alternative" "0,1")
7022 (const_string "vector")]
7023 (const_string "direct")))
7024 (set_attr "mode" "HI")])
7026 (define_expand "mulqi3"
7027 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7028 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7029 (match_operand:QI 2 "register_operand" "")))
7030 (clobber (reg:CC FLAGS_REG))])]
7031 "TARGET_QIMODE_MATH"
7038 (define_insn "*mulqi3_1"
7039 [(set (match_operand:QI 0 "register_operand" "=a")
7040 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7041 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7042 (clobber (reg:CC FLAGS_REG))]
7044 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7046 [(set_attr "type" "imul")
7047 (set_attr "length_immediate" "0")
7048 (set (attr "athlon_decode")
7049 (if_then_else (eq_attr "cpu" "athlon")
7050 (const_string "vector")
7051 (const_string "direct")))
7052 (set_attr "amdfam10_decode" "direct")
7053 (set_attr "mode" "QI")])
7055 (define_expand "umulqihi3"
7056 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7057 (mult:HI (zero_extend:HI
7058 (match_operand:QI 1 "nonimmediate_operand" ""))
7060 (match_operand:QI 2 "register_operand" ""))))
7061 (clobber (reg:CC FLAGS_REG))])]
7062 "TARGET_QIMODE_MATH"
7065 (define_insn "*umulqihi3_1"
7066 [(set (match_operand:HI 0 "register_operand" "=a")
7067 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7068 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7069 (clobber (reg:CC FLAGS_REG))]
7071 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7073 [(set_attr "type" "imul")
7074 (set_attr "length_immediate" "0")
7075 (set (attr "athlon_decode")
7076 (if_then_else (eq_attr "cpu" "athlon")
7077 (const_string "vector")
7078 (const_string "direct")))
7079 (set_attr "amdfam10_decode" "direct")
7080 (set_attr "mode" "QI")])
7082 (define_expand "mulqihi3"
7083 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7084 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7085 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7086 (clobber (reg:CC FLAGS_REG))])]
7087 "TARGET_QIMODE_MATH"
7090 (define_insn "*mulqihi3_insn"
7091 [(set (match_operand:HI 0 "register_operand" "=a")
7092 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7093 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7094 (clobber (reg:CC FLAGS_REG))]
7096 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7098 [(set_attr "type" "imul")
7099 (set_attr "length_immediate" "0")
7100 (set (attr "athlon_decode")
7101 (if_then_else (eq_attr "cpu" "athlon")
7102 (const_string "vector")
7103 (const_string "direct")))
7104 (set_attr "amdfam10_decode" "direct")
7105 (set_attr "mode" "QI")])
7107 (define_expand "umulditi3"
7108 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7109 (mult:TI (zero_extend:TI
7110 (match_operand:DI 1 "nonimmediate_operand" ""))
7112 (match_operand:DI 2 "register_operand" ""))))
7113 (clobber (reg:CC FLAGS_REG))])]
7117 (define_insn "*umulditi3_insn"
7118 [(set (match_operand:TI 0 "register_operand" "=A")
7119 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7120 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7121 (clobber (reg:CC FLAGS_REG))]
7123 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7125 [(set_attr "type" "imul")
7126 (set_attr "length_immediate" "0")
7127 (set (attr "athlon_decode")
7128 (if_then_else (eq_attr "cpu" "athlon")
7129 (const_string "vector")
7130 (const_string "double")))
7131 (set_attr "amdfam10_decode" "double")
7132 (set_attr "mode" "DI")])
7134 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7135 (define_expand "umulsidi3"
7136 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7137 (mult:DI (zero_extend:DI
7138 (match_operand:SI 1 "nonimmediate_operand" ""))
7140 (match_operand:SI 2 "register_operand" ""))))
7141 (clobber (reg:CC FLAGS_REG))])]
7145 (define_insn "*umulsidi3_insn"
7146 [(set (match_operand:DI 0 "register_operand" "=A")
7147 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7148 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7149 (clobber (reg:CC FLAGS_REG))]
7151 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7153 [(set_attr "type" "imul")
7154 (set_attr "length_immediate" "0")
7155 (set (attr "athlon_decode")
7156 (if_then_else (eq_attr "cpu" "athlon")
7157 (const_string "vector")
7158 (const_string "double")))
7159 (set_attr "amdfam10_decode" "double")
7160 (set_attr "mode" "SI")])
7162 (define_expand "mulditi3"
7163 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7164 (mult:TI (sign_extend:TI
7165 (match_operand:DI 1 "nonimmediate_operand" ""))
7167 (match_operand:DI 2 "register_operand" ""))))
7168 (clobber (reg:CC FLAGS_REG))])]
7172 (define_insn "*mulditi3_insn"
7173 [(set (match_operand:TI 0 "register_operand" "=A")
7174 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7175 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7176 (clobber (reg:CC FLAGS_REG))]
7178 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7180 [(set_attr "type" "imul")
7181 (set_attr "length_immediate" "0")
7182 (set (attr "athlon_decode")
7183 (if_then_else (eq_attr "cpu" "athlon")
7184 (const_string "vector")
7185 (const_string "double")))
7186 (set_attr "amdfam10_decode" "double")
7187 (set_attr "mode" "DI")])
7189 (define_expand "mulsidi3"
7190 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7191 (mult:DI (sign_extend:DI
7192 (match_operand:SI 1 "nonimmediate_operand" ""))
7194 (match_operand:SI 2 "register_operand" ""))))
7195 (clobber (reg:CC FLAGS_REG))])]
7199 (define_insn "*mulsidi3_insn"
7200 [(set (match_operand:DI 0 "register_operand" "=A")
7201 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7202 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7203 (clobber (reg:CC FLAGS_REG))]
7205 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7207 [(set_attr "type" "imul")
7208 (set_attr "length_immediate" "0")
7209 (set (attr "athlon_decode")
7210 (if_then_else (eq_attr "cpu" "athlon")
7211 (const_string "vector")
7212 (const_string "double")))
7213 (set_attr "amdfam10_decode" "double")
7214 (set_attr "mode" "SI")])
7216 (define_expand "umuldi3_highpart"
7217 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7220 (mult:TI (zero_extend:TI
7221 (match_operand:DI 1 "nonimmediate_operand" ""))
7223 (match_operand:DI 2 "register_operand" "")))
7225 (clobber (match_scratch:DI 3 ""))
7226 (clobber (reg:CC FLAGS_REG))])]
7230 (define_insn "*umuldi3_highpart_rex64"
7231 [(set (match_operand:DI 0 "register_operand" "=d")
7234 (mult:TI (zero_extend:TI
7235 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7237 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7239 (clobber (match_scratch:DI 3 "=1"))
7240 (clobber (reg:CC FLAGS_REG))]
7242 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7244 [(set_attr "type" "imul")
7245 (set_attr "length_immediate" "0")
7246 (set (attr "athlon_decode")
7247 (if_then_else (eq_attr "cpu" "athlon")
7248 (const_string "vector")
7249 (const_string "double")))
7250 (set_attr "amdfam10_decode" "double")
7251 (set_attr "mode" "DI")])
7253 (define_expand "umulsi3_highpart"
7254 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7257 (mult:DI (zero_extend:DI
7258 (match_operand:SI 1 "nonimmediate_operand" ""))
7260 (match_operand:SI 2 "register_operand" "")))
7262 (clobber (match_scratch:SI 3 ""))
7263 (clobber (reg:CC FLAGS_REG))])]
7267 (define_insn "*umulsi3_highpart_insn"
7268 [(set (match_operand:SI 0 "register_operand" "=d")
7271 (mult:DI (zero_extend:DI
7272 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7274 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7276 (clobber (match_scratch:SI 3 "=1"))
7277 (clobber (reg:CC FLAGS_REG))]
7278 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7280 [(set_attr "type" "imul")
7281 (set_attr "length_immediate" "0")
7282 (set (attr "athlon_decode")
7283 (if_then_else (eq_attr "cpu" "athlon")
7284 (const_string "vector")
7285 (const_string "double")))
7286 (set_attr "amdfam10_decode" "double")
7287 (set_attr "mode" "SI")])
7289 (define_insn "*umulsi3_highpart_zext"
7290 [(set (match_operand:DI 0 "register_operand" "=d")
7291 (zero_extend:DI (truncate:SI
7293 (mult:DI (zero_extend:DI
7294 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7296 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7298 (clobber (match_scratch:SI 3 "=1"))
7299 (clobber (reg:CC FLAGS_REG))]
7301 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7303 [(set_attr "type" "imul")
7304 (set_attr "length_immediate" "0")
7305 (set (attr "athlon_decode")
7306 (if_then_else (eq_attr "cpu" "athlon")
7307 (const_string "vector")
7308 (const_string "double")))
7309 (set_attr "amdfam10_decode" "double")
7310 (set_attr "mode" "SI")])
7312 (define_expand "smuldi3_highpart"
7313 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7316 (mult:TI (sign_extend:TI
7317 (match_operand:DI 1 "nonimmediate_operand" ""))
7319 (match_operand:DI 2 "register_operand" "")))
7321 (clobber (match_scratch:DI 3 ""))
7322 (clobber (reg:CC FLAGS_REG))])]
7326 (define_insn "*smuldi3_highpart_rex64"
7327 [(set (match_operand:DI 0 "register_operand" "=d")
7330 (mult:TI (sign_extend:TI
7331 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7333 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7335 (clobber (match_scratch:DI 3 "=1"))
7336 (clobber (reg:CC FLAGS_REG))]
7338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7340 [(set_attr "type" "imul")
7341 (set (attr "athlon_decode")
7342 (if_then_else (eq_attr "cpu" "athlon")
7343 (const_string "vector")
7344 (const_string "double")))
7345 (set_attr "amdfam10_decode" "double")
7346 (set_attr "mode" "DI")])
7348 (define_expand "smulsi3_highpart"
7349 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7352 (mult:DI (sign_extend:DI
7353 (match_operand:SI 1 "nonimmediate_operand" ""))
7355 (match_operand:SI 2 "register_operand" "")))
7357 (clobber (match_scratch:SI 3 ""))
7358 (clobber (reg:CC FLAGS_REG))])]
7362 (define_insn "*smulsi3_highpart_insn"
7363 [(set (match_operand:SI 0 "register_operand" "=d")
7366 (mult:DI (sign_extend:DI
7367 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7369 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7371 (clobber (match_scratch:SI 3 "=1"))
7372 (clobber (reg:CC FLAGS_REG))]
7373 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7375 [(set_attr "type" "imul")
7376 (set (attr "athlon_decode")
7377 (if_then_else (eq_attr "cpu" "athlon")
7378 (const_string "vector")
7379 (const_string "double")))
7380 (set_attr "amdfam10_decode" "double")
7381 (set_attr "mode" "SI")])
7383 (define_insn "*smulsi3_highpart_zext"
7384 [(set (match_operand:DI 0 "register_operand" "=d")
7385 (zero_extend:DI (truncate:SI
7387 (mult:DI (sign_extend:DI
7388 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7390 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7392 (clobber (match_scratch:SI 3 "=1"))
7393 (clobber (reg:CC FLAGS_REG))]
7395 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7397 [(set_attr "type" "imul")
7398 (set (attr "athlon_decode")
7399 (if_then_else (eq_attr "cpu" "athlon")
7400 (const_string "vector")
7401 (const_string "double")))
7402 (set_attr "amdfam10_decode" "double")
7403 (set_attr "mode" "SI")])
7405 ;; The patterns that match these are at the end of this file.
7407 (define_expand "mulxf3"
7408 [(set (match_operand:XF 0 "register_operand" "")
7409 (mult:XF (match_operand:XF 1 "register_operand" "")
7410 (match_operand:XF 2 "register_operand" "")))]
7414 (define_expand "muldf3"
7415 [(set (match_operand:DF 0 "register_operand" "")
7416 (mult:DF (match_operand:DF 1 "register_operand" "")
7417 (match_operand:DF 2 "nonimmediate_operand" "")))]
7418 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7421 (define_expand "mulsf3"
7422 [(set (match_operand:SF 0 "register_operand" "")
7423 (mult:SF (match_operand:SF 1 "register_operand" "")
7424 (match_operand:SF 2 "nonimmediate_operand" "")))]
7425 "TARGET_80387 || TARGET_SSE_MATH"
7428 ;; Divide instructions
7430 (define_insn "divqi3"
7431 [(set (match_operand:QI 0 "register_operand" "=a")
7432 (div:QI (match_operand:HI 1 "register_operand" "0")
7433 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7434 (clobber (reg:CC FLAGS_REG))]
7435 "TARGET_QIMODE_MATH"
7437 [(set_attr "type" "idiv")
7438 (set_attr "mode" "QI")])
7440 (define_insn "udivqi3"
7441 [(set (match_operand:QI 0 "register_operand" "=a")
7442 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7443 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7444 (clobber (reg:CC FLAGS_REG))]
7445 "TARGET_QIMODE_MATH"
7447 [(set_attr "type" "idiv")
7448 (set_attr "mode" "QI")])
7450 ;; The patterns that match these are at the end of this file.
7452 (define_expand "divxf3"
7453 [(set (match_operand:XF 0 "register_operand" "")
7454 (div:XF (match_operand:XF 1 "register_operand" "")
7455 (match_operand:XF 2 "register_operand" "")))]
7459 (define_expand "divdf3"
7460 [(set (match_operand:DF 0 "register_operand" "")
7461 (div:DF (match_operand:DF 1 "register_operand" "")
7462 (match_operand:DF 2 "nonimmediate_operand" "")))]
7463 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7466 (define_expand "divsf3"
7467 [(set (match_operand:SF 0 "register_operand" "")
7468 (div:SF (match_operand:SF 1 "register_operand" "")
7469 (match_operand:SF 2 "nonimmediate_operand" "")))]
7470 "TARGET_80387 || TARGET_SSE_MATH"
7473 ;; Remainder instructions.
7475 (define_expand "divmoddi4"
7476 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7477 (div:DI (match_operand:DI 1 "register_operand" "")
7478 (match_operand:DI 2 "nonimmediate_operand" "")))
7479 (set (match_operand:DI 3 "register_operand" "")
7480 (mod:DI (match_dup 1) (match_dup 2)))
7481 (clobber (reg:CC FLAGS_REG))])]
7485 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7486 ;; Penalize eax case slightly because it results in worse scheduling
7488 (define_insn "*divmoddi4_nocltd_rex64"
7489 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7490 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7491 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7492 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7493 (mod:DI (match_dup 2) (match_dup 3)))
7494 (clobber (reg:CC FLAGS_REG))]
7495 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7497 [(set_attr "type" "multi")])
7499 (define_insn "*divmoddi4_cltd_rex64"
7500 [(set (match_operand:DI 0 "register_operand" "=a")
7501 (div:DI (match_operand:DI 2 "register_operand" "a")
7502 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7503 (set (match_operand:DI 1 "register_operand" "=&d")
7504 (mod:DI (match_dup 2) (match_dup 3)))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7508 [(set_attr "type" "multi")])
7510 (define_insn "*divmoddi_noext_rex64"
7511 [(set (match_operand:DI 0 "register_operand" "=a")
7512 (div:DI (match_operand:DI 1 "register_operand" "0")
7513 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7514 (set (match_operand:DI 3 "register_operand" "=d")
7515 (mod:DI (match_dup 1) (match_dup 2)))
7516 (use (match_operand:DI 4 "register_operand" "3"))
7517 (clobber (reg:CC FLAGS_REG))]
7520 [(set_attr "type" "idiv")
7521 (set_attr "mode" "DI")])
7524 [(set (match_operand:DI 0 "register_operand" "")
7525 (div:DI (match_operand:DI 1 "register_operand" "")
7526 (match_operand:DI 2 "nonimmediate_operand" "")))
7527 (set (match_operand:DI 3 "register_operand" "")
7528 (mod:DI (match_dup 1) (match_dup 2)))
7529 (clobber (reg:CC FLAGS_REG))]
7530 "TARGET_64BIT && reload_completed"
7531 [(parallel [(set (match_dup 3)
7532 (ashiftrt:DI (match_dup 4) (const_int 63)))
7533 (clobber (reg:CC FLAGS_REG))])
7534 (parallel [(set (match_dup 0)
7535 (div:DI (reg:DI 0) (match_dup 2)))
7537 (mod:DI (reg:DI 0) (match_dup 2)))
7539 (clobber (reg:CC FLAGS_REG))])]
7541 /* Avoid use of cltd in favor of a mov+shift. */
7542 if (!TARGET_USE_CLTD && !optimize_size)
7544 if (true_regnum (operands[1]))
7545 emit_move_insn (operands[0], operands[1]);
7547 emit_move_insn (operands[3], operands[1]);
7548 operands[4] = operands[3];
7552 gcc_assert (!true_regnum (operands[1]));
7553 operands[4] = operands[1];
7558 (define_expand "divmodsi4"
7559 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7560 (div:SI (match_operand:SI 1 "register_operand" "")
7561 (match_operand:SI 2 "nonimmediate_operand" "")))
7562 (set (match_operand:SI 3 "register_operand" "")
7563 (mod:SI (match_dup 1) (match_dup 2)))
7564 (clobber (reg:CC FLAGS_REG))])]
7568 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7569 ;; Penalize eax case slightly because it results in worse scheduling
7571 (define_insn "*divmodsi4_nocltd"
7572 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7573 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7574 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7575 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7576 (mod:SI (match_dup 2) (match_dup 3)))
7577 (clobber (reg:CC FLAGS_REG))]
7578 "!optimize_size && !TARGET_USE_CLTD"
7580 [(set_attr "type" "multi")])
7582 (define_insn "*divmodsi4_cltd"
7583 [(set (match_operand:SI 0 "register_operand" "=a")
7584 (div:SI (match_operand:SI 2 "register_operand" "a")
7585 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7586 (set (match_operand:SI 1 "register_operand" "=&d")
7587 (mod:SI (match_dup 2) (match_dup 3)))
7588 (clobber (reg:CC FLAGS_REG))]
7589 "optimize_size || TARGET_USE_CLTD"
7591 [(set_attr "type" "multi")])
7593 (define_insn "*divmodsi_noext"
7594 [(set (match_operand:SI 0 "register_operand" "=a")
7595 (div:SI (match_operand:SI 1 "register_operand" "0")
7596 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7597 (set (match_operand:SI 3 "register_operand" "=d")
7598 (mod:SI (match_dup 1) (match_dup 2)))
7599 (use (match_operand:SI 4 "register_operand" "3"))
7600 (clobber (reg:CC FLAGS_REG))]
7603 [(set_attr "type" "idiv")
7604 (set_attr "mode" "SI")])
7607 [(set (match_operand:SI 0 "register_operand" "")
7608 (div:SI (match_operand:SI 1 "register_operand" "")
7609 (match_operand:SI 2 "nonimmediate_operand" "")))
7610 (set (match_operand:SI 3 "register_operand" "")
7611 (mod:SI (match_dup 1) (match_dup 2)))
7612 (clobber (reg:CC FLAGS_REG))]
7614 [(parallel [(set (match_dup 3)
7615 (ashiftrt:SI (match_dup 4) (const_int 31)))
7616 (clobber (reg:CC FLAGS_REG))])
7617 (parallel [(set (match_dup 0)
7618 (div:SI (reg:SI 0) (match_dup 2)))
7620 (mod:SI (reg:SI 0) (match_dup 2)))
7622 (clobber (reg:CC FLAGS_REG))])]
7624 /* Avoid use of cltd in favor of a mov+shift. */
7625 if (!TARGET_USE_CLTD && !optimize_size)
7627 if (true_regnum (operands[1]))
7628 emit_move_insn (operands[0], operands[1]);
7630 emit_move_insn (operands[3], operands[1]);
7631 operands[4] = operands[3];
7635 gcc_assert (!true_regnum (operands[1]));
7636 operands[4] = operands[1];
7640 (define_insn "divmodhi4"
7641 [(set (match_operand:HI 0 "register_operand" "=a")
7642 (div:HI (match_operand:HI 1 "register_operand" "0")
7643 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7644 (set (match_operand:HI 3 "register_operand" "=&d")
7645 (mod:HI (match_dup 1) (match_dup 2)))
7646 (clobber (reg:CC FLAGS_REG))]
7647 "TARGET_HIMODE_MATH"
7649 [(set_attr "type" "multi")
7650 (set_attr "length_immediate" "0")
7651 (set_attr "mode" "SI")])
7653 (define_insn "udivmoddi4"
7654 [(set (match_operand:DI 0 "register_operand" "=a")
7655 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7656 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7657 (set (match_operand:DI 3 "register_operand" "=&d")
7658 (umod:DI (match_dup 1) (match_dup 2)))
7659 (clobber (reg:CC FLAGS_REG))]
7661 "xor{q}\t%3, %3\;div{q}\t%2"
7662 [(set_attr "type" "multi")
7663 (set_attr "length_immediate" "0")
7664 (set_attr "mode" "DI")])
7666 (define_insn "*udivmoddi4_noext"
7667 [(set (match_operand:DI 0 "register_operand" "=a")
7668 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7669 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7670 (set (match_operand:DI 3 "register_operand" "=d")
7671 (umod:DI (match_dup 1) (match_dup 2)))
7673 (clobber (reg:CC FLAGS_REG))]
7676 [(set_attr "type" "idiv")
7677 (set_attr "mode" "DI")])
7680 [(set (match_operand:DI 0 "register_operand" "")
7681 (udiv:DI (match_operand:DI 1 "register_operand" "")
7682 (match_operand:DI 2 "nonimmediate_operand" "")))
7683 (set (match_operand:DI 3 "register_operand" "")
7684 (umod:DI (match_dup 1) (match_dup 2)))
7685 (clobber (reg:CC FLAGS_REG))]
7686 "TARGET_64BIT && reload_completed"
7687 [(set (match_dup 3) (const_int 0))
7688 (parallel [(set (match_dup 0)
7689 (udiv:DI (match_dup 1) (match_dup 2)))
7691 (umod:DI (match_dup 1) (match_dup 2)))
7693 (clobber (reg:CC FLAGS_REG))])]
7696 (define_insn "udivmodsi4"
7697 [(set (match_operand:SI 0 "register_operand" "=a")
7698 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7699 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7700 (set (match_operand:SI 3 "register_operand" "=&d")
7701 (umod:SI (match_dup 1) (match_dup 2)))
7702 (clobber (reg:CC FLAGS_REG))]
7704 "xor{l}\t%3, %3\;div{l}\t%2"
7705 [(set_attr "type" "multi")
7706 (set_attr "length_immediate" "0")
7707 (set_attr "mode" "SI")])
7709 (define_insn "*udivmodsi4_noext"
7710 [(set (match_operand:SI 0 "register_operand" "=a")
7711 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7712 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7713 (set (match_operand:SI 3 "register_operand" "=d")
7714 (umod:SI (match_dup 1) (match_dup 2)))
7716 (clobber (reg:CC FLAGS_REG))]
7719 [(set_attr "type" "idiv")
7720 (set_attr "mode" "SI")])
7723 [(set (match_operand:SI 0 "register_operand" "")
7724 (udiv:SI (match_operand:SI 1 "register_operand" "")
7725 (match_operand:SI 2 "nonimmediate_operand" "")))
7726 (set (match_operand:SI 3 "register_operand" "")
7727 (umod:SI (match_dup 1) (match_dup 2)))
7728 (clobber (reg:CC FLAGS_REG))]
7730 [(set (match_dup 3) (const_int 0))
7731 (parallel [(set (match_dup 0)
7732 (udiv:SI (match_dup 1) (match_dup 2)))
7734 (umod:SI (match_dup 1) (match_dup 2)))
7736 (clobber (reg:CC FLAGS_REG))])]
7739 (define_expand "udivmodhi4"
7740 [(set (match_dup 4) (const_int 0))
7741 (parallel [(set (match_operand:HI 0 "register_operand" "")
7742 (udiv:HI (match_operand:HI 1 "register_operand" "")
7743 (match_operand:HI 2 "nonimmediate_operand" "")))
7744 (set (match_operand:HI 3 "register_operand" "")
7745 (umod:HI (match_dup 1) (match_dup 2)))
7747 (clobber (reg:CC FLAGS_REG))])]
7748 "TARGET_HIMODE_MATH"
7749 "operands[4] = gen_reg_rtx (HImode);")
7751 (define_insn "*udivmodhi_noext"
7752 [(set (match_operand:HI 0 "register_operand" "=a")
7753 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7754 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7755 (set (match_operand:HI 3 "register_operand" "=d")
7756 (umod:HI (match_dup 1) (match_dup 2)))
7757 (use (match_operand:HI 4 "register_operand" "3"))
7758 (clobber (reg:CC FLAGS_REG))]
7761 [(set_attr "type" "idiv")
7762 (set_attr "mode" "HI")])
7764 ;; We cannot use div/idiv for double division, because it causes
7765 ;; "division by zero" on the overflow and that's not what we expect
7766 ;; from truncate. Because true (non truncating) double division is
7767 ;; never generated, we can't create this insn anyway.
7770 ; [(set (match_operand:SI 0 "register_operand" "=a")
7772 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7774 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7775 ; (set (match_operand:SI 3 "register_operand" "=d")
7777 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7778 ; (clobber (reg:CC FLAGS_REG))]
7780 ; "div{l}\t{%2, %0|%0, %2}"
7781 ; [(set_attr "type" "idiv")])
7783 ;;- Logical AND instructions
7785 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7786 ;; Note that this excludes ah.
7788 (define_insn "*testdi_1_rex64"
7789 [(set (reg FLAGS_REG)
7791 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7792 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7794 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7795 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7797 test{l}\t{%k1, %k0|%k0, %k1}
7798 test{l}\t{%k1, %k0|%k0, %k1}
7799 test{q}\t{%1, %0|%0, %1}
7800 test{q}\t{%1, %0|%0, %1}
7801 test{q}\t{%1, %0|%0, %1}"
7802 [(set_attr "type" "test")
7803 (set_attr "modrm" "0,1,0,1,1")
7804 (set_attr "mode" "SI,SI,DI,DI,DI")
7805 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7807 (define_insn "testsi_1"
7808 [(set (reg FLAGS_REG)
7810 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7811 (match_operand:SI 1 "general_operand" "in,in,rin"))
7813 "ix86_match_ccmode (insn, CCNOmode)
7814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7815 "test{l}\t{%1, %0|%0, %1}"
7816 [(set_attr "type" "test")
7817 (set_attr "modrm" "0,1,1")
7818 (set_attr "mode" "SI")
7819 (set_attr "pent_pair" "uv,np,uv")])
7821 (define_expand "testsi_ccno_1"
7822 [(set (reg:CCNO FLAGS_REG)
7824 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7825 (match_operand:SI 1 "nonmemory_operand" ""))
7830 (define_insn "*testhi_1"
7831 [(set (reg FLAGS_REG)
7832 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7833 (match_operand:HI 1 "general_operand" "n,n,rn"))
7835 "ix86_match_ccmode (insn, CCNOmode)
7836 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7837 "test{w}\t{%1, %0|%0, %1}"
7838 [(set_attr "type" "test")
7839 (set_attr "modrm" "0,1,1")
7840 (set_attr "mode" "HI")
7841 (set_attr "pent_pair" "uv,np,uv")])
7843 (define_expand "testqi_ccz_1"
7844 [(set (reg:CCZ FLAGS_REG)
7845 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7846 (match_operand:QI 1 "nonmemory_operand" ""))
7851 (define_insn "*testqi_1_maybe_si"
7852 [(set (reg FLAGS_REG)
7855 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7856 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7858 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7859 && ix86_match_ccmode (insn,
7860 CONST_INT_P (operands[1])
7861 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7863 if (which_alternative == 3)
7865 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7866 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7867 return "test{l}\t{%1, %k0|%k0, %1}";
7869 return "test{b}\t{%1, %0|%0, %1}";
7871 [(set_attr "type" "test")
7872 (set_attr "modrm" "0,1,1,1")
7873 (set_attr "mode" "QI,QI,QI,SI")
7874 (set_attr "pent_pair" "uv,np,uv,np")])
7876 (define_insn "*testqi_1"
7877 [(set (reg FLAGS_REG)
7880 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7881 (match_operand:QI 1 "general_operand" "n,n,qn"))
7883 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7884 && ix86_match_ccmode (insn, CCNOmode)"
7885 "test{b}\t{%1, %0|%0, %1}"
7886 [(set_attr "type" "test")
7887 (set_attr "modrm" "0,1,1")
7888 (set_attr "mode" "QI")
7889 (set_attr "pent_pair" "uv,np,uv")])
7891 (define_expand "testqi_ext_ccno_0"
7892 [(set (reg:CCNO FLAGS_REG)
7896 (match_operand 0 "ext_register_operand" "")
7899 (match_operand 1 "const_int_operand" ""))
7904 (define_insn "*testqi_ext_0"
7905 [(set (reg FLAGS_REG)
7909 (match_operand 0 "ext_register_operand" "Q")
7912 (match_operand 1 "const_int_operand" "n"))
7914 "ix86_match_ccmode (insn, CCNOmode)"
7915 "test{b}\t{%1, %h0|%h0, %1}"
7916 [(set_attr "type" "test")
7917 (set_attr "mode" "QI")
7918 (set_attr "length_immediate" "1")
7919 (set_attr "pent_pair" "np")])
7921 (define_insn "*testqi_ext_1"
7922 [(set (reg FLAGS_REG)
7926 (match_operand 0 "ext_register_operand" "Q")
7930 (match_operand:QI 1 "general_operand" "Qm")))
7932 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7933 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7934 "test{b}\t{%1, %h0|%h0, %1}"
7935 [(set_attr "type" "test")
7936 (set_attr "mode" "QI")])
7938 (define_insn "*testqi_ext_1_rex64"
7939 [(set (reg FLAGS_REG)
7943 (match_operand 0 "ext_register_operand" "Q")
7947 (match_operand:QI 1 "register_operand" "Q")))
7949 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7950 "test{b}\t{%1, %h0|%h0, %1}"
7951 [(set_attr "type" "test")
7952 (set_attr "mode" "QI")])
7954 (define_insn "*testqi_ext_2"
7955 [(set (reg FLAGS_REG)
7959 (match_operand 0 "ext_register_operand" "Q")
7963 (match_operand 1 "ext_register_operand" "Q")
7967 "ix86_match_ccmode (insn, CCNOmode)"
7968 "test{b}\t{%h1, %h0|%h0, %h1}"
7969 [(set_attr "type" "test")
7970 (set_attr "mode" "QI")])
7972 ;; Combine likes to form bit extractions for some tests. Humor it.
7973 (define_insn "*testqi_ext_3"
7974 [(set (reg FLAGS_REG)
7975 (compare (zero_extract:SI
7976 (match_operand 0 "nonimmediate_operand" "rm")
7977 (match_operand:SI 1 "const_int_operand" "")
7978 (match_operand:SI 2 "const_int_operand" ""))
7980 "ix86_match_ccmode (insn, CCNOmode)
7981 && INTVAL (operands[1]) > 0
7982 && INTVAL (operands[2]) >= 0
7983 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7984 && (GET_MODE (operands[0]) == SImode
7985 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7986 || GET_MODE (operands[0]) == HImode
7987 || GET_MODE (operands[0]) == QImode)"
7990 (define_insn "*testqi_ext_3_rex64"
7991 [(set (reg FLAGS_REG)
7992 (compare (zero_extract:DI
7993 (match_operand 0 "nonimmediate_operand" "rm")
7994 (match_operand:DI 1 "const_int_operand" "")
7995 (match_operand:DI 2 "const_int_operand" ""))
7998 && ix86_match_ccmode (insn, CCNOmode)
7999 && INTVAL (operands[1]) > 0
8000 && INTVAL (operands[2]) >= 0
8001 /* Ensure that resulting mask is zero or sign extended operand. */
8002 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8003 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8004 && INTVAL (operands[1]) > 32))
8005 && (GET_MODE (operands[0]) == SImode
8006 || GET_MODE (operands[0]) == DImode
8007 || GET_MODE (operands[0]) == HImode
8008 || GET_MODE (operands[0]) == QImode)"
8012 [(set (match_operand 0 "flags_reg_operand" "")
8013 (match_operator 1 "compare_operator"
8015 (match_operand 2 "nonimmediate_operand" "")
8016 (match_operand 3 "const_int_operand" "")
8017 (match_operand 4 "const_int_operand" ""))
8019 "ix86_match_ccmode (insn, CCNOmode)"
8020 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8022 rtx val = operands[2];
8023 HOST_WIDE_INT len = INTVAL (operands[3]);
8024 HOST_WIDE_INT pos = INTVAL (operands[4]);
8026 enum machine_mode mode, submode;
8028 mode = GET_MODE (val);
8031 /* ??? Combine likes to put non-volatile mem extractions in QImode
8032 no matter the size of the test. So find a mode that works. */
8033 if (! MEM_VOLATILE_P (val))
8035 mode = smallest_mode_for_size (pos + len, MODE_INT);
8036 val = adjust_address (val, mode, 0);
8039 else if (GET_CODE (val) == SUBREG
8040 && (submode = GET_MODE (SUBREG_REG (val)),
8041 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8042 && pos + len <= GET_MODE_BITSIZE (submode))
8044 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8046 val = SUBREG_REG (val);
8048 else if (mode == HImode && pos + len <= 8)
8050 /* Small HImode tests can be converted to QImode. */
8052 val = gen_lowpart (QImode, val);
8055 if (len == HOST_BITS_PER_WIDE_INT)
8058 mask = ((HOST_WIDE_INT)1 << len) - 1;
8061 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8064 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8065 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8066 ;; this is relatively important trick.
8067 ;; Do the conversion only post-reload to avoid limiting of the register class
8070 [(set (match_operand 0 "flags_reg_operand" "")
8071 (match_operator 1 "compare_operator"
8072 [(and (match_operand 2 "register_operand" "")
8073 (match_operand 3 "const_int_operand" ""))
8076 && QI_REG_P (operands[2])
8077 && GET_MODE (operands[2]) != QImode
8078 && ((ix86_match_ccmode (insn, CCZmode)
8079 && !(INTVAL (operands[3]) & ~(255 << 8)))
8080 || (ix86_match_ccmode (insn, CCNOmode)
8081 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8084 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8087 "operands[2] = gen_lowpart (SImode, operands[2]);
8088 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8091 [(set (match_operand 0 "flags_reg_operand" "")
8092 (match_operator 1 "compare_operator"
8093 [(and (match_operand 2 "nonimmediate_operand" "")
8094 (match_operand 3 "const_int_operand" ""))
8097 && GET_MODE (operands[2]) != QImode
8098 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8099 && ((ix86_match_ccmode (insn, CCZmode)
8100 && !(INTVAL (operands[3]) & ~255))
8101 || (ix86_match_ccmode (insn, CCNOmode)
8102 && !(INTVAL (operands[3]) & ~127)))"
8104 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8106 "operands[2] = gen_lowpart (QImode, operands[2]);
8107 operands[3] = gen_lowpart (QImode, operands[3]);")
8110 ;; %%% This used to optimize known byte-wide and operations to memory,
8111 ;; and sometimes to QImode registers. If this is considered useful,
8112 ;; it should be done with splitters.
8114 (define_expand "anddi3"
8115 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8116 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8117 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8118 (clobber (reg:CC FLAGS_REG))]
8120 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8122 (define_insn "*anddi_1_rex64"
8123 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8124 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8125 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8126 (clobber (reg:CC FLAGS_REG))]
8127 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8129 switch (get_attr_type (insn))
8133 enum machine_mode mode;
8135 gcc_assert (CONST_INT_P (operands[2]));
8136 if (INTVAL (operands[2]) == 0xff)
8140 gcc_assert (INTVAL (operands[2]) == 0xffff);
8144 operands[1] = gen_lowpart (mode, operands[1]);
8146 return "movz{bq|x}\t{%1,%0|%0, %1}";
8148 return "movz{wq|x}\t{%1,%0|%0, %1}";
8152 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8153 if (get_attr_mode (insn) == MODE_SI)
8154 return "and{l}\t{%k2, %k0|%k0, %k2}";
8156 return "and{q}\t{%2, %0|%0, %2}";
8159 [(set_attr "type" "alu,alu,alu,imovx")
8160 (set_attr "length_immediate" "*,*,*,0")
8161 (set_attr "mode" "SI,DI,DI,DI")])
8163 (define_insn "*anddi_2"
8164 [(set (reg FLAGS_REG)
8165 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8166 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8168 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8169 (and:DI (match_dup 1) (match_dup 2)))]
8170 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8171 && ix86_binary_operator_ok (AND, DImode, operands)"
8173 and{l}\t{%k2, %k0|%k0, %k2}
8174 and{q}\t{%2, %0|%0, %2}
8175 and{q}\t{%2, %0|%0, %2}"
8176 [(set_attr "type" "alu")
8177 (set_attr "mode" "SI,DI,DI")])
8179 (define_expand "andsi3"
8180 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8181 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8182 (match_operand:SI 2 "general_operand" "")))
8183 (clobber (reg:CC FLAGS_REG))]
8185 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8187 (define_insn "*andsi_1"
8188 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8189 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8190 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8191 (clobber (reg:CC FLAGS_REG))]
8192 "ix86_binary_operator_ok (AND, SImode, operands)"
8194 switch (get_attr_type (insn))
8198 enum machine_mode mode;
8200 gcc_assert (CONST_INT_P (operands[2]));
8201 if (INTVAL (operands[2]) == 0xff)
8205 gcc_assert (INTVAL (operands[2]) == 0xffff);
8209 operands[1] = gen_lowpart (mode, operands[1]);
8211 return "movz{bl|x}\t{%1,%0|%0, %1}";
8213 return "movz{wl|x}\t{%1,%0|%0, %1}";
8217 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8218 return "and{l}\t{%2, %0|%0, %2}";
8221 [(set_attr "type" "alu,alu,imovx")
8222 (set_attr "length_immediate" "*,*,0")
8223 (set_attr "mode" "SI")])
8226 [(set (match_operand 0 "register_operand" "")
8228 (const_int -65536)))
8229 (clobber (reg:CC FLAGS_REG))]
8230 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8231 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8232 "operands[1] = gen_lowpart (HImode, operands[0]);")
8235 [(set (match_operand 0 "ext_register_operand" "")
8238 (clobber (reg:CC FLAGS_REG))]
8239 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8240 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8241 "operands[1] = gen_lowpart (QImode, operands[0]);")
8244 [(set (match_operand 0 "ext_register_operand" "")
8246 (const_int -65281)))
8247 (clobber (reg:CC FLAGS_REG))]
8248 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8249 [(parallel [(set (zero_extract:SI (match_dup 0)
8253 (zero_extract:SI (match_dup 0)
8256 (zero_extract:SI (match_dup 0)
8259 (clobber (reg:CC FLAGS_REG))])]
8260 "operands[0] = gen_lowpart (SImode, operands[0]);")
8262 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8263 (define_insn "*andsi_1_zext"
8264 [(set (match_operand:DI 0 "register_operand" "=r")
8266 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8267 (match_operand:SI 2 "general_operand" "rim"))))
8268 (clobber (reg:CC FLAGS_REG))]
8269 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8270 "and{l}\t{%2, %k0|%k0, %2}"
8271 [(set_attr "type" "alu")
8272 (set_attr "mode" "SI")])
8274 (define_insn "*andsi_2"
8275 [(set (reg FLAGS_REG)
8276 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8277 (match_operand:SI 2 "general_operand" "rim,ri"))
8279 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8280 (and:SI (match_dup 1) (match_dup 2)))]
8281 "ix86_match_ccmode (insn, CCNOmode)
8282 && ix86_binary_operator_ok (AND, SImode, operands)"
8283 "and{l}\t{%2, %0|%0, %2}"
8284 [(set_attr "type" "alu")
8285 (set_attr "mode" "SI")])
8287 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8288 (define_insn "*andsi_2_zext"
8289 [(set (reg FLAGS_REG)
8290 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8291 (match_operand:SI 2 "general_operand" "rim"))
8293 (set (match_operand:DI 0 "register_operand" "=r")
8294 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8295 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8296 && ix86_binary_operator_ok (AND, SImode, operands)"
8297 "and{l}\t{%2, %k0|%k0, %2}"
8298 [(set_attr "type" "alu")
8299 (set_attr "mode" "SI")])
8301 (define_expand "andhi3"
8302 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8303 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8304 (match_operand:HI 2 "general_operand" "")))
8305 (clobber (reg:CC FLAGS_REG))]
8306 "TARGET_HIMODE_MATH"
8307 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8309 (define_insn "*andhi_1"
8310 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8311 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8312 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "ix86_binary_operator_ok (AND, HImode, operands)"
8316 switch (get_attr_type (insn))
8319 gcc_assert (CONST_INT_P (operands[2]));
8320 gcc_assert (INTVAL (operands[2]) == 0xff);
8321 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8324 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8326 return "and{w}\t{%2, %0|%0, %2}";
8329 [(set_attr "type" "alu,alu,imovx")
8330 (set_attr "length_immediate" "*,*,0")
8331 (set_attr "mode" "HI,HI,SI")])
8333 (define_insn "*andhi_2"
8334 [(set (reg FLAGS_REG)
8335 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8336 (match_operand:HI 2 "general_operand" "rim,ri"))
8338 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8339 (and:HI (match_dup 1) (match_dup 2)))]
8340 "ix86_match_ccmode (insn, CCNOmode)
8341 && ix86_binary_operator_ok (AND, HImode, operands)"
8342 "and{w}\t{%2, %0|%0, %2}"
8343 [(set_attr "type" "alu")
8344 (set_attr "mode" "HI")])
8346 (define_expand "andqi3"
8347 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8348 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8349 (match_operand:QI 2 "general_operand" "")))
8350 (clobber (reg:CC FLAGS_REG))]
8351 "TARGET_QIMODE_MATH"
8352 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8354 ;; %%% Potential partial reg stall on alternative 2. What to do?
8355 (define_insn "*andqi_1"
8356 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8357 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8358 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8359 (clobber (reg:CC FLAGS_REG))]
8360 "ix86_binary_operator_ok (AND, QImode, operands)"
8362 and{b}\t{%2, %0|%0, %2}
8363 and{b}\t{%2, %0|%0, %2}
8364 and{l}\t{%k2, %k0|%k0, %k2}"
8365 [(set_attr "type" "alu")
8366 (set_attr "mode" "QI,QI,SI")])
8368 (define_insn "*andqi_1_slp"
8369 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8370 (and:QI (match_dup 0)
8371 (match_operand:QI 1 "general_operand" "qi,qmi")))
8372 (clobber (reg:CC FLAGS_REG))]
8373 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8374 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8375 "and{b}\t{%1, %0|%0, %1}"
8376 [(set_attr "type" "alu1")
8377 (set_attr "mode" "QI")])
8379 (define_insn "*andqi_2_maybe_si"
8380 [(set (reg FLAGS_REG)
8382 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8383 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8385 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8386 (and:QI (match_dup 1) (match_dup 2)))]
8387 "ix86_binary_operator_ok (AND, QImode, operands)
8388 && ix86_match_ccmode (insn,
8389 CONST_INT_P (operands[2])
8390 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8392 if (which_alternative == 2)
8394 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8395 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8396 return "and{l}\t{%2, %k0|%k0, %2}";
8398 return "and{b}\t{%2, %0|%0, %2}";
8400 [(set_attr "type" "alu")
8401 (set_attr "mode" "QI,QI,SI")])
8403 (define_insn "*andqi_2"
8404 [(set (reg FLAGS_REG)
8406 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8407 (match_operand:QI 2 "general_operand" "qim,qi"))
8409 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8410 (and:QI (match_dup 1) (match_dup 2)))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && ix86_binary_operator_ok (AND, QImode, operands)"
8413 "and{b}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "QI")])
8417 (define_insn "*andqi_2_slp"
8418 [(set (reg FLAGS_REG)
8420 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8421 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8423 (set (strict_low_part (match_dup 0))
8424 (and:QI (match_dup 0) (match_dup 1)))]
8425 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8426 && ix86_match_ccmode (insn, CCNOmode)
8427 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8428 "and{b}\t{%1, %0|%0, %1}"
8429 [(set_attr "type" "alu1")
8430 (set_attr "mode" "QI")])
8432 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8433 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8434 ;; for a QImode operand, which of course failed.
8436 (define_insn "andqi_ext_0"
8437 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8442 (match_operand 1 "ext_register_operand" "0")
8445 (match_operand 2 "const_int_operand" "n")))
8446 (clobber (reg:CC FLAGS_REG))]
8448 "and{b}\t{%2, %h0|%h0, %2}"
8449 [(set_attr "type" "alu")
8450 (set_attr "length_immediate" "1")
8451 (set_attr "mode" "QI")])
8453 ;; Generated by peephole translating test to and. This shows up
8454 ;; often in fp comparisons.
8456 (define_insn "*andqi_ext_0_cc"
8457 [(set (reg FLAGS_REG)
8461 (match_operand 1 "ext_register_operand" "0")
8464 (match_operand 2 "const_int_operand" "n"))
8466 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8475 "ix86_match_ccmode (insn, CCNOmode)"
8476 "and{b}\t{%2, %h0|%h0, %2}"
8477 [(set_attr "type" "alu")
8478 (set_attr "length_immediate" "1")
8479 (set_attr "mode" "QI")])
8481 (define_insn "*andqi_ext_1"
8482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8487 (match_operand 1 "ext_register_operand" "0")
8491 (match_operand:QI 2 "general_operand" "Qm"))))
8492 (clobber (reg:CC FLAGS_REG))]
8494 "and{b}\t{%2, %h0|%h0, %2}"
8495 [(set_attr "type" "alu")
8496 (set_attr "length_immediate" "0")
8497 (set_attr "mode" "QI")])
8499 (define_insn "*andqi_ext_1_rex64"
8500 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8505 (match_operand 1 "ext_register_operand" "0")
8509 (match_operand 2 "ext_register_operand" "Q"))))
8510 (clobber (reg:CC FLAGS_REG))]
8512 "and{b}\t{%2, %h0|%h0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "length_immediate" "0")
8515 (set_attr "mode" "QI")])
8517 (define_insn "*andqi_ext_2"
8518 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8523 (match_operand 1 "ext_register_operand" "%0")
8527 (match_operand 2 "ext_register_operand" "Q")
8530 (clobber (reg:CC FLAGS_REG))]
8532 "and{b}\t{%h2, %h0|%h0, %h2}"
8533 [(set_attr "type" "alu")
8534 (set_attr "length_immediate" "0")
8535 (set_attr "mode" "QI")])
8537 ;; Convert wide AND instructions with immediate operand to shorter QImode
8538 ;; equivalents when possible.
8539 ;; Don't do the splitting with memory operands, since it introduces risk
8540 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8541 ;; for size, but that can (should?) be handled by generic code instead.
8543 [(set (match_operand 0 "register_operand" "")
8544 (and (match_operand 1 "register_operand" "")
8545 (match_operand 2 "const_int_operand" "")))
8546 (clobber (reg:CC FLAGS_REG))]
8548 && QI_REG_P (operands[0])
8549 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8550 && !(~INTVAL (operands[2]) & ~(255 << 8))
8551 && GET_MODE (operands[0]) != QImode"
8552 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8553 (and:SI (zero_extract:SI (match_dup 1)
8554 (const_int 8) (const_int 8))
8556 (clobber (reg:CC FLAGS_REG))])]
8557 "operands[0] = gen_lowpart (SImode, operands[0]);
8558 operands[1] = gen_lowpart (SImode, operands[1]);
8559 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8561 ;; Since AND can be encoded with sign extended immediate, this is only
8562 ;; profitable when 7th bit is not set.
8564 [(set (match_operand 0 "register_operand" "")
8565 (and (match_operand 1 "general_operand" "")
8566 (match_operand 2 "const_int_operand" "")))
8567 (clobber (reg:CC FLAGS_REG))]
8569 && ANY_QI_REG_P (operands[0])
8570 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571 && !(~INTVAL (operands[2]) & ~255)
8572 && !(INTVAL (operands[2]) & 128)
8573 && GET_MODE (operands[0]) != QImode"
8574 [(parallel [(set (strict_low_part (match_dup 0))
8575 (and:QI (match_dup 1)
8577 (clobber (reg:CC FLAGS_REG))])]
8578 "operands[0] = gen_lowpart (QImode, operands[0]);
8579 operands[1] = gen_lowpart (QImode, operands[1]);
8580 operands[2] = gen_lowpart (QImode, operands[2]);")
8582 ;; Logical inclusive OR instructions
8584 ;; %%% This used to optimize known byte-wide and operations to memory.
8585 ;; If this is considered useful, it should be done with splitters.
8587 (define_expand "iordi3"
8588 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8589 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8590 (match_operand:DI 2 "x86_64_general_operand" "")))
8591 (clobber (reg:CC FLAGS_REG))]
8593 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8595 (define_insn "*iordi_1_rex64"
8596 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8597 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8598 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8599 (clobber (reg:CC FLAGS_REG))]
8601 && ix86_binary_operator_ok (IOR, DImode, operands)"
8602 "or{q}\t{%2, %0|%0, %2}"
8603 [(set_attr "type" "alu")
8604 (set_attr "mode" "DI")])
8606 (define_insn "*iordi_2_rex64"
8607 [(set (reg FLAGS_REG)
8608 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8609 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8611 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8612 (ior:DI (match_dup 1) (match_dup 2)))]
8614 && ix86_match_ccmode (insn, CCNOmode)
8615 && ix86_binary_operator_ok (IOR, DImode, operands)"
8616 "or{q}\t{%2, %0|%0, %2}"
8617 [(set_attr "type" "alu")
8618 (set_attr "mode" "DI")])
8620 (define_insn "*iordi_3_rex64"
8621 [(set (reg FLAGS_REG)
8622 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8623 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8625 (clobber (match_scratch:DI 0 "=r"))]
8627 && ix86_match_ccmode (insn, CCNOmode)
8628 && ix86_binary_operator_ok (IOR, DImode, operands)"
8629 "or{q}\t{%2, %0|%0, %2}"
8630 [(set_attr "type" "alu")
8631 (set_attr "mode" "DI")])
8634 (define_expand "iorsi3"
8635 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8636 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8637 (match_operand:SI 2 "general_operand" "")))
8638 (clobber (reg:CC FLAGS_REG))]
8640 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8642 (define_insn "*iorsi_1"
8643 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8644 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8645 (match_operand:SI 2 "general_operand" "ri,rmi")))
8646 (clobber (reg:CC FLAGS_REG))]
8647 "ix86_binary_operator_ok (IOR, SImode, operands)"
8648 "or{l}\t{%2, %0|%0, %2}"
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "SI")])
8652 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8653 (define_insn "*iorsi_1_zext"
8654 [(set (match_operand:DI 0 "register_operand" "=rm")
8656 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8657 (match_operand:SI 2 "general_operand" "rim"))))
8658 (clobber (reg:CC FLAGS_REG))]
8659 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8660 "or{l}\t{%2, %k0|%k0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8664 (define_insn "*iorsi_1_zext_imm"
8665 [(set (match_operand:DI 0 "register_operand" "=rm")
8666 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8667 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8668 (clobber (reg:CC FLAGS_REG))]
8670 "or{l}\t{%2, %k0|%k0, %2}"
8671 [(set_attr "type" "alu")
8672 (set_attr "mode" "SI")])
8674 (define_insn "*iorsi_2"
8675 [(set (reg FLAGS_REG)
8676 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8677 (match_operand:SI 2 "general_operand" "rim,ri"))
8679 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8680 (ior:SI (match_dup 1) (match_dup 2)))]
8681 "ix86_match_ccmode (insn, CCNOmode)
8682 && ix86_binary_operator_ok (IOR, SImode, operands)"
8683 "or{l}\t{%2, %0|%0, %2}"
8684 [(set_attr "type" "alu")
8685 (set_attr "mode" "SI")])
8687 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8688 ;; ??? Special case for immediate operand is missing - it is tricky.
8689 (define_insn "*iorsi_2_zext"
8690 [(set (reg FLAGS_REG)
8691 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8692 (match_operand:SI 2 "general_operand" "rim"))
8694 (set (match_operand:DI 0 "register_operand" "=r")
8695 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8696 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8697 && ix86_binary_operator_ok (IOR, SImode, operands)"
8698 "or{l}\t{%2, %k0|%k0, %2}"
8699 [(set_attr "type" "alu")
8700 (set_attr "mode" "SI")])
8702 (define_insn "*iorsi_2_zext_imm"
8703 [(set (reg FLAGS_REG)
8704 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8705 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8707 (set (match_operand:DI 0 "register_operand" "=r")
8708 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8709 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8710 && ix86_binary_operator_ok (IOR, SImode, operands)"
8711 "or{l}\t{%2, %k0|%k0, %2}"
8712 [(set_attr "type" "alu")
8713 (set_attr "mode" "SI")])
8715 (define_insn "*iorsi_3"
8716 [(set (reg FLAGS_REG)
8717 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8718 (match_operand:SI 2 "general_operand" "rim"))
8720 (clobber (match_scratch:SI 0 "=r"))]
8721 "ix86_match_ccmode (insn, CCNOmode)
8722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8723 "or{l}\t{%2, %0|%0, %2}"
8724 [(set_attr "type" "alu")
8725 (set_attr "mode" "SI")])
8727 (define_expand "iorhi3"
8728 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8729 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8730 (match_operand:HI 2 "general_operand" "")))
8731 (clobber (reg:CC FLAGS_REG))]
8732 "TARGET_HIMODE_MATH"
8733 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8735 (define_insn "*iorhi_1"
8736 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8737 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8738 (match_operand:HI 2 "general_operand" "rmi,ri")))
8739 (clobber (reg:CC FLAGS_REG))]
8740 "ix86_binary_operator_ok (IOR, HImode, operands)"
8741 "or{w}\t{%2, %0|%0, %2}"
8742 [(set_attr "type" "alu")
8743 (set_attr "mode" "HI")])
8745 (define_insn "*iorhi_2"
8746 [(set (reg FLAGS_REG)
8747 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8748 (match_operand:HI 2 "general_operand" "rim,ri"))
8750 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8751 (ior:HI (match_dup 1) (match_dup 2)))]
8752 "ix86_match_ccmode (insn, CCNOmode)
8753 && ix86_binary_operator_ok (IOR, HImode, operands)"
8754 "or{w}\t{%2, %0|%0, %2}"
8755 [(set_attr "type" "alu")
8756 (set_attr "mode" "HI")])
8758 (define_insn "*iorhi_3"
8759 [(set (reg FLAGS_REG)
8760 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8761 (match_operand:HI 2 "general_operand" "rim"))
8763 (clobber (match_scratch:HI 0 "=r"))]
8764 "ix86_match_ccmode (insn, CCNOmode)
8765 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8766 "or{w}\t{%2, %0|%0, %2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "HI")])
8770 (define_expand "iorqi3"
8771 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8772 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8773 (match_operand:QI 2 "general_operand" "")))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "TARGET_QIMODE_MATH"
8776 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8778 ;; %%% Potential partial reg stall on alternative 2. What to do?
8779 (define_insn "*iorqi_1"
8780 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8781 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8782 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8783 (clobber (reg:CC FLAGS_REG))]
8784 "ix86_binary_operator_ok (IOR, QImode, operands)"
8786 or{b}\t{%2, %0|%0, %2}
8787 or{b}\t{%2, %0|%0, %2}
8788 or{l}\t{%k2, %k0|%k0, %k2}"
8789 [(set_attr "type" "alu")
8790 (set_attr "mode" "QI,QI,SI")])
8792 (define_insn "*iorqi_1_slp"
8793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8794 (ior:QI (match_dup 0)
8795 (match_operand:QI 1 "general_operand" "qmi,qi")))
8796 (clobber (reg:CC FLAGS_REG))]
8797 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8798 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8799 "or{b}\t{%1, %0|%0, %1}"
8800 [(set_attr "type" "alu1")
8801 (set_attr "mode" "QI")])
8803 (define_insn "*iorqi_2"
8804 [(set (reg FLAGS_REG)
8805 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8806 (match_operand:QI 2 "general_operand" "qim,qi"))
8808 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8809 (ior:QI (match_dup 1) (match_dup 2)))]
8810 "ix86_match_ccmode (insn, CCNOmode)
8811 && ix86_binary_operator_ok (IOR, QImode, operands)"
8812 "or{b}\t{%2, %0|%0, %2}"
8813 [(set_attr "type" "alu")
8814 (set_attr "mode" "QI")])
8816 (define_insn "*iorqi_2_slp"
8817 [(set (reg FLAGS_REG)
8818 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8819 (match_operand:QI 1 "general_operand" "qim,qi"))
8821 (set (strict_low_part (match_dup 0))
8822 (ior:QI (match_dup 0) (match_dup 1)))]
8823 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8824 && ix86_match_ccmode (insn, CCNOmode)
8825 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8826 "or{b}\t{%1, %0|%0, %1}"
8827 [(set_attr "type" "alu1")
8828 (set_attr "mode" "QI")])
8830 (define_insn "*iorqi_3"
8831 [(set (reg FLAGS_REG)
8832 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8833 (match_operand:QI 2 "general_operand" "qim"))
8835 (clobber (match_scratch:QI 0 "=q"))]
8836 "ix86_match_ccmode (insn, CCNOmode)
8837 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8838 "or{b}\t{%2, %0|%0, %2}"
8839 [(set_attr "type" "alu")
8840 (set_attr "mode" "QI")])
8842 (define_insn "iorqi_ext_0"
8843 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8848 (match_operand 1 "ext_register_operand" "0")
8851 (match_operand 2 "const_int_operand" "n")))
8852 (clobber (reg:CC FLAGS_REG))]
8853 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8854 "or{b}\t{%2, %h0|%h0, %2}"
8855 [(set_attr "type" "alu")
8856 (set_attr "length_immediate" "1")
8857 (set_attr "mode" "QI")])
8859 (define_insn "*iorqi_ext_1"
8860 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8865 (match_operand 1 "ext_register_operand" "0")
8869 (match_operand:QI 2 "general_operand" "Qm"))))
8870 (clobber (reg:CC FLAGS_REG))]
8872 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8873 "or{b}\t{%2, %h0|%h0, %2}"
8874 [(set_attr "type" "alu")
8875 (set_attr "length_immediate" "0")
8876 (set_attr "mode" "QI")])
8878 (define_insn "*iorqi_ext_1_rex64"
8879 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8884 (match_operand 1 "ext_register_operand" "0")
8888 (match_operand 2 "ext_register_operand" "Q"))))
8889 (clobber (reg:CC FLAGS_REG))]
8891 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8892 "or{b}\t{%2, %h0|%h0, %2}"
8893 [(set_attr "type" "alu")
8894 (set_attr "length_immediate" "0")
8895 (set_attr "mode" "QI")])
8897 (define_insn "*iorqi_ext_2"
8898 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8902 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8905 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8908 (clobber (reg:CC FLAGS_REG))]
8909 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8910 "ior{b}\t{%h2, %h0|%h0, %h2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "length_immediate" "0")
8913 (set_attr "mode" "QI")])
8916 [(set (match_operand 0 "register_operand" "")
8917 (ior (match_operand 1 "register_operand" "")
8918 (match_operand 2 "const_int_operand" "")))
8919 (clobber (reg:CC FLAGS_REG))]
8921 && QI_REG_P (operands[0])
8922 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8923 && !(INTVAL (operands[2]) & ~(255 << 8))
8924 && GET_MODE (operands[0]) != QImode"
8925 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8926 (ior:SI (zero_extract:SI (match_dup 1)
8927 (const_int 8) (const_int 8))
8929 (clobber (reg:CC FLAGS_REG))])]
8930 "operands[0] = gen_lowpart (SImode, operands[0]);
8931 operands[1] = gen_lowpart (SImode, operands[1]);
8932 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8934 ;; Since OR can be encoded with sign extended immediate, this is only
8935 ;; profitable when 7th bit is set.
8937 [(set (match_operand 0 "register_operand" "")
8938 (ior (match_operand 1 "general_operand" "")
8939 (match_operand 2 "const_int_operand" "")))
8940 (clobber (reg:CC FLAGS_REG))]
8942 && ANY_QI_REG_P (operands[0])
8943 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944 && !(INTVAL (operands[2]) & ~255)
8945 && (INTVAL (operands[2]) & 128)
8946 && GET_MODE (operands[0]) != QImode"
8947 [(parallel [(set (strict_low_part (match_dup 0))
8948 (ior:QI (match_dup 1)
8950 (clobber (reg:CC FLAGS_REG))])]
8951 "operands[0] = gen_lowpart (QImode, operands[0]);
8952 operands[1] = gen_lowpart (QImode, operands[1]);
8953 operands[2] = gen_lowpart (QImode, operands[2]);")
8955 ;; Logical XOR instructions
8957 ;; %%% This used to optimize known byte-wide and operations to memory.
8958 ;; If this is considered useful, it should be done with splitters.
8960 (define_expand "xordi3"
8961 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8962 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8963 (match_operand:DI 2 "x86_64_general_operand" "")))
8964 (clobber (reg:CC FLAGS_REG))]
8966 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8968 (define_insn "*xordi_1_rex64"
8969 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8970 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8971 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8972 (clobber (reg:CC FLAGS_REG))]
8974 && ix86_binary_operator_ok (XOR, DImode, operands)"
8976 xor{q}\t{%2, %0|%0, %2}
8977 xor{q}\t{%2, %0|%0, %2}"
8978 [(set_attr "type" "alu")
8979 (set_attr "mode" "DI,DI")])
8981 (define_insn "*xordi_2_rex64"
8982 [(set (reg FLAGS_REG)
8983 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8984 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8986 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8987 (xor:DI (match_dup 1) (match_dup 2)))]
8989 && ix86_match_ccmode (insn, CCNOmode)
8990 && ix86_binary_operator_ok (XOR, DImode, operands)"
8992 xor{q}\t{%2, %0|%0, %2}
8993 xor{q}\t{%2, %0|%0, %2}"
8994 [(set_attr "type" "alu")
8995 (set_attr "mode" "DI,DI")])
8997 (define_insn "*xordi_3_rex64"
8998 [(set (reg FLAGS_REG)
8999 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9000 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9002 (clobber (match_scratch:DI 0 "=r"))]
9004 && ix86_match_ccmode (insn, CCNOmode)
9005 && ix86_binary_operator_ok (XOR, DImode, operands)"
9006 "xor{q}\t{%2, %0|%0, %2}"
9007 [(set_attr "type" "alu")
9008 (set_attr "mode" "DI")])
9010 (define_expand "xorsi3"
9011 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9012 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9013 (match_operand:SI 2 "general_operand" "")))
9014 (clobber (reg:CC FLAGS_REG))]
9016 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9018 (define_insn "*xorsi_1"
9019 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9020 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9021 (match_operand:SI 2 "general_operand" "ri,rm")))
9022 (clobber (reg:CC FLAGS_REG))]
9023 "ix86_binary_operator_ok (XOR, SImode, operands)"
9024 "xor{l}\t{%2, %0|%0, %2}"
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "SI")])
9028 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9029 ;; Add speccase for immediates
9030 (define_insn "*xorsi_1_zext"
9031 [(set (match_operand:DI 0 "register_operand" "=r")
9033 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9034 (match_operand:SI 2 "general_operand" "rim"))))
9035 (clobber (reg:CC FLAGS_REG))]
9036 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9037 "xor{l}\t{%2, %k0|%k0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9041 (define_insn "*xorsi_1_zext_imm"
9042 [(set (match_operand:DI 0 "register_operand" "=r")
9043 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9044 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9045 (clobber (reg:CC FLAGS_REG))]
9046 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9047 "xor{l}\t{%2, %k0|%k0, %2}"
9048 [(set_attr "type" "alu")
9049 (set_attr "mode" "SI")])
9051 (define_insn "*xorsi_2"
9052 [(set (reg FLAGS_REG)
9053 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9054 (match_operand:SI 2 "general_operand" "rim,ri"))
9056 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9057 (xor:SI (match_dup 1) (match_dup 2)))]
9058 "ix86_match_ccmode (insn, CCNOmode)
9059 && ix86_binary_operator_ok (XOR, SImode, operands)"
9060 "xor{l}\t{%2, %0|%0, %2}"
9061 [(set_attr "type" "alu")
9062 (set_attr "mode" "SI")])
9064 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9065 ;; ??? Special case for immediate operand is missing - it is tricky.
9066 (define_insn "*xorsi_2_zext"
9067 [(set (reg FLAGS_REG)
9068 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9069 (match_operand:SI 2 "general_operand" "rim"))
9071 (set (match_operand:DI 0 "register_operand" "=r")
9072 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9073 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9074 && ix86_binary_operator_ok (XOR, SImode, operands)"
9075 "xor{l}\t{%2, %k0|%k0, %2}"
9076 [(set_attr "type" "alu")
9077 (set_attr "mode" "SI")])
9079 (define_insn "*xorsi_2_zext_imm"
9080 [(set (reg FLAGS_REG)
9081 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9082 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9084 (set (match_operand:DI 0 "register_operand" "=r")
9085 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9086 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9087 && ix86_binary_operator_ok (XOR, SImode, operands)"
9088 "xor{l}\t{%2, %k0|%k0, %2}"
9089 [(set_attr "type" "alu")
9090 (set_attr "mode" "SI")])
9092 (define_insn "*xorsi_3"
9093 [(set (reg FLAGS_REG)
9094 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9095 (match_operand:SI 2 "general_operand" "rim"))
9097 (clobber (match_scratch:SI 0 "=r"))]
9098 "ix86_match_ccmode (insn, CCNOmode)
9099 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9100 "xor{l}\t{%2, %0|%0, %2}"
9101 [(set_attr "type" "alu")
9102 (set_attr "mode" "SI")])
9104 (define_expand "xorhi3"
9105 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9106 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9107 (match_operand:HI 2 "general_operand" "")))
9108 (clobber (reg:CC FLAGS_REG))]
9109 "TARGET_HIMODE_MATH"
9110 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9112 (define_insn "*xorhi_1"
9113 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9114 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9115 (match_operand:HI 2 "general_operand" "rmi,ri")))
9116 (clobber (reg:CC FLAGS_REG))]
9117 "ix86_binary_operator_ok (XOR, HImode, operands)"
9118 "xor{w}\t{%2, %0|%0, %2}"
9119 [(set_attr "type" "alu")
9120 (set_attr "mode" "HI")])
9122 (define_insn "*xorhi_2"
9123 [(set (reg FLAGS_REG)
9124 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9125 (match_operand:HI 2 "general_operand" "rim,ri"))
9127 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9128 (xor:HI (match_dup 1) (match_dup 2)))]
9129 "ix86_match_ccmode (insn, CCNOmode)
9130 && ix86_binary_operator_ok (XOR, HImode, operands)"
9131 "xor{w}\t{%2, %0|%0, %2}"
9132 [(set_attr "type" "alu")
9133 (set_attr "mode" "HI")])
9135 (define_insn "*xorhi_3"
9136 [(set (reg FLAGS_REG)
9137 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9138 (match_operand:HI 2 "general_operand" "rim"))
9140 (clobber (match_scratch:HI 0 "=r"))]
9141 "ix86_match_ccmode (insn, CCNOmode)
9142 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9143 "xor{w}\t{%2, %0|%0, %2}"
9144 [(set_attr "type" "alu")
9145 (set_attr "mode" "HI")])
9147 (define_expand "xorqi3"
9148 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9149 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9150 (match_operand:QI 2 "general_operand" "")))
9151 (clobber (reg:CC FLAGS_REG))]
9152 "TARGET_QIMODE_MATH"
9153 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9155 ;; %%% Potential partial reg stall on alternative 2. What to do?
9156 (define_insn "*xorqi_1"
9157 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9158 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9159 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9160 (clobber (reg:CC FLAGS_REG))]
9161 "ix86_binary_operator_ok (XOR, QImode, operands)"
9163 xor{b}\t{%2, %0|%0, %2}
9164 xor{b}\t{%2, %0|%0, %2}
9165 xor{l}\t{%k2, %k0|%k0, %k2}"
9166 [(set_attr "type" "alu")
9167 (set_attr "mode" "QI,QI,SI")])
9169 (define_insn "*xorqi_1_slp"
9170 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9171 (xor:QI (match_dup 0)
9172 (match_operand:QI 1 "general_operand" "qi,qmi")))
9173 (clobber (reg:CC FLAGS_REG))]
9174 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9175 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9176 "xor{b}\t{%1, %0|%0, %1}"
9177 [(set_attr "type" "alu1")
9178 (set_attr "mode" "QI")])
9180 (define_insn "xorqi_ext_0"
9181 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9186 (match_operand 1 "ext_register_operand" "0")
9189 (match_operand 2 "const_int_operand" "n")))
9190 (clobber (reg:CC FLAGS_REG))]
9191 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9192 "xor{b}\t{%2, %h0|%h0, %2}"
9193 [(set_attr "type" "alu")
9194 (set_attr "length_immediate" "1")
9195 (set_attr "mode" "QI")])
9197 (define_insn "*xorqi_ext_1"
9198 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9203 (match_operand 1 "ext_register_operand" "0")
9207 (match_operand:QI 2 "general_operand" "Qm"))))
9208 (clobber (reg:CC FLAGS_REG))]
9210 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9211 "xor{b}\t{%2, %h0|%h0, %2}"
9212 [(set_attr "type" "alu")
9213 (set_attr "length_immediate" "0")
9214 (set_attr "mode" "QI")])
9216 (define_insn "*xorqi_ext_1_rex64"
9217 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9222 (match_operand 1 "ext_register_operand" "0")
9226 (match_operand 2 "ext_register_operand" "Q"))))
9227 (clobber (reg:CC FLAGS_REG))]
9229 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9230 "xor{b}\t{%2, %h0|%h0, %2}"
9231 [(set_attr "type" "alu")
9232 (set_attr "length_immediate" "0")
9233 (set_attr "mode" "QI")])
9235 (define_insn "*xorqi_ext_2"
9236 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9240 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9243 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9246 (clobber (reg:CC FLAGS_REG))]
9247 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9248 "xor{b}\t{%h2, %h0|%h0, %h2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "length_immediate" "0")
9251 (set_attr "mode" "QI")])
9253 (define_insn "*xorqi_cc_1"
9254 [(set (reg FLAGS_REG)
9256 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9257 (match_operand:QI 2 "general_operand" "qim,qi"))
9259 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9260 (xor:QI (match_dup 1) (match_dup 2)))]
9261 "ix86_match_ccmode (insn, CCNOmode)
9262 && ix86_binary_operator_ok (XOR, QImode, operands)"
9263 "xor{b}\t{%2, %0|%0, %2}"
9264 [(set_attr "type" "alu")
9265 (set_attr "mode" "QI")])
9267 (define_insn "*xorqi_2_slp"
9268 [(set (reg FLAGS_REG)
9269 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9270 (match_operand:QI 1 "general_operand" "qim,qi"))
9272 (set (strict_low_part (match_dup 0))
9273 (xor:QI (match_dup 0) (match_dup 1)))]
9274 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9275 && ix86_match_ccmode (insn, CCNOmode)
9276 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9277 "xor{b}\t{%1, %0|%0, %1}"
9278 [(set_attr "type" "alu1")
9279 (set_attr "mode" "QI")])
9281 (define_insn "*xorqi_cc_2"
9282 [(set (reg FLAGS_REG)
9284 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9285 (match_operand:QI 2 "general_operand" "qim"))
9287 (clobber (match_scratch:QI 0 "=q"))]
9288 "ix86_match_ccmode (insn, CCNOmode)
9289 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9290 "xor{b}\t{%2, %0|%0, %2}"
9291 [(set_attr "type" "alu")
9292 (set_attr "mode" "QI")])
9294 (define_insn "*xorqi_cc_ext_1"
9295 [(set (reg FLAGS_REG)
9299 (match_operand 1 "ext_register_operand" "0")
9302 (match_operand:QI 2 "general_operand" "qmn"))
9304 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9308 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9310 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9311 "xor{b}\t{%2, %h0|%h0, %2}"
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "QI")])
9315 (define_insn "*xorqi_cc_ext_1_rex64"
9316 [(set (reg FLAGS_REG)
9320 (match_operand 1 "ext_register_operand" "0")
9323 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9325 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9329 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9331 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9332 "xor{b}\t{%2, %h0|%h0, %2}"
9333 [(set_attr "type" "alu")
9334 (set_attr "mode" "QI")])
9336 (define_expand "xorqi_cc_ext_1"
9338 (set (reg:CCNO FLAGS_REG)
9342 (match_operand 1 "ext_register_operand" "")
9345 (match_operand:QI 2 "general_operand" ""))
9347 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9351 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9357 [(set (match_operand 0 "register_operand" "")
9358 (xor (match_operand 1 "register_operand" "")
9359 (match_operand 2 "const_int_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))]
9362 && QI_REG_P (operands[0])
9363 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9364 && !(INTVAL (operands[2]) & ~(255 << 8))
9365 && GET_MODE (operands[0]) != QImode"
9366 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9367 (xor:SI (zero_extract:SI (match_dup 1)
9368 (const_int 8) (const_int 8))
9370 (clobber (reg:CC FLAGS_REG))])]
9371 "operands[0] = gen_lowpart (SImode, operands[0]);
9372 operands[1] = gen_lowpart (SImode, operands[1]);
9373 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9375 ;; Since XOR can be encoded with sign extended immediate, this is only
9376 ;; profitable when 7th bit is set.
9378 [(set (match_operand 0 "register_operand" "")
9379 (xor (match_operand 1 "general_operand" "")
9380 (match_operand 2 "const_int_operand" "")))
9381 (clobber (reg:CC FLAGS_REG))]
9383 && ANY_QI_REG_P (operands[0])
9384 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385 && !(INTVAL (operands[2]) & ~255)
9386 && (INTVAL (operands[2]) & 128)
9387 && GET_MODE (operands[0]) != QImode"
9388 [(parallel [(set (strict_low_part (match_dup 0))
9389 (xor:QI (match_dup 1)
9391 (clobber (reg:CC FLAGS_REG))])]
9392 "operands[0] = gen_lowpart (QImode, operands[0]);
9393 operands[1] = gen_lowpart (QImode, operands[1]);
9394 operands[2] = gen_lowpart (QImode, operands[2]);")
9396 ;; Negation instructions
9398 (define_expand "negti2"
9399 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9400 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9401 (clobber (reg:CC FLAGS_REG))])]
9403 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9405 (define_insn "*negti2_1"
9406 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9407 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9408 (clobber (reg:CC FLAGS_REG))]
9410 && ix86_unary_operator_ok (NEG, TImode, operands)"
9414 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9415 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9416 (clobber (reg:CC FLAGS_REG))]
9417 "TARGET_64BIT && reload_completed"
9419 [(set (reg:CCZ FLAGS_REG)
9420 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9421 (set (match_dup 0) (neg:DI (match_dup 2)))])
9424 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9427 (clobber (reg:CC FLAGS_REG))])
9430 (neg:DI (match_dup 1)))
9431 (clobber (reg:CC FLAGS_REG))])]
9432 "split_ti (operands+1, 1, operands+2, operands+3);
9433 split_ti (operands+0, 1, operands+0, operands+1);")
9435 (define_expand "negdi2"
9436 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9437 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9438 (clobber (reg:CC FLAGS_REG))])]
9440 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9442 (define_insn "*negdi2_1"
9443 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9444 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9445 (clobber (reg:CC FLAGS_REG))]
9447 && ix86_unary_operator_ok (NEG, DImode, operands)"
9451 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9452 (neg:DI (match_operand:DI 1 "general_operand" "")))
9453 (clobber (reg:CC FLAGS_REG))]
9454 "!TARGET_64BIT && reload_completed"
9456 [(set (reg:CCZ FLAGS_REG)
9457 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9458 (set (match_dup 0) (neg:SI (match_dup 2)))])
9461 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9464 (clobber (reg:CC FLAGS_REG))])
9467 (neg:SI (match_dup 1)))
9468 (clobber (reg:CC FLAGS_REG))])]
9469 "split_di (operands+1, 1, operands+2, operands+3);
9470 split_di (operands+0, 1, operands+0, operands+1);")
9472 (define_insn "*negdi2_1_rex64"
9473 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9474 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9478 [(set_attr "type" "negnot")
9479 (set_attr "mode" "DI")])
9481 ;; The problem with neg is that it does not perform (compare x 0),
9482 ;; it really performs (compare 0 x), which leaves us with the zero
9483 ;; flag being the only useful item.
9485 (define_insn "*negdi2_cmpz_rex64"
9486 [(set (reg:CCZ FLAGS_REG)
9487 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9489 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9490 (neg:DI (match_dup 1)))]
9491 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9493 [(set_attr "type" "negnot")
9494 (set_attr "mode" "DI")])
9497 (define_expand "negsi2"
9498 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9499 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9500 (clobber (reg:CC FLAGS_REG))])]
9502 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9504 (define_insn "*negsi2_1"
9505 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9506 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9507 (clobber (reg:CC FLAGS_REG))]
9508 "ix86_unary_operator_ok (NEG, SImode, operands)"
9510 [(set_attr "type" "negnot")
9511 (set_attr "mode" "SI")])
9513 ;; Combine is quite creative about this pattern.
9514 (define_insn "*negsi2_1_zext"
9515 [(set (match_operand:DI 0 "register_operand" "=r")
9516 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9519 (clobber (reg:CC FLAGS_REG))]
9520 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9522 [(set_attr "type" "negnot")
9523 (set_attr "mode" "SI")])
9525 ;; The problem with neg is that it does not perform (compare x 0),
9526 ;; it really performs (compare 0 x), which leaves us with the zero
9527 ;; flag being the only useful item.
9529 (define_insn "*negsi2_cmpz"
9530 [(set (reg:CCZ FLAGS_REG)
9531 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9533 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9534 (neg:SI (match_dup 1)))]
9535 "ix86_unary_operator_ok (NEG, SImode, operands)"
9537 [(set_attr "type" "negnot")
9538 (set_attr "mode" "SI")])
9540 (define_insn "*negsi2_cmpz_zext"
9541 [(set (reg:CCZ FLAGS_REG)
9542 (compare:CCZ (lshiftrt:DI
9544 (match_operand:DI 1 "register_operand" "0")
9548 (set (match_operand:DI 0 "register_operand" "=r")
9549 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9552 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9554 [(set_attr "type" "negnot")
9555 (set_attr "mode" "SI")])
9557 (define_expand "neghi2"
9558 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9559 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9560 (clobber (reg:CC FLAGS_REG))])]
9561 "TARGET_HIMODE_MATH"
9562 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9564 (define_insn "*neghi2_1"
9565 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9566 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9567 (clobber (reg:CC FLAGS_REG))]
9568 "ix86_unary_operator_ok (NEG, HImode, operands)"
9570 [(set_attr "type" "negnot")
9571 (set_attr "mode" "HI")])
9573 (define_insn "*neghi2_cmpz"
9574 [(set (reg:CCZ FLAGS_REG)
9575 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9577 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9578 (neg:HI (match_dup 1)))]
9579 "ix86_unary_operator_ok (NEG, HImode, operands)"
9581 [(set_attr "type" "negnot")
9582 (set_attr "mode" "HI")])
9584 (define_expand "negqi2"
9585 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9586 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9587 (clobber (reg:CC FLAGS_REG))])]
9588 "TARGET_QIMODE_MATH"
9589 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9591 (define_insn "*negqi2_1"
9592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9593 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9594 (clobber (reg:CC FLAGS_REG))]
9595 "ix86_unary_operator_ok (NEG, QImode, operands)"
9597 [(set_attr "type" "negnot")
9598 (set_attr "mode" "QI")])
9600 (define_insn "*negqi2_cmpz"
9601 [(set (reg:CCZ FLAGS_REG)
9602 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9604 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9605 (neg:QI (match_dup 1)))]
9606 "ix86_unary_operator_ok (NEG, QImode, operands)"
9608 [(set_attr "type" "negnot")
9609 (set_attr "mode" "QI")])
9611 ;; Changing of sign for FP values is doable using integer unit too.
9613 (define_expand "negsf2"
9614 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9615 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9616 "TARGET_80387 || TARGET_SSE_MATH"
9617 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9619 (define_expand "abssf2"
9620 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9621 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9622 "TARGET_80387 || TARGET_SSE_MATH"
9623 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9625 (define_insn "*absnegsf2_mixed"
9626 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9627 (match_operator:SF 3 "absneg_operator"
9628 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9629 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9630 (clobber (reg:CC FLAGS_REG))]
9631 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9632 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9635 (define_insn "*absnegsf2_sse"
9636 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9637 (match_operator:SF 3 "absneg_operator"
9638 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9639 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9640 (clobber (reg:CC FLAGS_REG))]
9642 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9645 (define_insn "*absnegsf2_i387"
9646 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9647 (match_operator:SF 3 "absneg_operator"
9648 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9649 (use (match_operand 2 "" ""))
9650 (clobber (reg:CC FLAGS_REG))]
9651 "TARGET_80387 && !TARGET_SSE_MATH
9652 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9655 (define_expand "negdf2"
9656 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9657 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9658 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9659 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9661 (define_expand "absdf2"
9662 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9663 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9664 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9665 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9667 (define_insn "*absnegdf2_mixed"
9668 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
9669 (match_operator:DF 3 "absneg_operator"
9670 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9671 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
9672 (clobber (reg:CC FLAGS_REG))]
9673 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9674 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9677 (define_insn "*absnegdf2_sse"
9678 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
9679 (match_operator:DF 3 "absneg_operator"
9680 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9681 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
9682 (clobber (reg:CC FLAGS_REG))]
9683 "TARGET_SSE2 && TARGET_SSE_MATH
9684 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9687 (define_insn "*absnegdf2_i387"
9688 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9689 (match_operator:DF 3 "absneg_operator"
9690 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9691 (use (match_operand 2 "" ""))
9692 (clobber (reg:CC FLAGS_REG))]
9693 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9694 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9697 (define_expand "negxf2"
9698 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9699 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9701 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9703 (define_expand "absxf2"
9704 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9705 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9707 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9709 (define_insn "*absnegxf2_i387"
9710 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9711 (match_operator:XF 3 "absneg_operator"
9712 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9713 (use (match_operand 2 "" ""))
9714 (clobber (reg:CC FLAGS_REG))]
9716 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9719 (define_expand "negtf2"
9720 [(set (match_operand:TF 0 "nonimmediate_operand" "")
9721 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
9723 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
9725 (define_expand "abstf2"
9726 [(set (match_operand:TF 0 "nonimmediate_operand" "")
9727 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
9729 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
9731 (define_insn "*absnegtf2_sse"
9732 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x,m")
9733 (match_operator:TF 3 "absneg_operator"
9734 [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
9735 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0,X"))
9736 (clobber (reg:CC FLAGS_REG))]
9738 && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
9741 ;; Splitters for fp abs and neg.
9744 [(set (match_operand 0 "fp_register_operand" "")
9745 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9746 (use (match_operand 2 "" ""))
9747 (clobber (reg:CC FLAGS_REG))]
9749 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9752 [(set (match_operand 0 "register_operand" "")
9753 (match_operator 3 "absneg_operator"
9754 [(match_operand 1 "register_operand" "")]))
9755 (use (match_operand 2 "nonimmediate_operand" ""))
9756 (clobber (reg:CC FLAGS_REG))]
9757 "reload_completed && SSE_REG_P (operands[0])"
9758 [(set (match_dup 0) (match_dup 3))]
9760 enum machine_mode mode = GET_MODE (operands[0]);
9761 enum machine_mode vmode = GET_MODE (operands[2]);
9764 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9765 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9766 if (operands_match_p (operands[0], operands[2]))
9769 operands[1] = operands[2];
9772 if (GET_CODE (operands[3]) == ABS)
9773 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9775 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9780 [(set (match_operand:SF 0 "register_operand" "")
9781 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9782 (use (match_operand:V4SF 2 "" ""))
9783 (clobber (reg:CC FLAGS_REG))]
9785 [(parallel [(set (match_dup 0) (match_dup 1))
9786 (clobber (reg:CC FLAGS_REG))])]
9789 operands[0] = gen_lowpart (SImode, operands[0]);
9790 if (GET_CODE (operands[1]) == ABS)
9792 tmp = gen_int_mode (0x7fffffff, SImode);
9793 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9797 tmp = gen_int_mode (0x80000000, SImode);
9798 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9804 [(set (match_operand:DF 0 "register_operand" "")
9805 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9806 (use (match_operand 2 "" ""))
9807 (clobber (reg:CC FLAGS_REG))]
9809 [(parallel [(set (match_dup 0) (match_dup 1))
9810 (clobber (reg:CC FLAGS_REG))])]
9815 tmp = gen_lowpart (DImode, operands[0]);
9816 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9819 if (GET_CODE (operands[1]) == ABS)
9822 tmp = gen_rtx_NOT (DImode, tmp);
9826 operands[0] = gen_highpart (SImode, operands[0]);
9827 if (GET_CODE (operands[1]) == ABS)
9829 tmp = gen_int_mode (0x7fffffff, SImode);
9830 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9834 tmp = gen_int_mode (0x80000000, SImode);
9835 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9842 [(set (match_operand:XF 0 "register_operand" "")
9843 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9844 (use (match_operand 2 "" ""))
9845 (clobber (reg:CC FLAGS_REG))]
9847 [(parallel [(set (match_dup 0) (match_dup 1))
9848 (clobber (reg:CC FLAGS_REG))])]
9851 operands[0] = gen_rtx_REG (SImode,
9852 true_regnum (operands[0])
9853 + (TARGET_64BIT ? 1 : 2));
9854 if (GET_CODE (operands[1]) == ABS)
9856 tmp = GEN_INT (0x7fff);
9857 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9861 tmp = GEN_INT (0x8000);
9862 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9868 [(set (match_operand 0 "memory_operand" "")
9869 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9870 (use (match_operand 2 "" ""))
9871 (clobber (reg:CC FLAGS_REG))]
9873 [(parallel [(set (match_dup 0) (match_dup 1))
9874 (clobber (reg:CC FLAGS_REG))])]
9876 enum machine_mode mode = GET_MODE (operands[0]);
9877 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9880 operands[0] = adjust_address (operands[0], QImode, size - 1);
9881 if (GET_CODE (operands[1]) == ABS)
9883 tmp = gen_int_mode (0x7f, QImode);
9884 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9888 tmp = gen_int_mode (0x80, QImode);
9889 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9894 ;; Conditionalize these after reload. If they match before reload, we
9895 ;; lose the clobber and ability to use integer instructions.
9897 (define_insn "*negsf2_1"
9898 [(set (match_operand:SF 0 "register_operand" "=f")
9899 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9900 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9902 [(set_attr "type" "fsgn")
9903 (set_attr "mode" "SF")])
9905 (define_insn "*negdf2_1"
9906 [(set (match_operand:DF 0 "register_operand" "=f")
9907 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9908 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9910 [(set_attr "type" "fsgn")
9911 (set_attr "mode" "DF")])
9913 (define_insn "*negxf2_1"
9914 [(set (match_operand:XF 0 "register_operand" "=f")
9915 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9918 [(set_attr "type" "fsgn")
9919 (set_attr "mode" "XF")])
9921 (define_insn "*abssf2_1"
9922 [(set (match_operand:SF 0 "register_operand" "=f")
9923 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9924 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9926 [(set_attr "type" "fsgn")
9927 (set_attr "mode" "SF")])
9929 (define_insn "*absdf2_1"
9930 [(set (match_operand:DF 0 "register_operand" "=f")
9931 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9932 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9934 [(set_attr "type" "fsgn")
9935 (set_attr "mode" "DF")])
9937 (define_insn "*absxf2_1"
9938 [(set (match_operand:XF 0 "register_operand" "=f")
9939 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9942 [(set_attr "type" "fsgn")
9943 (set_attr "mode" "DF")])
9945 (define_insn "*negextendsfdf2"
9946 [(set (match_operand:DF 0 "register_operand" "=f")
9947 (neg:DF (float_extend:DF
9948 (match_operand:SF 1 "register_operand" "0"))))]
9949 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9951 [(set_attr "type" "fsgn")
9952 (set_attr "mode" "DF")])
9954 (define_insn "*negextenddfxf2"
9955 [(set (match_operand:XF 0 "register_operand" "=f")
9956 (neg:XF (float_extend:XF
9957 (match_operand:DF 1 "register_operand" "0"))))]
9960 [(set_attr "type" "fsgn")
9961 (set_attr "mode" "XF")])
9963 (define_insn "*negextendsfxf2"
9964 [(set (match_operand:XF 0 "register_operand" "=f")
9965 (neg:XF (float_extend:XF
9966 (match_operand:SF 1 "register_operand" "0"))))]
9969 [(set_attr "type" "fsgn")
9970 (set_attr "mode" "XF")])
9972 (define_insn "*absextendsfdf2"
9973 [(set (match_operand:DF 0 "register_operand" "=f")
9974 (abs:DF (float_extend:DF
9975 (match_operand:SF 1 "register_operand" "0"))))]
9976 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9978 [(set_attr "type" "fsgn")
9979 (set_attr "mode" "DF")])
9981 (define_insn "*absextenddfxf2"
9982 [(set (match_operand:XF 0 "register_operand" "=f")
9983 (abs:XF (float_extend:XF
9984 (match_operand:DF 1 "register_operand" "0"))))]
9987 [(set_attr "type" "fsgn")
9988 (set_attr "mode" "XF")])
9990 (define_insn "*absextendsfxf2"
9991 [(set (match_operand:XF 0 "register_operand" "=f")
9992 (abs:XF (float_extend:XF
9993 (match_operand:SF 1 "register_operand" "0"))))]
9996 [(set_attr "type" "fsgn")
9997 (set_attr "mode" "XF")])
9999 ;; Copysign instructions
10001 (define_mode_macro CSGNMODE [SF DF TF])
10002 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10004 (define_expand "copysign<mode>3"
10005 [(match_operand:CSGNMODE 0 "register_operand" "")
10006 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10007 (match_operand:CSGNMODE 2 "register_operand" "")]
10008 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10009 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10011 ix86_expand_copysign (operands);
10015 (define_insn_and_split "copysign<mode>3_const"
10016 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10018 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10019 (match_operand:CSGNMODE 2 "register_operand" "0")
10020 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10022 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10023 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10025 "&& reload_completed"
10028 ix86_split_copysign_const (operands);
10032 (define_insn "copysign<mode>3_var"
10033 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10035 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10036 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10037 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10038 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10040 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10041 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10042 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10046 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10048 [(match_operand:CSGNMODE 2 "register_operand" "")
10049 (match_operand:CSGNMODE 3 "register_operand" "")
10050 (match_operand:<CSGNVMODE> 4 "" "")
10051 (match_operand:<CSGNVMODE> 5 "" "")]
10053 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10054 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10055 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10056 && reload_completed"
10059 ix86_split_copysign_var (operands);
10063 ;; One complement instructions
10065 (define_expand "one_cmpldi2"
10066 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10067 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10069 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10071 (define_insn "*one_cmpldi2_1_rex64"
10072 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10073 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10074 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10076 [(set_attr "type" "negnot")
10077 (set_attr "mode" "DI")])
10079 (define_insn "*one_cmpldi2_2_rex64"
10080 [(set (reg FLAGS_REG)
10081 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10083 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10084 (not:DI (match_dup 1)))]
10085 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10086 && ix86_unary_operator_ok (NOT, DImode, operands)"
10088 [(set_attr "type" "alu1")
10089 (set_attr "mode" "DI")])
10092 [(set (match_operand 0 "flags_reg_operand" "")
10093 (match_operator 2 "compare_operator"
10094 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10096 (set (match_operand:DI 1 "nonimmediate_operand" "")
10097 (not:DI (match_dup 3)))]
10098 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10099 [(parallel [(set (match_dup 0)
10101 [(xor:DI (match_dup 3) (const_int -1))
10104 (xor:DI (match_dup 3) (const_int -1)))])]
10107 (define_expand "one_cmplsi2"
10108 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10109 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10111 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10113 (define_insn "*one_cmplsi2_1"
10114 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10115 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10116 "ix86_unary_operator_ok (NOT, SImode, operands)"
10118 [(set_attr "type" "negnot")
10119 (set_attr "mode" "SI")])
10121 ;; ??? Currently never generated - xor is used instead.
10122 (define_insn "*one_cmplsi2_1_zext"
10123 [(set (match_operand:DI 0 "register_operand" "=r")
10124 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10125 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10127 [(set_attr "type" "negnot")
10128 (set_attr "mode" "SI")])
10130 (define_insn "*one_cmplsi2_2"
10131 [(set (reg FLAGS_REG)
10132 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10134 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10135 (not:SI (match_dup 1)))]
10136 "ix86_match_ccmode (insn, CCNOmode)
10137 && ix86_unary_operator_ok (NOT, SImode, operands)"
10139 [(set_attr "type" "alu1")
10140 (set_attr "mode" "SI")])
10143 [(set (match_operand 0 "flags_reg_operand" "")
10144 (match_operator 2 "compare_operator"
10145 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10147 (set (match_operand:SI 1 "nonimmediate_operand" "")
10148 (not:SI (match_dup 3)))]
10149 "ix86_match_ccmode (insn, CCNOmode)"
10150 [(parallel [(set (match_dup 0)
10151 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10154 (xor:SI (match_dup 3) (const_int -1)))])]
10157 ;; ??? Currently never generated - xor is used instead.
10158 (define_insn "*one_cmplsi2_2_zext"
10159 [(set (reg FLAGS_REG)
10160 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10162 (set (match_operand:DI 0 "register_operand" "=r")
10163 (zero_extend:DI (not:SI (match_dup 1))))]
10164 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10165 && ix86_unary_operator_ok (NOT, SImode, operands)"
10167 [(set_attr "type" "alu1")
10168 (set_attr "mode" "SI")])
10171 [(set (match_operand 0 "flags_reg_operand" "")
10172 (match_operator 2 "compare_operator"
10173 [(not:SI (match_operand:SI 3 "register_operand" ""))
10175 (set (match_operand:DI 1 "register_operand" "")
10176 (zero_extend:DI (not:SI (match_dup 3))))]
10177 "ix86_match_ccmode (insn, CCNOmode)"
10178 [(parallel [(set (match_dup 0)
10179 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10182 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10185 (define_expand "one_cmplhi2"
10186 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10187 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10188 "TARGET_HIMODE_MATH"
10189 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10191 (define_insn "*one_cmplhi2_1"
10192 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10193 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10194 "ix86_unary_operator_ok (NOT, HImode, operands)"
10196 [(set_attr "type" "negnot")
10197 (set_attr "mode" "HI")])
10199 (define_insn "*one_cmplhi2_2"
10200 [(set (reg FLAGS_REG)
10201 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10203 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10204 (not:HI (match_dup 1)))]
10205 "ix86_match_ccmode (insn, CCNOmode)
10206 && ix86_unary_operator_ok (NEG, HImode, operands)"
10208 [(set_attr "type" "alu1")
10209 (set_attr "mode" "HI")])
10212 [(set (match_operand 0 "flags_reg_operand" "")
10213 (match_operator 2 "compare_operator"
10214 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10216 (set (match_operand:HI 1 "nonimmediate_operand" "")
10217 (not:HI (match_dup 3)))]
10218 "ix86_match_ccmode (insn, CCNOmode)"
10219 [(parallel [(set (match_dup 0)
10220 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10223 (xor:HI (match_dup 3) (const_int -1)))])]
10226 ;; %%% Potential partial reg stall on alternative 1. What to do?
10227 (define_expand "one_cmplqi2"
10228 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10229 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10230 "TARGET_QIMODE_MATH"
10231 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10233 (define_insn "*one_cmplqi2_1"
10234 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10235 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10236 "ix86_unary_operator_ok (NOT, QImode, operands)"
10240 [(set_attr "type" "negnot")
10241 (set_attr "mode" "QI,SI")])
10243 (define_insn "*one_cmplqi2_2"
10244 [(set (reg FLAGS_REG)
10245 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10247 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10248 (not:QI (match_dup 1)))]
10249 "ix86_match_ccmode (insn, CCNOmode)
10250 && ix86_unary_operator_ok (NOT, QImode, operands)"
10252 [(set_attr "type" "alu1")
10253 (set_attr "mode" "QI")])
10256 [(set (match_operand 0 "flags_reg_operand" "")
10257 (match_operator 2 "compare_operator"
10258 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10260 (set (match_operand:QI 1 "nonimmediate_operand" "")
10261 (not:QI (match_dup 3)))]
10262 "ix86_match_ccmode (insn, CCNOmode)"
10263 [(parallel [(set (match_dup 0)
10264 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10267 (xor:QI (match_dup 3) (const_int -1)))])]
10270 ;; Arithmetic shift instructions
10272 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10273 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10274 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10275 ;; from the assembler input.
10277 ;; This instruction shifts the target reg/mem as usual, but instead of
10278 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10279 ;; is a left shift double, bits are taken from the high order bits of
10280 ;; reg, else if the insn is a shift right double, bits are taken from the
10281 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10282 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10284 ;; Since sh[lr]d does not change the `reg' operand, that is done
10285 ;; separately, making all shifts emit pairs of shift double and normal
10286 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10287 ;; support a 63 bit shift, each shift where the count is in a reg expands
10288 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10290 ;; If the shift count is a constant, we need never emit more than one
10291 ;; shift pair, instead using moves and sign extension for counts greater
10294 (define_expand "ashlti3"
10295 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10296 (ashift:TI (match_operand:TI 1 "register_operand" "")
10297 (match_operand:QI 2 "nonmemory_operand" "")))
10298 (clobber (reg:CC FLAGS_REG))])]
10301 if (! immediate_operand (operands[2], QImode))
10303 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10306 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10310 (define_insn "ashlti3_1"
10311 [(set (match_operand:TI 0 "register_operand" "=r")
10312 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10313 (match_operand:QI 2 "register_operand" "c")))
10314 (clobber (match_scratch:DI 3 "=&r"))
10315 (clobber (reg:CC FLAGS_REG))]
10318 [(set_attr "type" "multi")])
10320 (define_insn "*ashlti3_2"
10321 [(set (match_operand:TI 0 "register_operand" "=r")
10322 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10323 (match_operand:QI 2 "immediate_operand" "O")))
10324 (clobber (reg:CC FLAGS_REG))]
10327 [(set_attr "type" "multi")])
10330 [(set (match_operand:TI 0 "register_operand" "")
10331 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10332 (match_operand:QI 2 "register_operand" "")))
10333 (clobber (match_scratch:DI 3 ""))
10334 (clobber (reg:CC FLAGS_REG))]
10335 "TARGET_64BIT && reload_completed"
10337 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10340 [(set (match_operand:TI 0 "register_operand" "")
10341 (ashift:TI (match_operand:TI 1 "register_operand" "")
10342 (match_operand:QI 2 "immediate_operand" "")))
10343 (clobber (reg:CC FLAGS_REG))]
10344 "TARGET_64BIT && reload_completed"
10346 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10348 (define_insn "x86_64_shld"
10349 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10350 (ior:DI (ashift:DI (match_dup 0)
10351 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10352 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10353 (minus:QI (const_int 64) (match_dup 2)))))
10354 (clobber (reg:CC FLAGS_REG))]
10357 shld{q}\t{%2, %1, %0|%0, %1, %2}
10358 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10359 [(set_attr "type" "ishift")
10360 (set_attr "prefix_0f" "1")
10361 (set_attr "mode" "DI")
10362 (set_attr "athlon_decode" "vector")
10363 (set_attr "amdfam10_decode" "vector")])
10365 (define_expand "x86_64_shift_adj"
10366 [(set (reg:CCZ FLAGS_REG)
10367 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10370 (set (match_operand:DI 0 "register_operand" "")
10371 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10372 (match_operand:DI 1 "register_operand" "")
10375 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10376 (match_operand:DI 3 "register_operand" "r")
10381 (define_expand "ashldi3"
10382 [(set (match_operand:DI 0 "shiftdi_operand" "")
10383 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10384 (match_operand:QI 2 "nonmemory_operand" "")))]
10386 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10388 (define_insn "*ashldi3_1_rex64"
10389 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10390 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10391 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10392 (clobber (reg:CC FLAGS_REG))]
10393 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10395 switch (get_attr_type (insn))
10398 gcc_assert (operands[2] == const1_rtx);
10399 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10400 return "add{q}\t%0, %0";
10403 gcc_assert (CONST_INT_P (operands[2]));
10404 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10405 operands[1] = gen_rtx_MULT (DImode, operands[1],
10406 GEN_INT (1 << INTVAL (operands[2])));
10407 return "lea{q}\t{%a1, %0|%0, %a1}";
10410 if (REG_P (operands[2]))
10411 return "sal{q}\t{%b2, %0|%0, %b2}";
10412 else if (operands[2] == const1_rtx
10413 && (TARGET_SHIFT1 || optimize_size))
10414 return "sal{q}\t%0";
10416 return "sal{q}\t{%2, %0|%0, %2}";
10419 [(set (attr "type")
10420 (cond [(eq_attr "alternative" "1")
10421 (const_string "lea")
10422 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10424 (match_operand 0 "register_operand" ""))
10425 (match_operand 2 "const1_operand" ""))
10426 (const_string "alu")
10428 (const_string "ishift")))
10429 (set_attr "mode" "DI")])
10431 ;; Convert lea to the lea pattern to avoid flags dependency.
10433 [(set (match_operand:DI 0 "register_operand" "")
10434 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10435 (match_operand:QI 2 "immediate_operand" "")))
10436 (clobber (reg:CC FLAGS_REG))]
10437 "TARGET_64BIT && reload_completed
10438 && true_regnum (operands[0]) != true_regnum (operands[1])"
10439 [(set (match_dup 0)
10440 (mult:DI (match_dup 1)
10442 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10444 ;; This pattern can't accept a variable shift count, since shifts by
10445 ;; zero don't affect the flags. We assume that shifts by constant
10446 ;; zero are optimized away.
10447 (define_insn "*ashldi3_cmp_rex64"
10448 [(set (reg FLAGS_REG)
10450 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10451 (match_operand:QI 2 "immediate_operand" "e"))
10453 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10454 (ashift:DI (match_dup 1) (match_dup 2)))]
10455 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10456 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10458 || !TARGET_PARTIAL_FLAG_REG_STALL
10459 || (operands[2] == const1_rtx
10461 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10463 switch (get_attr_type (insn))
10466 gcc_assert (operands[2] == const1_rtx);
10467 return "add{q}\t%0, %0";
10470 if (REG_P (operands[2]))
10471 return "sal{q}\t{%b2, %0|%0, %b2}";
10472 else if (operands[2] == const1_rtx
10473 && (TARGET_SHIFT1 || optimize_size))
10474 return "sal{q}\t%0";
10476 return "sal{q}\t{%2, %0|%0, %2}";
10479 [(set (attr "type")
10480 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10482 (match_operand 0 "register_operand" ""))
10483 (match_operand 2 "const1_operand" ""))
10484 (const_string "alu")
10486 (const_string "ishift")))
10487 (set_attr "mode" "DI")])
10489 (define_insn "*ashldi3_cconly_rex64"
10490 [(set (reg FLAGS_REG)
10492 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10493 (match_operand:QI 2 "immediate_operand" "e"))
10495 (clobber (match_scratch:DI 0 "=r"))]
10496 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10497 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10499 || !TARGET_PARTIAL_FLAG_REG_STALL
10500 || (operands[2] == const1_rtx
10502 || TARGET_DOUBLE_WITH_ADD)))"
10504 switch (get_attr_type (insn))
10507 gcc_assert (operands[2] == const1_rtx);
10508 return "add{q}\t%0, %0";
10511 if (REG_P (operands[2]))
10512 return "sal{q}\t{%b2, %0|%0, %b2}";
10513 else if (operands[2] == const1_rtx
10514 && (TARGET_SHIFT1 || optimize_size))
10515 return "sal{q}\t%0";
10517 return "sal{q}\t{%2, %0|%0, %2}";
10520 [(set (attr "type")
10521 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10523 (match_operand 0 "register_operand" ""))
10524 (match_operand 2 "const1_operand" ""))
10525 (const_string "alu")
10527 (const_string "ishift")))
10528 (set_attr "mode" "DI")])
10530 (define_insn "*ashldi3_1"
10531 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10532 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10533 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10534 (clobber (reg:CC FLAGS_REG))]
10537 [(set_attr "type" "multi")])
10539 ;; By default we don't ask for a scratch register, because when DImode
10540 ;; values are manipulated, registers are already at a premium. But if
10541 ;; we have one handy, we won't turn it away.
10543 [(match_scratch:SI 3 "r")
10544 (parallel [(set (match_operand:DI 0 "register_operand" "")
10545 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10546 (match_operand:QI 2 "nonmemory_operand" "")))
10547 (clobber (reg:CC FLAGS_REG))])
10549 "!TARGET_64BIT && TARGET_CMOVE"
10551 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10554 [(set (match_operand:DI 0 "register_operand" "")
10555 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10556 (match_operand:QI 2 "nonmemory_operand" "")))
10557 (clobber (reg:CC FLAGS_REG))]
10558 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10559 ? flow2_completed : reload_completed)"
10561 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10563 (define_insn "x86_shld_1"
10564 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10565 (ior:SI (ashift:SI (match_dup 0)
10566 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10567 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10568 (minus:QI (const_int 32) (match_dup 2)))))
10569 (clobber (reg:CC FLAGS_REG))]
10572 shld{l}\t{%2, %1, %0|%0, %1, %2}
10573 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10574 [(set_attr "type" "ishift")
10575 (set_attr "prefix_0f" "1")
10576 (set_attr "mode" "SI")
10577 (set_attr "pent_pair" "np")
10578 (set_attr "athlon_decode" "vector")
10579 (set_attr "amdfam10_decode" "vector")])
10581 (define_expand "x86_shift_adj_1"
10582 [(set (reg:CCZ FLAGS_REG)
10583 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10586 (set (match_operand:SI 0 "register_operand" "")
10587 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10588 (match_operand:SI 1 "register_operand" "")
10591 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10592 (match_operand:SI 3 "register_operand" "r")
10597 (define_expand "x86_shift_adj_2"
10598 [(use (match_operand:SI 0 "register_operand" ""))
10599 (use (match_operand:SI 1 "register_operand" ""))
10600 (use (match_operand:QI 2 "register_operand" ""))]
10603 rtx label = gen_label_rtx ();
10606 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10608 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10609 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10610 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10611 gen_rtx_LABEL_REF (VOIDmode, label),
10613 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10614 JUMP_LABEL (tmp) = label;
10616 emit_move_insn (operands[0], operands[1]);
10617 ix86_expand_clear (operands[1]);
10619 emit_label (label);
10620 LABEL_NUSES (label) = 1;
10625 (define_expand "ashlsi3"
10626 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10627 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10628 (match_operand:QI 2 "nonmemory_operand" "")))
10629 (clobber (reg:CC FLAGS_REG))]
10631 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10633 (define_insn "*ashlsi3_1"
10634 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10635 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10636 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10637 (clobber (reg:CC FLAGS_REG))]
10638 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10640 switch (get_attr_type (insn))
10643 gcc_assert (operands[2] == const1_rtx);
10644 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10645 return "add{l}\t%0, %0";
10651 if (REG_P (operands[2]))
10652 return "sal{l}\t{%b2, %0|%0, %b2}";
10653 else if (operands[2] == const1_rtx
10654 && (TARGET_SHIFT1 || optimize_size))
10655 return "sal{l}\t%0";
10657 return "sal{l}\t{%2, %0|%0, %2}";
10660 [(set (attr "type")
10661 (cond [(eq_attr "alternative" "1")
10662 (const_string "lea")
10663 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10665 (match_operand 0 "register_operand" ""))
10666 (match_operand 2 "const1_operand" ""))
10667 (const_string "alu")
10669 (const_string "ishift")))
10670 (set_attr "mode" "SI")])
10672 ;; Convert lea to the lea pattern to avoid flags dependency.
10674 [(set (match_operand 0 "register_operand" "")
10675 (ashift (match_operand 1 "index_register_operand" "")
10676 (match_operand:QI 2 "const_int_operand" "")))
10677 (clobber (reg:CC FLAGS_REG))]
10679 && true_regnum (operands[0]) != true_regnum (operands[1])
10680 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10684 enum machine_mode mode = GET_MODE (operands[0]);
10686 if (GET_MODE_SIZE (mode) < 4)
10687 operands[0] = gen_lowpart (SImode, operands[0]);
10689 operands[1] = gen_lowpart (Pmode, operands[1]);
10690 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10692 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10693 if (Pmode != SImode)
10694 pat = gen_rtx_SUBREG (SImode, pat, 0);
10695 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10699 ;; Rare case of shifting RSP is handled by generating move and shift
10701 [(set (match_operand 0 "register_operand" "")
10702 (ashift (match_operand 1 "register_operand" "")
10703 (match_operand:QI 2 "const_int_operand" "")))
10704 (clobber (reg:CC FLAGS_REG))]
10706 && true_regnum (operands[0]) != true_regnum (operands[1])"
10710 emit_move_insn (operands[0], operands[1]);
10711 pat = gen_rtx_SET (VOIDmode, operands[0],
10712 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10713 operands[0], operands[2]));
10714 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10715 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10719 (define_insn "*ashlsi3_1_zext"
10720 [(set (match_operand:DI 0 "register_operand" "=r,r")
10721 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10722 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10723 (clobber (reg:CC FLAGS_REG))]
10724 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10726 switch (get_attr_type (insn))
10729 gcc_assert (operands[2] == const1_rtx);
10730 return "add{l}\t%k0, %k0";
10736 if (REG_P (operands[2]))
10737 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10738 else if (operands[2] == const1_rtx
10739 && (TARGET_SHIFT1 || optimize_size))
10740 return "sal{l}\t%k0";
10742 return "sal{l}\t{%2, %k0|%k0, %2}";
10745 [(set (attr "type")
10746 (cond [(eq_attr "alternative" "1")
10747 (const_string "lea")
10748 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10750 (match_operand 2 "const1_operand" ""))
10751 (const_string "alu")
10753 (const_string "ishift")))
10754 (set_attr "mode" "SI")])
10756 ;; Convert lea to the lea pattern to avoid flags dependency.
10758 [(set (match_operand:DI 0 "register_operand" "")
10759 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10760 (match_operand:QI 2 "const_int_operand" ""))))
10761 (clobber (reg:CC FLAGS_REG))]
10762 "TARGET_64BIT && reload_completed
10763 && true_regnum (operands[0]) != true_regnum (operands[1])"
10764 [(set (match_dup 0) (zero_extend:DI
10765 (subreg:SI (mult:SI (match_dup 1)
10766 (match_dup 2)) 0)))]
10768 operands[1] = gen_lowpart (Pmode, operands[1]);
10769 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10772 ;; This pattern can't accept a variable shift count, since shifts by
10773 ;; zero don't affect the flags. We assume that shifts by constant
10774 ;; zero are optimized away.
10775 (define_insn "*ashlsi3_cmp"
10776 [(set (reg FLAGS_REG)
10778 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10779 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10781 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10782 (ashift:SI (match_dup 1) (match_dup 2)))]
10783 "ix86_match_ccmode (insn, CCGOCmode)
10784 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10786 || !TARGET_PARTIAL_FLAG_REG_STALL
10787 || (operands[2] == const1_rtx
10789 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10791 switch (get_attr_type (insn))
10794 gcc_assert (operands[2] == const1_rtx);
10795 return "add{l}\t%0, %0";
10798 if (REG_P (operands[2]))
10799 return "sal{l}\t{%b2, %0|%0, %b2}";
10800 else if (operands[2] == const1_rtx
10801 && (TARGET_SHIFT1 || optimize_size))
10802 return "sal{l}\t%0";
10804 return "sal{l}\t{%2, %0|%0, %2}";
10807 [(set (attr "type")
10808 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10810 (match_operand 0 "register_operand" ""))
10811 (match_operand 2 "const1_operand" ""))
10812 (const_string "alu")
10814 (const_string "ishift")))
10815 (set_attr "mode" "SI")])
10817 (define_insn "*ashlsi3_cconly"
10818 [(set (reg FLAGS_REG)
10820 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10821 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10823 (clobber (match_scratch:SI 0 "=r"))]
10824 "ix86_match_ccmode (insn, CCGOCmode)
10825 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10827 || !TARGET_PARTIAL_FLAG_REG_STALL
10828 || (operands[2] == const1_rtx
10830 || TARGET_DOUBLE_WITH_ADD)))"
10832 switch (get_attr_type (insn))
10835 gcc_assert (operands[2] == const1_rtx);
10836 return "add{l}\t%0, %0";
10839 if (REG_P (operands[2]))
10840 return "sal{l}\t{%b2, %0|%0, %b2}";
10841 else if (operands[2] == const1_rtx
10842 && (TARGET_SHIFT1 || optimize_size))
10843 return "sal{l}\t%0";
10845 return "sal{l}\t{%2, %0|%0, %2}";
10848 [(set (attr "type")
10849 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10851 (match_operand 0 "register_operand" ""))
10852 (match_operand 2 "const1_operand" ""))
10853 (const_string "alu")
10855 (const_string "ishift")))
10856 (set_attr "mode" "SI")])
10858 (define_insn "*ashlsi3_cmp_zext"
10859 [(set (reg FLAGS_REG)
10861 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10862 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10864 (set (match_operand:DI 0 "register_operand" "=r")
10865 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10866 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10867 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10869 || !TARGET_PARTIAL_FLAG_REG_STALL
10870 || (operands[2] == const1_rtx
10872 || TARGET_DOUBLE_WITH_ADD)))"
10874 switch (get_attr_type (insn))
10877 gcc_assert (operands[2] == const1_rtx);
10878 return "add{l}\t%k0, %k0";
10881 if (REG_P (operands[2]))
10882 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10883 else if (operands[2] == const1_rtx
10884 && (TARGET_SHIFT1 || optimize_size))
10885 return "sal{l}\t%k0";
10887 return "sal{l}\t{%2, %k0|%k0, %2}";
10890 [(set (attr "type")
10891 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10893 (match_operand 2 "const1_operand" ""))
10894 (const_string "alu")
10896 (const_string "ishift")))
10897 (set_attr "mode" "SI")])
10899 (define_expand "ashlhi3"
10900 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10901 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10902 (match_operand:QI 2 "nonmemory_operand" "")))
10903 (clobber (reg:CC FLAGS_REG))]
10904 "TARGET_HIMODE_MATH"
10905 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10907 (define_insn "*ashlhi3_1_lea"
10908 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10909 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10910 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10911 (clobber (reg:CC FLAGS_REG))]
10912 "!TARGET_PARTIAL_REG_STALL
10913 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10915 switch (get_attr_type (insn))
10920 gcc_assert (operands[2] == const1_rtx);
10921 return "add{w}\t%0, %0";
10924 if (REG_P (operands[2]))
10925 return "sal{w}\t{%b2, %0|%0, %b2}";
10926 else if (operands[2] == const1_rtx
10927 && (TARGET_SHIFT1 || optimize_size))
10928 return "sal{w}\t%0";
10930 return "sal{w}\t{%2, %0|%0, %2}";
10933 [(set (attr "type")
10934 (cond [(eq_attr "alternative" "1")
10935 (const_string "lea")
10936 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10938 (match_operand 0 "register_operand" ""))
10939 (match_operand 2 "const1_operand" ""))
10940 (const_string "alu")
10942 (const_string "ishift")))
10943 (set_attr "mode" "HI,SI")])
10945 (define_insn "*ashlhi3_1"
10946 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10947 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10948 (match_operand:QI 2 "nonmemory_operand" "cI")))
10949 (clobber (reg:CC FLAGS_REG))]
10950 "TARGET_PARTIAL_REG_STALL
10951 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10953 switch (get_attr_type (insn))
10956 gcc_assert (operands[2] == const1_rtx);
10957 return "add{w}\t%0, %0";
10960 if (REG_P (operands[2]))
10961 return "sal{w}\t{%b2, %0|%0, %b2}";
10962 else if (operands[2] == const1_rtx
10963 && (TARGET_SHIFT1 || optimize_size))
10964 return "sal{w}\t%0";
10966 return "sal{w}\t{%2, %0|%0, %2}";
10969 [(set (attr "type")
10970 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10972 (match_operand 0 "register_operand" ""))
10973 (match_operand 2 "const1_operand" ""))
10974 (const_string "alu")
10976 (const_string "ishift")))
10977 (set_attr "mode" "HI")])
10979 ;; This pattern can't accept a variable shift count, since shifts by
10980 ;; zero don't affect the flags. We assume that shifts by constant
10981 ;; zero are optimized away.
10982 (define_insn "*ashlhi3_cmp"
10983 [(set (reg FLAGS_REG)
10985 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10986 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10988 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10989 (ashift:HI (match_dup 1) (match_dup 2)))]
10990 "ix86_match_ccmode (insn, CCGOCmode)
10991 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10993 || !TARGET_PARTIAL_FLAG_REG_STALL
10994 || (operands[2] == const1_rtx
10996 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10998 switch (get_attr_type (insn))
11001 gcc_assert (operands[2] == const1_rtx);
11002 return "add{w}\t%0, %0";
11005 if (REG_P (operands[2]))
11006 return "sal{w}\t{%b2, %0|%0, %b2}";
11007 else if (operands[2] == const1_rtx
11008 && (TARGET_SHIFT1 || optimize_size))
11009 return "sal{w}\t%0";
11011 return "sal{w}\t{%2, %0|%0, %2}";
11014 [(set (attr "type")
11015 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11017 (match_operand 0 "register_operand" ""))
11018 (match_operand 2 "const1_operand" ""))
11019 (const_string "alu")
11021 (const_string "ishift")))
11022 (set_attr "mode" "HI")])
11024 (define_insn "*ashlhi3_cconly"
11025 [(set (reg FLAGS_REG)
11027 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11028 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11030 (clobber (match_scratch:HI 0 "=r"))]
11031 "ix86_match_ccmode (insn, CCGOCmode)
11032 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11034 || !TARGET_PARTIAL_FLAG_REG_STALL
11035 || (operands[2] == const1_rtx
11037 || TARGET_DOUBLE_WITH_ADD)))"
11039 switch (get_attr_type (insn))
11042 gcc_assert (operands[2] == const1_rtx);
11043 return "add{w}\t%0, %0";
11046 if (REG_P (operands[2]))
11047 return "sal{w}\t{%b2, %0|%0, %b2}";
11048 else if (operands[2] == const1_rtx
11049 && (TARGET_SHIFT1 || optimize_size))
11050 return "sal{w}\t%0";
11052 return "sal{w}\t{%2, %0|%0, %2}";
11055 [(set (attr "type")
11056 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11058 (match_operand 0 "register_operand" ""))
11059 (match_operand 2 "const1_operand" ""))
11060 (const_string "alu")
11062 (const_string "ishift")))
11063 (set_attr "mode" "HI")])
11065 (define_expand "ashlqi3"
11066 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11067 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11068 (match_operand:QI 2 "nonmemory_operand" "")))
11069 (clobber (reg:CC FLAGS_REG))]
11070 "TARGET_QIMODE_MATH"
11071 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11073 ;; %%% Potential partial reg stall on alternative 2. What to do?
11075 (define_insn "*ashlqi3_1_lea"
11076 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11077 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11078 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11079 (clobber (reg:CC FLAGS_REG))]
11080 "!TARGET_PARTIAL_REG_STALL
11081 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11083 switch (get_attr_type (insn))
11088 gcc_assert (operands[2] == const1_rtx);
11089 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11090 return "add{l}\t%k0, %k0";
11092 return "add{b}\t%0, %0";
11095 if (REG_P (operands[2]))
11097 if (get_attr_mode (insn) == MODE_SI)
11098 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11100 return "sal{b}\t{%b2, %0|%0, %b2}";
11102 else if (operands[2] == const1_rtx
11103 && (TARGET_SHIFT1 || optimize_size))
11105 if (get_attr_mode (insn) == MODE_SI)
11106 return "sal{l}\t%0";
11108 return "sal{b}\t%0";
11112 if (get_attr_mode (insn) == MODE_SI)
11113 return "sal{l}\t{%2, %k0|%k0, %2}";
11115 return "sal{b}\t{%2, %0|%0, %2}";
11119 [(set (attr "type")
11120 (cond [(eq_attr "alternative" "2")
11121 (const_string "lea")
11122 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11124 (match_operand 0 "register_operand" ""))
11125 (match_operand 2 "const1_operand" ""))
11126 (const_string "alu")
11128 (const_string "ishift")))
11129 (set_attr "mode" "QI,SI,SI")])
11131 (define_insn "*ashlqi3_1"
11132 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11133 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11134 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11135 (clobber (reg:CC FLAGS_REG))]
11136 "TARGET_PARTIAL_REG_STALL
11137 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11139 switch (get_attr_type (insn))
11142 gcc_assert (operands[2] == const1_rtx);
11143 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11144 return "add{l}\t%k0, %k0";
11146 return "add{b}\t%0, %0";
11149 if (REG_P (operands[2]))
11151 if (get_attr_mode (insn) == MODE_SI)
11152 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11154 return "sal{b}\t{%b2, %0|%0, %b2}";
11156 else if (operands[2] == const1_rtx
11157 && (TARGET_SHIFT1 || optimize_size))
11159 if (get_attr_mode (insn) == MODE_SI)
11160 return "sal{l}\t%0";
11162 return "sal{b}\t%0";
11166 if (get_attr_mode (insn) == MODE_SI)
11167 return "sal{l}\t{%2, %k0|%k0, %2}";
11169 return "sal{b}\t{%2, %0|%0, %2}";
11173 [(set (attr "type")
11174 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11176 (match_operand 0 "register_operand" ""))
11177 (match_operand 2 "const1_operand" ""))
11178 (const_string "alu")
11180 (const_string "ishift")))
11181 (set_attr "mode" "QI,SI")])
11183 ;; This pattern can't accept a variable shift count, since shifts by
11184 ;; zero don't affect the flags. We assume that shifts by constant
11185 ;; zero are optimized away.
11186 (define_insn "*ashlqi3_cmp"
11187 [(set (reg FLAGS_REG)
11189 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11190 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11192 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11193 (ashift:QI (match_dup 1) (match_dup 2)))]
11194 "ix86_match_ccmode (insn, CCGOCmode)
11195 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11197 || !TARGET_PARTIAL_FLAG_REG_STALL
11198 || (operands[2] == const1_rtx
11200 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11202 switch (get_attr_type (insn))
11205 gcc_assert (operands[2] == const1_rtx);
11206 return "add{b}\t%0, %0";
11209 if (REG_P (operands[2]))
11210 return "sal{b}\t{%b2, %0|%0, %b2}";
11211 else if (operands[2] == const1_rtx
11212 && (TARGET_SHIFT1 || optimize_size))
11213 return "sal{b}\t%0";
11215 return "sal{b}\t{%2, %0|%0, %2}";
11218 [(set (attr "type")
11219 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11221 (match_operand 0 "register_operand" ""))
11222 (match_operand 2 "const1_operand" ""))
11223 (const_string "alu")
11225 (const_string "ishift")))
11226 (set_attr "mode" "QI")])
11228 (define_insn "*ashlqi3_cconly"
11229 [(set (reg FLAGS_REG)
11231 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11232 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11234 (clobber (match_scratch:QI 0 "=q"))]
11235 "ix86_match_ccmode (insn, CCGOCmode)
11236 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11238 || !TARGET_PARTIAL_FLAG_REG_STALL
11239 || (operands[2] == const1_rtx
11241 || TARGET_DOUBLE_WITH_ADD)))"
11243 switch (get_attr_type (insn))
11246 gcc_assert (operands[2] == const1_rtx);
11247 return "add{b}\t%0, %0";
11250 if (REG_P (operands[2]))
11251 return "sal{b}\t{%b2, %0|%0, %b2}";
11252 else if (operands[2] == const1_rtx
11253 && (TARGET_SHIFT1 || optimize_size))
11254 return "sal{b}\t%0";
11256 return "sal{b}\t{%2, %0|%0, %2}";
11259 [(set (attr "type")
11260 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11262 (match_operand 0 "register_operand" ""))
11263 (match_operand 2 "const1_operand" ""))
11264 (const_string "alu")
11266 (const_string "ishift")))
11267 (set_attr "mode" "QI")])
11269 ;; See comment above `ashldi3' about how this works.
11271 (define_expand "ashrti3"
11272 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11273 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11274 (match_operand:QI 2 "nonmemory_operand" "")))
11275 (clobber (reg:CC FLAGS_REG))])]
11278 if (! immediate_operand (operands[2], QImode))
11280 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11283 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11287 (define_insn "ashrti3_1"
11288 [(set (match_operand:TI 0 "register_operand" "=r")
11289 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11290 (match_operand:QI 2 "register_operand" "c")))
11291 (clobber (match_scratch:DI 3 "=&r"))
11292 (clobber (reg:CC FLAGS_REG))]
11295 [(set_attr "type" "multi")])
11297 (define_insn "*ashrti3_2"
11298 [(set (match_operand:TI 0 "register_operand" "=r")
11299 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11300 (match_operand:QI 2 "immediate_operand" "O")))
11301 (clobber (reg:CC FLAGS_REG))]
11304 [(set_attr "type" "multi")])
11307 [(set (match_operand:TI 0 "register_operand" "")
11308 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11309 (match_operand:QI 2 "register_operand" "")))
11310 (clobber (match_scratch:DI 3 ""))
11311 (clobber (reg:CC FLAGS_REG))]
11312 "TARGET_64BIT && reload_completed"
11314 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11317 [(set (match_operand:TI 0 "register_operand" "")
11318 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11319 (match_operand:QI 2 "immediate_operand" "")))
11320 (clobber (reg:CC FLAGS_REG))]
11321 "TARGET_64BIT && reload_completed"
11323 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11325 (define_insn "x86_64_shrd"
11326 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11327 (ior:DI (ashiftrt:DI (match_dup 0)
11328 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11329 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11330 (minus:QI (const_int 64) (match_dup 2)))))
11331 (clobber (reg:CC FLAGS_REG))]
11334 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11335 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11336 [(set_attr "type" "ishift")
11337 (set_attr "prefix_0f" "1")
11338 (set_attr "mode" "DI")
11339 (set_attr "athlon_decode" "vector")
11340 (set_attr "amdfam10_decode" "vector")])
11342 (define_expand "ashrdi3"
11343 [(set (match_operand:DI 0 "shiftdi_operand" "")
11344 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11345 (match_operand:QI 2 "nonmemory_operand" "")))]
11347 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11349 (define_insn "*ashrdi3_63_rex64"
11350 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11351 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11352 (match_operand:DI 2 "const_int_operand" "i,i")))
11353 (clobber (reg:CC FLAGS_REG))]
11354 "TARGET_64BIT && INTVAL (operands[2]) == 63
11355 && (TARGET_USE_CLTD || optimize_size)
11356 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11359 sar{q}\t{%2, %0|%0, %2}"
11360 [(set_attr "type" "imovx,ishift")
11361 (set_attr "prefix_0f" "0,*")
11362 (set_attr "length_immediate" "0,*")
11363 (set_attr "modrm" "0,1")
11364 (set_attr "mode" "DI")])
11366 (define_insn "*ashrdi3_1_one_bit_rex64"
11367 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11368 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11369 (match_operand:QI 2 "const1_operand" "")))
11370 (clobber (reg:CC FLAGS_REG))]
11371 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11372 && (TARGET_SHIFT1 || optimize_size)"
11374 [(set_attr "type" "ishift")
11375 (set (attr "length")
11376 (if_then_else (match_operand:DI 0 "register_operand" "")
11378 (const_string "*")))])
11380 (define_insn "*ashrdi3_1_rex64"
11381 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11382 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11383 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11384 (clobber (reg:CC FLAGS_REG))]
11385 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11387 sar{q}\t{%2, %0|%0, %2}
11388 sar{q}\t{%b2, %0|%0, %b2}"
11389 [(set_attr "type" "ishift")
11390 (set_attr "mode" "DI")])
11392 ;; This pattern can't accept a variable shift count, since shifts by
11393 ;; zero don't affect the flags. We assume that shifts by constant
11394 ;; zero are optimized away.
11395 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11396 [(set (reg FLAGS_REG)
11398 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11399 (match_operand:QI 2 "const1_operand" ""))
11401 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11402 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11403 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11404 && (TARGET_SHIFT1 || optimize_size)
11405 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11407 [(set_attr "type" "ishift")
11408 (set (attr "length")
11409 (if_then_else (match_operand:DI 0 "register_operand" "")
11411 (const_string "*")))])
11413 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11414 [(set (reg FLAGS_REG)
11416 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11417 (match_operand:QI 2 "const1_operand" ""))
11419 (clobber (match_scratch:DI 0 "=r"))]
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" "2")])
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags. We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*ashrdi3_cmp_rex64"
11431 [(set (reg FLAGS_REG)
11433 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434 (match_operand:QI 2 "const_int_operand" "n"))
11436 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11437 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11438 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11441 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11442 "sar{q}\t{%2, %0|%0, %2}"
11443 [(set_attr "type" "ishift")
11444 (set_attr "mode" "DI")])
11446 (define_insn "*ashrdi3_cconly_rex64"
11447 [(set (reg FLAGS_REG)
11449 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11450 (match_operand:QI 2 "const_int_operand" "n"))
11452 (clobber (match_scratch:DI 0 "=r"))]
11453 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11454 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11456 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11457 "sar{q}\t{%2, %0|%0, %2}"
11458 [(set_attr "type" "ishift")
11459 (set_attr "mode" "DI")])
11461 (define_insn "*ashrdi3_1"
11462 [(set (match_operand:DI 0 "register_operand" "=r")
11463 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11464 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11465 (clobber (reg:CC FLAGS_REG))]
11468 [(set_attr "type" "multi")])
11470 ;; By default we don't ask for a scratch register, because when DImode
11471 ;; values are manipulated, registers are already at a premium. But if
11472 ;; we have one handy, we won't turn it away.
11474 [(match_scratch:SI 3 "r")
11475 (parallel [(set (match_operand:DI 0 "register_operand" "")
11476 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11477 (match_operand:QI 2 "nonmemory_operand" "")))
11478 (clobber (reg:CC FLAGS_REG))])
11480 "!TARGET_64BIT && TARGET_CMOVE"
11482 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11485 [(set (match_operand:DI 0 "register_operand" "")
11486 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11487 (match_operand:QI 2 "nonmemory_operand" "")))
11488 (clobber (reg:CC FLAGS_REG))]
11489 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11490 ? flow2_completed : reload_completed)"
11492 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11494 (define_insn "x86_shrd_1"
11495 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11496 (ior:SI (ashiftrt:SI (match_dup 0)
11497 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11498 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11499 (minus:QI (const_int 32) (match_dup 2)))))
11500 (clobber (reg:CC FLAGS_REG))]
11503 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11504 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11505 [(set_attr "type" "ishift")
11506 (set_attr "prefix_0f" "1")
11507 (set_attr "pent_pair" "np")
11508 (set_attr "mode" "SI")])
11510 (define_expand "x86_shift_adj_3"
11511 [(use (match_operand:SI 0 "register_operand" ""))
11512 (use (match_operand:SI 1 "register_operand" ""))
11513 (use (match_operand:QI 2 "register_operand" ""))]
11516 rtx label = gen_label_rtx ();
11519 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11521 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11522 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11523 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11524 gen_rtx_LABEL_REF (VOIDmode, label),
11526 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11527 JUMP_LABEL (tmp) = label;
11529 emit_move_insn (operands[0], operands[1]);
11530 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11532 emit_label (label);
11533 LABEL_NUSES (label) = 1;
11538 (define_insn "ashrsi3_31"
11539 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11540 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11541 (match_operand:SI 2 "const_int_operand" "i,i")))
11542 (clobber (reg:CC FLAGS_REG))]
11543 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11544 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11547 sar{l}\t{%2, %0|%0, %2}"
11548 [(set_attr "type" "imovx,ishift")
11549 (set_attr "prefix_0f" "0,*")
11550 (set_attr "length_immediate" "0,*")
11551 (set_attr "modrm" "0,1")
11552 (set_attr "mode" "SI")])
11554 (define_insn "*ashrsi3_31_zext"
11555 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11556 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11557 (match_operand:SI 2 "const_int_operand" "i,i"))))
11558 (clobber (reg:CC FLAGS_REG))]
11559 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11560 && INTVAL (operands[2]) == 31
11561 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11564 sar{l}\t{%2, %k0|%k0, %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_expand "ashrsi3"
11572 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11573 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11574 (match_operand:QI 2 "nonmemory_operand" "")))
11575 (clobber (reg:CC FLAGS_REG))]
11577 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11579 (define_insn "*ashrsi3_1_one_bit"
11580 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11581 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11582 (match_operand:QI 2 "const1_operand" "")))
11583 (clobber (reg:CC FLAGS_REG))]
11584 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11585 && (TARGET_SHIFT1 || optimize_size)"
11587 [(set_attr "type" "ishift")
11588 (set (attr "length")
11589 (if_then_else (match_operand:SI 0 "register_operand" "")
11591 (const_string "*")))])
11593 (define_insn "*ashrsi3_1_one_bit_zext"
11594 [(set (match_operand:DI 0 "register_operand" "=r")
11595 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11596 (match_operand:QI 2 "const1_operand" ""))))
11597 (clobber (reg:CC FLAGS_REG))]
11598 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11599 && (TARGET_SHIFT1 || optimize_size)"
11601 [(set_attr "type" "ishift")
11602 (set_attr "length" "2")])
11604 (define_insn "*ashrsi3_1"
11605 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11606 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11607 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11608 (clobber (reg:CC FLAGS_REG))]
11609 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11611 sar{l}\t{%2, %0|%0, %2}
11612 sar{l}\t{%b2, %0|%0, %b2}"
11613 [(set_attr "type" "ishift")
11614 (set_attr "mode" "SI")])
11616 (define_insn "*ashrsi3_1_zext"
11617 [(set (match_operand:DI 0 "register_operand" "=r,r")
11618 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11619 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11620 (clobber (reg:CC FLAGS_REG))]
11621 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11623 sar{l}\t{%2, %k0|%k0, %2}
11624 sar{l}\t{%b2, %k0|%k0, %b2}"
11625 [(set_attr "type" "ishift")
11626 (set_attr "mode" "SI")])
11628 ;; This pattern can't accept a variable shift count, since shifts by
11629 ;; zero don't affect the flags. We assume that shifts by constant
11630 ;; zero are optimized away.
11631 (define_insn "*ashrsi3_one_bit_cmp"
11632 [(set (reg FLAGS_REG)
11634 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11635 (match_operand:QI 2 "const1_operand" ""))
11637 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11638 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11639 "ix86_match_ccmode (insn, CCGOCmode)
11640 && (TARGET_SHIFT1 || optimize_size)
11641 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11643 [(set_attr "type" "ishift")
11644 (set (attr "length")
11645 (if_then_else (match_operand:SI 0 "register_operand" "")
11647 (const_string "*")))])
11649 (define_insn "*ashrsi3_one_bit_cconly"
11650 [(set (reg FLAGS_REG)
11652 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11653 (match_operand:QI 2 "const1_operand" ""))
11655 (clobber (match_scratch:SI 0 "=r"))]
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" "2")])
11663 (define_insn "*ashrsi3_one_bit_cmp_zext"
11664 [(set (reg FLAGS_REG)
11666 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11667 (match_operand:QI 2 "const1_operand" ""))
11669 (set (match_operand:DI 0 "register_operand" "=r")
11670 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11671 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11672 && (TARGET_SHIFT1 || optimize_size)
11673 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11675 [(set_attr "type" "ishift")
11676 (set_attr "length" "2")])
11678 ;; This pattern can't accept a variable shift count, since shifts by
11679 ;; zero don't affect the flags. We assume that shifts by constant
11680 ;; zero are optimized away.
11681 (define_insn "*ashrsi3_cmp"
11682 [(set (reg FLAGS_REG)
11684 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11685 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11687 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11688 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11689 "ix86_match_ccmode (insn, CCGOCmode)
11690 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11692 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11693 "sar{l}\t{%2, %0|%0, %2}"
11694 [(set_attr "type" "ishift")
11695 (set_attr "mode" "SI")])
11697 (define_insn "*ashrsi3_cconly"
11698 [(set (reg FLAGS_REG)
11700 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11701 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11703 (clobber (match_scratch:SI 0 "=r"))]
11704 "ix86_match_ccmode (insn, CCGOCmode)
11705 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11707 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11708 "sar{l}\t{%2, %0|%0, %2}"
11709 [(set_attr "type" "ishift")
11710 (set_attr "mode" "SI")])
11712 (define_insn "*ashrsi3_cmp_zext"
11713 [(set (reg FLAGS_REG)
11715 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11716 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11718 (set (match_operand:DI 0 "register_operand" "=r")
11719 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11720 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11721 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11723 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11724 "sar{l}\t{%2, %k0|%k0, %2}"
11725 [(set_attr "type" "ishift")
11726 (set_attr "mode" "SI")])
11728 (define_expand "ashrhi3"
11729 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11730 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11731 (match_operand:QI 2 "nonmemory_operand" "")))
11732 (clobber (reg:CC FLAGS_REG))]
11733 "TARGET_HIMODE_MATH"
11734 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11736 (define_insn "*ashrhi3_1_one_bit"
11737 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11738 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11739 (match_operand:QI 2 "const1_operand" "")))
11740 (clobber (reg:CC FLAGS_REG))]
11741 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11742 && (TARGET_SHIFT1 || optimize_size)"
11744 [(set_attr "type" "ishift")
11745 (set (attr "length")
11746 (if_then_else (match_operand 0 "register_operand" "")
11748 (const_string "*")))])
11750 (define_insn "*ashrhi3_1"
11751 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11752 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11753 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11754 (clobber (reg:CC FLAGS_REG))]
11755 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11757 sar{w}\t{%2, %0|%0, %2}
11758 sar{w}\t{%b2, %0|%0, %b2}"
11759 [(set_attr "type" "ishift")
11760 (set_attr "mode" "HI")])
11762 ;; This pattern can't accept a variable shift count, since shifts by
11763 ;; zero don't affect the flags. We assume that shifts by constant
11764 ;; zero are optimized away.
11765 (define_insn "*ashrhi3_one_bit_cmp"
11766 [(set (reg FLAGS_REG)
11768 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11769 (match_operand:QI 2 "const1_operand" ""))
11771 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11772 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11773 "ix86_match_ccmode (insn, CCGOCmode)
11774 && (TARGET_SHIFT1 || optimize_size)
11775 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11777 [(set_attr "type" "ishift")
11778 (set (attr "length")
11779 (if_then_else (match_operand 0 "register_operand" "")
11781 (const_string "*")))])
11783 (define_insn "*ashrhi3_one_bit_cconly"
11784 [(set (reg FLAGS_REG)
11786 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11787 (match_operand:QI 2 "const1_operand" ""))
11789 (clobber (match_scratch:HI 0 "=r"))]
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" "2")])
11797 ;; This pattern can't accept a variable shift count, since shifts by
11798 ;; zero don't affect the flags. We assume that shifts by constant
11799 ;; zero are optimized away.
11800 (define_insn "*ashrhi3_cmp"
11801 [(set (reg FLAGS_REG)
11803 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11804 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11806 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11807 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11808 "ix86_match_ccmode (insn, CCGOCmode)
11809 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11811 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11812 "sar{w}\t{%2, %0|%0, %2}"
11813 [(set_attr "type" "ishift")
11814 (set_attr "mode" "HI")])
11816 (define_insn "*ashrhi3_cconly"
11817 [(set (reg FLAGS_REG)
11819 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11820 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11822 (clobber (match_scratch:HI 0 "=r"))]
11823 "ix86_match_ccmode (insn, CCGOCmode)
11824 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11826 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11827 "sar{w}\t{%2, %0|%0, %2}"
11828 [(set_attr "type" "ishift")
11829 (set_attr "mode" "HI")])
11831 (define_expand "ashrqi3"
11832 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11833 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11834 (match_operand:QI 2 "nonmemory_operand" "")))
11835 (clobber (reg:CC FLAGS_REG))]
11836 "TARGET_QIMODE_MATH"
11837 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11839 (define_insn "*ashrqi3_1_one_bit"
11840 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11841 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11842 (match_operand:QI 2 "const1_operand" "")))
11843 (clobber (reg:CC FLAGS_REG))]
11844 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11845 && (TARGET_SHIFT1 || optimize_size)"
11847 [(set_attr "type" "ishift")
11848 (set (attr "length")
11849 (if_then_else (match_operand 0 "register_operand" "")
11851 (const_string "*")))])
11853 (define_insn "*ashrqi3_1_one_bit_slp"
11854 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11855 (ashiftrt:QI (match_dup 0)
11856 (match_operand:QI 1 "const1_operand" "")))
11857 (clobber (reg:CC FLAGS_REG))]
11858 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11859 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11860 && (TARGET_SHIFT1 || optimize_size)"
11862 [(set_attr "type" "ishift1")
11863 (set (attr "length")
11864 (if_then_else (match_operand 0 "register_operand" "")
11866 (const_string "*")))])
11868 (define_insn "*ashrqi3_1"
11869 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11870 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11871 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11872 (clobber (reg:CC FLAGS_REG))]
11873 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11875 sar{b}\t{%2, %0|%0, %2}
11876 sar{b}\t{%b2, %0|%0, %b2}"
11877 [(set_attr "type" "ishift")
11878 (set_attr "mode" "QI")])
11880 (define_insn "*ashrqi3_1_slp"
11881 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11882 (ashiftrt:QI (match_dup 0)
11883 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11884 (clobber (reg:CC FLAGS_REG))]
11885 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11886 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11888 sar{b}\t{%1, %0|%0, %1}
11889 sar{b}\t{%b1, %0|%0, %b1}"
11890 [(set_attr "type" "ishift1")
11891 (set_attr "mode" "QI")])
11893 ;; This pattern can't accept a variable shift count, since shifts by
11894 ;; zero don't affect the flags. We assume that shifts by constant
11895 ;; zero are optimized away.
11896 (define_insn "*ashrqi3_one_bit_cmp"
11897 [(set (reg FLAGS_REG)
11899 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11900 (match_operand:QI 2 "const1_operand" "I"))
11902 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11903 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11904 "ix86_match_ccmode (insn, CCGOCmode)
11905 && (TARGET_SHIFT1 || optimize_size)
11906 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11908 [(set_attr "type" "ishift")
11909 (set (attr "length")
11910 (if_then_else (match_operand 0 "register_operand" "")
11912 (const_string "*")))])
11914 (define_insn "*ashrqi3_one_bit_cconly"
11915 [(set (reg FLAGS_REG)
11917 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11918 (match_operand:QI 2 "const1_operand" "I"))
11920 (clobber (match_scratch:QI 0 "=q"))]
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" "2")])
11928 ;; This pattern can't accept a variable shift count, since shifts by
11929 ;; zero don't affect the flags. We assume that shifts by constant
11930 ;; zero are optimized away.
11931 (define_insn "*ashrqi3_cmp"
11932 [(set (reg FLAGS_REG)
11934 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11935 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11937 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11938 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11939 "ix86_match_ccmode (insn, CCGOCmode)
11940 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11942 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11943 "sar{b}\t{%2, %0|%0, %2}"
11944 [(set_attr "type" "ishift")
11945 (set_attr "mode" "QI")])
11947 (define_insn "*ashrqi3_cconly"
11948 [(set (reg FLAGS_REG)
11950 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11951 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11953 (clobber (match_scratch:QI 0 "=q"))]
11954 "ix86_match_ccmode (insn, CCGOCmode)
11955 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11957 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11958 "sar{b}\t{%2, %0|%0, %2}"
11959 [(set_attr "type" "ishift")
11960 (set_attr "mode" "QI")])
11963 ;; Logical shift instructions
11965 ;; See comment above `ashldi3' about how this works.
11967 (define_expand "lshrti3"
11968 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11969 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11970 (match_operand:QI 2 "nonmemory_operand" "")))
11971 (clobber (reg:CC FLAGS_REG))])]
11974 if (! immediate_operand (operands[2], QImode))
11976 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11979 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11983 (define_insn "lshrti3_1"
11984 [(set (match_operand:TI 0 "register_operand" "=r")
11985 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11986 (match_operand:QI 2 "register_operand" "c")))
11987 (clobber (match_scratch:DI 3 "=&r"))
11988 (clobber (reg:CC FLAGS_REG))]
11991 [(set_attr "type" "multi")])
11993 (define_insn "*lshrti3_2"
11994 [(set (match_operand:TI 0 "register_operand" "=r")
11995 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11996 (match_operand:QI 2 "immediate_operand" "O")))
11997 (clobber (reg:CC FLAGS_REG))]
12000 [(set_attr "type" "multi")])
12003 [(set (match_operand:TI 0 "register_operand" "")
12004 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12005 (match_operand:QI 2 "register_operand" "")))
12006 (clobber (match_scratch:DI 3 ""))
12007 (clobber (reg:CC FLAGS_REG))]
12008 "TARGET_64BIT && reload_completed"
12010 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12013 [(set (match_operand:TI 0 "register_operand" "")
12014 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12015 (match_operand:QI 2 "immediate_operand" "")))
12016 (clobber (reg:CC FLAGS_REG))]
12017 "TARGET_64BIT && reload_completed"
12019 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12021 (define_expand "lshrdi3"
12022 [(set (match_operand:DI 0 "shiftdi_operand" "")
12023 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12024 (match_operand:QI 2 "nonmemory_operand" "")))]
12026 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12028 (define_insn "*lshrdi3_1_one_bit_rex64"
12029 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12030 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12031 (match_operand:QI 2 "const1_operand" "")))
12032 (clobber (reg:CC FLAGS_REG))]
12033 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12034 && (TARGET_SHIFT1 || optimize_size)"
12036 [(set_attr "type" "ishift")
12037 (set (attr "length")
12038 (if_then_else (match_operand:DI 0 "register_operand" "")
12040 (const_string "*")))])
12042 (define_insn "*lshrdi3_1_rex64"
12043 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12044 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12045 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12046 (clobber (reg:CC FLAGS_REG))]
12047 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12049 shr{q}\t{%2, %0|%0, %2}
12050 shr{q}\t{%b2, %0|%0, %b2}"
12051 [(set_attr "type" "ishift")
12052 (set_attr "mode" "DI")])
12054 ;; This pattern can't accept a variable shift count, since shifts by
12055 ;; zero don't affect the flags. We assume that shifts by constant
12056 ;; zero are optimized away.
12057 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12058 [(set (reg FLAGS_REG)
12060 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12061 (match_operand:QI 2 "const1_operand" ""))
12063 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12064 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12065 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12066 && (TARGET_SHIFT1 || optimize_size)
12067 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12069 [(set_attr "type" "ishift")
12070 (set (attr "length")
12071 (if_then_else (match_operand:DI 0 "register_operand" "")
12073 (const_string "*")))])
12075 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12076 [(set (reg FLAGS_REG)
12078 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12079 (match_operand:QI 2 "const1_operand" ""))
12081 (clobber (match_scratch:DI 0 "=r"))]
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" "2")])
12089 ;; This pattern can't accept a variable shift count, since shifts by
12090 ;; zero don't affect the flags. We assume that shifts by constant
12091 ;; zero are optimized away.
12092 (define_insn "*lshrdi3_cmp_rex64"
12093 [(set (reg FLAGS_REG)
12095 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12096 (match_operand:QI 2 "const_int_operand" "e"))
12098 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12099 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12100 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12101 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12103 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12104 "shr{q}\t{%2, %0|%0, %2}"
12105 [(set_attr "type" "ishift")
12106 (set_attr "mode" "DI")])
12108 (define_insn "*lshrdi3_cconly_rex64"
12109 [(set (reg FLAGS_REG)
12111 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12112 (match_operand:QI 2 "const_int_operand" "e"))
12114 (clobber (match_scratch:DI 0 "=r"))]
12115 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12116 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12118 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12119 "shr{q}\t{%2, %0|%0, %2}"
12120 [(set_attr "type" "ishift")
12121 (set_attr "mode" "DI")])
12123 (define_insn "*lshrdi3_1"
12124 [(set (match_operand:DI 0 "register_operand" "=r")
12125 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12126 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12127 (clobber (reg:CC FLAGS_REG))]
12130 [(set_attr "type" "multi")])
12132 ;; By default we don't ask for a scratch register, because when DImode
12133 ;; values are manipulated, registers are already at a premium. But if
12134 ;; we have one handy, we won't turn it away.
12136 [(match_scratch:SI 3 "r")
12137 (parallel [(set (match_operand:DI 0 "register_operand" "")
12138 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12139 (match_operand:QI 2 "nonmemory_operand" "")))
12140 (clobber (reg:CC FLAGS_REG))])
12142 "!TARGET_64BIT && TARGET_CMOVE"
12144 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12147 [(set (match_operand:DI 0 "register_operand" "")
12148 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12149 (match_operand:QI 2 "nonmemory_operand" "")))
12150 (clobber (reg:CC FLAGS_REG))]
12151 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12152 ? flow2_completed : reload_completed)"
12154 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12156 (define_expand "lshrsi3"
12157 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12158 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12159 (match_operand:QI 2 "nonmemory_operand" "")))
12160 (clobber (reg:CC FLAGS_REG))]
12162 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12164 (define_insn "*lshrsi3_1_one_bit"
12165 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12166 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12167 (match_operand:QI 2 "const1_operand" "")))
12168 (clobber (reg:CC FLAGS_REG))]
12169 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12170 && (TARGET_SHIFT1 || optimize_size)"
12172 [(set_attr "type" "ishift")
12173 (set (attr "length")
12174 (if_then_else (match_operand:SI 0 "register_operand" "")
12176 (const_string "*")))])
12178 (define_insn "*lshrsi3_1_one_bit_zext"
12179 [(set (match_operand:DI 0 "register_operand" "=r")
12180 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12181 (match_operand:QI 2 "const1_operand" "")))
12182 (clobber (reg:CC FLAGS_REG))]
12183 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12184 && (TARGET_SHIFT1 || optimize_size)"
12186 [(set_attr "type" "ishift")
12187 (set_attr "length" "2")])
12189 (define_insn "*lshrsi3_1"
12190 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12191 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12192 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12193 (clobber (reg:CC FLAGS_REG))]
12194 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12196 shr{l}\t{%2, %0|%0, %2}
12197 shr{l}\t{%b2, %0|%0, %b2}"
12198 [(set_attr "type" "ishift")
12199 (set_attr "mode" "SI")])
12201 (define_insn "*lshrsi3_1_zext"
12202 [(set (match_operand:DI 0 "register_operand" "=r,r")
12204 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12205 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12206 (clobber (reg:CC FLAGS_REG))]
12207 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12209 shr{l}\t{%2, %k0|%k0, %2}
12210 shr{l}\t{%b2, %k0|%k0, %b2}"
12211 [(set_attr "type" "ishift")
12212 (set_attr "mode" "SI")])
12214 ;; This pattern can't accept a variable shift count, since shifts by
12215 ;; zero don't affect the flags. We assume that shifts by constant
12216 ;; zero are optimized away.
12217 (define_insn "*lshrsi3_one_bit_cmp"
12218 [(set (reg FLAGS_REG)
12220 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12221 (match_operand:QI 2 "const1_operand" ""))
12223 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12224 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12225 "ix86_match_ccmode (insn, CCGOCmode)
12226 && (TARGET_SHIFT1 || optimize_size)
12227 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12229 [(set_attr "type" "ishift")
12230 (set (attr "length")
12231 (if_then_else (match_operand:SI 0 "register_operand" "")
12233 (const_string "*")))])
12235 (define_insn "*lshrsi3_one_bit_cconly"
12236 [(set (reg FLAGS_REG)
12238 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12239 (match_operand:QI 2 "const1_operand" ""))
12241 (clobber (match_scratch:SI 0 "=r"))]
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" "2")])
12249 (define_insn "*lshrsi3_cmp_one_bit_zext"
12250 [(set (reg FLAGS_REG)
12252 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12253 (match_operand:QI 2 "const1_operand" ""))
12255 (set (match_operand:DI 0 "register_operand" "=r")
12256 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12257 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12258 && (TARGET_SHIFT1 || optimize_size)
12259 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12261 [(set_attr "type" "ishift")
12262 (set_attr "length" "2")])
12264 ;; This pattern can't accept a variable shift count, since shifts by
12265 ;; zero don't affect the flags. We assume that shifts by constant
12266 ;; zero are optimized away.
12267 (define_insn "*lshrsi3_cmp"
12268 [(set (reg FLAGS_REG)
12270 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12271 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12273 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12274 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12275 "ix86_match_ccmode (insn, CCGOCmode)
12276 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12278 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12279 "shr{l}\t{%2, %0|%0, %2}"
12280 [(set_attr "type" "ishift")
12281 (set_attr "mode" "SI")])
12283 (define_insn "*lshrsi3_cconly"
12284 [(set (reg FLAGS_REG)
12286 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12287 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12289 (clobber (match_scratch:SI 0 "=r"))]
12290 "ix86_match_ccmode (insn, CCGOCmode)
12291 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12293 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12294 "shr{l}\t{%2, %0|%0, %2}"
12295 [(set_attr "type" "ishift")
12296 (set_attr "mode" "SI")])
12298 (define_insn "*lshrsi3_cmp_zext"
12299 [(set (reg FLAGS_REG)
12301 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12302 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12304 (set (match_operand:DI 0 "register_operand" "=r")
12305 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12306 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12307 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12309 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12310 "shr{l}\t{%2, %k0|%k0, %2}"
12311 [(set_attr "type" "ishift")
12312 (set_attr "mode" "SI")])
12314 (define_expand "lshrhi3"
12315 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12316 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12317 (match_operand:QI 2 "nonmemory_operand" "")))
12318 (clobber (reg:CC FLAGS_REG))]
12319 "TARGET_HIMODE_MATH"
12320 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12322 (define_insn "*lshrhi3_1_one_bit"
12323 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12324 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12325 (match_operand:QI 2 "const1_operand" "")))
12326 (clobber (reg:CC FLAGS_REG))]
12327 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12328 && (TARGET_SHIFT1 || optimize_size)"
12330 [(set_attr "type" "ishift")
12331 (set (attr "length")
12332 (if_then_else (match_operand 0 "register_operand" "")
12334 (const_string "*")))])
12336 (define_insn "*lshrhi3_1"
12337 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12338 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12339 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12340 (clobber (reg:CC FLAGS_REG))]
12341 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12343 shr{w}\t{%2, %0|%0, %2}
12344 shr{w}\t{%b2, %0|%0, %b2}"
12345 [(set_attr "type" "ishift")
12346 (set_attr "mode" "HI")])
12348 ;; This pattern can't accept a variable shift count, since shifts by
12349 ;; zero don't affect the flags. We assume that shifts by constant
12350 ;; zero are optimized away.
12351 (define_insn "*lshrhi3_one_bit_cmp"
12352 [(set (reg FLAGS_REG)
12354 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12355 (match_operand:QI 2 "const1_operand" ""))
12357 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12358 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12359 "ix86_match_ccmode (insn, CCGOCmode)
12360 && (TARGET_SHIFT1 || optimize_size)
12361 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12363 [(set_attr "type" "ishift")
12364 (set (attr "length")
12365 (if_then_else (match_operand:SI 0 "register_operand" "")
12367 (const_string "*")))])
12369 (define_insn "*lshrhi3_one_bit_cconly"
12370 [(set (reg FLAGS_REG)
12372 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12373 (match_operand:QI 2 "const1_operand" ""))
12375 (clobber (match_scratch:HI 0 "=r"))]
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" "2")])
12383 ;; This pattern can't accept a variable shift count, since shifts by
12384 ;; zero don't affect the flags. We assume that shifts by constant
12385 ;; zero are optimized away.
12386 (define_insn "*lshrhi3_cmp"
12387 [(set (reg FLAGS_REG)
12389 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12390 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12392 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12393 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12394 "ix86_match_ccmode (insn, CCGOCmode)
12395 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12397 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12398 "shr{w}\t{%2, %0|%0, %2}"
12399 [(set_attr "type" "ishift")
12400 (set_attr "mode" "HI")])
12402 (define_insn "*lshrhi3_cconly"
12403 [(set (reg FLAGS_REG)
12405 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12406 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12408 (clobber (match_scratch:HI 0 "=r"))]
12409 "ix86_match_ccmode (insn, CCGOCmode)
12410 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12412 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12413 "shr{w}\t{%2, %0|%0, %2}"
12414 [(set_attr "type" "ishift")
12415 (set_attr "mode" "HI")])
12417 (define_expand "lshrqi3"
12418 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12419 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12420 (match_operand:QI 2 "nonmemory_operand" "")))
12421 (clobber (reg:CC FLAGS_REG))]
12422 "TARGET_QIMODE_MATH"
12423 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12425 (define_insn "*lshrqi3_1_one_bit"
12426 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12427 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12428 (match_operand:QI 2 "const1_operand" "")))
12429 (clobber (reg:CC FLAGS_REG))]
12430 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12431 && (TARGET_SHIFT1 || optimize_size)"
12433 [(set_attr "type" "ishift")
12434 (set (attr "length")
12435 (if_then_else (match_operand 0 "register_operand" "")
12437 (const_string "*")))])
12439 (define_insn "*lshrqi3_1_one_bit_slp"
12440 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12441 (lshiftrt:QI (match_dup 0)
12442 (match_operand:QI 1 "const1_operand" "")))
12443 (clobber (reg:CC FLAGS_REG))]
12444 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12445 && (TARGET_SHIFT1 || optimize_size)"
12447 [(set_attr "type" "ishift1")
12448 (set (attr "length")
12449 (if_then_else (match_operand 0 "register_operand" "")
12451 (const_string "*")))])
12453 (define_insn "*lshrqi3_1"
12454 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12455 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12456 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12460 shr{b}\t{%2, %0|%0, %2}
12461 shr{b}\t{%b2, %0|%0, %b2}"
12462 [(set_attr "type" "ishift")
12463 (set_attr "mode" "QI")])
12465 (define_insn "*lshrqi3_1_slp"
12466 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12467 (lshiftrt:QI (match_dup 0)
12468 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12469 (clobber (reg:CC FLAGS_REG))]
12470 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12471 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12473 shr{b}\t{%1, %0|%0, %1}
12474 shr{b}\t{%b1, %0|%0, %b1}"
12475 [(set_attr "type" "ishift1")
12476 (set_attr "mode" "QI")])
12478 ;; This pattern can't accept a variable shift count, since shifts by
12479 ;; zero don't affect the flags. We assume that shifts by constant
12480 ;; zero are optimized away.
12481 (define_insn "*lshrqi2_one_bit_cmp"
12482 [(set (reg FLAGS_REG)
12484 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12485 (match_operand:QI 2 "const1_operand" ""))
12487 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12488 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12489 "ix86_match_ccmode (insn, CCGOCmode)
12490 && (TARGET_SHIFT1 || optimize_size)
12491 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12493 [(set_attr "type" "ishift")
12494 (set (attr "length")
12495 (if_then_else (match_operand:SI 0 "register_operand" "")
12497 (const_string "*")))])
12499 (define_insn "*lshrqi2_one_bit_cconly"
12500 [(set (reg FLAGS_REG)
12502 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12503 (match_operand:QI 2 "const1_operand" ""))
12505 (clobber (match_scratch:QI 0 "=q"))]
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" "2")])
12513 ;; This pattern can't accept a variable shift count, since shifts by
12514 ;; zero don't affect the flags. We assume that shifts by constant
12515 ;; zero are optimized away.
12516 (define_insn "*lshrqi2_cmp"
12517 [(set (reg FLAGS_REG)
12519 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12520 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12522 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12523 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12524 "ix86_match_ccmode (insn, CCGOCmode)
12525 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12527 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12528 "shr{b}\t{%2, %0|%0, %2}"
12529 [(set_attr "type" "ishift")
12530 (set_attr "mode" "QI")])
12532 (define_insn "*lshrqi2_cconly"
12533 [(set (reg FLAGS_REG)
12535 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12536 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12538 (clobber (match_scratch:QI 0 "=q"))]
12539 "ix86_match_ccmode (insn, CCGOCmode)
12540 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12542 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12543 "shr{b}\t{%2, %0|%0, %2}"
12544 [(set_attr "type" "ishift")
12545 (set_attr "mode" "QI")])
12547 ;; Rotate instructions
12549 (define_expand "rotldi3"
12550 [(set (match_operand:DI 0 "shiftdi_operand" "")
12551 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12552 (match_operand:QI 2 "nonmemory_operand" "")))
12553 (clobber (reg:CC FLAGS_REG))]
12558 ix86_expand_binary_operator (ROTATE, DImode, operands);
12561 if (!const_1_to_31_operand (operands[2], VOIDmode))
12563 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12567 ;; Implement rotation using two double-precision shift instructions
12568 ;; and a scratch register.
12569 (define_insn_and_split "ix86_rotldi3"
12570 [(set (match_operand:DI 0 "register_operand" "=r")
12571 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12572 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12573 (clobber (reg:CC FLAGS_REG))
12574 (clobber (match_scratch:SI 3 "=&r"))]
12577 "&& reload_completed"
12578 [(set (match_dup 3) (match_dup 4))
12580 [(set (match_dup 4)
12581 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12582 (lshiftrt:SI (match_dup 5)
12583 (minus:QI (const_int 32) (match_dup 2)))))
12584 (clobber (reg:CC FLAGS_REG))])
12586 [(set (match_dup 5)
12587 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12588 (lshiftrt:SI (match_dup 3)
12589 (minus:QI (const_int 32) (match_dup 2)))))
12590 (clobber (reg:CC FLAGS_REG))])]
12591 "split_di (operands, 1, operands + 4, operands + 5);")
12593 (define_insn "*rotlsi3_1_one_bit_rex64"
12594 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12595 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12596 (match_operand:QI 2 "const1_operand" "")))
12597 (clobber (reg:CC FLAGS_REG))]
12598 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12599 && (TARGET_SHIFT1 || optimize_size)"
12601 [(set_attr "type" "rotate")
12602 (set (attr "length")
12603 (if_then_else (match_operand:DI 0 "register_operand" "")
12605 (const_string "*")))])
12607 (define_insn "*rotldi3_1_rex64"
12608 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12609 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12610 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12611 (clobber (reg:CC FLAGS_REG))]
12612 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12614 rol{q}\t{%2, %0|%0, %2}
12615 rol{q}\t{%b2, %0|%0, %b2}"
12616 [(set_attr "type" "rotate")
12617 (set_attr "mode" "DI")])
12619 (define_expand "rotlsi3"
12620 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12621 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12622 (match_operand:QI 2 "nonmemory_operand" "")))
12623 (clobber (reg:CC FLAGS_REG))]
12625 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12627 (define_insn "*rotlsi3_1_one_bit"
12628 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12629 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12630 (match_operand:QI 2 "const1_operand" "")))
12631 (clobber (reg:CC FLAGS_REG))]
12632 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12633 && (TARGET_SHIFT1 || optimize_size)"
12635 [(set_attr "type" "rotate")
12636 (set (attr "length")
12637 (if_then_else (match_operand:SI 0 "register_operand" "")
12639 (const_string "*")))])
12641 (define_insn "*rotlsi3_1_one_bit_zext"
12642 [(set (match_operand:DI 0 "register_operand" "=r")
12644 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12645 (match_operand:QI 2 "const1_operand" ""))))
12646 (clobber (reg:CC FLAGS_REG))]
12647 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12648 && (TARGET_SHIFT1 || optimize_size)"
12650 [(set_attr "type" "rotate")
12651 (set_attr "length" "2")])
12653 (define_insn "*rotlsi3_1"
12654 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12655 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12656 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12657 (clobber (reg:CC FLAGS_REG))]
12658 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12660 rol{l}\t{%2, %0|%0, %2}
12661 rol{l}\t{%b2, %0|%0, %b2}"
12662 [(set_attr "type" "rotate")
12663 (set_attr "mode" "SI")])
12665 (define_insn "*rotlsi3_1_zext"
12666 [(set (match_operand:DI 0 "register_operand" "=r,r")
12668 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12669 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12670 (clobber (reg:CC FLAGS_REG))]
12671 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12673 rol{l}\t{%2, %k0|%k0, %2}
12674 rol{l}\t{%b2, %k0|%k0, %b2}"
12675 [(set_attr "type" "rotate")
12676 (set_attr "mode" "SI")])
12678 (define_expand "rotlhi3"
12679 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12680 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12681 (match_operand:QI 2 "nonmemory_operand" "")))
12682 (clobber (reg:CC FLAGS_REG))]
12683 "TARGET_HIMODE_MATH"
12684 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12686 (define_insn "*rotlhi3_1_one_bit"
12687 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12688 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12689 (match_operand:QI 2 "const1_operand" "")))
12690 (clobber (reg:CC FLAGS_REG))]
12691 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12692 && (TARGET_SHIFT1 || optimize_size)"
12694 [(set_attr "type" "rotate")
12695 (set (attr "length")
12696 (if_then_else (match_operand 0 "register_operand" "")
12698 (const_string "*")))])
12700 (define_insn "*rotlhi3_1"
12701 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12702 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12703 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12704 (clobber (reg:CC FLAGS_REG))]
12705 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12707 rol{w}\t{%2, %0|%0, %2}
12708 rol{w}\t{%b2, %0|%0, %b2}"
12709 [(set_attr "type" "rotate")
12710 (set_attr "mode" "HI")])
12713 [(set (match_operand:HI 0 "register_operand" "")
12714 (rotate:HI (match_dup 0) (const_int 8)))
12715 (clobber (reg:CC FLAGS_REG))]
12717 [(parallel [(set (strict_low_part (match_dup 0))
12718 (bswap:HI (match_dup 0)))
12719 (clobber (reg:CC FLAGS_REG))])]
12722 (define_expand "rotlqi3"
12723 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12724 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12725 (match_operand:QI 2 "nonmemory_operand" "")))
12726 (clobber (reg:CC FLAGS_REG))]
12727 "TARGET_QIMODE_MATH"
12728 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12730 (define_insn "*rotlqi3_1_one_bit_slp"
12731 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12732 (rotate:QI (match_dup 0)
12733 (match_operand:QI 1 "const1_operand" "")))
12734 (clobber (reg:CC FLAGS_REG))]
12735 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12736 && (TARGET_SHIFT1 || optimize_size)"
12738 [(set_attr "type" "rotate1")
12739 (set (attr "length")
12740 (if_then_else (match_operand 0 "register_operand" "")
12742 (const_string "*")))])
12744 (define_insn "*rotlqi3_1_one_bit"
12745 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12746 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12747 (match_operand:QI 2 "const1_operand" "")))
12748 (clobber (reg:CC FLAGS_REG))]
12749 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12750 && (TARGET_SHIFT1 || optimize_size)"
12752 [(set_attr "type" "rotate")
12753 (set (attr "length")
12754 (if_then_else (match_operand 0 "register_operand" "")
12756 (const_string "*")))])
12758 (define_insn "*rotlqi3_1_slp"
12759 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12760 (rotate:QI (match_dup 0)
12761 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12762 (clobber (reg:CC FLAGS_REG))]
12763 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12764 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12766 rol{b}\t{%1, %0|%0, %1}
12767 rol{b}\t{%b1, %0|%0, %b1}"
12768 [(set_attr "type" "rotate1")
12769 (set_attr "mode" "QI")])
12771 (define_insn "*rotlqi3_1"
12772 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12773 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12774 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12775 (clobber (reg:CC FLAGS_REG))]
12776 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12778 rol{b}\t{%2, %0|%0, %2}
12779 rol{b}\t{%b2, %0|%0, %b2}"
12780 [(set_attr "type" "rotate")
12781 (set_attr "mode" "QI")])
12783 (define_expand "rotrdi3"
12784 [(set (match_operand:DI 0 "shiftdi_operand" "")
12785 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12786 (match_operand:QI 2 "nonmemory_operand" "")))
12787 (clobber (reg:CC FLAGS_REG))]
12792 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12795 if (!const_1_to_31_operand (operands[2], VOIDmode))
12797 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12801 ;; Implement rotation using two double-precision shift instructions
12802 ;; and a scratch register.
12803 (define_insn_and_split "ix86_rotrdi3"
12804 [(set (match_operand:DI 0 "register_operand" "=r")
12805 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12806 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12807 (clobber (reg:CC FLAGS_REG))
12808 (clobber (match_scratch:SI 3 "=&r"))]
12811 "&& reload_completed"
12812 [(set (match_dup 3) (match_dup 4))
12814 [(set (match_dup 4)
12815 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12816 (ashift:SI (match_dup 5)
12817 (minus:QI (const_int 32) (match_dup 2)))))
12818 (clobber (reg:CC FLAGS_REG))])
12820 [(set (match_dup 5)
12821 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12822 (ashift:SI (match_dup 3)
12823 (minus:QI (const_int 32) (match_dup 2)))))
12824 (clobber (reg:CC FLAGS_REG))])]
12825 "split_di (operands, 1, operands + 4, operands + 5);")
12827 (define_insn "*rotrdi3_1_one_bit_rex64"
12828 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12829 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12830 (match_operand:QI 2 "const1_operand" "")))
12831 (clobber (reg:CC FLAGS_REG))]
12832 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12833 && (TARGET_SHIFT1 || optimize_size)"
12835 [(set_attr "type" "rotate")
12836 (set (attr "length")
12837 (if_then_else (match_operand:DI 0 "register_operand" "")
12839 (const_string "*")))])
12841 (define_insn "*rotrdi3_1_rex64"
12842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12843 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12844 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12845 (clobber (reg:CC FLAGS_REG))]
12846 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12848 ror{q}\t{%2, %0|%0, %2}
12849 ror{q}\t{%b2, %0|%0, %b2}"
12850 [(set_attr "type" "rotate")
12851 (set_attr "mode" "DI")])
12853 (define_expand "rotrsi3"
12854 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12855 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12856 (match_operand:QI 2 "nonmemory_operand" "")))
12857 (clobber (reg:CC FLAGS_REG))]
12859 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12861 (define_insn "*rotrsi3_1_one_bit"
12862 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12863 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12864 (match_operand:QI 2 "const1_operand" "")))
12865 (clobber (reg:CC FLAGS_REG))]
12866 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12867 && (TARGET_SHIFT1 || optimize_size)"
12869 [(set_attr "type" "rotate")
12870 (set (attr "length")
12871 (if_then_else (match_operand:SI 0 "register_operand" "")
12873 (const_string "*")))])
12875 (define_insn "*rotrsi3_1_one_bit_zext"
12876 [(set (match_operand:DI 0 "register_operand" "=r")
12878 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12879 (match_operand:QI 2 "const1_operand" ""))))
12880 (clobber (reg:CC FLAGS_REG))]
12881 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12882 && (TARGET_SHIFT1 || optimize_size)"
12884 [(set_attr "type" "rotate")
12885 (set (attr "length")
12886 (if_then_else (match_operand:SI 0 "register_operand" "")
12888 (const_string "*")))])
12890 (define_insn "*rotrsi3_1"
12891 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12892 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12893 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12894 (clobber (reg:CC FLAGS_REG))]
12895 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12897 ror{l}\t{%2, %0|%0, %2}
12898 ror{l}\t{%b2, %0|%0, %b2}"
12899 [(set_attr "type" "rotate")
12900 (set_attr "mode" "SI")])
12902 (define_insn "*rotrsi3_1_zext"
12903 [(set (match_operand:DI 0 "register_operand" "=r,r")
12905 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12906 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12907 (clobber (reg:CC FLAGS_REG))]
12908 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12910 ror{l}\t{%2, %k0|%k0, %2}
12911 ror{l}\t{%b2, %k0|%k0, %b2}"
12912 [(set_attr "type" "rotate")
12913 (set_attr "mode" "SI")])
12915 (define_expand "rotrhi3"
12916 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12917 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12918 (match_operand:QI 2 "nonmemory_operand" "")))
12919 (clobber (reg:CC FLAGS_REG))]
12920 "TARGET_HIMODE_MATH"
12921 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12923 (define_insn "*rotrhi3_one_bit"
12924 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12925 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12926 (match_operand:QI 2 "const1_operand" "")))
12927 (clobber (reg:CC FLAGS_REG))]
12928 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12929 && (TARGET_SHIFT1 || optimize_size)"
12931 [(set_attr "type" "rotate")
12932 (set (attr "length")
12933 (if_then_else (match_operand 0 "register_operand" "")
12935 (const_string "*")))])
12937 (define_insn "*rotrhi3_1"
12938 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12939 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12940 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12941 (clobber (reg:CC FLAGS_REG))]
12942 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12944 ror{w}\t{%2, %0|%0, %2}
12945 ror{w}\t{%b2, %0|%0, %b2}"
12946 [(set_attr "type" "rotate")
12947 (set_attr "mode" "HI")])
12950 [(set (match_operand:HI 0 "register_operand" "")
12951 (rotatert:HI (match_dup 0) (const_int 8)))
12952 (clobber (reg:CC FLAGS_REG))]
12954 [(parallel [(set (strict_low_part (match_dup 0))
12955 (bswap:HI (match_dup 0)))
12956 (clobber (reg:CC FLAGS_REG))])]
12959 (define_expand "rotrqi3"
12960 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12961 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12962 (match_operand:QI 2 "nonmemory_operand" "")))
12963 (clobber (reg:CC FLAGS_REG))]
12964 "TARGET_QIMODE_MATH"
12965 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12967 (define_insn "*rotrqi3_1_one_bit"
12968 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12969 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12970 (match_operand:QI 2 "const1_operand" "")))
12971 (clobber (reg:CC FLAGS_REG))]
12972 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12973 && (TARGET_SHIFT1 || optimize_size)"
12975 [(set_attr "type" "rotate")
12976 (set (attr "length")
12977 (if_then_else (match_operand 0 "register_operand" "")
12979 (const_string "*")))])
12981 (define_insn "*rotrqi3_1_one_bit_slp"
12982 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12983 (rotatert:QI (match_dup 0)
12984 (match_operand:QI 1 "const1_operand" "")))
12985 (clobber (reg:CC FLAGS_REG))]
12986 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12987 && (TARGET_SHIFT1 || optimize_size)"
12989 [(set_attr "type" "rotate1")
12990 (set (attr "length")
12991 (if_then_else (match_operand 0 "register_operand" "")
12993 (const_string "*")))])
12995 (define_insn "*rotrqi3_1"
12996 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12997 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12998 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12999 (clobber (reg:CC FLAGS_REG))]
13000 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13002 ror{b}\t{%2, %0|%0, %2}
13003 ror{b}\t{%b2, %0|%0, %b2}"
13004 [(set_attr "type" "rotate")
13005 (set_attr "mode" "QI")])
13007 (define_insn "*rotrqi3_1_slp"
13008 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13009 (rotatert:QI (match_dup 0)
13010 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13011 (clobber (reg:CC FLAGS_REG))]
13012 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13013 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13015 ror{b}\t{%1, %0|%0, %1}
13016 ror{b}\t{%b1, %0|%0, %b1}"
13017 [(set_attr "type" "rotate1")
13018 (set_attr "mode" "QI")])
13020 ;; Bit set / bit test instructions
13022 (define_expand "extv"
13023 [(set (match_operand:SI 0 "register_operand" "")
13024 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13025 (match_operand:SI 2 "const8_operand" "")
13026 (match_operand:SI 3 "const8_operand" "")))]
13029 /* Handle extractions from %ah et al. */
13030 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13033 /* From mips.md: extract_bit_field doesn't verify that our source
13034 matches the predicate, so check it again here. */
13035 if (! ext_register_operand (operands[1], VOIDmode))
13039 (define_expand "extzv"
13040 [(set (match_operand:SI 0 "register_operand" "")
13041 (zero_extract:SI (match_operand 1 "ext_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 "insv"
13057 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13058 (match_operand 1 "const8_operand" "")
13059 (match_operand 2 "const8_operand" ""))
13060 (match_operand 3 "register_operand" ""))]
13063 /* Handle insertions to %ah et al. */
13064 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13067 /* From mips.md: insert_bit_field doesn't verify that our source
13068 matches the predicate, so check it again here. */
13069 if (! ext_register_operand (operands[0], VOIDmode))
13073 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13075 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13080 ;; %%% bts, btr, btc, bt.
13081 ;; In general these instructions are *slow* when applied to memory,
13082 ;; since they enforce atomic operation. When applied to registers,
13083 ;; it depends on the cpu implementation. They're never faster than
13084 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13085 ;; no point. But in 64-bit, we can't hold the relevant immediates
13086 ;; within the instruction itself, so operating on bits in the high
13087 ;; 32-bits of a register becomes easier.
13089 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13090 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13091 ;; negdf respectively, so they can never be disabled entirely.
13093 (define_insn "*btsq"
13094 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13096 (match_operand:DI 1 "const_0_to_63_operand" ""))
13098 (clobber (reg:CC FLAGS_REG))]
13099 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13101 [(set_attr "type" "alu1")])
13103 (define_insn "*btrq"
13104 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13106 (match_operand:DI 1 "const_0_to_63_operand" ""))
13108 (clobber (reg:CC FLAGS_REG))]
13109 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13111 [(set_attr "type" "alu1")])
13113 (define_insn "*btcq"
13114 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13116 (match_operand:DI 1 "const_0_to_63_operand" ""))
13117 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13118 (clobber (reg:CC FLAGS_REG))]
13119 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13121 [(set_attr "type" "alu1")])
13123 ;; Allow Nocona to avoid these instructions if a register is available.
13126 [(match_scratch:DI 2 "r")
13127 (parallel [(set (zero_extract:DI
13128 (match_operand:DI 0 "register_operand" "")
13130 (match_operand:DI 1 "const_0_to_63_operand" ""))
13132 (clobber (reg:CC FLAGS_REG))])]
13133 "TARGET_64BIT && !TARGET_USE_BT"
13136 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13139 if (HOST_BITS_PER_WIDE_INT >= 64)
13140 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13141 else if (i < HOST_BITS_PER_WIDE_INT)
13142 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13144 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13146 op1 = immed_double_const (lo, hi, DImode);
13149 emit_move_insn (operands[2], op1);
13153 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13158 [(match_scratch:DI 2 "r")
13159 (parallel [(set (zero_extract:DI
13160 (match_operand:DI 0 "register_operand" "")
13162 (match_operand:DI 1 "const_0_to_63_operand" ""))
13164 (clobber (reg:CC FLAGS_REG))])]
13165 "TARGET_64BIT && !TARGET_USE_BT"
13168 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13171 if (HOST_BITS_PER_WIDE_INT >= 64)
13172 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13173 else if (i < HOST_BITS_PER_WIDE_INT)
13174 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13176 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13178 op1 = immed_double_const (~lo, ~hi, DImode);
13181 emit_move_insn (operands[2], op1);
13185 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13190 [(match_scratch:DI 2 "r")
13191 (parallel [(set (zero_extract:DI
13192 (match_operand:DI 0 "register_operand" "")
13194 (match_operand:DI 1 "const_0_to_63_operand" ""))
13195 (not:DI (zero_extract:DI
13196 (match_dup 0) (const_int 1) (match_dup 1))))
13197 (clobber (reg:CC FLAGS_REG))])]
13198 "TARGET_64BIT && !TARGET_USE_BT"
13201 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13204 if (HOST_BITS_PER_WIDE_INT >= 64)
13205 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13206 else if (i < HOST_BITS_PER_WIDE_INT)
13207 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13209 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13211 op1 = immed_double_const (lo, hi, DImode);
13214 emit_move_insn (operands[2], op1);
13218 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13222 ;; Store-flag instructions.
13224 ;; For all sCOND expanders, also expand the compare or test insn that
13225 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13227 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13228 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13229 ;; way, which can later delete the movzx if only QImode is needed.
13231 (define_expand "seq"
13232 [(set (match_operand:QI 0 "register_operand" "")
13233 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13235 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13237 (define_expand "sne"
13238 [(set (match_operand:QI 0 "register_operand" "")
13239 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13241 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13243 (define_expand "sgt"
13244 [(set (match_operand:QI 0 "register_operand" "")
13245 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13247 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13249 (define_expand "sgtu"
13250 [(set (match_operand:QI 0 "register_operand" "")
13251 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13253 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13255 (define_expand "slt"
13256 [(set (match_operand:QI 0 "register_operand" "")
13257 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13259 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13261 (define_expand "sltu"
13262 [(set (match_operand:QI 0 "register_operand" "")
13263 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13265 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13267 (define_expand "sge"
13268 [(set (match_operand:QI 0 "register_operand" "")
13269 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13271 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13273 (define_expand "sgeu"
13274 [(set (match_operand:QI 0 "register_operand" "")
13275 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13277 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13279 (define_expand "sle"
13280 [(set (match_operand:QI 0 "register_operand" "")
13281 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13283 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13285 (define_expand "sleu"
13286 [(set (match_operand:QI 0 "register_operand" "")
13287 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13289 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13291 (define_expand "sunordered"
13292 [(set (match_operand:QI 0 "register_operand" "")
13293 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294 "TARGET_80387 || TARGET_SSE"
13295 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13297 (define_expand "sordered"
13298 [(set (match_operand:QI 0 "register_operand" "")
13299 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13301 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13303 (define_expand "suneq"
13304 [(set (match_operand:QI 0 "register_operand" "")
13305 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13306 "TARGET_80387 || TARGET_SSE"
13307 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13309 (define_expand "sunge"
13310 [(set (match_operand:QI 0 "register_operand" "")
13311 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13312 "TARGET_80387 || TARGET_SSE"
13313 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13315 (define_expand "sungt"
13316 [(set (match_operand:QI 0 "register_operand" "")
13317 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13318 "TARGET_80387 || TARGET_SSE"
13319 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13321 (define_expand "sunle"
13322 [(set (match_operand:QI 0 "register_operand" "")
13323 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13324 "TARGET_80387 || TARGET_SSE"
13325 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13327 (define_expand "sunlt"
13328 [(set (match_operand:QI 0 "register_operand" "")
13329 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13330 "TARGET_80387 || TARGET_SSE"
13331 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13333 (define_expand "sltgt"
13334 [(set (match_operand:QI 0 "register_operand" "")
13335 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13336 "TARGET_80387 || TARGET_SSE"
13337 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13339 (define_insn "*setcc_1"
13340 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13341 (match_operator:QI 1 "ix86_comparison_operator"
13342 [(reg FLAGS_REG) (const_int 0)]))]
13345 [(set_attr "type" "setcc")
13346 (set_attr "mode" "QI")])
13348 (define_insn "*setcc_2"
13349 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13350 (match_operator:QI 1 "ix86_comparison_operator"
13351 [(reg FLAGS_REG) (const_int 0)]))]
13354 [(set_attr "type" "setcc")
13355 (set_attr "mode" "QI")])
13357 ;; In general it is not safe to assume too much about CCmode registers,
13358 ;; so simplify-rtx stops when it sees a second one. Under certain
13359 ;; conditions this is safe on x86, so help combine not create
13366 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13367 (ne:QI (match_operator 1 "ix86_comparison_operator"
13368 [(reg FLAGS_REG) (const_int 0)])
13371 [(set (match_dup 0) (match_dup 1))]
13373 PUT_MODE (operands[1], QImode);
13377 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13378 (ne:QI (match_operator 1 "ix86_comparison_operator"
13379 [(reg FLAGS_REG) (const_int 0)])
13382 [(set (match_dup 0) (match_dup 1))]
13384 PUT_MODE (operands[1], QImode);
13388 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13389 (eq:QI (match_operator 1 "ix86_comparison_operator"
13390 [(reg FLAGS_REG) (const_int 0)])
13393 [(set (match_dup 0) (match_dup 1))]
13395 rtx new_op1 = copy_rtx (operands[1]);
13396 operands[1] = new_op1;
13397 PUT_MODE (new_op1, QImode);
13398 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13399 GET_MODE (XEXP (new_op1, 0))));
13401 /* Make sure that (a) the CCmode we have for the flags is strong
13402 enough for the reversed compare or (b) we have a valid FP compare. */
13403 if (! ix86_comparison_operator (new_op1, VOIDmode))
13408 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13409 (eq:QI (match_operator 1 "ix86_comparison_operator"
13410 [(reg FLAGS_REG) (const_int 0)])
13413 [(set (match_dup 0) (match_dup 1))]
13415 rtx new_op1 = copy_rtx (operands[1]);
13416 operands[1] = new_op1;
13417 PUT_MODE (new_op1, QImode);
13418 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13419 GET_MODE (XEXP (new_op1, 0))));
13421 /* Make sure that (a) the CCmode we have for the flags is strong
13422 enough for the reversed compare or (b) we have a valid FP compare. */
13423 if (! ix86_comparison_operator (new_op1, VOIDmode))
13427 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13428 ;; subsequent logical operations are used to imitate conditional moves.
13429 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13432 (define_insn "*sse_setccsf"
13433 [(set (match_operand:SF 0 "register_operand" "=x")
13434 (match_operator:SF 1 "sse_comparison_operator"
13435 [(match_operand:SF 2 "register_operand" "0")
13436 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13438 "cmp%D1ss\t{%3, %0|%0, %3}"
13439 [(set_attr "type" "ssecmp")
13440 (set_attr "mode" "SF")])
13442 (define_insn "*sse_setccdf"
13443 [(set (match_operand:DF 0 "register_operand" "=x")
13444 (match_operator:DF 1 "sse_comparison_operator"
13445 [(match_operand:DF 2 "register_operand" "0")
13446 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13448 "cmp%D1sd\t{%3, %0|%0, %3}"
13449 [(set_attr "type" "ssecmp")
13450 (set_attr "mode" "DF")])
13452 ;; Basic conditional jump instructions.
13453 ;; We ignore the overflow flag for signed branch instructions.
13455 ;; For all bCOND expanders, also expand the compare or test insn that
13456 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13458 (define_expand "beq"
13460 (if_then_else (match_dup 1)
13461 (label_ref (match_operand 0 "" ""))
13464 "ix86_expand_branch (EQ, operands[0]); DONE;")
13466 (define_expand "bne"
13468 (if_then_else (match_dup 1)
13469 (label_ref (match_operand 0 "" ""))
13472 "ix86_expand_branch (NE, operands[0]); DONE;")
13474 (define_expand "bgt"
13476 (if_then_else (match_dup 1)
13477 (label_ref (match_operand 0 "" ""))
13480 "ix86_expand_branch (GT, operands[0]); DONE;")
13482 (define_expand "bgtu"
13484 (if_then_else (match_dup 1)
13485 (label_ref (match_operand 0 "" ""))
13488 "ix86_expand_branch (GTU, operands[0]); DONE;")
13490 (define_expand "blt"
13492 (if_then_else (match_dup 1)
13493 (label_ref (match_operand 0 "" ""))
13496 "ix86_expand_branch (LT, operands[0]); DONE;")
13498 (define_expand "bltu"
13500 (if_then_else (match_dup 1)
13501 (label_ref (match_operand 0 "" ""))
13504 "ix86_expand_branch (LTU, operands[0]); DONE;")
13506 (define_expand "bge"
13508 (if_then_else (match_dup 1)
13509 (label_ref (match_operand 0 "" ""))
13512 "ix86_expand_branch (GE, operands[0]); DONE;")
13514 (define_expand "bgeu"
13516 (if_then_else (match_dup 1)
13517 (label_ref (match_operand 0 "" ""))
13520 "ix86_expand_branch (GEU, operands[0]); DONE;")
13522 (define_expand "ble"
13524 (if_then_else (match_dup 1)
13525 (label_ref (match_operand 0 "" ""))
13528 "ix86_expand_branch (LE, operands[0]); DONE;")
13530 (define_expand "bleu"
13532 (if_then_else (match_dup 1)
13533 (label_ref (match_operand 0 "" ""))
13536 "ix86_expand_branch (LEU, operands[0]); DONE;")
13538 (define_expand "bunordered"
13540 (if_then_else (match_dup 1)
13541 (label_ref (match_operand 0 "" ""))
13543 "TARGET_80387 || TARGET_SSE_MATH"
13544 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13546 (define_expand "bordered"
13548 (if_then_else (match_dup 1)
13549 (label_ref (match_operand 0 "" ""))
13551 "TARGET_80387 || TARGET_SSE_MATH"
13552 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13554 (define_expand "buneq"
13556 (if_then_else (match_dup 1)
13557 (label_ref (match_operand 0 "" ""))
13559 "TARGET_80387 || TARGET_SSE_MATH"
13560 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13562 (define_expand "bunge"
13564 (if_then_else (match_dup 1)
13565 (label_ref (match_operand 0 "" ""))
13567 "TARGET_80387 || TARGET_SSE_MATH"
13568 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13570 (define_expand "bungt"
13572 (if_then_else (match_dup 1)
13573 (label_ref (match_operand 0 "" ""))
13575 "TARGET_80387 || TARGET_SSE_MATH"
13576 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13578 (define_expand "bunle"
13580 (if_then_else (match_dup 1)
13581 (label_ref (match_operand 0 "" ""))
13583 "TARGET_80387 || TARGET_SSE_MATH"
13584 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13586 (define_expand "bunlt"
13588 (if_then_else (match_dup 1)
13589 (label_ref (match_operand 0 "" ""))
13591 "TARGET_80387 || TARGET_SSE_MATH"
13592 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13594 (define_expand "bltgt"
13596 (if_then_else (match_dup 1)
13597 (label_ref (match_operand 0 "" ""))
13599 "TARGET_80387 || TARGET_SSE_MATH"
13600 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13602 (define_insn "*jcc_1"
13604 (if_then_else (match_operator 1 "ix86_comparison_operator"
13605 [(reg FLAGS_REG) (const_int 0)])
13606 (label_ref (match_operand 0 "" ""))
13610 [(set_attr "type" "ibr")
13611 (set_attr "modrm" "0")
13612 (set (attr "length")
13613 (if_then_else (and (ge (minus (match_dup 0) (pc))
13615 (lt (minus (match_dup 0) (pc))
13620 (define_insn "*jcc_2"
13622 (if_then_else (match_operator 1 "ix86_comparison_operator"
13623 [(reg FLAGS_REG) (const_int 0)])
13625 (label_ref (match_operand 0 "" ""))))]
13628 [(set_attr "type" "ibr")
13629 (set_attr "modrm" "0")
13630 (set (attr "length")
13631 (if_then_else (and (ge (minus (match_dup 0) (pc))
13633 (lt (minus (match_dup 0) (pc))
13638 ;; In general it is not safe to assume too much about CCmode registers,
13639 ;; so simplify-rtx stops when it sees a second one. Under certain
13640 ;; conditions this is safe on x86, so help combine not create
13648 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13649 [(reg FLAGS_REG) (const_int 0)])
13651 (label_ref (match_operand 1 "" ""))
13655 (if_then_else (match_dup 0)
13656 (label_ref (match_dup 1))
13659 PUT_MODE (operands[0], VOIDmode);
13664 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13665 [(reg FLAGS_REG) (const_int 0)])
13667 (label_ref (match_operand 1 "" ""))
13671 (if_then_else (match_dup 0)
13672 (label_ref (match_dup 1))
13675 rtx new_op0 = copy_rtx (operands[0]);
13676 operands[0] = new_op0;
13677 PUT_MODE (new_op0, VOIDmode);
13678 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13679 GET_MODE (XEXP (new_op0, 0))));
13681 /* Make sure that (a) the CCmode we have for the flags is strong
13682 enough for the reversed compare or (b) we have a valid FP compare. */
13683 if (! ix86_comparison_operator (new_op0, VOIDmode))
13687 ;; Define combination compare-and-branch fp compare instructions to use
13688 ;; during early optimization. Splitting the operation apart early makes
13689 ;; for bad code when we want to reverse the operation.
13691 (define_insn "*fp_jcc_1_mixed"
13693 (if_then_else (match_operator 0 "comparison_operator"
13694 [(match_operand 1 "register_operand" "f,x")
13695 (match_operand 2 "nonimmediate_operand" "f,xm")])
13696 (label_ref (match_operand 3 "" ""))
13698 (clobber (reg:CCFP FPSR_REG))
13699 (clobber (reg:CCFP FLAGS_REG))]
13700 "TARGET_MIX_SSE_I387
13701 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13702 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13703 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13706 (define_insn "*fp_jcc_1_sse"
13708 (if_then_else (match_operator 0 "comparison_operator"
13709 [(match_operand 1 "register_operand" "x")
13710 (match_operand 2 "nonimmediate_operand" "xm")])
13711 (label_ref (match_operand 3 "" ""))
13713 (clobber (reg:CCFP FPSR_REG))
13714 (clobber (reg:CCFP FLAGS_REG))]
13716 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13717 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13718 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13721 (define_insn "*fp_jcc_1_387"
13723 (if_then_else (match_operator 0 "comparison_operator"
13724 [(match_operand 1 "register_operand" "f")
13725 (match_operand 2 "register_operand" "f")])
13726 (label_ref (match_operand 3 "" ""))
13728 (clobber (reg:CCFP FPSR_REG))
13729 (clobber (reg:CCFP FLAGS_REG))]
13730 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13732 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13733 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13736 (define_insn "*fp_jcc_2_mixed"
13738 (if_then_else (match_operator 0 "comparison_operator"
13739 [(match_operand 1 "register_operand" "f,x")
13740 (match_operand 2 "nonimmediate_operand" "f,xm")])
13742 (label_ref (match_operand 3 "" ""))))
13743 (clobber (reg:CCFP FPSR_REG))
13744 (clobber (reg:CCFP FLAGS_REG))]
13745 "TARGET_MIX_SSE_I387
13746 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13747 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13748 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13751 (define_insn "*fp_jcc_2_sse"
13753 (if_then_else (match_operator 0 "comparison_operator"
13754 [(match_operand 1 "register_operand" "x")
13755 (match_operand 2 "nonimmediate_operand" "xm")])
13757 (label_ref (match_operand 3 "" ""))))
13758 (clobber (reg:CCFP FPSR_REG))
13759 (clobber (reg:CCFP FLAGS_REG))]
13761 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13762 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13763 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13766 (define_insn "*fp_jcc_2_387"
13768 (if_then_else (match_operator 0 "comparison_operator"
13769 [(match_operand 1 "register_operand" "f")
13770 (match_operand 2 "register_operand" "f")])
13772 (label_ref (match_operand 3 "" ""))))
13773 (clobber (reg:CCFP FPSR_REG))
13774 (clobber (reg:CCFP FLAGS_REG))]
13775 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13777 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13778 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13781 (define_insn "*fp_jcc_3_387"
13783 (if_then_else (match_operator 0 "comparison_operator"
13784 [(match_operand 1 "register_operand" "f")
13785 (match_operand 2 "nonimmediate_operand" "fm")])
13786 (label_ref (match_operand 3 "" ""))
13788 (clobber (reg:CCFP FPSR_REG))
13789 (clobber (reg:CCFP FLAGS_REG))
13790 (clobber (match_scratch:HI 4 "=a"))]
13792 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13793 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13794 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13795 && SELECT_CC_MODE (GET_CODE (operands[0]),
13796 operands[1], operands[2]) == CCFPmode
13797 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13800 (define_insn "*fp_jcc_4_387"
13802 (if_then_else (match_operator 0 "comparison_operator"
13803 [(match_operand 1 "register_operand" "f")
13804 (match_operand 2 "nonimmediate_operand" "fm")])
13806 (label_ref (match_operand 3 "" ""))))
13807 (clobber (reg:CCFP FPSR_REG))
13808 (clobber (reg:CCFP FLAGS_REG))
13809 (clobber (match_scratch:HI 4 "=a"))]
13811 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13812 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13813 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13814 && SELECT_CC_MODE (GET_CODE (operands[0]),
13815 operands[1], operands[2]) == CCFPmode
13816 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13819 (define_insn "*fp_jcc_5_387"
13821 (if_then_else (match_operator 0 "comparison_operator"
13822 [(match_operand 1 "register_operand" "f")
13823 (match_operand 2 "register_operand" "f")])
13824 (label_ref (match_operand 3 "" ""))
13826 (clobber (reg:CCFP FPSR_REG))
13827 (clobber (reg:CCFP FLAGS_REG))
13828 (clobber (match_scratch:HI 4 "=a"))]
13829 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13830 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13831 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13834 (define_insn "*fp_jcc_6_387"
13836 (if_then_else (match_operator 0 "comparison_operator"
13837 [(match_operand 1 "register_operand" "f")
13838 (match_operand 2 "register_operand" "f")])
13840 (label_ref (match_operand 3 "" ""))))
13841 (clobber (reg:CCFP FPSR_REG))
13842 (clobber (reg:CCFP FLAGS_REG))
13843 (clobber (match_scratch:HI 4 "=a"))]
13844 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13845 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13846 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13849 (define_insn "*fp_jcc_7_387"
13851 (if_then_else (match_operator 0 "comparison_operator"
13852 [(match_operand 1 "register_operand" "f")
13853 (match_operand 2 "const0_operand" "X")])
13854 (label_ref (match_operand 3 "" ""))
13856 (clobber (reg:CCFP FPSR_REG))
13857 (clobber (reg:CCFP FLAGS_REG))
13858 (clobber (match_scratch:HI 4 "=a"))]
13859 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13860 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13861 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13862 && SELECT_CC_MODE (GET_CODE (operands[0]),
13863 operands[1], operands[2]) == CCFPmode
13864 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13867 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13868 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13869 ;; with a precedence over other operators and is always put in the first
13870 ;; place. Swap condition and operands to match ficom instruction.
13872 (define_insn "*fp_jcc_8<mode>_387"
13874 (if_then_else (match_operator 0 "comparison_operator"
13875 [(match_operator 1 "float_operator"
13876 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13877 (match_operand 3 "register_operand" "f,f")])
13878 (label_ref (match_operand 4 "" ""))
13880 (clobber (reg:CCFP FPSR_REG))
13881 (clobber (reg:CCFP FLAGS_REG))
13882 (clobber (match_scratch:HI 5 "=a,a"))]
13883 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13884 && TARGET_USE_<MODE>MODE_FIOP
13885 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13886 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13887 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13888 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13893 (if_then_else (match_operator 0 "comparison_operator"
13894 [(match_operand 1 "register_operand" "")
13895 (match_operand 2 "nonimmediate_operand" "")])
13896 (match_operand 3 "" "")
13897 (match_operand 4 "" "")))
13898 (clobber (reg:CCFP FPSR_REG))
13899 (clobber (reg:CCFP FLAGS_REG))]
13903 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13904 operands[3], operands[4], NULL_RTX, NULL_RTX);
13910 (if_then_else (match_operator 0 "comparison_operator"
13911 [(match_operand 1 "register_operand" "")
13912 (match_operand 2 "general_operand" "")])
13913 (match_operand 3 "" "")
13914 (match_operand 4 "" "")))
13915 (clobber (reg:CCFP FPSR_REG))
13916 (clobber (reg:CCFP FLAGS_REG))
13917 (clobber (match_scratch:HI 5 "=a"))]
13921 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13922 operands[3], operands[4], operands[5], NULL_RTX);
13928 (if_then_else (match_operator 0 "comparison_operator"
13929 [(match_operator 1 "float_operator"
13930 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13931 (match_operand 3 "register_operand" "")])
13932 (match_operand 4 "" "")
13933 (match_operand 5 "" "")))
13934 (clobber (reg:CCFP FPSR_REG))
13935 (clobber (reg:CCFP FLAGS_REG))
13936 (clobber (match_scratch:HI 6 "=a"))]
13940 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13941 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13942 operands[3], operands[7],
13943 operands[4], operands[5], operands[6], NULL_RTX);
13947 ;; %%% Kill this when reload knows how to do it.
13950 (if_then_else (match_operator 0 "comparison_operator"
13951 [(match_operator 1 "float_operator"
13952 [(match_operand:X87MODEI12 2 "register_operand" "")])
13953 (match_operand 3 "register_operand" "")])
13954 (match_operand 4 "" "")
13955 (match_operand 5 "" "")))
13956 (clobber (reg:CCFP FPSR_REG))
13957 (clobber (reg:CCFP FLAGS_REG))
13958 (clobber (match_scratch:HI 6 "=a"))]
13962 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13963 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13964 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13965 operands[3], operands[7],
13966 operands[4], operands[5], operands[6], operands[2]);
13970 ;; Unconditional and other jump instructions
13972 (define_insn "jump"
13974 (label_ref (match_operand 0 "" "")))]
13977 [(set_attr "type" "ibr")
13978 (set (attr "length")
13979 (if_then_else (and (ge (minus (match_dup 0) (pc))
13981 (lt (minus (match_dup 0) (pc))
13985 (set_attr "modrm" "0")])
13987 (define_expand "indirect_jump"
13988 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13992 (define_insn "*indirect_jump"
13993 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13996 [(set_attr "type" "ibr")
13997 (set_attr "length_immediate" "0")])
13999 (define_insn "*indirect_jump_rtx64"
14000 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14003 [(set_attr "type" "ibr")
14004 (set_attr "length_immediate" "0")])
14006 (define_expand "tablejump"
14007 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14008 (use (label_ref (match_operand 1 "" "")))])]
14011 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14012 relative. Convert the relative address to an absolute address. */
14016 enum rtx_code code;
14018 /* We can't use @GOTOFF for text labels on VxWorks;
14019 see gotoff_operand. */
14020 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14024 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14026 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14030 op1 = pic_offset_table_rtx;
14035 op0 = pic_offset_table_rtx;
14039 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14044 (define_insn "*tablejump_1"
14045 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14046 (use (label_ref (match_operand 1 "" "")))]
14049 [(set_attr "type" "ibr")
14050 (set_attr "length_immediate" "0")])
14052 (define_insn "*tablejump_1_rtx64"
14053 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14054 (use (label_ref (match_operand 1 "" "")))]
14057 [(set_attr "type" "ibr")
14058 (set_attr "length_immediate" "0")])
14060 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14063 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14064 (set (match_operand:QI 1 "register_operand" "")
14065 (match_operator:QI 2 "ix86_comparison_operator"
14066 [(reg FLAGS_REG) (const_int 0)]))
14067 (set (match_operand 3 "q_regs_operand" "")
14068 (zero_extend (match_dup 1)))]
14069 "(peep2_reg_dead_p (3, operands[1])
14070 || operands_match_p (operands[1], operands[3]))
14071 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14072 [(set (match_dup 4) (match_dup 0))
14073 (set (strict_low_part (match_dup 5))
14076 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14077 operands[5] = gen_lowpart (QImode, operands[3]);
14078 ix86_expand_clear (operands[3]);
14081 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14084 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14085 (set (match_operand:QI 1 "register_operand" "")
14086 (match_operator:QI 2 "ix86_comparison_operator"
14087 [(reg FLAGS_REG) (const_int 0)]))
14088 (parallel [(set (match_operand 3 "q_regs_operand" "")
14089 (zero_extend (match_dup 1)))
14090 (clobber (reg:CC FLAGS_REG))])]
14091 "(peep2_reg_dead_p (3, operands[1])
14092 || operands_match_p (operands[1], operands[3]))
14093 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14094 [(set (match_dup 4) (match_dup 0))
14095 (set (strict_low_part (match_dup 5))
14098 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14099 operands[5] = gen_lowpart (QImode, operands[3]);
14100 ix86_expand_clear (operands[3]);
14103 ;; Call instructions.
14105 ;; The predicates normally associated with named expanders are not properly
14106 ;; checked for calls. This is a bug in the generic code, but it isn't that
14107 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14109 ;; Call subroutine returning no value.
14111 (define_expand "call_pop"
14112 [(parallel [(call (match_operand:QI 0 "" "")
14113 (match_operand:SI 1 "" ""))
14114 (set (reg:SI SP_REG)
14115 (plus:SI (reg:SI SP_REG)
14116 (match_operand:SI 3 "" "")))])]
14119 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14123 (define_insn "*call_pop_0"
14124 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14125 (match_operand:SI 1 "" ""))
14126 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14127 (match_operand:SI 2 "immediate_operand" "")))]
14130 if (SIBLING_CALL_P (insn))
14133 return "call\t%P0";
14135 [(set_attr "type" "call")])
14137 (define_insn "*call_pop_1"
14138 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14139 (match_operand:SI 1 "" ""))
14140 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14141 (match_operand:SI 2 "immediate_operand" "i")))]
14144 if (constant_call_address_operand (operands[0], Pmode))
14146 if (SIBLING_CALL_P (insn))
14149 return "call\t%P0";
14151 if (SIBLING_CALL_P (insn))
14154 return "call\t%A0";
14156 [(set_attr "type" "call")])
14158 (define_expand "call"
14159 [(call (match_operand:QI 0 "" "")
14160 (match_operand 1 "" ""))
14161 (use (match_operand 2 "" ""))]
14164 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14168 (define_expand "sibcall"
14169 [(call (match_operand:QI 0 "" "")
14170 (match_operand 1 "" ""))
14171 (use (match_operand 2 "" ""))]
14174 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14178 (define_insn "*call_0"
14179 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14180 (match_operand 1 "" ""))]
14183 if (SIBLING_CALL_P (insn))
14186 return "call\t%P0";
14188 [(set_attr "type" "call")])
14190 (define_insn "*call_1"
14191 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14192 (match_operand 1 "" ""))]
14193 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14195 if (constant_call_address_operand (operands[0], Pmode))
14196 return "call\t%P0";
14197 return "call\t%A0";
14199 [(set_attr "type" "call")])
14201 (define_insn "*sibcall_1"
14202 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14203 (match_operand 1 "" ""))]
14204 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14206 if (constant_call_address_operand (operands[0], Pmode))
14210 [(set_attr "type" "call")])
14212 (define_insn "*call_1_rex64"
14213 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14214 (match_operand 1 "" ""))]
14215 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14216 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14218 if (constant_call_address_operand (operands[0], Pmode))
14219 return "call\t%P0";
14220 return "call\t%A0";
14222 [(set_attr "type" "call")])
14224 (define_insn "*call_1_rex64_large"
14225 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14226 (match_operand 1 "" ""))]
14227 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14229 [(set_attr "type" "call")])
14231 (define_insn "*sibcall_1_rex64"
14232 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14233 (match_operand 1 "" ""))]
14234 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14236 [(set_attr "type" "call")])
14238 (define_insn "*sibcall_1_rex64_v"
14239 [(call (mem:QI (reg:DI R11_REG))
14240 (match_operand 0 "" ""))]
14241 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14243 [(set_attr "type" "call")])
14246 ;; Call subroutine, returning value in operand 0
14248 (define_expand "call_value_pop"
14249 [(parallel [(set (match_operand 0 "" "")
14250 (call (match_operand:QI 1 "" "")
14251 (match_operand:SI 2 "" "")))
14252 (set (reg:SI SP_REG)
14253 (plus:SI (reg:SI SP_REG)
14254 (match_operand:SI 4 "" "")))])]
14257 ix86_expand_call (operands[0], operands[1], operands[2],
14258 operands[3], operands[4], 0);
14262 (define_expand "call_value"
14263 [(set (match_operand 0 "" "")
14264 (call (match_operand:QI 1 "" "")
14265 (match_operand:SI 2 "" "")))
14266 (use (match_operand:SI 3 "" ""))]
14267 ;; Operand 2 not used on the i386.
14270 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14274 (define_expand "sibcall_value"
14275 [(set (match_operand 0 "" "")
14276 (call (match_operand:QI 1 "" "")
14277 (match_operand:SI 2 "" "")))
14278 (use (match_operand:SI 3 "" ""))]
14279 ;; Operand 2 not used on the i386.
14282 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14286 ;; Call subroutine returning any type.
14288 (define_expand "untyped_call"
14289 [(parallel [(call (match_operand 0 "" "")
14291 (match_operand 1 "" "")
14292 (match_operand 2 "" "")])]
14297 /* In order to give reg-stack an easier job in validating two
14298 coprocessor registers as containing a possible return value,
14299 simply pretend the untyped call returns a complex long double
14302 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14303 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14304 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14307 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14309 rtx set = XVECEXP (operands[2], 0, i);
14310 emit_move_insn (SET_DEST (set), SET_SRC (set));
14313 /* The optimizer does not know that the call sets the function value
14314 registers we stored in the result block. We avoid problems by
14315 claiming that all hard registers are used and clobbered at this
14317 emit_insn (gen_blockage (const0_rtx));
14322 ;; Prologue and epilogue instructions
14324 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14325 ;; all of memory. This blocks insns from being moved across this point.
14327 (define_insn "blockage"
14328 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14331 [(set_attr "length" "0")])
14333 ;; Insn emitted into the body of a function to return from a function.
14334 ;; This is only done if the function's epilogue is known to be simple.
14335 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14337 (define_expand "return"
14339 "ix86_can_use_return_insn_p ()"
14341 if (current_function_pops_args)
14343 rtx popc = GEN_INT (current_function_pops_args);
14344 emit_jump_insn (gen_return_pop_internal (popc));
14349 (define_insn "return_internal"
14353 [(set_attr "length" "1")
14354 (set_attr "length_immediate" "0")
14355 (set_attr "modrm" "0")])
14357 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14358 ;; instruction Athlon and K8 have.
14360 (define_insn "return_internal_long"
14362 (unspec [(const_int 0)] UNSPEC_REP)]
14365 [(set_attr "length" "1")
14366 (set_attr "length_immediate" "0")
14367 (set_attr "prefix_rep" "1")
14368 (set_attr "modrm" "0")])
14370 (define_insn "return_pop_internal"
14372 (use (match_operand:SI 0 "const_int_operand" ""))]
14375 [(set_attr "length" "3")
14376 (set_attr "length_immediate" "2")
14377 (set_attr "modrm" "0")])
14379 (define_insn "return_indirect_internal"
14381 (use (match_operand:SI 0 "register_operand" "r"))]
14384 [(set_attr "type" "ibr")
14385 (set_attr "length_immediate" "0")])
14391 [(set_attr "length" "1")
14392 (set_attr "length_immediate" "0")
14393 (set_attr "modrm" "0")])
14395 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14396 ;; branch prediction penalty for the third jump in a 16-byte
14399 (define_insn "align"
14400 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14403 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14404 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14406 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14407 The align insn is used to avoid 3 jump instructions in the row to improve
14408 branch prediction and the benefits hardly outweigh the cost of extra 8
14409 nops on the average inserted by full alignment pseudo operation. */
14413 [(set_attr "length" "16")])
14415 (define_expand "prologue"
14418 "ix86_expand_prologue (); DONE;")
14420 (define_insn "set_got"
14421 [(set (match_operand:SI 0 "register_operand" "=r")
14422 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14423 (clobber (reg:CC FLAGS_REG))]
14425 { return output_set_got (operands[0], NULL_RTX); }
14426 [(set_attr "type" "multi")
14427 (set_attr "length" "12")])
14429 (define_insn "set_got_labelled"
14430 [(set (match_operand:SI 0 "register_operand" "=r")
14431 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14433 (clobber (reg:CC FLAGS_REG))]
14435 { return output_set_got (operands[0], operands[1]); }
14436 [(set_attr "type" "multi")
14437 (set_attr "length" "12")])
14439 (define_insn "set_got_rex64"
14440 [(set (match_operand:DI 0 "register_operand" "=r")
14441 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14443 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14444 [(set_attr "type" "lea")
14445 (set_attr "length" "6")])
14447 (define_insn "set_rip_rex64"
14448 [(set (match_operand:DI 0 "register_operand" "=r")
14449 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14451 "lea{q}\t%l1(%%rip), %0"
14452 [(set_attr "type" "lea")
14453 (set_attr "length" "6")])
14455 (define_insn "set_got_offset_rex64"
14456 [(set (match_operand:DI 0 "register_operand" "=r")
14457 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14459 "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14460 [(set_attr "type" "imov")
14461 (set_attr "length" "11")])
14463 (define_expand "epilogue"
14466 "ix86_expand_epilogue (1); DONE;")
14468 (define_expand "sibcall_epilogue"
14471 "ix86_expand_epilogue (0); DONE;")
14473 (define_expand "eh_return"
14474 [(use (match_operand 0 "register_operand" ""))]
14477 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14479 /* Tricky bit: we write the address of the handler to which we will
14480 be returning into someone else's stack frame, one word below the
14481 stack address we wish to restore. */
14482 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14483 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14484 tmp = gen_rtx_MEM (Pmode, tmp);
14485 emit_move_insn (tmp, ra);
14487 if (Pmode == SImode)
14488 emit_jump_insn (gen_eh_return_si (sa));
14490 emit_jump_insn (gen_eh_return_di (sa));
14495 (define_insn_and_split "eh_return_si"
14497 (unspec [(match_operand:SI 0 "register_operand" "c")]
14498 UNSPEC_EH_RETURN))]
14503 "ix86_expand_epilogue (2); DONE;")
14505 (define_insn_and_split "eh_return_di"
14507 (unspec [(match_operand:DI 0 "register_operand" "c")]
14508 UNSPEC_EH_RETURN))]
14513 "ix86_expand_epilogue (2); DONE;")
14515 (define_insn "leave"
14516 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14517 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14518 (clobber (mem:BLK (scratch)))]
14521 [(set_attr "type" "leave")])
14523 (define_insn "leave_rex64"
14524 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14525 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14526 (clobber (mem:BLK (scratch)))]
14529 [(set_attr "type" "leave")])
14531 (define_expand "ffssi2"
14533 [(set (match_operand:SI 0 "register_operand" "")
14534 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14535 (clobber (match_scratch:SI 2 ""))
14536 (clobber (reg:CC FLAGS_REG))])]
14540 (define_insn_and_split "*ffs_cmove"
14541 [(set (match_operand:SI 0 "register_operand" "=r")
14542 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14543 (clobber (match_scratch:SI 2 "=&r"))
14544 (clobber (reg:CC FLAGS_REG))]
14547 "&& reload_completed"
14548 [(set (match_dup 2) (const_int -1))
14549 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14550 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14551 (set (match_dup 0) (if_then_else:SI
14552 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14555 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14556 (clobber (reg:CC FLAGS_REG))])]
14559 (define_insn_and_split "*ffs_no_cmove"
14560 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14561 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14562 (clobber (match_scratch:SI 2 "=&q"))
14563 (clobber (reg:CC FLAGS_REG))]
14567 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14568 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14569 (set (strict_low_part (match_dup 3))
14570 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14571 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14572 (clobber (reg:CC FLAGS_REG))])
14573 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14574 (clobber (reg:CC FLAGS_REG))])
14575 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14576 (clobber (reg:CC FLAGS_REG))])]
14578 operands[3] = gen_lowpart (QImode, operands[2]);
14579 ix86_expand_clear (operands[2]);
14582 (define_insn "*ffssi_1"
14583 [(set (reg:CCZ FLAGS_REG)
14584 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14586 (set (match_operand:SI 0 "register_operand" "=r")
14587 (ctz:SI (match_dup 1)))]
14589 "bsf{l}\t{%1, %0|%0, %1}"
14590 [(set_attr "prefix_0f" "1")])
14592 (define_expand "ffsdi2"
14594 [(set (match_operand:DI 0 "register_operand" "")
14595 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14596 (clobber (match_scratch:DI 2 ""))
14597 (clobber (reg:CC FLAGS_REG))])]
14598 "TARGET_64BIT && TARGET_CMOVE"
14601 (define_insn_and_split "*ffs_rex64"
14602 [(set (match_operand:DI 0 "register_operand" "=r")
14603 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14604 (clobber (match_scratch:DI 2 "=&r"))
14605 (clobber (reg:CC FLAGS_REG))]
14606 "TARGET_64BIT && TARGET_CMOVE"
14608 "&& reload_completed"
14609 [(set (match_dup 2) (const_int -1))
14610 (parallel [(set (reg:CCZ FLAGS_REG)
14611 (compare:CCZ (match_dup 1) (const_int 0)))
14612 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14613 (set (match_dup 0) (if_then_else:DI
14614 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14617 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14618 (clobber (reg:CC FLAGS_REG))])]
14621 (define_insn "*ffsdi_1"
14622 [(set (reg:CCZ FLAGS_REG)
14623 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14625 (set (match_operand:DI 0 "register_operand" "=r")
14626 (ctz:DI (match_dup 1)))]
14628 "bsf{q}\t{%1, %0|%0, %1}"
14629 [(set_attr "prefix_0f" "1")])
14631 (define_insn "ctzsi2"
14632 [(set (match_operand:SI 0 "register_operand" "=r")
14633 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14634 (clobber (reg:CC FLAGS_REG))]
14636 "bsf{l}\t{%1, %0|%0, %1}"
14637 [(set_attr "prefix_0f" "1")])
14639 (define_insn "ctzdi2"
14640 [(set (match_operand:DI 0 "register_operand" "=r")
14641 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14642 (clobber (reg:CC FLAGS_REG))]
14644 "bsf{q}\t{%1, %0|%0, %1}"
14645 [(set_attr "prefix_0f" "1")])
14647 (define_expand "clzsi2"
14649 [(set (match_operand:SI 0 "register_operand" "")
14650 (minus:SI (const_int 31)
14651 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14652 (clobber (reg:CC FLAGS_REG))])
14654 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14655 (clobber (reg:CC FLAGS_REG))])]
14660 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14665 (define_insn "clzsi2_abm"
14666 [(set (match_operand:SI 0 "register_operand" "=r")
14667 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14668 (clobber (reg:CC FLAGS_REG))]
14670 "lzcnt{l}\t{%1, %0|%0, %1}"
14671 [(set_attr "prefix_rep" "1")
14672 (set_attr "type" "bitmanip")
14673 (set_attr "mode" "SI")])
14675 (define_insn "*bsr"
14676 [(set (match_operand:SI 0 "register_operand" "=r")
14677 (minus:SI (const_int 31)
14678 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14679 (clobber (reg:CC FLAGS_REG))]
14681 "bsr{l}\t{%1, %0|%0, %1}"
14682 [(set_attr "prefix_0f" "1")
14683 (set_attr "mode" "SI")])
14685 (define_insn "popcountsi2"
14686 [(set (match_operand:SI 0 "register_operand" "=r")
14687 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14688 (clobber (reg:CC FLAGS_REG))]
14690 "popcnt{l}\t{%1, %0|%0, %1}"
14691 [(set_attr "prefix_rep" "1")
14692 (set_attr "type" "bitmanip")
14693 (set_attr "mode" "SI")])
14695 (define_insn "*popcountsi2_cmp"
14696 [(set (reg FLAGS_REG)
14698 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14700 (set (match_operand:SI 0 "register_operand" "=r")
14701 (popcount:SI (match_dup 1)))]
14702 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14703 "popcnt{l}\t{%1, %0|%0, %1}"
14704 [(set_attr "prefix_rep" "1")
14705 (set_attr "type" "bitmanip")
14706 (set_attr "mode" "SI")])
14708 (define_insn "*popcountsi2_cmp_zext"
14709 [(set (reg FLAGS_REG)
14711 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14713 (set (match_operand:DI 0 "register_operand" "=r")
14714 (zero_extend:DI(popcount:SI (match_dup 1))))]
14715 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14716 "popcnt{l}\t{%1, %0|%0, %1}"
14717 [(set_attr "prefix_rep" "1")
14718 (set_attr "type" "bitmanip")
14719 (set_attr "mode" "SI")])
14721 (define_expand "bswapsi2"
14722 [(set (match_operand:SI 0 "register_operand" "")
14723 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14728 rtx x = operands[0];
14730 emit_move_insn (x, operands[1]);
14731 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14732 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14733 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14738 (define_insn "*bswapsi_1"
14739 [(set (match_operand:SI 0 "register_operand" "=r")
14740 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14743 [(set_attr "prefix_0f" "1")
14744 (set_attr "length" "2")])
14746 (define_insn "*bswaphi_lowpart_1"
14747 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14748 (bswap:HI (match_dup 0)))
14749 (clobber (reg:CC FLAGS_REG))]
14750 "TARGET_USE_XCHGB || optimize_size"
14752 xchg{b}\t{%h0, %b0|%b0, %h0}
14753 rol{w}\t{$8, %0|%0, 8}"
14754 [(set_attr "length" "2,4")
14755 (set_attr "mode" "QI,HI")])
14757 (define_insn "bswaphi_lowpart"
14758 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14759 (bswap:HI (match_dup 0)))
14760 (clobber (reg:CC FLAGS_REG))]
14762 "rol{w}\t{$8, %0|%0, 8}"
14763 [(set_attr "length" "4")
14764 (set_attr "mode" "HI")])
14766 (define_insn "bswapdi2"
14767 [(set (match_operand:DI 0 "register_operand" "=r")
14768 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14771 [(set_attr "prefix_0f" "1")
14772 (set_attr "length" "3")])
14774 (define_expand "clzdi2"
14776 [(set (match_operand:DI 0 "register_operand" "")
14777 (minus:DI (const_int 63)
14778 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14779 (clobber (reg:CC FLAGS_REG))])
14781 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14782 (clobber (reg:CC FLAGS_REG))])]
14787 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14792 (define_insn "clzdi2_abm"
14793 [(set (match_operand:DI 0 "register_operand" "=r")
14794 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14795 (clobber (reg:CC FLAGS_REG))]
14796 "TARGET_64BIT && TARGET_ABM"
14797 "lzcnt{q}\t{%1, %0|%0, %1}"
14798 [(set_attr "prefix_rep" "1")
14799 (set_attr "type" "bitmanip")
14800 (set_attr "mode" "DI")])
14802 (define_insn "*bsr_rex64"
14803 [(set (match_operand:DI 0 "register_operand" "=r")
14804 (minus:DI (const_int 63)
14805 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14806 (clobber (reg:CC FLAGS_REG))]
14808 "bsr{q}\t{%1, %0|%0, %1}"
14809 [(set_attr "prefix_0f" "1")
14810 (set_attr "mode" "DI")])
14812 (define_insn "popcountdi2"
14813 [(set (match_operand:DI 0 "register_operand" "=r")
14814 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14815 (clobber (reg:CC FLAGS_REG))]
14816 "TARGET_64BIT && TARGET_POPCNT"
14817 "popcnt{q}\t{%1, %0|%0, %1}"
14818 [(set_attr "prefix_rep" "1")
14819 (set_attr "type" "bitmanip")
14820 (set_attr "mode" "DI")])
14822 (define_insn "*popcountdi2_cmp"
14823 [(set (reg FLAGS_REG)
14825 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14827 (set (match_operand:DI 0 "register_operand" "=r")
14828 (popcount:DI (match_dup 1)))]
14829 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14830 "popcnt{q}\t{%1, %0|%0, %1}"
14831 [(set_attr "prefix_rep" "1")
14832 (set_attr "type" "bitmanip")
14833 (set_attr "mode" "DI")])
14835 (define_expand "clzhi2"
14837 [(set (match_operand:HI 0 "register_operand" "")
14838 (minus:HI (const_int 15)
14839 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14840 (clobber (reg:CC FLAGS_REG))])
14842 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14843 (clobber (reg:CC FLAGS_REG))])]
14848 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14853 (define_insn "clzhi2_abm"
14854 [(set (match_operand:HI 0 "register_operand" "=r")
14855 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14856 (clobber (reg:CC FLAGS_REG))]
14858 "lzcnt{w}\t{%1, %0|%0, %1}"
14859 [(set_attr "prefix_rep" "1")
14860 (set_attr "type" "bitmanip")
14861 (set_attr "mode" "HI")])
14863 (define_insn "*bsrhi"
14864 [(set (match_operand:HI 0 "register_operand" "=r")
14865 (minus:HI (const_int 15)
14866 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14867 (clobber (reg:CC FLAGS_REG))]
14869 "bsr{w}\t{%1, %0|%0, %1}"
14870 [(set_attr "prefix_0f" "1")
14871 (set_attr "mode" "HI")])
14873 (define_insn "popcounthi2"
14874 [(set (match_operand:HI 0 "register_operand" "=r")
14875 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14876 (clobber (reg:CC FLAGS_REG))]
14878 "popcnt{w}\t{%1, %0|%0, %1}"
14879 [(set_attr "prefix_rep" "1")
14880 (set_attr "type" "bitmanip")
14881 (set_attr "mode" "HI")])
14883 (define_insn "*popcounthi2_cmp"
14884 [(set (reg FLAGS_REG)
14886 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14888 (set (match_operand:HI 0 "register_operand" "=r")
14889 (popcount:HI (match_dup 1)))]
14890 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14891 "popcnt{w}\t{%1, %0|%0, %1}"
14892 [(set_attr "prefix_rep" "1")
14893 (set_attr "type" "bitmanip")
14894 (set_attr "mode" "HI")])
14896 (define_expand "paritydi2"
14897 [(set (match_operand:DI 0 "register_operand" "")
14898 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
14901 rtx scratch = gen_reg_rtx (QImode);
14904 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14905 NULL_RTX, operands[1]));
14907 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14908 gen_rtx_REG (CCmode, FLAGS_REG),
14910 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14913 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14916 rtx tmp = gen_reg_rtx (SImode);
14918 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14919 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14924 (define_insn_and_split "paritydi2_cmp"
14925 [(set (reg:CC FLAGS_REG)
14926 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
14927 (clobber (match_scratch:DI 0 "=r,X"))
14928 (clobber (match_scratch:SI 1 "=r,r"))
14929 (clobber (match_scratch:HI 2 "=Q,Q"))]
14932 "&& reload_completed"
14934 [(set (match_dup 1)
14935 (xor:SI (match_dup 1) (match_dup 4)))
14936 (clobber (reg:CC FLAGS_REG))])
14938 [(set (reg:CC FLAGS_REG)
14939 (parity:CC (match_dup 1)))
14940 (clobber (match_dup 1))
14941 (clobber (match_dup 2))])]
14943 operands[4] = gen_lowpart (SImode, operands[3]);
14945 if (MEM_P (operands[3]))
14946 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
14947 else if (! TARGET_64BIT)
14948 operands[1] = gen_highpart (SImode, operands[3]);
14951 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14952 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14956 (define_expand "paritysi2"
14957 [(set (match_operand:SI 0 "register_operand" "")
14958 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
14961 rtx scratch = gen_reg_rtx (QImode);
14964 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14966 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14967 gen_rtx_REG (CCmode, FLAGS_REG),
14969 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14971 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14975 (define_insn_and_split "paritysi2_cmp"
14976 [(set (reg:CC FLAGS_REG)
14977 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
14978 (clobber (match_scratch:SI 0 "=r,X"))
14979 (clobber (match_scratch:HI 1 "=Q,Q"))]
14982 "&& reload_completed"
14984 [(set (match_dup 1)
14985 (xor:HI (match_dup 1) (match_dup 3)))
14986 (clobber (reg:CC FLAGS_REG))])
14988 [(set (reg:CC FLAGS_REG)
14989 (parity:CC (match_dup 1)))
14990 (clobber (match_dup 1))])]
14992 operands[3] = gen_lowpart (HImode, operands[2]);
14994 if (MEM_P (operands[2]))
14995 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
14998 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14999 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15003 (define_insn "*parityhi2_cmp"
15004 [(set (reg:CC FLAGS_REG)
15005 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15006 (clobber (match_scratch:HI 0 "=Q"))]
15008 "xor{b}\t{%h0, %b0|%b0, %h0}"
15009 [(set_attr "length" "2")
15010 (set_attr "mode" "HI")])
15012 (define_insn "*parityqi2_cmp"
15013 [(set (reg:CC FLAGS_REG)
15014 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15017 [(set_attr "length" "2")
15018 (set_attr "mode" "QI")])
15020 ;; Thread-local storage patterns for ELF.
15022 ;; Note that these code sequences must appear exactly as shown
15023 ;; in order to allow linker relaxation.
15025 (define_insn "*tls_global_dynamic_32_gnu"
15026 [(set (match_operand:SI 0 "register_operand" "=a")
15027 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15028 (match_operand:SI 2 "tls_symbolic_operand" "")
15029 (match_operand:SI 3 "call_insn_operand" "")]
15031 (clobber (match_scratch:SI 4 "=d"))
15032 (clobber (match_scratch:SI 5 "=c"))
15033 (clobber (reg:CC FLAGS_REG))]
15034 "!TARGET_64BIT && TARGET_GNU_TLS"
15035 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15036 [(set_attr "type" "multi")
15037 (set_attr "length" "12")])
15039 (define_insn "*tls_global_dynamic_32_sun"
15040 [(set (match_operand:SI 0 "register_operand" "=a")
15041 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15042 (match_operand:SI 2 "tls_symbolic_operand" "")
15043 (match_operand:SI 3 "call_insn_operand" "")]
15045 (clobber (match_scratch:SI 4 "=d"))
15046 (clobber (match_scratch:SI 5 "=c"))
15047 (clobber (reg:CC FLAGS_REG))]
15048 "!TARGET_64BIT && TARGET_SUN_TLS"
15049 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15050 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15051 [(set_attr "type" "multi")
15052 (set_attr "length" "14")])
15054 (define_expand "tls_global_dynamic_32"
15055 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15058 (match_operand:SI 1 "tls_symbolic_operand" "")
15061 (clobber (match_scratch:SI 4 ""))
15062 (clobber (match_scratch:SI 5 ""))
15063 (clobber (reg:CC FLAGS_REG))])]
15067 operands[2] = pic_offset_table_rtx;
15070 operands[2] = gen_reg_rtx (Pmode);
15071 emit_insn (gen_set_got (operands[2]));
15073 if (TARGET_GNU2_TLS)
15075 emit_insn (gen_tls_dynamic_gnu2_32
15076 (operands[0], operands[1], operands[2]));
15079 operands[3] = ix86_tls_get_addr ();
15082 (define_insn "*tls_global_dynamic_64"
15083 [(set (match_operand:DI 0 "register_operand" "=a")
15084 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15085 (match_operand:DI 3 "" "")))
15086 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15089 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15090 [(set_attr "type" "multi")
15091 (set_attr "length" "16")])
15093 (define_expand "tls_global_dynamic_64"
15094 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15095 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15096 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15100 if (TARGET_GNU2_TLS)
15102 emit_insn (gen_tls_dynamic_gnu2_64
15103 (operands[0], operands[1]));
15106 operands[2] = ix86_tls_get_addr ();
15109 (define_insn "*tls_local_dynamic_base_32_gnu"
15110 [(set (match_operand:SI 0 "register_operand" "=a")
15111 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15112 (match_operand:SI 2 "call_insn_operand" "")]
15113 UNSPEC_TLS_LD_BASE))
15114 (clobber (match_scratch:SI 3 "=d"))
15115 (clobber (match_scratch:SI 4 "=c"))
15116 (clobber (reg:CC FLAGS_REG))]
15117 "!TARGET_64BIT && TARGET_GNU_TLS"
15118 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15119 [(set_attr "type" "multi")
15120 (set_attr "length" "11")])
15122 (define_insn "*tls_local_dynamic_base_32_sun"
15123 [(set (match_operand:SI 0 "register_operand" "=a")
15124 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15125 (match_operand:SI 2 "call_insn_operand" "")]
15126 UNSPEC_TLS_LD_BASE))
15127 (clobber (match_scratch:SI 3 "=d"))
15128 (clobber (match_scratch:SI 4 "=c"))
15129 (clobber (reg:CC FLAGS_REG))]
15130 "!TARGET_64BIT && TARGET_SUN_TLS"
15131 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15132 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15133 [(set_attr "type" "multi")
15134 (set_attr "length" "13")])
15136 (define_expand "tls_local_dynamic_base_32"
15137 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15138 (unspec:SI [(match_dup 1) (match_dup 2)]
15139 UNSPEC_TLS_LD_BASE))
15140 (clobber (match_scratch:SI 3 ""))
15141 (clobber (match_scratch:SI 4 ""))
15142 (clobber (reg:CC FLAGS_REG))])]
15146 operands[1] = pic_offset_table_rtx;
15149 operands[1] = gen_reg_rtx (Pmode);
15150 emit_insn (gen_set_got (operands[1]));
15152 if (TARGET_GNU2_TLS)
15154 emit_insn (gen_tls_dynamic_gnu2_32
15155 (operands[0], ix86_tls_module_base (), operands[1]));
15158 operands[2] = ix86_tls_get_addr ();
15161 (define_insn "*tls_local_dynamic_base_64"
15162 [(set (match_operand:DI 0 "register_operand" "=a")
15163 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15164 (match_operand:DI 2 "" "")))
15165 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15167 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15168 [(set_attr "type" "multi")
15169 (set_attr "length" "12")])
15171 (define_expand "tls_local_dynamic_base_64"
15172 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15173 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15174 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15177 if (TARGET_GNU2_TLS)
15179 emit_insn (gen_tls_dynamic_gnu2_64
15180 (operands[0], ix86_tls_module_base ()));
15183 operands[1] = ix86_tls_get_addr ();
15186 ;; Local dynamic of a single variable is a lose. Show combine how
15187 ;; to convert that back to global dynamic.
15189 (define_insn_and_split "*tls_local_dynamic_32_once"
15190 [(set (match_operand:SI 0 "register_operand" "=a")
15191 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15192 (match_operand:SI 2 "call_insn_operand" "")]
15193 UNSPEC_TLS_LD_BASE)
15194 (const:SI (unspec:SI
15195 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15197 (clobber (match_scratch:SI 4 "=d"))
15198 (clobber (match_scratch:SI 5 "=c"))
15199 (clobber (reg:CC FLAGS_REG))]
15203 [(parallel [(set (match_dup 0)
15204 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15206 (clobber (match_dup 4))
15207 (clobber (match_dup 5))
15208 (clobber (reg:CC FLAGS_REG))])]
15211 ;; Load and add the thread base pointer from %gs:0.
15213 (define_insn "*load_tp_si"
15214 [(set (match_operand:SI 0 "register_operand" "=r")
15215 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15217 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15218 [(set_attr "type" "imov")
15219 (set_attr "modrm" "0")
15220 (set_attr "length" "7")
15221 (set_attr "memory" "load")
15222 (set_attr "imm_disp" "false")])
15224 (define_insn "*add_tp_si"
15225 [(set (match_operand:SI 0 "register_operand" "=r")
15226 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15227 (match_operand:SI 1 "register_operand" "0")))
15228 (clobber (reg:CC FLAGS_REG))]
15230 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15231 [(set_attr "type" "alu")
15232 (set_attr "modrm" "0")
15233 (set_attr "length" "7")
15234 (set_attr "memory" "load")
15235 (set_attr "imm_disp" "false")])
15237 (define_insn "*load_tp_di"
15238 [(set (match_operand:DI 0 "register_operand" "=r")
15239 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15241 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15242 [(set_attr "type" "imov")
15243 (set_attr "modrm" "0")
15244 (set_attr "length" "7")
15245 (set_attr "memory" "load")
15246 (set_attr "imm_disp" "false")])
15248 (define_insn "*add_tp_di"
15249 [(set (match_operand:DI 0 "register_operand" "=r")
15250 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15251 (match_operand:DI 1 "register_operand" "0")))
15252 (clobber (reg:CC FLAGS_REG))]
15254 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15255 [(set_attr "type" "alu")
15256 (set_attr "modrm" "0")
15257 (set_attr "length" "7")
15258 (set_attr "memory" "load")
15259 (set_attr "imm_disp" "false")])
15261 ;; GNU2 TLS patterns can be split.
15263 (define_expand "tls_dynamic_gnu2_32"
15264 [(set (match_dup 3)
15265 (plus:SI (match_operand:SI 2 "register_operand" "")
15267 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15270 [(set (match_operand:SI 0 "register_operand" "")
15271 (unspec:SI [(match_dup 1) (match_dup 3)
15272 (match_dup 2) (reg:SI SP_REG)]
15274 (clobber (reg:CC FLAGS_REG))])]
15275 "!TARGET_64BIT && TARGET_GNU2_TLS"
15277 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15278 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15281 (define_insn "*tls_dynamic_lea_32"
15282 [(set (match_operand:SI 0 "register_operand" "=r")
15283 (plus:SI (match_operand:SI 1 "register_operand" "b")
15285 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15286 UNSPEC_TLSDESC))))]
15287 "!TARGET_64BIT && TARGET_GNU2_TLS"
15288 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15289 [(set_attr "type" "lea")
15290 (set_attr "mode" "SI")
15291 (set_attr "length" "6")
15292 (set_attr "length_address" "4")])
15294 (define_insn "*tls_dynamic_call_32"
15295 [(set (match_operand:SI 0 "register_operand" "=a")
15296 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15297 (match_operand:SI 2 "register_operand" "0")
15298 ;; we have to make sure %ebx still points to the GOT
15299 (match_operand:SI 3 "register_operand" "b")
15302 (clobber (reg:CC FLAGS_REG))]
15303 "!TARGET_64BIT && TARGET_GNU2_TLS"
15304 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15305 [(set_attr "type" "call")
15306 (set_attr "length" "2")
15307 (set_attr "length_address" "0")])
15309 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15310 [(set (match_operand:SI 0 "register_operand" "=&a")
15312 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15313 (match_operand:SI 4 "" "")
15314 (match_operand:SI 2 "register_operand" "b")
15317 (const:SI (unspec:SI
15318 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15320 (clobber (reg:CC FLAGS_REG))]
15321 "!TARGET_64BIT && TARGET_GNU2_TLS"
15324 [(set (match_dup 0) (match_dup 5))]
15326 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15327 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15330 (define_expand "tls_dynamic_gnu2_64"
15331 [(set (match_dup 2)
15332 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15335 [(set (match_operand:DI 0 "register_operand" "")
15336 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15338 (clobber (reg:CC FLAGS_REG))])]
15339 "TARGET_64BIT && TARGET_GNU2_TLS"
15341 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15342 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15345 (define_insn "*tls_dynamic_lea_64"
15346 [(set (match_operand:DI 0 "register_operand" "=r")
15347 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15349 "TARGET_64BIT && TARGET_GNU2_TLS"
15350 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15351 [(set_attr "type" "lea")
15352 (set_attr "mode" "DI")
15353 (set_attr "length" "7")
15354 (set_attr "length_address" "4")])
15356 (define_insn "*tls_dynamic_call_64"
15357 [(set (match_operand:DI 0 "register_operand" "=a")
15358 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15359 (match_operand:DI 2 "register_operand" "0")
15362 (clobber (reg:CC FLAGS_REG))]
15363 "TARGET_64BIT && TARGET_GNU2_TLS"
15364 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15365 [(set_attr "type" "call")
15366 (set_attr "length" "2")
15367 (set_attr "length_address" "0")])
15369 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15370 [(set (match_operand:DI 0 "register_operand" "=&a")
15372 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15373 (match_operand:DI 3 "" "")
15376 (const:DI (unspec:DI
15377 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15379 (clobber (reg:CC FLAGS_REG))]
15380 "TARGET_64BIT && TARGET_GNU2_TLS"
15383 [(set (match_dup 0) (match_dup 4))]
15385 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15386 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15391 ;; These patterns match the binary 387 instructions for addM3, subM3,
15392 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15393 ;; SFmode. The first is the normal insn, the second the same insn but
15394 ;; with one operand a conversion, and the third the same insn but with
15395 ;; the other operand a conversion. The conversion may be SFmode or
15396 ;; SImode if the target mode DFmode, but only SImode if the target mode
15399 ;; Gcc is slightly more smart about handling normal two address instructions
15400 ;; so use special patterns for add and mull.
15402 (define_insn "*fop_sf_comm_mixed"
15403 [(set (match_operand:SF 0 "register_operand" "=f,x")
15404 (match_operator:SF 3 "binary_fp_operator"
15405 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15406 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15407 "TARGET_MIX_SSE_I387
15408 && COMMUTATIVE_ARITH_P (operands[3])
15409 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15410 "* return output_387_binary_op (insn, operands);"
15411 [(set (attr "type")
15412 (if_then_else (eq_attr "alternative" "1")
15413 (if_then_else (match_operand:SF 3 "mult_operator" "")
15414 (const_string "ssemul")
15415 (const_string "sseadd"))
15416 (if_then_else (match_operand:SF 3 "mult_operator" "")
15417 (const_string "fmul")
15418 (const_string "fop"))))
15419 (set_attr "mode" "SF")])
15421 (define_insn "*fop_sf_comm_sse"
15422 [(set (match_operand:SF 0 "register_operand" "=x")
15423 (match_operator:SF 3 "binary_fp_operator"
15424 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15425 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15427 && COMMUTATIVE_ARITH_P (operands[3])
15428 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15429 "* return output_387_binary_op (insn, operands);"
15430 [(set (attr "type")
15431 (if_then_else (match_operand:SF 3 "mult_operator" "")
15432 (const_string "ssemul")
15433 (const_string "sseadd")))
15434 (set_attr "mode" "SF")])
15436 (define_insn "*fop_sf_comm_i387"
15437 [(set (match_operand:SF 0 "register_operand" "=f")
15438 (match_operator:SF 3 "binary_fp_operator"
15439 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15440 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15442 && COMMUTATIVE_ARITH_P (operands[3])
15443 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15444 "* return output_387_binary_op (insn, operands);"
15445 [(set (attr "type")
15446 (if_then_else (match_operand:SF 3 "mult_operator" "")
15447 (const_string "fmul")
15448 (const_string "fop")))
15449 (set_attr "mode" "SF")])
15451 (define_insn "*fop_sf_1_mixed"
15452 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15453 (match_operator:SF 3 "binary_fp_operator"
15454 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15455 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15456 "TARGET_MIX_SSE_I387
15457 && !COMMUTATIVE_ARITH_P (operands[3])
15458 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15459 "* return output_387_binary_op (insn, operands);"
15460 [(set (attr "type")
15461 (cond [(and (eq_attr "alternative" "2")
15462 (match_operand:SF 3 "mult_operator" ""))
15463 (const_string "ssemul")
15464 (and (eq_attr "alternative" "2")
15465 (match_operand:SF 3 "div_operator" ""))
15466 (const_string "ssediv")
15467 (eq_attr "alternative" "2")
15468 (const_string "sseadd")
15469 (match_operand:SF 3 "mult_operator" "")
15470 (const_string "fmul")
15471 (match_operand:SF 3 "div_operator" "")
15472 (const_string "fdiv")
15474 (const_string "fop")))
15475 (set_attr "mode" "SF")])
15477 (define_insn "*fop_sf_1_sse"
15478 [(set (match_operand:SF 0 "register_operand" "=x")
15479 (match_operator:SF 3 "binary_fp_operator"
15480 [(match_operand:SF 1 "register_operand" "0")
15481 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15483 && !COMMUTATIVE_ARITH_P (operands[3])"
15484 "* return output_387_binary_op (insn, operands);"
15485 [(set (attr "type")
15486 (cond [(match_operand:SF 3 "mult_operator" "")
15487 (const_string "ssemul")
15488 (match_operand:SF 3 "div_operator" "")
15489 (const_string "ssediv")
15491 (const_string "sseadd")))
15492 (set_attr "mode" "SF")])
15494 ;; This pattern is not fully shadowed by the pattern above.
15495 (define_insn "*fop_sf_1_i387"
15496 [(set (match_operand:SF 0 "register_operand" "=f,f")
15497 (match_operator:SF 3 "binary_fp_operator"
15498 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15499 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15500 "TARGET_80387 && !TARGET_SSE_MATH
15501 && !COMMUTATIVE_ARITH_P (operands[3])
15502 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15503 "* return output_387_binary_op (insn, operands);"
15504 [(set (attr "type")
15505 (cond [(match_operand:SF 3 "mult_operator" "")
15506 (const_string "fmul")
15507 (match_operand:SF 3 "div_operator" "")
15508 (const_string "fdiv")
15510 (const_string "fop")))
15511 (set_attr "mode" "SF")])
15513 ;; ??? Add SSE splitters for these!
15514 (define_insn "*fop_sf_2<mode>_i387"
15515 [(set (match_operand:SF 0 "register_operand" "=f,f")
15516 (match_operator:SF 3 "binary_fp_operator"
15517 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15518 (match_operand:SF 2 "register_operand" "0,0")]))]
15519 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15520 "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
15529 (set_attr "mode" "<MODE>")])
15531 (define_insn "*fop_sf_3<mode>_i387"
15532 [(set (match_operand:SF 0 "register_operand" "=f,f")
15533 (match_operator:SF 3 "binary_fp_operator"
15534 [(match_operand:SF 1 "register_operand" "0,0")
15535 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
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_df_comm_mixed"
15549 [(set (match_operand:DF 0 "register_operand" "=f,x")
15550 (match_operator:DF 3 "binary_fp_operator"
15551 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15552 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15553 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15554 && COMMUTATIVE_ARITH_P (operands[3])
15555 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15556 "* return output_387_binary_op (insn, operands);"
15557 [(set (attr "type")
15558 (if_then_else (eq_attr "alternative" "1")
15559 (if_then_else (match_operand:DF 3 "mult_operator" "")
15560 (const_string "ssemul")
15561 (const_string "sseadd"))
15562 (if_then_else (match_operand:DF 3 "mult_operator" "")
15563 (const_string "fmul")
15564 (const_string "fop"))))
15565 (set_attr "mode" "DF")])
15567 (define_insn "*fop_df_comm_sse"
15568 [(set (match_operand:DF 0 "register_operand" "=x")
15569 (match_operator:DF 3 "binary_fp_operator"
15570 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15571 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15572 "TARGET_SSE2 && TARGET_SSE_MATH
15573 && COMMUTATIVE_ARITH_P (operands[3])
15574 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15575 "* return output_387_binary_op (insn, operands);"
15576 [(set (attr "type")
15577 (if_then_else (match_operand:DF 3 "mult_operator" "")
15578 (const_string "ssemul")
15579 (const_string "sseadd")))
15580 (set_attr "mode" "DF")])
15582 (define_insn "*fop_df_comm_i387"
15583 [(set (match_operand:DF 0 "register_operand" "=f")
15584 (match_operator:DF 3 "binary_fp_operator"
15585 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15586 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15588 && COMMUTATIVE_ARITH_P (operands[3])
15589 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15590 "* return output_387_binary_op (insn, operands);"
15591 [(set (attr "type")
15592 (if_then_else (match_operand:DF 3 "mult_operator" "")
15593 (const_string "fmul")
15594 (const_string "fop")))
15595 (set_attr "mode" "DF")])
15597 (define_insn "*fop_df_1_mixed"
15598 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15599 (match_operator:DF 3 "binary_fp_operator"
15600 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15601 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15602 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15603 && !COMMUTATIVE_ARITH_P (operands[3])
15604 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15605 "* return output_387_binary_op (insn, operands);"
15606 [(set (attr "type")
15607 (cond [(and (eq_attr "alternative" "2")
15608 (match_operand:DF 3 "mult_operator" ""))
15609 (const_string "ssemul")
15610 (and (eq_attr "alternative" "2")
15611 (match_operand:DF 3 "div_operator" ""))
15612 (const_string "ssediv")
15613 (eq_attr "alternative" "2")
15614 (const_string "sseadd")
15615 (match_operand:DF 3 "mult_operator" "")
15616 (const_string "fmul")
15617 (match_operand:DF 3 "div_operator" "")
15618 (const_string "fdiv")
15620 (const_string "fop")))
15621 (set_attr "mode" "DF")])
15623 (define_insn "*fop_df_1_sse"
15624 [(set (match_operand:DF 0 "register_operand" "=x")
15625 (match_operator:DF 3 "binary_fp_operator"
15626 [(match_operand:DF 1 "register_operand" "0")
15627 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15628 "TARGET_SSE2 && TARGET_SSE_MATH
15629 && !COMMUTATIVE_ARITH_P (operands[3])"
15630 "* return output_387_binary_op (insn, operands);"
15631 [(set_attr "mode" "DF")
15633 (cond [(match_operand:DF 3 "mult_operator" "")
15634 (const_string "ssemul")
15635 (match_operand:DF 3 "div_operator" "")
15636 (const_string "ssediv")
15638 (const_string "sseadd")))])
15640 ;; This pattern is not fully shadowed by the pattern above.
15641 (define_insn "*fop_df_1_i387"
15642 [(set (match_operand:DF 0 "register_operand" "=f,f")
15643 (match_operator:DF 3 "binary_fp_operator"
15644 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15645 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15646 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15647 && !COMMUTATIVE_ARITH_P (operands[3])
15648 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15649 "* return output_387_binary_op (insn, operands);"
15650 [(set (attr "type")
15651 (cond [(match_operand:DF 3 "mult_operator" "")
15652 (const_string "fmul")
15653 (match_operand:DF 3 "div_operator" "")
15654 (const_string "fdiv")
15656 (const_string "fop")))
15657 (set_attr "mode" "DF")])
15659 ;; ??? Add SSE splitters for these!
15660 (define_insn "*fop_df_2<mode>_i387"
15661 [(set (match_operand:DF 0 "register_operand" "=f,f")
15662 (match_operator:DF 3 "binary_fp_operator"
15663 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15664 (match_operand:DF 2 "register_operand" "0,0")]))]
15665 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15666 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15667 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15668 [(set (attr "type")
15669 (cond [(match_operand:DF 3 "mult_operator" "")
15670 (const_string "fmul")
15671 (match_operand:DF 3 "div_operator" "")
15672 (const_string "fdiv")
15674 (const_string "fop")))
15675 (set_attr "fp_int_src" "true")
15676 (set_attr "mode" "<MODE>")])
15678 (define_insn "*fop_df_3<mode>_i387"
15679 [(set (match_operand:DF 0 "register_operand" "=f,f")
15680 (match_operator:DF 3 "binary_fp_operator"
15681 [(match_operand:DF 1 "register_operand" "0,0")
15682 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15683 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15684 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15685 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15686 [(set (attr "type")
15687 (cond [(match_operand:DF 3 "mult_operator" "")
15688 (const_string "fmul")
15689 (match_operand:DF 3 "div_operator" "")
15690 (const_string "fdiv")
15692 (const_string "fop")))
15693 (set_attr "fp_int_src" "true")
15694 (set_attr "mode" "<MODE>")])
15696 (define_insn "*fop_df_4_i387"
15697 [(set (match_operand:DF 0 "register_operand" "=f,f")
15698 (match_operator:DF 3 "binary_fp_operator"
15699 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15700 (match_operand:DF 2 "register_operand" "0,f")]))]
15701 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15702 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15703 "* return output_387_binary_op (insn, operands);"
15704 [(set (attr "type")
15705 (cond [(match_operand:DF 3 "mult_operator" "")
15706 (const_string "fmul")
15707 (match_operand:DF 3 "div_operator" "")
15708 (const_string "fdiv")
15710 (const_string "fop")))
15711 (set_attr "mode" "SF")])
15713 (define_insn "*fop_df_5_i387"
15714 [(set (match_operand:DF 0 "register_operand" "=f,f")
15715 (match_operator:DF 3 "binary_fp_operator"
15716 [(match_operand:DF 1 "register_operand" "0,f")
15718 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15719 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
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_6_i387"
15731 [(set (match_operand:DF 0 "register_operand" "=f,f")
15732 (match_operator:DF 3 "binary_fp_operator"
15734 (match_operand:SF 1 "register_operand" "0,f"))
15736 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15737 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15738 "* return output_387_binary_op (insn, operands);"
15739 [(set (attr "type")
15740 (cond [(match_operand:DF 3 "mult_operator" "")
15741 (const_string "fmul")
15742 (match_operand:DF 3 "div_operator" "")
15743 (const_string "fdiv")
15745 (const_string "fop")))
15746 (set_attr "mode" "SF")])
15748 (define_insn "*fop_xf_comm_i387"
15749 [(set (match_operand:XF 0 "register_operand" "=f")
15750 (match_operator:XF 3 "binary_fp_operator"
15751 [(match_operand:XF 1 "register_operand" "%0")
15752 (match_operand:XF 2 "register_operand" "f")]))]
15754 && COMMUTATIVE_ARITH_P (operands[3])"
15755 "* return output_387_binary_op (insn, operands);"
15756 [(set (attr "type")
15757 (if_then_else (match_operand:XF 3 "mult_operator" "")
15758 (const_string "fmul")
15759 (const_string "fop")))
15760 (set_attr "mode" "XF")])
15762 (define_insn "*fop_xf_1_i387"
15763 [(set (match_operand:XF 0 "register_operand" "=f,f")
15764 (match_operator:XF 3 "binary_fp_operator"
15765 [(match_operand:XF 1 "register_operand" "0,f")
15766 (match_operand:XF 2 "register_operand" "f,0")]))]
15768 && !COMMUTATIVE_ARITH_P (operands[3])"
15769 "* return output_387_binary_op (insn, operands);"
15770 [(set (attr "type")
15771 (cond [(match_operand:XF 3 "mult_operator" "")
15772 (const_string "fmul")
15773 (match_operand:XF 3 "div_operator" "")
15774 (const_string "fdiv")
15776 (const_string "fop")))
15777 (set_attr "mode" "XF")])
15779 (define_insn "*fop_xf_2<mode>_i387"
15780 [(set (match_operand:XF 0 "register_operand" "=f,f")
15781 (match_operator:XF 3 "binary_fp_operator"
15782 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15783 (match_operand:XF 2 "register_operand" "0,0")]))]
15784 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15785 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15786 [(set (attr "type")
15787 (cond [(match_operand:XF 3 "mult_operator" "")
15788 (const_string "fmul")
15789 (match_operand:XF 3 "div_operator" "")
15790 (const_string "fdiv")
15792 (const_string "fop")))
15793 (set_attr "fp_int_src" "true")
15794 (set_attr "mode" "<MODE>")])
15796 (define_insn "*fop_xf_3<mode>_i387"
15797 [(set (match_operand:XF 0 "register_operand" "=f,f")
15798 (match_operator:XF 3 "binary_fp_operator"
15799 [(match_operand:XF 1 "register_operand" "0,0")
15800 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
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_4_i387"
15814 [(set (match_operand:XF 0 "register_operand" "=f,f")
15815 (match_operator:XF 3 "binary_fp_operator"
15817 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15818 (match_operand:XF 2 "register_operand" "0,f")]))]
15820 "* return output_387_binary_op (insn, operands);"
15821 [(set (attr "type")
15822 (cond [(match_operand:XF 3 "mult_operator" "")
15823 (const_string "fmul")
15824 (match_operand:XF 3 "div_operator" "")
15825 (const_string "fdiv")
15827 (const_string "fop")))
15828 (set_attr "mode" "SF")])
15830 (define_insn "*fop_xf_5_i387"
15831 [(set (match_operand:XF 0 "register_operand" "=f,f")
15832 (match_operator:XF 3 "binary_fp_operator"
15833 [(match_operand:XF 1 "register_operand" "0,f")
15835 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
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_6_i387"
15848 [(set (match_operand:XF 0 "register_operand" "=f,f")
15849 (match_operator:XF 3 "binary_fp_operator"
15851 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15853 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15855 "* return output_387_binary_op (insn, operands);"
15856 [(set (attr "type")
15857 (cond [(match_operand:XF 3 "mult_operator" "")
15858 (const_string "fmul")
15859 (match_operand:XF 3 "div_operator" "")
15860 (const_string "fdiv")
15862 (const_string "fop")))
15863 (set_attr "mode" "SF")])
15866 [(set (match_operand 0 "register_operand" "")
15867 (match_operator 3 "binary_fp_operator"
15868 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15869 (match_operand 2 "register_operand" "")]))]
15871 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15874 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15875 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15876 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15877 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15878 GET_MODE (operands[3]),
15881 ix86_free_from_memory (GET_MODE (operands[1]));
15886 [(set (match_operand 0 "register_operand" "")
15887 (match_operator 3 "binary_fp_operator"
15888 [(match_operand 1 "register_operand" "")
15889 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15891 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15894 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15895 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15896 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15897 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15898 GET_MODE (operands[3]),
15901 ix86_free_from_memory (GET_MODE (operands[2]));
15905 ;; FPU special functions.
15907 ;; This pattern implements a no-op XFmode truncation for
15908 ;; all fancy i386 XFmode math functions.
15910 (define_insn "truncxf<mode>2_i387_noop_unspec"
15911 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15912 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15913 UNSPEC_TRUNC_NOOP))]
15914 "TARGET_USE_FANCY_MATH_387"
15915 "* return output_387_reg_move (insn, operands);"
15916 [(set_attr "type" "fmov")
15917 (set_attr "mode" "<MODE>")])
15919 (define_insn "sqrtxf2"
15920 [(set (match_operand:XF 0 "register_operand" "=f")
15921 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15922 "TARGET_USE_FANCY_MATH_387"
15924 [(set_attr "type" "fpspc")
15925 (set_attr "mode" "XF")
15926 (set_attr "athlon_decode" "direct")
15927 (set_attr "amdfam10_decode" "direct")])
15929 (define_insn "sqrt_extend<mode>xf2_i387"
15930 [(set (match_operand:XF 0 "register_operand" "=f")
15933 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15934 "TARGET_USE_FANCY_MATH_387"
15936 [(set_attr "type" "fpspc")
15937 (set_attr "mode" "XF")
15938 (set_attr "athlon_decode" "direct")
15939 (set_attr "amdfam10_decode" "direct")])
15941 (define_insn "*sqrt<mode>2_sse"
15942 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15944 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15945 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15946 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15947 [(set_attr "type" "sse")
15948 (set_attr "mode" "<MODE>")
15949 (set_attr "athlon_decode" "*")
15950 (set_attr "amdfam10_decode" "*")])
15952 (define_expand "sqrt<mode>2"
15953 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15955 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15956 "TARGET_USE_FANCY_MATH_387
15957 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15959 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15961 rtx op0 = gen_reg_rtx (XFmode);
15962 rtx op1 = force_reg (<MODE>mode, operands[1]);
15964 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15965 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15970 (define_insn "fpremxf4_i387"
15971 [(set (match_operand:XF 0 "register_operand" "=f")
15972 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15973 (match_operand:XF 3 "register_operand" "1")]
15975 (set (match_operand:XF 1 "register_operand" "=u")
15976 (unspec:XF [(match_dup 2) (match_dup 3)]
15978 (set (reg:CCFP FPSR_REG)
15979 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15981 "TARGET_USE_FANCY_MATH_387"
15983 [(set_attr "type" "fpspc")
15984 (set_attr "mode" "XF")])
15986 (define_expand "fmodxf3"
15987 [(use (match_operand:XF 0 "register_operand" ""))
15988 (use (match_operand:XF 1 "register_operand" ""))
15989 (use (match_operand:XF 2 "register_operand" ""))]
15990 "TARGET_USE_FANCY_MATH_387"
15992 rtx label = gen_label_rtx ();
15994 emit_label (label);
15996 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15997 operands[1], operands[2]));
15998 ix86_emit_fp_unordered_jump (label);
15999 LABEL_NUSES (label) = 1;
16001 emit_move_insn (operands[0], operands[1]);
16005 (define_expand "fmod<mode>3"
16006 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16007 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16008 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16009 "TARGET_USE_FANCY_MATH_387"
16011 rtx label = gen_label_rtx ();
16013 rtx op1 = gen_reg_rtx (XFmode);
16014 rtx op2 = gen_reg_rtx (XFmode);
16016 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16017 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16019 emit_label (label);
16020 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16021 ix86_emit_fp_unordered_jump (label);
16022 LABEL_NUSES (label) = 1;
16024 /* Truncate the result properly for strict SSE math. */
16025 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16026 && !TARGET_MIX_SSE_I387)
16027 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16029 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16034 (define_insn "fprem1xf4_i387"
16035 [(set (match_operand:XF 0 "register_operand" "=f")
16036 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16037 (match_operand:XF 3 "register_operand" "1")]
16039 (set (match_operand:XF 1 "register_operand" "=u")
16040 (unspec:XF [(match_dup 2) (match_dup 3)]
16042 (set (reg:CCFP FPSR_REG)
16043 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16045 "TARGET_USE_FANCY_MATH_387"
16047 [(set_attr "type" "fpspc")
16048 (set_attr "mode" "XF")])
16050 (define_expand "remainderxf3"
16051 [(use (match_operand:XF 0 "register_operand" ""))
16052 (use (match_operand:XF 1 "register_operand" ""))
16053 (use (match_operand:XF 2 "register_operand" ""))]
16054 "TARGET_USE_FANCY_MATH_387"
16056 rtx label = gen_label_rtx ();
16058 emit_label (label);
16060 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16061 operands[1], operands[2]));
16062 ix86_emit_fp_unordered_jump (label);
16063 LABEL_NUSES (label) = 1;
16065 emit_move_insn (operands[0], operands[1]);
16069 (define_expand "remainder<mode>3"
16070 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16071 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16072 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16073 "TARGET_USE_FANCY_MATH_387"
16075 rtx label = gen_label_rtx ();
16077 rtx op1 = gen_reg_rtx (XFmode);
16078 rtx op2 = gen_reg_rtx (XFmode);
16080 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16081 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16083 emit_label (label);
16085 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16086 ix86_emit_fp_unordered_jump (label);
16087 LABEL_NUSES (label) = 1;
16089 /* Truncate the result properly for strict SSE math. */
16090 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16091 && !TARGET_MIX_SSE_I387)
16092 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16094 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16099 (define_insn "*sinxf2_i387"
16100 [(set (match_operand:XF 0 "register_operand" "=f")
16101 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16102 "TARGET_USE_FANCY_MATH_387
16103 && flag_unsafe_math_optimizations"
16105 [(set_attr "type" "fpspc")
16106 (set_attr "mode" "XF")])
16108 (define_insn "*sin_extend<mode>xf2_i387"
16109 [(set (match_operand:XF 0 "register_operand" "=f")
16110 (unspec:XF [(float_extend:XF
16111 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16113 "TARGET_USE_FANCY_MATH_387
16114 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16115 || TARGET_MIX_SSE_I387)
16116 && flag_unsafe_math_optimizations"
16118 [(set_attr "type" "fpspc")
16119 (set_attr "mode" "XF")])
16121 (define_insn "*cosxf2_i387"
16122 [(set (match_operand:XF 0 "register_operand" "=f")
16123 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16124 "TARGET_USE_FANCY_MATH_387
16125 && flag_unsafe_math_optimizations"
16127 [(set_attr "type" "fpspc")
16128 (set_attr "mode" "XF")])
16130 (define_insn "*cos_extend<mode>xf2_i387"
16131 [(set (match_operand:XF 0 "register_operand" "=f")
16132 (unspec:XF [(float_extend:XF
16133 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16135 "TARGET_USE_FANCY_MATH_387
16136 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16137 || TARGET_MIX_SSE_I387)
16138 && flag_unsafe_math_optimizations"
16140 [(set_attr "type" "fpspc")
16141 (set_attr "mode" "XF")])
16143 ;; When sincos pattern is defined, sin and cos builtin functions will be
16144 ;; expanded to sincos pattern with one of its outputs left unused.
16145 ;; CSE pass will figure out if two sincos patterns can be combined,
16146 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16147 ;; depending on the unused output.
16149 (define_insn "sincosxf3"
16150 [(set (match_operand:XF 0 "register_operand" "=f")
16151 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16152 UNSPEC_SINCOS_COS))
16153 (set (match_operand:XF 1 "register_operand" "=u")
16154 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16155 "TARGET_USE_FANCY_MATH_387
16156 && flag_unsafe_math_optimizations"
16158 [(set_attr "type" "fpspc")
16159 (set_attr "mode" "XF")])
16162 [(set (match_operand:XF 0 "register_operand" "")
16163 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16164 UNSPEC_SINCOS_COS))
16165 (set (match_operand:XF 1 "register_operand" "")
16166 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16167 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16168 && !reload_completed && !reload_in_progress"
16169 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16173 [(set (match_operand:XF 0 "register_operand" "")
16174 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16175 UNSPEC_SINCOS_COS))
16176 (set (match_operand:XF 1 "register_operand" "")
16177 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16178 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16179 && !reload_completed && !reload_in_progress"
16180 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16183 (define_insn "sincos_extend<mode>xf3_i387"
16184 [(set (match_operand:XF 0 "register_operand" "=f")
16185 (unspec:XF [(float_extend:XF
16186 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16187 UNSPEC_SINCOS_COS))
16188 (set (match_operand:XF 1 "register_operand" "=u")
16189 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16190 "TARGET_USE_FANCY_MATH_387
16191 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16192 || TARGET_MIX_SSE_I387)
16193 && flag_unsafe_math_optimizations"
16195 [(set_attr "type" "fpspc")
16196 (set_attr "mode" "XF")])
16199 [(set (match_operand:XF 0 "register_operand" "")
16200 (unspec:XF [(float_extend:XF
16201 (match_operand:X87MODEF12 2 "register_operand" ""))]
16202 UNSPEC_SINCOS_COS))
16203 (set (match_operand:XF 1 "register_operand" "")
16204 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16205 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16206 && !reload_completed && !reload_in_progress"
16207 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16211 [(set (match_operand:XF 0 "register_operand" "")
16212 (unspec:XF [(float_extend:XF
16213 (match_operand:X87MODEF12 2 "register_operand" ""))]
16214 UNSPEC_SINCOS_COS))
16215 (set (match_operand:XF 1 "register_operand" "")
16216 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16217 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16218 && !reload_completed && !reload_in_progress"
16219 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16222 (define_expand "sincos<mode>3"
16223 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16224 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16225 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16226 "TARGET_USE_FANCY_MATH_387
16227 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16228 || TARGET_MIX_SSE_I387)
16229 && flag_unsafe_math_optimizations"
16231 rtx op0 = gen_reg_rtx (XFmode);
16232 rtx op1 = gen_reg_rtx (XFmode);
16234 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16235 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16236 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16240 (define_insn "fptanxf4_i387"
16241 [(set (match_operand:XF 0 "register_operand" "=f")
16242 (match_operand:XF 3 "const_double_operand" "F"))
16243 (set (match_operand:XF 1 "register_operand" "=u")
16244 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16246 "TARGET_USE_FANCY_MATH_387
16247 && flag_unsafe_math_optimizations
16248 && standard_80387_constant_p (operands[3]) == 2"
16250 [(set_attr "type" "fpspc")
16251 (set_attr "mode" "XF")])
16253 (define_insn "fptan_extend<mode>xf4_i387"
16254 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16255 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16256 (set (match_operand:XF 1 "register_operand" "=u")
16257 (unspec:XF [(float_extend:XF
16258 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16260 "TARGET_USE_FANCY_MATH_387
16261 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16262 || TARGET_MIX_SSE_I387)
16263 && flag_unsafe_math_optimizations
16264 && standard_80387_constant_p (operands[3]) == 2"
16266 [(set_attr "type" "fpspc")
16267 (set_attr "mode" "XF")])
16269 (define_expand "tanxf2"
16270 [(use (match_operand:XF 0 "register_operand" ""))
16271 (use (match_operand:XF 1 "register_operand" ""))]
16272 "TARGET_USE_FANCY_MATH_387
16273 && flag_unsafe_math_optimizations"
16275 rtx one = gen_reg_rtx (XFmode);
16276 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16278 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16282 (define_expand "tan<mode>2"
16283 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16284 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16285 "TARGET_USE_FANCY_MATH_387
16286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16287 || TARGET_MIX_SSE_I387)
16288 && flag_unsafe_math_optimizations"
16290 rtx op0 = gen_reg_rtx (XFmode);
16292 rtx one = gen_reg_rtx (<MODE>mode);
16293 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16295 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16296 operands[1], op2));
16297 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16301 (define_insn "*fpatanxf3_i387"
16302 [(set (match_operand:XF 0 "register_operand" "=f")
16303 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16304 (match_operand:XF 2 "register_operand" "u")]
16306 (clobber (match_scratch:XF 3 "=2"))]
16307 "TARGET_USE_FANCY_MATH_387
16308 && flag_unsafe_math_optimizations"
16310 [(set_attr "type" "fpspc")
16311 (set_attr "mode" "XF")])
16313 (define_insn "fpatan_extend<mode>xf3_i387"
16314 [(set (match_operand:XF 0 "register_operand" "=f")
16315 (unspec:XF [(float_extend:XF
16316 (match_operand:X87MODEF12 1 "register_operand" "0"))
16318 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16320 (clobber (match_scratch:XF 3 "=2"))]
16321 "TARGET_USE_FANCY_MATH_387
16322 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16323 || TARGET_MIX_SSE_I387)
16324 && flag_unsafe_math_optimizations"
16326 [(set_attr "type" "fpspc")
16327 (set_attr "mode" "XF")])
16329 (define_expand "atan2xf3"
16330 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16331 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16332 (match_operand:XF 1 "register_operand" "")]
16334 (clobber (match_scratch:XF 3 ""))])]
16335 "TARGET_USE_FANCY_MATH_387
16336 && flag_unsafe_math_optimizations"
16339 (define_expand "atan2<mode>3"
16340 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16341 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16342 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16343 "TARGET_USE_FANCY_MATH_387
16344 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16345 || TARGET_MIX_SSE_I387)
16346 && flag_unsafe_math_optimizations"
16348 rtx op0 = gen_reg_rtx (XFmode);
16350 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16351 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16355 (define_expand "atanxf2"
16356 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16357 (unspec:XF [(match_dup 2)
16358 (match_operand:XF 1 "register_operand" "")]
16360 (clobber (match_scratch:XF 3 ""))])]
16361 "TARGET_USE_FANCY_MATH_387
16362 && flag_unsafe_math_optimizations"
16364 operands[2] = gen_reg_rtx (XFmode);
16365 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16368 (define_expand "atan<mode>2"
16369 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16370 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16371 "TARGET_USE_FANCY_MATH_387
16372 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16373 || TARGET_MIX_SSE_I387)
16374 && flag_unsafe_math_optimizations"
16376 rtx op0 = gen_reg_rtx (XFmode);
16378 rtx op2 = gen_reg_rtx (<MODE>mode);
16379 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16381 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16382 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16386 (define_expand "asinxf2"
16387 [(set (match_dup 2)
16388 (mult:XF (match_operand:XF 1 "register_operand" "")
16390 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16391 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16392 (parallel [(set (match_operand:XF 0 "register_operand" "")
16393 (unspec:XF [(match_dup 5) (match_dup 1)]
16395 (clobber (match_scratch:XF 6 ""))])]
16396 "TARGET_USE_FANCY_MATH_387
16397 && flag_unsafe_math_optimizations && !optimize_size"
16401 for (i = 2; i < 6; i++)
16402 operands[i] = gen_reg_rtx (XFmode);
16404 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16407 (define_expand "asin<mode>2"
16408 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16409 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16410 "TARGET_USE_FANCY_MATH_387
16411 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16412 || TARGET_MIX_SSE_I387)
16413 && flag_unsafe_math_optimizations && !optimize_size"
16415 rtx op0 = gen_reg_rtx (XFmode);
16416 rtx op1 = gen_reg_rtx (XFmode);
16418 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16419 emit_insn (gen_asinxf2 (op0, op1));
16420 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16424 (define_expand "acosxf2"
16425 [(set (match_dup 2)
16426 (mult:XF (match_operand:XF 1 "register_operand" "")
16428 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16429 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16430 (parallel [(set (match_operand:XF 0 "register_operand" "")
16431 (unspec:XF [(match_dup 1) (match_dup 5)]
16433 (clobber (match_scratch:XF 6 ""))])]
16434 "TARGET_USE_FANCY_MATH_387
16435 && flag_unsafe_math_optimizations && !optimize_size"
16439 for (i = 2; i < 6; i++)
16440 operands[i] = gen_reg_rtx (XFmode);
16442 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16445 (define_expand "acos<mode>2"
16446 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16447 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16448 "TARGET_USE_FANCY_MATH_387
16449 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16450 || TARGET_MIX_SSE_I387)
16451 && flag_unsafe_math_optimizations && !optimize_size"
16453 rtx op0 = gen_reg_rtx (XFmode);
16454 rtx op1 = gen_reg_rtx (XFmode);
16456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16457 emit_insn (gen_acosxf2 (op0, op1));
16458 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16462 (define_insn "fyl2xxf3_i387"
16463 [(set (match_operand:XF 0 "register_operand" "=f")
16464 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16465 (match_operand:XF 2 "register_operand" "u")]
16467 (clobber (match_scratch:XF 3 "=2"))]
16468 "TARGET_USE_FANCY_MATH_387
16469 && flag_unsafe_math_optimizations"
16471 [(set_attr "type" "fpspc")
16472 (set_attr "mode" "XF")])
16474 (define_insn "fyl2x_extend<mode>xf3_i387"
16475 [(set (match_operand:XF 0 "register_operand" "=f")
16476 (unspec:XF [(float_extend:XF
16477 (match_operand:X87MODEF12 1 "register_operand" "0"))
16478 (match_operand:XF 2 "register_operand" "u")]
16480 (clobber (match_scratch:XF 3 "=2"))]
16481 "TARGET_USE_FANCY_MATH_387
16482 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16483 || TARGET_MIX_SSE_I387)
16484 && flag_unsafe_math_optimizations"
16486 [(set_attr "type" "fpspc")
16487 (set_attr "mode" "XF")])
16489 (define_expand "logxf2"
16490 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16491 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16492 (match_dup 2)] UNSPEC_FYL2X))
16493 (clobber (match_scratch:XF 3 ""))])]
16494 "TARGET_USE_FANCY_MATH_387
16495 && flag_unsafe_math_optimizations"
16497 operands[2] = gen_reg_rtx (XFmode);
16498 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16501 (define_expand "log<mode>2"
16502 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16503 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16504 "TARGET_USE_FANCY_MATH_387
16505 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16506 || TARGET_MIX_SSE_I387)
16507 && flag_unsafe_math_optimizations"
16509 rtx op0 = gen_reg_rtx (XFmode);
16511 rtx op2 = gen_reg_rtx (XFmode);
16512 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16514 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16515 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16519 (define_expand "log10xf2"
16520 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16521 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16522 (match_dup 2)] UNSPEC_FYL2X))
16523 (clobber (match_scratch:XF 3 ""))])]
16524 "TARGET_USE_FANCY_MATH_387
16525 && flag_unsafe_math_optimizations"
16527 operands[2] = gen_reg_rtx (XFmode);
16528 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16531 (define_expand "log10<mode>2"
16532 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16533 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16534 "TARGET_USE_FANCY_MATH_387
16535 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16536 || TARGET_MIX_SSE_I387)
16537 && flag_unsafe_math_optimizations"
16539 rtx op0 = gen_reg_rtx (XFmode);
16541 rtx op2 = gen_reg_rtx (XFmode);
16542 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16544 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16545 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16549 (define_expand "log2xf2"
16550 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16551 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16552 (match_dup 2)] UNSPEC_FYL2X))
16553 (clobber (match_scratch:XF 3 ""))])]
16554 "TARGET_USE_FANCY_MATH_387
16555 && flag_unsafe_math_optimizations"
16557 operands[2] = gen_reg_rtx (XFmode);
16558 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16561 (define_expand "log2<mode>2"
16562 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16563 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16564 "TARGET_USE_FANCY_MATH_387
16565 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16566 || TARGET_MIX_SSE_I387)
16567 && flag_unsafe_math_optimizations"
16569 rtx op0 = gen_reg_rtx (XFmode);
16571 rtx op2 = gen_reg_rtx (XFmode);
16572 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16574 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16575 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16579 (define_insn "fyl2xp1xf3_i387"
16580 [(set (match_operand:XF 0 "register_operand" "=f")
16581 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16582 (match_operand:XF 2 "register_operand" "u")]
16584 (clobber (match_scratch:XF 3 "=2"))]
16585 "TARGET_USE_FANCY_MATH_387
16586 && flag_unsafe_math_optimizations"
16588 [(set_attr "type" "fpspc")
16589 (set_attr "mode" "XF")])
16591 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16592 [(set (match_operand:XF 0 "register_operand" "=f")
16593 (unspec:XF [(float_extend:XF
16594 (match_operand:X87MODEF12 1 "register_operand" "0"))
16595 (match_operand:XF 2 "register_operand" "u")]
16597 (clobber (match_scratch:XF 3 "=2"))]
16598 "TARGET_USE_FANCY_MATH_387
16599 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16600 || TARGET_MIX_SSE_I387)
16601 && flag_unsafe_math_optimizations"
16603 [(set_attr "type" "fpspc")
16604 (set_attr "mode" "XF")])
16606 (define_expand "log1pxf2"
16607 [(use (match_operand:XF 0 "register_operand" ""))
16608 (use (match_operand:XF 1 "register_operand" ""))]
16609 "TARGET_USE_FANCY_MATH_387
16610 && flag_unsafe_math_optimizations && !optimize_size"
16612 ix86_emit_i387_log1p (operands[0], operands[1]);
16616 (define_expand "log1p<mode>2"
16617 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16618 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16619 "TARGET_USE_FANCY_MATH_387
16620 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16621 || TARGET_MIX_SSE_I387)
16622 && flag_unsafe_math_optimizations && !optimize_size"
16624 rtx op0 = gen_reg_rtx (XFmode);
16626 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16628 ix86_emit_i387_log1p (op0, operands[1]);
16629 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16633 (define_insn "fxtractxf3_i387"
16634 [(set (match_operand:XF 0 "register_operand" "=f")
16635 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16636 UNSPEC_XTRACT_FRACT))
16637 (set (match_operand:XF 1 "register_operand" "=u")
16638 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16639 "TARGET_USE_FANCY_MATH_387
16640 && flag_unsafe_math_optimizations"
16642 [(set_attr "type" "fpspc")
16643 (set_attr "mode" "XF")])
16645 (define_insn "fxtract_extend<mode>xf3_i387"
16646 [(set (match_operand:XF 0 "register_operand" "=f")
16647 (unspec:XF [(float_extend:XF
16648 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16649 UNSPEC_XTRACT_FRACT))
16650 (set (match_operand:XF 1 "register_operand" "=u")
16651 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16652 "TARGET_USE_FANCY_MATH_387
16653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16654 || TARGET_MIX_SSE_I387)
16655 && flag_unsafe_math_optimizations"
16657 [(set_attr "type" "fpspc")
16658 (set_attr "mode" "XF")])
16660 (define_expand "logbxf2"
16661 [(parallel [(set (match_dup 2)
16662 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16663 UNSPEC_XTRACT_FRACT))
16664 (set (match_operand:XF 0 "register_operand" "")
16665 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16666 "TARGET_USE_FANCY_MATH_387
16667 && flag_unsafe_math_optimizations"
16669 operands[2] = gen_reg_rtx (XFmode);
16672 (define_expand "logb<mode>2"
16673 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16674 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16675 "TARGET_USE_FANCY_MATH_387
16676 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16677 || TARGET_MIX_SSE_I387)
16678 && flag_unsafe_math_optimizations"
16680 rtx op0 = gen_reg_rtx (XFmode);
16681 rtx op1 = gen_reg_rtx (XFmode);
16683 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16684 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16688 (define_expand "ilogbxf2"
16689 [(use (match_operand:SI 0 "register_operand" ""))
16690 (use (match_operand:XF 1 "register_operand" ""))]
16691 "TARGET_USE_FANCY_MATH_387
16692 && flag_unsafe_math_optimizations && !optimize_size"
16694 rtx op0 = gen_reg_rtx (XFmode);
16695 rtx op1 = gen_reg_rtx (XFmode);
16697 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16698 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16702 (define_expand "ilogb<mode>2"
16703 [(use (match_operand:SI 0 "register_operand" ""))
16704 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16705 "TARGET_USE_FANCY_MATH_387
16706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16707 || TARGET_MIX_SSE_I387)
16708 && flag_unsafe_math_optimizations && !optimize_size"
16710 rtx op0 = gen_reg_rtx (XFmode);
16711 rtx op1 = gen_reg_rtx (XFmode);
16713 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16714 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16718 (define_insn "*f2xm1xf2_i387"
16719 [(set (match_operand:XF 0 "register_operand" "=f")
16720 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16722 "TARGET_USE_FANCY_MATH_387
16723 && flag_unsafe_math_optimizations"
16725 [(set_attr "type" "fpspc")
16726 (set_attr "mode" "XF")])
16728 (define_insn "*fscalexf4_i387"
16729 [(set (match_operand:XF 0 "register_operand" "=f")
16730 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16731 (match_operand:XF 3 "register_operand" "1")]
16732 UNSPEC_FSCALE_FRACT))
16733 (set (match_operand:XF 1 "register_operand" "=u")
16734 (unspec:XF [(match_dup 2) (match_dup 3)]
16735 UNSPEC_FSCALE_EXP))]
16736 "TARGET_USE_FANCY_MATH_387
16737 && flag_unsafe_math_optimizations"
16739 [(set_attr "type" "fpspc")
16740 (set_attr "mode" "XF")])
16742 (define_expand "expNcorexf3"
16743 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16744 (match_operand:XF 2 "register_operand" "")))
16745 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16746 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16747 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16748 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16749 (parallel [(set (match_operand:XF 0 "register_operand" "")
16750 (unspec:XF [(match_dup 8) (match_dup 4)]
16751 UNSPEC_FSCALE_FRACT))
16753 (unspec:XF [(match_dup 8) (match_dup 4)]
16754 UNSPEC_FSCALE_EXP))])]
16755 "TARGET_USE_FANCY_MATH_387
16756 && flag_unsafe_math_optimizations && !optimize_size"
16760 for (i = 3; i < 10; i++)
16761 operands[i] = gen_reg_rtx (XFmode);
16763 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16766 (define_expand "expxf2"
16767 [(use (match_operand:XF 0 "register_operand" ""))
16768 (use (match_operand:XF 1 "register_operand" ""))]
16769 "TARGET_USE_FANCY_MATH_387
16770 && flag_unsafe_math_optimizations && !optimize_size"
16772 rtx op2 = gen_reg_rtx (XFmode);
16773 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16775 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16779 (define_expand "exp<mode>2"
16780 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16781 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16782 "TARGET_USE_FANCY_MATH_387
16783 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16784 || TARGET_MIX_SSE_I387)
16785 && flag_unsafe_math_optimizations && !optimize_size"
16787 rtx op0 = gen_reg_rtx (XFmode);
16788 rtx op1 = gen_reg_rtx (XFmode);
16790 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16791 emit_insn (gen_expxf2 (op0, op1));
16792 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16796 (define_expand "exp10xf2"
16797 [(use (match_operand:XF 0 "register_operand" ""))
16798 (use (match_operand:XF 1 "register_operand" ""))]
16799 "TARGET_USE_FANCY_MATH_387
16800 && flag_unsafe_math_optimizations && !optimize_size"
16802 rtx op2 = gen_reg_rtx (XFmode);
16803 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16805 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16809 (define_expand "exp10<mode>2"
16810 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16811 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16812 "TARGET_USE_FANCY_MATH_387
16813 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16814 || TARGET_MIX_SSE_I387)
16815 && flag_unsafe_math_optimizations && !optimize_size"
16817 rtx op0 = gen_reg_rtx (XFmode);
16818 rtx op1 = gen_reg_rtx (XFmode);
16820 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16821 emit_insn (gen_exp10xf2 (op0, op1));
16822 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16826 (define_expand "exp2xf2"
16827 [(use (match_operand:XF 0 "register_operand" ""))
16828 (use (match_operand:XF 1 "register_operand" ""))]
16829 "TARGET_USE_FANCY_MATH_387
16830 && flag_unsafe_math_optimizations && !optimize_size"
16832 rtx op2 = gen_reg_rtx (XFmode);
16833 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16835 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16839 (define_expand "exp2<mode>2"
16840 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16841 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16842 "TARGET_USE_FANCY_MATH_387
16843 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16844 || TARGET_MIX_SSE_I387)
16845 && flag_unsafe_math_optimizations && !optimize_size"
16847 rtx op0 = gen_reg_rtx (XFmode);
16848 rtx op1 = gen_reg_rtx (XFmode);
16850 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16851 emit_insn (gen_exp2xf2 (op0, op1));
16852 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16856 (define_expand "expm1xf2"
16857 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16859 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16860 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16861 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16862 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16863 (parallel [(set (match_dup 7)
16864 (unspec:XF [(match_dup 6) (match_dup 4)]
16865 UNSPEC_FSCALE_FRACT))
16867 (unspec:XF [(match_dup 6) (match_dup 4)]
16868 UNSPEC_FSCALE_EXP))])
16869 (parallel [(set (match_dup 10)
16870 (unspec:XF [(match_dup 9) (match_dup 8)]
16871 UNSPEC_FSCALE_FRACT))
16872 (set (match_dup 11)
16873 (unspec:XF [(match_dup 9) (match_dup 8)]
16874 UNSPEC_FSCALE_EXP))])
16875 (set (match_dup 12) (minus:XF (match_dup 10)
16876 (float_extend:XF (match_dup 13))))
16877 (set (match_operand:XF 0 "register_operand" "")
16878 (plus:XF (match_dup 12) (match_dup 7)))]
16879 "TARGET_USE_FANCY_MATH_387
16880 && flag_unsafe_math_optimizations && !optimize_size"
16884 for (i = 2; i < 13; i++)
16885 operands[i] = gen_reg_rtx (XFmode);
16888 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16890 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16893 (define_expand "expm1<mode>2"
16894 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16895 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16896 "TARGET_USE_FANCY_MATH_387
16897 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16898 || TARGET_MIX_SSE_I387)
16899 && flag_unsafe_math_optimizations && !optimize_size"
16901 rtx op0 = gen_reg_rtx (XFmode);
16902 rtx op1 = gen_reg_rtx (XFmode);
16904 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16905 emit_insn (gen_expm1xf2 (op0, op1));
16906 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16910 (define_expand "ldexpxf3"
16911 [(set (match_dup 3)
16912 (float:XF (match_operand:SI 2 "register_operand" "")))
16913 (parallel [(set (match_operand:XF 0 " register_operand" "")
16914 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16916 UNSPEC_FSCALE_FRACT))
16918 (unspec:XF [(match_dup 1) (match_dup 3)]
16919 UNSPEC_FSCALE_EXP))])]
16920 "TARGET_USE_FANCY_MATH_387
16921 && flag_unsafe_math_optimizations && !optimize_size"
16923 operands[3] = gen_reg_rtx (XFmode);
16924 operands[4] = gen_reg_rtx (XFmode);
16927 (define_expand "ldexp<mode>3"
16928 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16929 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16930 (use (match_operand:SI 2 "register_operand" ""))]
16931 "TARGET_USE_FANCY_MATH_387
16932 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16933 || TARGET_MIX_SSE_I387)
16934 && flag_unsafe_math_optimizations && !optimize_size"
16936 rtx op0 = gen_reg_rtx (XFmode);
16937 rtx op1 = gen_reg_rtx (XFmode);
16939 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16940 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16941 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16945 (define_expand "scalbxf3"
16946 [(parallel [(set (match_operand:XF 0 " register_operand" "")
16947 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16948 (match_operand:XF 2 "register_operand" "")]
16949 UNSPEC_FSCALE_FRACT))
16951 (unspec:XF [(match_dup 1) (match_dup 2)]
16952 UNSPEC_FSCALE_EXP))])]
16953 "TARGET_USE_FANCY_MATH_387
16954 && flag_unsafe_math_optimizations && !optimize_size"
16956 operands[3] = gen_reg_rtx (XFmode);
16959 (define_expand "scalb<mode>3"
16960 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16961 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16962 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16963 "TARGET_USE_FANCY_MATH_387
16964 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16965 || TARGET_MIX_SSE_I387)
16966 && flag_unsafe_math_optimizations && !optimize_size"
16968 rtx op0 = gen_reg_rtx (XFmode);
16969 rtx op1 = gen_reg_rtx (XFmode);
16970 rtx op2 = gen_reg_rtx (XFmode);
16972 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16973 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16974 emit_insn (gen_scalbxf3 (op0, op1, op2));
16975 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16980 (define_insn "sse4_1_round<mode>2"
16981 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16982 (unspec:SSEMODEF [(match_operand:SSEMODEF 1 "register_operand" "x")
16983 (match_operand:SI 2 "const_0_to_15_operand" "n")]
16986 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16987 [(set_attr "type" "ssecvt")
16988 (set_attr "prefix_extra" "1")
16989 (set_attr "mode" "<MODE>")])
16991 (define_insn "rintxf2"
16992 [(set (match_operand:XF 0 "register_operand" "=f")
16993 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16995 "TARGET_USE_FANCY_MATH_387
16996 && flag_unsafe_math_optimizations"
16998 [(set_attr "type" "fpspc")
16999 (set_attr "mode" "XF")])
17001 (define_expand "rint<mode>2"
17002 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17003 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17004 "(TARGET_USE_FANCY_MATH_387
17005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17006 || TARGET_MIX_SSE_I387)
17007 && flag_unsafe_math_optimizations)
17008 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17009 && !flag_trapping_math
17010 && (TARGET_SSE4_1 || !optimize_size))"
17012 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17013 && !flag_trapping_math
17014 && (TARGET_SSE4_1 || !optimize_size))
17017 emit_insn (gen_sse4_1_round<mode>2
17018 (operands[0], operands[1], GEN_INT (0x04)));
17020 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 (TARGET_64BIT || (<MODE>mode != DFmode))
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 "floor<mode>2"
17249 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17250 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17251 "(TARGET_USE_FANCY_MATH_387
17252 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17253 || TARGET_MIX_SSE_I387)
17254 && flag_unsafe_math_optimizations && !optimize_size)
17255 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17256 && !flag_trapping_math
17257 && (TARGET_SSE4_1 || !optimize_size))"
17259 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17260 && !flag_trapping_math
17261 && (TARGET_SSE4_1 || !optimize_size))
17264 emit_insn (gen_sse4_1_round<mode>2
17265 (operands[0], operands[1], GEN_INT (0x01)));
17266 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17267 ix86_expand_floorceil (operand0, operand1, true);
17269 ix86_expand_floorceildf_32 (operand0, operand1, true);
17273 rtx op0 = gen_reg_rtx (XFmode);
17274 rtx op1 = gen_reg_rtx (XFmode);
17276 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17277 emit_insn (gen_frndintxf2_floor (op0, op1));
17279 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17284 (define_insn_and_split "*fist<mode>2_floor_1"
17285 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17286 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17287 UNSPEC_FIST_FLOOR))
17288 (clobber (reg:CC FLAGS_REG))]
17289 "TARGET_USE_FANCY_MATH_387
17290 && flag_unsafe_math_optimizations
17291 && !(reload_completed || reload_in_progress)"
17296 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17298 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17299 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17300 if (memory_operand (operands[0], VOIDmode))
17301 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17302 operands[2], operands[3]));
17305 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17306 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17307 operands[2], operands[3],
17312 [(set_attr "type" "fistp")
17313 (set_attr "i387_cw" "floor")
17314 (set_attr "mode" "<MODE>")])
17316 (define_insn "fistdi2_floor"
17317 [(set (match_operand:DI 0 "memory_operand" "=m")
17318 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17319 UNSPEC_FIST_FLOOR))
17320 (use (match_operand:HI 2 "memory_operand" "m"))
17321 (use (match_operand:HI 3 "memory_operand" "m"))
17322 (clobber (match_scratch:XF 4 "=&1f"))]
17323 "TARGET_USE_FANCY_MATH_387
17324 && flag_unsafe_math_optimizations"
17325 "* return output_fix_trunc (insn, operands, 0);"
17326 [(set_attr "type" "fistp")
17327 (set_attr "i387_cw" "floor")
17328 (set_attr "mode" "DI")])
17330 (define_insn "fistdi2_floor_with_temp"
17331 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17332 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17333 UNSPEC_FIST_FLOOR))
17334 (use (match_operand:HI 2 "memory_operand" "m,m"))
17335 (use (match_operand:HI 3 "memory_operand" "m,m"))
17336 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17337 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17338 "TARGET_USE_FANCY_MATH_387
17339 && flag_unsafe_math_optimizations"
17341 [(set_attr "type" "fistp")
17342 (set_attr "i387_cw" "floor")
17343 (set_attr "mode" "DI")])
17346 [(set (match_operand:DI 0 "register_operand" "")
17347 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17348 UNSPEC_FIST_FLOOR))
17349 (use (match_operand:HI 2 "memory_operand" ""))
17350 (use (match_operand:HI 3 "memory_operand" ""))
17351 (clobber (match_operand:DI 4 "memory_operand" ""))
17352 (clobber (match_scratch 5 ""))]
17354 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17355 (use (match_dup 2))
17356 (use (match_dup 3))
17357 (clobber (match_dup 5))])
17358 (set (match_dup 0) (match_dup 4))]
17362 [(set (match_operand:DI 0 "memory_operand" "")
17363 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17364 UNSPEC_FIST_FLOOR))
17365 (use (match_operand:HI 2 "memory_operand" ""))
17366 (use (match_operand:HI 3 "memory_operand" ""))
17367 (clobber (match_operand:DI 4 "memory_operand" ""))
17368 (clobber (match_scratch 5 ""))]
17370 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17371 (use (match_dup 2))
17372 (use (match_dup 3))
17373 (clobber (match_dup 5))])]
17376 (define_insn "fist<mode>2_floor"
17377 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17378 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17379 UNSPEC_FIST_FLOOR))
17380 (use (match_operand:HI 2 "memory_operand" "m"))
17381 (use (match_operand:HI 3 "memory_operand" "m"))]
17382 "TARGET_USE_FANCY_MATH_387
17383 && flag_unsafe_math_optimizations"
17384 "* return output_fix_trunc (insn, operands, 0);"
17385 [(set_attr "type" "fistp")
17386 (set_attr "i387_cw" "floor")
17387 (set_attr "mode" "<MODE>")])
17389 (define_insn "fist<mode>2_floor_with_temp"
17390 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17391 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17392 UNSPEC_FIST_FLOOR))
17393 (use (match_operand:HI 2 "memory_operand" "m,m"))
17394 (use (match_operand:HI 3 "memory_operand" "m,m"))
17395 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17396 "TARGET_USE_FANCY_MATH_387
17397 && flag_unsafe_math_optimizations"
17399 [(set_attr "type" "fistp")
17400 (set_attr "i387_cw" "floor")
17401 (set_attr "mode" "<MODE>")])
17404 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17405 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17406 UNSPEC_FIST_FLOOR))
17407 (use (match_operand:HI 2 "memory_operand" ""))
17408 (use (match_operand:HI 3 "memory_operand" ""))
17409 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17411 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17412 UNSPEC_FIST_FLOOR))
17413 (use (match_dup 2))
17414 (use (match_dup 3))])
17415 (set (match_dup 0) (match_dup 4))]
17419 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17420 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17421 UNSPEC_FIST_FLOOR))
17422 (use (match_operand:HI 2 "memory_operand" ""))
17423 (use (match_operand:HI 3 "memory_operand" ""))
17424 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17426 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17427 UNSPEC_FIST_FLOOR))
17428 (use (match_dup 2))
17429 (use (match_dup 3))])]
17432 (define_expand "lfloorxf<mode>2"
17433 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17434 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17435 UNSPEC_FIST_FLOOR))
17436 (clobber (reg:CC FLAGS_REG))])]
17437 "TARGET_USE_FANCY_MATH_387
17438 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17439 && flag_unsafe_math_optimizations"
17442 (define_expand "lfloor<mode>di2"
17443 [(match_operand:DI 0 "nonimmediate_operand" "")
17444 (match_operand:SSEMODEF 1 "register_operand" "")]
17445 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17446 && !flag_trapping_math
17449 ix86_expand_lfloorceil (operand0, operand1, true);
17453 (define_expand "lfloor<mode>si2"
17454 [(match_operand:SI 0 "nonimmediate_operand" "")
17455 (match_operand:SSEMODEF 1 "register_operand" "")]
17456 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17457 && !flag_trapping_math
17458 && (!optimize_size || !TARGET_64BIT)"
17460 ix86_expand_lfloorceil (operand0, operand1, true);
17464 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17465 (define_insn_and_split "frndintxf2_ceil"
17466 [(set (match_operand:XF 0 "register_operand" "=f")
17467 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17468 UNSPEC_FRNDINT_CEIL))
17469 (clobber (reg:CC FLAGS_REG))]
17470 "TARGET_USE_FANCY_MATH_387
17471 && flag_unsafe_math_optimizations
17472 && !(reload_completed || reload_in_progress)"
17477 ix86_optimize_mode_switching[I387_CEIL] = 1;
17479 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17480 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17482 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17483 operands[2], operands[3]));
17486 [(set_attr "type" "frndint")
17487 (set_attr "i387_cw" "ceil")
17488 (set_attr "mode" "XF")])
17490 (define_insn "frndintxf2_ceil_i387"
17491 [(set (match_operand:XF 0 "register_operand" "=f")
17492 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17493 UNSPEC_FRNDINT_CEIL))
17494 (use (match_operand:HI 2 "memory_operand" "m"))
17495 (use (match_operand:HI 3 "memory_operand" "m"))]
17496 "TARGET_USE_FANCY_MATH_387
17497 && flag_unsafe_math_optimizations"
17498 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17499 [(set_attr "type" "frndint")
17500 (set_attr "i387_cw" "ceil")
17501 (set_attr "mode" "XF")])
17503 (define_expand "ceilxf2"
17504 [(use (match_operand:XF 0 "register_operand" ""))
17505 (use (match_operand:XF 1 "register_operand" ""))]
17506 "TARGET_USE_FANCY_MATH_387
17507 && flag_unsafe_math_optimizations && !optimize_size"
17509 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17513 (define_expand "ceil<mode>2"
17514 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17515 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17516 "(TARGET_USE_FANCY_MATH_387
17517 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17518 || TARGET_MIX_SSE_I387)
17519 && flag_unsafe_math_optimizations && !optimize_size)
17520 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17521 && !flag_trapping_math
17522 && (TARGET_SSE4_1 || !optimize_size))"
17524 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17525 && !flag_trapping_math
17526 && (TARGET_SSE4_1 || !optimize_size))
17529 emit_insn (gen_sse4_1_round<mode>2
17530 (operands[0], operands[1], GEN_INT (0x02)));
17531 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17532 ix86_expand_floorceil (operand0, operand1, false);
17534 ix86_expand_floorceildf_32 (operand0, operand1, false);
17538 rtx op0 = gen_reg_rtx (XFmode);
17539 rtx op1 = gen_reg_rtx (XFmode);
17541 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17542 emit_insn (gen_frndintxf2_ceil (op0, op1));
17544 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17549 (define_insn_and_split "*fist<mode>2_ceil_1"
17550 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17551 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17553 (clobber (reg:CC FLAGS_REG))]
17554 "TARGET_USE_FANCY_MATH_387
17555 && flag_unsafe_math_optimizations
17556 && !(reload_completed || reload_in_progress)"
17561 ix86_optimize_mode_switching[I387_CEIL] = 1;
17563 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17564 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17565 if (memory_operand (operands[0], VOIDmode))
17566 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17567 operands[2], operands[3]));
17570 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17571 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17572 operands[2], operands[3],
17577 [(set_attr "type" "fistp")
17578 (set_attr "i387_cw" "ceil")
17579 (set_attr "mode" "<MODE>")])
17581 (define_insn "fistdi2_ceil"
17582 [(set (match_operand:DI 0 "memory_operand" "=m")
17583 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17585 (use (match_operand:HI 2 "memory_operand" "m"))
17586 (use (match_operand:HI 3 "memory_operand" "m"))
17587 (clobber (match_scratch:XF 4 "=&1f"))]
17588 "TARGET_USE_FANCY_MATH_387
17589 && flag_unsafe_math_optimizations"
17590 "* return output_fix_trunc (insn, operands, 0);"
17591 [(set_attr "type" "fistp")
17592 (set_attr "i387_cw" "ceil")
17593 (set_attr "mode" "DI")])
17595 (define_insn "fistdi2_ceil_with_temp"
17596 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17597 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17599 (use (match_operand:HI 2 "memory_operand" "m,m"))
17600 (use (match_operand:HI 3 "memory_operand" "m,m"))
17601 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17602 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17603 "TARGET_USE_FANCY_MATH_387
17604 && flag_unsafe_math_optimizations"
17606 [(set_attr "type" "fistp")
17607 (set_attr "i387_cw" "ceil")
17608 (set_attr "mode" "DI")])
17611 [(set (match_operand:DI 0 "register_operand" "")
17612 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17614 (use (match_operand:HI 2 "memory_operand" ""))
17615 (use (match_operand:HI 3 "memory_operand" ""))
17616 (clobber (match_operand:DI 4 "memory_operand" ""))
17617 (clobber (match_scratch 5 ""))]
17619 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17620 (use (match_dup 2))
17621 (use (match_dup 3))
17622 (clobber (match_dup 5))])
17623 (set (match_dup 0) (match_dup 4))]
17627 [(set (match_operand:DI 0 "memory_operand" "")
17628 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17630 (use (match_operand:HI 2 "memory_operand" ""))
17631 (use (match_operand:HI 3 "memory_operand" ""))
17632 (clobber (match_operand:DI 4 "memory_operand" ""))
17633 (clobber (match_scratch 5 ""))]
17635 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17636 (use (match_dup 2))
17637 (use (match_dup 3))
17638 (clobber (match_dup 5))])]
17641 (define_insn "fist<mode>2_ceil"
17642 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17643 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17645 (use (match_operand:HI 2 "memory_operand" "m"))
17646 (use (match_operand:HI 3 "memory_operand" "m"))]
17647 "TARGET_USE_FANCY_MATH_387
17648 && flag_unsafe_math_optimizations"
17649 "* return output_fix_trunc (insn, operands, 0);"
17650 [(set_attr "type" "fistp")
17651 (set_attr "i387_cw" "ceil")
17652 (set_attr "mode" "<MODE>")])
17654 (define_insn "fist<mode>2_ceil_with_temp"
17655 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17656 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17658 (use (match_operand:HI 2 "memory_operand" "m,m"))
17659 (use (match_operand:HI 3 "memory_operand" "m,m"))
17660 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17661 "TARGET_USE_FANCY_MATH_387
17662 && flag_unsafe_math_optimizations"
17664 [(set_attr "type" "fistp")
17665 (set_attr "i387_cw" "ceil")
17666 (set_attr "mode" "<MODE>")])
17669 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17670 (unspec:X87MODEI12 [(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:X87MODEI12 4 "memory_operand" ""))]
17676 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17678 (use (match_dup 2))
17679 (use (match_dup 3))])
17680 (set (match_dup 0) (match_dup 4))]
17684 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17685 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17687 (use (match_operand:HI 2 "memory_operand" ""))
17688 (use (match_operand:HI 3 "memory_operand" ""))
17689 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17691 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17693 (use (match_dup 2))
17694 (use (match_dup 3))])]
17697 (define_expand "lceilxf<mode>2"
17698 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17699 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17701 (clobber (reg:CC FLAGS_REG))])]
17702 "TARGET_USE_FANCY_MATH_387
17703 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17704 && flag_unsafe_math_optimizations"
17707 (define_expand "lceil<mode>di2"
17708 [(match_operand:DI 0 "nonimmediate_operand" "")
17709 (match_operand:SSEMODEF 1 "register_operand" "")]
17710 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17711 && !flag_trapping_math"
17713 ix86_expand_lfloorceil (operand0, operand1, false);
17717 (define_expand "lceil<mode>si2"
17718 [(match_operand:SI 0 "nonimmediate_operand" "")
17719 (match_operand:SSEMODEF 1 "register_operand" "")]
17720 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17721 && !flag_trapping_math"
17723 ix86_expand_lfloorceil (operand0, operand1, false);
17727 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17728 (define_insn_and_split "frndintxf2_trunc"
17729 [(set (match_operand:XF 0 "register_operand" "=f")
17730 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17731 UNSPEC_FRNDINT_TRUNC))
17732 (clobber (reg:CC FLAGS_REG))]
17733 "TARGET_USE_FANCY_MATH_387
17734 && flag_unsafe_math_optimizations
17735 && !(reload_completed || reload_in_progress)"
17740 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17742 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17743 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17745 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17746 operands[2], operands[3]));
17749 [(set_attr "type" "frndint")
17750 (set_attr "i387_cw" "trunc")
17751 (set_attr "mode" "XF")])
17753 (define_insn "frndintxf2_trunc_i387"
17754 [(set (match_operand:XF 0 "register_operand" "=f")
17755 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17756 UNSPEC_FRNDINT_TRUNC))
17757 (use (match_operand:HI 2 "memory_operand" "m"))
17758 (use (match_operand:HI 3 "memory_operand" "m"))]
17759 "TARGET_USE_FANCY_MATH_387
17760 && flag_unsafe_math_optimizations"
17761 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17762 [(set_attr "type" "frndint")
17763 (set_attr "i387_cw" "trunc")
17764 (set_attr "mode" "XF")])
17766 (define_expand "btruncxf2"
17767 [(use (match_operand:XF 0 "register_operand" ""))
17768 (use (match_operand:XF 1 "register_operand" ""))]
17769 "TARGET_USE_FANCY_MATH_387
17770 && flag_unsafe_math_optimizations && !optimize_size"
17772 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17776 (define_expand "btrunc<mode>2"
17777 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17778 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17779 "(TARGET_USE_FANCY_MATH_387
17780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17781 || TARGET_MIX_SSE_I387)
17782 && flag_unsafe_math_optimizations && !optimize_size)
17783 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17784 && !flag_trapping_math
17785 && (TARGET_SSE4_1 || !optimize_size))"
17787 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17788 && !flag_trapping_math
17789 && (TARGET_SSE4_1 || !optimize_size))
17792 emit_insn (gen_sse4_1_round<mode>2
17793 (operands[0], operands[1], GEN_INT (0x03)));
17794 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17795 ix86_expand_trunc (operand0, operand1);
17797 ix86_expand_truncdf_32 (operand0, operand1);
17801 rtx op0 = gen_reg_rtx (XFmode);
17802 rtx op1 = gen_reg_rtx (XFmode);
17804 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17805 emit_insn (gen_frndintxf2_trunc (op0, op1));
17807 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17812 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17813 (define_insn_and_split "frndintxf2_mask_pm"
17814 [(set (match_operand:XF 0 "register_operand" "=f")
17815 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17816 UNSPEC_FRNDINT_MASK_PM))
17817 (clobber (reg:CC FLAGS_REG))]
17818 "TARGET_USE_FANCY_MATH_387
17819 && flag_unsafe_math_optimizations
17820 && !(reload_completed || reload_in_progress)"
17825 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17827 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17828 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17830 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17831 operands[2], operands[3]));
17834 [(set_attr "type" "frndint")
17835 (set_attr "i387_cw" "mask_pm")
17836 (set_attr "mode" "XF")])
17838 (define_insn "frndintxf2_mask_pm_i387"
17839 [(set (match_operand:XF 0 "register_operand" "=f")
17840 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17841 UNSPEC_FRNDINT_MASK_PM))
17842 (use (match_operand:HI 2 "memory_operand" "m"))
17843 (use (match_operand:HI 3 "memory_operand" "m"))]
17844 "TARGET_USE_FANCY_MATH_387
17845 && flag_unsafe_math_optimizations"
17846 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17847 [(set_attr "type" "frndint")
17848 (set_attr "i387_cw" "mask_pm")
17849 (set_attr "mode" "XF")])
17851 (define_expand "nearbyintxf2"
17852 [(use (match_operand:XF 0 "register_operand" ""))
17853 (use (match_operand:XF 1 "register_operand" ""))]
17854 "TARGET_USE_FANCY_MATH_387
17855 && flag_unsafe_math_optimizations"
17857 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17862 (define_expand "nearbyintdf2"
17863 [(use (match_operand:DF 0 "register_operand" ""))
17864 (use (match_operand:DF 1 "register_operand" ""))]
17865 "TARGET_USE_FANCY_MATH_387
17866 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17867 && flag_unsafe_math_optimizations"
17869 rtx op0 = gen_reg_rtx (XFmode);
17870 rtx op1 = gen_reg_rtx (XFmode);
17872 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17873 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17875 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17879 (define_expand "nearbyintsf2"
17880 [(use (match_operand:SF 0 "register_operand" ""))
17881 (use (match_operand:SF 1 "register_operand" ""))]
17882 "TARGET_USE_FANCY_MATH_387
17883 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17884 && flag_unsafe_math_optimizations"
17886 rtx op0 = gen_reg_rtx (XFmode);
17887 rtx op1 = gen_reg_rtx (XFmode);
17889 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17890 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17892 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17896 (define_insn "fxam<mode>2_i387"
17897 [(set (match_operand:HI 0 "register_operand" "=a")
17899 [(match_operand:X87MODEF 1 "register_operand" "f")]
17901 "TARGET_USE_FANCY_MATH_387"
17902 "fxam\n\tfnstsw\t%0"
17903 [(set_attr "type" "multi")
17904 (set_attr "unit" "i387")
17905 (set_attr "mode" "<MODE>")])
17907 (define_expand "isinf<mode>2"
17908 [(use (match_operand:SI 0 "register_operand" ""))
17909 (use (match_operand:X87MODEF 1 "register_operand" ""))]
17910 "TARGET_USE_FANCY_MATH_387
17911 && TARGET_C99_FUNCTIONS
17912 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17913 || TARGET_MIX_SSE_I387)"
17915 rtx mask = GEN_INT (0x45);
17916 rtx val = GEN_INT (0x05);
17920 rtx scratch = gen_reg_rtx (HImode);
17921 rtx res = gen_reg_rtx (QImode);
17923 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17924 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17925 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17926 cond = gen_rtx_fmt_ee (EQ, QImode,
17927 gen_rtx_REG (CCmode, FLAGS_REG),
17929 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17930 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17935 ;; Block operation instructions
17937 (define_expand "movmemsi"
17938 [(use (match_operand:BLK 0 "memory_operand" ""))
17939 (use (match_operand:BLK 1 "memory_operand" ""))
17940 (use (match_operand:SI 2 "nonmemory_operand" ""))
17941 (use (match_operand:SI 3 "const_int_operand" ""))
17942 (use (match_operand:SI 4 "const_int_operand" ""))
17943 (use (match_operand:SI 5 "const_int_operand" ""))]
17946 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17947 operands[4], operands[5]))
17953 (define_expand "movmemdi"
17954 [(use (match_operand:BLK 0 "memory_operand" ""))
17955 (use (match_operand:BLK 1 "memory_operand" ""))
17956 (use (match_operand:DI 2 "nonmemory_operand" ""))
17957 (use (match_operand:DI 3 "const_int_operand" ""))
17958 (use (match_operand:SI 4 "const_int_operand" ""))
17959 (use (match_operand:SI 5 "const_int_operand" ""))]
17962 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17963 operands[4], operands[5]))
17969 ;; Most CPUs don't like single string operations
17970 ;; Handle this case here to simplify previous expander.
17972 (define_expand "strmov"
17973 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17974 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17975 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17976 (clobber (reg:CC FLAGS_REG))])
17977 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17978 (clobber (reg:CC FLAGS_REG))])]
17981 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17983 /* If .md ever supports :P for Pmode, these can be directly
17984 in the pattern above. */
17985 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17986 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17988 if (TARGET_SINGLE_STRINGOP || optimize_size)
17990 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17991 operands[2], operands[3],
17992 operands[5], operands[6]));
17996 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17999 (define_expand "strmov_singleop"
18000 [(parallel [(set (match_operand 1 "memory_operand" "")
18001 (match_operand 3 "memory_operand" ""))
18002 (set (match_operand 0 "register_operand" "")
18003 (match_operand 4 "" ""))
18004 (set (match_operand 2 "register_operand" "")
18005 (match_operand 5 "" ""))])]
18006 "TARGET_SINGLE_STRINGOP || optimize_size"
18009 (define_insn "*strmovdi_rex_1"
18010 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18011 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18012 (set (match_operand:DI 0 "register_operand" "=D")
18013 (plus:DI (match_dup 2)
18015 (set (match_operand:DI 1 "register_operand" "=S")
18016 (plus:DI (match_dup 3)
18018 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18020 [(set_attr "type" "str")
18021 (set_attr "mode" "DI")
18022 (set_attr "memory" "both")])
18024 (define_insn "*strmovsi_1"
18025 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18026 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18027 (set (match_operand:SI 0 "register_operand" "=D")
18028 (plus:SI (match_dup 2)
18030 (set (match_operand:SI 1 "register_operand" "=S")
18031 (plus:SI (match_dup 3)
18033 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18035 [(set_attr "type" "str")
18036 (set_attr "mode" "SI")
18037 (set_attr "memory" "both")])
18039 (define_insn "*strmovsi_rex_1"
18040 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18041 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18042 (set (match_operand:DI 0 "register_operand" "=D")
18043 (plus:DI (match_dup 2)
18045 (set (match_operand:DI 1 "register_operand" "=S")
18046 (plus:DI (match_dup 3)
18048 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18050 [(set_attr "type" "str")
18051 (set_attr "mode" "SI")
18052 (set_attr "memory" "both")])
18054 (define_insn "*strmovhi_1"
18055 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18056 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18057 (set (match_operand:SI 0 "register_operand" "=D")
18058 (plus:SI (match_dup 2)
18060 (set (match_operand:SI 1 "register_operand" "=S")
18061 (plus:SI (match_dup 3)
18063 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18065 [(set_attr "type" "str")
18066 (set_attr "memory" "both")
18067 (set_attr "mode" "HI")])
18069 (define_insn "*strmovhi_rex_1"
18070 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18071 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18072 (set (match_operand:DI 0 "register_operand" "=D")
18073 (plus:DI (match_dup 2)
18075 (set (match_operand:DI 1 "register_operand" "=S")
18076 (plus:DI (match_dup 3)
18078 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18080 [(set_attr "type" "str")
18081 (set_attr "memory" "both")
18082 (set_attr "mode" "HI")])
18084 (define_insn "*strmovqi_1"
18085 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18086 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18087 (set (match_operand:SI 0 "register_operand" "=D")
18088 (plus:SI (match_dup 2)
18090 (set (match_operand:SI 1 "register_operand" "=S")
18091 (plus:SI (match_dup 3)
18093 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18095 [(set_attr "type" "str")
18096 (set_attr "memory" "both")
18097 (set_attr "mode" "QI")])
18099 (define_insn "*strmovqi_rex_1"
18100 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18101 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18102 (set (match_operand:DI 0 "register_operand" "=D")
18103 (plus:DI (match_dup 2)
18105 (set (match_operand:DI 1 "register_operand" "=S")
18106 (plus:DI (match_dup 3)
18108 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18110 [(set_attr "type" "str")
18111 (set_attr "memory" "both")
18112 (set_attr "mode" "QI")])
18114 (define_expand "rep_mov"
18115 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18116 (set (match_operand 0 "register_operand" "")
18117 (match_operand 5 "" ""))
18118 (set (match_operand 2 "register_operand" "")
18119 (match_operand 6 "" ""))
18120 (set (match_operand 1 "memory_operand" "")
18121 (match_operand 3 "memory_operand" ""))
18122 (use (match_dup 4))])]
18126 (define_insn "*rep_movdi_rex64"
18127 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18128 (set (match_operand:DI 0 "register_operand" "=D")
18129 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18131 (match_operand:DI 3 "register_operand" "0")))
18132 (set (match_operand:DI 1 "register_operand" "=S")
18133 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18134 (match_operand:DI 4 "register_operand" "1")))
18135 (set (mem:BLK (match_dup 3))
18136 (mem:BLK (match_dup 4)))
18137 (use (match_dup 5))]
18139 "{rep\;movsq|rep movsq}"
18140 [(set_attr "type" "str")
18141 (set_attr "prefix_rep" "1")
18142 (set_attr "memory" "both")
18143 (set_attr "mode" "DI")])
18145 (define_insn "*rep_movsi"
18146 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18147 (set (match_operand:SI 0 "register_operand" "=D")
18148 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18150 (match_operand:SI 3 "register_operand" "0")))
18151 (set (match_operand:SI 1 "register_operand" "=S")
18152 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18153 (match_operand:SI 4 "register_operand" "1")))
18154 (set (mem:BLK (match_dup 3))
18155 (mem:BLK (match_dup 4)))
18156 (use (match_dup 5))]
18158 "{rep\;movsl|rep movsd}"
18159 [(set_attr "type" "str")
18160 (set_attr "prefix_rep" "1")
18161 (set_attr "memory" "both")
18162 (set_attr "mode" "SI")])
18164 (define_insn "*rep_movsi_rex64"
18165 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18166 (set (match_operand:DI 0 "register_operand" "=D")
18167 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18169 (match_operand:DI 3 "register_operand" "0")))
18170 (set (match_operand:DI 1 "register_operand" "=S")
18171 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18172 (match_operand:DI 4 "register_operand" "1")))
18173 (set (mem:BLK (match_dup 3))
18174 (mem:BLK (match_dup 4)))
18175 (use (match_dup 5))]
18177 "{rep\;movsl|rep movsd}"
18178 [(set_attr "type" "str")
18179 (set_attr "prefix_rep" "1")
18180 (set_attr "memory" "both")
18181 (set_attr "mode" "SI")])
18183 (define_insn "*rep_movqi"
18184 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18185 (set (match_operand:SI 0 "register_operand" "=D")
18186 (plus:SI (match_operand:SI 3 "register_operand" "0")
18187 (match_operand:SI 5 "register_operand" "2")))
18188 (set (match_operand:SI 1 "register_operand" "=S")
18189 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18190 (set (mem:BLK (match_dup 3))
18191 (mem:BLK (match_dup 4)))
18192 (use (match_dup 5))]
18194 "{rep\;movsb|rep movsb}"
18195 [(set_attr "type" "str")
18196 (set_attr "prefix_rep" "1")
18197 (set_attr "memory" "both")
18198 (set_attr "mode" "SI")])
18200 (define_insn "*rep_movqi_rex64"
18201 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18202 (set (match_operand:DI 0 "register_operand" "=D")
18203 (plus:DI (match_operand:DI 3 "register_operand" "0")
18204 (match_operand:DI 5 "register_operand" "2")))
18205 (set (match_operand:DI 1 "register_operand" "=S")
18206 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18207 (set (mem:BLK (match_dup 3))
18208 (mem:BLK (match_dup 4)))
18209 (use (match_dup 5))]
18211 "{rep\;movsb|rep movsb}"
18212 [(set_attr "type" "str")
18213 (set_attr "prefix_rep" "1")
18214 (set_attr "memory" "both")
18215 (set_attr "mode" "SI")])
18217 (define_expand "setmemsi"
18218 [(use (match_operand:BLK 0 "memory_operand" ""))
18219 (use (match_operand:SI 1 "nonmemory_operand" ""))
18220 (use (match_operand 2 "const_int_operand" ""))
18221 (use (match_operand 3 "const_int_operand" ""))
18222 (use (match_operand:SI 4 "const_int_operand" ""))
18223 (use (match_operand:SI 5 "const_int_operand" ""))]
18226 if (ix86_expand_setmem (operands[0], operands[1],
18227 operands[2], operands[3],
18228 operands[4], operands[5]))
18234 (define_expand "setmemdi"
18235 [(use (match_operand:BLK 0 "memory_operand" ""))
18236 (use (match_operand:DI 1 "nonmemory_operand" ""))
18237 (use (match_operand 2 "const_int_operand" ""))
18238 (use (match_operand 3 "const_int_operand" ""))
18239 (use (match_operand 4 "const_int_operand" ""))
18240 (use (match_operand 5 "const_int_operand" ""))]
18243 if (ix86_expand_setmem (operands[0], operands[1],
18244 operands[2], operands[3],
18245 operands[4], operands[5]))
18251 ;; Most CPUs don't like single string operations
18252 ;; Handle this case here to simplify previous expander.
18254 (define_expand "strset"
18255 [(set (match_operand 1 "memory_operand" "")
18256 (match_operand 2 "register_operand" ""))
18257 (parallel [(set (match_operand 0 "register_operand" "")
18259 (clobber (reg:CC FLAGS_REG))])]
18262 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18263 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18265 /* If .md ever supports :P for Pmode, this can be directly
18266 in the pattern above. */
18267 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18268 GEN_INT (GET_MODE_SIZE (GET_MODE
18270 if (TARGET_SINGLE_STRINGOP || optimize_size)
18272 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18278 (define_expand "strset_singleop"
18279 [(parallel [(set (match_operand 1 "memory_operand" "")
18280 (match_operand 2 "register_operand" ""))
18281 (set (match_operand 0 "register_operand" "")
18282 (match_operand 3 "" ""))])]
18283 "TARGET_SINGLE_STRINGOP || optimize_size"
18286 (define_insn "*strsetdi_rex_1"
18287 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18288 (match_operand:DI 2 "register_operand" "a"))
18289 (set (match_operand:DI 0 "register_operand" "=D")
18290 (plus:DI (match_dup 1)
18292 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18294 [(set_attr "type" "str")
18295 (set_attr "memory" "store")
18296 (set_attr "mode" "DI")])
18298 (define_insn "*strsetsi_1"
18299 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18300 (match_operand:SI 2 "register_operand" "a"))
18301 (set (match_operand:SI 0 "register_operand" "=D")
18302 (plus:SI (match_dup 1)
18304 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18306 [(set_attr "type" "str")
18307 (set_attr "memory" "store")
18308 (set_attr "mode" "SI")])
18310 (define_insn "*strsetsi_rex_1"
18311 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18312 (match_operand:SI 2 "register_operand" "a"))
18313 (set (match_operand:DI 0 "register_operand" "=D")
18314 (plus:DI (match_dup 1)
18316 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18318 [(set_attr "type" "str")
18319 (set_attr "memory" "store")
18320 (set_attr "mode" "SI")])
18322 (define_insn "*strsethi_1"
18323 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18324 (match_operand:HI 2 "register_operand" "a"))
18325 (set (match_operand:SI 0 "register_operand" "=D")
18326 (plus:SI (match_dup 1)
18328 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18330 [(set_attr "type" "str")
18331 (set_attr "memory" "store")
18332 (set_attr "mode" "HI")])
18334 (define_insn "*strsethi_rex_1"
18335 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18336 (match_operand:HI 2 "register_operand" "a"))
18337 (set (match_operand:DI 0 "register_operand" "=D")
18338 (plus:DI (match_dup 1)
18340 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18342 [(set_attr "type" "str")
18343 (set_attr "memory" "store")
18344 (set_attr "mode" "HI")])
18346 (define_insn "*strsetqi_1"
18347 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18348 (match_operand:QI 2 "register_operand" "a"))
18349 (set (match_operand:SI 0 "register_operand" "=D")
18350 (plus:SI (match_dup 1)
18352 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18354 [(set_attr "type" "str")
18355 (set_attr "memory" "store")
18356 (set_attr "mode" "QI")])
18358 (define_insn "*strsetqi_rex_1"
18359 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18360 (match_operand:QI 2 "register_operand" "a"))
18361 (set (match_operand:DI 0 "register_operand" "=D")
18362 (plus:DI (match_dup 1)
18364 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18366 [(set_attr "type" "str")
18367 (set_attr "memory" "store")
18368 (set_attr "mode" "QI")])
18370 (define_expand "rep_stos"
18371 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18372 (set (match_operand 0 "register_operand" "")
18373 (match_operand 4 "" ""))
18374 (set (match_operand 2 "memory_operand" "") (const_int 0))
18375 (use (match_operand 3 "register_operand" ""))
18376 (use (match_dup 1))])]
18380 (define_insn "*rep_stosdi_rex64"
18381 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18382 (set (match_operand:DI 0 "register_operand" "=D")
18383 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18385 (match_operand:DI 3 "register_operand" "0")))
18386 (set (mem:BLK (match_dup 3))
18388 (use (match_operand:DI 2 "register_operand" "a"))
18389 (use (match_dup 4))]
18391 "{rep\;stosq|rep stosq}"
18392 [(set_attr "type" "str")
18393 (set_attr "prefix_rep" "1")
18394 (set_attr "memory" "store")
18395 (set_attr "mode" "DI")])
18397 (define_insn "*rep_stossi"
18398 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18399 (set (match_operand:SI 0 "register_operand" "=D")
18400 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18402 (match_operand:SI 3 "register_operand" "0")))
18403 (set (mem:BLK (match_dup 3))
18405 (use (match_operand:SI 2 "register_operand" "a"))
18406 (use (match_dup 4))]
18408 "{rep\;stosl|rep stosd}"
18409 [(set_attr "type" "str")
18410 (set_attr "prefix_rep" "1")
18411 (set_attr "memory" "store")
18412 (set_attr "mode" "SI")])
18414 (define_insn "*rep_stossi_rex64"
18415 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18416 (set (match_operand:DI 0 "register_operand" "=D")
18417 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18419 (match_operand:DI 3 "register_operand" "0")))
18420 (set (mem:BLK (match_dup 3))
18422 (use (match_operand:SI 2 "register_operand" "a"))
18423 (use (match_dup 4))]
18425 "{rep\;stosl|rep stosd}"
18426 [(set_attr "type" "str")
18427 (set_attr "prefix_rep" "1")
18428 (set_attr "memory" "store")
18429 (set_attr "mode" "SI")])
18431 (define_insn "*rep_stosqi"
18432 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18433 (set (match_operand:SI 0 "register_operand" "=D")
18434 (plus:SI (match_operand:SI 3 "register_operand" "0")
18435 (match_operand:SI 4 "register_operand" "1")))
18436 (set (mem:BLK (match_dup 3))
18438 (use (match_operand:QI 2 "register_operand" "a"))
18439 (use (match_dup 4))]
18441 "{rep\;stosb|rep stosb}"
18442 [(set_attr "type" "str")
18443 (set_attr "prefix_rep" "1")
18444 (set_attr "memory" "store")
18445 (set_attr "mode" "QI")])
18447 (define_insn "*rep_stosqi_rex64"
18448 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18449 (set (match_operand:DI 0 "register_operand" "=D")
18450 (plus:DI (match_operand:DI 3 "register_operand" "0")
18451 (match_operand:DI 4 "register_operand" "1")))
18452 (set (mem:BLK (match_dup 3))
18454 (use (match_operand:QI 2 "register_operand" "a"))
18455 (use (match_dup 4))]
18457 "{rep\;stosb|rep stosb}"
18458 [(set_attr "type" "str")
18459 (set_attr "prefix_rep" "1")
18460 (set_attr "memory" "store")
18461 (set_attr "mode" "QI")])
18463 (define_expand "cmpstrnsi"
18464 [(set (match_operand:SI 0 "register_operand" "")
18465 (compare:SI (match_operand:BLK 1 "general_operand" "")
18466 (match_operand:BLK 2 "general_operand" "")))
18467 (use (match_operand 3 "general_operand" ""))
18468 (use (match_operand 4 "immediate_operand" ""))]
18469 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18471 rtx addr1, addr2, out, outlow, count, countreg, align;
18473 /* Can't use this if the user has appropriated esi or edi. */
18474 if (global_regs[4] || global_regs[5])
18479 out = gen_reg_rtx (SImode);
18481 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18482 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18483 if (addr1 != XEXP (operands[1], 0))
18484 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18485 if (addr2 != XEXP (operands[2], 0))
18486 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18488 count = operands[3];
18489 countreg = ix86_zero_extend_to_Pmode (count);
18491 /* %%% Iff we are testing strict equality, we can use known alignment
18492 to good advantage. This may be possible with combine, particularly
18493 once cc0 is dead. */
18494 align = operands[4];
18496 if (CONST_INT_P (count))
18498 if (INTVAL (count) == 0)
18500 emit_move_insn (operands[0], const0_rtx);
18503 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18504 operands[1], operands[2]));
18509 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18511 emit_insn (gen_cmpsi_1 (countreg, countreg));
18512 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18513 operands[1], operands[2]));
18516 outlow = gen_lowpart (QImode, out);
18517 emit_insn (gen_cmpintqi (outlow));
18518 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18520 if (operands[0] != out)
18521 emit_move_insn (operands[0], out);
18526 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18528 (define_expand "cmpintqi"
18529 [(set (match_dup 1)
18530 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18532 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18533 (parallel [(set (match_operand:QI 0 "register_operand" "")
18534 (minus:QI (match_dup 1)
18536 (clobber (reg:CC FLAGS_REG))])]
18538 "operands[1] = gen_reg_rtx (QImode);
18539 operands[2] = gen_reg_rtx (QImode);")
18541 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18542 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18544 (define_expand "cmpstrnqi_nz_1"
18545 [(parallel [(set (reg:CC FLAGS_REG)
18546 (compare:CC (match_operand 4 "memory_operand" "")
18547 (match_operand 5 "memory_operand" "")))
18548 (use (match_operand 2 "register_operand" ""))
18549 (use (match_operand:SI 3 "immediate_operand" ""))
18550 (clobber (match_operand 0 "register_operand" ""))
18551 (clobber (match_operand 1 "register_operand" ""))
18552 (clobber (match_dup 2))])]
18556 (define_insn "*cmpstrnqi_nz_1"
18557 [(set (reg:CC FLAGS_REG)
18558 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18559 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18560 (use (match_operand:SI 6 "register_operand" "2"))
18561 (use (match_operand:SI 3 "immediate_operand" "i"))
18562 (clobber (match_operand:SI 0 "register_operand" "=S"))
18563 (clobber (match_operand:SI 1 "register_operand" "=D"))
18564 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18567 [(set_attr "type" "str")
18568 (set_attr "mode" "QI")
18569 (set_attr "prefix_rep" "1")])
18571 (define_insn "*cmpstrnqi_nz_rex_1"
18572 [(set (reg:CC FLAGS_REG)
18573 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18574 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18575 (use (match_operand:DI 6 "register_operand" "2"))
18576 (use (match_operand:SI 3 "immediate_operand" "i"))
18577 (clobber (match_operand:DI 0 "register_operand" "=S"))
18578 (clobber (match_operand:DI 1 "register_operand" "=D"))
18579 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18582 [(set_attr "type" "str")
18583 (set_attr "mode" "QI")
18584 (set_attr "prefix_rep" "1")])
18586 ;; The same, but the count is not known to not be zero.
18588 (define_expand "cmpstrnqi_1"
18589 [(parallel [(set (reg:CC FLAGS_REG)
18590 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18592 (compare:CC (match_operand 4 "memory_operand" "")
18593 (match_operand 5 "memory_operand" ""))
18595 (use (match_operand:SI 3 "immediate_operand" ""))
18596 (use (reg:CC FLAGS_REG))
18597 (clobber (match_operand 0 "register_operand" ""))
18598 (clobber (match_operand 1 "register_operand" ""))
18599 (clobber (match_dup 2))])]
18603 (define_insn "*cmpstrnqi_1"
18604 [(set (reg:CC FLAGS_REG)
18605 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18607 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18608 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18610 (use (match_operand:SI 3 "immediate_operand" "i"))
18611 (use (reg:CC FLAGS_REG))
18612 (clobber (match_operand:SI 0 "register_operand" "=S"))
18613 (clobber (match_operand:SI 1 "register_operand" "=D"))
18614 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18617 [(set_attr "type" "str")
18618 (set_attr "mode" "QI")
18619 (set_attr "prefix_rep" "1")])
18621 (define_insn "*cmpstrnqi_rex_1"
18622 [(set (reg:CC FLAGS_REG)
18623 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18625 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18626 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18628 (use (match_operand:SI 3 "immediate_operand" "i"))
18629 (use (reg:CC FLAGS_REG))
18630 (clobber (match_operand:DI 0 "register_operand" "=S"))
18631 (clobber (match_operand:DI 1 "register_operand" "=D"))
18632 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18635 [(set_attr "type" "str")
18636 (set_attr "mode" "QI")
18637 (set_attr "prefix_rep" "1")])
18639 (define_expand "strlensi"
18640 [(set (match_operand:SI 0 "register_operand" "")
18641 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18642 (match_operand:QI 2 "immediate_operand" "")
18643 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18646 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18652 (define_expand "strlendi"
18653 [(set (match_operand:DI 0 "register_operand" "")
18654 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18655 (match_operand:QI 2 "immediate_operand" "")
18656 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18659 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18665 (define_expand "strlenqi_1"
18666 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18667 (clobber (match_operand 1 "register_operand" ""))
18668 (clobber (reg:CC FLAGS_REG))])]
18672 (define_insn "*strlenqi_1"
18673 [(set (match_operand:SI 0 "register_operand" "=&c")
18674 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18675 (match_operand:QI 2 "register_operand" "a")
18676 (match_operand:SI 3 "immediate_operand" "i")
18677 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18678 (clobber (match_operand:SI 1 "register_operand" "=D"))
18679 (clobber (reg:CC FLAGS_REG))]
18682 [(set_attr "type" "str")
18683 (set_attr "mode" "QI")
18684 (set_attr "prefix_rep" "1")])
18686 (define_insn "*strlenqi_rex_1"
18687 [(set (match_operand:DI 0 "register_operand" "=&c")
18688 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18689 (match_operand:QI 2 "register_operand" "a")
18690 (match_operand:DI 3 "immediate_operand" "i")
18691 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18692 (clobber (match_operand:DI 1 "register_operand" "=D"))
18693 (clobber (reg:CC FLAGS_REG))]
18696 [(set_attr "type" "str")
18697 (set_attr "mode" "QI")
18698 (set_attr "prefix_rep" "1")])
18700 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18701 ;; handled in combine, but it is not currently up to the task.
18702 ;; When used for their truth value, the cmpstrn* expanders generate
18711 ;; The intermediate three instructions are unnecessary.
18713 ;; This one handles cmpstrn*_nz_1...
18716 (set (reg:CC FLAGS_REG)
18717 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18718 (mem:BLK (match_operand 5 "register_operand" ""))))
18719 (use (match_operand 6 "register_operand" ""))
18720 (use (match_operand:SI 3 "immediate_operand" ""))
18721 (clobber (match_operand 0 "register_operand" ""))
18722 (clobber (match_operand 1 "register_operand" ""))
18723 (clobber (match_operand 2 "register_operand" ""))])
18724 (set (match_operand:QI 7 "register_operand" "")
18725 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18726 (set (match_operand:QI 8 "register_operand" "")
18727 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18728 (set (reg FLAGS_REG)
18729 (compare (match_dup 7) (match_dup 8)))
18731 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18733 (set (reg:CC FLAGS_REG)
18734 (compare:CC (mem:BLK (match_dup 4))
18735 (mem:BLK (match_dup 5))))
18736 (use (match_dup 6))
18737 (use (match_dup 3))
18738 (clobber (match_dup 0))
18739 (clobber (match_dup 1))
18740 (clobber (match_dup 2))])]
18743 ;; ...and this one handles cmpstrn*_1.
18746 (set (reg:CC FLAGS_REG)
18747 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18749 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18750 (mem:BLK (match_operand 5 "register_operand" "")))
18752 (use (match_operand:SI 3 "immediate_operand" ""))
18753 (use (reg:CC FLAGS_REG))
18754 (clobber (match_operand 0 "register_operand" ""))
18755 (clobber (match_operand 1 "register_operand" ""))
18756 (clobber (match_operand 2 "register_operand" ""))])
18757 (set (match_operand:QI 7 "register_operand" "")
18758 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18759 (set (match_operand:QI 8 "register_operand" "")
18760 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18761 (set (reg FLAGS_REG)
18762 (compare (match_dup 7) (match_dup 8)))
18764 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18766 (set (reg:CC FLAGS_REG)
18767 (if_then_else:CC (ne (match_dup 6)
18769 (compare:CC (mem:BLK (match_dup 4))
18770 (mem:BLK (match_dup 5)))
18772 (use (match_dup 3))
18773 (use (reg:CC FLAGS_REG))
18774 (clobber (match_dup 0))
18775 (clobber (match_dup 1))
18776 (clobber (match_dup 2))])]
18781 ;; Conditional move instructions.
18783 (define_expand "movdicc"
18784 [(set (match_operand:DI 0 "register_operand" "")
18785 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18786 (match_operand:DI 2 "general_operand" "")
18787 (match_operand:DI 3 "general_operand" "")))]
18789 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18791 (define_insn "x86_movdicc_0_m1_rex64"
18792 [(set (match_operand:DI 0 "register_operand" "=r")
18793 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18796 (clobber (reg:CC FLAGS_REG))]
18799 ; Since we don't have the proper number of operands for an alu insn,
18800 ; fill in all the blanks.
18801 [(set_attr "type" "alu")
18802 (set_attr "pent_pair" "pu")
18803 (set_attr "memory" "none")
18804 (set_attr "imm_disp" "false")
18805 (set_attr "mode" "DI")
18806 (set_attr "length_immediate" "0")])
18808 (define_insn "*movdicc_c_rex64"
18809 [(set (match_operand:DI 0 "register_operand" "=r,r")
18810 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18811 [(reg FLAGS_REG) (const_int 0)])
18812 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18813 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18814 "TARGET_64BIT && TARGET_CMOVE
18815 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18817 cmov%O2%C1\t{%2, %0|%0, %2}
18818 cmov%O2%c1\t{%3, %0|%0, %3}"
18819 [(set_attr "type" "icmov")
18820 (set_attr "mode" "DI")])
18822 (define_expand "movsicc"
18823 [(set (match_operand:SI 0 "register_operand" "")
18824 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18825 (match_operand:SI 2 "general_operand" "")
18826 (match_operand:SI 3 "general_operand" "")))]
18828 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18830 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18831 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18832 ;; So just document what we're doing explicitly.
18834 (define_insn "x86_movsicc_0_m1"
18835 [(set (match_operand:SI 0 "register_operand" "=r")
18836 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18839 (clobber (reg:CC FLAGS_REG))]
18842 ; Since we don't have the proper number of operands for an alu insn,
18843 ; fill in all the blanks.
18844 [(set_attr "type" "alu")
18845 (set_attr "pent_pair" "pu")
18846 (set_attr "memory" "none")
18847 (set_attr "imm_disp" "false")
18848 (set_attr "mode" "SI")
18849 (set_attr "length_immediate" "0")])
18851 (define_insn "*movsicc_noc"
18852 [(set (match_operand:SI 0 "register_operand" "=r,r")
18853 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18854 [(reg FLAGS_REG) (const_int 0)])
18855 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18856 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18858 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18860 cmov%O2%C1\t{%2, %0|%0, %2}
18861 cmov%O2%c1\t{%3, %0|%0, %3}"
18862 [(set_attr "type" "icmov")
18863 (set_attr "mode" "SI")])
18865 (define_expand "movhicc"
18866 [(set (match_operand:HI 0 "register_operand" "")
18867 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18868 (match_operand:HI 2 "general_operand" "")
18869 (match_operand:HI 3 "general_operand" "")))]
18870 "TARGET_HIMODE_MATH"
18871 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18873 (define_insn "*movhicc_noc"
18874 [(set (match_operand:HI 0 "register_operand" "=r,r")
18875 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18876 [(reg FLAGS_REG) (const_int 0)])
18877 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18878 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18880 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18882 cmov%O2%C1\t{%2, %0|%0, %2}
18883 cmov%O2%c1\t{%3, %0|%0, %3}"
18884 [(set_attr "type" "icmov")
18885 (set_attr "mode" "HI")])
18887 (define_expand "movqicc"
18888 [(set (match_operand:QI 0 "register_operand" "")
18889 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18890 (match_operand:QI 2 "general_operand" "")
18891 (match_operand:QI 3 "general_operand" "")))]
18892 "TARGET_QIMODE_MATH"
18893 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18895 (define_insn_and_split "*movqicc_noc"
18896 [(set (match_operand:QI 0 "register_operand" "=r,r")
18897 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18898 [(match_operand 4 "flags_reg_operand" "")
18900 (match_operand:QI 2 "register_operand" "r,0")
18901 (match_operand:QI 3 "register_operand" "0,r")))]
18902 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18904 "&& reload_completed"
18905 [(set (match_dup 0)
18906 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18909 "operands[0] = gen_lowpart (SImode, operands[0]);
18910 operands[2] = gen_lowpart (SImode, operands[2]);
18911 operands[3] = gen_lowpart (SImode, operands[3]);"
18912 [(set_attr "type" "icmov")
18913 (set_attr "mode" "SI")])
18915 (define_expand "movsfcc"
18916 [(set (match_operand:SF 0 "register_operand" "")
18917 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18918 (match_operand:SF 2 "register_operand" "")
18919 (match_operand:SF 3 "register_operand" "")))]
18920 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18921 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18923 (define_insn "*movsfcc_1_387"
18924 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18925 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18926 [(reg FLAGS_REG) (const_int 0)])
18927 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18928 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18929 "TARGET_80387 && TARGET_CMOVE
18930 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18932 fcmov%F1\t{%2, %0|%0, %2}
18933 fcmov%f1\t{%3, %0|%0, %3}
18934 cmov%O2%C1\t{%2, %0|%0, %2}
18935 cmov%O2%c1\t{%3, %0|%0, %3}"
18936 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18937 (set_attr "mode" "SF,SF,SI,SI")])
18939 (define_expand "movdfcc"
18940 [(set (match_operand:DF 0 "register_operand" "")
18941 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18942 (match_operand:DF 2 "register_operand" "")
18943 (match_operand:DF 3 "register_operand" "")))]
18944 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18945 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18947 (define_insn "*movdfcc_1"
18948 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18949 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18950 [(reg FLAGS_REG) (const_int 0)])
18951 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18952 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18953 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18954 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18956 fcmov%F1\t{%2, %0|%0, %2}
18957 fcmov%f1\t{%3, %0|%0, %3}
18960 [(set_attr "type" "fcmov,fcmov,multi,multi")
18961 (set_attr "mode" "DF")])
18963 (define_insn "*movdfcc_1_rex64"
18964 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18965 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18966 [(reg FLAGS_REG) (const_int 0)])
18967 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18968 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18969 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18970 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18972 fcmov%F1\t{%2, %0|%0, %2}
18973 fcmov%f1\t{%3, %0|%0, %3}
18974 cmov%O2%C1\t{%2, %0|%0, %2}
18975 cmov%O2%c1\t{%3, %0|%0, %3}"
18976 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18977 (set_attr "mode" "DF")])
18980 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18981 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18982 [(match_operand 4 "flags_reg_operand" "")
18984 (match_operand:DF 2 "nonimmediate_operand" "")
18985 (match_operand:DF 3 "nonimmediate_operand" "")))]
18986 "!TARGET_64BIT && reload_completed"
18987 [(set (match_dup 2)
18988 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18992 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18995 "split_di (operands+2, 1, operands+5, operands+6);
18996 split_di (operands+3, 1, operands+7, operands+8);
18997 split_di (operands, 1, operands+2, operands+3);")
18999 (define_expand "movxfcc"
19000 [(set (match_operand:XF 0 "register_operand" "")
19001 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19002 (match_operand:XF 2 "register_operand" "")
19003 (match_operand:XF 3 "register_operand" "")))]
19004 "TARGET_80387 && TARGET_CMOVE"
19005 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19007 (define_insn "*movxfcc_1"
19008 [(set (match_operand:XF 0 "register_operand" "=f,f")
19009 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19010 [(reg FLAGS_REG) (const_int 0)])
19011 (match_operand:XF 2 "register_operand" "f,0")
19012 (match_operand:XF 3 "register_operand" "0,f")))]
19013 "TARGET_80387 && TARGET_CMOVE"
19015 fcmov%F1\t{%2, %0|%0, %2}
19016 fcmov%f1\t{%3, %0|%0, %3}"
19017 [(set_attr "type" "fcmov")
19018 (set_attr "mode" "XF")])
19020 ;; These versions of the min/max patterns are intentionally ignorant of
19021 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19022 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19023 ;; are undefined in this condition, we're certain this is correct.
19025 (define_insn "sminsf3"
19026 [(set (match_operand:SF 0 "register_operand" "=x")
19027 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19028 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19030 "minss\t{%2, %0|%0, %2}"
19031 [(set_attr "type" "sseadd")
19032 (set_attr "mode" "SF")])
19034 (define_insn "smaxsf3"
19035 [(set (match_operand:SF 0 "register_operand" "=x")
19036 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19037 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19039 "maxss\t{%2, %0|%0, %2}"
19040 [(set_attr "type" "sseadd")
19041 (set_attr "mode" "SF")])
19043 (define_insn "smindf3"
19044 [(set (match_operand:DF 0 "register_operand" "=x")
19045 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19046 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19047 "TARGET_SSE2 && TARGET_SSE_MATH"
19048 "minsd\t{%2, %0|%0, %2}"
19049 [(set_attr "type" "sseadd")
19050 (set_attr "mode" "DF")])
19052 (define_insn "smaxdf3"
19053 [(set (match_operand:DF 0 "register_operand" "=x")
19054 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19055 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19056 "TARGET_SSE2 && TARGET_SSE_MATH"
19057 "maxsd\t{%2, %0|%0, %2}"
19058 [(set_attr "type" "sseadd")
19059 (set_attr "mode" "DF")])
19061 ;; These versions of the min/max patterns implement exactly the operations
19062 ;; min = (op1 < op2 ? op1 : op2)
19063 ;; max = (!(op1 < op2) ? op1 : op2)
19064 ;; Their operands are not commutative, and thus they may be used in the
19065 ;; presence of -0.0 and NaN.
19067 (define_insn "*ieee_sminsf3"
19068 [(set (match_operand:SF 0 "register_operand" "=x")
19069 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19070 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19073 "minss\t{%2, %0|%0, %2}"
19074 [(set_attr "type" "sseadd")
19075 (set_attr "mode" "SF")])
19077 (define_insn "*ieee_smaxsf3"
19078 [(set (match_operand:SF 0 "register_operand" "=x")
19079 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19080 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19083 "maxss\t{%2, %0|%0, %2}"
19084 [(set_attr "type" "sseadd")
19085 (set_attr "mode" "SF")])
19087 (define_insn "*ieee_smindf3"
19088 [(set (match_operand:DF 0 "register_operand" "=x")
19089 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19090 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19092 "TARGET_SSE2 && TARGET_SSE_MATH"
19093 "minsd\t{%2, %0|%0, %2}"
19094 [(set_attr "type" "sseadd")
19095 (set_attr "mode" "DF")])
19097 (define_insn "*ieee_smaxdf3"
19098 [(set (match_operand:DF 0 "register_operand" "=x")
19099 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19100 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19102 "TARGET_SSE2 && TARGET_SSE_MATH"
19103 "maxsd\t{%2, %0|%0, %2}"
19104 [(set_attr "type" "sseadd")
19105 (set_attr "mode" "DF")])
19107 ;; Make two stack loads independent:
19109 ;; fld %st(0) -> fld bb
19110 ;; fmul bb fmul %st(1), %st
19112 ;; Actually we only match the last two instructions for simplicity.
19114 [(set (match_operand 0 "fp_register_operand" "")
19115 (match_operand 1 "fp_register_operand" ""))
19117 (match_operator 2 "binary_fp_operator"
19119 (match_operand 3 "memory_operand" "")]))]
19120 "REGNO (operands[0]) != REGNO (operands[1])"
19121 [(set (match_dup 0) (match_dup 3))
19122 (set (match_dup 0) (match_dup 4))]
19124 ;; The % modifier is not operational anymore in peephole2's, so we have to
19125 ;; swap the operands manually in the case of addition and multiplication.
19126 "if (COMMUTATIVE_ARITH_P (operands[2]))
19127 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19128 operands[0], operands[1]);
19130 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19131 operands[1], operands[0]);")
19133 ;; Conditional addition patterns
19134 (define_expand "addqicc"
19135 [(match_operand:QI 0 "register_operand" "")
19136 (match_operand 1 "comparison_operator" "")
19137 (match_operand:QI 2 "register_operand" "")
19138 (match_operand:QI 3 "const_int_operand" "")]
19140 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19142 (define_expand "addhicc"
19143 [(match_operand:HI 0 "register_operand" "")
19144 (match_operand 1 "comparison_operator" "")
19145 (match_operand:HI 2 "register_operand" "")
19146 (match_operand:HI 3 "const_int_operand" "")]
19148 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19150 (define_expand "addsicc"
19151 [(match_operand:SI 0 "register_operand" "")
19152 (match_operand 1 "comparison_operator" "")
19153 (match_operand:SI 2 "register_operand" "")
19154 (match_operand:SI 3 "const_int_operand" "")]
19156 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19158 (define_expand "adddicc"
19159 [(match_operand:DI 0 "register_operand" "")
19160 (match_operand 1 "comparison_operator" "")
19161 (match_operand:DI 2 "register_operand" "")
19162 (match_operand:DI 3 "const_int_operand" "")]
19164 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19167 ;; Misc patterns (?)
19169 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19170 ;; Otherwise there will be nothing to keep
19172 ;; [(set (reg ebp) (reg esp))]
19173 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19174 ;; (clobber (eflags)]
19175 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19177 ;; in proper program order.
19178 (define_insn "pro_epilogue_adjust_stack_1"
19179 [(set (match_operand:SI 0 "register_operand" "=r,r")
19180 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19181 (match_operand:SI 2 "immediate_operand" "i,i")))
19182 (clobber (reg:CC FLAGS_REG))
19183 (clobber (mem:BLK (scratch)))]
19186 switch (get_attr_type (insn))
19189 return "mov{l}\t{%1, %0|%0, %1}";
19192 if (CONST_INT_P (operands[2])
19193 && (INTVAL (operands[2]) == 128
19194 || (INTVAL (operands[2]) < 0
19195 && INTVAL (operands[2]) != -128)))
19197 operands[2] = GEN_INT (-INTVAL (operands[2]));
19198 return "sub{l}\t{%2, %0|%0, %2}";
19200 return "add{l}\t{%2, %0|%0, %2}";
19203 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19204 return "lea{l}\t{%a2, %0|%0, %a2}";
19207 gcc_unreachable ();
19210 [(set (attr "type")
19211 (cond [(eq_attr "alternative" "0")
19212 (const_string "alu")
19213 (match_operand:SI 2 "const0_operand" "")
19214 (const_string "imov")
19216 (const_string "lea")))
19217 (set_attr "mode" "SI")])
19219 (define_insn "pro_epilogue_adjust_stack_rex64"
19220 [(set (match_operand:DI 0 "register_operand" "=r,r")
19221 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19222 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19223 (clobber (reg:CC FLAGS_REG))
19224 (clobber (mem:BLK (scratch)))]
19227 switch (get_attr_type (insn))
19230 return "mov{q}\t{%1, %0|%0, %1}";
19233 if (CONST_INT_P (operands[2])
19234 /* Avoid overflows. */
19235 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19236 && (INTVAL (operands[2]) == 128
19237 || (INTVAL (operands[2]) < 0
19238 && INTVAL (operands[2]) != -128)))
19240 operands[2] = GEN_INT (-INTVAL (operands[2]));
19241 return "sub{q}\t{%2, %0|%0, %2}";
19243 return "add{q}\t{%2, %0|%0, %2}";
19246 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19247 return "lea{q}\t{%a2, %0|%0, %a2}";
19250 gcc_unreachable ();
19253 [(set (attr "type")
19254 (cond [(eq_attr "alternative" "0")
19255 (const_string "alu")
19256 (match_operand:DI 2 "const0_operand" "")
19257 (const_string "imov")
19259 (const_string "lea")))
19260 (set_attr "mode" "DI")])
19262 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19263 [(set (match_operand:DI 0 "register_operand" "=r,r")
19264 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19265 (match_operand:DI 3 "immediate_operand" "i,i")))
19266 (use (match_operand:DI 2 "register_operand" "r,r"))
19267 (clobber (reg:CC FLAGS_REG))
19268 (clobber (mem:BLK (scratch)))]
19271 switch (get_attr_type (insn))
19274 return "add{q}\t{%2, %0|%0, %2}";
19277 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19278 return "lea{q}\t{%a2, %0|%0, %a2}";
19281 gcc_unreachable ();
19284 [(set_attr "type" "alu,lea")
19285 (set_attr "mode" "DI")])
19287 (define_insn "allocate_stack_worker_32"
19288 [(set (match_operand:SI 0 "register_operand" "+a")
19289 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19290 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19291 (clobber (reg:CC FLAGS_REG))]
19292 "!TARGET_64BIT && TARGET_STACK_PROBE"
19294 [(set_attr "type" "multi")
19295 (set_attr "length" "5")])
19297 (define_insn "allocate_stack_worker_64"
19298 [(set (match_operand:DI 0 "register_operand" "=a")
19299 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19300 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19301 (clobber (reg:DI R10_REG))
19302 (clobber (reg:DI R11_REG))
19303 (clobber (reg:CC FLAGS_REG))]
19304 "TARGET_64BIT && TARGET_STACK_PROBE"
19306 [(set_attr "type" "multi")
19307 (set_attr "length" "5")])
19309 (define_expand "allocate_stack"
19310 [(match_operand 0 "register_operand" "")
19311 (match_operand 1 "general_operand" "")]
19312 "TARGET_STACK_PROBE"
19316 #ifndef CHECK_STACK_LIMIT
19317 #define CHECK_STACK_LIMIT 0
19320 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19321 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19323 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19324 stack_pointer_rtx, 0, OPTAB_DIRECT);
19325 if (x != stack_pointer_rtx)
19326 emit_move_insn (stack_pointer_rtx, x);
19330 x = copy_to_mode_reg (Pmode, operands[1]);
19332 x = gen_allocate_stack_worker_64 (x);
19334 x = gen_allocate_stack_worker_32 (x);
19338 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19342 (define_expand "builtin_setjmp_receiver"
19343 [(label_ref (match_operand 0 "" ""))]
19344 "!TARGET_64BIT && flag_pic"
19349 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19350 rtx label_rtx = gen_label_rtx ();
19351 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19352 xops[0] = xops[1] = picreg;
19353 xops[2] = gen_rtx_CONST (SImode,
19354 gen_rtx_MINUS (SImode,
19355 gen_rtx_LABEL_REF (SImode, label_rtx),
19356 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19357 ix86_expand_binary_operator (MINUS, SImode, xops);
19360 emit_insn (gen_set_got (pic_offset_table_rtx));
19364 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19367 [(set (match_operand 0 "register_operand" "")
19368 (match_operator 3 "promotable_binary_operator"
19369 [(match_operand 1 "register_operand" "")
19370 (match_operand 2 "aligned_operand" "")]))
19371 (clobber (reg:CC FLAGS_REG))]
19372 "! TARGET_PARTIAL_REG_STALL && reload_completed
19373 && ((GET_MODE (operands[0]) == HImode
19374 && ((!optimize_size && !TARGET_FAST_PREFIX)
19375 /* ??? next two lines just !satisfies_constraint_K (...) */
19376 || !CONST_INT_P (operands[2])
19377 || satisfies_constraint_K (operands[2])))
19378 || (GET_MODE (operands[0]) == QImode
19379 && (TARGET_PROMOTE_QImode || optimize_size)))"
19380 [(parallel [(set (match_dup 0)
19381 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19382 (clobber (reg:CC FLAGS_REG))])]
19383 "operands[0] = gen_lowpart (SImode, operands[0]);
19384 operands[1] = gen_lowpart (SImode, operands[1]);
19385 if (GET_CODE (operands[3]) != ASHIFT)
19386 operands[2] = gen_lowpart (SImode, operands[2]);
19387 PUT_MODE (operands[3], SImode);")
19389 ; Promote the QImode tests, as i386 has encoding of the AND
19390 ; instruction with 32-bit sign-extended immediate and thus the
19391 ; instruction size is unchanged, except in the %eax case for
19392 ; which it is increased by one byte, hence the ! optimize_size.
19394 [(set (match_operand 0 "flags_reg_operand" "")
19395 (match_operator 2 "compare_operator"
19396 [(and (match_operand 3 "aligned_operand" "")
19397 (match_operand 4 "const_int_operand" ""))
19399 (set (match_operand 1 "register_operand" "")
19400 (and (match_dup 3) (match_dup 4)))]
19401 "! TARGET_PARTIAL_REG_STALL && reload_completed
19402 /* Ensure that the operand will remain sign-extended immediate. */
19403 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19405 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19406 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19407 [(parallel [(set (match_dup 0)
19408 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19411 (and:SI (match_dup 3) (match_dup 4)))])]
19414 = gen_int_mode (INTVAL (operands[4])
19415 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19416 operands[1] = gen_lowpart (SImode, operands[1]);
19417 operands[3] = gen_lowpart (SImode, operands[3]);
19420 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19421 ; the TEST instruction with 32-bit sign-extended immediate and thus
19422 ; the instruction size would at least double, which is not what we
19423 ; want even with ! optimize_size.
19425 [(set (match_operand 0 "flags_reg_operand" "")
19426 (match_operator 1 "compare_operator"
19427 [(and (match_operand:HI 2 "aligned_operand" "")
19428 (match_operand:HI 3 "const_int_operand" ""))
19430 "! TARGET_PARTIAL_REG_STALL && reload_completed
19431 /* Ensure that the operand will remain sign-extended immediate. */
19432 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19433 && ! TARGET_FAST_PREFIX
19434 && ! optimize_size"
19435 [(set (match_dup 0)
19436 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19440 = gen_int_mode (INTVAL (operands[3])
19441 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19442 operands[2] = gen_lowpart (SImode, operands[2]);
19446 [(set (match_operand 0 "register_operand" "")
19447 (neg (match_operand 1 "register_operand" "")))
19448 (clobber (reg:CC FLAGS_REG))]
19449 "! TARGET_PARTIAL_REG_STALL && reload_completed
19450 && (GET_MODE (operands[0]) == HImode
19451 || (GET_MODE (operands[0]) == QImode
19452 && (TARGET_PROMOTE_QImode || optimize_size)))"
19453 [(parallel [(set (match_dup 0)
19454 (neg:SI (match_dup 1)))
19455 (clobber (reg:CC FLAGS_REG))])]
19456 "operands[0] = gen_lowpart (SImode, operands[0]);
19457 operands[1] = gen_lowpart (SImode, operands[1]);")
19460 [(set (match_operand 0 "register_operand" "")
19461 (not (match_operand 1 "register_operand" "")))]
19462 "! TARGET_PARTIAL_REG_STALL && reload_completed
19463 && (GET_MODE (operands[0]) == HImode
19464 || (GET_MODE (operands[0]) == QImode
19465 && (TARGET_PROMOTE_QImode || optimize_size)))"
19466 [(set (match_dup 0)
19467 (not:SI (match_dup 1)))]
19468 "operands[0] = gen_lowpart (SImode, operands[0]);
19469 operands[1] = gen_lowpart (SImode, operands[1]);")
19472 [(set (match_operand 0 "register_operand" "")
19473 (if_then_else (match_operator 1 "comparison_operator"
19474 [(reg FLAGS_REG) (const_int 0)])
19475 (match_operand 2 "register_operand" "")
19476 (match_operand 3 "register_operand" "")))]
19477 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19478 && (GET_MODE (operands[0]) == HImode
19479 || (GET_MODE (operands[0]) == QImode
19480 && (TARGET_PROMOTE_QImode || optimize_size)))"
19481 [(set (match_dup 0)
19482 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19483 "operands[0] = gen_lowpart (SImode, operands[0]);
19484 operands[2] = gen_lowpart (SImode, operands[2]);
19485 operands[3] = gen_lowpart (SImode, operands[3]);")
19488 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19489 ;; transform a complex memory operation into two memory to register operations.
19491 ;; Don't push memory operands
19493 [(set (match_operand:SI 0 "push_operand" "")
19494 (match_operand:SI 1 "memory_operand" ""))
19495 (match_scratch:SI 2 "r")]
19496 "!optimize_size && !TARGET_PUSH_MEMORY
19497 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19498 [(set (match_dup 2) (match_dup 1))
19499 (set (match_dup 0) (match_dup 2))]
19503 [(set (match_operand:DI 0 "push_operand" "")
19504 (match_operand:DI 1 "memory_operand" ""))
19505 (match_scratch:DI 2 "r")]
19506 "!optimize_size && !TARGET_PUSH_MEMORY
19507 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19508 [(set (match_dup 2) (match_dup 1))
19509 (set (match_dup 0) (match_dup 2))]
19512 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19515 [(set (match_operand:SF 0 "push_operand" "")
19516 (match_operand:SF 1 "memory_operand" ""))
19517 (match_scratch:SF 2 "r")]
19518 "!optimize_size && !TARGET_PUSH_MEMORY
19519 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19520 [(set (match_dup 2) (match_dup 1))
19521 (set (match_dup 0) (match_dup 2))]
19525 [(set (match_operand:HI 0 "push_operand" "")
19526 (match_operand:HI 1 "memory_operand" ""))
19527 (match_scratch:HI 2 "r")]
19528 "!optimize_size && !TARGET_PUSH_MEMORY
19529 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19530 [(set (match_dup 2) (match_dup 1))
19531 (set (match_dup 0) (match_dup 2))]
19535 [(set (match_operand:QI 0 "push_operand" "")
19536 (match_operand:QI 1 "memory_operand" ""))
19537 (match_scratch:QI 2 "q")]
19538 "!optimize_size && !TARGET_PUSH_MEMORY
19539 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19540 [(set (match_dup 2) (match_dup 1))
19541 (set (match_dup 0) (match_dup 2))]
19544 ;; Don't move an immediate directly to memory when the instruction
19547 [(match_scratch:SI 1 "r")
19548 (set (match_operand:SI 0 "memory_operand" "")
19551 && ! TARGET_USE_MOV0
19552 && TARGET_SPLIT_LONG_MOVES
19553 && get_attr_length (insn) >= ix86_cost->large_insn
19554 && peep2_regno_dead_p (0, FLAGS_REG)"
19555 [(parallel [(set (match_dup 1) (const_int 0))
19556 (clobber (reg:CC FLAGS_REG))])
19557 (set (match_dup 0) (match_dup 1))]
19561 [(match_scratch:HI 1 "r")
19562 (set (match_operand:HI 0 "memory_operand" "")
19565 && ! TARGET_USE_MOV0
19566 && TARGET_SPLIT_LONG_MOVES
19567 && get_attr_length (insn) >= ix86_cost->large_insn
19568 && peep2_regno_dead_p (0, FLAGS_REG)"
19569 [(parallel [(set (match_dup 2) (const_int 0))
19570 (clobber (reg:CC FLAGS_REG))])
19571 (set (match_dup 0) (match_dup 1))]
19572 "operands[2] = gen_lowpart (SImode, operands[1]);")
19575 [(match_scratch:QI 1 "q")
19576 (set (match_operand:QI 0 "memory_operand" "")
19579 && ! TARGET_USE_MOV0
19580 && TARGET_SPLIT_LONG_MOVES
19581 && get_attr_length (insn) >= ix86_cost->large_insn
19582 && peep2_regno_dead_p (0, FLAGS_REG)"
19583 [(parallel [(set (match_dup 2) (const_int 0))
19584 (clobber (reg:CC FLAGS_REG))])
19585 (set (match_dup 0) (match_dup 1))]
19586 "operands[2] = gen_lowpart (SImode, operands[1]);")
19589 [(match_scratch:SI 2 "r")
19590 (set (match_operand:SI 0 "memory_operand" "")
19591 (match_operand:SI 1 "immediate_operand" ""))]
19593 && get_attr_length (insn) >= ix86_cost->large_insn
19594 && TARGET_SPLIT_LONG_MOVES"
19595 [(set (match_dup 2) (match_dup 1))
19596 (set (match_dup 0) (match_dup 2))]
19600 [(match_scratch:HI 2 "r")
19601 (set (match_operand:HI 0 "memory_operand" "")
19602 (match_operand:HI 1 "immediate_operand" ""))]
19603 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19604 && TARGET_SPLIT_LONG_MOVES"
19605 [(set (match_dup 2) (match_dup 1))
19606 (set (match_dup 0) (match_dup 2))]
19610 [(match_scratch:QI 2 "q")
19611 (set (match_operand:QI 0 "memory_operand" "")
19612 (match_operand:QI 1 "immediate_operand" ""))]
19613 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19614 && TARGET_SPLIT_LONG_MOVES"
19615 [(set (match_dup 2) (match_dup 1))
19616 (set (match_dup 0) (match_dup 2))]
19619 ;; Don't compare memory with zero, load and use a test instead.
19621 [(set (match_operand 0 "flags_reg_operand" "")
19622 (match_operator 1 "compare_operator"
19623 [(match_operand:SI 2 "memory_operand" "")
19625 (match_scratch:SI 3 "r")]
19626 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19627 [(set (match_dup 3) (match_dup 2))
19628 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19631 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19632 ;; Don't split NOTs with a displacement operand, because resulting XOR
19633 ;; will not be pairable anyway.
19635 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19636 ;; represented using a modRM byte. The XOR replacement is long decoded,
19637 ;; so this split helps here as well.
19639 ;; Note: Can't do this as a regular split because we can't get proper
19640 ;; lifetime information then.
19643 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19644 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19646 && peep2_regno_dead_p (0, FLAGS_REG)
19647 && ((TARGET_NOT_UNPAIRABLE
19648 && (!MEM_P (operands[0])
19649 || !memory_displacement_operand (operands[0], SImode)))
19650 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))"
19651 [(parallel [(set (match_dup 0)
19652 (xor:SI (match_dup 1) (const_int -1)))
19653 (clobber (reg:CC FLAGS_REG))])]
19657 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19658 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19660 && peep2_regno_dead_p (0, FLAGS_REG)
19661 && ((TARGET_NOT_UNPAIRABLE
19662 && (!MEM_P (operands[0])
19663 || !memory_displacement_operand (operands[0], HImode)))
19664 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))"
19665 [(parallel [(set (match_dup 0)
19666 (xor:HI (match_dup 1) (const_int -1)))
19667 (clobber (reg:CC FLAGS_REG))])]
19671 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19672 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19674 && peep2_regno_dead_p (0, FLAGS_REG)
19675 && ((TARGET_NOT_UNPAIRABLE
19676 && (!MEM_P (operands[0])
19677 || !memory_displacement_operand (operands[0], QImode)))
19678 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))"
19679 [(parallel [(set (match_dup 0)
19680 (xor:QI (match_dup 1) (const_int -1)))
19681 (clobber (reg:CC FLAGS_REG))])]
19684 ;; Non pairable "test imm, reg" instructions can be translated to
19685 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19686 ;; byte opcode instead of two, have a short form for byte operands),
19687 ;; so do it for other CPUs as well. Given that the value was dead,
19688 ;; this should not create any new dependencies. Pass on the sub-word
19689 ;; versions if we're concerned about partial register stalls.
19692 [(set (match_operand 0 "flags_reg_operand" "")
19693 (match_operator 1 "compare_operator"
19694 [(and:SI (match_operand:SI 2 "register_operand" "")
19695 (match_operand:SI 3 "immediate_operand" ""))
19697 "ix86_match_ccmode (insn, CCNOmode)
19698 && (true_regnum (operands[2]) != 0
19699 || satisfies_constraint_K (operands[3]))
19700 && peep2_reg_dead_p (1, operands[2])"
19702 [(set (match_dup 0)
19703 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19706 (and:SI (match_dup 2) (match_dup 3)))])]
19709 ;; We don't need to handle HImode case, because it will be promoted to SImode
19710 ;; on ! TARGET_PARTIAL_REG_STALL
19713 [(set (match_operand 0 "flags_reg_operand" "")
19714 (match_operator 1 "compare_operator"
19715 [(and:QI (match_operand:QI 2 "register_operand" "")
19716 (match_operand:QI 3 "immediate_operand" ""))
19718 "! TARGET_PARTIAL_REG_STALL
19719 && ix86_match_ccmode (insn, CCNOmode)
19720 && true_regnum (operands[2]) != 0
19721 && peep2_reg_dead_p (1, operands[2])"
19723 [(set (match_dup 0)
19724 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19727 (and:QI (match_dup 2) (match_dup 3)))])]
19731 [(set (match_operand 0 "flags_reg_operand" "")
19732 (match_operator 1 "compare_operator"
19735 (match_operand 2 "ext_register_operand" "")
19738 (match_operand 3 "const_int_operand" ""))
19740 "! TARGET_PARTIAL_REG_STALL
19741 && ix86_match_ccmode (insn, CCNOmode)
19742 && true_regnum (operands[2]) != 0
19743 && peep2_reg_dead_p (1, operands[2])"
19744 [(parallel [(set (match_dup 0)
19753 (set (zero_extract:SI (match_dup 2)
19764 ;; Don't do logical operations with memory inputs.
19766 [(match_scratch:SI 2 "r")
19767 (parallel [(set (match_operand:SI 0 "register_operand" "")
19768 (match_operator:SI 3 "arith_or_logical_operator"
19770 (match_operand:SI 1 "memory_operand" "")]))
19771 (clobber (reg:CC FLAGS_REG))])]
19772 "! optimize_size && ! TARGET_READ_MODIFY"
19773 [(set (match_dup 2) (match_dup 1))
19774 (parallel [(set (match_dup 0)
19775 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19776 (clobber (reg:CC FLAGS_REG))])]
19780 [(match_scratch:SI 2 "r")
19781 (parallel [(set (match_operand:SI 0 "register_operand" "")
19782 (match_operator:SI 3 "arith_or_logical_operator"
19783 [(match_operand:SI 1 "memory_operand" "")
19785 (clobber (reg:CC FLAGS_REG))])]
19786 "! optimize_size && ! TARGET_READ_MODIFY"
19787 [(set (match_dup 2) (match_dup 1))
19788 (parallel [(set (match_dup 0)
19789 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19790 (clobber (reg:CC FLAGS_REG))])]
19793 ; Don't do logical operations with memory outputs
19795 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19796 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19797 ; the same decoder scheduling characteristics as the original.
19800 [(match_scratch:SI 2 "r")
19801 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19802 (match_operator:SI 3 "arith_or_logical_operator"
19804 (match_operand:SI 1 "nonmemory_operand" "")]))
19805 (clobber (reg:CC FLAGS_REG))])]
19806 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19807 [(set (match_dup 2) (match_dup 0))
19808 (parallel [(set (match_dup 2)
19809 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19810 (clobber (reg:CC FLAGS_REG))])
19811 (set (match_dup 0) (match_dup 2))]
19815 [(match_scratch:SI 2 "r")
19816 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19817 (match_operator:SI 3 "arith_or_logical_operator"
19818 [(match_operand:SI 1 "nonmemory_operand" "")
19820 (clobber (reg:CC FLAGS_REG))])]
19821 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19822 [(set (match_dup 2) (match_dup 0))
19823 (parallel [(set (match_dup 2)
19824 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19825 (clobber (reg:CC FLAGS_REG))])
19826 (set (match_dup 0) (match_dup 2))]
19829 ;; Attempt to always use XOR for zeroing registers.
19831 [(set (match_operand 0 "register_operand" "")
19832 (match_operand 1 "const0_operand" ""))]
19833 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19834 && (! TARGET_USE_MOV0 || optimize_size)
19835 && GENERAL_REG_P (operands[0])
19836 && peep2_regno_dead_p (0, FLAGS_REG)"
19837 [(parallel [(set (match_dup 0) (const_int 0))
19838 (clobber (reg:CC FLAGS_REG))])]
19840 operands[0] = gen_lowpart (word_mode, operands[0]);
19844 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19846 "(GET_MODE (operands[0]) == QImode
19847 || GET_MODE (operands[0]) == HImode)
19848 && (! TARGET_USE_MOV0 || optimize_size)
19849 && peep2_regno_dead_p (0, FLAGS_REG)"
19850 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19851 (clobber (reg:CC FLAGS_REG))])])
19853 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19855 [(set (match_operand 0 "register_operand" "")
19857 "(GET_MODE (operands[0]) == HImode
19858 || GET_MODE (operands[0]) == SImode
19859 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19860 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
19861 && peep2_regno_dead_p (0, FLAGS_REG)"
19862 [(parallel [(set (match_dup 0) (const_int -1))
19863 (clobber (reg:CC FLAGS_REG))])]
19864 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19867 ;; Attempt to convert simple leas to adds. These can be created by
19870 [(set (match_operand:SI 0 "register_operand" "")
19871 (plus:SI (match_dup 0)
19872 (match_operand:SI 1 "nonmemory_operand" "")))]
19873 "peep2_regno_dead_p (0, FLAGS_REG)"
19874 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19875 (clobber (reg:CC FLAGS_REG))])]
19879 [(set (match_operand:SI 0 "register_operand" "")
19880 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19881 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19882 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19883 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19884 (clobber (reg:CC FLAGS_REG))])]
19885 "operands[2] = gen_lowpart (SImode, operands[2]);")
19888 [(set (match_operand:DI 0 "register_operand" "")
19889 (plus:DI (match_dup 0)
19890 (match_operand:DI 1 "x86_64_general_operand" "")))]
19891 "peep2_regno_dead_p (0, FLAGS_REG)"
19892 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19893 (clobber (reg:CC FLAGS_REG))])]
19897 [(set (match_operand:SI 0 "register_operand" "")
19898 (mult:SI (match_dup 0)
19899 (match_operand:SI 1 "const_int_operand" "")))]
19900 "exact_log2 (INTVAL (operands[1])) >= 0
19901 && peep2_regno_dead_p (0, FLAGS_REG)"
19902 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19903 (clobber (reg:CC FLAGS_REG))])]
19904 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19907 [(set (match_operand:DI 0 "register_operand" "")
19908 (mult:DI (match_dup 0)
19909 (match_operand:DI 1 "const_int_operand" "")))]
19910 "exact_log2 (INTVAL (operands[1])) >= 0
19911 && peep2_regno_dead_p (0, FLAGS_REG)"
19912 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19913 (clobber (reg:CC FLAGS_REG))])]
19914 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19917 [(set (match_operand:SI 0 "register_operand" "")
19918 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19919 (match_operand:DI 2 "const_int_operand" "")) 0))]
19920 "exact_log2 (INTVAL (operands[2])) >= 0
19921 && REGNO (operands[0]) == REGNO (operands[1])
19922 && peep2_regno_dead_p (0, FLAGS_REG)"
19923 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19924 (clobber (reg:CC FLAGS_REG))])]
19925 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19927 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19928 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19929 ;; many CPUs it is also faster, since special hardware to avoid esp
19930 ;; dependencies is present.
19932 ;; While some of these conversions may be done using splitters, we use peepholes
19933 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19935 ;; Convert prologue esp subtractions to push.
19936 ;; We need register to push. In order to keep verify_flow_info happy we have
19938 ;; - use scratch and clobber it in order to avoid dependencies
19939 ;; - use already live register
19940 ;; We can't use the second way right now, since there is no reliable way how to
19941 ;; verify that given register is live. First choice will also most likely in
19942 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19943 ;; call clobbered registers are dead. We may want to use base pointer as an
19944 ;; alternative when no register is available later.
19947 [(match_scratch:SI 0 "r")
19948 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19949 (clobber (reg:CC FLAGS_REG))
19950 (clobber (mem:BLK (scratch)))])]
19951 "optimize_size || !TARGET_SUB_ESP_4"
19952 [(clobber (match_dup 0))
19953 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19954 (clobber (mem:BLK (scratch)))])])
19957 [(match_scratch:SI 0 "r")
19958 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19959 (clobber (reg:CC FLAGS_REG))
19960 (clobber (mem:BLK (scratch)))])]
19961 "optimize_size || !TARGET_SUB_ESP_8"
19962 [(clobber (match_dup 0))
19963 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19964 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19965 (clobber (mem:BLK (scratch)))])])
19967 ;; Convert esp subtractions to push.
19969 [(match_scratch:SI 0 "r")
19970 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19971 (clobber (reg:CC FLAGS_REG))])]
19972 "optimize_size || !TARGET_SUB_ESP_4"
19973 [(clobber (match_dup 0))
19974 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19977 [(match_scratch:SI 0 "r")
19978 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19979 (clobber (reg:CC FLAGS_REG))])]
19980 "optimize_size || !TARGET_SUB_ESP_8"
19981 [(clobber (match_dup 0))
19982 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19983 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19985 ;; Convert epilogue deallocator to pop.
19987 [(match_scratch:SI 0 "r")
19988 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19989 (clobber (reg:CC FLAGS_REG))
19990 (clobber (mem:BLK (scratch)))])]
19991 "optimize_size || !TARGET_ADD_ESP_4"
19992 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19993 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19994 (clobber (mem:BLK (scratch)))])]
19997 ;; Two pops case is tricky, since pop causes dependency on destination register.
19998 ;; We use two registers if available.
20000 [(match_scratch:SI 0 "r")
20001 (match_scratch:SI 1 "r")
20002 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20003 (clobber (reg:CC FLAGS_REG))
20004 (clobber (mem:BLK (scratch)))])]
20005 "optimize_size || !TARGET_ADD_ESP_8"
20006 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20007 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20008 (clobber (mem:BLK (scratch)))])
20009 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20010 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20014 [(match_scratch:SI 0 "r")
20015 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20016 (clobber (reg:CC FLAGS_REG))
20017 (clobber (mem:BLK (scratch)))])]
20019 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20020 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20021 (clobber (mem:BLK (scratch)))])
20022 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20023 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20026 ;; Convert esp additions to pop.
20028 [(match_scratch:SI 0 "r")
20029 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20030 (clobber (reg:CC FLAGS_REG))])]
20032 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20033 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20036 ;; Two pops case is tricky, since pop causes dependency on destination register.
20037 ;; We use two registers if available.
20039 [(match_scratch:SI 0 "r")
20040 (match_scratch:SI 1 "r")
20041 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20042 (clobber (reg:CC FLAGS_REG))])]
20044 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20045 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20046 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20047 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20051 [(match_scratch:SI 0 "r")
20052 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20053 (clobber (reg:CC FLAGS_REG))])]
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 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20058 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20061 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20062 ;; required and register dies. Similarly for 128 to plus -128.
20064 [(set (match_operand 0 "flags_reg_operand" "")
20065 (match_operator 1 "compare_operator"
20066 [(match_operand 2 "register_operand" "")
20067 (match_operand 3 "const_int_operand" "")]))]
20068 "(INTVAL (operands[3]) == -1
20069 || INTVAL (operands[3]) == 1
20070 || INTVAL (operands[3]) == 128)
20071 && ix86_match_ccmode (insn, CCGCmode)
20072 && peep2_reg_dead_p (1, operands[2])"
20073 [(parallel [(set (match_dup 0)
20074 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20075 (clobber (match_dup 2))])]
20079 [(match_scratch:DI 0 "r")
20080 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20081 (clobber (reg:CC FLAGS_REG))
20082 (clobber (mem:BLK (scratch)))])]
20083 "optimize_size || !TARGET_SUB_ESP_4"
20084 [(clobber (match_dup 0))
20085 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20086 (clobber (mem:BLK (scratch)))])])
20089 [(match_scratch:DI 0 "r")
20090 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20091 (clobber (reg:CC FLAGS_REG))
20092 (clobber (mem:BLK (scratch)))])]
20093 "optimize_size || !TARGET_SUB_ESP_8"
20094 [(clobber (match_dup 0))
20095 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20096 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20097 (clobber (mem:BLK (scratch)))])])
20099 ;; Convert esp subtractions to push.
20101 [(match_scratch:DI 0 "r")
20102 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20103 (clobber (reg:CC FLAGS_REG))])]
20104 "optimize_size || !TARGET_SUB_ESP_4"
20105 [(clobber (match_dup 0))
20106 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20109 [(match_scratch:DI 0 "r")
20110 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20111 (clobber (reg:CC FLAGS_REG))])]
20112 "optimize_size || !TARGET_SUB_ESP_8"
20113 [(clobber (match_dup 0))
20114 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20115 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20117 ;; Convert epilogue deallocator to pop.
20119 [(match_scratch:DI 0 "r")
20120 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20121 (clobber (reg:CC FLAGS_REG))
20122 (clobber (mem:BLK (scratch)))])]
20123 "optimize_size || !TARGET_ADD_ESP_4"
20124 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20125 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20126 (clobber (mem:BLK (scratch)))])]
20129 ;; Two pops case is tricky, since pop causes dependency on destination register.
20130 ;; We use two registers if available.
20132 [(match_scratch:DI 0 "r")
20133 (match_scratch:DI 1 "r")
20134 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20135 (clobber (reg:CC FLAGS_REG))
20136 (clobber (mem:BLK (scratch)))])]
20137 "optimize_size || !TARGET_ADD_ESP_8"
20138 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20139 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20140 (clobber (mem:BLK (scratch)))])
20141 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20142 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20146 [(match_scratch:DI 0 "r")
20147 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20148 (clobber (reg:CC FLAGS_REG))
20149 (clobber (mem:BLK (scratch)))])]
20151 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20152 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20153 (clobber (mem:BLK (scratch)))])
20154 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20155 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20158 ;; Convert esp additions to pop.
20160 [(match_scratch:DI 0 "r")
20161 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20162 (clobber (reg:CC FLAGS_REG))])]
20164 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20165 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20168 ;; Two pops case is tricky, since pop causes dependency on destination register.
20169 ;; We use two registers if available.
20171 [(match_scratch:DI 0 "r")
20172 (match_scratch:DI 1 "r")
20173 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20174 (clobber (reg:CC FLAGS_REG))])]
20176 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20177 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20178 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20179 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20183 [(match_scratch:DI 0 "r")
20184 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20185 (clobber (reg:CC FLAGS_REG))])]
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 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20190 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20193 ;; Convert imul by three, five and nine into lea
20196 [(set (match_operand:SI 0 "register_operand" "")
20197 (mult:SI (match_operand:SI 1 "register_operand" "")
20198 (match_operand:SI 2 "const_int_operand" "")))
20199 (clobber (reg:CC FLAGS_REG))])]
20200 "INTVAL (operands[2]) == 3
20201 || INTVAL (operands[2]) == 5
20202 || INTVAL (operands[2]) == 9"
20203 [(set (match_dup 0)
20204 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20206 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20210 [(set (match_operand:SI 0 "register_operand" "")
20211 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20212 (match_operand:SI 2 "const_int_operand" "")))
20213 (clobber (reg:CC FLAGS_REG))])]
20215 && (INTVAL (operands[2]) == 3
20216 || INTVAL (operands[2]) == 5
20217 || INTVAL (operands[2]) == 9)"
20218 [(set (match_dup 0) (match_dup 1))
20220 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20222 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20226 [(set (match_operand:DI 0 "register_operand" "")
20227 (mult:DI (match_operand:DI 1 "register_operand" "")
20228 (match_operand:DI 2 "const_int_operand" "")))
20229 (clobber (reg:CC FLAGS_REG))])]
20231 && (INTVAL (operands[2]) == 3
20232 || INTVAL (operands[2]) == 5
20233 || INTVAL (operands[2]) == 9)"
20234 [(set (match_dup 0)
20235 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20237 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20241 [(set (match_operand:DI 0 "register_operand" "")
20242 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20243 (match_operand:DI 2 "const_int_operand" "")))
20244 (clobber (reg:CC FLAGS_REG))])]
20247 && (INTVAL (operands[2]) == 3
20248 || INTVAL (operands[2]) == 5
20249 || INTVAL (operands[2]) == 9)"
20250 [(set (match_dup 0) (match_dup 1))
20252 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20254 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20256 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20257 ;; imul $32bit_imm, reg, reg is direct decoded.
20259 [(match_scratch:DI 3 "r")
20260 (parallel [(set (match_operand:DI 0 "register_operand" "")
20261 (mult:DI (match_operand:DI 1 "memory_operand" "")
20262 (match_operand:DI 2 "immediate_operand" "")))
20263 (clobber (reg:CC FLAGS_REG))])]
20264 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20265 && !satisfies_constraint_K (operands[2])"
20266 [(set (match_dup 3) (match_dup 1))
20267 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20268 (clobber (reg:CC FLAGS_REG))])]
20272 [(match_scratch:SI 3 "r")
20273 (parallel [(set (match_operand:SI 0 "register_operand" "")
20274 (mult:SI (match_operand:SI 1 "memory_operand" "")
20275 (match_operand:SI 2 "immediate_operand" "")))
20276 (clobber (reg:CC FLAGS_REG))])]
20277 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20278 && !satisfies_constraint_K (operands[2])"
20279 [(set (match_dup 3) (match_dup 1))
20280 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20281 (clobber (reg:CC FLAGS_REG))])]
20285 [(match_scratch:SI 3 "r")
20286 (parallel [(set (match_operand:DI 0 "register_operand" "")
20288 (mult:SI (match_operand:SI 1 "memory_operand" "")
20289 (match_operand:SI 2 "immediate_operand" ""))))
20290 (clobber (reg:CC FLAGS_REG))])]
20291 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20292 && !satisfies_constraint_K (operands[2])"
20293 [(set (match_dup 3) (match_dup 1))
20294 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20295 (clobber (reg:CC FLAGS_REG))])]
20298 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20299 ;; Convert it into imul reg, reg
20300 ;; It would be better to force assembler to encode instruction using long
20301 ;; immediate, but there is apparently no way to do so.
20303 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20304 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20305 (match_operand:DI 2 "const_int_operand" "")))
20306 (clobber (reg:CC FLAGS_REG))])
20307 (match_scratch:DI 3 "r")]
20308 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20309 && satisfies_constraint_K (operands[2])"
20310 [(set (match_dup 3) (match_dup 2))
20311 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20312 (clobber (reg:CC FLAGS_REG))])]
20314 if (!rtx_equal_p (operands[0], operands[1]))
20315 emit_move_insn (operands[0], operands[1]);
20319 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20320 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20321 (match_operand:SI 2 "const_int_operand" "")))
20322 (clobber (reg:CC FLAGS_REG))])
20323 (match_scratch:SI 3 "r")]
20324 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20325 && satisfies_constraint_K (operands[2])"
20326 [(set (match_dup 3) (match_dup 2))
20327 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20328 (clobber (reg:CC FLAGS_REG))])]
20330 if (!rtx_equal_p (operands[0], operands[1]))
20331 emit_move_insn (operands[0], operands[1]);
20335 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20336 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20337 (match_operand:HI 2 "immediate_operand" "")))
20338 (clobber (reg:CC FLAGS_REG))])
20339 (match_scratch:HI 3 "r")]
20340 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20341 [(set (match_dup 3) (match_dup 2))
20342 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20343 (clobber (reg:CC FLAGS_REG))])]
20345 if (!rtx_equal_p (operands[0], operands[1]))
20346 emit_move_insn (operands[0], operands[1]);
20349 ;; After splitting up read-modify operations, array accesses with memory
20350 ;; operands might end up in form:
20352 ;; movl 4(%esp), %edx
20354 ;; instead of pre-splitting:
20356 ;; addl 4(%esp), %eax
20358 ;; movl 4(%esp), %edx
20359 ;; leal (%edx,%eax,4), %eax
20362 [(parallel [(set (match_operand 0 "register_operand" "")
20363 (ashift (match_operand 1 "register_operand" "")
20364 (match_operand 2 "const_int_operand" "")))
20365 (clobber (reg:CC FLAGS_REG))])
20366 (set (match_operand 3 "register_operand")
20367 (match_operand 4 "x86_64_general_operand" ""))
20368 (parallel [(set (match_operand 5 "register_operand" "")
20369 (plus (match_operand 6 "register_operand" "")
20370 (match_operand 7 "register_operand" "")))
20371 (clobber (reg:CC FLAGS_REG))])]
20372 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20373 /* Validate MODE for lea. */
20374 && ((!TARGET_PARTIAL_REG_STALL
20375 && (GET_MODE (operands[0]) == QImode
20376 || GET_MODE (operands[0]) == HImode))
20377 || GET_MODE (operands[0]) == SImode
20378 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20379 /* We reorder load and the shift. */
20380 && !rtx_equal_p (operands[1], operands[3])
20381 && !reg_overlap_mentioned_p (operands[0], operands[4])
20382 /* Last PLUS must consist of operand 0 and 3. */
20383 && !rtx_equal_p (operands[0], operands[3])
20384 && (rtx_equal_p (operands[3], operands[6])
20385 || rtx_equal_p (operands[3], operands[7]))
20386 && (rtx_equal_p (operands[0], operands[6])
20387 || rtx_equal_p (operands[0], operands[7]))
20388 /* The intermediate operand 0 must die or be same as output. */
20389 && (rtx_equal_p (operands[0], operands[5])
20390 || peep2_reg_dead_p (3, operands[0]))"
20391 [(set (match_dup 3) (match_dup 4))
20392 (set (match_dup 0) (match_dup 1))]
20394 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20395 int scale = 1 << INTVAL (operands[2]);
20396 rtx index = gen_lowpart (Pmode, operands[1]);
20397 rtx base = gen_lowpart (Pmode, operands[3]);
20398 rtx dest = gen_lowpart (mode, operands[5]);
20400 operands[1] = gen_rtx_PLUS (Pmode, base,
20401 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20403 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20404 operands[0] = dest;
20407 ;; Call-value patterns last so that the wildcard operand does not
20408 ;; disrupt insn-recog's switch tables.
20410 (define_insn "*call_value_pop_0"
20411 [(set (match_operand 0 "" "")
20412 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20413 (match_operand:SI 2 "" "")))
20414 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20415 (match_operand:SI 3 "immediate_operand" "")))]
20418 if (SIBLING_CALL_P (insn))
20421 return "call\t%P1";
20423 [(set_attr "type" "callv")])
20425 (define_insn "*call_value_pop_1"
20426 [(set (match_operand 0 "" "")
20427 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20428 (match_operand:SI 2 "" "")))
20429 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20430 (match_operand:SI 3 "immediate_operand" "i")))]
20433 if (constant_call_address_operand (operands[1], Pmode))
20435 if (SIBLING_CALL_P (insn))
20438 return "call\t%P1";
20440 if (SIBLING_CALL_P (insn))
20443 return "call\t%A1";
20445 [(set_attr "type" "callv")])
20447 (define_insn "*call_value_0"
20448 [(set (match_operand 0 "" "")
20449 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20450 (match_operand:SI 2 "" "")))]
20453 if (SIBLING_CALL_P (insn))
20456 return "call\t%P1";
20458 [(set_attr "type" "callv")])
20460 (define_insn "*call_value_0_rex64"
20461 [(set (match_operand 0 "" "")
20462 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20463 (match_operand:DI 2 "const_int_operand" "")))]
20466 if (SIBLING_CALL_P (insn))
20469 return "call\t%P1";
20471 [(set_attr "type" "callv")])
20473 (define_insn "*call_value_1"
20474 [(set (match_operand 0 "" "")
20475 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20476 (match_operand:SI 2 "" "")))]
20477 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20479 if (constant_call_address_operand (operands[1], Pmode))
20480 return "call\t%P1";
20481 return "call\t%A1";
20483 [(set_attr "type" "callv")])
20485 (define_insn "*sibcall_value_1"
20486 [(set (match_operand 0 "" "")
20487 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20488 (match_operand:SI 2 "" "")))]
20489 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20491 if (constant_call_address_operand (operands[1], Pmode))
20495 [(set_attr "type" "callv")])
20497 (define_insn "*call_value_1_rex64"
20498 [(set (match_operand 0 "" "")
20499 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20500 (match_operand:DI 2 "" "")))]
20501 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20502 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20504 if (constant_call_address_operand (operands[1], Pmode))
20505 return "call\t%P1";
20506 return "call\t%A1";
20508 [(set_attr "type" "callv")])
20510 (define_insn "*call_value_1_rex64_large"
20511 [(set (match_operand 0 "" "")
20512 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20513 (match_operand:DI 2 "" "")))]
20514 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20516 [(set_attr "type" "callv")])
20518 (define_insn "*sibcall_value_1_rex64"
20519 [(set (match_operand 0 "" "")
20520 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20521 (match_operand:DI 2 "" "")))]
20522 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20524 [(set_attr "type" "callv")])
20526 (define_insn "*sibcall_value_1_rex64_v"
20527 [(set (match_operand 0 "" "")
20528 (call (mem:QI (reg:DI R11_REG))
20529 (match_operand:DI 1 "" "")))]
20530 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20532 [(set_attr "type" "callv")])
20534 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20535 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20536 ;; caught for use by garbage collectors and the like. Using an insn that
20537 ;; maps to SIGILL makes it more likely the program will rightfully die.
20538 ;; Keeping with tradition, "6" is in honor of #UD.
20539 (define_insn "trap"
20540 [(trap_if (const_int 1) (const_int 6))]
20542 { return ASM_SHORT "0x0b0f"; }
20543 [(set_attr "length" "2")])
20545 (define_expand "sse_prologue_save"
20546 [(parallel [(set (match_operand:BLK 0 "" "")
20547 (unspec:BLK [(reg:DI 21)
20554 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20555 (use (match_operand:DI 1 "register_operand" ""))
20556 (use (match_operand:DI 2 "immediate_operand" ""))
20557 (use (label_ref:DI (match_operand 3 "" "")))])]
20561 (define_insn "*sse_prologue_save_insn"
20562 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20563 (match_operand:DI 4 "const_int_operand" "n")))
20564 (unspec:BLK [(reg:DI 21)
20571 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20572 (use (match_operand:DI 1 "register_operand" "r"))
20573 (use (match_operand:DI 2 "const_int_operand" "i"))
20574 (use (label_ref:DI (match_operand 3 "" "X")))]
20576 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20577 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20581 operands[0] = gen_rtx_MEM (Pmode,
20582 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20583 output_asm_insn (\"jmp\\t%A1\", operands);
20584 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20586 operands[4] = adjust_address (operands[0], DImode, i*16);
20587 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20588 PUT_MODE (operands[4], TImode);
20589 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20590 output_asm_insn (\"rex\", operands);
20591 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20593 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20594 CODE_LABEL_NUMBER (operands[3]));
20598 [(set_attr "type" "other")
20599 (set_attr "length_immediate" "0")
20600 (set_attr "length_address" "0")
20601 (set_attr "length" "135")
20602 (set_attr "memory" "store")
20603 (set_attr "modrm" "0")
20604 (set_attr "mode" "DI")])
20606 (define_expand "prefetch"
20607 [(prefetch (match_operand 0 "address_operand" "")
20608 (match_operand:SI 1 "const_int_operand" "")
20609 (match_operand:SI 2 "const_int_operand" ""))]
20610 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20612 int rw = INTVAL (operands[1]);
20613 int locality = INTVAL (operands[2]);
20615 gcc_assert (rw == 0 || rw == 1);
20616 gcc_assert (locality >= 0 && locality <= 3);
20617 gcc_assert (GET_MODE (operands[0]) == Pmode
20618 || GET_MODE (operands[0]) == VOIDmode);
20620 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20621 supported by SSE counterpart or the SSE prefetch is not available
20622 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20624 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20625 operands[2] = GEN_INT (3);
20627 operands[1] = const0_rtx;
20630 (define_insn "*prefetch_sse"
20631 [(prefetch (match_operand:SI 0 "address_operand" "p")
20633 (match_operand:SI 1 "const_int_operand" ""))]
20634 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20636 static const char * const patterns[4] = {
20637 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20640 int locality = INTVAL (operands[1]);
20641 gcc_assert (locality >= 0 && locality <= 3);
20643 return patterns[locality];
20645 [(set_attr "type" "sse")
20646 (set_attr "memory" "none")])
20648 (define_insn "*prefetch_sse_rex"
20649 [(prefetch (match_operand:DI 0 "address_operand" "p")
20651 (match_operand:SI 1 "const_int_operand" ""))]
20652 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20654 static const char * const patterns[4] = {
20655 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20658 int locality = INTVAL (operands[1]);
20659 gcc_assert (locality >= 0 && locality <= 3);
20661 return patterns[locality];
20663 [(set_attr "type" "sse")
20664 (set_attr "memory" "none")])
20666 (define_insn "*prefetch_3dnow"
20667 [(prefetch (match_operand:SI 0 "address_operand" "p")
20668 (match_operand:SI 1 "const_int_operand" "n")
20670 "TARGET_3DNOW && !TARGET_64BIT"
20672 if (INTVAL (operands[1]) == 0)
20673 return "prefetch\t%a0";
20675 return "prefetchw\t%a0";
20677 [(set_attr "type" "mmx")
20678 (set_attr "memory" "none")])
20680 (define_insn "*prefetch_3dnow_rex"
20681 [(prefetch (match_operand:DI 0 "address_operand" "p")
20682 (match_operand:SI 1 "const_int_operand" "n")
20684 "TARGET_3DNOW && TARGET_64BIT"
20686 if (INTVAL (operands[1]) == 0)
20687 return "prefetch\t%a0";
20689 return "prefetchw\t%a0";
20691 [(set_attr "type" "mmx")
20692 (set_attr "memory" "none")])
20694 (define_expand "stack_protect_set"
20695 [(match_operand 0 "memory_operand" "")
20696 (match_operand 1 "memory_operand" "")]
20699 #ifdef TARGET_THREAD_SSP_OFFSET
20701 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20702 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20704 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20705 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20708 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20710 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20715 (define_insn "stack_protect_set_si"
20716 [(set (match_operand:SI 0 "memory_operand" "=m")
20717 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20718 (set (match_scratch:SI 2 "=&r") (const_int 0))
20719 (clobber (reg:CC FLAGS_REG))]
20721 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20722 [(set_attr "type" "multi")])
20724 (define_insn "stack_protect_set_di"
20725 [(set (match_operand:DI 0 "memory_operand" "=m")
20726 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20727 (set (match_scratch:DI 2 "=&r") (const_int 0))
20728 (clobber (reg:CC FLAGS_REG))]
20730 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20731 [(set_attr "type" "multi")])
20733 (define_insn "stack_tls_protect_set_si"
20734 [(set (match_operand:SI 0 "memory_operand" "=m")
20735 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20736 (set (match_scratch:SI 2 "=&r") (const_int 0))
20737 (clobber (reg:CC FLAGS_REG))]
20739 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20740 [(set_attr "type" "multi")])
20742 (define_insn "stack_tls_protect_set_di"
20743 [(set (match_operand:DI 0 "memory_operand" "=m")
20744 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20745 (set (match_scratch:DI 2 "=&r") (const_int 0))
20746 (clobber (reg:CC FLAGS_REG))]
20749 /* The kernel uses a different segment register for performance reasons; a
20750 system call would not have to trash the userspace segment register,
20751 which would be expensive */
20752 if (ix86_cmodel != CM_KERNEL)
20753 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20755 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20757 [(set_attr "type" "multi")])
20759 (define_expand "stack_protect_test"
20760 [(match_operand 0 "memory_operand" "")
20761 (match_operand 1 "memory_operand" "")
20762 (match_operand 2 "" "")]
20765 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20766 ix86_compare_op0 = operands[0];
20767 ix86_compare_op1 = operands[1];
20768 ix86_compare_emitted = flags;
20770 #ifdef TARGET_THREAD_SSP_OFFSET
20772 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20773 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20775 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20776 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20779 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20781 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20783 emit_jump_insn (gen_beq (operands[2]));
20787 (define_insn "stack_protect_test_si"
20788 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20789 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20790 (match_operand:SI 2 "memory_operand" "m")]
20792 (clobber (match_scratch:SI 3 "=&r"))]
20794 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20795 [(set_attr "type" "multi")])
20797 (define_insn "stack_protect_test_di"
20798 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20799 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20800 (match_operand:DI 2 "memory_operand" "m")]
20802 (clobber (match_scratch:DI 3 "=&r"))]
20804 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20805 [(set_attr "type" "multi")])
20807 (define_insn "stack_tls_protect_test_si"
20808 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20809 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20810 (match_operand:SI 2 "const_int_operand" "i")]
20811 UNSPEC_SP_TLS_TEST))
20812 (clobber (match_scratch:SI 3 "=r"))]
20814 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20815 [(set_attr "type" "multi")])
20817 (define_insn "stack_tls_protect_test_di"
20818 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20819 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20820 (match_operand:DI 2 "const_int_operand" "i")]
20821 UNSPEC_SP_TLS_TEST))
20822 (clobber (match_scratch:DI 3 "=r"))]
20825 /* The kernel uses a different segment register for performance reasons; a
20826 system call would not have to trash the userspace segment register,
20827 which would be expensive */
20828 if (ix86_cmodel != CM_KERNEL)
20829 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20831 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20833 [(set_attr "type" "multi")])
20835 (define_mode_macro CRC32MODE [QI HI SI])
20836 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
20837 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
20839 (define_insn "sse4_2_crc32<mode>"
20840 [(set (match_operand:SI 0 "register_operand" "=r")
20842 [(match_operand:SI 1 "register_operand" "0")
20843 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
20846 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
20847 [(set_attr "type" "sselog1")
20848 (set_attr "prefix_rep" "1")
20849 (set_attr "prefix_extra" "1")
20850 (set_attr "mode" "SI")])
20852 (define_insn "sse4_2_crc32di"
20853 [(set (match_operand:DI 0 "register_operand" "=r")
20855 [(match_operand:DI 1 "register_operand" "0")
20856 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20858 "TARGET_SSE4_2 && TARGET_64BIT"
20859 "crc32q\t{%2, %0|%0, %2}"
20860 [(set_attr "type" "sselog1")
20861 (set_attr "prefix_rep" "1")
20862 (set_attr "prefix_extra" "1")
20863 (set_attr "mode" "DI")])
20867 (include "sync.md")