1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
63 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_SET_GOT_OFFSET 17)
74 (UNSPEC_TLS_LD_BASE 20)
77 ; Other random patterns
86 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
87 (UNSPEC_TRUNC_NOOP 39)
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 40)
108 ; Generic math support
110 (UNSPEC_IEEE_MIN 51) ; not commutative
111 (UNSPEC_IEEE_MAX 52) ; not commutative
126 (UNSPEC_FRNDINT_FLOOR 70)
127 (UNSPEC_FRNDINT_CEIL 71)
128 (UNSPEC_FRNDINT_TRUNC 72)
129 (UNSPEC_FRNDINT_MASK_PM 73)
130 (UNSPEC_FIST_FLOOR 74)
131 (UNSPEC_FIST_CEIL 75)
133 ; x87 Double output FP
134 (UNSPEC_SINCOS_COS 80)
135 (UNSPEC_SINCOS_SIN 81)
136 (UNSPEC_XTRACT_FRACT 84)
137 (UNSPEC_XTRACT_EXP 85)
138 (UNSPEC_FSCALE_FRACT 86)
139 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
161 (UNSPEC_INSERTQI 132)
166 (UNSPEC_INSERTPS 135)
168 (UNSPEC_MOVNTDQA 137)
170 (UNSPEC_PHMINPOSUW 139)
176 (UNSPEC_PCMPESTR 144)
177 (UNSPEC_PCMPISTR 145)
180 (UNSPEC_SSE5_INTRINSIC 150)
181 (UNSPEC_SSE5_UNSIGNED_CMP 151)
182 (UNSPEC_SSE5_TRUEFALSE 152)
183 (UNSPEC_SSE5_PERMUTE 153)
184 (UNSPEC_SSE5_ASHIFT 154)
185 (UNSPEC_SSE5_LSHIFT 155)
187 (UNSPEC_CVTPH2PS 157)
188 (UNSPEC_CVTPS2PH 158)
192 [(UNSPECV_BLOCKAGE 0)
193 (UNSPECV_STACK_PROBE 1)
202 (UNSPECV_CMPXCHG_1 10)
203 (UNSPECV_CMPXCHG_2 11)
206 (UNSPECV_PROLOGUE_USE 14)
209 ;; Constants to represent pcomtrue/pcomfalse variants
219 ;; Registers by name.
235 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
238 ;; In C guard expressions, put expressions which may be compile-time
239 ;; constants first. This allows for better optimization. For
240 ;; example, write "TARGET_64BIT && reload_completed", not
241 ;; "reload_completed && TARGET_64BIT".
244 ;; Processor type. This attribute must exactly match the processor_type
245 ;; enumeration in i386.h.
246 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
247 nocona,core2,generic32,generic64,amdfam10"
248 (const (symbol_ref "ix86_tune")))
250 ;; A basic instruction type. Refinements due to arguments to be
251 ;; provided in other attributes.
254 alu,alu1,negnot,imov,imovx,lea,
255 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
256 icmp,test,ibr,setcc,icmov,
257 push,pop,call,callv,leave,
259 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
260 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
261 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
263 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
264 (const_string "other"))
266 ;; Main data type used by the insn
268 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
269 (const_string "unknown"))
271 ;; The CPU unit operations uses.
272 (define_attr "unit" "integer,i387,sse,mmx,unknown"
273 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
274 (const_string "i387")
275 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
276 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
277 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
279 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
281 (eq_attr "type" "other")
282 (const_string "unknown")]
283 (const_string "integer")))
285 ;; The (bounding maximum) length of an instruction immediate.
286 (define_attr "length_immediate" ""
287 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
290 (eq_attr "unit" "i387,sse,mmx")
292 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
294 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
295 (eq_attr "type" "imov,test")
296 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
297 (eq_attr "type" "call")
298 (if_then_else (match_operand 0 "constant_call_address_operand" "")
301 (eq_attr "type" "callv")
302 (if_then_else (match_operand 1 "constant_call_address_operand" "")
305 ;; We don't know the size before shorten_branches. Expect
306 ;; the instruction to fit for better scheduling.
307 (eq_attr "type" "ibr")
310 (symbol_ref "/* Update immediate_length and other attributes! */
311 gcc_unreachable (),1")))
313 ;; The (bounding maximum) length of an instruction address.
314 (define_attr "length_address" ""
315 (cond [(eq_attr "type" "str,other,multi,fxch")
317 (and (eq_attr "type" "call")
318 (match_operand 0 "constant_call_address_operand" ""))
320 (and (eq_attr "type" "callv")
321 (match_operand 1 "constant_call_address_operand" ""))
324 (symbol_ref "ix86_attr_length_address_default (insn)")))
326 ;; Set when length prefix is used.
327 (define_attr "prefix_data16" ""
328 (if_then_else (ior (eq_attr "mode" "HI")
329 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
333 ;; Set when string REP prefix is used.
334 (define_attr "prefix_rep" ""
335 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
339 ;; Set when 0f opcode prefix is used.
340 (define_attr "prefix_0f" ""
342 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
343 (eq_attr "unit" "sse,mmx"))
347 ;; Set when REX opcode prefix is used.
348 (define_attr "prefix_rex" ""
349 (cond [(and (eq_attr "mode" "DI")
350 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
352 (and (eq_attr "mode" "QI")
353 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
356 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
362 ;; There are also additional prefixes in SSSE3.
363 (define_attr "prefix_extra" "" (const_int 0))
365 ;; Set when modrm byte is used.
366 (define_attr "modrm" ""
367 (cond [(eq_attr "type" "str,leave")
369 (eq_attr "unit" "i387")
371 (and (eq_attr "type" "incdec")
372 (ior (match_operand:SI 1 "register_operand" "")
373 (match_operand:HI 1 "register_operand" "")))
375 (and (eq_attr "type" "push")
376 (not (match_operand 1 "memory_operand" "")))
378 (and (eq_attr "type" "pop")
379 (not (match_operand 0 "memory_operand" "")))
381 (and (eq_attr "type" "imov")
382 (ior (and (match_operand 0 "register_operand" "")
383 (match_operand 1 "immediate_operand" ""))
384 (ior (and (match_operand 0 "ax_reg_operand" "")
385 (match_operand 1 "memory_displacement_only_operand" ""))
386 (and (match_operand 0 "memory_displacement_only_operand" "")
387 (match_operand 1 "ax_reg_operand" "")))))
389 (and (eq_attr "type" "call")
390 (match_operand 0 "constant_call_address_operand" ""))
392 (and (eq_attr "type" "callv")
393 (match_operand 1 "constant_call_address_operand" ""))
398 ;; The (bounding maximum) length of an instruction in bytes.
399 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
400 ;; Later we may want to split them and compute proper length as for
402 (define_attr "length" ""
403 (cond [(eq_attr "type" "other,multi,fistp,frndint")
405 (eq_attr "type" "fcmp")
407 (eq_attr "unit" "i387")
409 (plus (attr "prefix_data16")
410 (attr "length_address")))]
411 (plus (plus (attr "modrm")
412 (plus (attr "prefix_0f")
413 (plus (attr "prefix_rex")
414 (plus (attr "prefix_extra")
416 (plus (attr "prefix_rep")
417 (plus (attr "prefix_data16")
418 (plus (attr "length_immediate")
419 (attr "length_address")))))))
421 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
422 ;; `store' if there is a simple memory reference therein, or `unknown'
423 ;; if the instruction is complex.
425 (define_attr "memory" "none,load,store,both,unknown"
426 (cond [(eq_attr "type" "other,multi,str")
427 (const_string "unknown")
428 (eq_attr "type" "lea,fcmov,fpspc")
429 (const_string "none")
430 (eq_attr "type" "fistp,leave")
431 (const_string "both")
432 (eq_attr "type" "frndint")
433 (const_string "load")
434 (eq_attr "type" "push")
435 (if_then_else (match_operand 1 "memory_operand" "")
436 (const_string "both")
437 (const_string "store"))
438 (eq_attr "type" "pop")
439 (if_then_else (match_operand 0 "memory_operand" "")
440 (const_string "both")
441 (const_string "load"))
442 (eq_attr "type" "setcc")
443 (if_then_else (match_operand 0 "memory_operand" "")
444 (const_string "store")
445 (const_string "none"))
446 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
447 (if_then_else (ior (match_operand 0 "memory_operand" "")
448 (match_operand 1 "memory_operand" ""))
449 (const_string "load")
450 (const_string "none"))
451 (eq_attr "type" "ibr")
452 (if_then_else (match_operand 0 "memory_operand" "")
453 (const_string "load")
454 (const_string "none"))
455 (eq_attr "type" "call")
456 (if_then_else (match_operand 0 "constant_call_address_operand" "")
457 (const_string "none")
458 (const_string "load"))
459 (eq_attr "type" "callv")
460 (if_then_else (match_operand 1 "constant_call_address_operand" "")
461 (const_string "none")
462 (const_string "load"))
463 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
464 (match_operand 1 "memory_operand" ""))
465 (const_string "both")
466 (and (match_operand 0 "memory_operand" "")
467 (match_operand 1 "memory_operand" ""))
468 (const_string "both")
469 (match_operand 0 "memory_operand" "")
470 (const_string "store")
471 (match_operand 1 "memory_operand" "")
472 (const_string "load")
474 "!alu1,negnot,ishift1,
475 imov,imovx,icmp,test,bitmanip,
477 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
478 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
479 (match_operand 2 "memory_operand" ""))
480 (const_string "load")
481 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
482 (match_operand 3 "memory_operand" ""))
483 (const_string "load")
485 (const_string "none")))
487 ;; Indicates if an instruction has both an immediate and a displacement.
489 (define_attr "imm_disp" "false,true,unknown"
490 (cond [(eq_attr "type" "other,multi")
491 (const_string "unknown")
492 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
493 (and (match_operand 0 "memory_displacement_operand" "")
494 (match_operand 1 "immediate_operand" "")))
495 (const_string "true")
496 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
497 (and (match_operand 0 "memory_displacement_operand" "")
498 (match_operand 2 "immediate_operand" "")))
499 (const_string "true")
501 (const_string "false")))
503 ;; Indicates if an FP operation has an integer source.
505 (define_attr "fp_int_src" "false,true"
506 (const_string "false"))
508 ;; Defines rounding mode of an FP operation.
510 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
511 (const_string "any"))
513 ;; Describe a user's asm statement.
514 (define_asm_attributes
515 [(set_attr "length" "128")
516 (set_attr "type" "multi")])
518 ;; All integer comparison codes.
519 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
521 ;; All floating-point comparison codes.
522 (define_code_iterator fp_cond [unordered ordered
523 uneq unge ungt unle unlt ltgt ])
525 (define_code_iterator plusminus [plus minus])
527 ;; Base name for define_insn and insn mnemonic.
528 (define_code_attr addsub [(plus "add") (minus "sub")])
530 ;; Mark commutative operators as such in constraints.
531 (define_code_attr comm [(plus "%") (minus "")])
533 ;; Mapping of signed max and min
534 (define_code_iterator smaxmin [smax smin])
536 ;; Mapping of unsigned max and min
537 (define_code_iterator umaxmin [umax umin])
539 ;; Base name for integer and FP insn mnemonic
540 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins") (umax "maxu") (umin "minu")])
541 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
543 ;; All single word integer modes.
544 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
546 ;; Instruction suffix for integer modes.
547 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
549 ;; Register class for integer modes.
550 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
552 ;; Immediate operand constraint for integer modes.
553 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
555 ;; General operand predicate for integer modes.
556 (define_mode_attr general_operand
557 [(QI "general_operand")
558 (HI "general_operand")
559 (SI "general_operand")
560 (DI "x86_64_general_operand")])
562 ;; SSE and x87 SFmode and DFmode floating point modes
563 (define_mode_iterator MODEF [SF DF])
565 ;; All x87 floating point modes
566 (define_mode_iterator X87MODEF [SF DF XF])
568 ;; All integer modes handled by x87 fisttp operator.
569 (define_mode_iterator X87MODEI [HI SI DI])
571 ;; All integer modes handled by integer x87 operators.
572 (define_mode_iterator X87MODEI12 [HI SI])
574 ;; All integer modes handled by SSE cvtts?2si* operators.
575 (define_mode_iterator SSEMODEI24 [SI DI])
577 ;; SSE asm suffix for floating point modes
578 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
580 ;; SSE vector mode corresponding to a scalar mode
581 (define_mode_attr ssevecmode
582 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
584 ;; Instruction suffix for REX 64bit operators.
585 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
587 ;; Scheduling descriptions
589 (include "pentium.md")
592 (include "athlon.md")
596 ;; Operand and operator predicates and constraints
598 (include "predicates.md")
599 (include "constraints.md")
602 ;; Compare instructions.
604 ;; All compare insns have expanders that save the operands away without
605 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
606 ;; after the cmp) will actually emit the cmpM.
608 (define_expand "cmpti"
609 [(set (reg:CC FLAGS_REG)
610 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
611 (match_operand:TI 1 "x86_64_general_operand" "")))]
614 if (MEM_P (operands[0]) && MEM_P (operands[1]))
615 operands[0] = force_reg (TImode, operands[0]);
616 ix86_compare_op0 = operands[0];
617 ix86_compare_op1 = operands[1];
621 (define_expand "cmpdi"
622 [(set (reg:CC FLAGS_REG)
623 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
624 (match_operand:DI 1 "x86_64_general_operand" "")))]
627 if (MEM_P (operands[0]) && MEM_P (operands[1]))
628 operands[0] = force_reg (DImode, operands[0]);
629 ix86_compare_op0 = operands[0];
630 ix86_compare_op1 = operands[1];
634 (define_expand "cmpsi"
635 [(set (reg:CC FLAGS_REG)
636 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
637 (match_operand:SI 1 "general_operand" "")))]
640 if (MEM_P (operands[0]) && MEM_P (operands[1]))
641 operands[0] = force_reg (SImode, operands[0]);
642 ix86_compare_op0 = operands[0];
643 ix86_compare_op1 = operands[1];
647 (define_expand "cmphi"
648 [(set (reg:CC FLAGS_REG)
649 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
650 (match_operand:HI 1 "general_operand" "")))]
653 if (MEM_P (operands[0]) && MEM_P (operands[1]))
654 operands[0] = force_reg (HImode, operands[0]);
655 ix86_compare_op0 = operands[0];
656 ix86_compare_op1 = operands[1];
660 (define_expand "cmpqi"
661 [(set (reg:CC FLAGS_REG)
662 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
663 (match_operand:QI 1 "general_operand" "")))]
666 if (MEM_P (operands[0]) && MEM_P (operands[1]))
667 operands[0] = force_reg (QImode, operands[0]);
668 ix86_compare_op0 = operands[0];
669 ix86_compare_op1 = operands[1];
673 (define_insn "cmpdi_ccno_1_rex64"
674 [(set (reg FLAGS_REG)
675 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
676 (match_operand:DI 1 "const0_operand" "n,n")))]
677 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
680 cmp{q}\t{%1, %0|%0, %1}"
681 [(set_attr "type" "test,icmp")
682 (set_attr "length_immediate" "0,1")
683 (set_attr "mode" "DI")])
685 (define_insn "*cmpdi_minus_1_rex64"
686 [(set (reg FLAGS_REG)
687 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
688 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
690 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
691 "cmp{q}\t{%1, %0|%0, %1}"
692 [(set_attr "type" "icmp")
693 (set_attr "mode" "DI")])
695 (define_expand "cmpdi_1_rex64"
696 [(set (reg:CC FLAGS_REG)
697 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
698 (match_operand:DI 1 "general_operand" "")))]
702 (define_insn "cmpdi_1_insn_rex64"
703 [(set (reg FLAGS_REG)
704 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
705 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
706 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
707 "cmp{q}\t{%1, %0|%0, %1}"
708 [(set_attr "type" "icmp")
709 (set_attr "mode" "DI")])
712 (define_insn "*cmpsi_ccno_1"
713 [(set (reg FLAGS_REG)
714 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
715 (match_operand:SI 1 "const0_operand" "n,n")))]
716 "ix86_match_ccmode (insn, CCNOmode)"
719 cmp{l}\t{%1, %0|%0, %1}"
720 [(set_attr "type" "test,icmp")
721 (set_attr "length_immediate" "0,1")
722 (set_attr "mode" "SI")])
724 (define_insn "*cmpsi_minus_1"
725 [(set (reg FLAGS_REG)
726 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
727 (match_operand:SI 1 "general_operand" "ri,mr"))
729 "ix86_match_ccmode (insn, CCGOCmode)"
730 "cmp{l}\t{%1, %0|%0, %1}"
731 [(set_attr "type" "icmp")
732 (set_attr "mode" "SI")])
734 (define_expand "cmpsi_1"
735 [(set (reg:CC FLAGS_REG)
736 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
737 (match_operand:SI 1 "general_operand" "")))]
741 (define_insn "*cmpsi_1_insn"
742 [(set (reg FLAGS_REG)
743 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
744 (match_operand:SI 1 "general_operand" "ri,mr")))]
745 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
746 && ix86_match_ccmode (insn, CCmode)"
747 "cmp{l}\t{%1, %0|%0, %1}"
748 [(set_attr "type" "icmp")
749 (set_attr "mode" "SI")])
751 (define_insn "*cmphi_ccno_1"
752 [(set (reg FLAGS_REG)
753 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
754 (match_operand:HI 1 "const0_operand" "n,n")))]
755 "ix86_match_ccmode (insn, CCNOmode)"
758 cmp{w}\t{%1, %0|%0, %1}"
759 [(set_attr "type" "test,icmp")
760 (set_attr "length_immediate" "0,1")
761 (set_attr "mode" "HI")])
763 (define_insn "*cmphi_minus_1"
764 [(set (reg FLAGS_REG)
765 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
766 (match_operand:HI 1 "general_operand" "ri,mr"))
768 "ix86_match_ccmode (insn, CCGOCmode)"
769 "cmp{w}\t{%1, %0|%0, %1}"
770 [(set_attr "type" "icmp")
771 (set_attr "mode" "HI")])
773 (define_insn "*cmphi_1"
774 [(set (reg FLAGS_REG)
775 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
776 (match_operand:HI 1 "general_operand" "ri,mr")))]
777 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
778 && ix86_match_ccmode (insn, CCmode)"
779 "cmp{w}\t{%1, %0|%0, %1}"
780 [(set_attr "type" "icmp")
781 (set_attr "mode" "HI")])
783 (define_insn "*cmpqi_ccno_1"
784 [(set (reg FLAGS_REG)
785 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
786 (match_operand:QI 1 "const0_operand" "n,n")))]
787 "ix86_match_ccmode (insn, CCNOmode)"
790 cmp{b}\t{$0, %0|%0, 0}"
791 [(set_attr "type" "test,icmp")
792 (set_attr "length_immediate" "0,1")
793 (set_attr "mode" "QI")])
795 (define_insn "*cmpqi_1"
796 [(set (reg FLAGS_REG)
797 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
798 (match_operand:QI 1 "general_operand" "qi,mq")))]
799 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
800 && ix86_match_ccmode (insn, CCmode)"
801 "cmp{b}\t{%1, %0|%0, %1}"
802 [(set_attr "type" "icmp")
803 (set_attr "mode" "QI")])
805 (define_insn "*cmpqi_minus_1"
806 [(set (reg FLAGS_REG)
807 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
808 (match_operand:QI 1 "general_operand" "qi,mq"))
810 "ix86_match_ccmode (insn, CCGOCmode)"
811 "cmp{b}\t{%1, %0|%0, %1}"
812 [(set_attr "type" "icmp")
813 (set_attr "mode" "QI")])
815 (define_insn "*cmpqi_ext_1"
816 [(set (reg FLAGS_REG)
818 (match_operand:QI 0 "general_operand" "Qm")
821 (match_operand 1 "ext_register_operand" "Q")
824 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
825 "cmp{b}\t{%h1, %0|%0, %h1}"
826 [(set_attr "type" "icmp")
827 (set_attr "mode" "QI")])
829 (define_insn "*cmpqi_ext_1_rex64"
830 [(set (reg FLAGS_REG)
832 (match_operand:QI 0 "register_operand" "Q")
835 (match_operand 1 "ext_register_operand" "Q")
838 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
839 "cmp{b}\t{%h1, %0|%0, %h1}"
840 [(set_attr "type" "icmp")
841 (set_attr "mode" "QI")])
843 (define_insn "*cmpqi_ext_2"
844 [(set (reg FLAGS_REG)
848 (match_operand 0 "ext_register_operand" "Q")
851 (match_operand:QI 1 "const0_operand" "n")))]
852 "ix86_match_ccmode (insn, CCNOmode)"
854 [(set_attr "type" "test")
855 (set_attr "length_immediate" "0")
856 (set_attr "mode" "QI")])
858 (define_expand "cmpqi_ext_3"
859 [(set (reg:CC FLAGS_REG)
863 (match_operand 0 "ext_register_operand" "")
866 (match_operand:QI 1 "general_operand" "")))]
870 (define_insn "cmpqi_ext_3_insn"
871 [(set (reg FLAGS_REG)
875 (match_operand 0 "ext_register_operand" "Q")
878 (match_operand:QI 1 "general_operand" "Qmn")))]
879 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
880 "cmp{b}\t{%1, %h0|%h0, %1}"
881 [(set_attr "type" "icmp")
882 (set_attr "mode" "QI")])
884 (define_insn "cmpqi_ext_3_insn_rex64"
885 [(set (reg FLAGS_REG)
889 (match_operand 0 "ext_register_operand" "Q")
892 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
893 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
894 "cmp{b}\t{%1, %h0|%h0, %1}"
895 [(set_attr "type" "icmp")
896 (set_attr "mode" "QI")])
898 (define_insn "*cmpqi_ext_4"
899 [(set (reg FLAGS_REG)
903 (match_operand 0 "ext_register_operand" "Q")
908 (match_operand 1 "ext_register_operand" "Q")
911 "ix86_match_ccmode (insn, CCmode)"
912 "cmp{b}\t{%h1, %h0|%h0, %h1}"
913 [(set_attr "type" "icmp")
914 (set_attr "mode" "QI")])
916 ;; These implement float point compares.
917 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
918 ;; which would allow mix and match FP modes on the compares. Which is what
919 ;; the old patterns did, but with many more of them.
921 (define_expand "cmpxf"
922 [(set (reg:CC FLAGS_REG)
923 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
924 (match_operand:XF 1 "nonmemory_operand" "")))]
927 ix86_compare_op0 = operands[0];
928 ix86_compare_op1 = operands[1];
932 (define_expand "cmp<mode>"
933 [(set (reg:CC FLAGS_REG)
934 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
935 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
936 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
938 ix86_compare_op0 = operands[0];
939 ix86_compare_op1 = operands[1];
943 ;; FP compares, step 1:
944 ;; Set the FP condition codes.
946 ;; CCFPmode compare with exceptions
947 ;; CCFPUmode compare with no exceptions
949 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
950 ;; used to manage the reg stack popping would not be preserved.
952 (define_insn "*cmpfp_0"
953 [(set (match_operand:HI 0 "register_operand" "=a")
956 (match_operand 1 "register_operand" "f")
957 (match_operand 2 "const0_operand" "X"))]
959 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
960 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
961 "* return output_fp_compare (insn, operands, 0, 0);"
962 [(set_attr "type" "multi")
963 (set_attr "unit" "i387")
965 (cond [(match_operand:SF 1 "" "")
967 (match_operand:DF 1 "" "")
970 (const_string "XF")))])
972 (define_insn_and_split "*cmpfp_0_cc"
973 [(set (reg:CCFP FLAGS_REG)
975 (match_operand 1 "register_operand" "f")
976 (match_operand 2 "const0_operand" "X")))
977 (clobber (match_operand:HI 0 "register_operand" "=a"))]
978 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
979 && TARGET_SAHF && !TARGET_CMOVE
980 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
982 "&& reload_completed"
985 [(compare:CCFP (match_dup 1)(match_dup 2))]
987 (set (reg:CC FLAGS_REG)
988 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
990 [(set_attr "type" "multi")
991 (set_attr "unit" "i387")
993 (cond [(match_operand:SF 1 "" "")
995 (match_operand:DF 1 "" "")
998 (const_string "XF")))])
1000 (define_insn "*cmpfp_xf"
1001 [(set (match_operand:HI 0 "register_operand" "=a")
1004 (match_operand:XF 1 "register_operand" "f")
1005 (match_operand:XF 2 "register_operand" "f"))]
1008 "* return output_fp_compare (insn, operands, 0, 0);"
1009 [(set_attr "type" "multi")
1010 (set_attr "unit" "i387")
1011 (set_attr "mode" "XF")])
1013 (define_insn_and_split "*cmpfp_xf_cc"
1014 [(set (reg:CCFP FLAGS_REG)
1016 (match_operand:XF 1 "register_operand" "f")
1017 (match_operand:XF 2 "register_operand" "f")))
1018 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1020 && TARGET_SAHF && !TARGET_CMOVE"
1022 "&& reload_completed"
1025 [(compare:CCFP (match_dup 1)(match_dup 2))]
1027 (set (reg:CC FLAGS_REG)
1028 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1030 [(set_attr "type" "multi")
1031 (set_attr "unit" "i387")
1032 (set_attr "mode" "XF")])
1034 (define_insn "*cmpfp_<mode>"
1035 [(set (match_operand:HI 0 "register_operand" "=a")
1038 (match_operand:MODEF 1 "register_operand" "f")
1039 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1042 "* return output_fp_compare (insn, operands, 0, 0);"
1043 [(set_attr "type" "multi")
1044 (set_attr "unit" "i387")
1045 (set_attr "mode" "<MODE>")])
1047 (define_insn_and_split "*cmpfp_<mode>_cc"
1048 [(set (reg:CCFP FLAGS_REG)
1050 (match_operand:MODEF 1 "register_operand" "f")
1051 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1052 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1054 && TARGET_SAHF && !TARGET_CMOVE"
1056 "&& reload_completed"
1059 [(compare:CCFP (match_dup 1)(match_dup 2))]
1061 (set (reg:CC FLAGS_REG)
1062 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1064 [(set_attr "type" "multi")
1065 (set_attr "unit" "i387")
1066 (set_attr "mode" "<MODE>")])
1068 (define_insn "*cmpfp_u"
1069 [(set (match_operand:HI 0 "register_operand" "=a")
1072 (match_operand 1 "register_operand" "f")
1073 (match_operand 2 "register_operand" "f"))]
1075 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1077 "* return output_fp_compare (insn, operands, 0, 1);"
1078 [(set_attr "type" "multi")
1079 (set_attr "unit" "i387")
1081 (cond [(match_operand:SF 1 "" "")
1083 (match_operand:DF 1 "" "")
1086 (const_string "XF")))])
1088 (define_insn_and_split "*cmpfp_u_cc"
1089 [(set (reg:CCFPU FLAGS_REG)
1091 (match_operand 1 "register_operand" "f")
1092 (match_operand 2 "register_operand" "f")))
1093 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1094 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1095 && TARGET_SAHF && !TARGET_CMOVE
1096 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1098 "&& reload_completed"
1101 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1103 (set (reg:CC FLAGS_REG)
1104 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1106 [(set_attr "type" "multi")
1107 (set_attr "unit" "i387")
1109 (cond [(match_operand:SF 1 "" "")
1111 (match_operand:DF 1 "" "")
1114 (const_string "XF")))])
1116 (define_insn "*cmpfp_<mode>"
1117 [(set (match_operand:HI 0 "register_operand" "=a")
1120 (match_operand 1 "register_operand" "f")
1121 (match_operator 3 "float_operator"
1122 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1124 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1125 && TARGET_USE_<MODE>MODE_FIOP
1126 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1127 "* return output_fp_compare (insn, operands, 0, 0);"
1128 [(set_attr "type" "multi")
1129 (set_attr "unit" "i387")
1130 (set_attr "fp_int_src" "true")
1131 (set_attr "mode" "<MODE>")])
1133 (define_insn_and_split "*cmpfp_<mode>_cc"
1134 [(set (reg:CCFP FLAGS_REG)
1136 (match_operand 1 "register_operand" "f")
1137 (match_operator 3 "float_operator"
1138 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1139 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1140 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1141 && TARGET_SAHF && !TARGET_CMOVE
1142 && TARGET_USE_<MODE>MODE_FIOP
1143 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1145 "&& reload_completed"
1150 (match_op_dup 3 [(match_dup 2)]))]
1152 (set (reg:CC FLAGS_REG)
1153 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1155 [(set_attr "type" "multi")
1156 (set_attr "unit" "i387")
1157 (set_attr "fp_int_src" "true")
1158 (set_attr "mode" "<MODE>")])
1160 ;; FP compares, step 2
1161 ;; Move the fpsw to ax.
1163 (define_insn "x86_fnstsw_1"
1164 [(set (match_operand:HI 0 "register_operand" "=a")
1165 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1168 [(set_attr "length" "2")
1169 (set_attr "mode" "SI")
1170 (set_attr "unit" "i387")])
1172 ;; FP compares, step 3
1173 ;; Get ax into flags, general case.
1175 (define_insn "x86_sahf_1"
1176 [(set (reg:CC FLAGS_REG)
1177 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1181 #ifdef HAVE_AS_IX86_SAHF
1184 return ".byte\t0x9e";
1187 [(set_attr "length" "1")
1188 (set_attr "athlon_decode" "vector")
1189 (set_attr "amdfam10_decode" "direct")
1190 (set_attr "mode" "SI")])
1192 ;; Pentium Pro can do steps 1 through 3 in one go.
1193 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1194 (define_insn "*cmpfp_i_mixed"
1195 [(set (reg:CCFP FLAGS_REG)
1196 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1197 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1198 "TARGET_MIX_SSE_I387
1199 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1200 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1201 "* return output_fp_compare (insn, operands, 1, 0);"
1202 [(set_attr "type" "fcmp,ssecomi")
1204 (if_then_else (match_operand:SF 1 "" "")
1206 (const_string "DF")))
1207 (set_attr "athlon_decode" "vector")
1208 (set_attr "amdfam10_decode" "direct")])
1210 (define_insn "*cmpfp_i_sse"
1211 [(set (reg:CCFP FLAGS_REG)
1212 (compare:CCFP (match_operand 0 "register_operand" "x")
1213 (match_operand 1 "nonimmediate_operand" "xm")))]
1215 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1216 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1217 "* return output_fp_compare (insn, operands, 1, 0);"
1218 [(set_attr "type" "ssecomi")
1220 (if_then_else (match_operand:SF 1 "" "")
1222 (const_string "DF")))
1223 (set_attr "athlon_decode" "vector")
1224 (set_attr "amdfam10_decode" "direct")])
1226 (define_insn "*cmpfp_i_i387"
1227 [(set (reg:CCFP FLAGS_REG)
1228 (compare:CCFP (match_operand 0 "register_operand" "f")
1229 (match_operand 1 "register_operand" "f")))]
1230 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1232 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1233 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1234 "* return output_fp_compare (insn, operands, 1, 0);"
1235 [(set_attr "type" "fcmp")
1237 (cond [(match_operand:SF 1 "" "")
1239 (match_operand:DF 1 "" "")
1242 (const_string "XF")))
1243 (set_attr "athlon_decode" "vector")
1244 (set_attr "amdfam10_decode" "direct")])
1246 (define_insn "*cmpfp_iu_mixed"
1247 [(set (reg:CCFPU FLAGS_REG)
1248 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1249 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1250 "TARGET_MIX_SSE_I387
1251 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1252 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1253 "* return output_fp_compare (insn, operands, 1, 1);"
1254 [(set_attr "type" "fcmp,ssecomi")
1256 (if_then_else (match_operand:SF 1 "" "")
1258 (const_string "DF")))
1259 (set_attr "athlon_decode" "vector")
1260 (set_attr "amdfam10_decode" "direct")])
1262 (define_insn "*cmpfp_iu_sse"
1263 [(set (reg:CCFPU FLAGS_REG)
1264 (compare:CCFPU (match_operand 0 "register_operand" "x")
1265 (match_operand 1 "nonimmediate_operand" "xm")))]
1267 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1268 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1269 "* return output_fp_compare (insn, operands, 1, 1);"
1270 [(set_attr "type" "ssecomi")
1272 (if_then_else (match_operand:SF 1 "" "")
1274 (const_string "DF")))
1275 (set_attr "athlon_decode" "vector")
1276 (set_attr "amdfam10_decode" "direct")])
1278 (define_insn "*cmpfp_iu_387"
1279 [(set (reg:CCFPU FLAGS_REG)
1280 (compare:CCFPU (match_operand 0 "register_operand" "f")
1281 (match_operand 1 "register_operand" "f")))]
1282 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1284 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1285 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1286 "* return output_fp_compare (insn, operands, 1, 1);"
1287 [(set_attr "type" "fcmp")
1289 (cond [(match_operand:SF 1 "" "")
1291 (match_operand:DF 1 "" "")
1294 (const_string "XF")))
1295 (set_attr "athlon_decode" "vector")
1296 (set_attr "amdfam10_decode" "direct")])
1298 ;; Move instructions.
1300 ;; General case of fullword move.
1302 (define_expand "movsi"
1303 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1304 (match_operand:SI 1 "general_operand" ""))]
1306 "ix86_expand_move (SImode, operands); DONE;")
1308 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1311 ;; %%% We don't use a post-inc memory reference because x86 is not a
1312 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1313 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1314 ;; targets without our curiosities, and it is just as easy to represent
1315 ;; this differently.
1317 (define_insn "*pushsi2"
1318 [(set (match_operand:SI 0 "push_operand" "=<")
1319 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1322 [(set_attr "type" "push")
1323 (set_attr "mode" "SI")])
1325 ;; For 64BIT abi we always round up to 8 bytes.
1326 (define_insn "*pushsi2_rex64"
1327 [(set (match_operand:SI 0 "push_operand" "=X")
1328 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1331 [(set_attr "type" "push")
1332 (set_attr "mode" "SI")])
1334 (define_insn "*pushsi2_prologue"
1335 [(set (match_operand:SI 0 "push_operand" "=<")
1336 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1337 (clobber (mem:BLK (scratch)))]
1340 [(set_attr "type" "push")
1341 (set_attr "mode" "SI")])
1343 (define_insn "*popsi1_epilogue"
1344 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1345 (mem:SI (reg:SI SP_REG)))
1346 (set (reg:SI SP_REG)
1347 (plus:SI (reg:SI SP_REG) (const_int 4)))
1348 (clobber (mem:BLK (scratch)))]
1351 [(set_attr "type" "pop")
1352 (set_attr "mode" "SI")])
1354 (define_insn "popsi1"
1355 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1356 (mem:SI (reg:SI SP_REG)))
1357 (set (reg:SI SP_REG)
1358 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1361 [(set_attr "type" "pop")
1362 (set_attr "mode" "SI")])
1364 (define_insn "*movsi_xor"
1365 [(set (match_operand:SI 0 "register_operand" "=r")
1366 (match_operand:SI 1 "const0_operand" "i"))
1367 (clobber (reg:CC FLAGS_REG))]
1368 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1370 [(set_attr "type" "alu1")
1371 (set_attr "mode" "SI")
1372 (set_attr "length_immediate" "0")])
1374 (define_insn "*movsi_or"
1375 [(set (match_operand:SI 0 "register_operand" "=r")
1376 (match_operand:SI 1 "immediate_operand" "i"))
1377 (clobber (reg:CC FLAGS_REG))]
1379 && operands[1] == constm1_rtx
1380 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1382 operands[1] = constm1_rtx;
1383 return "or{l}\t{%1, %0|%0, %1}";
1385 [(set_attr "type" "alu1")
1386 (set_attr "mode" "SI")
1387 (set_attr "length_immediate" "1")])
1389 (define_insn "*movsi_1"
1390 [(set (match_operand:SI 0 "nonimmediate_operand"
1391 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1392 (match_operand:SI 1 "general_operand"
1393 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1394 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1396 switch (get_attr_type (insn))
1399 if (get_attr_mode (insn) == MODE_TI)
1400 return "pxor\t%0, %0";
1401 return "xorps\t%0, %0";
1404 switch (get_attr_mode (insn))
1407 return "movdqa\t{%1, %0|%0, %1}";
1409 return "movaps\t{%1, %0|%0, %1}";
1411 return "movd\t{%1, %0|%0, %1}";
1413 return "movss\t{%1, %0|%0, %1}";
1419 return "pxor\t%0, %0";
1422 if (get_attr_mode (insn) == MODE_DI)
1423 return "movq\t{%1, %0|%0, %1}";
1424 return "movd\t{%1, %0|%0, %1}";
1427 return "lea{l}\t{%1, %0|%0, %1}";
1430 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1431 return "mov{l}\t{%1, %0|%0, %1}";
1435 (cond [(eq_attr "alternative" "2")
1436 (const_string "mmxadd")
1437 (eq_attr "alternative" "3,4,5")
1438 (const_string "mmxmov")
1439 (eq_attr "alternative" "6")
1440 (const_string "sselog1")
1441 (eq_attr "alternative" "7,8,9,10,11")
1442 (const_string "ssemov")
1443 (match_operand:DI 1 "pic_32bit_operand" "")
1444 (const_string "lea")
1446 (const_string "imov")))
1448 (cond [(eq_attr "alternative" "2,3")
1450 (eq_attr "alternative" "6,7")
1452 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1453 (const_string "V4SF")
1454 (const_string "TI"))
1455 (and (eq_attr "alternative" "8,9,10,11")
1456 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1459 (const_string "SI")))])
1461 ;; Stores and loads of ax to arbitrary constant address.
1462 ;; We fake an second form of instruction to force reload to load address
1463 ;; into register when rax is not available
1464 (define_insn "*movabssi_1_rex64"
1465 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1466 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1467 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1469 movabs{l}\t{%1, %P0|%P0, %1}
1470 mov{l}\t{%1, %a0|%a0, %1}"
1471 [(set_attr "type" "imov")
1472 (set_attr "modrm" "0,*")
1473 (set_attr "length_address" "8,0")
1474 (set_attr "length_immediate" "0,*")
1475 (set_attr "memory" "store")
1476 (set_attr "mode" "SI")])
1478 (define_insn "*movabssi_2_rex64"
1479 [(set (match_operand:SI 0 "register_operand" "=a,r")
1480 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1481 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1483 movabs{l}\t{%P1, %0|%0, %P1}
1484 mov{l}\t{%a1, %0|%0, %a1}"
1485 [(set_attr "type" "imov")
1486 (set_attr "modrm" "0,*")
1487 (set_attr "length_address" "8,0")
1488 (set_attr "length_immediate" "0")
1489 (set_attr "memory" "load")
1490 (set_attr "mode" "SI")])
1492 (define_insn "*swapsi"
1493 [(set (match_operand:SI 0 "register_operand" "+r")
1494 (match_operand:SI 1 "register_operand" "+r"))
1499 [(set_attr "type" "imov")
1500 (set_attr "mode" "SI")
1501 (set_attr "pent_pair" "np")
1502 (set_attr "athlon_decode" "vector")
1503 (set_attr "amdfam10_decode" "double")])
1505 (define_expand "movhi"
1506 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1507 (match_operand:HI 1 "general_operand" ""))]
1509 "ix86_expand_move (HImode, operands); DONE;")
1511 (define_insn "*pushhi2"
1512 [(set (match_operand:HI 0 "push_operand" "=X")
1513 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1516 [(set_attr "type" "push")
1517 (set_attr "mode" "SI")])
1519 ;; For 64BIT abi we always round up to 8 bytes.
1520 (define_insn "*pushhi2_rex64"
1521 [(set (match_operand:HI 0 "push_operand" "=X")
1522 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1525 [(set_attr "type" "push")
1526 (set_attr "mode" "DI")])
1528 (define_insn "*movhi_1"
1529 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1530 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1531 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1533 switch (get_attr_type (insn))
1536 /* movzwl is faster than movw on p2 due to partial word stalls,
1537 though not as fast as an aligned movl. */
1538 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1540 if (get_attr_mode (insn) == MODE_SI)
1541 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1543 return "mov{w}\t{%1, %0|%0, %1}";
1547 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1548 (const_string "imov")
1549 (and (eq_attr "alternative" "0")
1550 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1552 (eq (symbol_ref "TARGET_HIMODE_MATH")
1554 (const_string "imov")
1555 (and (eq_attr "alternative" "1,2")
1556 (match_operand:HI 1 "aligned_operand" ""))
1557 (const_string "imov")
1558 (and (ne (symbol_ref "TARGET_MOVX")
1560 (eq_attr "alternative" "0,2"))
1561 (const_string "imovx")
1563 (const_string "imov")))
1565 (cond [(eq_attr "type" "imovx")
1567 (and (eq_attr "alternative" "1,2")
1568 (match_operand:HI 1 "aligned_operand" ""))
1570 (and (eq_attr "alternative" "0")
1571 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1573 (eq (symbol_ref "TARGET_HIMODE_MATH")
1577 (const_string "HI")))])
1579 ;; Stores and loads of ax to arbitrary constant address.
1580 ;; We fake an second form of instruction to force reload to load address
1581 ;; into register when rax is not available
1582 (define_insn "*movabshi_1_rex64"
1583 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1584 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1585 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1587 movabs{w}\t{%1, %P0|%P0, %1}
1588 mov{w}\t{%1, %a0|%a0, %1}"
1589 [(set_attr "type" "imov")
1590 (set_attr "modrm" "0,*")
1591 (set_attr "length_address" "8,0")
1592 (set_attr "length_immediate" "0,*")
1593 (set_attr "memory" "store")
1594 (set_attr "mode" "HI")])
1596 (define_insn "*movabshi_2_rex64"
1597 [(set (match_operand:HI 0 "register_operand" "=a,r")
1598 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1599 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1601 movabs{w}\t{%P1, %0|%0, %P1}
1602 mov{w}\t{%a1, %0|%0, %a1}"
1603 [(set_attr "type" "imov")
1604 (set_attr "modrm" "0,*")
1605 (set_attr "length_address" "8,0")
1606 (set_attr "length_immediate" "0")
1607 (set_attr "memory" "load")
1608 (set_attr "mode" "HI")])
1610 (define_insn "*swaphi_1"
1611 [(set (match_operand:HI 0 "register_operand" "+r")
1612 (match_operand:HI 1 "register_operand" "+r"))
1615 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1617 [(set_attr "type" "imov")
1618 (set_attr "mode" "SI")
1619 (set_attr "pent_pair" "np")
1620 (set_attr "athlon_decode" "vector")
1621 (set_attr "amdfam10_decode" "double")])
1623 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1624 (define_insn "*swaphi_2"
1625 [(set (match_operand:HI 0 "register_operand" "+r")
1626 (match_operand:HI 1 "register_operand" "+r"))
1629 "TARGET_PARTIAL_REG_STALL"
1631 [(set_attr "type" "imov")
1632 (set_attr "mode" "HI")
1633 (set_attr "pent_pair" "np")
1634 (set_attr "athlon_decode" "vector")])
1636 (define_expand "movstricthi"
1637 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1638 (match_operand:HI 1 "general_operand" ""))]
1639 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1641 /* Don't generate memory->memory moves, go through a register */
1642 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1643 operands[1] = force_reg (HImode, operands[1]);
1646 (define_insn "*movstricthi_1"
1647 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1648 (match_operand:HI 1 "general_operand" "rn,m"))]
1649 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1650 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1651 "mov{w}\t{%1, %0|%0, %1}"
1652 [(set_attr "type" "imov")
1653 (set_attr "mode" "HI")])
1655 (define_insn "*movstricthi_xor"
1656 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1657 (match_operand:HI 1 "const0_operand" "i"))
1658 (clobber (reg:CC FLAGS_REG))]
1660 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1662 [(set_attr "type" "alu1")
1663 (set_attr "mode" "HI")
1664 (set_attr "length_immediate" "0")])
1666 (define_expand "movqi"
1667 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1668 (match_operand:QI 1 "general_operand" ""))]
1670 "ix86_expand_move (QImode, operands); DONE;")
1672 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1673 ;; "push a byte". But actually we use pushl, which has the effect
1674 ;; of rounding the amount pushed up to a word.
1676 (define_insn "*pushqi2"
1677 [(set (match_operand:QI 0 "push_operand" "=X")
1678 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1681 [(set_attr "type" "push")
1682 (set_attr "mode" "SI")])
1684 ;; For 64BIT abi we always round up to 8 bytes.
1685 (define_insn "*pushqi2_rex64"
1686 [(set (match_operand:QI 0 "push_operand" "=X")
1687 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1690 [(set_attr "type" "push")
1691 (set_attr "mode" "DI")])
1693 ;; Situation is quite tricky about when to choose full sized (SImode) move
1694 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1695 ;; partial register dependency machines (such as AMD Athlon), where QImode
1696 ;; moves issue extra dependency and for partial register stalls machines
1697 ;; that don't use QImode patterns (and QImode move cause stall on the next
1700 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1701 ;; register stall machines with, where we use QImode instructions, since
1702 ;; partial register stall can be caused there. Then we use movzx.
1703 (define_insn "*movqi_1"
1704 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1705 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1706 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1708 switch (get_attr_type (insn))
1711 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1712 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1714 if (get_attr_mode (insn) == MODE_SI)
1715 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1717 return "mov{b}\t{%1, %0|%0, %1}";
1721 (cond [(and (eq_attr "alternative" "5")
1722 (not (match_operand:QI 1 "aligned_operand" "")))
1723 (const_string "imovx")
1724 (ne (symbol_ref "optimize_size") (const_int 0))
1725 (const_string "imov")
1726 (and (eq_attr "alternative" "3")
1727 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1729 (eq (symbol_ref "TARGET_QIMODE_MATH")
1731 (const_string "imov")
1732 (eq_attr "alternative" "3,5")
1733 (const_string "imovx")
1734 (and (ne (symbol_ref "TARGET_MOVX")
1736 (eq_attr "alternative" "2"))
1737 (const_string "imovx")
1739 (const_string "imov")))
1741 (cond [(eq_attr "alternative" "3,4,5")
1743 (eq_attr "alternative" "6")
1745 (eq_attr "type" "imovx")
1747 (and (eq_attr "type" "imov")
1748 (and (eq_attr "alternative" "0,1")
1749 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1751 (and (eq (symbol_ref "optimize_size")
1753 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1756 ;; Avoid partial register stalls when not using QImode arithmetic
1757 (and (eq_attr "type" "imov")
1758 (and (eq_attr "alternative" "0,1")
1759 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1761 (eq (symbol_ref "TARGET_QIMODE_MATH")
1765 (const_string "QI")))])
1767 (define_expand "reload_outqi"
1768 [(parallel [(match_operand:QI 0 "" "=m")
1769 (match_operand:QI 1 "register_operand" "r")
1770 (match_operand:QI 2 "register_operand" "=&q")])]
1774 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1776 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1777 if (! q_regs_operand (op1, QImode))
1779 emit_insn (gen_movqi (op2, op1));
1782 emit_insn (gen_movqi (op0, op1));
1786 (define_insn "*swapqi_1"
1787 [(set (match_operand:QI 0 "register_operand" "+r")
1788 (match_operand:QI 1 "register_operand" "+r"))
1791 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1793 [(set_attr "type" "imov")
1794 (set_attr "mode" "SI")
1795 (set_attr "pent_pair" "np")
1796 (set_attr "athlon_decode" "vector")
1797 (set_attr "amdfam10_decode" "vector")])
1799 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1800 (define_insn "*swapqi_2"
1801 [(set (match_operand:QI 0 "register_operand" "+q")
1802 (match_operand:QI 1 "register_operand" "+q"))
1805 "TARGET_PARTIAL_REG_STALL"
1807 [(set_attr "type" "imov")
1808 (set_attr "mode" "QI")
1809 (set_attr "pent_pair" "np")
1810 (set_attr "athlon_decode" "vector")])
1812 (define_expand "movstrictqi"
1813 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1814 (match_operand:QI 1 "general_operand" ""))]
1815 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1817 /* Don't generate memory->memory moves, go through a register. */
1818 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1819 operands[1] = force_reg (QImode, operands[1]);
1822 (define_insn "*movstrictqi_1"
1823 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1824 (match_operand:QI 1 "general_operand" "*qn,m"))]
1825 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1826 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1827 "mov{b}\t{%1, %0|%0, %1}"
1828 [(set_attr "type" "imov")
1829 (set_attr "mode" "QI")])
1831 (define_insn "*movstrictqi_xor"
1832 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1833 (match_operand:QI 1 "const0_operand" "i"))
1834 (clobber (reg:CC FLAGS_REG))]
1835 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1837 [(set_attr "type" "alu1")
1838 (set_attr "mode" "QI")
1839 (set_attr "length_immediate" "0")])
1841 (define_insn "*movsi_extv_1"
1842 [(set (match_operand:SI 0 "register_operand" "=R")
1843 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1847 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1848 [(set_attr "type" "imovx")
1849 (set_attr "mode" "SI")])
1851 (define_insn "*movhi_extv_1"
1852 [(set (match_operand:HI 0 "register_operand" "=R")
1853 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1857 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1858 [(set_attr "type" "imovx")
1859 (set_attr "mode" "SI")])
1861 (define_insn "*movqi_extv_1"
1862 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1863 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1868 switch (get_attr_type (insn))
1871 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1873 return "mov{b}\t{%h1, %0|%0, %h1}";
1877 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1878 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1879 (ne (symbol_ref "TARGET_MOVX")
1881 (const_string "imovx")
1882 (const_string "imov")))
1884 (if_then_else (eq_attr "type" "imovx")
1886 (const_string "QI")))])
1888 (define_insn "*movqi_extv_1_rex64"
1889 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1890 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1895 switch (get_attr_type (insn))
1898 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1900 return "mov{b}\t{%h1, %0|%0, %h1}";
1904 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1905 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1906 (ne (symbol_ref "TARGET_MOVX")
1908 (const_string "imovx")
1909 (const_string "imov")))
1911 (if_then_else (eq_attr "type" "imovx")
1913 (const_string "QI")))])
1915 ;; Stores and loads of ax to arbitrary constant address.
1916 ;; We fake an second form of instruction to force reload to load address
1917 ;; into register when rax is not available
1918 (define_insn "*movabsqi_1_rex64"
1919 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1920 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1921 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1923 movabs{b}\t{%1, %P0|%P0, %1}
1924 mov{b}\t{%1, %a0|%a0, %1}"
1925 [(set_attr "type" "imov")
1926 (set_attr "modrm" "0,*")
1927 (set_attr "length_address" "8,0")
1928 (set_attr "length_immediate" "0,*")
1929 (set_attr "memory" "store")
1930 (set_attr "mode" "QI")])
1932 (define_insn "*movabsqi_2_rex64"
1933 [(set (match_operand:QI 0 "register_operand" "=a,r")
1934 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1935 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1937 movabs{b}\t{%P1, %0|%0, %P1}
1938 mov{b}\t{%a1, %0|%0, %a1}"
1939 [(set_attr "type" "imov")
1940 (set_attr "modrm" "0,*")
1941 (set_attr "length_address" "8,0")
1942 (set_attr "length_immediate" "0")
1943 (set_attr "memory" "load")
1944 (set_attr "mode" "QI")])
1946 (define_insn "*movdi_extzv_1"
1947 [(set (match_operand:DI 0 "register_operand" "=R")
1948 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1952 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1953 [(set_attr "type" "imovx")
1954 (set_attr "mode" "DI")])
1956 (define_insn "*movsi_extzv_1"
1957 [(set (match_operand:SI 0 "register_operand" "=R")
1958 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1962 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1963 [(set_attr "type" "imovx")
1964 (set_attr "mode" "SI")])
1966 (define_insn "*movqi_extzv_2"
1967 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1968 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1973 switch (get_attr_type (insn))
1976 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1978 return "mov{b}\t{%h1, %0|%0, %h1}";
1982 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1983 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1984 (ne (symbol_ref "TARGET_MOVX")
1986 (const_string "imovx")
1987 (const_string "imov")))
1989 (if_then_else (eq_attr "type" "imovx")
1991 (const_string "QI")))])
1993 (define_insn "*movqi_extzv_2_rex64"
1994 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1995 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2000 switch (get_attr_type (insn))
2003 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2005 return "mov{b}\t{%h1, %0|%0, %h1}";
2009 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2010 (ne (symbol_ref "TARGET_MOVX")
2012 (const_string "imovx")
2013 (const_string "imov")))
2015 (if_then_else (eq_attr "type" "imovx")
2017 (const_string "QI")))])
2019 (define_insn "movsi_insv_1"
2020 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2023 (match_operand:SI 1 "general_operand" "Qmn"))]
2025 "mov{b}\t{%b1, %h0|%h0, %b1}"
2026 [(set_attr "type" "imov")
2027 (set_attr "mode" "QI")])
2029 (define_insn "*movsi_insv_1_rex64"
2030 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2033 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2035 "mov{b}\t{%b1, %h0|%h0, %b1}"
2036 [(set_attr "type" "imov")
2037 (set_attr "mode" "QI")])
2039 (define_insn "movdi_insv_1_rex64"
2040 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2043 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2045 "mov{b}\t{%b1, %h0|%h0, %b1}"
2046 [(set_attr "type" "imov")
2047 (set_attr "mode" "QI")])
2049 (define_insn "*movqi_insv_2"
2050 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2053 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2056 "mov{b}\t{%h1, %h0|%h0, %h1}"
2057 [(set_attr "type" "imov")
2058 (set_attr "mode" "QI")])
2060 (define_expand "movdi"
2061 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2062 (match_operand:DI 1 "general_operand" ""))]
2064 "ix86_expand_move (DImode, operands); DONE;")
2066 (define_insn "*pushdi"
2067 [(set (match_operand:DI 0 "push_operand" "=<")
2068 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2072 (define_insn "*pushdi2_rex64"
2073 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2074 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2079 [(set_attr "type" "push,multi")
2080 (set_attr "mode" "DI")])
2082 ;; Convert impossible pushes of immediate to existing instructions.
2083 ;; First try to get scratch register and go through it. In case this
2084 ;; fails, push sign extended lower part first and then overwrite
2085 ;; upper part by 32bit move.
2087 [(match_scratch:DI 2 "r")
2088 (set (match_operand:DI 0 "push_operand" "")
2089 (match_operand:DI 1 "immediate_operand" ""))]
2090 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091 && !x86_64_immediate_operand (operands[1], DImode)"
2092 [(set (match_dup 2) (match_dup 1))
2093 (set (match_dup 0) (match_dup 2))]
2096 ;; We need to define this as both peepholer and splitter for case
2097 ;; peephole2 pass is not run.
2098 ;; "&& 1" is needed to keep it from matching the previous pattern.
2100 [(set (match_operand:DI 0 "push_operand" "")
2101 (match_operand:DI 1 "immediate_operand" ""))]
2102 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2103 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2104 [(set (match_dup 0) (match_dup 1))
2105 (set (match_dup 2) (match_dup 3))]
2106 "split_di (operands + 1, 1, operands + 2, operands + 3);
2107 operands[1] = gen_lowpart (DImode, operands[2]);
2108 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2113 [(set (match_operand:DI 0 "push_operand" "")
2114 (match_operand:DI 1 "immediate_operand" ""))]
2115 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2116 ? epilogue_completed : reload_completed)
2117 && !symbolic_operand (operands[1], DImode)
2118 && !x86_64_immediate_operand (operands[1], DImode)"
2119 [(set (match_dup 0) (match_dup 1))
2120 (set (match_dup 2) (match_dup 3))]
2121 "split_di (operands + 1, 1, operands + 2, operands + 3);
2122 operands[1] = gen_lowpart (DImode, operands[2]);
2123 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2127 (define_insn "*pushdi2_prologue_rex64"
2128 [(set (match_operand:DI 0 "push_operand" "=<")
2129 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2130 (clobber (mem:BLK (scratch)))]
2133 [(set_attr "type" "push")
2134 (set_attr "mode" "DI")])
2136 (define_insn "*popdi1_epilogue_rex64"
2137 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2138 (mem:DI (reg:DI SP_REG)))
2139 (set (reg:DI SP_REG)
2140 (plus:DI (reg:DI SP_REG) (const_int 8)))
2141 (clobber (mem:BLK (scratch)))]
2144 [(set_attr "type" "pop")
2145 (set_attr "mode" "DI")])
2147 (define_insn "popdi1"
2148 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2149 (mem:DI (reg:DI SP_REG)))
2150 (set (reg:DI SP_REG)
2151 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2154 [(set_attr "type" "pop")
2155 (set_attr "mode" "DI")])
2157 (define_insn "*movdi_xor_rex64"
2158 [(set (match_operand:DI 0 "register_operand" "=r")
2159 (match_operand:DI 1 "const0_operand" "i"))
2160 (clobber (reg:CC FLAGS_REG))]
2161 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2162 && reload_completed"
2164 [(set_attr "type" "alu1")
2165 (set_attr "mode" "SI")
2166 (set_attr "length_immediate" "0")])
2168 (define_insn "*movdi_or_rex64"
2169 [(set (match_operand:DI 0 "register_operand" "=r")
2170 (match_operand:DI 1 "const_int_operand" "i"))
2171 (clobber (reg:CC FLAGS_REG))]
2172 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2174 && operands[1] == constm1_rtx"
2176 operands[1] = constm1_rtx;
2177 return "or{q}\t{%1, %0|%0, %1}";
2179 [(set_attr "type" "alu1")
2180 (set_attr "mode" "DI")
2181 (set_attr "length_immediate" "1")])
2183 (define_insn "*movdi_2"
2184 [(set (match_operand:DI 0 "nonimmediate_operand"
2185 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2186 (match_operand:DI 1 "general_operand"
2187 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2188 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2193 movq\t{%1, %0|%0, %1}
2194 movq\t{%1, %0|%0, %1}
2196 movq\t{%1, %0|%0, %1}
2197 movdqa\t{%1, %0|%0, %1}
2198 movq\t{%1, %0|%0, %1}
2200 movlps\t{%1, %0|%0, %1}
2201 movaps\t{%1, %0|%0, %1}
2202 movlps\t{%1, %0|%0, %1}"
2203 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2204 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2207 [(set (match_operand:DI 0 "push_operand" "")
2208 (match_operand:DI 1 "general_operand" ""))]
2209 "!TARGET_64BIT && reload_completed
2210 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2212 "ix86_split_long_move (operands); DONE;")
2214 ;; %%% This multiword shite has got to go.
2216 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2217 (match_operand:DI 1 "general_operand" ""))]
2218 "!TARGET_64BIT && reload_completed
2219 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2220 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2222 "ix86_split_long_move (operands); DONE;")
2224 (define_insn "*movdi_1_rex64"
2225 [(set (match_operand:DI 0 "nonimmediate_operand"
2226 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2227 (match_operand:DI 1 "general_operand"
2228 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2229 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2231 switch (get_attr_type (insn))
2234 if (SSE_REG_P (operands[0]))
2235 return "movq2dq\t{%1, %0|%0, %1}";
2237 return "movdq2q\t{%1, %0|%0, %1}";
2240 if (get_attr_mode (insn) == MODE_TI)
2241 return "movdqa\t{%1, %0|%0, %1}";
2245 /* Moves from and into integer register is done using movd
2246 opcode with REX prefix. */
2247 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2248 return "movd\t{%1, %0|%0, %1}";
2249 return "movq\t{%1, %0|%0, %1}";
2253 return "pxor\t%0, %0";
2259 return "lea{q}\t{%a1, %0|%0, %a1}";
2262 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2263 if (get_attr_mode (insn) == MODE_SI)
2264 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2265 else if (which_alternative == 2)
2266 return "movabs{q}\t{%1, %0|%0, %1}";
2268 return "mov{q}\t{%1, %0|%0, %1}";
2272 (cond [(eq_attr "alternative" "5")
2273 (const_string "mmxadd")
2274 (eq_attr "alternative" "6,7,8,9,10")
2275 (const_string "mmxmov")
2276 (eq_attr "alternative" "11")
2277 (const_string "sselog1")
2278 (eq_attr "alternative" "12,13,14,15,16")
2279 (const_string "ssemov")
2280 (eq_attr "alternative" "17,18")
2281 (const_string "ssecvt")
2282 (eq_attr "alternative" "4")
2283 (const_string "multi")
2284 (match_operand:DI 1 "pic_32bit_operand" "")
2285 (const_string "lea")
2287 (const_string "imov")))
2288 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2289 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2290 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2292 ;; Stores and loads of ax to arbitrary constant address.
2293 ;; We fake an second form of instruction to force reload to load address
2294 ;; into register when rax is not available
2295 (define_insn "*movabsdi_1_rex64"
2296 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2297 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2298 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2300 movabs{q}\t{%1, %P0|%P0, %1}
2301 mov{q}\t{%1, %a0|%a0, %1}"
2302 [(set_attr "type" "imov")
2303 (set_attr "modrm" "0,*")
2304 (set_attr "length_address" "8,0")
2305 (set_attr "length_immediate" "0,*")
2306 (set_attr "memory" "store")
2307 (set_attr "mode" "DI")])
2309 (define_insn "*movabsdi_2_rex64"
2310 [(set (match_operand:DI 0 "register_operand" "=a,r")
2311 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2312 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2314 movabs{q}\t{%P1, %0|%0, %P1}
2315 mov{q}\t{%a1, %0|%0, %a1}"
2316 [(set_attr "type" "imov")
2317 (set_attr "modrm" "0,*")
2318 (set_attr "length_address" "8,0")
2319 (set_attr "length_immediate" "0")
2320 (set_attr "memory" "load")
2321 (set_attr "mode" "DI")])
2323 ;; Convert impossible stores of immediate to existing instructions.
2324 ;; First try to get scratch register and go through it. In case this
2325 ;; fails, move by 32bit parts.
2327 [(match_scratch:DI 2 "r")
2328 (set (match_operand:DI 0 "memory_operand" "")
2329 (match_operand:DI 1 "immediate_operand" ""))]
2330 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2331 && !x86_64_immediate_operand (operands[1], DImode)"
2332 [(set (match_dup 2) (match_dup 1))
2333 (set (match_dup 0) (match_dup 2))]
2336 ;; We need to define this as both peepholer and splitter for case
2337 ;; peephole2 pass is not run.
2338 ;; "&& 1" is needed to keep it from matching the previous pattern.
2340 [(set (match_operand:DI 0 "memory_operand" "")
2341 (match_operand:DI 1 "immediate_operand" ""))]
2342 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2343 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2344 [(set (match_dup 2) (match_dup 3))
2345 (set (match_dup 4) (match_dup 5))]
2346 "split_di (operands, 2, operands + 2, operands + 4);")
2349 [(set (match_operand:DI 0 "memory_operand" "")
2350 (match_operand:DI 1 "immediate_operand" ""))]
2351 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2352 ? epilogue_completed : reload_completed)
2353 && !symbolic_operand (operands[1], DImode)
2354 && !x86_64_immediate_operand (operands[1], DImode)"
2355 [(set (match_dup 2) (match_dup 3))
2356 (set (match_dup 4) (match_dup 5))]
2357 "split_di (operands, 2, operands + 2, operands + 4);")
2359 (define_insn "*swapdi_rex64"
2360 [(set (match_operand:DI 0 "register_operand" "+r")
2361 (match_operand:DI 1 "register_operand" "+r"))
2366 [(set_attr "type" "imov")
2367 (set_attr "mode" "DI")
2368 (set_attr "pent_pair" "np")
2369 (set_attr "athlon_decode" "vector")
2370 (set_attr "amdfam10_decode" "double")])
2372 (define_expand "movti"
2373 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2374 (match_operand:TI 1 "nonimmediate_operand" ""))]
2375 "TARGET_SSE || TARGET_64BIT"
2378 ix86_expand_move (TImode, operands);
2379 else if (push_operand (operands[0], TImode))
2380 ix86_expand_push (TImode, operands[1]);
2382 ix86_expand_vector_move (TImode, operands);
2386 (define_insn "*movti_internal"
2387 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2388 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2389 "TARGET_SSE && !TARGET_64BIT
2390 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2392 switch (which_alternative)
2395 if (get_attr_mode (insn) == MODE_V4SF)
2396 return "xorps\t%0, %0";
2398 return "pxor\t%0, %0";
2401 /* TDmode values are passed as TImode on the stack. Moving them
2402 to stack may result in unaligned memory access. */
2403 if (misaligned_operand (operands[0], TImode)
2404 || misaligned_operand (operands[1], TImode))
2406 if (get_attr_mode (insn) == MODE_V4SF)
2407 return "movups\t{%1, %0|%0, %1}";
2409 return "movdqu\t{%1, %0|%0, %1}";
2413 if (get_attr_mode (insn) == MODE_V4SF)
2414 return "movaps\t{%1, %0|%0, %1}";
2416 return "movdqa\t{%1, %0|%0, %1}";
2422 [(set_attr "type" "sselog1,ssemov,ssemov")
2424 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2425 (ne (symbol_ref "optimize_size") (const_int 0)))
2426 (const_string "V4SF")
2427 (and (eq_attr "alternative" "2")
2428 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2430 (const_string "V4SF")]
2431 (const_string "TI")))])
2433 (define_insn "*movti_rex64"
2434 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2435 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2439 switch (which_alternative)
2445 if (get_attr_mode (insn) == MODE_V4SF)
2446 return "xorps\t%0, %0";
2448 return "pxor\t%0, %0";
2451 /* TDmode values are passed as TImode on the stack. Moving them
2452 to stack may result in unaligned memory access. */
2453 if (misaligned_operand (operands[0], TImode)
2454 || misaligned_operand (operands[1], TImode))
2456 if (get_attr_mode (insn) == MODE_V4SF)
2457 return "movups\t{%1, %0|%0, %1}";
2459 return "movdqu\t{%1, %0|%0, %1}";
2463 if (get_attr_mode (insn) == MODE_V4SF)
2464 return "movaps\t{%1, %0|%0, %1}";
2466 return "movdqa\t{%1, %0|%0, %1}";
2472 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2474 (cond [(eq_attr "alternative" "2,3")
2476 (ne (symbol_ref "optimize_size")
2478 (const_string "V4SF")
2479 (const_string "TI"))
2480 (eq_attr "alternative" "4")
2482 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2484 (ne (symbol_ref "optimize_size")
2486 (const_string "V4SF")
2487 (const_string "TI"))]
2488 (const_string "DI")))])
2491 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2492 (match_operand:TI 1 "general_operand" ""))]
2493 "reload_completed && !SSE_REG_P (operands[0])
2494 && !SSE_REG_P (operands[1])"
2496 "ix86_split_long_move (operands); DONE;")
2498 ;; This expands to what emit_move_complex would generate if we didn't
2499 ;; have a movti pattern. Having this avoids problems with reload on
2500 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2501 ;; to have around all the time.
2502 (define_expand "movcdi"
2503 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2504 (match_operand:CDI 1 "general_operand" ""))]
2507 if (push_operand (operands[0], CDImode))
2508 emit_move_complex_push (CDImode, operands[0], operands[1]);
2510 emit_move_complex_parts (operands[0], operands[1]);
2514 (define_expand "movsf"
2515 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2516 (match_operand:SF 1 "general_operand" ""))]
2518 "ix86_expand_move (SFmode, operands); DONE;")
2520 (define_insn "*pushsf"
2521 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2522 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2525 /* Anything else should be already split before reg-stack. */
2526 gcc_assert (which_alternative == 1);
2527 return "push{l}\t%1";
2529 [(set_attr "type" "multi,push,multi")
2530 (set_attr "unit" "i387,*,*")
2531 (set_attr "mode" "SF,SI,SF")])
2533 (define_insn "*pushsf_rex64"
2534 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2535 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2538 /* Anything else should be already split before reg-stack. */
2539 gcc_assert (which_alternative == 1);
2540 return "push{q}\t%q1";
2542 [(set_attr "type" "multi,push,multi")
2543 (set_attr "unit" "i387,*,*")
2544 (set_attr "mode" "SF,DI,SF")])
2547 [(set (match_operand:SF 0 "push_operand" "")
2548 (match_operand:SF 1 "memory_operand" ""))]
2550 && MEM_P (operands[1])
2551 && (operands[2] = find_constant_src (insn))"
2556 ;; %%% Kill this when call knows how to work this out.
2558 [(set (match_operand:SF 0 "push_operand" "")
2559 (match_operand:SF 1 "any_fp_register_operand" ""))]
2561 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2562 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2565 [(set (match_operand:SF 0 "push_operand" "")
2566 (match_operand:SF 1 "any_fp_register_operand" ""))]
2568 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2569 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2571 (define_insn "*movsf_1"
2572 [(set (match_operand:SF 0 "nonimmediate_operand"
2573 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2574 (match_operand:SF 1 "general_operand"
2575 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2576 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2577 && (reload_in_progress || reload_completed
2578 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2579 || (!TARGET_SSE_MATH && optimize_size
2580 && standard_80387_constant_p (operands[1]))
2581 || GET_CODE (operands[1]) != CONST_DOUBLE
2582 || memory_operand (operands[0], SFmode))"
2584 switch (which_alternative)
2588 return output_387_reg_move (insn, operands);
2591 return standard_80387_constant_opcode (operands[1]);
2595 return "mov{l}\t{%1, %0|%0, %1}";
2597 if (get_attr_mode (insn) == MODE_TI)
2598 return "pxor\t%0, %0";
2600 return "xorps\t%0, %0";
2602 if (get_attr_mode (insn) == MODE_V4SF)
2603 return "movaps\t{%1, %0|%0, %1}";
2605 return "movss\t{%1, %0|%0, %1}";
2607 return "movss\t{%1, %0|%0, %1}";
2610 case 12: case 13: case 14: case 15:
2611 return "movd\t{%1, %0|%0, %1}";
2614 return "movq\t{%1, %0|%0, %1}";
2620 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2622 (cond [(eq_attr "alternative" "3,4,9,10")
2624 (eq_attr "alternative" "5")
2626 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2628 (ne (symbol_ref "TARGET_SSE2")
2630 (eq (symbol_ref "optimize_size")
2633 (const_string "V4SF"))
2634 /* For architectures resolving dependencies on
2635 whole SSE registers use APS move to break dependency
2636 chains, otherwise use short move to avoid extra work.
2638 Do the same for architectures resolving dependencies on
2639 the parts. While in DF mode it is better to always handle
2640 just register parts, the SF mode is different due to lack
2641 of instructions to load just part of the register. It is
2642 better to maintain the whole registers in single format
2643 to avoid problems on using packed logical operations. */
2644 (eq_attr "alternative" "6")
2646 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2648 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2650 (const_string "V4SF")
2651 (const_string "SF"))
2652 (eq_attr "alternative" "11")
2653 (const_string "DI")]
2654 (const_string "SF")))])
2656 (define_insn "*swapsf"
2657 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2658 (match_operand:SF 1 "fp_register_operand" "+f"))
2661 "reload_completed || TARGET_80387"
2663 if (STACK_TOP_P (operands[0]))
2668 [(set_attr "type" "fxch")
2669 (set_attr "mode" "SF")])
2671 (define_expand "movdf"
2672 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2673 (match_operand:DF 1 "general_operand" ""))]
2675 "ix86_expand_move (DFmode, operands); DONE;")
2677 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2678 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2679 ;; On the average, pushdf using integers can be still shorter. Allow this
2680 ;; pattern for optimize_size too.
2682 (define_insn "*pushdf_nointeger"
2683 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2684 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2685 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2687 /* This insn should be already split before reg-stack. */
2690 [(set_attr "type" "multi")
2691 (set_attr "unit" "i387,*,*,*")
2692 (set_attr "mode" "DF,SI,SI,DF")])
2694 (define_insn "*pushdf_integer"
2695 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2696 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2697 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2699 /* This insn should be already split before reg-stack. */
2702 [(set_attr "type" "multi")
2703 (set_attr "unit" "i387,*,*")
2704 (set_attr "mode" "DF,SI,DF")])
2706 ;; %%% Kill this when call knows how to work this out.
2708 [(set (match_operand:DF 0 "push_operand" "")
2709 (match_operand:DF 1 "any_fp_register_operand" ""))]
2710 "!TARGET_64BIT && reload_completed"
2711 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2712 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2716 [(set (match_operand:DF 0 "push_operand" "")
2717 (match_operand:DF 1 "any_fp_register_operand" ""))]
2718 "TARGET_64BIT && reload_completed"
2719 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2720 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2724 [(set (match_operand:DF 0 "push_operand" "")
2725 (match_operand:DF 1 "general_operand" ""))]
2728 "ix86_split_long_move (operands); DONE;")
2730 ;; Moving is usually shorter when only FP registers are used. This separate
2731 ;; movdf pattern avoids the use of integer registers for FP operations
2732 ;; when optimizing for size.
2734 (define_insn "*movdf_nointeger"
2735 [(set (match_operand:DF 0 "nonimmediate_operand"
2736 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2737 (match_operand:DF 1 "general_operand"
2738 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2739 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2740 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2741 && (reload_in_progress || reload_completed
2742 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2743 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2744 && !memory_operand (operands[0], DFmode)
2745 && standard_80387_constant_p (operands[1]))
2746 || GET_CODE (operands[1]) != CONST_DOUBLE
2748 || !TARGET_MEMORY_MISMATCH_STALL
2749 || reload_in_progress || reload_completed)
2750 && memory_operand (operands[0], DFmode)))"
2752 switch (which_alternative)
2756 return output_387_reg_move (insn, operands);
2759 return standard_80387_constant_opcode (operands[1]);
2765 switch (get_attr_mode (insn))
2768 return "xorps\t%0, %0";
2770 return "xorpd\t%0, %0";
2772 return "pxor\t%0, %0";
2779 switch (get_attr_mode (insn))
2782 return "movaps\t{%1, %0|%0, %1}";
2784 return "movapd\t{%1, %0|%0, %1}";
2786 return "movdqa\t{%1, %0|%0, %1}";
2788 return "movq\t{%1, %0|%0, %1}";
2790 return "movsd\t{%1, %0|%0, %1}";
2792 return "movlpd\t{%1, %0|%0, %1}";
2794 return "movlps\t{%1, %0|%0, %1}";
2803 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2805 (cond [(eq_attr "alternative" "0,1,2")
2807 (eq_attr "alternative" "3,4")
2810 /* For SSE1, we have many fewer alternatives. */
2811 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2812 (cond [(eq_attr "alternative" "5,6")
2813 (const_string "V4SF")
2815 (const_string "V2SF"))
2817 /* xorps is one byte shorter. */
2818 (eq_attr "alternative" "5")
2819 (cond [(ne (symbol_ref "optimize_size")
2821 (const_string "V4SF")
2822 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2826 (const_string "V2DF"))
2828 /* For architectures resolving dependencies on
2829 whole SSE registers use APD move to break dependency
2830 chains, otherwise use short move to avoid extra work.
2832 movaps encodes one byte shorter. */
2833 (eq_attr "alternative" "6")
2835 [(ne (symbol_ref "optimize_size")
2837 (const_string "V4SF")
2838 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2840 (const_string "V2DF")
2842 (const_string "DF"))
2843 /* For architectures resolving dependencies on register
2844 parts we may avoid extra work to zero out upper part
2846 (eq_attr "alternative" "7")
2848 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2850 (const_string "V1DF")
2851 (const_string "DF"))
2853 (const_string "DF")))])
2855 (define_insn "*movdf_integer_rex64"
2856 [(set (match_operand:DF 0 "nonimmediate_operand"
2857 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2858 (match_operand:DF 1 "general_operand"
2859 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2860 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2861 && (reload_in_progress || reload_completed
2862 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2863 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2864 && standard_80387_constant_p (operands[1]))
2865 || GET_CODE (operands[1]) != CONST_DOUBLE
2866 || memory_operand (operands[0], DFmode))"
2868 switch (which_alternative)
2872 return output_387_reg_move (insn, operands);
2875 return standard_80387_constant_opcode (operands[1]);
2882 switch (get_attr_mode (insn))
2885 return "xorps\t%0, %0";
2887 return "xorpd\t%0, %0";
2889 return "pxor\t%0, %0";
2896 switch (get_attr_mode (insn))
2899 return "movaps\t{%1, %0|%0, %1}";
2901 return "movapd\t{%1, %0|%0, %1}";
2903 return "movdqa\t{%1, %0|%0, %1}";
2905 return "movq\t{%1, %0|%0, %1}";
2907 return "movsd\t{%1, %0|%0, %1}";
2909 return "movlpd\t{%1, %0|%0, %1}";
2911 return "movlps\t{%1, %0|%0, %1}";
2918 return "movd\t{%1, %0|%0, %1}";
2924 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2926 (cond [(eq_attr "alternative" "0,1,2")
2928 (eq_attr "alternative" "3,4,9,10")
2931 /* For SSE1, we have many fewer alternatives. */
2932 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2933 (cond [(eq_attr "alternative" "5,6")
2934 (const_string "V4SF")
2936 (const_string "V2SF"))
2938 /* xorps is one byte shorter. */
2939 (eq_attr "alternative" "5")
2940 (cond [(ne (symbol_ref "optimize_size")
2942 (const_string "V4SF")
2943 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2947 (const_string "V2DF"))
2949 /* For architectures resolving dependencies on
2950 whole SSE registers use APD move to break dependency
2951 chains, otherwise use short move to avoid extra work.
2953 movaps encodes one byte shorter. */
2954 (eq_attr "alternative" "6")
2956 [(ne (symbol_ref "optimize_size")
2958 (const_string "V4SF")
2959 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2961 (const_string "V2DF")
2963 (const_string "DF"))
2964 /* For architectures resolving dependencies on register
2965 parts we may avoid extra work to zero out upper part
2967 (eq_attr "alternative" "7")
2969 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2971 (const_string "V1DF")
2972 (const_string "DF"))
2974 (const_string "DF")))])
2976 (define_insn "*movdf_integer"
2977 [(set (match_operand:DF 0 "nonimmediate_operand"
2978 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2979 (match_operand:DF 1 "general_operand"
2980 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2981 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2982 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2983 && (reload_in_progress || reload_completed
2984 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2985 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2986 && standard_80387_constant_p (operands[1]))
2987 || GET_CODE (operands[1]) != CONST_DOUBLE
2988 || memory_operand (operands[0], DFmode))"
2990 switch (which_alternative)
2994 return output_387_reg_move (insn, operands);
2997 return standard_80387_constant_opcode (operands[1]);
3004 switch (get_attr_mode (insn))
3007 return "xorps\t%0, %0";
3009 return "xorpd\t%0, %0";
3011 return "pxor\t%0, %0";
3018 switch (get_attr_mode (insn))
3021 return "movaps\t{%1, %0|%0, %1}";
3023 return "movapd\t{%1, %0|%0, %1}";
3025 return "movdqa\t{%1, %0|%0, %1}";
3027 return "movq\t{%1, %0|%0, %1}";
3029 return "movsd\t{%1, %0|%0, %1}";
3031 return "movlpd\t{%1, %0|%0, %1}";
3033 return "movlps\t{%1, %0|%0, %1}";
3042 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3044 (cond [(eq_attr "alternative" "0,1,2")
3046 (eq_attr "alternative" "3,4")
3049 /* For SSE1, we have many fewer alternatives. */
3050 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3051 (cond [(eq_attr "alternative" "5,6")
3052 (const_string "V4SF")
3054 (const_string "V2SF"))
3056 /* xorps is one byte shorter. */
3057 (eq_attr "alternative" "5")
3058 (cond [(ne (symbol_ref "optimize_size")
3060 (const_string "V4SF")
3061 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3065 (const_string "V2DF"))
3067 /* For architectures resolving dependencies on
3068 whole SSE registers use APD move to break dependency
3069 chains, otherwise use short move to avoid extra work.
3071 movaps encodes one byte shorter. */
3072 (eq_attr "alternative" "6")
3074 [(ne (symbol_ref "optimize_size")
3076 (const_string "V4SF")
3077 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3079 (const_string "V2DF")
3081 (const_string "DF"))
3082 /* For architectures resolving dependencies on register
3083 parts we may avoid extra work to zero out upper part
3085 (eq_attr "alternative" "7")
3087 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3089 (const_string "V1DF")
3090 (const_string "DF"))
3092 (const_string "DF")))])
3095 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3096 (match_operand:DF 1 "general_operand" ""))]
3098 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3099 && ! (ANY_FP_REG_P (operands[0]) ||
3100 (GET_CODE (operands[0]) == SUBREG
3101 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3102 && ! (ANY_FP_REG_P (operands[1]) ||
3103 (GET_CODE (operands[1]) == SUBREG
3104 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3106 "ix86_split_long_move (operands); DONE;")
3108 (define_insn "*swapdf"
3109 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3110 (match_operand:DF 1 "fp_register_operand" "+f"))
3113 "reload_completed || TARGET_80387"
3115 if (STACK_TOP_P (operands[0]))
3120 [(set_attr "type" "fxch")
3121 (set_attr "mode" "DF")])
3123 (define_expand "movxf"
3124 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3125 (match_operand:XF 1 "general_operand" ""))]
3127 "ix86_expand_move (XFmode, operands); DONE;")
3129 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3130 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3131 ;; Pushing using integer instructions is longer except for constants
3132 ;; and direct memory references.
3133 ;; (assuming that any given constant is pushed only once, but this ought to be
3134 ;; handled elsewhere).
3136 (define_insn "*pushxf_nointeger"
3137 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3138 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3141 /* This insn should be already split before reg-stack. */
3144 [(set_attr "type" "multi")
3145 (set_attr "unit" "i387,*,*")
3146 (set_attr "mode" "XF,SI,SI")])
3148 (define_insn "*pushxf_integer"
3149 [(set (match_operand:XF 0 "push_operand" "=<,<")
3150 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3153 /* This insn should be already split before reg-stack. */
3156 [(set_attr "type" "multi")
3157 (set_attr "unit" "i387,*")
3158 (set_attr "mode" "XF,SI")])
3161 [(set (match_operand 0 "push_operand" "")
3162 (match_operand 1 "general_operand" ""))]
3164 && (GET_MODE (operands[0]) == XFmode
3165 || GET_MODE (operands[0]) == DFmode)
3166 && !ANY_FP_REG_P (operands[1])"
3168 "ix86_split_long_move (operands); DONE;")
3171 [(set (match_operand:XF 0 "push_operand" "")
3172 (match_operand:XF 1 "any_fp_register_operand" ""))]
3174 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3175 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3176 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3179 [(set (match_operand:XF 0 "push_operand" "")
3180 (match_operand:XF 1 "any_fp_register_operand" ""))]
3182 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3183 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3184 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3186 ;; Do not use integer registers when optimizing for size
3187 (define_insn "*movxf_nointeger"
3188 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3189 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3191 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3192 && (reload_in_progress || reload_completed
3193 || (optimize_size && standard_80387_constant_p (operands[1]))
3194 || GET_CODE (operands[1]) != CONST_DOUBLE
3195 || memory_operand (operands[0], XFmode))"
3197 switch (which_alternative)
3201 return output_387_reg_move (insn, operands);
3204 return standard_80387_constant_opcode (operands[1]);
3212 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3213 (set_attr "mode" "XF,XF,XF,SI,SI")])
3215 (define_insn "*movxf_integer"
3216 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3217 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3219 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3220 && (reload_in_progress || reload_completed
3221 || (optimize_size && standard_80387_constant_p (operands[1]))
3222 || GET_CODE (operands[1]) != CONST_DOUBLE
3223 || memory_operand (operands[0], XFmode))"
3225 switch (which_alternative)
3229 return output_387_reg_move (insn, operands);
3232 return standard_80387_constant_opcode (operands[1]);
3241 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3242 (set_attr "mode" "XF,XF,XF,SI,SI")])
3244 (define_expand "movtf"
3245 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3246 (match_operand:TF 1 "nonimmediate_operand" ""))]
3249 ix86_expand_move (TFmode, operands);
3253 (define_insn "*movtf_internal"
3254 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3255 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3257 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3259 switch (which_alternative)
3263 if (get_attr_mode (insn) == MODE_V4SF)
3264 return "movaps\t{%1, %0|%0, %1}";
3266 return "movdqa\t{%1, %0|%0, %1}";
3268 if (get_attr_mode (insn) == MODE_V4SF)
3269 return "xorps\t%0, %0";
3271 return "pxor\t%0, %0";
3279 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3281 (cond [(eq_attr "alternative" "0,2")
3283 (ne (symbol_ref "optimize_size")
3285 (const_string "V4SF")
3286 (const_string "TI"))
3287 (eq_attr "alternative" "1")
3289 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3291 (ne (symbol_ref "optimize_size")
3293 (const_string "V4SF")
3294 (const_string "TI"))]
3295 (const_string "DI")))])
3298 [(set (match_operand 0 "nonimmediate_operand" "")
3299 (match_operand 1 "general_operand" ""))]
3301 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3302 && GET_MODE (operands[0]) == XFmode
3303 && ! (ANY_FP_REG_P (operands[0]) ||
3304 (GET_CODE (operands[0]) == SUBREG
3305 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3306 && ! (ANY_FP_REG_P (operands[1]) ||
3307 (GET_CODE (operands[1]) == SUBREG
3308 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3310 "ix86_split_long_move (operands); DONE;")
3313 [(set (match_operand 0 "register_operand" "")
3314 (match_operand 1 "memory_operand" ""))]
3316 && MEM_P (operands[1])
3317 && (GET_MODE (operands[0]) == TFmode
3318 || GET_MODE (operands[0]) == XFmode
3319 || GET_MODE (operands[0]) == SFmode
3320 || GET_MODE (operands[0]) == DFmode)
3321 && (operands[2] = find_constant_src (insn))"
3322 [(set (match_dup 0) (match_dup 2))]
3324 rtx c = operands[2];
3325 rtx r = operands[0];
3327 if (GET_CODE (r) == SUBREG)
3332 if (!standard_sse_constant_p (c))
3335 else if (FP_REG_P (r))
3337 if (!standard_80387_constant_p (c))
3340 else if (MMX_REG_P (r))
3345 [(set (match_operand 0 "register_operand" "")
3346 (float_extend (match_operand 1 "memory_operand" "")))]
3348 && MEM_P (operands[1])
3349 && (GET_MODE (operands[0]) == TFmode
3350 || GET_MODE (operands[0]) == XFmode
3351 || GET_MODE (operands[0]) == SFmode
3352 || GET_MODE (operands[0]) == DFmode)
3353 && (operands[2] = find_constant_src (insn))"
3354 [(set (match_dup 0) (match_dup 2))]
3356 rtx c = operands[2];
3357 rtx r = operands[0];
3359 if (GET_CODE (r) == SUBREG)
3364 if (!standard_sse_constant_p (c))
3367 else if (FP_REG_P (r))
3369 if (!standard_80387_constant_p (c))
3372 else if (MMX_REG_P (r))
3376 (define_insn "swapxf"
3377 [(set (match_operand:XF 0 "register_operand" "+f")
3378 (match_operand:XF 1 "register_operand" "+f"))
3383 if (STACK_TOP_P (operands[0]))
3388 [(set_attr "type" "fxch")
3389 (set_attr "mode" "XF")])
3391 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3393 [(set (match_operand:X87MODEF 0 "register_operand" "")
3394 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3395 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3396 && (standard_80387_constant_p (operands[1]) == 8
3397 || standard_80387_constant_p (operands[1]) == 9)"
3398 [(set (match_dup 0)(match_dup 1))
3400 (neg:X87MODEF (match_dup 0)))]
3404 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3405 if (real_isnegzero (&r))
3406 operands[1] = CONST0_RTX (<MODE>mode);
3408 operands[1] = CONST1_RTX (<MODE>mode);
3412 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3413 (match_operand:TF 1 "general_operand" ""))]
3415 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3417 "ix86_split_long_move (operands); DONE;")
3419 ;; Zero extension instructions
3421 (define_expand "zero_extendhisi2"
3422 [(set (match_operand:SI 0 "register_operand" "")
3423 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3426 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3428 operands[1] = force_reg (HImode, operands[1]);
3429 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3434 (define_insn "zero_extendhisi2_and"
3435 [(set (match_operand:SI 0 "register_operand" "=r")
3436 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3437 (clobber (reg:CC FLAGS_REG))]
3438 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3440 [(set_attr "type" "alu1")
3441 (set_attr "mode" "SI")])
3444 [(set (match_operand:SI 0 "register_operand" "")
3445 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3446 (clobber (reg:CC FLAGS_REG))]
3447 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3448 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3449 (clobber (reg:CC FLAGS_REG))])]
3452 (define_insn "*zero_extendhisi2_movzwl"
3453 [(set (match_operand:SI 0 "register_operand" "=r")
3454 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3455 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3456 "movz{wl|x}\t{%1, %0|%0, %1}"
3457 [(set_attr "type" "imovx")
3458 (set_attr "mode" "SI")])
3460 (define_expand "zero_extendqihi2"
3462 [(set (match_operand:HI 0 "register_operand" "")
3463 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3464 (clobber (reg:CC FLAGS_REG))])]
3468 (define_insn "*zero_extendqihi2_and"
3469 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3470 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3471 (clobber (reg:CC FLAGS_REG))]
3472 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3474 [(set_attr "type" "alu1")
3475 (set_attr "mode" "HI")])
3477 (define_insn "*zero_extendqihi2_movzbw_and"
3478 [(set (match_operand:HI 0 "register_operand" "=r,r")
3479 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3480 (clobber (reg:CC FLAGS_REG))]
3481 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3483 [(set_attr "type" "imovx,alu1")
3484 (set_attr "mode" "HI")])
3486 ; zero extend to SImode here to avoid partial register stalls
3487 (define_insn "*zero_extendqihi2_movzbl"
3488 [(set (match_operand:HI 0 "register_operand" "=r")
3489 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3490 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3491 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3492 [(set_attr "type" "imovx")
3493 (set_attr "mode" "SI")])
3495 ;; For the movzbw case strip only the clobber
3497 [(set (match_operand:HI 0 "register_operand" "")
3498 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3499 (clobber (reg:CC FLAGS_REG))]
3501 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3502 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3503 [(set (match_operand:HI 0 "register_operand" "")
3504 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3506 ;; When source and destination does not overlap, clear destination
3507 ;; first and then do the movb
3509 [(set (match_operand:HI 0 "register_operand" "")
3510 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3511 (clobber (reg:CC FLAGS_REG))]
3513 && ANY_QI_REG_P (operands[0])
3514 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3515 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3516 [(set (match_dup 0) (const_int 0))
3517 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3518 "operands[2] = gen_lowpart (QImode, operands[0]);")
3520 ;; Rest is handled by single and.
3522 [(set (match_operand:HI 0 "register_operand" "")
3523 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3524 (clobber (reg:CC FLAGS_REG))]
3526 && true_regnum (operands[0]) == true_regnum (operands[1])"
3527 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3528 (clobber (reg:CC FLAGS_REG))])]
3531 (define_expand "zero_extendqisi2"
3533 [(set (match_operand:SI 0 "register_operand" "")
3534 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3535 (clobber (reg:CC FLAGS_REG))])]
3539 (define_insn "*zero_extendqisi2_and"
3540 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3541 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3542 (clobber (reg:CC FLAGS_REG))]
3543 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3545 [(set_attr "type" "alu1")
3546 (set_attr "mode" "SI")])
3548 (define_insn "*zero_extendqisi2_movzbw_and"
3549 [(set (match_operand:SI 0 "register_operand" "=r,r")
3550 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3551 (clobber (reg:CC FLAGS_REG))]
3552 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3554 [(set_attr "type" "imovx,alu1")
3555 (set_attr "mode" "SI")])
3557 (define_insn "*zero_extendqisi2_movzbw"
3558 [(set (match_operand:SI 0 "register_operand" "=r")
3559 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3560 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3561 "movz{bl|x}\t{%1, %0|%0, %1}"
3562 [(set_attr "type" "imovx")
3563 (set_attr "mode" "SI")])
3565 ;; For the movzbl case strip only the clobber
3567 [(set (match_operand:SI 0 "register_operand" "")
3568 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3569 (clobber (reg:CC FLAGS_REG))]
3571 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3572 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3574 (zero_extend:SI (match_dup 1)))])
3576 ;; When source and destination does not overlap, clear destination
3577 ;; first and then do the movb
3579 [(set (match_operand:SI 0 "register_operand" "")
3580 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3581 (clobber (reg:CC FLAGS_REG))]
3583 && ANY_QI_REG_P (operands[0])
3584 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3585 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3586 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3587 [(set (match_dup 0) (const_int 0))
3588 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3589 "operands[2] = gen_lowpart (QImode, operands[0]);")
3591 ;; Rest is handled by single and.
3593 [(set (match_operand:SI 0 "register_operand" "")
3594 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3595 (clobber (reg:CC FLAGS_REG))]
3597 && true_regnum (operands[0]) == true_regnum (operands[1])"
3598 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3599 (clobber (reg:CC FLAGS_REG))])]
3602 ;; %%% Kill me once multi-word ops are sane.
3603 (define_expand "zero_extendsidi2"
3604 [(set (match_operand:DI 0 "register_operand" "")
3605 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3610 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3615 (define_insn "zero_extendsidi2_32"
3616 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3618 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3619 (clobber (reg:CC FLAGS_REG))]
3625 movd\t{%1, %0|%0, %1}
3626 movd\t{%1, %0|%0, %1}
3627 movd\t{%1, %0|%0, %1}
3628 movd\t{%1, %0|%0, %1}"
3629 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3630 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3632 (define_insn "zero_extendsidi2_rex64"
3633 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3635 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3638 mov\t{%k1, %k0|%k0, %k1}
3640 movd\t{%1, %0|%0, %1}
3641 movd\t{%1, %0|%0, %1}
3642 movd\t{%1, %0|%0, %1}
3643 movd\t{%1, %0|%0, %1}"
3644 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3645 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3648 [(set (match_operand:DI 0 "memory_operand" "")
3649 (zero_extend:DI (match_dup 0)))]
3651 [(set (match_dup 4) (const_int 0))]
3652 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3655 [(set (match_operand:DI 0 "register_operand" "")
3656 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3657 (clobber (reg:CC FLAGS_REG))]
3658 "!TARGET_64BIT && reload_completed
3659 && true_regnum (operands[0]) == true_regnum (operands[1])"
3660 [(set (match_dup 4) (const_int 0))]
3661 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3664 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3665 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3666 (clobber (reg:CC FLAGS_REG))]
3667 "!TARGET_64BIT && reload_completed
3668 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3669 [(set (match_dup 3) (match_dup 1))
3670 (set (match_dup 4) (const_int 0))]
3671 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3673 (define_insn "zero_extendhidi2"
3674 [(set (match_operand:DI 0 "register_operand" "=r")
3675 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3677 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3678 [(set_attr "type" "imovx")
3679 (set_attr "mode" "DI")])
3681 (define_insn "zero_extendqidi2"
3682 [(set (match_operand:DI 0 "register_operand" "=r")
3683 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3685 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3686 [(set_attr "type" "imovx")
3687 (set_attr "mode" "DI")])
3689 ;; Sign extension instructions
3691 (define_expand "extendsidi2"
3692 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3693 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3694 (clobber (reg:CC FLAGS_REG))
3695 (clobber (match_scratch:SI 2 ""))])]
3700 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3705 (define_insn "*extendsidi2_1"
3706 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3707 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3708 (clobber (reg:CC FLAGS_REG))
3709 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3713 (define_insn "extendsidi2_rex64"
3714 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3715 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3719 movs{lq|x}\t{%1,%0|%0, %1}"
3720 [(set_attr "type" "imovx")
3721 (set_attr "mode" "DI")
3722 (set_attr "prefix_0f" "0")
3723 (set_attr "modrm" "0,1")])
3725 (define_insn "extendhidi2"
3726 [(set (match_operand:DI 0 "register_operand" "=r")
3727 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3729 "movs{wq|x}\t{%1,%0|%0, %1}"
3730 [(set_attr "type" "imovx")
3731 (set_attr "mode" "DI")])
3733 (define_insn "extendqidi2"
3734 [(set (match_operand:DI 0 "register_operand" "=r")
3735 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3737 "movs{bq|x}\t{%1,%0|%0, %1}"
3738 [(set_attr "type" "imovx")
3739 (set_attr "mode" "DI")])
3741 ;; Extend to memory case when source register does die.
3743 [(set (match_operand:DI 0 "memory_operand" "")
3744 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3745 (clobber (reg:CC FLAGS_REG))
3746 (clobber (match_operand:SI 2 "register_operand" ""))]
3748 && dead_or_set_p (insn, operands[1])
3749 && !reg_mentioned_p (operands[1], operands[0]))"
3750 [(set (match_dup 3) (match_dup 1))
3751 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3752 (clobber (reg:CC FLAGS_REG))])
3753 (set (match_dup 4) (match_dup 1))]
3754 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3756 ;; Extend to memory case when source register does not die.
3758 [(set (match_operand:DI 0 "memory_operand" "")
3759 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3760 (clobber (reg:CC FLAGS_REG))
3761 (clobber (match_operand:SI 2 "register_operand" ""))]
3765 split_di (&operands[0], 1, &operands[3], &operands[4]);
3767 emit_move_insn (operands[3], operands[1]);
3769 /* Generate a cltd if possible and doing so it profitable. */
3770 if ((optimize_size || TARGET_USE_CLTD)
3771 && true_regnum (operands[1]) == AX_REG
3772 && true_regnum (operands[2]) == DX_REG)
3774 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3778 emit_move_insn (operands[2], operands[1]);
3779 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3781 emit_move_insn (operands[4], operands[2]);
3785 ;; Extend to register case. Optimize case where source and destination
3786 ;; registers match and cases where we can use cltd.
3788 [(set (match_operand:DI 0 "register_operand" "")
3789 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3790 (clobber (reg:CC FLAGS_REG))
3791 (clobber (match_scratch:SI 2 ""))]
3795 split_di (&operands[0], 1, &operands[3], &operands[4]);
3797 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3798 emit_move_insn (operands[3], operands[1]);
3800 /* Generate a cltd if possible and doing so it profitable. */
3801 if ((optimize_size || TARGET_USE_CLTD)
3802 && true_regnum (operands[3]) == AX_REG)
3804 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3808 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3809 emit_move_insn (operands[4], operands[1]);
3811 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3815 (define_insn "extendhisi2"
3816 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3817 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3820 switch (get_attr_prefix_0f (insn))
3823 return "{cwtl|cwde}";
3825 return "movs{wl|x}\t{%1,%0|%0, %1}";
3828 [(set_attr "type" "imovx")
3829 (set_attr "mode" "SI")
3830 (set (attr "prefix_0f")
3831 ;; movsx is short decodable while cwtl is vector decoded.
3832 (if_then_else (and (eq_attr "cpu" "!k6")
3833 (eq_attr "alternative" "0"))
3835 (const_string "1")))
3837 (if_then_else (eq_attr "prefix_0f" "0")
3839 (const_string "1")))])
3841 (define_insn "*extendhisi2_zext"
3842 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3844 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3847 switch (get_attr_prefix_0f (insn))
3850 return "{cwtl|cwde}";
3852 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3855 [(set_attr "type" "imovx")
3856 (set_attr "mode" "SI")
3857 (set (attr "prefix_0f")
3858 ;; movsx is short decodable while cwtl is vector decoded.
3859 (if_then_else (and (eq_attr "cpu" "!k6")
3860 (eq_attr "alternative" "0"))
3862 (const_string "1")))
3864 (if_then_else (eq_attr "prefix_0f" "0")
3866 (const_string "1")))])
3868 (define_insn "extendqihi2"
3869 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3870 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3873 switch (get_attr_prefix_0f (insn))
3876 return "{cbtw|cbw}";
3878 return "movs{bw|x}\t{%1,%0|%0, %1}";
3881 [(set_attr "type" "imovx")
3882 (set_attr "mode" "HI")
3883 (set (attr "prefix_0f")
3884 ;; movsx is short decodable while cwtl is vector decoded.
3885 (if_then_else (and (eq_attr "cpu" "!k6")
3886 (eq_attr "alternative" "0"))
3888 (const_string "1")))
3890 (if_then_else (eq_attr "prefix_0f" "0")
3892 (const_string "1")))])
3894 (define_insn "extendqisi2"
3895 [(set (match_operand:SI 0 "register_operand" "=r")
3896 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3898 "movs{bl|x}\t{%1,%0|%0, %1}"
3899 [(set_attr "type" "imovx")
3900 (set_attr "mode" "SI")])
3902 (define_insn "*extendqisi2_zext"
3903 [(set (match_operand:DI 0 "register_operand" "=r")
3905 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3907 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3908 [(set_attr "type" "imovx")
3909 (set_attr "mode" "SI")])
3911 ;; Conversions between float and double.
3913 ;; These are all no-ops in the model used for the 80387. So just
3916 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3917 (define_insn "*dummy_extendsfdf2"
3918 [(set (match_operand:DF 0 "push_operand" "=<")
3919 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3924 [(set (match_operand:DF 0 "push_operand" "")
3925 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3927 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3928 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3931 [(set (match_operand:DF 0 "push_operand" "")
3932 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3934 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3935 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3937 (define_insn "*dummy_extendsfxf2"
3938 [(set (match_operand:XF 0 "push_operand" "=<")
3939 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3944 [(set (match_operand:XF 0 "push_operand" "")
3945 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3947 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3948 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3949 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3952 [(set (match_operand:XF 0 "push_operand" "")
3953 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3955 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3956 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3957 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3960 [(set (match_operand:XF 0 "push_operand" "")
3961 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3963 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3964 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3965 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3968 [(set (match_operand:XF 0 "push_operand" "")
3969 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3971 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3972 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3973 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3975 (define_expand "extendsfdf2"
3976 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3977 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3978 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3980 /* ??? Needed for compress_float_constant since all fp constants
3981 are LEGITIMATE_CONSTANT_P. */
3982 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3984 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3985 && standard_80387_constant_p (operands[1]) > 0)
3987 operands[1] = simplify_const_unary_operation
3988 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3989 emit_move_insn_1 (operands[0], operands[1]);
3992 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3996 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3998 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4000 We do the conversion post reload to avoid producing of 128bit spills
4001 that might lead to ICE on 32bit target. The sequence unlikely combine
4004 [(set (match_operand:DF 0 "register_operand" "")
4006 (match_operand:SF 1 "nonimmediate_operand" "")))]
4007 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4008 && reload_completed && SSE_REG_P (operands[0])"
4013 (parallel [(const_int 0) (const_int 1)]))))]
4015 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4016 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4017 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4018 Try to avoid move when unpacking can be done in source. */
4019 if (REG_P (operands[1]))
4021 /* If it is unsafe to overwrite upper half of source, we need
4022 to move to destination and unpack there. */
4023 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4024 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4025 && true_regnum (operands[0]) != true_regnum (operands[1]))
4027 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4028 emit_move_insn (tmp, operands[1]);
4031 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4032 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4035 emit_insn (gen_vec_setv4sf_0 (operands[3],
4036 CONST0_RTX (V4SFmode), operands[1]));
4039 (define_insn "*extendsfdf2_mixed"
4040 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4042 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4043 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4045 switch (which_alternative)
4049 return output_387_reg_move (insn, operands);
4052 return "cvtss2sd\t{%1, %0|%0, %1}";
4058 [(set_attr "type" "fmov,fmov,ssecvt")
4059 (set_attr "mode" "SF,XF,DF")])
4061 (define_insn "*extendsfdf2_sse"
4062 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4063 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4064 "TARGET_SSE2 && TARGET_SSE_MATH"
4065 "cvtss2sd\t{%1, %0|%0, %1}"
4066 [(set_attr "type" "ssecvt")
4067 (set_attr "mode" "DF")])
4069 (define_insn "*extendsfdf2_i387"
4070 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4071 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4073 "* return output_387_reg_move (insn, operands);"
4074 [(set_attr "type" "fmov")
4075 (set_attr "mode" "SF,XF")])
4077 (define_expand "extend<mode>xf2"
4078 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4079 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4082 /* ??? Needed for compress_float_constant since all fp constants
4083 are LEGITIMATE_CONSTANT_P. */
4084 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4086 if (standard_80387_constant_p (operands[1]) > 0)
4088 operands[1] = simplify_const_unary_operation
4089 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4090 emit_move_insn_1 (operands[0], operands[1]);
4093 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4097 (define_insn "*extend<mode>xf2_i387"
4098 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4100 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4102 "* return output_387_reg_move (insn, operands);"
4103 [(set_attr "type" "fmov")
4104 (set_attr "mode" "<MODE>,XF")])
4106 ;; %%% This seems bad bad news.
4107 ;; This cannot output into an f-reg because there is no way to be sure
4108 ;; of truncating in that case. Otherwise this is just like a simple move
4109 ;; insn. So we pretend we can output to a reg in order to get better
4110 ;; register preferencing, but we really use a stack slot.
4112 ;; Conversion from DFmode to SFmode.
4114 (define_expand "truncdfsf2"
4115 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4117 (match_operand:DF 1 "nonimmediate_operand" "")))]
4118 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4120 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4122 else if (flag_unsafe_math_optimizations)
4126 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4127 rtx temp = assign_386_stack_local (SFmode, slot);
4128 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4133 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4135 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4137 We do the conversion post reload to avoid producing of 128bit spills
4138 that might lead to ICE on 32bit target. The sequence unlikely combine
4141 [(set (match_operand:SF 0 "register_operand" "")
4143 (match_operand:DF 1 "nonimmediate_operand" "")))]
4144 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4145 && reload_completed && SSE_REG_P (operands[0])"
4148 (float_truncate:V2SF
4152 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4153 operands[3] = CONST0_RTX (V2SFmode);
4154 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4155 /* Use movsd for loading from memory, unpcklpd for registers.
4156 Try to avoid move when unpacking can be done in source, or SSE3
4157 movddup is available. */
4158 if (REG_P (operands[1]))
4161 && true_regnum (operands[0]) != true_regnum (operands[1])
4162 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4163 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4165 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4166 emit_move_insn (tmp, operands[1]);
4169 else if (!TARGET_SSE3)
4170 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4171 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4174 emit_insn (gen_sse2_loadlpd (operands[4],
4175 CONST0_RTX (V2DFmode), operands[1]));
4178 (define_expand "truncdfsf2_with_temp"
4179 [(parallel [(set (match_operand:SF 0 "" "")
4180 (float_truncate:SF (match_operand:DF 1 "" "")))
4181 (clobber (match_operand:SF 2 "" ""))])]
4184 (define_insn "*truncdfsf_fast_mixed"
4185 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4187 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4188 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4190 switch (which_alternative)
4194 return output_387_reg_move (insn, operands);
4196 return "cvtsd2ss\t{%1, %0|%0, %1}";
4201 [(set_attr "type" "fmov,fmov,ssecvt")
4202 (set_attr "mode" "SF")])
4204 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4205 ;; because nothing we do here is unsafe.
4206 (define_insn "*truncdfsf_fast_sse"
4207 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4209 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4210 "TARGET_SSE2 && TARGET_SSE_MATH"
4211 "cvtsd2ss\t{%1, %0|%0, %1}"
4212 [(set_attr "type" "ssecvt")
4213 (set_attr "mode" "SF")])
4215 (define_insn "*truncdfsf_fast_i387"
4216 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4218 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4219 "TARGET_80387 && flag_unsafe_math_optimizations"
4220 "* return output_387_reg_move (insn, operands);"
4221 [(set_attr "type" "fmov")
4222 (set_attr "mode" "SF")])
4224 (define_insn "*truncdfsf_mixed"
4225 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4227 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4228 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4229 "TARGET_MIX_SSE_I387"
4231 switch (which_alternative)
4234 return output_387_reg_move (insn, operands);
4239 return "cvtsd2ss\t{%1, %0|%0, %1}";
4244 [(set_attr "type" "fmov,multi,ssecvt")
4245 (set_attr "unit" "*,i387,*")
4246 (set_attr "mode" "SF")])
4248 (define_insn "*truncdfsf_i387"
4249 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4251 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4252 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4255 switch (which_alternative)
4258 return output_387_reg_move (insn, operands);
4266 [(set_attr "type" "fmov,multi")
4267 (set_attr "unit" "*,i387")
4268 (set_attr "mode" "SF")])
4270 (define_insn "*truncdfsf2_i387_1"
4271 [(set (match_operand:SF 0 "memory_operand" "=m")
4273 (match_operand:DF 1 "register_operand" "f")))]
4275 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4276 && !TARGET_MIX_SSE_I387"
4277 "* return output_387_reg_move (insn, operands);"
4278 [(set_attr "type" "fmov")
4279 (set_attr "mode" "SF")])
4282 [(set (match_operand:SF 0 "register_operand" "")
4284 (match_operand:DF 1 "fp_register_operand" "")))
4285 (clobber (match_operand 2 "" ""))]
4287 [(set (match_dup 2) (match_dup 1))
4288 (set (match_dup 0) (match_dup 2))]
4290 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4293 ;; Conversion from XFmode to {SF,DF}mode
4295 (define_expand "truncxf<mode>2"
4296 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4297 (float_truncate:MODEF
4298 (match_operand:XF 1 "register_operand" "")))
4299 (clobber (match_dup 2))])]
4302 if (flag_unsafe_math_optimizations)
4304 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4305 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4306 if (reg != operands[0])
4307 emit_move_insn (operands[0], reg);
4312 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4313 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4317 (define_insn "*truncxfsf2_mixed"
4318 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4320 (match_operand:XF 1 "register_operand" "f,f")))
4321 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4324 gcc_assert (!which_alternative);
4325 return output_387_reg_move (insn, operands);
4327 [(set_attr "type" "fmov,multi")
4328 (set_attr "unit" "*,i387")
4329 (set_attr "mode" "SF")])
4331 (define_insn "*truncxfdf2_mixed"
4332 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4334 (match_operand:XF 1 "register_operand" "f,f")))
4335 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4338 gcc_assert (!which_alternative);
4339 return output_387_reg_move (insn, operands);
4341 [(set_attr "type" "fmov,multi")
4342 (set_attr "unit" "*,i387")
4343 (set_attr "mode" "DF")])
4345 (define_insn "truncxf<mode>2_i387_noop"
4346 [(set (match_operand:MODEF 0 "register_operand" "=f")
4347 (float_truncate:MODEF
4348 (match_operand:XF 1 "register_operand" "f")))]
4349 "TARGET_80387 && flag_unsafe_math_optimizations"
4350 "* return output_387_reg_move (insn, operands);"
4351 [(set_attr "type" "fmov")
4352 (set_attr "mode" "<MODE>")])
4354 (define_insn "*truncxf<mode>2_i387"
4355 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4356 (float_truncate:MODEF
4357 (match_operand:XF 1 "register_operand" "f")))]
4359 "* return output_387_reg_move (insn, operands);"
4360 [(set_attr "type" "fmov")
4361 (set_attr "mode" "<MODE>")])
4364 [(set (match_operand:MODEF 0 "register_operand" "")
4365 (float_truncate:MODEF
4366 (match_operand:XF 1 "register_operand" "")))
4367 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4368 "TARGET_80387 && reload_completed"
4369 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4370 (set (match_dup 0) (match_dup 2))]
4374 [(set (match_operand:MODEF 0 "memory_operand" "")
4375 (float_truncate:MODEF
4376 (match_operand:XF 1 "register_operand" "")))
4377 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4379 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4382 ;; Signed conversion to DImode.
4384 (define_expand "fix_truncxfdi2"
4385 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4386 (fix:DI (match_operand:XF 1 "register_operand" "")))
4387 (clobber (reg:CC FLAGS_REG))])]
4392 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4397 (define_expand "fix_trunc<mode>di2"
4398 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4399 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4400 (clobber (reg:CC FLAGS_REG))])]
4401 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4404 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4406 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4409 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4411 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4412 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4413 if (out != operands[0])
4414 emit_move_insn (operands[0], out);
4419 ;; Signed conversion to SImode.
4421 (define_expand "fix_truncxfsi2"
4422 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4423 (fix:SI (match_operand:XF 1 "register_operand" "")))
4424 (clobber (reg:CC FLAGS_REG))])]
4429 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4434 (define_expand "fix_trunc<mode>si2"
4435 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4436 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4437 (clobber (reg:CC FLAGS_REG))])]
4438 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4441 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4443 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4446 if (SSE_FLOAT_MODE_P (<MODE>mode))
4448 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4449 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4450 if (out != operands[0])
4451 emit_move_insn (operands[0], out);
4456 ;; Signed conversion to HImode.
4458 (define_expand "fix_trunc<mode>hi2"
4459 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4460 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4461 (clobber (reg:CC FLAGS_REG))])]
4463 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4467 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4472 ;; Unsigned conversion to SImode.
4474 (define_expand "fixuns_trunc<mode>si2"
4476 [(set (match_operand:SI 0 "register_operand" "")
4478 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4480 (clobber (match_scratch:<ssevecmode> 3 ""))
4481 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4482 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4484 enum machine_mode mode = <MODE>mode;
4485 enum machine_mode vecmode = <ssevecmode>mode;
4486 REAL_VALUE_TYPE TWO31r;
4489 real_ldexp (&TWO31r, &dconst1, 31);
4490 two31 = const_double_from_real_value (TWO31r, mode);
4491 two31 = ix86_build_const_vector (mode, true, two31);
4492 operands[2] = force_reg (vecmode, two31);
4495 (define_insn_and_split "*fixuns_trunc<mode>_1"
4496 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4498 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4499 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4500 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4501 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4502 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4504 "&& reload_completed"
4507 ix86_split_convert_uns_si_sse (operands);
4511 ;; Unsigned conversion to HImode.
4512 ;; Without these patterns, we'll try the unsigned SI conversion which
4513 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4515 (define_expand "fixuns_trunc<mode>hi2"
4517 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4518 (set (match_operand:HI 0 "nonimmediate_operand" "")
4519 (subreg:HI (match_dup 2) 0))]
4520 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4521 "operands[2] = gen_reg_rtx (SImode);")
4523 ;; When SSE is available, it is always faster to use it!
4524 (define_insn "fix_trunc<mode>di_sse"
4525 [(set (match_operand:DI 0 "register_operand" "=r,r")
4526 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4527 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4528 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4529 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4530 [(set_attr "type" "sseicvt")
4531 (set_attr "mode" "<MODE>")
4532 (set_attr "athlon_decode" "double,vector")
4533 (set_attr "amdfam10_decode" "double,double")])
4535 (define_insn "fix_trunc<mode>si_sse"
4536 [(set (match_operand:SI 0 "register_operand" "=r,r")
4537 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4538 "SSE_FLOAT_MODE_P (<MODE>mode)
4539 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4540 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4541 [(set_attr "type" "sseicvt")
4542 (set_attr "mode" "<MODE>")
4543 (set_attr "athlon_decode" "double,vector")
4544 (set_attr "amdfam10_decode" "double,double")])
4546 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4548 [(set (match_operand:MODEF 0 "register_operand" "")
4549 (match_operand:MODEF 1 "memory_operand" ""))
4550 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4551 (fix:SSEMODEI24 (match_dup 0)))]
4552 "TARGET_SHORTEN_X87_SSE
4553 && peep2_reg_dead_p (2, operands[0])"
4554 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4557 ;; Avoid vector decoded forms of the instruction.
4559 [(match_scratch:DF 2 "Y2")
4560 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4561 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4562 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4563 [(set (match_dup 2) (match_dup 1))
4564 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4568 [(match_scratch:SF 2 "x")
4569 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4570 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4571 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4572 [(set (match_dup 2) (match_dup 1))
4573 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4576 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4577 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4578 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4579 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4581 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4582 && (TARGET_64BIT || <MODE>mode != DImode))
4584 && !(reload_completed || reload_in_progress)"
4589 if (memory_operand (operands[0], VOIDmode))
4590 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4593 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4594 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4600 [(set_attr "type" "fisttp")
4601 (set_attr "mode" "<MODE>")])
4603 (define_insn "fix_trunc<mode>_i387_fisttp"
4604 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4605 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4606 (clobber (match_scratch:XF 2 "=&1f"))]
4607 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4609 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4610 && (TARGET_64BIT || <MODE>mode != DImode))
4611 && TARGET_SSE_MATH)"
4612 "* return output_fix_trunc (insn, operands, 1);"
4613 [(set_attr "type" "fisttp")
4614 (set_attr "mode" "<MODE>")])
4616 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4617 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4618 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4619 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4620 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4621 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4623 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4624 && (TARGET_64BIT || <MODE>mode != DImode))
4625 && TARGET_SSE_MATH)"
4627 [(set_attr "type" "fisttp")
4628 (set_attr "mode" "<MODE>")])
4631 [(set (match_operand:X87MODEI 0 "register_operand" "")
4632 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4633 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4634 (clobber (match_scratch 3 ""))]
4636 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4637 (clobber (match_dup 3))])
4638 (set (match_dup 0) (match_dup 2))]
4642 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4643 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4644 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4645 (clobber (match_scratch 3 ""))]
4647 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4648 (clobber (match_dup 3))])]
4651 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4652 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4653 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4654 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4655 ;; function in i386.c.
4656 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4657 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4658 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4659 (clobber (reg:CC FLAGS_REG))]
4660 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4662 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4663 && (TARGET_64BIT || <MODE>mode != DImode))
4664 && !(reload_completed || reload_in_progress)"
4669 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4671 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4672 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4673 if (memory_operand (operands[0], VOIDmode))
4674 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4675 operands[2], operands[3]));
4678 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4679 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4680 operands[2], operands[3],
4685 [(set_attr "type" "fistp")
4686 (set_attr "i387_cw" "trunc")
4687 (set_attr "mode" "<MODE>")])
4689 (define_insn "fix_truncdi_i387"
4690 [(set (match_operand:DI 0 "memory_operand" "=m")
4691 (fix:DI (match_operand 1 "register_operand" "f")))
4692 (use (match_operand:HI 2 "memory_operand" "m"))
4693 (use (match_operand:HI 3 "memory_operand" "m"))
4694 (clobber (match_scratch:XF 4 "=&1f"))]
4695 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4697 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4698 "* return output_fix_trunc (insn, operands, 0);"
4699 [(set_attr "type" "fistp")
4700 (set_attr "i387_cw" "trunc")
4701 (set_attr "mode" "DI")])
4703 (define_insn "fix_truncdi_i387_with_temp"
4704 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4705 (fix:DI (match_operand 1 "register_operand" "f,f")))
4706 (use (match_operand:HI 2 "memory_operand" "m,m"))
4707 (use (match_operand:HI 3 "memory_operand" "m,m"))
4708 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4709 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4710 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4712 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4714 [(set_attr "type" "fistp")
4715 (set_attr "i387_cw" "trunc")
4716 (set_attr "mode" "DI")])
4719 [(set (match_operand:DI 0 "register_operand" "")
4720 (fix:DI (match_operand 1 "register_operand" "")))
4721 (use (match_operand:HI 2 "memory_operand" ""))
4722 (use (match_operand:HI 3 "memory_operand" ""))
4723 (clobber (match_operand:DI 4 "memory_operand" ""))
4724 (clobber (match_scratch 5 ""))]
4726 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4729 (clobber (match_dup 5))])
4730 (set (match_dup 0) (match_dup 4))]
4734 [(set (match_operand:DI 0 "memory_operand" "")
4735 (fix:DI (match_operand 1 "register_operand" "")))
4736 (use (match_operand:HI 2 "memory_operand" ""))
4737 (use (match_operand:HI 3 "memory_operand" ""))
4738 (clobber (match_operand:DI 4 "memory_operand" ""))
4739 (clobber (match_scratch 5 ""))]
4741 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4744 (clobber (match_dup 5))])]
4747 (define_insn "fix_trunc<mode>_i387"
4748 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4749 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4750 (use (match_operand:HI 2 "memory_operand" "m"))
4751 (use (match_operand:HI 3 "memory_operand" "m"))]
4752 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4754 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4755 "* return output_fix_trunc (insn, operands, 0);"
4756 [(set_attr "type" "fistp")
4757 (set_attr "i387_cw" "trunc")
4758 (set_attr "mode" "<MODE>")])
4760 (define_insn "fix_trunc<mode>_i387_with_temp"
4761 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4762 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4763 (use (match_operand:HI 2 "memory_operand" "m,m"))
4764 (use (match_operand:HI 3 "memory_operand" "m,m"))
4765 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4766 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4768 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4770 [(set_attr "type" "fistp")
4771 (set_attr "i387_cw" "trunc")
4772 (set_attr "mode" "<MODE>")])
4775 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4776 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4777 (use (match_operand:HI 2 "memory_operand" ""))
4778 (use (match_operand:HI 3 "memory_operand" ""))
4779 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4781 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4783 (use (match_dup 3))])
4784 (set (match_dup 0) (match_dup 4))]
4788 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4789 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4790 (use (match_operand:HI 2 "memory_operand" ""))
4791 (use (match_operand:HI 3 "memory_operand" ""))
4792 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4794 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4796 (use (match_dup 3))])]
4799 (define_insn "x86_fnstcw_1"
4800 [(set (match_operand:HI 0 "memory_operand" "=m")
4801 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4804 [(set_attr "length" "2")
4805 (set_attr "mode" "HI")
4806 (set_attr "unit" "i387")])
4808 (define_insn "x86_fldcw_1"
4809 [(set (reg:HI FPCR_REG)
4810 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4813 [(set_attr "length" "2")
4814 (set_attr "mode" "HI")
4815 (set_attr "unit" "i387")
4816 (set_attr "athlon_decode" "vector")
4817 (set_attr "amdfam10_decode" "vector")])
4819 ;; Conversion between fixed point and floating point.
4821 ;; Even though we only accept memory inputs, the backend _really_
4822 ;; wants to be able to do this between registers.
4824 (define_expand "floathi<mode>2"
4825 [(set (match_operand:X87MODEF 0 "register_operand" "")
4826 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4828 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4829 || TARGET_MIX_SSE_I387)"
4832 ;; Pre-reload splitter to add memory clobber to the pattern.
4833 (define_insn_and_split "*floathi<mode>2_1"
4834 [(set (match_operand:X87MODEF 0 "register_operand" "")
4835 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4838 || TARGET_MIX_SSE_I387)
4839 && !(reload_completed || reload_in_progress)"
4842 [(parallel [(set (match_dup 0)
4843 (float:X87MODEF (match_dup 1)))
4844 (clobber (match_dup 2))])]
4845 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4847 (define_insn "*floathi<mode>2_i387_with_temp"
4848 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4849 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4850 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4852 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4853 || TARGET_MIX_SSE_I387)"
4855 [(set_attr "type" "fmov,multi")
4856 (set_attr "mode" "<MODE>")
4857 (set_attr "unit" "*,i387")
4858 (set_attr "fp_int_src" "true")])
4860 (define_insn "*floathi<mode>2_i387"
4861 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4862 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4865 || TARGET_MIX_SSE_I387)"
4867 [(set_attr "type" "fmov")
4868 (set_attr "mode" "<MODE>")
4869 (set_attr "fp_int_src" "true")])
4872 [(set (match_operand:X87MODEF 0 "register_operand" "")
4873 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4874 (clobber (match_operand:HI 2 "memory_operand" ""))]
4876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4877 || TARGET_MIX_SSE_I387)
4878 && reload_completed"
4879 [(set (match_dup 2) (match_dup 1))
4880 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4884 [(set (match_operand:X87MODEF 0 "register_operand" "")
4885 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4886 (clobber (match_operand:HI 2 "memory_operand" ""))]
4888 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4889 || TARGET_MIX_SSE_I387)
4890 && reload_completed"
4891 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4894 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4895 [(set (match_operand:X87MODEF 0 "register_operand" "")
4897 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4899 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4900 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4903 ;; Pre-reload splitter to add memory clobber to the pattern.
4904 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4905 [(set (match_operand:X87MODEF 0 "register_operand" "")
4906 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4908 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4909 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4910 || TARGET_MIX_SSE_I387))
4911 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4912 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4913 && ((<SSEMODEI24:MODE>mode == SImode
4914 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4915 && flag_trapping_math)
4916 || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4917 && !(reload_completed || reload_in_progress)"
4920 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4921 (clobber (match_dup 2))])]
4922 "operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);")
4924 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4925 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4927 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4928 (clobber (match_operand:SI 2 "memory_operand" "=m,m,m,m,m"))]
4929 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4930 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4932 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4933 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4934 (set_attr "unit" "*,i387,*,*,*")
4935 (set_attr "athlon_decode" "*,*,double,direct,double")
4936 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4937 (set_attr "fp_int_src" "true")])
4939 (define_insn "*floatsi<mode>2_vector_mixed"
4940 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4941 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4942 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4943 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4947 [(set_attr "type" "fmov,sseicvt")
4948 (set_attr "mode" "<MODE>,<ssevecmode>")
4949 (set_attr "unit" "i387,*")
4950 (set_attr "athlon_decode" "*,direct")
4951 (set_attr "amdfam10_decode" "*,double")
4952 (set_attr "fp_int_src" "true")])
4954 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4955 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4957 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4958 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m,m,m"))]
4959 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4960 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4962 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4963 (set_attr "mode" "<MODEF:MODE>")
4964 (set_attr "unit" "*,i387,*,*")
4965 (set_attr "athlon_decode" "*,*,double,direct")
4966 (set_attr "amdfam10_decode" "*,*,vector,double")
4967 (set_attr "fp_int_src" "true")])
4970 [(set (match_operand:MODEF 0 "register_operand" "")
4971 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4972 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4973 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4974 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4975 && TARGET_INTER_UNIT_CONVERSIONS
4977 && (SSE_REG_P (operands[0])
4978 || (GET_CODE (operands[0]) == SUBREG
4979 && SSE_REG_P (operands[0])))"
4980 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
4984 [(set (match_operand:MODEF 0 "register_operand" "")
4985 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4986 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4987 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4988 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4989 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
4991 && (SSE_REG_P (operands[0])
4992 || (GET_CODE (operands[0]) == SUBREG
4993 && SSE_REG_P (operands[0])))"
4994 [(set (match_dup 2) (match_dup 1))
4995 (set (match_dup 0) (float:MODEF (match_dup 2)))]
4998 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
4999 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5001 (match_operand:SSEMODEI24 1 "register_operand" "m,r,m")))]
5002 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5003 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5004 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5007 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5008 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5009 [(set_attr "type" "fmov,sseicvt,sseicvt")
5010 (set_attr "mode" "<MODEF:MODE>")
5011 (set_attr "unit" "i387,*,*")
5012 (set_attr "athlon_decode" "*,double,direct")
5013 (set_attr "amdfam10_decode" "*,vector,double")
5014 (set_attr "fp_int_src" "true")])
5016 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5017 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5019 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5020 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5021 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5022 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5025 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5026 [(set_attr "type" "fmov,sseicvt")
5027 (set_attr "mode" "<MODEF:MODE>")
5028 (set_attr "athlon_decode" "*,direct")
5029 (set_attr "amdfam10_decode" "*,double")
5030 (set_attr "fp_int_src" "true")])
5032 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5033 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5035 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5036 (clobber (match_operand:SI 2 "memory_operand" "=m,m,m"))]
5037 "TARGET_SSE2 && TARGET_SSE_MATH
5038 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5040 [(set_attr "type" "sseicvt")
5041 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5042 (set_attr "athlon_decode" "double,direct,double")
5043 (set_attr "amdfam10_decode" "vector,double,double")
5044 (set_attr "fp_int_src" "true")])
5046 (define_insn "*floatsi<mode>2_vector_sse"
5047 [(set (match_operand:MODEF 0 "register_operand" "=x")
5048 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5049 "TARGET_SSE2 && TARGET_SSE_MATH
5050 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5052 [(set_attr "type" "sseicvt")
5053 (set_attr "mode" "<MODE>")
5054 (set_attr "athlon_decode" "direct")
5055 (set_attr "amdfam10_decode" "double")
5056 (set_attr "fp_int_src" "true")])
5059 [(set (match_operand:MODEF 0 "register_operand" "")
5060 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5061 (clobber (match_operand:SI 2 "memory_operand" ""))]
5062 "TARGET_SSE2 && TARGET_SSE_MATH
5063 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5065 && (SSE_REG_P (operands[0])
5066 || (GET_CODE (operands[0]) == SUBREG
5067 && SSE_REG_P (operands[0])))"
5070 rtx op1 = operands[1];
5072 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5074 if (GET_CODE (op1) == SUBREG)
5075 op1 = SUBREG_REG (op1);
5077 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5079 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5080 emit_insn (gen_sse2_loadld (operands[4],
5081 CONST0_RTX (V4SImode), operands[1]));
5083 /* We can ignore possible trapping value in the
5084 high part of SSE register for non-trapping math. */
5085 else if (SSE_REG_P (op1) && !flag_trapping_math)
5086 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5089 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5090 emit_move_insn (operands[2], operands[1]);
5091 emit_insn (gen_sse2_loadld (operands[4],
5092 CONST0_RTX (V4SImode), operands[2]));
5095 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5100 [(set (match_operand:MODEF 0 "register_operand" "")
5101 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5102 (clobber (match_operand:SI 2 "memory_operand" ""))]
5103 "TARGET_SSE2 && TARGET_SSE_MATH
5104 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5106 && (SSE_REG_P (operands[0])
5107 || (GET_CODE (operands[0]) == SUBREG
5108 && SSE_REG_P (operands[0])))"
5111 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5113 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5115 emit_insn (gen_sse2_loadld (operands[4],
5116 CONST0_RTX (V4SImode), operands[1]));
5118 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5123 [(set (match_operand:MODEF 0 "register_operand" "")
5124 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5125 "TARGET_SSE2 && TARGET_SSE_MATH
5126 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5128 && (SSE_REG_P (operands[0])
5129 || (GET_CODE (operands[0]) == SUBREG
5130 && SSE_REG_P (operands[0])))"
5133 rtx op1 = operands[1];
5135 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5137 if (GET_CODE (op1) == SUBREG)
5138 op1 = SUBREG_REG (op1);
5140 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5142 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5143 emit_insn (gen_sse2_loadld (operands[4],
5144 CONST0_RTX (V4SImode), operands[1]));
5146 /* We can ignore possible trapping value in the
5147 high part of SSE register for non-trapping math. */
5148 else if (SSE_REG_P (op1) && !flag_trapping_math)
5149 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5155 [(set (match_operand:MODEF 0 "register_operand" "")
5156 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5157 "TARGET_SSE2 && TARGET_SSE_MATH
5158 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5160 && (SSE_REG_P (operands[0])
5161 || (GET_CODE (operands[0]) == SUBREG
5162 && SSE_REG_P (operands[0])))"
5165 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5167 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5169 emit_insn (gen_sse2_loadld (operands[4],
5170 CONST0_RTX (V4SImode), operands[1]));
5172 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5176 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5177 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5179 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5180 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m"))]
5181 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5182 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5184 [(set_attr "type" "sseicvt")
5185 (set_attr "mode" "<MODEF:MODE>")
5186 (set_attr "athlon_decode" "double,direct")
5187 (set_attr "amdfam10_decode" "vector,double")
5188 (set_attr "fp_int_src" "true")])
5190 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5191 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5193 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5194 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5195 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5196 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5198 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5199 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5200 [(set_attr "type" "sseicvt")
5201 (set_attr "mode" "<MODEF:MODE>")
5202 (set_attr "athlon_decode" "double,direct")
5203 (set_attr "amdfam10_decode" "vector,double")
5204 (set_attr "fp_int_src" "true")])
5207 [(set (match_operand:MODEF 0 "register_operand" "")
5208 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5209 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5210 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5211 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5212 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5214 && (SSE_REG_P (operands[0])
5215 || (GET_CODE (operands[0]) == SUBREG
5216 && SSE_REG_P (operands[0])))"
5217 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5220 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5221 [(set (match_operand:MODEF 0 "register_operand" "=x")
5223 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5224 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5225 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5226 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5227 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5228 [(set_attr "type" "sseicvt")
5229 (set_attr "mode" "<MODEF:MODE>")
5230 (set_attr "athlon_decode" "direct")
5231 (set_attr "amdfam10_decode" "double")
5232 (set_attr "fp_int_src" "true")])
5235 [(set (match_operand:MODEF 0 "register_operand" "")
5236 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5237 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5238 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5239 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5240 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5242 && (SSE_REG_P (operands[0])
5243 || (GET_CODE (operands[0]) == SUBREG
5244 && SSE_REG_P (operands[0])))"
5245 [(set (match_dup 2) (match_dup 1))
5246 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5250 [(set (match_operand:MODEF 0 "register_operand" "")
5251 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5252 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5253 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5254 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5256 && (SSE_REG_P (operands[0])
5257 || (GET_CODE (operands[0]) == SUBREG
5258 && SSE_REG_P (operands[0])))"
5259 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5262 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5263 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5265 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5266 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m"))]
5271 [(set_attr "type" "fmov,multi")
5272 (set_attr "mode" "<X87MODEF:MODE>")
5273 (set_attr "unit" "*,i387")
5274 (set_attr "fp_int_src" "true")])
5276 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5277 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5279 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5282 [(set_attr "type" "fmov")
5283 (set_attr "mode" "<X87MODEF:MODE>")
5284 (set_attr "fp_int_src" "true")])
5287 [(set (match_operand:X87MODEF 0 "register_operand" "")
5288 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5289 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5292 && FP_REG_P (operands[0])"
5293 [(set (match_dup 2) (match_dup 1))
5294 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5298 [(set (match_operand:X87MODEF 0 "register_operand" "")
5299 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5300 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5303 && FP_REG_P (operands[0])"
5304 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5307 ;; Avoid store forwarding (partial memory) stall penalty by extending
5308 ;; SImode value to DImode through XMM register instead of pushing two
5309 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5310 ;; targets benefit from this optimization. Also note that fild
5311 ;; loads from memory only.
5313 (define_insn "*floatunssi<mode>2_1"
5314 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5315 (unsigned_float:X87MODEF
5316 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5317 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5318 (clobber (match_scratch:SI 3 "=X,x"))]
5320 && TARGET_80387 && TARGET_SSE"
5322 [(set_attr "type" "multi")
5323 (set_attr "mode" "<MODE>")])
5326 [(set (match_operand:X87MODEF 0 "register_operand" "")
5327 (unsigned_float:X87MODEF
5328 (match_operand:SI 1 "register_operand" "")))
5329 (clobber (match_operand:DI 2 "memory_operand" ""))
5330 (clobber (match_scratch:SI 3 ""))]
5332 && TARGET_80387 && TARGET_SSE
5333 && reload_completed"
5334 [(set (match_dup 2) (match_dup 1))
5336 (float:X87MODEF (match_dup 2)))]
5337 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5340 [(set (match_operand:X87MODEF 0 "register_operand" "")
5341 (unsigned_float:X87MODEF
5342 (match_operand:SI 1 "memory_operand" "")))
5343 (clobber (match_operand:DI 2 "memory_operand" ""))
5344 (clobber (match_scratch:SI 3 ""))]
5346 && TARGET_80387 && TARGET_SSE
5347 && reload_completed"
5348 [(set (match_dup 2) (match_dup 3))
5350 (float:X87MODEF (match_dup 2)))]
5352 emit_move_insn (operands[3], operands[1]);
5353 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5356 (define_expand "floatunssi<mode>2"
5358 [(set (match_operand:X87MODEF 0 "register_operand" "")
5359 (unsigned_float:X87MODEF
5360 (match_operand:SI 1 "nonimmediate_operand" "")))
5361 (clobber (match_dup 2))
5362 (clobber (match_scratch:SI 3 ""))])]
5364 && ((TARGET_80387 && TARGET_SSE)
5365 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5367 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5369 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5374 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5375 operands[2] = assign_386_stack_local (DImode, slot);
5379 (define_expand "floatunsdisf2"
5380 [(use (match_operand:SF 0 "register_operand" ""))
5381 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5382 "TARGET_64BIT && TARGET_SSE_MATH"
5383 "x86_emit_floatuns (operands); DONE;")
5385 (define_expand "floatunsdidf2"
5386 [(use (match_operand:DF 0 "register_operand" ""))
5387 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5388 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5389 && TARGET_SSE2 && TARGET_SSE_MATH"
5392 x86_emit_floatuns (operands);
5394 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5400 ;; %%% splits for addditi3
5402 (define_expand "addti3"
5403 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5404 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5405 (match_operand:TI 2 "x86_64_general_operand" "")))
5406 (clobber (reg:CC FLAGS_REG))]
5408 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5410 (define_insn "*addti3_1"
5411 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5412 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5413 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5414 (clobber (reg:CC FLAGS_REG))]
5415 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5419 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5420 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5421 (match_operand:TI 2 "x86_64_general_operand" "")))
5422 (clobber (reg:CC FLAGS_REG))]
5423 "TARGET_64BIT && reload_completed"
5424 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5426 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5427 (parallel [(set (match_dup 3)
5428 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5431 (clobber (reg:CC FLAGS_REG))])]
5432 "split_ti (operands+0, 1, operands+0, operands+3);
5433 split_ti (operands+1, 1, operands+1, operands+4);
5434 split_ti (operands+2, 1, operands+2, operands+5);")
5436 ;; %%% splits for addsidi3
5437 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5438 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5439 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5441 (define_expand "adddi3"
5442 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5443 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5444 (match_operand:DI 2 "x86_64_general_operand" "")))
5445 (clobber (reg:CC FLAGS_REG))]
5447 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5449 (define_insn "*adddi3_1"
5450 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5451 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5452 (match_operand:DI 2 "general_operand" "roiF,riF")))
5453 (clobber (reg:CC FLAGS_REG))]
5454 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5458 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5459 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5460 (match_operand:DI 2 "general_operand" "")))
5461 (clobber (reg:CC FLAGS_REG))]
5462 "!TARGET_64BIT && reload_completed"
5463 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5465 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5466 (parallel [(set (match_dup 3)
5467 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5470 (clobber (reg:CC FLAGS_REG))])]
5471 "split_di (operands+0, 1, operands+0, operands+3);
5472 split_di (operands+1, 1, operands+1, operands+4);
5473 split_di (operands+2, 1, operands+2, operands+5);")
5475 (define_insn "adddi3_carry_rex64"
5476 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5477 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5478 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5479 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5480 (clobber (reg:CC FLAGS_REG))]
5481 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5482 "adc{q}\t{%2, %0|%0, %2}"
5483 [(set_attr "type" "alu")
5484 (set_attr "pent_pair" "pu")
5485 (set_attr "mode" "DI")])
5487 (define_insn "*adddi3_cc_rex64"
5488 [(set (reg:CC FLAGS_REG)
5489 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5490 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5492 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5493 (plus:DI (match_dup 1) (match_dup 2)))]
5494 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5495 "add{q}\t{%2, %0|%0, %2}"
5496 [(set_attr "type" "alu")
5497 (set_attr "mode" "DI")])
5499 (define_insn "*<addsub><mode>3_cc_overflow"
5500 [(set (reg:CCC FLAGS_REG)
5503 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5504 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5506 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5507 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5508 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5509 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5510 [(set_attr "type" "alu")
5511 (set_attr "mode" "<MODE>")])
5513 (define_insn "*add<mode>3_cconly_overflow"
5514 [(set (reg:CCC FLAGS_REG)
5516 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5517 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5519 (clobber (match_scratch:SWI 0 "=<r>"))]
5520 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5521 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5522 [(set_attr "type" "alu")
5523 (set_attr "mode" "<MODE>")])
5525 (define_insn "*sub<mode>3_cconly_overflow"
5526 [(set (reg:CCC FLAGS_REG)
5528 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5529 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5532 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5533 [(set_attr "type" "icmp")
5534 (set_attr "mode" "<MODE>")])
5536 (define_insn "*<addsub>si3_zext_cc_overflow"
5537 [(set (reg:CCC FLAGS_REG)
5539 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5540 (match_operand:SI 2 "general_operand" "g"))
5542 (set (match_operand:DI 0 "register_operand" "=r")
5543 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5544 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5545 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5546 [(set_attr "type" "alu")
5547 (set_attr "mode" "SI")])
5549 (define_insn "addqi3_carry"
5550 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5551 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5552 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5553 (match_operand:QI 2 "general_operand" "qi,qm")))
5554 (clobber (reg:CC FLAGS_REG))]
5555 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5556 "adc{b}\t{%2, %0|%0, %2}"
5557 [(set_attr "type" "alu")
5558 (set_attr "pent_pair" "pu")
5559 (set_attr "mode" "QI")])
5561 (define_insn "addhi3_carry"
5562 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5563 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5564 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5565 (match_operand:HI 2 "general_operand" "ri,rm")))
5566 (clobber (reg:CC FLAGS_REG))]
5567 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5568 "adc{w}\t{%2, %0|%0, %2}"
5569 [(set_attr "type" "alu")
5570 (set_attr "pent_pair" "pu")
5571 (set_attr "mode" "HI")])
5573 (define_insn "addsi3_carry"
5574 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5575 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5576 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5577 (match_operand:SI 2 "general_operand" "ri,rm")))
5578 (clobber (reg:CC FLAGS_REG))]
5579 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5580 "adc{l}\t{%2, %0|%0, %2}"
5581 [(set_attr "type" "alu")
5582 (set_attr "pent_pair" "pu")
5583 (set_attr "mode" "SI")])
5585 (define_insn "*addsi3_carry_zext"
5586 [(set (match_operand:DI 0 "register_operand" "=r")
5588 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5589 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5590 (match_operand:SI 2 "general_operand" "g"))))
5591 (clobber (reg:CC FLAGS_REG))]
5592 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5593 "adc{l}\t{%2, %k0|%k0, %2}"
5594 [(set_attr "type" "alu")
5595 (set_attr "pent_pair" "pu")
5596 (set_attr "mode" "SI")])
5598 (define_insn "*addsi3_cc"
5599 [(set (reg:CC FLAGS_REG)
5600 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5601 (match_operand:SI 2 "general_operand" "ri,rm")]
5603 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5604 (plus:SI (match_dup 1) (match_dup 2)))]
5605 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5606 "add{l}\t{%2, %0|%0, %2}"
5607 [(set_attr "type" "alu")
5608 (set_attr "mode" "SI")])
5610 (define_insn "addqi3_cc"
5611 [(set (reg:CC FLAGS_REG)
5612 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5613 (match_operand:QI 2 "general_operand" "qi,qm")]
5615 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5616 (plus:QI (match_dup 1) (match_dup 2)))]
5617 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5618 "add{b}\t{%2, %0|%0, %2}"
5619 [(set_attr "type" "alu")
5620 (set_attr "mode" "QI")])
5622 (define_expand "addsi3"
5623 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5624 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5625 (match_operand:SI 2 "general_operand" "")))
5626 (clobber (reg:CC FLAGS_REG))])]
5628 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5630 (define_insn "*lea_1"
5631 [(set (match_operand:SI 0 "register_operand" "=r")
5632 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5634 "lea{l}\t{%a1, %0|%0, %a1}"
5635 [(set_attr "type" "lea")
5636 (set_attr "mode" "SI")])
5638 (define_insn "*lea_1_rex64"
5639 [(set (match_operand:SI 0 "register_operand" "=r")
5640 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5642 "lea{l}\t{%a1, %0|%0, %a1}"
5643 [(set_attr "type" "lea")
5644 (set_attr "mode" "SI")])
5646 (define_insn "*lea_1_zext"
5647 [(set (match_operand:DI 0 "register_operand" "=r")
5649 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5651 "lea{l}\t{%a1, %k0|%k0, %a1}"
5652 [(set_attr "type" "lea")
5653 (set_attr "mode" "SI")])
5655 (define_insn "*lea_2_rex64"
5656 [(set (match_operand:DI 0 "register_operand" "=r")
5657 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5659 "lea{q}\t{%a1, %0|%0, %a1}"
5660 [(set_attr "type" "lea")
5661 (set_attr "mode" "DI")])
5663 ;; The lea patterns for non-Pmodes needs to be matched by several
5664 ;; insns converted to real lea by splitters.
5666 (define_insn_and_split "*lea_general_1"
5667 [(set (match_operand 0 "register_operand" "=r")
5668 (plus (plus (match_operand 1 "index_register_operand" "l")
5669 (match_operand 2 "register_operand" "r"))
5670 (match_operand 3 "immediate_operand" "i")))]
5671 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5672 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5673 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5674 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5675 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5676 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5677 || GET_MODE (operands[3]) == VOIDmode)"
5679 "&& reload_completed"
5683 operands[0] = gen_lowpart (SImode, operands[0]);
5684 operands[1] = gen_lowpart (Pmode, operands[1]);
5685 operands[2] = gen_lowpart (Pmode, operands[2]);
5686 operands[3] = gen_lowpart (Pmode, operands[3]);
5687 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5689 if (Pmode != SImode)
5690 pat = gen_rtx_SUBREG (SImode, pat, 0);
5691 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5694 [(set_attr "type" "lea")
5695 (set_attr "mode" "SI")])
5697 (define_insn_and_split "*lea_general_1_zext"
5698 [(set (match_operand:DI 0 "register_operand" "=r")
5700 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5701 (match_operand:SI 2 "register_operand" "r"))
5702 (match_operand:SI 3 "immediate_operand" "i"))))]
5705 "&& reload_completed"
5707 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5709 (match_dup 3)) 0)))]
5711 operands[1] = gen_lowpart (Pmode, operands[1]);
5712 operands[2] = gen_lowpart (Pmode, operands[2]);
5713 operands[3] = gen_lowpart (Pmode, operands[3]);
5715 [(set_attr "type" "lea")
5716 (set_attr "mode" "SI")])
5718 (define_insn_and_split "*lea_general_2"
5719 [(set (match_operand 0 "register_operand" "=r")
5720 (plus (mult (match_operand 1 "index_register_operand" "l")
5721 (match_operand 2 "const248_operand" "i"))
5722 (match_operand 3 "nonmemory_operand" "ri")))]
5723 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5724 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5725 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5726 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5727 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5728 || GET_MODE (operands[3]) == VOIDmode)"
5730 "&& reload_completed"
5734 operands[0] = gen_lowpart (SImode, operands[0]);
5735 operands[1] = gen_lowpart (Pmode, operands[1]);
5736 operands[3] = gen_lowpart (Pmode, operands[3]);
5737 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5739 if (Pmode != SImode)
5740 pat = gen_rtx_SUBREG (SImode, pat, 0);
5741 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5744 [(set_attr "type" "lea")
5745 (set_attr "mode" "SI")])
5747 (define_insn_and_split "*lea_general_2_zext"
5748 [(set (match_operand:DI 0 "register_operand" "=r")
5750 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5751 (match_operand:SI 2 "const248_operand" "n"))
5752 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5755 "&& reload_completed"
5757 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5759 (match_dup 3)) 0)))]
5761 operands[1] = gen_lowpart (Pmode, operands[1]);
5762 operands[3] = gen_lowpart (Pmode, operands[3]);
5764 [(set_attr "type" "lea")
5765 (set_attr "mode" "SI")])
5767 (define_insn_and_split "*lea_general_3"
5768 [(set (match_operand 0 "register_operand" "=r")
5769 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5770 (match_operand 2 "const248_operand" "i"))
5771 (match_operand 3 "register_operand" "r"))
5772 (match_operand 4 "immediate_operand" "i")))]
5773 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5774 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5775 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5776 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5777 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5779 "&& reload_completed"
5783 operands[0] = gen_lowpart (SImode, operands[0]);
5784 operands[1] = gen_lowpart (Pmode, operands[1]);
5785 operands[3] = gen_lowpart (Pmode, operands[3]);
5786 operands[4] = gen_lowpart (Pmode, operands[4]);
5787 pat = gen_rtx_PLUS (Pmode,
5788 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5792 if (Pmode != SImode)
5793 pat = gen_rtx_SUBREG (SImode, pat, 0);
5794 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5797 [(set_attr "type" "lea")
5798 (set_attr "mode" "SI")])
5800 (define_insn_and_split "*lea_general_3_zext"
5801 [(set (match_operand:DI 0 "register_operand" "=r")
5803 (plus:SI (plus:SI (mult:SI
5804 (match_operand:SI 1 "index_register_operand" "l")
5805 (match_operand:SI 2 "const248_operand" "n"))
5806 (match_operand:SI 3 "register_operand" "r"))
5807 (match_operand:SI 4 "immediate_operand" "i"))))]
5810 "&& reload_completed"
5812 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5815 (match_dup 4)) 0)))]
5817 operands[1] = gen_lowpart (Pmode, operands[1]);
5818 operands[3] = gen_lowpart (Pmode, operands[3]);
5819 operands[4] = gen_lowpart (Pmode, operands[4]);
5821 [(set_attr "type" "lea")
5822 (set_attr "mode" "SI")])
5824 (define_insn "*adddi_1_rex64"
5825 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5826 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5827 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5828 (clobber (reg:CC FLAGS_REG))]
5829 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5831 switch (get_attr_type (insn))
5834 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5835 return "lea{q}\t{%a2, %0|%0, %a2}";
5838 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5839 if (operands[2] == const1_rtx)
5840 return "inc{q}\t%0";
5843 gcc_assert (operands[2] == constm1_rtx);
5844 return "dec{q}\t%0";
5848 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5850 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5851 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5852 if (CONST_INT_P (operands[2])
5853 /* Avoid overflows. */
5854 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5855 && (INTVAL (operands[2]) == 128
5856 || (INTVAL (operands[2]) < 0
5857 && INTVAL (operands[2]) != -128)))
5859 operands[2] = GEN_INT (-INTVAL (operands[2]));
5860 return "sub{q}\t{%2, %0|%0, %2}";
5862 return "add{q}\t{%2, %0|%0, %2}";
5866 (cond [(eq_attr "alternative" "2")
5867 (const_string "lea")
5868 ; Current assemblers are broken and do not allow @GOTOFF in
5869 ; ought but a memory context.
5870 (match_operand:DI 2 "pic_symbolic_operand" "")
5871 (const_string "lea")
5872 (match_operand:DI 2 "incdec_operand" "")
5873 (const_string "incdec")
5875 (const_string "alu")))
5876 (set_attr "mode" "DI")])
5878 ;; Convert lea to the lea pattern to avoid flags dependency.
5880 [(set (match_operand:DI 0 "register_operand" "")
5881 (plus:DI (match_operand:DI 1 "register_operand" "")
5882 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5883 (clobber (reg:CC FLAGS_REG))]
5884 "TARGET_64BIT && reload_completed
5885 && true_regnum (operands[0]) != true_regnum (operands[1])"
5887 (plus:DI (match_dup 1)
5891 (define_insn "*adddi_2_rex64"
5892 [(set (reg FLAGS_REG)
5894 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5895 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5897 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5898 (plus:DI (match_dup 1) (match_dup 2)))]
5899 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5900 && ix86_binary_operator_ok (PLUS, DImode, operands)
5901 /* Current assemblers are broken and do not allow @GOTOFF in
5902 ought but a memory context. */
5903 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5905 switch (get_attr_type (insn))
5908 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5909 if (operands[2] == const1_rtx)
5910 return "inc{q}\t%0";
5913 gcc_assert (operands[2] == constm1_rtx);
5914 return "dec{q}\t%0";
5918 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5919 /* ???? We ought to handle there the 32bit case too
5920 - do we need new constraint? */
5921 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5922 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5923 if (CONST_INT_P (operands[2])
5924 /* Avoid overflows. */
5925 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5926 && (INTVAL (operands[2]) == 128
5927 || (INTVAL (operands[2]) < 0
5928 && INTVAL (operands[2]) != -128)))
5930 operands[2] = GEN_INT (-INTVAL (operands[2]));
5931 return "sub{q}\t{%2, %0|%0, %2}";
5933 return "add{q}\t{%2, %0|%0, %2}";
5937 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5938 (const_string "incdec")
5939 (const_string "alu")))
5940 (set_attr "mode" "DI")])
5942 (define_insn "*adddi_3_rex64"
5943 [(set (reg FLAGS_REG)
5944 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5945 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5946 (clobber (match_scratch:DI 0 "=r"))]
5948 && ix86_match_ccmode (insn, CCZmode)
5949 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5950 /* Current assemblers are broken and do not allow @GOTOFF in
5951 ought but a memory context. */
5952 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5954 switch (get_attr_type (insn))
5957 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5958 if (operands[2] == const1_rtx)
5959 return "inc{q}\t%0";
5962 gcc_assert (operands[2] == constm1_rtx);
5963 return "dec{q}\t%0";
5967 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5968 /* ???? We ought to handle there the 32bit case too
5969 - do we need new constraint? */
5970 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5972 if (CONST_INT_P (operands[2])
5973 /* Avoid overflows. */
5974 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5975 && (INTVAL (operands[2]) == 128
5976 || (INTVAL (operands[2]) < 0
5977 && INTVAL (operands[2]) != -128)))
5979 operands[2] = GEN_INT (-INTVAL (operands[2]));
5980 return "sub{q}\t{%2, %0|%0, %2}";
5982 return "add{q}\t{%2, %0|%0, %2}";
5986 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5987 (const_string "incdec")
5988 (const_string "alu")))
5989 (set_attr "mode" "DI")])
5991 ; For comparisons against 1, -1 and 128, we may generate better code
5992 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5993 ; is matched then. We can't accept general immediate, because for
5994 ; case of overflows, the result is messed up.
5995 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5997 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5998 ; only for comparisons not depending on it.
5999 (define_insn "*adddi_4_rex64"
6000 [(set (reg FLAGS_REG)
6001 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6002 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6003 (clobber (match_scratch:DI 0 "=rm"))]
6005 && ix86_match_ccmode (insn, CCGCmode)"
6007 switch (get_attr_type (insn))
6010 if (operands[2] == constm1_rtx)
6011 return "inc{q}\t%0";
6014 gcc_assert (operands[2] == const1_rtx);
6015 return "dec{q}\t%0";
6019 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6020 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6021 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6022 if ((INTVAL (operands[2]) == -128
6023 || (INTVAL (operands[2]) > 0
6024 && INTVAL (operands[2]) != 128))
6025 /* Avoid overflows. */
6026 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6027 return "sub{q}\t{%2, %0|%0, %2}";
6028 operands[2] = GEN_INT (-INTVAL (operands[2]));
6029 return "add{q}\t{%2, %0|%0, %2}";
6033 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6034 (const_string "incdec")
6035 (const_string "alu")))
6036 (set_attr "mode" "DI")])
6038 (define_insn "*adddi_5_rex64"
6039 [(set (reg FLAGS_REG)
6041 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6042 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6044 (clobber (match_scratch:DI 0 "=r"))]
6046 && ix86_match_ccmode (insn, CCGOCmode)
6047 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6048 /* Current assemblers are broken and do not allow @GOTOFF in
6049 ought but a memory context. */
6050 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6052 switch (get_attr_type (insn))
6055 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6056 if (operands[2] == const1_rtx)
6057 return "inc{q}\t%0";
6060 gcc_assert (operands[2] == constm1_rtx);
6061 return "dec{q}\t%0";
6065 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6066 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6067 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6068 if (CONST_INT_P (operands[2])
6069 /* Avoid overflows. */
6070 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6071 && (INTVAL (operands[2]) == 128
6072 || (INTVAL (operands[2]) < 0
6073 && INTVAL (operands[2]) != -128)))
6075 operands[2] = GEN_INT (-INTVAL (operands[2]));
6076 return "sub{q}\t{%2, %0|%0, %2}";
6078 return "add{q}\t{%2, %0|%0, %2}";
6082 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6083 (const_string "incdec")
6084 (const_string "alu")))
6085 (set_attr "mode" "DI")])
6088 (define_insn "*addsi_1"
6089 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6090 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6091 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6092 (clobber (reg:CC FLAGS_REG))]
6093 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6095 switch (get_attr_type (insn))
6098 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6099 return "lea{l}\t{%a2, %0|%0, %a2}";
6102 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6103 if (operands[2] == const1_rtx)
6104 return "inc{l}\t%0";
6107 gcc_assert (operands[2] == constm1_rtx);
6108 return "dec{l}\t%0";
6112 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6114 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6115 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6116 if (CONST_INT_P (operands[2])
6117 && (INTVAL (operands[2]) == 128
6118 || (INTVAL (operands[2]) < 0
6119 && INTVAL (operands[2]) != -128)))
6121 operands[2] = GEN_INT (-INTVAL (operands[2]));
6122 return "sub{l}\t{%2, %0|%0, %2}";
6124 return "add{l}\t{%2, %0|%0, %2}";
6128 (cond [(eq_attr "alternative" "2")
6129 (const_string "lea")
6130 ; Current assemblers are broken and do not allow @GOTOFF in
6131 ; ought but a memory context.
6132 (match_operand:SI 2 "pic_symbolic_operand" "")
6133 (const_string "lea")
6134 (match_operand:SI 2 "incdec_operand" "")
6135 (const_string "incdec")
6137 (const_string "alu")))
6138 (set_attr "mode" "SI")])
6140 ;; Convert lea to the lea pattern to avoid flags dependency.
6142 [(set (match_operand 0 "register_operand" "")
6143 (plus (match_operand 1 "register_operand" "")
6144 (match_operand 2 "nonmemory_operand" "")))
6145 (clobber (reg:CC FLAGS_REG))]
6147 && true_regnum (operands[0]) != true_regnum (operands[1])"
6151 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6152 may confuse gen_lowpart. */
6153 if (GET_MODE (operands[0]) != Pmode)
6155 operands[1] = gen_lowpart (Pmode, operands[1]);
6156 operands[2] = gen_lowpart (Pmode, operands[2]);
6158 operands[0] = gen_lowpart (SImode, operands[0]);
6159 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6160 if (Pmode != SImode)
6161 pat = gen_rtx_SUBREG (SImode, pat, 0);
6162 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6166 ;; It may seem that nonimmediate operand is proper one for operand 1.
6167 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6168 ;; we take care in ix86_binary_operator_ok to not allow two memory
6169 ;; operands so proper swapping will be done in reload. This allow
6170 ;; patterns constructed from addsi_1 to match.
6171 (define_insn "addsi_1_zext"
6172 [(set (match_operand:DI 0 "register_operand" "=r,r")
6174 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6175 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6176 (clobber (reg:CC FLAGS_REG))]
6177 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6179 switch (get_attr_type (insn))
6182 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6183 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6186 if (operands[2] == const1_rtx)
6187 return "inc{l}\t%k0";
6190 gcc_assert (operands[2] == constm1_rtx);
6191 return "dec{l}\t%k0";
6195 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6196 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6197 if (CONST_INT_P (operands[2])
6198 && (INTVAL (operands[2]) == 128
6199 || (INTVAL (operands[2]) < 0
6200 && INTVAL (operands[2]) != -128)))
6202 operands[2] = GEN_INT (-INTVAL (operands[2]));
6203 return "sub{l}\t{%2, %k0|%k0, %2}";
6205 return "add{l}\t{%2, %k0|%k0, %2}";
6209 (cond [(eq_attr "alternative" "1")
6210 (const_string "lea")
6211 ; Current assemblers are broken and do not allow @GOTOFF in
6212 ; ought but a memory context.
6213 (match_operand:SI 2 "pic_symbolic_operand" "")
6214 (const_string "lea")
6215 (match_operand:SI 2 "incdec_operand" "")
6216 (const_string "incdec")
6218 (const_string "alu")))
6219 (set_attr "mode" "SI")])
6221 ;; Convert lea to the lea pattern to avoid flags dependency.
6223 [(set (match_operand:DI 0 "register_operand" "")
6225 (plus:SI (match_operand:SI 1 "register_operand" "")
6226 (match_operand:SI 2 "nonmemory_operand" ""))))
6227 (clobber (reg:CC FLAGS_REG))]
6228 "TARGET_64BIT && reload_completed
6229 && true_regnum (operands[0]) != true_regnum (operands[1])"
6231 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6233 operands[1] = gen_lowpart (Pmode, operands[1]);
6234 operands[2] = gen_lowpart (Pmode, operands[2]);
6237 (define_insn "*addsi_2"
6238 [(set (reg FLAGS_REG)
6240 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6241 (match_operand:SI 2 "general_operand" "rmni,rni"))
6243 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6244 (plus:SI (match_dup 1) (match_dup 2)))]
6245 "ix86_match_ccmode (insn, CCGOCmode)
6246 && ix86_binary_operator_ok (PLUS, SImode, operands)
6247 /* Current assemblers are broken and do not allow @GOTOFF in
6248 ought but a memory context. */
6249 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6251 switch (get_attr_type (insn))
6254 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6255 if (operands[2] == const1_rtx)
6256 return "inc{l}\t%0";
6259 gcc_assert (operands[2] == constm1_rtx);
6260 return "dec{l}\t%0";
6264 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6265 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6266 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6267 if (CONST_INT_P (operands[2])
6268 && (INTVAL (operands[2]) == 128
6269 || (INTVAL (operands[2]) < 0
6270 && INTVAL (operands[2]) != -128)))
6272 operands[2] = GEN_INT (-INTVAL (operands[2]));
6273 return "sub{l}\t{%2, %0|%0, %2}";
6275 return "add{l}\t{%2, %0|%0, %2}";
6279 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6280 (const_string "incdec")
6281 (const_string "alu")))
6282 (set_attr "mode" "SI")])
6284 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6285 (define_insn "*addsi_2_zext"
6286 [(set (reg FLAGS_REG)
6288 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6289 (match_operand:SI 2 "general_operand" "rmni"))
6291 (set (match_operand:DI 0 "register_operand" "=r")
6292 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6293 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6294 && ix86_binary_operator_ok (PLUS, SImode, operands)
6295 /* Current assemblers are broken and do not allow @GOTOFF in
6296 ought but a memory context. */
6297 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6299 switch (get_attr_type (insn))
6302 if (operands[2] == const1_rtx)
6303 return "inc{l}\t%k0";
6306 gcc_assert (operands[2] == constm1_rtx);
6307 return "dec{l}\t%k0";
6311 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6312 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6313 if (CONST_INT_P (operands[2])
6314 && (INTVAL (operands[2]) == 128
6315 || (INTVAL (operands[2]) < 0
6316 && INTVAL (operands[2]) != -128)))
6318 operands[2] = GEN_INT (-INTVAL (operands[2]));
6319 return "sub{l}\t{%2, %k0|%k0, %2}";
6321 return "add{l}\t{%2, %k0|%k0, %2}";
6325 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6326 (const_string "incdec")
6327 (const_string "alu")))
6328 (set_attr "mode" "SI")])
6330 (define_insn "*addsi_3"
6331 [(set (reg FLAGS_REG)
6332 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6333 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6334 (clobber (match_scratch:SI 0 "=r"))]
6335 "ix86_match_ccmode (insn, CCZmode)
6336 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6337 /* Current assemblers are broken and do not allow @GOTOFF in
6338 ought but a memory context. */
6339 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6341 switch (get_attr_type (insn))
6344 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6345 if (operands[2] == const1_rtx)
6346 return "inc{l}\t%0";
6349 gcc_assert (operands[2] == constm1_rtx);
6350 return "dec{l}\t%0";
6354 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6355 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6356 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6357 if (CONST_INT_P (operands[2])
6358 && (INTVAL (operands[2]) == 128
6359 || (INTVAL (operands[2]) < 0
6360 && INTVAL (operands[2]) != -128)))
6362 operands[2] = GEN_INT (-INTVAL (operands[2]));
6363 return "sub{l}\t{%2, %0|%0, %2}";
6365 return "add{l}\t{%2, %0|%0, %2}";
6369 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6370 (const_string "incdec")
6371 (const_string "alu")))
6372 (set_attr "mode" "SI")])
6374 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6375 (define_insn "*addsi_3_zext"
6376 [(set (reg FLAGS_REG)
6377 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6378 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6379 (set (match_operand:DI 0 "register_operand" "=r")
6380 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6381 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6382 && ix86_binary_operator_ok (PLUS, SImode, operands)
6383 /* Current assemblers are broken and do not allow @GOTOFF in
6384 ought but a memory context. */
6385 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6387 switch (get_attr_type (insn))
6390 if (operands[2] == const1_rtx)
6391 return "inc{l}\t%k0";
6394 gcc_assert (operands[2] == constm1_rtx);
6395 return "dec{l}\t%k0";
6399 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6400 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6401 if (CONST_INT_P (operands[2])
6402 && (INTVAL (operands[2]) == 128
6403 || (INTVAL (operands[2]) < 0
6404 && INTVAL (operands[2]) != -128)))
6406 operands[2] = GEN_INT (-INTVAL (operands[2]));
6407 return "sub{l}\t{%2, %k0|%k0, %2}";
6409 return "add{l}\t{%2, %k0|%k0, %2}";
6413 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6414 (const_string "incdec")
6415 (const_string "alu")))
6416 (set_attr "mode" "SI")])
6418 ; For comparisons against 1, -1 and 128, we may generate better code
6419 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6420 ; is matched then. We can't accept general immediate, because for
6421 ; case of overflows, the result is messed up.
6422 ; This pattern also don't hold of 0x80000000, since the value overflows
6424 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6425 ; only for comparisons not depending on it.
6426 (define_insn "*addsi_4"
6427 [(set (reg FLAGS_REG)
6428 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6429 (match_operand:SI 2 "const_int_operand" "n")))
6430 (clobber (match_scratch:SI 0 "=rm"))]
6431 "ix86_match_ccmode (insn, CCGCmode)
6432 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6434 switch (get_attr_type (insn))
6437 if (operands[2] == constm1_rtx)
6438 return "inc{l}\t%0";
6441 gcc_assert (operands[2] == const1_rtx);
6442 return "dec{l}\t%0";
6446 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6447 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6448 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6449 if ((INTVAL (operands[2]) == -128
6450 || (INTVAL (operands[2]) > 0
6451 && INTVAL (operands[2]) != 128)))
6452 return "sub{l}\t{%2, %0|%0, %2}";
6453 operands[2] = GEN_INT (-INTVAL (operands[2]));
6454 return "add{l}\t{%2, %0|%0, %2}";
6458 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6459 (const_string "incdec")
6460 (const_string "alu")))
6461 (set_attr "mode" "SI")])
6463 (define_insn "*addsi_5"
6464 [(set (reg FLAGS_REG)
6466 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6467 (match_operand:SI 2 "general_operand" "rmni"))
6469 (clobber (match_scratch:SI 0 "=r"))]
6470 "ix86_match_ccmode (insn, CCGOCmode)
6471 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6472 /* Current assemblers are broken and do not allow @GOTOFF in
6473 ought but a memory context. */
6474 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6476 switch (get_attr_type (insn))
6479 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6480 if (operands[2] == const1_rtx)
6481 return "inc{l}\t%0";
6484 gcc_assert (operands[2] == constm1_rtx);
6485 return "dec{l}\t%0";
6489 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6490 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6491 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6492 if (CONST_INT_P (operands[2])
6493 && (INTVAL (operands[2]) == 128
6494 || (INTVAL (operands[2]) < 0
6495 && INTVAL (operands[2]) != -128)))
6497 operands[2] = GEN_INT (-INTVAL (operands[2]));
6498 return "sub{l}\t{%2, %0|%0, %2}";
6500 return "add{l}\t{%2, %0|%0, %2}";
6504 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6505 (const_string "incdec")
6506 (const_string "alu")))
6507 (set_attr "mode" "SI")])
6509 (define_expand "addhi3"
6510 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6511 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6512 (match_operand:HI 2 "general_operand" "")))
6513 (clobber (reg:CC FLAGS_REG))])]
6514 "TARGET_HIMODE_MATH"
6515 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6517 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6518 ;; type optimizations enabled by define-splits. This is not important
6519 ;; for PII, and in fact harmful because of partial register stalls.
6521 (define_insn "*addhi_1_lea"
6522 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6523 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6524 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6525 (clobber (reg:CC FLAGS_REG))]
6526 "!TARGET_PARTIAL_REG_STALL
6527 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6529 switch (get_attr_type (insn))
6534 if (operands[2] == const1_rtx)
6535 return "inc{w}\t%0";
6538 gcc_assert (operands[2] == constm1_rtx);
6539 return "dec{w}\t%0";
6543 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6544 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6545 if (CONST_INT_P (operands[2])
6546 && (INTVAL (operands[2]) == 128
6547 || (INTVAL (operands[2]) < 0
6548 && INTVAL (operands[2]) != -128)))
6550 operands[2] = GEN_INT (-INTVAL (operands[2]));
6551 return "sub{w}\t{%2, %0|%0, %2}";
6553 return "add{w}\t{%2, %0|%0, %2}";
6557 (if_then_else (eq_attr "alternative" "2")
6558 (const_string "lea")
6559 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6560 (const_string "incdec")
6561 (const_string "alu"))))
6562 (set_attr "mode" "HI,HI,SI")])
6564 (define_insn "*addhi_1"
6565 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6566 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6567 (match_operand:HI 2 "general_operand" "ri,rm")))
6568 (clobber (reg:CC FLAGS_REG))]
6569 "TARGET_PARTIAL_REG_STALL
6570 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6572 switch (get_attr_type (insn))
6575 if (operands[2] == const1_rtx)
6576 return "inc{w}\t%0";
6579 gcc_assert (operands[2] == constm1_rtx);
6580 return "dec{w}\t%0";
6584 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6585 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6586 if (CONST_INT_P (operands[2])
6587 && (INTVAL (operands[2]) == 128
6588 || (INTVAL (operands[2]) < 0
6589 && INTVAL (operands[2]) != -128)))
6591 operands[2] = GEN_INT (-INTVAL (operands[2]));
6592 return "sub{w}\t{%2, %0|%0, %2}";
6594 return "add{w}\t{%2, %0|%0, %2}";
6598 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6599 (const_string "incdec")
6600 (const_string "alu")))
6601 (set_attr "mode" "HI")])
6603 (define_insn "*addhi_2"
6604 [(set (reg FLAGS_REG)
6606 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6607 (match_operand:HI 2 "general_operand" "rmni,rni"))
6609 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6610 (plus:HI (match_dup 1) (match_dup 2)))]
6611 "ix86_match_ccmode (insn, CCGOCmode)
6612 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6614 switch (get_attr_type (insn))
6617 if (operands[2] == const1_rtx)
6618 return "inc{w}\t%0";
6621 gcc_assert (operands[2] == constm1_rtx);
6622 return "dec{w}\t%0";
6626 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6627 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6628 if (CONST_INT_P (operands[2])
6629 && (INTVAL (operands[2]) == 128
6630 || (INTVAL (operands[2]) < 0
6631 && INTVAL (operands[2]) != -128)))
6633 operands[2] = GEN_INT (-INTVAL (operands[2]));
6634 return "sub{w}\t{%2, %0|%0, %2}";
6636 return "add{w}\t{%2, %0|%0, %2}";
6640 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6641 (const_string "incdec")
6642 (const_string "alu")))
6643 (set_attr "mode" "HI")])
6645 (define_insn "*addhi_3"
6646 [(set (reg FLAGS_REG)
6647 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6648 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6649 (clobber (match_scratch:HI 0 "=r"))]
6650 "ix86_match_ccmode (insn, CCZmode)
6651 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6653 switch (get_attr_type (insn))
6656 if (operands[2] == const1_rtx)
6657 return "inc{w}\t%0";
6660 gcc_assert (operands[2] == constm1_rtx);
6661 return "dec{w}\t%0";
6665 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6666 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6667 if (CONST_INT_P (operands[2])
6668 && (INTVAL (operands[2]) == 128
6669 || (INTVAL (operands[2]) < 0
6670 && INTVAL (operands[2]) != -128)))
6672 operands[2] = GEN_INT (-INTVAL (operands[2]));
6673 return "sub{w}\t{%2, %0|%0, %2}";
6675 return "add{w}\t{%2, %0|%0, %2}";
6679 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6680 (const_string "incdec")
6681 (const_string "alu")))
6682 (set_attr "mode" "HI")])
6684 ; See comments above addsi_4 for details.
6685 (define_insn "*addhi_4"
6686 [(set (reg FLAGS_REG)
6687 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6688 (match_operand:HI 2 "const_int_operand" "n")))
6689 (clobber (match_scratch:HI 0 "=rm"))]
6690 "ix86_match_ccmode (insn, CCGCmode)
6691 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6693 switch (get_attr_type (insn))
6696 if (operands[2] == constm1_rtx)
6697 return "inc{w}\t%0";
6700 gcc_assert (operands[2] == const1_rtx);
6701 return "dec{w}\t%0";
6705 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6706 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6707 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6708 if ((INTVAL (operands[2]) == -128
6709 || (INTVAL (operands[2]) > 0
6710 && INTVAL (operands[2]) != 128)))
6711 return "sub{w}\t{%2, %0|%0, %2}";
6712 operands[2] = GEN_INT (-INTVAL (operands[2]));
6713 return "add{w}\t{%2, %0|%0, %2}";
6717 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6718 (const_string "incdec")
6719 (const_string "alu")))
6720 (set_attr "mode" "SI")])
6723 (define_insn "*addhi_5"
6724 [(set (reg FLAGS_REG)
6726 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6727 (match_operand:HI 2 "general_operand" "rmni"))
6729 (clobber (match_scratch:HI 0 "=r"))]
6730 "ix86_match_ccmode (insn, CCGOCmode)
6731 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6733 switch (get_attr_type (insn))
6736 if (operands[2] == const1_rtx)
6737 return "inc{w}\t%0";
6740 gcc_assert (operands[2] == constm1_rtx);
6741 return "dec{w}\t%0";
6745 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6746 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6747 if (CONST_INT_P (operands[2])
6748 && (INTVAL (operands[2]) == 128
6749 || (INTVAL (operands[2]) < 0
6750 && INTVAL (operands[2]) != -128)))
6752 operands[2] = GEN_INT (-INTVAL (operands[2]));
6753 return "sub{w}\t{%2, %0|%0, %2}";
6755 return "add{w}\t{%2, %0|%0, %2}";
6759 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6760 (const_string "incdec")
6761 (const_string "alu")))
6762 (set_attr "mode" "HI")])
6764 (define_expand "addqi3"
6765 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6766 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6767 (match_operand:QI 2 "general_operand" "")))
6768 (clobber (reg:CC FLAGS_REG))])]
6769 "TARGET_QIMODE_MATH"
6770 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6772 ;; %%% Potential partial reg stall on alternative 2. What to do?
6773 (define_insn "*addqi_1_lea"
6774 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6775 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6776 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6777 (clobber (reg:CC FLAGS_REG))]
6778 "!TARGET_PARTIAL_REG_STALL
6779 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6781 int widen = (which_alternative == 2);
6782 switch (get_attr_type (insn))
6787 if (operands[2] == const1_rtx)
6788 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6791 gcc_assert (operands[2] == constm1_rtx);
6792 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6796 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6797 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6798 if (CONST_INT_P (operands[2])
6799 && (INTVAL (operands[2]) == 128
6800 || (INTVAL (operands[2]) < 0
6801 && INTVAL (operands[2]) != -128)))
6803 operands[2] = GEN_INT (-INTVAL (operands[2]));
6805 return "sub{l}\t{%2, %k0|%k0, %2}";
6807 return "sub{b}\t{%2, %0|%0, %2}";
6810 return "add{l}\t{%k2, %k0|%k0, %k2}";
6812 return "add{b}\t{%2, %0|%0, %2}";
6816 (if_then_else (eq_attr "alternative" "3")
6817 (const_string "lea")
6818 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6819 (const_string "incdec")
6820 (const_string "alu"))))
6821 (set_attr "mode" "QI,QI,SI,SI")])
6823 (define_insn "*addqi_1"
6824 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6825 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6826 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6827 (clobber (reg:CC FLAGS_REG))]
6828 "TARGET_PARTIAL_REG_STALL
6829 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6831 int widen = (which_alternative == 2);
6832 switch (get_attr_type (insn))
6835 if (operands[2] == const1_rtx)
6836 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6839 gcc_assert (operands[2] == constm1_rtx);
6840 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6844 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6845 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6846 if (CONST_INT_P (operands[2])
6847 && (INTVAL (operands[2]) == 128
6848 || (INTVAL (operands[2]) < 0
6849 && INTVAL (operands[2]) != -128)))
6851 operands[2] = GEN_INT (-INTVAL (operands[2]));
6853 return "sub{l}\t{%2, %k0|%k0, %2}";
6855 return "sub{b}\t{%2, %0|%0, %2}";
6858 return "add{l}\t{%k2, %k0|%k0, %k2}";
6860 return "add{b}\t{%2, %0|%0, %2}";
6864 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6865 (const_string "incdec")
6866 (const_string "alu")))
6867 (set_attr "mode" "QI,QI,SI")])
6869 (define_insn "*addqi_1_slp"
6870 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6871 (plus:QI (match_dup 0)
6872 (match_operand:QI 1 "general_operand" "qn,qnm")))
6873 (clobber (reg:CC FLAGS_REG))]
6874 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6875 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6877 switch (get_attr_type (insn))
6880 if (operands[1] == const1_rtx)
6881 return "inc{b}\t%0";
6884 gcc_assert (operands[1] == constm1_rtx);
6885 return "dec{b}\t%0";
6889 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6890 if (CONST_INT_P (operands[1])
6891 && INTVAL (operands[1]) < 0)
6893 operands[1] = GEN_INT (-INTVAL (operands[1]));
6894 return "sub{b}\t{%1, %0|%0, %1}";
6896 return "add{b}\t{%1, %0|%0, %1}";
6900 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6901 (const_string "incdec")
6902 (const_string "alu1")))
6903 (set (attr "memory")
6904 (if_then_else (match_operand 1 "memory_operand" "")
6905 (const_string "load")
6906 (const_string "none")))
6907 (set_attr "mode" "QI")])
6909 (define_insn "*addqi_2"
6910 [(set (reg FLAGS_REG)
6912 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6913 (match_operand:QI 2 "general_operand" "qmni,qni"))
6915 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6916 (plus:QI (match_dup 1) (match_dup 2)))]
6917 "ix86_match_ccmode (insn, CCGOCmode)
6918 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6920 switch (get_attr_type (insn))
6923 if (operands[2] == const1_rtx)
6924 return "inc{b}\t%0";
6927 gcc_assert (operands[2] == constm1_rtx
6928 || (CONST_INT_P (operands[2])
6929 && INTVAL (operands[2]) == 255));
6930 return "dec{b}\t%0";
6934 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6935 if (CONST_INT_P (operands[2])
6936 && INTVAL (operands[2]) < 0)
6938 operands[2] = GEN_INT (-INTVAL (operands[2]));
6939 return "sub{b}\t{%2, %0|%0, %2}";
6941 return "add{b}\t{%2, %0|%0, %2}";
6945 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6946 (const_string "incdec")
6947 (const_string "alu")))
6948 (set_attr "mode" "QI")])
6950 (define_insn "*addqi_3"
6951 [(set (reg FLAGS_REG)
6952 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6953 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6954 (clobber (match_scratch:QI 0 "=q"))]
6955 "ix86_match_ccmode (insn, CCZmode)
6956 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6958 switch (get_attr_type (insn))
6961 if (operands[2] == const1_rtx)
6962 return "inc{b}\t%0";
6965 gcc_assert (operands[2] == constm1_rtx
6966 || (CONST_INT_P (operands[2])
6967 && INTVAL (operands[2]) == 255));
6968 return "dec{b}\t%0";
6972 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6973 if (CONST_INT_P (operands[2])
6974 && INTVAL (operands[2]) < 0)
6976 operands[2] = GEN_INT (-INTVAL (operands[2]));
6977 return "sub{b}\t{%2, %0|%0, %2}";
6979 return "add{b}\t{%2, %0|%0, %2}";
6983 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6984 (const_string "incdec")
6985 (const_string "alu")))
6986 (set_attr "mode" "QI")])
6988 ; See comments above addsi_4 for details.
6989 (define_insn "*addqi_4"
6990 [(set (reg FLAGS_REG)
6991 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6992 (match_operand:QI 2 "const_int_operand" "n")))
6993 (clobber (match_scratch:QI 0 "=qm"))]
6994 "ix86_match_ccmode (insn, CCGCmode)
6995 && (INTVAL (operands[2]) & 0xff) != 0x80"
6997 switch (get_attr_type (insn))
7000 if (operands[2] == constm1_rtx
7001 || (CONST_INT_P (operands[2])
7002 && INTVAL (operands[2]) == 255))
7003 return "inc{b}\t%0";
7006 gcc_assert (operands[2] == const1_rtx);
7007 return "dec{b}\t%0";
7011 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7012 if (INTVAL (operands[2]) < 0)
7014 operands[2] = GEN_INT (-INTVAL (operands[2]));
7015 return "add{b}\t{%2, %0|%0, %2}";
7017 return "sub{b}\t{%2, %0|%0, %2}";
7021 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7022 (const_string "incdec")
7023 (const_string "alu")))
7024 (set_attr "mode" "QI")])
7027 (define_insn "*addqi_5"
7028 [(set (reg FLAGS_REG)
7030 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7031 (match_operand:QI 2 "general_operand" "qmni"))
7033 (clobber (match_scratch:QI 0 "=q"))]
7034 "ix86_match_ccmode (insn, CCGOCmode)
7035 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7037 switch (get_attr_type (insn))
7040 if (operands[2] == const1_rtx)
7041 return "inc{b}\t%0";
7044 gcc_assert (operands[2] == constm1_rtx
7045 || (CONST_INT_P (operands[2])
7046 && INTVAL (operands[2]) == 255));
7047 return "dec{b}\t%0";
7051 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7052 if (CONST_INT_P (operands[2])
7053 && INTVAL (operands[2]) < 0)
7055 operands[2] = GEN_INT (-INTVAL (operands[2]));
7056 return "sub{b}\t{%2, %0|%0, %2}";
7058 return "add{b}\t{%2, %0|%0, %2}";
7062 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7063 (const_string "incdec")
7064 (const_string "alu")))
7065 (set_attr "mode" "QI")])
7068 (define_insn "addqi_ext_1"
7069 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7074 (match_operand 1 "ext_register_operand" "0")
7077 (match_operand:QI 2 "general_operand" "Qmn")))
7078 (clobber (reg:CC FLAGS_REG))]
7081 switch (get_attr_type (insn))
7084 if (operands[2] == const1_rtx)
7085 return "inc{b}\t%h0";
7088 gcc_assert (operands[2] == constm1_rtx
7089 || (CONST_INT_P (operands[2])
7090 && INTVAL (operands[2]) == 255));
7091 return "dec{b}\t%h0";
7095 return "add{b}\t{%2, %h0|%h0, %2}";
7099 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7100 (const_string "incdec")
7101 (const_string "alu")))
7102 (set_attr "mode" "QI")])
7104 (define_insn "*addqi_ext_1_rex64"
7105 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7110 (match_operand 1 "ext_register_operand" "0")
7113 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7114 (clobber (reg:CC FLAGS_REG))]
7117 switch (get_attr_type (insn))
7120 if (operands[2] == const1_rtx)
7121 return "inc{b}\t%h0";
7124 gcc_assert (operands[2] == constm1_rtx
7125 || (CONST_INT_P (operands[2])
7126 && INTVAL (operands[2]) == 255));
7127 return "dec{b}\t%h0";
7131 return "add{b}\t{%2, %h0|%h0, %2}";
7135 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7136 (const_string "incdec")
7137 (const_string "alu")))
7138 (set_attr "mode" "QI")])
7140 (define_insn "*addqi_ext_2"
7141 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7146 (match_operand 1 "ext_register_operand" "%0")
7150 (match_operand 2 "ext_register_operand" "Q")
7153 (clobber (reg:CC FLAGS_REG))]
7155 "add{b}\t{%h2, %h0|%h0, %h2}"
7156 [(set_attr "type" "alu")
7157 (set_attr "mode" "QI")])
7159 ;; The patterns that match these are at the end of this file.
7161 (define_expand "addxf3"
7162 [(set (match_operand:XF 0 "register_operand" "")
7163 (plus:XF (match_operand:XF 1 "register_operand" "")
7164 (match_operand:XF 2 "register_operand" "")))]
7168 (define_expand "add<mode>3"
7169 [(set (match_operand:MODEF 0 "register_operand" "")
7170 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7171 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7172 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7175 ;; Subtract instructions
7177 ;; %%% splits for subditi3
7179 (define_expand "subti3"
7180 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7181 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7182 (match_operand:TI 2 "x86_64_general_operand" "")))
7183 (clobber (reg:CC FLAGS_REG))])]
7185 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7187 (define_insn "*subti3_1"
7188 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7189 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7190 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7191 (clobber (reg:CC FLAGS_REG))]
7192 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7196 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7197 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7198 (match_operand:TI 2 "x86_64_general_operand" "")))
7199 (clobber (reg:CC FLAGS_REG))]
7200 "TARGET_64BIT && reload_completed"
7201 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7202 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7203 (parallel [(set (match_dup 3)
7204 (minus:DI (match_dup 4)
7205 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7207 (clobber (reg:CC FLAGS_REG))])]
7208 "split_ti (operands+0, 1, operands+0, operands+3);
7209 split_ti (operands+1, 1, operands+1, operands+4);
7210 split_ti (operands+2, 1, operands+2, operands+5);")
7212 ;; %%% splits for subsidi3
7214 (define_expand "subdi3"
7215 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7216 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7217 (match_operand:DI 2 "x86_64_general_operand" "")))
7218 (clobber (reg:CC FLAGS_REG))])]
7220 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7222 (define_insn "*subdi3_1"
7223 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7224 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7225 (match_operand:DI 2 "general_operand" "roiF,riF")))
7226 (clobber (reg:CC FLAGS_REG))]
7227 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7231 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7232 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7233 (match_operand:DI 2 "general_operand" "")))
7234 (clobber (reg:CC FLAGS_REG))]
7235 "!TARGET_64BIT && reload_completed"
7236 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7237 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7238 (parallel [(set (match_dup 3)
7239 (minus:SI (match_dup 4)
7240 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7242 (clobber (reg:CC FLAGS_REG))])]
7243 "split_di (operands+0, 1, operands+0, operands+3);
7244 split_di (operands+1, 1, operands+1, operands+4);
7245 split_di (operands+2, 1, operands+2, operands+5);")
7247 (define_insn "subdi3_carry_rex64"
7248 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7249 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7250 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7251 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7252 (clobber (reg:CC FLAGS_REG))]
7253 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7254 "sbb{q}\t{%2, %0|%0, %2}"
7255 [(set_attr "type" "alu")
7256 (set_attr "pent_pair" "pu")
7257 (set_attr "mode" "DI")])
7259 (define_insn "*subdi_1_rex64"
7260 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7261 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7262 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7263 (clobber (reg:CC FLAGS_REG))]
7264 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7265 "sub{q}\t{%2, %0|%0, %2}"
7266 [(set_attr "type" "alu")
7267 (set_attr "mode" "DI")])
7269 (define_insn "*subdi_2_rex64"
7270 [(set (reg FLAGS_REG)
7272 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7273 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7275 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7276 (minus:DI (match_dup 1) (match_dup 2)))]
7277 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7278 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7279 "sub{q}\t{%2, %0|%0, %2}"
7280 [(set_attr "type" "alu")
7281 (set_attr "mode" "DI")])
7283 (define_insn "*subdi_3_rex63"
7284 [(set (reg FLAGS_REG)
7285 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7286 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7287 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7288 (minus:DI (match_dup 1) (match_dup 2)))]
7289 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7290 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7291 "sub{q}\t{%2, %0|%0, %2}"
7292 [(set_attr "type" "alu")
7293 (set_attr "mode" "DI")])
7295 (define_insn "subqi3_carry"
7296 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7297 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7298 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7299 (match_operand:QI 2 "general_operand" "qi,qm"))))
7300 (clobber (reg:CC FLAGS_REG))]
7301 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7302 "sbb{b}\t{%2, %0|%0, %2}"
7303 [(set_attr "type" "alu")
7304 (set_attr "pent_pair" "pu")
7305 (set_attr "mode" "QI")])
7307 (define_insn "subhi3_carry"
7308 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7309 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7310 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7311 (match_operand:HI 2 "general_operand" "ri,rm"))))
7312 (clobber (reg:CC FLAGS_REG))]
7313 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7314 "sbb{w}\t{%2, %0|%0, %2}"
7315 [(set_attr "type" "alu")
7316 (set_attr "pent_pair" "pu")
7317 (set_attr "mode" "HI")])
7319 (define_insn "subsi3_carry"
7320 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7321 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7322 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7323 (match_operand:SI 2 "general_operand" "ri,rm"))))
7324 (clobber (reg:CC FLAGS_REG))]
7325 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7326 "sbb{l}\t{%2, %0|%0, %2}"
7327 [(set_attr "type" "alu")
7328 (set_attr "pent_pair" "pu")
7329 (set_attr "mode" "SI")])
7331 (define_insn "subsi3_carry_zext"
7332 [(set (match_operand:DI 0 "register_operand" "=r")
7334 (minus:SI (match_operand:SI 1 "register_operand" "0")
7335 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7336 (match_operand:SI 2 "general_operand" "g")))))
7337 (clobber (reg:CC FLAGS_REG))]
7338 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7339 "sbb{l}\t{%2, %k0|%k0, %2}"
7340 [(set_attr "type" "alu")
7341 (set_attr "pent_pair" "pu")
7342 (set_attr "mode" "SI")])
7344 (define_expand "subsi3"
7345 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7346 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7347 (match_operand:SI 2 "general_operand" "")))
7348 (clobber (reg:CC FLAGS_REG))])]
7350 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7352 (define_insn "*subsi_1"
7353 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7354 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7355 (match_operand:SI 2 "general_operand" "ri,rm")))
7356 (clobber (reg:CC FLAGS_REG))]
7357 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7358 "sub{l}\t{%2, %0|%0, %2}"
7359 [(set_attr "type" "alu")
7360 (set_attr "mode" "SI")])
7362 (define_insn "*subsi_1_zext"
7363 [(set (match_operand:DI 0 "register_operand" "=r")
7365 (minus:SI (match_operand:SI 1 "register_operand" "0")
7366 (match_operand:SI 2 "general_operand" "g"))))
7367 (clobber (reg:CC FLAGS_REG))]
7368 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7369 "sub{l}\t{%2, %k0|%k0, %2}"
7370 [(set_attr "type" "alu")
7371 (set_attr "mode" "SI")])
7373 (define_insn "*subsi_2"
7374 [(set (reg FLAGS_REG)
7376 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7377 (match_operand:SI 2 "general_operand" "ri,rm"))
7379 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7380 (minus:SI (match_dup 1) (match_dup 2)))]
7381 "ix86_match_ccmode (insn, CCGOCmode)
7382 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7383 "sub{l}\t{%2, %0|%0, %2}"
7384 [(set_attr "type" "alu")
7385 (set_attr "mode" "SI")])
7387 (define_insn "*subsi_2_zext"
7388 [(set (reg FLAGS_REG)
7390 (minus:SI (match_operand:SI 1 "register_operand" "0")
7391 (match_operand:SI 2 "general_operand" "g"))
7393 (set (match_operand:DI 0 "register_operand" "=r")
7395 (minus:SI (match_dup 1)
7397 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7398 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7399 "sub{l}\t{%2, %k0|%k0, %2}"
7400 [(set_attr "type" "alu")
7401 (set_attr "mode" "SI")])
7403 (define_insn "*subsi_3"
7404 [(set (reg FLAGS_REG)
7405 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7406 (match_operand:SI 2 "general_operand" "ri,rm")))
7407 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7408 (minus:SI (match_dup 1) (match_dup 2)))]
7409 "ix86_match_ccmode (insn, CCmode)
7410 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7411 "sub{l}\t{%2, %0|%0, %2}"
7412 [(set_attr "type" "alu")
7413 (set_attr "mode" "SI")])
7415 (define_insn "*subsi_3_zext"
7416 [(set (reg FLAGS_REG)
7417 (compare (match_operand:SI 1 "register_operand" "0")
7418 (match_operand:SI 2 "general_operand" "g")))
7419 (set (match_operand:DI 0 "register_operand" "=r")
7421 (minus:SI (match_dup 1)
7423 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7424 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7425 "sub{l}\t{%2, %1|%1, %2}"
7426 [(set_attr "type" "alu")
7427 (set_attr "mode" "DI")])
7429 (define_expand "subhi3"
7430 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7431 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7432 (match_operand:HI 2 "general_operand" "")))
7433 (clobber (reg:CC FLAGS_REG))])]
7434 "TARGET_HIMODE_MATH"
7435 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7437 (define_insn "*subhi_1"
7438 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7439 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7440 (match_operand:HI 2 "general_operand" "ri,rm")))
7441 (clobber (reg:CC FLAGS_REG))]
7442 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7443 "sub{w}\t{%2, %0|%0, %2}"
7444 [(set_attr "type" "alu")
7445 (set_attr "mode" "HI")])
7447 (define_insn "*subhi_2"
7448 [(set (reg FLAGS_REG)
7450 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7451 (match_operand:HI 2 "general_operand" "ri,rm"))
7453 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7454 (minus:HI (match_dup 1) (match_dup 2)))]
7455 "ix86_match_ccmode (insn, CCGOCmode)
7456 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7457 "sub{w}\t{%2, %0|%0, %2}"
7458 [(set_attr "type" "alu")
7459 (set_attr "mode" "HI")])
7461 (define_insn "*subhi_3"
7462 [(set (reg FLAGS_REG)
7463 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7464 (match_operand:HI 2 "general_operand" "ri,rm")))
7465 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7466 (minus:HI (match_dup 1) (match_dup 2)))]
7467 "ix86_match_ccmode (insn, CCmode)
7468 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7469 "sub{w}\t{%2, %0|%0, %2}"
7470 [(set_attr "type" "alu")
7471 (set_attr "mode" "HI")])
7473 (define_expand "subqi3"
7474 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7475 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7476 (match_operand:QI 2 "general_operand" "")))
7477 (clobber (reg:CC FLAGS_REG))])]
7478 "TARGET_QIMODE_MATH"
7479 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7481 (define_insn "*subqi_1"
7482 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7483 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7484 (match_operand:QI 2 "general_operand" "qn,qmn")))
7485 (clobber (reg:CC FLAGS_REG))]
7486 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7487 "sub{b}\t{%2, %0|%0, %2}"
7488 [(set_attr "type" "alu")
7489 (set_attr "mode" "QI")])
7491 (define_insn "*subqi_1_slp"
7492 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7493 (minus:QI (match_dup 0)
7494 (match_operand:QI 1 "general_operand" "qn,qmn")))
7495 (clobber (reg:CC FLAGS_REG))]
7496 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7497 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7498 "sub{b}\t{%1, %0|%0, %1}"
7499 [(set_attr "type" "alu1")
7500 (set_attr "mode" "QI")])
7502 (define_insn "*subqi_2"
7503 [(set (reg FLAGS_REG)
7505 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7506 (match_operand:QI 2 "general_operand" "qi,qm"))
7508 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7509 (minus:HI (match_dup 1) (match_dup 2)))]
7510 "ix86_match_ccmode (insn, CCGOCmode)
7511 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7512 "sub{b}\t{%2, %0|%0, %2}"
7513 [(set_attr "type" "alu")
7514 (set_attr "mode" "QI")])
7516 (define_insn "*subqi_3"
7517 [(set (reg FLAGS_REG)
7518 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7519 (match_operand:QI 2 "general_operand" "qi,qm")))
7520 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7521 (minus:HI (match_dup 1) (match_dup 2)))]
7522 "ix86_match_ccmode (insn, CCmode)
7523 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7524 "sub{b}\t{%2, %0|%0, %2}"
7525 [(set_attr "type" "alu")
7526 (set_attr "mode" "QI")])
7528 ;; The patterns that match these are at the end of this file.
7530 (define_expand "subxf3"
7531 [(set (match_operand:XF 0 "register_operand" "")
7532 (minus:XF (match_operand:XF 1 "register_operand" "")
7533 (match_operand:XF 2 "register_operand" "")))]
7537 (define_expand "sub<mode>3"
7538 [(set (match_operand:MODEF 0 "register_operand" "")
7539 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7540 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7541 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7544 ;; Multiply instructions
7546 (define_expand "muldi3"
7547 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7548 (mult:DI (match_operand:DI 1 "register_operand" "")
7549 (match_operand:DI 2 "x86_64_general_operand" "")))
7550 (clobber (reg:CC FLAGS_REG))])]
7555 ;; IMUL reg64, reg64, imm8 Direct
7556 ;; IMUL reg64, mem64, imm8 VectorPath
7557 ;; IMUL reg64, reg64, imm32 Direct
7558 ;; IMUL reg64, mem64, imm32 VectorPath
7559 ;; IMUL reg64, reg64 Direct
7560 ;; IMUL reg64, mem64 Direct
7562 (define_insn "*muldi3_1_rex64"
7563 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7564 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7565 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7566 (clobber (reg:CC FLAGS_REG))]
7568 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7570 imul{q}\t{%2, %1, %0|%0, %1, %2}
7571 imul{q}\t{%2, %1, %0|%0, %1, %2}
7572 imul{q}\t{%2, %0|%0, %2}"
7573 [(set_attr "type" "imul")
7574 (set_attr "prefix_0f" "0,0,1")
7575 (set (attr "athlon_decode")
7576 (cond [(eq_attr "cpu" "athlon")
7577 (const_string "vector")
7578 (eq_attr "alternative" "1")
7579 (const_string "vector")
7580 (and (eq_attr "alternative" "2")
7581 (match_operand 1 "memory_operand" ""))
7582 (const_string "vector")]
7583 (const_string "direct")))
7584 (set (attr "amdfam10_decode")
7585 (cond [(and (eq_attr "alternative" "0,1")
7586 (match_operand 1 "memory_operand" ""))
7587 (const_string "vector")]
7588 (const_string "direct")))
7589 (set_attr "mode" "DI")])
7591 (define_expand "mulsi3"
7592 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7593 (mult:SI (match_operand:SI 1 "register_operand" "")
7594 (match_operand:SI 2 "general_operand" "")))
7595 (clobber (reg:CC FLAGS_REG))])]
7600 ;; IMUL reg32, reg32, imm8 Direct
7601 ;; IMUL reg32, mem32, imm8 VectorPath
7602 ;; IMUL reg32, reg32, imm32 Direct
7603 ;; IMUL reg32, mem32, imm32 VectorPath
7604 ;; IMUL reg32, reg32 Direct
7605 ;; IMUL reg32, mem32 Direct
7607 (define_insn "*mulsi3_1"
7608 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7609 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7610 (match_operand:SI 2 "general_operand" "K,i,mr")))
7611 (clobber (reg:CC FLAGS_REG))]
7612 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7614 imul{l}\t{%2, %1, %0|%0, %1, %2}
7615 imul{l}\t{%2, %1, %0|%0, %1, %2}
7616 imul{l}\t{%2, %0|%0, %2}"
7617 [(set_attr "type" "imul")
7618 (set_attr "prefix_0f" "0,0,1")
7619 (set (attr "athlon_decode")
7620 (cond [(eq_attr "cpu" "athlon")
7621 (const_string "vector")
7622 (eq_attr "alternative" "1")
7623 (const_string "vector")
7624 (and (eq_attr "alternative" "2")
7625 (match_operand 1 "memory_operand" ""))
7626 (const_string "vector")]
7627 (const_string "direct")))
7628 (set (attr "amdfam10_decode")
7629 (cond [(and (eq_attr "alternative" "0,1")
7630 (match_operand 1 "memory_operand" ""))
7631 (const_string "vector")]
7632 (const_string "direct")))
7633 (set_attr "mode" "SI")])
7635 (define_insn "*mulsi3_1_zext"
7636 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7638 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7639 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7640 (clobber (reg:CC FLAGS_REG))]
7642 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7644 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7645 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7646 imul{l}\t{%2, %k0|%k0, %2}"
7647 [(set_attr "type" "imul")
7648 (set_attr "prefix_0f" "0,0,1")
7649 (set (attr "athlon_decode")
7650 (cond [(eq_attr "cpu" "athlon")
7651 (const_string "vector")
7652 (eq_attr "alternative" "1")
7653 (const_string "vector")
7654 (and (eq_attr "alternative" "2")
7655 (match_operand 1 "memory_operand" ""))
7656 (const_string "vector")]
7657 (const_string "direct")))
7658 (set (attr "amdfam10_decode")
7659 (cond [(and (eq_attr "alternative" "0,1")
7660 (match_operand 1 "memory_operand" ""))
7661 (const_string "vector")]
7662 (const_string "direct")))
7663 (set_attr "mode" "SI")])
7665 (define_expand "mulhi3"
7666 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7667 (mult:HI (match_operand:HI 1 "register_operand" "")
7668 (match_operand:HI 2 "general_operand" "")))
7669 (clobber (reg:CC FLAGS_REG))])]
7670 "TARGET_HIMODE_MATH"
7674 ;; IMUL reg16, reg16, imm8 VectorPath
7675 ;; IMUL reg16, mem16, imm8 VectorPath
7676 ;; IMUL reg16, reg16, imm16 VectorPath
7677 ;; IMUL reg16, mem16, imm16 VectorPath
7678 ;; IMUL reg16, reg16 Direct
7679 ;; IMUL reg16, mem16 Direct
7680 (define_insn "*mulhi3_1"
7681 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7682 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7683 (match_operand:HI 2 "general_operand" "K,i,mr")))
7684 (clobber (reg:CC FLAGS_REG))]
7685 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7687 imul{w}\t{%2, %1, %0|%0, %1, %2}
7688 imul{w}\t{%2, %1, %0|%0, %1, %2}
7689 imul{w}\t{%2, %0|%0, %2}"
7690 [(set_attr "type" "imul")
7691 (set_attr "prefix_0f" "0,0,1")
7692 (set (attr "athlon_decode")
7693 (cond [(eq_attr "cpu" "athlon")
7694 (const_string "vector")
7695 (eq_attr "alternative" "1,2")
7696 (const_string "vector")]
7697 (const_string "direct")))
7698 (set (attr "amdfam10_decode")
7699 (cond [(eq_attr "alternative" "0,1")
7700 (const_string "vector")]
7701 (const_string "direct")))
7702 (set_attr "mode" "HI")])
7704 (define_expand "mulqi3"
7705 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7706 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7707 (match_operand:QI 2 "register_operand" "")))
7708 (clobber (reg:CC FLAGS_REG))])]
7709 "TARGET_QIMODE_MATH"
7716 (define_insn "*mulqi3_1"
7717 [(set (match_operand:QI 0 "register_operand" "=a")
7718 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7719 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7720 (clobber (reg:CC FLAGS_REG))]
7722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7724 [(set_attr "type" "imul")
7725 (set_attr "length_immediate" "0")
7726 (set (attr "athlon_decode")
7727 (if_then_else (eq_attr "cpu" "athlon")
7728 (const_string "vector")
7729 (const_string "direct")))
7730 (set_attr "amdfam10_decode" "direct")
7731 (set_attr "mode" "QI")])
7733 (define_expand "umulqihi3"
7734 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7735 (mult:HI (zero_extend:HI
7736 (match_operand:QI 1 "nonimmediate_operand" ""))
7738 (match_operand:QI 2 "register_operand" ""))))
7739 (clobber (reg:CC FLAGS_REG))])]
7740 "TARGET_QIMODE_MATH"
7743 (define_insn "*umulqihi3_1"
7744 [(set (match_operand:HI 0 "register_operand" "=a")
7745 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7746 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7747 (clobber (reg:CC FLAGS_REG))]
7749 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7751 [(set_attr "type" "imul")
7752 (set_attr "length_immediate" "0")
7753 (set (attr "athlon_decode")
7754 (if_then_else (eq_attr "cpu" "athlon")
7755 (const_string "vector")
7756 (const_string "direct")))
7757 (set_attr "amdfam10_decode" "direct")
7758 (set_attr "mode" "QI")])
7760 (define_expand "mulqihi3"
7761 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7762 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7763 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7764 (clobber (reg:CC FLAGS_REG))])]
7765 "TARGET_QIMODE_MATH"
7768 (define_insn "*mulqihi3_insn"
7769 [(set (match_operand:HI 0 "register_operand" "=a")
7770 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7771 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7772 (clobber (reg:CC FLAGS_REG))]
7774 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7776 [(set_attr "type" "imul")
7777 (set_attr "length_immediate" "0")
7778 (set (attr "athlon_decode")
7779 (if_then_else (eq_attr "cpu" "athlon")
7780 (const_string "vector")
7781 (const_string "direct")))
7782 (set_attr "amdfam10_decode" "direct")
7783 (set_attr "mode" "QI")])
7785 (define_expand "umulditi3"
7786 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7787 (mult:TI (zero_extend:TI
7788 (match_operand:DI 1 "nonimmediate_operand" ""))
7790 (match_operand:DI 2 "register_operand" ""))))
7791 (clobber (reg:CC FLAGS_REG))])]
7795 (define_insn "*umulditi3_insn"
7796 [(set (match_operand:TI 0 "register_operand" "=A")
7797 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7798 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7799 (clobber (reg:CC FLAGS_REG))]
7801 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7803 [(set_attr "type" "imul")
7804 (set_attr "length_immediate" "0")
7805 (set (attr "athlon_decode")
7806 (if_then_else (eq_attr "cpu" "athlon")
7807 (const_string "vector")
7808 (const_string "double")))
7809 (set_attr "amdfam10_decode" "double")
7810 (set_attr "mode" "DI")])
7812 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7813 (define_expand "umulsidi3"
7814 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7815 (mult:DI (zero_extend:DI
7816 (match_operand:SI 1 "nonimmediate_operand" ""))
7818 (match_operand:SI 2 "register_operand" ""))))
7819 (clobber (reg:CC FLAGS_REG))])]
7823 (define_insn "*umulsidi3_insn"
7824 [(set (match_operand:DI 0 "register_operand" "=A")
7825 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7826 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7827 (clobber (reg:CC FLAGS_REG))]
7829 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7831 [(set_attr "type" "imul")
7832 (set_attr "length_immediate" "0")
7833 (set (attr "athlon_decode")
7834 (if_then_else (eq_attr "cpu" "athlon")
7835 (const_string "vector")
7836 (const_string "double")))
7837 (set_attr "amdfam10_decode" "double")
7838 (set_attr "mode" "SI")])
7840 (define_expand "mulditi3"
7841 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7842 (mult:TI (sign_extend:TI
7843 (match_operand:DI 1 "nonimmediate_operand" ""))
7845 (match_operand:DI 2 "register_operand" ""))))
7846 (clobber (reg:CC FLAGS_REG))])]
7850 (define_insn "*mulditi3_insn"
7851 [(set (match_operand:TI 0 "register_operand" "=A")
7852 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7853 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7854 (clobber (reg:CC FLAGS_REG))]
7856 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7858 [(set_attr "type" "imul")
7859 (set_attr "length_immediate" "0")
7860 (set (attr "athlon_decode")
7861 (if_then_else (eq_attr "cpu" "athlon")
7862 (const_string "vector")
7863 (const_string "double")))
7864 (set_attr "amdfam10_decode" "double")
7865 (set_attr "mode" "DI")])
7867 (define_expand "mulsidi3"
7868 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7869 (mult:DI (sign_extend:DI
7870 (match_operand:SI 1 "nonimmediate_operand" ""))
7872 (match_operand:SI 2 "register_operand" ""))))
7873 (clobber (reg:CC FLAGS_REG))])]
7877 (define_insn "*mulsidi3_insn"
7878 [(set (match_operand:DI 0 "register_operand" "=A")
7879 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7880 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7881 (clobber (reg:CC FLAGS_REG))]
7883 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7885 [(set_attr "type" "imul")
7886 (set_attr "length_immediate" "0")
7887 (set (attr "athlon_decode")
7888 (if_then_else (eq_attr "cpu" "athlon")
7889 (const_string "vector")
7890 (const_string "double")))
7891 (set_attr "amdfam10_decode" "double")
7892 (set_attr "mode" "SI")])
7894 (define_expand "umuldi3_highpart"
7895 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7898 (mult:TI (zero_extend:TI
7899 (match_operand:DI 1 "nonimmediate_operand" ""))
7901 (match_operand:DI 2 "register_operand" "")))
7903 (clobber (match_scratch:DI 3 ""))
7904 (clobber (reg:CC FLAGS_REG))])]
7908 (define_insn "*umuldi3_highpart_rex64"
7909 [(set (match_operand:DI 0 "register_operand" "=d")
7912 (mult:TI (zero_extend:TI
7913 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7915 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7917 (clobber (match_scratch:DI 3 "=1"))
7918 (clobber (reg:CC FLAGS_REG))]
7920 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7922 [(set_attr "type" "imul")
7923 (set_attr "length_immediate" "0")
7924 (set (attr "athlon_decode")
7925 (if_then_else (eq_attr "cpu" "athlon")
7926 (const_string "vector")
7927 (const_string "double")))
7928 (set_attr "amdfam10_decode" "double")
7929 (set_attr "mode" "DI")])
7931 (define_expand "umulsi3_highpart"
7932 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7935 (mult:DI (zero_extend:DI
7936 (match_operand:SI 1 "nonimmediate_operand" ""))
7938 (match_operand:SI 2 "register_operand" "")))
7940 (clobber (match_scratch:SI 3 ""))
7941 (clobber (reg:CC FLAGS_REG))])]
7945 (define_insn "*umulsi3_highpart_insn"
7946 [(set (match_operand:SI 0 "register_operand" "=d")
7949 (mult:DI (zero_extend:DI
7950 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7952 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7954 (clobber (match_scratch:SI 3 "=1"))
7955 (clobber (reg:CC FLAGS_REG))]
7956 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7958 [(set_attr "type" "imul")
7959 (set_attr "length_immediate" "0")
7960 (set (attr "athlon_decode")
7961 (if_then_else (eq_attr "cpu" "athlon")
7962 (const_string "vector")
7963 (const_string "double")))
7964 (set_attr "amdfam10_decode" "double")
7965 (set_attr "mode" "SI")])
7967 (define_insn "*umulsi3_highpart_zext"
7968 [(set (match_operand:DI 0 "register_operand" "=d")
7969 (zero_extend:DI (truncate:SI
7971 (mult:DI (zero_extend:DI
7972 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7974 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7976 (clobber (match_scratch:SI 3 "=1"))
7977 (clobber (reg:CC FLAGS_REG))]
7979 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7981 [(set_attr "type" "imul")
7982 (set_attr "length_immediate" "0")
7983 (set (attr "athlon_decode")
7984 (if_then_else (eq_attr "cpu" "athlon")
7985 (const_string "vector")
7986 (const_string "double")))
7987 (set_attr "amdfam10_decode" "double")
7988 (set_attr "mode" "SI")])
7990 (define_expand "smuldi3_highpart"
7991 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7994 (mult:TI (sign_extend:TI
7995 (match_operand:DI 1 "nonimmediate_operand" ""))
7997 (match_operand:DI 2 "register_operand" "")))
7999 (clobber (match_scratch:DI 3 ""))
8000 (clobber (reg:CC FLAGS_REG))])]
8004 (define_insn "*smuldi3_highpart_rex64"
8005 [(set (match_operand:DI 0 "register_operand" "=d")
8008 (mult:TI (sign_extend:TI
8009 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8011 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8013 (clobber (match_scratch:DI 3 "=1"))
8014 (clobber (reg:CC FLAGS_REG))]
8016 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8018 [(set_attr "type" "imul")
8019 (set (attr "athlon_decode")
8020 (if_then_else (eq_attr "cpu" "athlon")
8021 (const_string "vector")
8022 (const_string "double")))
8023 (set_attr "amdfam10_decode" "double")
8024 (set_attr "mode" "DI")])
8026 (define_expand "smulsi3_highpart"
8027 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8030 (mult:DI (sign_extend:DI
8031 (match_operand:SI 1 "nonimmediate_operand" ""))
8033 (match_operand:SI 2 "register_operand" "")))
8035 (clobber (match_scratch:SI 3 ""))
8036 (clobber (reg:CC FLAGS_REG))])]
8040 (define_insn "*smulsi3_highpart_insn"
8041 [(set (match_operand:SI 0 "register_operand" "=d")
8044 (mult:DI (sign_extend:DI
8045 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8047 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8049 (clobber (match_scratch:SI 3 "=1"))
8050 (clobber (reg:CC FLAGS_REG))]
8051 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8053 [(set_attr "type" "imul")
8054 (set (attr "athlon_decode")
8055 (if_then_else (eq_attr "cpu" "athlon")
8056 (const_string "vector")
8057 (const_string "double")))
8058 (set_attr "amdfam10_decode" "double")
8059 (set_attr "mode" "SI")])
8061 (define_insn "*smulsi3_highpart_zext"
8062 [(set (match_operand:DI 0 "register_operand" "=d")
8063 (zero_extend:DI (truncate:SI
8065 (mult:DI (sign_extend:DI
8066 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8068 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8070 (clobber (match_scratch:SI 3 "=1"))
8071 (clobber (reg:CC FLAGS_REG))]
8073 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8075 [(set_attr "type" "imul")
8076 (set (attr "athlon_decode")
8077 (if_then_else (eq_attr "cpu" "athlon")
8078 (const_string "vector")
8079 (const_string "double")))
8080 (set_attr "amdfam10_decode" "double")
8081 (set_attr "mode" "SI")])
8083 ;; The patterns that match these are at the end of this file.
8085 (define_expand "mulxf3"
8086 [(set (match_operand:XF 0 "register_operand" "")
8087 (mult:XF (match_operand:XF 1 "register_operand" "")
8088 (match_operand:XF 2 "register_operand" "")))]
8092 (define_expand "mul<mode>3"
8093 [(set (match_operand:MODEF 0 "register_operand" "")
8094 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8095 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8096 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8099 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8102 ;; Divide instructions
8104 (define_insn "divqi3"
8105 [(set (match_operand:QI 0 "register_operand" "=a")
8106 (div:QI (match_operand:HI 1 "register_operand" "0")
8107 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8108 (clobber (reg:CC FLAGS_REG))]
8109 "TARGET_QIMODE_MATH"
8111 [(set_attr "type" "idiv")
8112 (set_attr "mode" "QI")])
8114 (define_insn "udivqi3"
8115 [(set (match_operand:QI 0 "register_operand" "=a")
8116 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8117 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8118 (clobber (reg:CC FLAGS_REG))]
8119 "TARGET_QIMODE_MATH"
8121 [(set_attr "type" "idiv")
8122 (set_attr "mode" "QI")])
8124 ;; The patterns that match these are at the end of this file.
8126 (define_expand "divxf3"
8127 [(set (match_operand:XF 0 "register_operand" "")
8128 (div:XF (match_operand:XF 1 "register_operand" "")
8129 (match_operand:XF 2 "register_operand" "")))]
8133 (define_expand "divdf3"
8134 [(set (match_operand:DF 0 "register_operand" "")
8135 (div:DF (match_operand:DF 1 "register_operand" "")
8136 (match_operand:DF 2 "nonimmediate_operand" "")))]
8137 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8140 (define_expand "divsf3"
8141 [(set (match_operand:SF 0 "register_operand" "")
8142 (div:SF (match_operand:SF 1 "register_operand" "")
8143 (match_operand:SF 2 "nonimmediate_operand" "")))]
8144 "TARGET_80387 || TARGET_SSE_MATH"
8146 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8147 && flag_finite_math_only && !flag_trapping_math
8148 && flag_unsafe_math_optimizations)
8150 ix86_emit_swdivsf (operands[0], operands[1],
8151 operands[2], SFmode);
8156 ;; Remainder instructions.
8158 (define_expand "divmoddi4"
8159 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8160 (div:DI (match_operand:DI 1 "register_operand" "")
8161 (match_operand:DI 2 "nonimmediate_operand" "")))
8162 (set (match_operand:DI 3 "register_operand" "")
8163 (mod:DI (match_dup 1) (match_dup 2)))
8164 (clobber (reg:CC FLAGS_REG))])]
8168 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8169 ;; Penalize eax case slightly because it results in worse scheduling
8171 (define_insn "*divmoddi4_nocltd_rex64"
8172 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8173 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8174 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8175 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8176 (mod:DI (match_dup 2) (match_dup 3)))
8177 (clobber (reg:CC FLAGS_REG))]
8178 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8180 [(set_attr "type" "multi")])
8182 (define_insn "*divmoddi4_cltd_rex64"
8183 [(set (match_operand:DI 0 "register_operand" "=a")
8184 (div:DI (match_operand:DI 2 "register_operand" "a")
8185 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8186 (set (match_operand:DI 1 "register_operand" "=&d")
8187 (mod:DI (match_dup 2) (match_dup 3)))
8188 (clobber (reg:CC FLAGS_REG))]
8189 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8191 [(set_attr "type" "multi")])
8193 (define_insn "*divmoddi_noext_rex64"
8194 [(set (match_operand:DI 0 "register_operand" "=a")
8195 (div:DI (match_operand:DI 1 "register_operand" "0")
8196 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8197 (set (match_operand:DI 3 "register_operand" "=d")
8198 (mod:DI (match_dup 1) (match_dup 2)))
8199 (use (match_operand:DI 4 "register_operand" "3"))
8200 (clobber (reg:CC FLAGS_REG))]
8203 [(set_attr "type" "idiv")
8204 (set_attr "mode" "DI")])
8207 [(set (match_operand:DI 0 "register_operand" "")
8208 (div:DI (match_operand:DI 1 "register_operand" "")
8209 (match_operand:DI 2 "nonimmediate_operand" "")))
8210 (set (match_operand:DI 3 "register_operand" "")
8211 (mod:DI (match_dup 1) (match_dup 2)))
8212 (clobber (reg:CC FLAGS_REG))]
8213 "TARGET_64BIT && reload_completed"
8214 [(parallel [(set (match_dup 3)
8215 (ashiftrt:DI (match_dup 4) (const_int 63)))
8216 (clobber (reg:CC FLAGS_REG))])
8217 (parallel [(set (match_dup 0)
8218 (div:DI (reg:DI 0) (match_dup 2)))
8220 (mod:DI (reg:DI 0) (match_dup 2)))
8222 (clobber (reg:CC FLAGS_REG))])]
8224 /* Avoid use of cltd in favor of a mov+shift. */
8225 if (!TARGET_USE_CLTD && !optimize_size)
8227 if (true_regnum (operands[1]))
8228 emit_move_insn (operands[0], operands[1]);
8230 emit_move_insn (operands[3], operands[1]);
8231 operands[4] = operands[3];
8235 gcc_assert (!true_regnum (operands[1]));
8236 operands[4] = operands[1];
8241 (define_expand "divmodsi4"
8242 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8243 (div:SI (match_operand:SI 1 "register_operand" "")
8244 (match_operand:SI 2 "nonimmediate_operand" "")))
8245 (set (match_operand:SI 3 "register_operand" "")
8246 (mod:SI (match_dup 1) (match_dup 2)))
8247 (clobber (reg:CC FLAGS_REG))])]
8251 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8252 ;; Penalize eax case slightly because it results in worse scheduling
8254 (define_insn "*divmodsi4_nocltd"
8255 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8256 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8257 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8258 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8259 (mod:SI (match_dup 2) (match_dup 3)))
8260 (clobber (reg:CC FLAGS_REG))]
8261 "!optimize_size && !TARGET_USE_CLTD"
8263 [(set_attr "type" "multi")])
8265 (define_insn "*divmodsi4_cltd"
8266 [(set (match_operand:SI 0 "register_operand" "=a")
8267 (div:SI (match_operand:SI 2 "register_operand" "a")
8268 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8269 (set (match_operand:SI 1 "register_operand" "=&d")
8270 (mod:SI (match_dup 2) (match_dup 3)))
8271 (clobber (reg:CC FLAGS_REG))]
8272 "optimize_size || TARGET_USE_CLTD"
8274 [(set_attr "type" "multi")])
8276 (define_insn "*divmodsi_noext"
8277 [(set (match_operand:SI 0 "register_operand" "=a")
8278 (div:SI (match_operand:SI 1 "register_operand" "0")
8279 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8280 (set (match_operand:SI 3 "register_operand" "=d")
8281 (mod:SI (match_dup 1) (match_dup 2)))
8282 (use (match_operand:SI 4 "register_operand" "3"))
8283 (clobber (reg:CC FLAGS_REG))]
8286 [(set_attr "type" "idiv")
8287 (set_attr "mode" "SI")])
8290 [(set (match_operand:SI 0 "register_operand" "")
8291 (div:SI (match_operand:SI 1 "register_operand" "")
8292 (match_operand:SI 2 "nonimmediate_operand" "")))
8293 (set (match_operand:SI 3 "register_operand" "")
8294 (mod:SI (match_dup 1) (match_dup 2)))
8295 (clobber (reg:CC FLAGS_REG))]
8297 [(parallel [(set (match_dup 3)
8298 (ashiftrt:SI (match_dup 4) (const_int 31)))
8299 (clobber (reg:CC FLAGS_REG))])
8300 (parallel [(set (match_dup 0)
8301 (div:SI (reg:SI 0) (match_dup 2)))
8303 (mod:SI (reg:SI 0) (match_dup 2)))
8305 (clobber (reg:CC FLAGS_REG))])]
8307 /* Avoid use of cltd in favor of a mov+shift. */
8308 if (!TARGET_USE_CLTD && !optimize_size)
8310 if (true_regnum (operands[1]))
8311 emit_move_insn (operands[0], operands[1]);
8313 emit_move_insn (operands[3], operands[1]);
8314 operands[4] = operands[3];
8318 gcc_assert (!true_regnum (operands[1]));
8319 operands[4] = operands[1];
8323 (define_insn "divmodhi4"
8324 [(set (match_operand:HI 0 "register_operand" "=a")
8325 (div:HI (match_operand:HI 1 "register_operand" "0")
8326 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8327 (set (match_operand:HI 3 "register_operand" "=&d")
8328 (mod:HI (match_dup 1) (match_dup 2)))
8329 (clobber (reg:CC FLAGS_REG))]
8330 "TARGET_HIMODE_MATH"
8332 [(set_attr "type" "multi")
8333 (set_attr "length_immediate" "0")
8334 (set_attr "mode" "SI")])
8336 (define_insn "udivmoddi4"
8337 [(set (match_operand:DI 0 "register_operand" "=a")
8338 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8339 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8340 (set (match_operand:DI 3 "register_operand" "=&d")
8341 (umod:DI (match_dup 1) (match_dup 2)))
8342 (clobber (reg:CC FLAGS_REG))]
8344 "xor{q}\t%3, %3\;div{q}\t%2"
8345 [(set_attr "type" "multi")
8346 (set_attr "length_immediate" "0")
8347 (set_attr "mode" "DI")])
8349 (define_insn "*udivmoddi4_noext"
8350 [(set (match_operand:DI 0 "register_operand" "=a")
8351 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8352 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8353 (set (match_operand:DI 3 "register_operand" "=d")
8354 (umod:DI (match_dup 1) (match_dup 2)))
8356 (clobber (reg:CC FLAGS_REG))]
8359 [(set_attr "type" "idiv")
8360 (set_attr "mode" "DI")])
8363 [(set (match_operand:DI 0 "register_operand" "")
8364 (udiv:DI (match_operand:DI 1 "register_operand" "")
8365 (match_operand:DI 2 "nonimmediate_operand" "")))
8366 (set (match_operand:DI 3 "register_operand" "")
8367 (umod:DI (match_dup 1) (match_dup 2)))
8368 (clobber (reg:CC FLAGS_REG))]
8369 "TARGET_64BIT && reload_completed"
8370 [(set (match_dup 3) (const_int 0))
8371 (parallel [(set (match_dup 0)
8372 (udiv:DI (match_dup 1) (match_dup 2)))
8374 (umod:DI (match_dup 1) (match_dup 2)))
8376 (clobber (reg:CC FLAGS_REG))])]
8379 (define_insn "udivmodsi4"
8380 [(set (match_operand:SI 0 "register_operand" "=a")
8381 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8382 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8383 (set (match_operand:SI 3 "register_operand" "=&d")
8384 (umod:SI (match_dup 1) (match_dup 2)))
8385 (clobber (reg:CC FLAGS_REG))]
8387 "xor{l}\t%3, %3\;div{l}\t%2"
8388 [(set_attr "type" "multi")
8389 (set_attr "length_immediate" "0")
8390 (set_attr "mode" "SI")])
8392 (define_insn "*udivmodsi4_noext"
8393 [(set (match_operand:SI 0 "register_operand" "=a")
8394 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8395 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8396 (set (match_operand:SI 3 "register_operand" "=d")
8397 (umod:SI (match_dup 1) (match_dup 2)))
8399 (clobber (reg:CC FLAGS_REG))]
8402 [(set_attr "type" "idiv")
8403 (set_attr "mode" "SI")])
8406 [(set (match_operand:SI 0 "register_operand" "")
8407 (udiv:SI (match_operand:SI 1 "register_operand" "")
8408 (match_operand:SI 2 "nonimmediate_operand" "")))
8409 (set (match_operand:SI 3 "register_operand" "")
8410 (umod:SI (match_dup 1) (match_dup 2)))
8411 (clobber (reg:CC FLAGS_REG))]
8413 [(set (match_dup 3) (const_int 0))
8414 (parallel [(set (match_dup 0)
8415 (udiv:SI (match_dup 1) (match_dup 2)))
8417 (umod:SI (match_dup 1) (match_dup 2)))
8419 (clobber (reg:CC FLAGS_REG))])]
8422 (define_expand "udivmodhi4"
8423 [(set (match_dup 4) (const_int 0))
8424 (parallel [(set (match_operand:HI 0 "register_operand" "")
8425 (udiv:HI (match_operand:HI 1 "register_operand" "")
8426 (match_operand:HI 2 "nonimmediate_operand" "")))
8427 (set (match_operand:HI 3 "register_operand" "")
8428 (umod:HI (match_dup 1) (match_dup 2)))
8430 (clobber (reg:CC FLAGS_REG))])]
8431 "TARGET_HIMODE_MATH"
8432 "operands[4] = gen_reg_rtx (HImode);")
8434 (define_insn "*udivmodhi_noext"
8435 [(set (match_operand:HI 0 "register_operand" "=a")
8436 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8437 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8438 (set (match_operand:HI 3 "register_operand" "=d")
8439 (umod:HI (match_dup 1) (match_dup 2)))
8440 (use (match_operand:HI 4 "register_operand" "3"))
8441 (clobber (reg:CC FLAGS_REG))]
8444 [(set_attr "type" "idiv")
8445 (set_attr "mode" "HI")])
8447 ;; We cannot use div/idiv for double division, because it causes
8448 ;; "division by zero" on the overflow and that's not what we expect
8449 ;; from truncate. Because true (non truncating) double division is
8450 ;; never generated, we can't create this insn anyway.
8453 ; [(set (match_operand:SI 0 "register_operand" "=a")
8455 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8457 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8458 ; (set (match_operand:SI 3 "register_operand" "=d")
8460 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8461 ; (clobber (reg:CC FLAGS_REG))]
8463 ; "div{l}\t{%2, %0|%0, %2}"
8464 ; [(set_attr "type" "idiv")])
8466 ;;- Logical AND instructions
8468 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8469 ;; Note that this excludes ah.
8471 (define_insn "*testdi_1_rex64"
8472 [(set (reg FLAGS_REG)
8474 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8475 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8477 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8478 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8480 test{l}\t{%k1, %k0|%k0, %k1}
8481 test{l}\t{%k1, %k0|%k0, %k1}
8482 test{q}\t{%1, %0|%0, %1}
8483 test{q}\t{%1, %0|%0, %1}
8484 test{q}\t{%1, %0|%0, %1}"
8485 [(set_attr "type" "test")
8486 (set_attr "modrm" "0,1,0,1,1")
8487 (set_attr "mode" "SI,SI,DI,DI,DI")
8488 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8490 (define_insn "testsi_1"
8491 [(set (reg FLAGS_REG)
8493 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8494 (match_operand:SI 1 "general_operand" "in,in,rin"))
8496 "ix86_match_ccmode (insn, CCNOmode)
8497 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8498 "test{l}\t{%1, %0|%0, %1}"
8499 [(set_attr "type" "test")
8500 (set_attr "modrm" "0,1,1")
8501 (set_attr "mode" "SI")
8502 (set_attr "pent_pair" "uv,np,uv")])
8504 (define_expand "testsi_ccno_1"
8505 [(set (reg:CCNO FLAGS_REG)
8507 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8508 (match_operand:SI 1 "nonmemory_operand" ""))
8513 (define_insn "*testhi_1"
8514 [(set (reg FLAGS_REG)
8515 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8516 (match_operand:HI 1 "general_operand" "n,n,rn"))
8518 "ix86_match_ccmode (insn, CCNOmode)
8519 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8520 "test{w}\t{%1, %0|%0, %1}"
8521 [(set_attr "type" "test")
8522 (set_attr "modrm" "0,1,1")
8523 (set_attr "mode" "HI")
8524 (set_attr "pent_pair" "uv,np,uv")])
8526 (define_expand "testqi_ccz_1"
8527 [(set (reg:CCZ FLAGS_REG)
8528 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8529 (match_operand:QI 1 "nonmemory_operand" ""))
8534 (define_insn "*testqi_1_maybe_si"
8535 [(set (reg FLAGS_REG)
8538 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8539 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8541 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8542 && ix86_match_ccmode (insn,
8543 CONST_INT_P (operands[1])
8544 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8546 if (which_alternative == 3)
8548 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8549 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8550 return "test{l}\t{%1, %k0|%k0, %1}";
8552 return "test{b}\t{%1, %0|%0, %1}";
8554 [(set_attr "type" "test")
8555 (set_attr "modrm" "0,1,1,1")
8556 (set_attr "mode" "QI,QI,QI,SI")
8557 (set_attr "pent_pair" "uv,np,uv,np")])
8559 (define_insn "*testqi_1"
8560 [(set (reg FLAGS_REG)
8563 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8564 (match_operand:QI 1 "general_operand" "n,n,qn"))
8566 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8567 && ix86_match_ccmode (insn, CCNOmode)"
8568 "test{b}\t{%1, %0|%0, %1}"
8569 [(set_attr "type" "test")
8570 (set_attr "modrm" "0,1,1")
8571 (set_attr "mode" "QI")
8572 (set_attr "pent_pair" "uv,np,uv")])
8574 (define_expand "testqi_ext_ccno_0"
8575 [(set (reg:CCNO FLAGS_REG)
8579 (match_operand 0 "ext_register_operand" "")
8582 (match_operand 1 "const_int_operand" ""))
8587 (define_insn "*testqi_ext_0"
8588 [(set (reg FLAGS_REG)
8592 (match_operand 0 "ext_register_operand" "Q")
8595 (match_operand 1 "const_int_operand" "n"))
8597 "ix86_match_ccmode (insn, CCNOmode)"
8598 "test{b}\t{%1, %h0|%h0, %1}"
8599 [(set_attr "type" "test")
8600 (set_attr "mode" "QI")
8601 (set_attr "length_immediate" "1")
8602 (set_attr "pent_pair" "np")])
8604 (define_insn "*testqi_ext_1"
8605 [(set (reg FLAGS_REG)
8609 (match_operand 0 "ext_register_operand" "Q")
8613 (match_operand:QI 1 "general_operand" "Qm")))
8615 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8616 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8617 "test{b}\t{%1, %h0|%h0, %1}"
8618 [(set_attr "type" "test")
8619 (set_attr "mode" "QI")])
8621 (define_insn "*testqi_ext_1_rex64"
8622 [(set (reg FLAGS_REG)
8626 (match_operand 0 "ext_register_operand" "Q")
8630 (match_operand:QI 1 "register_operand" "Q")))
8632 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8633 "test{b}\t{%1, %h0|%h0, %1}"
8634 [(set_attr "type" "test")
8635 (set_attr "mode" "QI")])
8637 (define_insn "*testqi_ext_2"
8638 [(set (reg FLAGS_REG)
8642 (match_operand 0 "ext_register_operand" "Q")
8646 (match_operand 1 "ext_register_operand" "Q")
8650 "ix86_match_ccmode (insn, CCNOmode)"
8651 "test{b}\t{%h1, %h0|%h0, %h1}"
8652 [(set_attr "type" "test")
8653 (set_attr "mode" "QI")])
8655 ;; Combine likes to form bit extractions for some tests. Humor it.
8656 (define_insn "*testqi_ext_3"
8657 [(set (reg FLAGS_REG)
8658 (compare (zero_extract:SI
8659 (match_operand 0 "nonimmediate_operand" "rm")
8660 (match_operand:SI 1 "const_int_operand" "")
8661 (match_operand:SI 2 "const_int_operand" ""))
8663 "ix86_match_ccmode (insn, CCNOmode)
8664 && INTVAL (operands[1]) > 0
8665 && INTVAL (operands[2]) >= 0
8666 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8667 && (GET_MODE (operands[0]) == SImode
8668 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8669 || GET_MODE (operands[0]) == HImode
8670 || GET_MODE (operands[0]) == QImode)"
8673 (define_insn "*testqi_ext_3_rex64"
8674 [(set (reg FLAGS_REG)
8675 (compare (zero_extract:DI
8676 (match_operand 0 "nonimmediate_operand" "rm")
8677 (match_operand:DI 1 "const_int_operand" "")
8678 (match_operand:DI 2 "const_int_operand" ""))
8681 && ix86_match_ccmode (insn, CCNOmode)
8682 && INTVAL (operands[1]) > 0
8683 && INTVAL (operands[2]) >= 0
8684 /* Ensure that resulting mask is zero or sign extended operand. */
8685 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8686 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8687 && INTVAL (operands[1]) > 32))
8688 && (GET_MODE (operands[0]) == SImode
8689 || GET_MODE (operands[0]) == DImode
8690 || GET_MODE (operands[0]) == HImode
8691 || GET_MODE (operands[0]) == QImode)"
8695 [(set (match_operand 0 "flags_reg_operand" "")
8696 (match_operator 1 "compare_operator"
8698 (match_operand 2 "nonimmediate_operand" "")
8699 (match_operand 3 "const_int_operand" "")
8700 (match_operand 4 "const_int_operand" ""))
8702 "ix86_match_ccmode (insn, CCNOmode)"
8703 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8705 rtx val = operands[2];
8706 HOST_WIDE_INT len = INTVAL (operands[3]);
8707 HOST_WIDE_INT pos = INTVAL (operands[4]);
8709 enum machine_mode mode, submode;
8711 mode = GET_MODE (val);
8714 /* ??? Combine likes to put non-volatile mem extractions in QImode
8715 no matter the size of the test. So find a mode that works. */
8716 if (! MEM_VOLATILE_P (val))
8718 mode = smallest_mode_for_size (pos + len, MODE_INT);
8719 val = adjust_address (val, mode, 0);
8722 else if (GET_CODE (val) == SUBREG
8723 && (submode = GET_MODE (SUBREG_REG (val)),
8724 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8725 && pos + len <= GET_MODE_BITSIZE (submode))
8727 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8729 val = SUBREG_REG (val);
8731 else if (mode == HImode && pos + len <= 8)
8733 /* Small HImode tests can be converted to QImode. */
8735 val = gen_lowpart (QImode, val);
8738 if (len == HOST_BITS_PER_WIDE_INT)
8741 mask = ((HOST_WIDE_INT)1 << len) - 1;
8744 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8747 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8748 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8749 ;; this is relatively important trick.
8750 ;; Do the conversion only post-reload to avoid limiting of the register class
8753 [(set (match_operand 0 "flags_reg_operand" "")
8754 (match_operator 1 "compare_operator"
8755 [(and (match_operand 2 "register_operand" "")
8756 (match_operand 3 "const_int_operand" ""))
8759 && QI_REG_P (operands[2])
8760 && GET_MODE (operands[2]) != QImode
8761 && ((ix86_match_ccmode (insn, CCZmode)
8762 && !(INTVAL (operands[3]) & ~(255 << 8)))
8763 || (ix86_match_ccmode (insn, CCNOmode)
8764 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8767 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8770 "operands[2] = gen_lowpart (SImode, operands[2]);
8771 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8774 [(set (match_operand 0 "flags_reg_operand" "")
8775 (match_operator 1 "compare_operator"
8776 [(and (match_operand 2 "nonimmediate_operand" "")
8777 (match_operand 3 "const_int_operand" ""))
8780 && GET_MODE (operands[2]) != QImode
8781 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8782 && ((ix86_match_ccmode (insn, CCZmode)
8783 && !(INTVAL (operands[3]) & ~255))
8784 || (ix86_match_ccmode (insn, CCNOmode)
8785 && !(INTVAL (operands[3]) & ~127)))"
8787 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8789 "operands[2] = gen_lowpart (QImode, operands[2]);
8790 operands[3] = gen_lowpart (QImode, operands[3]);")
8793 ;; %%% This used to optimize known byte-wide and operations to memory,
8794 ;; and sometimes to QImode registers. If this is considered useful,
8795 ;; it should be done with splitters.
8797 (define_expand "anddi3"
8798 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8799 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8800 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8801 (clobber (reg:CC FLAGS_REG))]
8803 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8805 (define_insn "*anddi_1_rex64"
8806 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8807 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8808 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8809 (clobber (reg:CC FLAGS_REG))]
8810 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8812 switch (get_attr_type (insn))
8816 enum machine_mode mode;
8818 gcc_assert (CONST_INT_P (operands[2]));
8819 if (INTVAL (operands[2]) == 0xff)
8823 gcc_assert (INTVAL (operands[2]) == 0xffff);
8827 operands[1] = gen_lowpart (mode, operands[1]);
8829 return "movz{bq|x}\t{%1,%0|%0, %1}";
8831 return "movz{wq|x}\t{%1,%0|%0, %1}";
8835 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8836 if (get_attr_mode (insn) == MODE_SI)
8837 return "and{l}\t{%k2, %k0|%k0, %k2}";
8839 return "and{q}\t{%2, %0|%0, %2}";
8842 [(set_attr "type" "alu,alu,alu,imovx")
8843 (set_attr "length_immediate" "*,*,*,0")
8844 (set_attr "mode" "SI,DI,DI,DI")])
8846 (define_insn "*anddi_2"
8847 [(set (reg FLAGS_REG)
8848 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8849 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8851 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8852 (and:DI (match_dup 1) (match_dup 2)))]
8853 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8854 && ix86_binary_operator_ok (AND, DImode, operands)"
8856 and{l}\t{%k2, %k0|%k0, %k2}
8857 and{q}\t{%2, %0|%0, %2}
8858 and{q}\t{%2, %0|%0, %2}"
8859 [(set_attr "type" "alu")
8860 (set_attr "mode" "SI,DI,DI")])
8862 (define_expand "andsi3"
8863 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8864 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8865 (match_operand:SI 2 "general_operand" "")))
8866 (clobber (reg:CC FLAGS_REG))]
8868 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8870 (define_insn "*andsi_1"
8871 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8872 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8873 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8874 (clobber (reg:CC FLAGS_REG))]
8875 "ix86_binary_operator_ok (AND, SImode, operands)"
8877 switch (get_attr_type (insn))
8881 enum machine_mode mode;
8883 gcc_assert (CONST_INT_P (operands[2]));
8884 if (INTVAL (operands[2]) == 0xff)
8888 gcc_assert (INTVAL (operands[2]) == 0xffff);
8892 operands[1] = gen_lowpart (mode, operands[1]);
8894 return "movz{bl|x}\t{%1,%0|%0, %1}";
8896 return "movz{wl|x}\t{%1,%0|%0, %1}";
8900 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8901 return "and{l}\t{%2, %0|%0, %2}";
8904 [(set_attr "type" "alu,alu,imovx")
8905 (set_attr "length_immediate" "*,*,0")
8906 (set_attr "mode" "SI")])
8909 [(set (match_operand 0 "register_operand" "")
8911 (const_int -65536)))
8912 (clobber (reg:CC FLAGS_REG))]
8913 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8914 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8915 "operands[1] = gen_lowpart (HImode, operands[0]);")
8918 [(set (match_operand 0 "ext_register_operand" "")
8921 (clobber (reg:CC FLAGS_REG))]
8922 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8923 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8924 "operands[1] = gen_lowpart (QImode, operands[0]);")
8927 [(set (match_operand 0 "ext_register_operand" "")
8929 (const_int -65281)))
8930 (clobber (reg:CC FLAGS_REG))]
8931 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8932 [(parallel [(set (zero_extract:SI (match_dup 0)
8936 (zero_extract:SI (match_dup 0)
8939 (zero_extract:SI (match_dup 0)
8942 (clobber (reg:CC FLAGS_REG))])]
8943 "operands[0] = gen_lowpart (SImode, operands[0]);")
8945 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8946 (define_insn "*andsi_1_zext"
8947 [(set (match_operand:DI 0 "register_operand" "=r")
8949 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8950 (match_operand:SI 2 "general_operand" "g"))))
8951 (clobber (reg:CC FLAGS_REG))]
8952 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8953 "and{l}\t{%2, %k0|%k0, %2}"
8954 [(set_attr "type" "alu")
8955 (set_attr "mode" "SI")])
8957 (define_insn "*andsi_2"
8958 [(set (reg FLAGS_REG)
8959 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8960 (match_operand:SI 2 "general_operand" "g,ri"))
8962 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8963 (and:SI (match_dup 1) (match_dup 2)))]
8964 "ix86_match_ccmode (insn, CCNOmode)
8965 && ix86_binary_operator_ok (AND, SImode, operands)"
8966 "and{l}\t{%2, %0|%0, %2}"
8967 [(set_attr "type" "alu")
8968 (set_attr "mode" "SI")])
8970 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8971 (define_insn "*andsi_2_zext"
8972 [(set (reg FLAGS_REG)
8973 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8974 (match_operand:SI 2 "general_operand" "g"))
8976 (set (match_operand:DI 0 "register_operand" "=r")
8977 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8978 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8979 && ix86_binary_operator_ok (AND, SImode, operands)"
8980 "and{l}\t{%2, %k0|%k0, %2}"
8981 [(set_attr "type" "alu")
8982 (set_attr "mode" "SI")])
8984 (define_expand "andhi3"
8985 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8986 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8987 (match_operand:HI 2 "general_operand" "")))
8988 (clobber (reg:CC FLAGS_REG))]
8989 "TARGET_HIMODE_MATH"
8990 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8992 (define_insn "*andhi_1"
8993 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8994 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8995 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8996 (clobber (reg:CC FLAGS_REG))]
8997 "ix86_binary_operator_ok (AND, HImode, operands)"
8999 switch (get_attr_type (insn))
9002 gcc_assert (CONST_INT_P (operands[2]));
9003 gcc_assert (INTVAL (operands[2]) == 0xff);
9004 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9007 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9009 return "and{w}\t{%2, %0|%0, %2}";
9012 [(set_attr "type" "alu,alu,imovx")
9013 (set_attr "length_immediate" "*,*,0")
9014 (set_attr "mode" "HI,HI,SI")])
9016 (define_insn "*andhi_2"
9017 [(set (reg FLAGS_REG)
9018 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9019 (match_operand:HI 2 "general_operand" "g,ri"))
9021 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9022 (and:HI (match_dup 1) (match_dup 2)))]
9023 "ix86_match_ccmode (insn, CCNOmode)
9024 && ix86_binary_operator_ok (AND, HImode, operands)"
9025 "and{w}\t{%2, %0|%0, %2}"
9026 [(set_attr "type" "alu")
9027 (set_attr "mode" "HI")])
9029 (define_expand "andqi3"
9030 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9031 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9032 (match_operand:QI 2 "general_operand" "")))
9033 (clobber (reg:CC FLAGS_REG))]
9034 "TARGET_QIMODE_MATH"
9035 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9037 ;; %%% Potential partial reg stall on alternative 2. What to do?
9038 (define_insn "*andqi_1"
9039 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9040 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9041 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9042 (clobber (reg:CC FLAGS_REG))]
9043 "ix86_binary_operator_ok (AND, QImode, operands)"
9045 and{b}\t{%2, %0|%0, %2}
9046 and{b}\t{%2, %0|%0, %2}
9047 and{l}\t{%k2, %k0|%k0, %k2}"
9048 [(set_attr "type" "alu")
9049 (set_attr "mode" "QI,QI,SI")])
9051 (define_insn "*andqi_1_slp"
9052 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9053 (and:QI (match_dup 0)
9054 (match_operand:QI 1 "general_operand" "qi,qmi")))
9055 (clobber (reg:CC FLAGS_REG))]
9056 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9057 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9058 "and{b}\t{%1, %0|%0, %1}"
9059 [(set_attr "type" "alu1")
9060 (set_attr "mode" "QI")])
9062 (define_insn "*andqi_2_maybe_si"
9063 [(set (reg FLAGS_REG)
9065 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9066 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9068 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9069 (and:QI (match_dup 1) (match_dup 2)))]
9070 "ix86_binary_operator_ok (AND, QImode, operands)
9071 && ix86_match_ccmode (insn,
9072 CONST_INT_P (operands[2])
9073 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9075 if (which_alternative == 2)
9077 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9078 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9079 return "and{l}\t{%2, %k0|%k0, %2}";
9081 return "and{b}\t{%2, %0|%0, %2}";
9083 [(set_attr "type" "alu")
9084 (set_attr "mode" "QI,QI,SI")])
9086 (define_insn "*andqi_2"
9087 [(set (reg FLAGS_REG)
9089 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9090 (match_operand:QI 2 "general_operand" "qim,qi"))
9092 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9093 (and:QI (match_dup 1) (match_dup 2)))]
9094 "ix86_match_ccmode (insn, CCNOmode)
9095 && ix86_binary_operator_ok (AND, QImode, operands)"
9096 "and{b}\t{%2, %0|%0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "QI")])
9100 (define_insn "*andqi_2_slp"
9101 [(set (reg FLAGS_REG)
9103 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9104 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9106 (set (strict_low_part (match_dup 0))
9107 (and:QI (match_dup 0) (match_dup 1)))]
9108 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9109 && ix86_match_ccmode (insn, CCNOmode)
9110 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9111 "and{b}\t{%1, %0|%0, %1}"
9112 [(set_attr "type" "alu1")
9113 (set_attr "mode" "QI")])
9115 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9116 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9117 ;; for a QImode operand, which of course failed.
9119 (define_insn "andqi_ext_0"
9120 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9125 (match_operand 1 "ext_register_operand" "0")
9128 (match_operand 2 "const_int_operand" "n")))
9129 (clobber (reg:CC FLAGS_REG))]
9131 "and{b}\t{%2, %h0|%h0, %2}"
9132 [(set_attr "type" "alu")
9133 (set_attr "length_immediate" "1")
9134 (set_attr "mode" "QI")])
9136 ;; Generated by peephole translating test to and. This shows up
9137 ;; often in fp comparisons.
9139 (define_insn "*andqi_ext_0_cc"
9140 [(set (reg FLAGS_REG)
9144 (match_operand 1 "ext_register_operand" "0")
9147 (match_operand 2 "const_int_operand" "n"))
9149 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9158 "ix86_match_ccmode (insn, CCNOmode)"
9159 "and{b}\t{%2, %h0|%h0, %2}"
9160 [(set_attr "type" "alu")
9161 (set_attr "length_immediate" "1")
9162 (set_attr "mode" "QI")])
9164 (define_insn "*andqi_ext_1"
9165 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9170 (match_operand 1 "ext_register_operand" "0")
9174 (match_operand:QI 2 "general_operand" "Qm"))))
9175 (clobber (reg:CC FLAGS_REG))]
9177 "and{b}\t{%2, %h0|%h0, %2}"
9178 [(set_attr "type" "alu")
9179 (set_attr "length_immediate" "0")
9180 (set_attr "mode" "QI")])
9182 (define_insn "*andqi_ext_1_rex64"
9183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9188 (match_operand 1 "ext_register_operand" "0")
9192 (match_operand 2 "ext_register_operand" "Q"))))
9193 (clobber (reg:CC FLAGS_REG))]
9195 "and{b}\t{%2, %h0|%h0, %2}"
9196 [(set_attr "type" "alu")
9197 (set_attr "length_immediate" "0")
9198 (set_attr "mode" "QI")])
9200 (define_insn "*andqi_ext_2"
9201 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9206 (match_operand 1 "ext_register_operand" "%0")
9210 (match_operand 2 "ext_register_operand" "Q")
9213 (clobber (reg:CC FLAGS_REG))]
9215 "and{b}\t{%h2, %h0|%h0, %h2}"
9216 [(set_attr "type" "alu")
9217 (set_attr "length_immediate" "0")
9218 (set_attr "mode" "QI")])
9220 ;; Convert wide AND instructions with immediate operand to shorter QImode
9221 ;; equivalents when possible.
9222 ;; Don't do the splitting with memory operands, since it introduces risk
9223 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9224 ;; for size, but that can (should?) be handled by generic code instead.
9226 [(set (match_operand 0 "register_operand" "")
9227 (and (match_operand 1 "register_operand" "")
9228 (match_operand 2 "const_int_operand" "")))
9229 (clobber (reg:CC FLAGS_REG))]
9231 && QI_REG_P (operands[0])
9232 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9233 && !(~INTVAL (operands[2]) & ~(255 << 8))
9234 && GET_MODE (operands[0]) != QImode"
9235 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9236 (and:SI (zero_extract:SI (match_dup 1)
9237 (const_int 8) (const_int 8))
9239 (clobber (reg:CC FLAGS_REG))])]
9240 "operands[0] = gen_lowpart (SImode, operands[0]);
9241 operands[1] = gen_lowpart (SImode, operands[1]);
9242 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9244 ;; Since AND can be encoded with sign extended immediate, this is only
9245 ;; profitable when 7th bit is not set.
9247 [(set (match_operand 0 "register_operand" "")
9248 (and (match_operand 1 "general_operand" "")
9249 (match_operand 2 "const_int_operand" "")))
9250 (clobber (reg:CC FLAGS_REG))]
9252 && ANY_QI_REG_P (operands[0])
9253 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9254 && !(~INTVAL (operands[2]) & ~255)
9255 && !(INTVAL (operands[2]) & 128)
9256 && GET_MODE (operands[0]) != QImode"
9257 [(parallel [(set (strict_low_part (match_dup 0))
9258 (and:QI (match_dup 1)
9260 (clobber (reg:CC FLAGS_REG))])]
9261 "operands[0] = gen_lowpart (QImode, operands[0]);
9262 operands[1] = gen_lowpart (QImode, operands[1]);
9263 operands[2] = gen_lowpart (QImode, operands[2]);")
9265 ;; Logical inclusive OR instructions
9267 ;; %%% This used to optimize known byte-wide and operations to memory.
9268 ;; If this is considered useful, it should be done with splitters.
9270 (define_expand "iordi3"
9271 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9272 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9273 (match_operand:DI 2 "x86_64_general_operand" "")))
9274 (clobber (reg:CC FLAGS_REG))]
9276 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9278 (define_insn "*iordi_1_rex64"
9279 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9280 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9281 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9282 (clobber (reg:CC FLAGS_REG))]
9284 && ix86_binary_operator_ok (IOR, DImode, operands)"
9285 "or{q}\t{%2, %0|%0, %2}"
9286 [(set_attr "type" "alu")
9287 (set_attr "mode" "DI")])
9289 (define_insn "*iordi_2_rex64"
9290 [(set (reg FLAGS_REG)
9291 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9292 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9294 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9295 (ior:DI (match_dup 1) (match_dup 2)))]
9297 && ix86_match_ccmode (insn, CCNOmode)
9298 && ix86_binary_operator_ok (IOR, DImode, operands)"
9299 "or{q}\t{%2, %0|%0, %2}"
9300 [(set_attr "type" "alu")
9301 (set_attr "mode" "DI")])
9303 (define_insn "*iordi_3_rex64"
9304 [(set (reg FLAGS_REG)
9305 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9306 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9308 (clobber (match_scratch:DI 0 "=r"))]
9310 && ix86_match_ccmode (insn, CCNOmode)
9311 && ix86_binary_operator_ok (IOR, DImode, operands)"
9312 "or{q}\t{%2, %0|%0, %2}"
9313 [(set_attr "type" "alu")
9314 (set_attr "mode" "DI")])
9317 (define_expand "iorsi3"
9318 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9319 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9320 (match_operand:SI 2 "general_operand" "")))
9321 (clobber (reg:CC FLAGS_REG))]
9323 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9325 (define_insn "*iorsi_1"
9326 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9327 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9328 (match_operand:SI 2 "general_operand" "ri,g")))
9329 (clobber (reg:CC FLAGS_REG))]
9330 "ix86_binary_operator_ok (IOR, SImode, operands)"
9331 "or{l}\t{%2, %0|%0, %2}"
9332 [(set_attr "type" "alu")
9333 (set_attr "mode" "SI")])
9335 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9336 (define_insn "*iorsi_1_zext"
9337 [(set (match_operand:DI 0 "register_operand" "=r")
9339 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9340 (match_operand:SI 2 "general_operand" "g"))))
9341 (clobber (reg:CC FLAGS_REG))]
9342 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9343 "or{l}\t{%2, %k0|%k0, %2}"
9344 [(set_attr "type" "alu")
9345 (set_attr "mode" "SI")])
9347 (define_insn "*iorsi_1_zext_imm"
9348 [(set (match_operand:DI 0 "register_operand" "=r")
9349 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9350 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9351 (clobber (reg:CC FLAGS_REG))]
9353 "or{l}\t{%2, %k0|%k0, %2}"
9354 [(set_attr "type" "alu")
9355 (set_attr "mode" "SI")])
9357 (define_insn "*iorsi_2"
9358 [(set (reg FLAGS_REG)
9359 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9360 (match_operand:SI 2 "general_operand" "g,ri"))
9362 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9363 (ior:SI (match_dup 1) (match_dup 2)))]
9364 "ix86_match_ccmode (insn, CCNOmode)
9365 && ix86_binary_operator_ok (IOR, SImode, operands)"
9366 "or{l}\t{%2, %0|%0, %2}"
9367 [(set_attr "type" "alu")
9368 (set_attr "mode" "SI")])
9370 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9371 ;; ??? Special case for immediate operand is missing - it is tricky.
9372 (define_insn "*iorsi_2_zext"
9373 [(set (reg FLAGS_REG)
9374 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9375 (match_operand:SI 2 "general_operand" "g"))
9377 (set (match_operand:DI 0 "register_operand" "=r")
9378 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9379 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9380 && ix86_binary_operator_ok (IOR, SImode, operands)"
9381 "or{l}\t{%2, %k0|%k0, %2}"
9382 [(set_attr "type" "alu")
9383 (set_attr "mode" "SI")])
9385 (define_insn "*iorsi_2_zext_imm"
9386 [(set (reg FLAGS_REG)
9387 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9388 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9390 (set (match_operand:DI 0 "register_operand" "=r")
9391 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9392 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9393 && ix86_binary_operator_ok (IOR, SImode, operands)"
9394 "or{l}\t{%2, %k0|%k0, %2}"
9395 [(set_attr "type" "alu")
9396 (set_attr "mode" "SI")])
9398 (define_insn "*iorsi_3"
9399 [(set (reg FLAGS_REG)
9400 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9401 (match_operand:SI 2 "general_operand" "g"))
9403 (clobber (match_scratch:SI 0 "=r"))]
9404 "ix86_match_ccmode (insn, CCNOmode)
9405 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9406 "or{l}\t{%2, %0|%0, %2}"
9407 [(set_attr "type" "alu")
9408 (set_attr "mode" "SI")])
9410 (define_expand "iorhi3"
9411 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9412 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9413 (match_operand:HI 2 "general_operand" "")))
9414 (clobber (reg:CC FLAGS_REG))]
9415 "TARGET_HIMODE_MATH"
9416 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9418 (define_insn "*iorhi_1"
9419 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9420 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9421 (match_operand:HI 2 "general_operand" "g,ri")))
9422 (clobber (reg:CC FLAGS_REG))]
9423 "ix86_binary_operator_ok (IOR, HImode, operands)"
9424 "or{w}\t{%2, %0|%0, %2}"
9425 [(set_attr "type" "alu")
9426 (set_attr "mode" "HI")])
9428 (define_insn "*iorhi_2"
9429 [(set (reg FLAGS_REG)
9430 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9431 (match_operand:HI 2 "general_operand" "g,ri"))
9433 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9434 (ior:HI (match_dup 1) (match_dup 2)))]
9435 "ix86_match_ccmode (insn, CCNOmode)
9436 && ix86_binary_operator_ok (IOR, HImode, operands)"
9437 "or{w}\t{%2, %0|%0, %2}"
9438 [(set_attr "type" "alu")
9439 (set_attr "mode" "HI")])
9441 (define_insn "*iorhi_3"
9442 [(set (reg FLAGS_REG)
9443 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9444 (match_operand:HI 2 "general_operand" "g"))
9446 (clobber (match_scratch:HI 0 "=r"))]
9447 "ix86_match_ccmode (insn, CCNOmode)
9448 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9449 "or{w}\t{%2, %0|%0, %2}"
9450 [(set_attr "type" "alu")
9451 (set_attr "mode" "HI")])
9453 (define_expand "iorqi3"
9454 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9455 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9456 (match_operand:QI 2 "general_operand" "")))
9457 (clobber (reg:CC FLAGS_REG))]
9458 "TARGET_QIMODE_MATH"
9459 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9461 ;; %%% Potential partial reg stall on alternative 2. What to do?
9462 (define_insn "*iorqi_1"
9463 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9464 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9465 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9466 (clobber (reg:CC FLAGS_REG))]
9467 "ix86_binary_operator_ok (IOR, QImode, operands)"
9469 or{b}\t{%2, %0|%0, %2}
9470 or{b}\t{%2, %0|%0, %2}
9471 or{l}\t{%k2, %k0|%k0, %k2}"
9472 [(set_attr "type" "alu")
9473 (set_attr "mode" "QI,QI,SI")])
9475 (define_insn "*iorqi_1_slp"
9476 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9477 (ior:QI (match_dup 0)
9478 (match_operand:QI 1 "general_operand" "qmi,qi")))
9479 (clobber (reg:CC FLAGS_REG))]
9480 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9481 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9482 "or{b}\t{%1, %0|%0, %1}"
9483 [(set_attr "type" "alu1")
9484 (set_attr "mode" "QI")])
9486 (define_insn "*iorqi_2"
9487 [(set (reg FLAGS_REG)
9488 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9489 (match_operand:QI 2 "general_operand" "qim,qi"))
9491 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9492 (ior:QI (match_dup 1) (match_dup 2)))]
9493 "ix86_match_ccmode (insn, CCNOmode)
9494 && ix86_binary_operator_ok (IOR, QImode, operands)"
9495 "or{b}\t{%2, %0|%0, %2}"
9496 [(set_attr "type" "alu")
9497 (set_attr "mode" "QI")])
9499 (define_insn "*iorqi_2_slp"
9500 [(set (reg FLAGS_REG)
9501 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9502 (match_operand:QI 1 "general_operand" "qim,qi"))
9504 (set (strict_low_part (match_dup 0))
9505 (ior:QI (match_dup 0) (match_dup 1)))]
9506 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9507 && ix86_match_ccmode (insn, CCNOmode)
9508 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9509 "or{b}\t{%1, %0|%0, %1}"
9510 [(set_attr "type" "alu1")
9511 (set_attr "mode" "QI")])
9513 (define_insn "*iorqi_3"
9514 [(set (reg FLAGS_REG)
9515 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9516 (match_operand:QI 2 "general_operand" "qim"))
9518 (clobber (match_scratch:QI 0 "=q"))]
9519 "ix86_match_ccmode (insn, CCNOmode)
9520 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9521 "or{b}\t{%2, %0|%0, %2}"
9522 [(set_attr "type" "alu")
9523 (set_attr "mode" "QI")])
9525 (define_insn "iorqi_ext_0"
9526 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9531 (match_operand 1 "ext_register_operand" "0")
9534 (match_operand 2 "const_int_operand" "n")))
9535 (clobber (reg:CC FLAGS_REG))]
9536 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9537 "or{b}\t{%2, %h0|%h0, %2}"
9538 [(set_attr "type" "alu")
9539 (set_attr "length_immediate" "1")
9540 (set_attr "mode" "QI")])
9542 (define_insn "*iorqi_ext_1"
9543 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9548 (match_operand 1 "ext_register_operand" "0")
9552 (match_operand:QI 2 "general_operand" "Qm"))))
9553 (clobber (reg:CC FLAGS_REG))]
9555 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9556 "or{b}\t{%2, %h0|%h0, %2}"
9557 [(set_attr "type" "alu")
9558 (set_attr "length_immediate" "0")
9559 (set_attr "mode" "QI")])
9561 (define_insn "*iorqi_ext_1_rex64"
9562 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9567 (match_operand 1 "ext_register_operand" "0")
9571 (match_operand 2 "ext_register_operand" "Q"))))
9572 (clobber (reg:CC FLAGS_REG))]
9574 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9575 "or{b}\t{%2, %h0|%h0, %2}"
9576 [(set_attr "type" "alu")
9577 (set_attr "length_immediate" "0")
9578 (set_attr "mode" "QI")])
9580 (define_insn "*iorqi_ext_2"
9581 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9585 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9588 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9591 (clobber (reg:CC FLAGS_REG))]
9592 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9593 "ior{b}\t{%h2, %h0|%h0, %h2}"
9594 [(set_attr "type" "alu")
9595 (set_attr "length_immediate" "0")
9596 (set_attr "mode" "QI")])
9599 [(set (match_operand 0 "register_operand" "")
9600 (ior (match_operand 1 "register_operand" "")
9601 (match_operand 2 "const_int_operand" "")))
9602 (clobber (reg:CC FLAGS_REG))]
9604 && QI_REG_P (operands[0])
9605 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9606 && !(INTVAL (operands[2]) & ~(255 << 8))
9607 && GET_MODE (operands[0]) != QImode"
9608 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9609 (ior:SI (zero_extract:SI (match_dup 1)
9610 (const_int 8) (const_int 8))
9612 (clobber (reg:CC FLAGS_REG))])]
9613 "operands[0] = gen_lowpart (SImode, operands[0]);
9614 operands[1] = gen_lowpart (SImode, operands[1]);
9615 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9617 ;; Since OR can be encoded with sign extended immediate, this is only
9618 ;; profitable when 7th bit is set.
9620 [(set (match_operand 0 "register_operand" "")
9621 (ior (match_operand 1 "general_operand" "")
9622 (match_operand 2 "const_int_operand" "")))
9623 (clobber (reg:CC FLAGS_REG))]
9625 && ANY_QI_REG_P (operands[0])
9626 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9627 && !(INTVAL (operands[2]) & ~255)
9628 && (INTVAL (operands[2]) & 128)
9629 && GET_MODE (operands[0]) != QImode"
9630 [(parallel [(set (strict_low_part (match_dup 0))
9631 (ior:QI (match_dup 1)
9633 (clobber (reg:CC FLAGS_REG))])]
9634 "operands[0] = gen_lowpart (QImode, operands[0]);
9635 operands[1] = gen_lowpart (QImode, operands[1]);
9636 operands[2] = gen_lowpart (QImode, operands[2]);")
9638 ;; Logical XOR instructions
9640 ;; %%% This used to optimize known byte-wide and operations to memory.
9641 ;; If this is considered useful, it should be done with splitters.
9643 (define_expand "xordi3"
9644 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9645 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9646 (match_operand:DI 2 "x86_64_general_operand" "")))
9647 (clobber (reg:CC FLAGS_REG))]
9649 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9651 (define_insn "*xordi_1_rex64"
9652 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9653 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9654 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9655 (clobber (reg:CC FLAGS_REG))]
9657 && ix86_binary_operator_ok (XOR, DImode, operands)"
9659 xor{q}\t{%2, %0|%0, %2}
9660 xor{q}\t{%2, %0|%0, %2}"
9661 [(set_attr "type" "alu")
9662 (set_attr "mode" "DI,DI")])
9664 (define_insn "*xordi_2_rex64"
9665 [(set (reg FLAGS_REG)
9666 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9667 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9669 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9670 (xor:DI (match_dup 1) (match_dup 2)))]
9672 && ix86_match_ccmode (insn, CCNOmode)
9673 && ix86_binary_operator_ok (XOR, DImode, operands)"
9675 xor{q}\t{%2, %0|%0, %2}
9676 xor{q}\t{%2, %0|%0, %2}"
9677 [(set_attr "type" "alu")
9678 (set_attr "mode" "DI,DI")])
9680 (define_insn "*xordi_3_rex64"
9681 [(set (reg FLAGS_REG)
9682 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9683 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9685 (clobber (match_scratch:DI 0 "=r"))]
9687 && ix86_match_ccmode (insn, CCNOmode)
9688 && ix86_binary_operator_ok (XOR, DImode, operands)"
9689 "xor{q}\t{%2, %0|%0, %2}"
9690 [(set_attr "type" "alu")
9691 (set_attr "mode" "DI")])
9693 (define_expand "xorsi3"
9694 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9695 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9696 (match_operand:SI 2 "general_operand" "")))
9697 (clobber (reg:CC FLAGS_REG))]
9699 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9701 (define_insn "*xorsi_1"
9702 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9703 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9704 (match_operand:SI 2 "general_operand" "ri,rm")))
9705 (clobber (reg:CC FLAGS_REG))]
9706 "ix86_binary_operator_ok (XOR, SImode, operands)"
9707 "xor{l}\t{%2, %0|%0, %2}"
9708 [(set_attr "type" "alu")
9709 (set_attr "mode" "SI")])
9711 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9712 ;; Add speccase for immediates
9713 (define_insn "*xorsi_1_zext"
9714 [(set (match_operand:DI 0 "register_operand" "=r")
9716 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9717 (match_operand:SI 2 "general_operand" "g"))))
9718 (clobber (reg:CC FLAGS_REG))]
9719 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9720 "xor{l}\t{%2, %k0|%k0, %2}"
9721 [(set_attr "type" "alu")
9722 (set_attr "mode" "SI")])
9724 (define_insn "*xorsi_1_zext_imm"
9725 [(set (match_operand:DI 0 "register_operand" "=r")
9726 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9727 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9728 (clobber (reg:CC FLAGS_REG))]
9729 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9730 "xor{l}\t{%2, %k0|%k0, %2}"
9731 [(set_attr "type" "alu")
9732 (set_attr "mode" "SI")])
9734 (define_insn "*xorsi_2"
9735 [(set (reg FLAGS_REG)
9736 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9737 (match_operand:SI 2 "general_operand" "g,ri"))
9739 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9740 (xor:SI (match_dup 1) (match_dup 2)))]
9741 "ix86_match_ccmode (insn, CCNOmode)
9742 && ix86_binary_operator_ok (XOR, SImode, operands)"
9743 "xor{l}\t{%2, %0|%0, %2}"
9744 [(set_attr "type" "alu")
9745 (set_attr "mode" "SI")])
9747 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9748 ;; ??? Special case for immediate operand is missing - it is tricky.
9749 (define_insn "*xorsi_2_zext"
9750 [(set (reg FLAGS_REG)
9751 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9752 (match_operand:SI 2 "general_operand" "g"))
9754 (set (match_operand:DI 0 "register_operand" "=r")
9755 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9756 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9757 && ix86_binary_operator_ok (XOR, SImode, operands)"
9758 "xor{l}\t{%2, %k0|%k0, %2}"
9759 [(set_attr "type" "alu")
9760 (set_attr "mode" "SI")])
9762 (define_insn "*xorsi_2_zext_imm"
9763 [(set (reg FLAGS_REG)
9764 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9765 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9767 (set (match_operand:DI 0 "register_operand" "=r")
9768 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9769 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9770 && ix86_binary_operator_ok (XOR, SImode, operands)"
9771 "xor{l}\t{%2, %k0|%k0, %2}"
9772 [(set_attr "type" "alu")
9773 (set_attr "mode" "SI")])
9775 (define_insn "*xorsi_3"
9776 [(set (reg FLAGS_REG)
9777 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9778 (match_operand:SI 2 "general_operand" "g"))
9780 (clobber (match_scratch:SI 0 "=r"))]
9781 "ix86_match_ccmode (insn, CCNOmode)
9782 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9783 "xor{l}\t{%2, %0|%0, %2}"
9784 [(set_attr "type" "alu")
9785 (set_attr "mode" "SI")])
9787 (define_expand "xorhi3"
9788 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9789 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9790 (match_operand:HI 2 "general_operand" "")))
9791 (clobber (reg:CC FLAGS_REG))]
9792 "TARGET_HIMODE_MATH"
9793 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9795 (define_insn "*xorhi_1"
9796 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9797 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9798 (match_operand:HI 2 "general_operand" "g,ri")))
9799 (clobber (reg:CC FLAGS_REG))]
9800 "ix86_binary_operator_ok (XOR, HImode, operands)"
9801 "xor{w}\t{%2, %0|%0, %2}"
9802 [(set_attr "type" "alu")
9803 (set_attr "mode" "HI")])
9805 (define_insn "*xorhi_2"
9806 [(set (reg FLAGS_REG)
9807 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9808 (match_operand:HI 2 "general_operand" "g,ri"))
9810 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9811 (xor:HI (match_dup 1) (match_dup 2)))]
9812 "ix86_match_ccmode (insn, CCNOmode)
9813 && ix86_binary_operator_ok (XOR, HImode, operands)"
9814 "xor{w}\t{%2, %0|%0, %2}"
9815 [(set_attr "type" "alu")
9816 (set_attr "mode" "HI")])
9818 (define_insn "*xorhi_3"
9819 [(set (reg FLAGS_REG)
9820 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9821 (match_operand:HI 2 "general_operand" "g"))
9823 (clobber (match_scratch:HI 0 "=r"))]
9824 "ix86_match_ccmode (insn, CCNOmode)
9825 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9826 "xor{w}\t{%2, %0|%0, %2}"
9827 [(set_attr "type" "alu")
9828 (set_attr "mode" "HI")])
9830 (define_expand "xorqi3"
9831 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9832 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9833 (match_operand:QI 2 "general_operand" "")))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "TARGET_QIMODE_MATH"
9836 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9838 ;; %%% Potential partial reg stall on alternative 2. What to do?
9839 (define_insn "*xorqi_1"
9840 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9841 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9842 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9843 (clobber (reg:CC FLAGS_REG))]
9844 "ix86_binary_operator_ok (XOR, QImode, operands)"
9846 xor{b}\t{%2, %0|%0, %2}
9847 xor{b}\t{%2, %0|%0, %2}
9848 xor{l}\t{%k2, %k0|%k0, %k2}"
9849 [(set_attr "type" "alu")
9850 (set_attr "mode" "QI,QI,SI")])
9852 (define_insn "*xorqi_1_slp"
9853 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9854 (xor:QI (match_dup 0)
9855 (match_operand:QI 1 "general_operand" "qi,qmi")))
9856 (clobber (reg:CC FLAGS_REG))]
9857 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9858 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9859 "xor{b}\t{%1, %0|%0, %1}"
9860 [(set_attr "type" "alu1")
9861 (set_attr "mode" "QI")])
9863 (define_insn "xorqi_ext_0"
9864 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9869 (match_operand 1 "ext_register_operand" "0")
9872 (match_operand 2 "const_int_operand" "n")))
9873 (clobber (reg:CC FLAGS_REG))]
9874 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9875 "xor{b}\t{%2, %h0|%h0, %2}"
9876 [(set_attr "type" "alu")
9877 (set_attr "length_immediate" "1")
9878 (set_attr "mode" "QI")])
9880 (define_insn "*xorqi_ext_1"
9881 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9886 (match_operand 1 "ext_register_operand" "0")
9890 (match_operand:QI 2 "general_operand" "Qm"))))
9891 (clobber (reg:CC FLAGS_REG))]
9893 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9894 "xor{b}\t{%2, %h0|%h0, %2}"
9895 [(set_attr "type" "alu")
9896 (set_attr "length_immediate" "0")
9897 (set_attr "mode" "QI")])
9899 (define_insn "*xorqi_ext_1_rex64"
9900 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9905 (match_operand 1 "ext_register_operand" "0")
9909 (match_operand 2 "ext_register_operand" "Q"))))
9910 (clobber (reg:CC FLAGS_REG))]
9912 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9913 "xor{b}\t{%2, %h0|%h0, %2}"
9914 [(set_attr "type" "alu")
9915 (set_attr "length_immediate" "0")
9916 (set_attr "mode" "QI")])
9918 (define_insn "*xorqi_ext_2"
9919 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9923 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9926 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9929 (clobber (reg:CC FLAGS_REG))]
9930 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9931 "xor{b}\t{%h2, %h0|%h0, %h2}"
9932 [(set_attr "type" "alu")
9933 (set_attr "length_immediate" "0")
9934 (set_attr "mode" "QI")])
9936 (define_insn "*xorqi_cc_1"
9937 [(set (reg FLAGS_REG)
9939 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9940 (match_operand:QI 2 "general_operand" "qim,qi"))
9942 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9943 (xor:QI (match_dup 1) (match_dup 2)))]
9944 "ix86_match_ccmode (insn, CCNOmode)
9945 && ix86_binary_operator_ok (XOR, QImode, operands)"
9946 "xor{b}\t{%2, %0|%0, %2}"
9947 [(set_attr "type" "alu")
9948 (set_attr "mode" "QI")])
9950 (define_insn "*xorqi_2_slp"
9951 [(set (reg FLAGS_REG)
9952 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9953 (match_operand:QI 1 "general_operand" "qim,qi"))
9955 (set (strict_low_part (match_dup 0))
9956 (xor:QI (match_dup 0) (match_dup 1)))]
9957 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9958 && ix86_match_ccmode (insn, CCNOmode)
9959 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9960 "xor{b}\t{%1, %0|%0, %1}"
9961 [(set_attr "type" "alu1")
9962 (set_attr "mode" "QI")])
9964 (define_insn "*xorqi_cc_2"
9965 [(set (reg FLAGS_REG)
9967 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9968 (match_operand:QI 2 "general_operand" "qim"))
9970 (clobber (match_scratch:QI 0 "=q"))]
9971 "ix86_match_ccmode (insn, CCNOmode)
9972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9973 "xor{b}\t{%2, %0|%0, %2}"
9974 [(set_attr "type" "alu")
9975 (set_attr "mode" "QI")])
9977 (define_insn "*xorqi_cc_ext_1"
9978 [(set (reg FLAGS_REG)
9982 (match_operand 1 "ext_register_operand" "0")
9985 (match_operand:QI 2 "general_operand" "qmn"))
9987 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9991 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9993 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9994 "xor{b}\t{%2, %h0|%h0, %2}"
9995 [(set_attr "type" "alu")
9996 (set_attr "mode" "QI")])
9998 (define_insn "*xorqi_cc_ext_1_rex64"
9999 [(set (reg FLAGS_REG)
10003 (match_operand 1 "ext_register_operand" "0")
10006 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10008 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10012 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10014 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10015 "xor{b}\t{%2, %h0|%h0, %2}"
10016 [(set_attr "type" "alu")
10017 (set_attr "mode" "QI")])
10019 (define_expand "xorqi_cc_ext_1"
10021 (set (reg:CCNO FLAGS_REG)
10025 (match_operand 1 "ext_register_operand" "")
10028 (match_operand:QI 2 "general_operand" ""))
10030 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10034 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10040 [(set (match_operand 0 "register_operand" "")
10041 (xor (match_operand 1 "register_operand" "")
10042 (match_operand 2 "const_int_operand" "")))
10043 (clobber (reg:CC FLAGS_REG))]
10045 && QI_REG_P (operands[0])
10046 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10047 && !(INTVAL (operands[2]) & ~(255 << 8))
10048 && GET_MODE (operands[0]) != QImode"
10049 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10050 (xor:SI (zero_extract:SI (match_dup 1)
10051 (const_int 8) (const_int 8))
10053 (clobber (reg:CC FLAGS_REG))])]
10054 "operands[0] = gen_lowpart (SImode, operands[0]);
10055 operands[1] = gen_lowpart (SImode, operands[1]);
10056 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10058 ;; Since XOR can be encoded with sign extended immediate, this is only
10059 ;; profitable when 7th bit is set.
10061 [(set (match_operand 0 "register_operand" "")
10062 (xor (match_operand 1 "general_operand" "")
10063 (match_operand 2 "const_int_operand" "")))
10064 (clobber (reg:CC FLAGS_REG))]
10066 && ANY_QI_REG_P (operands[0])
10067 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10068 && !(INTVAL (operands[2]) & ~255)
10069 && (INTVAL (operands[2]) & 128)
10070 && GET_MODE (operands[0]) != QImode"
10071 [(parallel [(set (strict_low_part (match_dup 0))
10072 (xor:QI (match_dup 1)
10074 (clobber (reg:CC FLAGS_REG))])]
10075 "operands[0] = gen_lowpart (QImode, operands[0]);
10076 operands[1] = gen_lowpart (QImode, operands[1]);
10077 operands[2] = gen_lowpart (QImode, operands[2]);")
10079 ;; Negation instructions
10081 (define_expand "negti2"
10082 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10083 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10084 (clobber (reg:CC FLAGS_REG))])]
10086 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10088 (define_insn "*negti2_1"
10089 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10090 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10091 (clobber (reg:CC FLAGS_REG))]
10093 && ix86_unary_operator_ok (NEG, TImode, operands)"
10097 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10098 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10099 (clobber (reg:CC FLAGS_REG))]
10100 "TARGET_64BIT && reload_completed"
10102 [(set (reg:CCZ FLAGS_REG)
10103 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10104 (set (match_dup 0) (neg:DI (match_dup 2)))])
10106 [(set (match_dup 1)
10107 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10110 (clobber (reg:CC FLAGS_REG))])
10112 [(set (match_dup 1)
10113 (neg:DI (match_dup 1)))
10114 (clobber (reg:CC FLAGS_REG))])]
10115 "split_ti (operands+1, 1, operands+2, operands+3);
10116 split_ti (operands+0, 1, operands+0, operands+1);")
10118 (define_expand "negdi2"
10119 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10120 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10121 (clobber (reg:CC FLAGS_REG))])]
10123 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10125 (define_insn "*negdi2_1"
10126 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10127 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10128 (clobber (reg:CC FLAGS_REG))]
10130 && ix86_unary_operator_ok (NEG, DImode, operands)"
10134 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10135 (neg:DI (match_operand:DI 1 "general_operand" "")))
10136 (clobber (reg:CC FLAGS_REG))]
10137 "!TARGET_64BIT && reload_completed"
10139 [(set (reg:CCZ FLAGS_REG)
10140 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10141 (set (match_dup 0) (neg:SI (match_dup 2)))])
10143 [(set (match_dup 1)
10144 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10147 (clobber (reg:CC FLAGS_REG))])
10149 [(set (match_dup 1)
10150 (neg:SI (match_dup 1)))
10151 (clobber (reg:CC FLAGS_REG))])]
10152 "split_di (operands+1, 1, operands+2, operands+3);
10153 split_di (operands+0, 1, operands+0, operands+1);")
10155 (define_insn "*negdi2_1_rex64"
10156 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10157 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10158 (clobber (reg:CC FLAGS_REG))]
10159 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10161 [(set_attr "type" "negnot")
10162 (set_attr "mode" "DI")])
10164 ;; The problem with neg is that it does not perform (compare x 0),
10165 ;; it really performs (compare 0 x), which leaves us with the zero
10166 ;; flag being the only useful item.
10168 (define_insn "*negdi2_cmpz_rex64"
10169 [(set (reg:CCZ FLAGS_REG)
10170 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10172 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10173 (neg:DI (match_dup 1)))]
10174 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10176 [(set_attr "type" "negnot")
10177 (set_attr "mode" "DI")])
10180 (define_expand "negsi2"
10181 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10182 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10183 (clobber (reg:CC FLAGS_REG))])]
10185 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10187 (define_insn "*negsi2_1"
10188 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10189 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10190 (clobber (reg:CC FLAGS_REG))]
10191 "ix86_unary_operator_ok (NEG, SImode, operands)"
10193 [(set_attr "type" "negnot")
10194 (set_attr "mode" "SI")])
10196 ;; Combine is quite creative about this pattern.
10197 (define_insn "*negsi2_1_zext"
10198 [(set (match_operand:DI 0 "register_operand" "=r")
10199 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10202 (clobber (reg:CC FLAGS_REG))]
10203 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10205 [(set_attr "type" "negnot")
10206 (set_attr "mode" "SI")])
10208 ;; The problem with neg is that it does not perform (compare x 0),
10209 ;; it really performs (compare 0 x), which leaves us with the zero
10210 ;; flag being the only useful item.
10212 (define_insn "*negsi2_cmpz"
10213 [(set (reg:CCZ FLAGS_REG)
10214 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10216 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10217 (neg:SI (match_dup 1)))]
10218 "ix86_unary_operator_ok (NEG, SImode, operands)"
10220 [(set_attr "type" "negnot")
10221 (set_attr "mode" "SI")])
10223 (define_insn "*negsi2_cmpz_zext"
10224 [(set (reg:CCZ FLAGS_REG)
10225 (compare:CCZ (lshiftrt:DI
10227 (match_operand:DI 1 "register_operand" "0")
10231 (set (match_operand:DI 0 "register_operand" "=r")
10232 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10235 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10237 [(set_attr "type" "negnot")
10238 (set_attr "mode" "SI")])
10240 (define_expand "neghi2"
10241 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10242 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10243 (clobber (reg:CC FLAGS_REG))])]
10244 "TARGET_HIMODE_MATH"
10245 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10247 (define_insn "*neghi2_1"
10248 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10249 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10250 (clobber (reg:CC FLAGS_REG))]
10251 "ix86_unary_operator_ok (NEG, HImode, operands)"
10253 [(set_attr "type" "negnot")
10254 (set_attr "mode" "HI")])
10256 (define_insn "*neghi2_cmpz"
10257 [(set (reg:CCZ FLAGS_REG)
10258 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10260 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10261 (neg:HI (match_dup 1)))]
10262 "ix86_unary_operator_ok (NEG, HImode, operands)"
10264 [(set_attr "type" "negnot")
10265 (set_attr "mode" "HI")])
10267 (define_expand "negqi2"
10268 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10269 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10270 (clobber (reg:CC FLAGS_REG))])]
10271 "TARGET_QIMODE_MATH"
10272 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10274 (define_insn "*negqi2_1"
10275 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10276 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10277 (clobber (reg:CC FLAGS_REG))]
10278 "ix86_unary_operator_ok (NEG, QImode, operands)"
10280 [(set_attr "type" "negnot")
10281 (set_attr "mode" "QI")])
10283 (define_insn "*negqi2_cmpz"
10284 [(set (reg:CCZ FLAGS_REG)
10285 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10287 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10288 (neg:QI (match_dup 1)))]
10289 "ix86_unary_operator_ok (NEG, QImode, operands)"
10291 [(set_attr "type" "negnot")
10292 (set_attr "mode" "QI")])
10294 ;; Changing of sign for FP values is doable using integer unit too.
10296 (define_expand "neg<mode>2"
10297 [(set (match_operand:X87MODEF 0 "register_operand" "")
10298 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10299 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10300 "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10302 (define_expand "abs<mode>2"
10303 [(set (match_operand:X87MODEF 0 "register_operand" "")
10304 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10305 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10306 "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10308 (define_insn "*absneg<mode>2_mixed"
10309 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10310 (match_operator:MODEF 3 "absneg_operator"
10311 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10312 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10313 (clobber (reg:CC FLAGS_REG))]
10314 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10317 (define_insn "*absneg<mode>2_sse"
10318 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10319 (match_operator:MODEF 3 "absneg_operator"
10320 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10321 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10322 (clobber (reg:CC FLAGS_REG))]
10323 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10326 (define_insn "*absneg<mode>2_i387"
10327 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10328 (match_operator:X87MODEF 3 "absneg_operator"
10329 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10330 (use (match_operand 2 "" ""))
10331 (clobber (reg:CC FLAGS_REG))]
10332 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10335 (define_expand "negtf2"
10336 [(set (match_operand:TF 0 "register_operand" "")
10337 (neg:TF (match_operand:TF 1 "register_operand" "")))]
10339 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10341 (define_expand "abstf2"
10342 [(set (match_operand:TF 0 "register_operand" "")
10343 (abs:TF (match_operand:TF 1 "register_operand" "")))]
10345 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10347 (define_insn "*absnegtf2_sse"
10348 [(set (match_operand:TF 0 "register_operand" "=x,x")
10349 (match_operator:TF 3 "absneg_operator"
10350 [(match_operand:TF 1 "register_operand" "0,x")]))
10351 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10352 (clobber (reg:CC FLAGS_REG))]
10356 ;; Splitters for fp abs and neg.
10359 [(set (match_operand 0 "fp_register_operand" "")
10360 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10361 (use (match_operand 2 "" ""))
10362 (clobber (reg:CC FLAGS_REG))]
10364 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10367 [(set (match_operand 0 "register_operand" "")
10368 (match_operator 3 "absneg_operator"
10369 [(match_operand 1 "register_operand" "")]))
10370 (use (match_operand 2 "nonimmediate_operand" ""))
10371 (clobber (reg:CC FLAGS_REG))]
10372 "reload_completed && SSE_REG_P (operands[0])"
10373 [(set (match_dup 0) (match_dup 3))]
10375 enum machine_mode mode = GET_MODE (operands[0]);
10376 enum machine_mode vmode = GET_MODE (operands[2]);
10379 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10380 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10381 if (operands_match_p (operands[0], operands[2]))
10384 operands[1] = operands[2];
10387 if (GET_CODE (operands[3]) == ABS)
10388 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10390 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10395 [(set (match_operand:SF 0 "register_operand" "")
10396 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10397 (use (match_operand:V4SF 2 "" ""))
10398 (clobber (reg:CC FLAGS_REG))]
10400 [(parallel [(set (match_dup 0) (match_dup 1))
10401 (clobber (reg:CC FLAGS_REG))])]
10404 operands[0] = gen_lowpart (SImode, operands[0]);
10405 if (GET_CODE (operands[1]) == ABS)
10407 tmp = gen_int_mode (0x7fffffff, SImode);
10408 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10412 tmp = gen_int_mode (0x80000000, SImode);
10413 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10419 [(set (match_operand:DF 0 "register_operand" "")
10420 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10421 (use (match_operand 2 "" ""))
10422 (clobber (reg:CC FLAGS_REG))]
10424 [(parallel [(set (match_dup 0) (match_dup 1))
10425 (clobber (reg:CC FLAGS_REG))])]
10430 tmp = gen_lowpart (DImode, operands[0]);
10431 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10434 if (GET_CODE (operands[1]) == ABS)
10437 tmp = gen_rtx_NOT (DImode, tmp);
10441 operands[0] = gen_highpart (SImode, operands[0]);
10442 if (GET_CODE (operands[1]) == ABS)
10444 tmp = gen_int_mode (0x7fffffff, SImode);
10445 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10449 tmp = gen_int_mode (0x80000000, SImode);
10450 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10457 [(set (match_operand:XF 0 "register_operand" "")
10458 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10459 (use (match_operand 2 "" ""))
10460 (clobber (reg:CC FLAGS_REG))]
10462 [(parallel [(set (match_dup 0) (match_dup 1))
10463 (clobber (reg:CC FLAGS_REG))])]
10466 operands[0] = gen_rtx_REG (SImode,
10467 true_regnum (operands[0])
10468 + (TARGET_64BIT ? 1 : 2));
10469 if (GET_CODE (operands[1]) == ABS)
10471 tmp = GEN_INT (0x7fff);
10472 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10476 tmp = GEN_INT (0x8000);
10477 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10482 ;; Conditionalize these after reload. If they match before reload, we
10483 ;; lose the clobber and ability to use integer instructions.
10485 (define_insn "*neg<mode>2_1"
10486 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10487 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10489 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10491 [(set_attr "type" "fsgn")
10492 (set_attr "mode" "<MODE>")])
10494 (define_insn "*abs<mode>2_1"
10495 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10496 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10498 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10500 [(set_attr "type" "fsgn")
10501 (set_attr "mode" "<MODE>")])
10503 (define_insn "*negextendsfdf2"
10504 [(set (match_operand:DF 0 "register_operand" "=f")
10505 (neg:DF (float_extend:DF
10506 (match_operand:SF 1 "register_operand" "0"))))]
10507 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10509 [(set_attr "type" "fsgn")
10510 (set_attr "mode" "DF")])
10512 (define_insn "*negextenddfxf2"
10513 [(set (match_operand:XF 0 "register_operand" "=f")
10514 (neg:XF (float_extend:XF
10515 (match_operand:DF 1 "register_operand" "0"))))]
10518 [(set_attr "type" "fsgn")
10519 (set_attr "mode" "XF")])
10521 (define_insn "*negextendsfxf2"
10522 [(set (match_operand:XF 0 "register_operand" "=f")
10523 (neg:XF (float_extend:XF
10524 (match_operand:SF 1 "register_operand" "0"))))]
10527 [(set_attr "type" "fsgn")
10528 (set_attr "mode" "XF")])
10530 (define_insn "*absextendsfdf2"
10531 [(set (match_operand:DF 0 "register_operand" "=f")
10532 (abs:DF (float_extend:DF
10533 (match_operand:SF 1 "register_operand" "0"))))]
10534 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10536 [(set_attr "type" "fsgn")
10537 (set_attr "mode" "DF")])
10539 (define_insn "*absextenddfxf2"
10540 [(set (match_operand:XF 0 "register_operand" "=f")
10541 (abs:XF (float_extend:XF
10542 (match_operand:DF 1 "register_operand" "0"))))]
10545 [(set_attr "type" "fsgn")
10546 (set_attr "mode" "XF")])
10548 (define_insn "*absextendsfxf2"
10549 [(set (match_operand:XF 0 "register_operand" "=f")
10550 (abs:XF (float_extend:XF
10551 (match_operand:SF 1 "register_operand" "0"))))]
10554 [(set_attr "type" "fsgn")
10555 (set_attr "mode" "XF")])
10557 ;; Copysign instructions
10559 (define_mode_iterator CSGNMODE [SF DF TF])
10560 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10562 (define_expand "copysign<mode>3"
10563 [(match_operand:CSGNMODE 0 "register_operand" "")
10564 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10565 (match_operand:CSGNMODE 2 "register_operand" "")]
10566 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10567 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10569 ix86_expand_copysign (operands);
10573 (define_insn_and_split "copysign<mode>3_const"
10574 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10576 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10577 (match_operand:CSGNMODE 2 "register_operand" "0")
10578 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10580 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10581 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10583 "&& reload_completed"
10586 ix86_split_copysign_const (operands);
10590 (define_insn "copysign<mode>3_var"
10591 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10593 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10594 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10595 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10596 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10598 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10599 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10600 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10604 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10606 [(match_operand:CSGNMODE 2 "register_operand" "")
10607 (match_operand:CSGNMODE 3 "register_operand" "")
10608 (match_operand:<CSGNVMODE> 4 "" "")
10609 (match_operand:<CSGNVMODE> 5 "" "")]
10611 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10612 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10613 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10614 && reload_completed"
10617 ix86_split_copysign_var (operands);
10621 ;; One complement instructions
10623 (define_expand "one_cmpldi2"
10624 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10625 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10627 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10629 (define_insn "*one_cmpldi2_1_rex64"
10630 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10631 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10632 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10634 [(set_attr "type" "negnot")
10635 (set_attr "mode" "DI")])
10637 (define_insn "*one_cmpldi2_2_rex64"
10638 [(set (reg FLAGS_REG)
10639 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10641 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10642 (not:DI (match_dup 1)))]
10643 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10644 && ix86_unary_operator_ok (NOT, DImode, operands)"
10646 [(set_attr "type" "alu1")
10647 (set_attr "mode" "DI")])
10650 [(set (match_operand 0 "flags_reg_operand" "")
10651 (match_operator 2 "compare_operator"
10652 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10654 (set (match_operand:DI 1 "nonimmediate_operand" "")
10655 (not:DI (match_dup 3)))]
10656 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10657 [(parallel [(set (match_dup 0)
10659 [(xor:DI (match_dup 3) (const_int -1))
10662 (xor:DI (match_dup 3) (const_int -1)))])]
10665 (define_expand "one_cmplsi2"
10666 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10667 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10669 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10671 (define_insn "*one_cmplsi2_1"
10672 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10673 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10674 "ix86_unary_operator_ok (NOT, SImode, operands)"
10676 [(set_attr "type" "negnot")
10677 (set_attr "mode" "SI")])
10679 ;; ??? Currently never generated - xor is used instead.
10680 (define_insn "*one_cmplsi2_1_zext"
10681 [(set (match_operand:DI 0 "register_operand" "=r")
10682 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10683 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10685 [(set_attr "type" "negnot")
10686 (set_attr "mode" "SI")])
10688 (define_insn "*one_cmplsi2_2"
10689 [(set (reg FLAGS_REG)
10690 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10692 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10693 (not:SI (match_dup 1)))]
10694 "ix86_match_ccmode (insn, CCNOmode)
10695 && ix86_unary_operator_ok (NOT, SImode, operands)"
10697 [(set_attr "type" "alu1")
10698 (set_attr "mode" "SI")])
10701 [(set (match_operand 0 "flags_reg_operand" "")
10702 (match_operator 2 "compare_operator"
10703 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10705 (set (match_operand:SI 1 "nonimmediate_operand" "")
10706 (not:SI (match_dup 3)))]
10707 "ix86_match_ccmode (insn, CCNOmode)"
10708 [(parallel [(set (match_dup 0)
10709 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10712 (xor:SI (match_dup 3) (const_int -1)))])]
10715 ;; ??? Currently never generated - xor is used instead.
10716 (define_insn "*one_cmplsi2_2_zext"
10717 [(set (reg FLAGS_REG)
10718 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10720 (set (match_operand:DI 0 "register_operand" "=r")
10721 (zero_extend:DI (not:SI (match_dup 1))))]
10722 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10723 && ix86_unary_operator_ok (NOT, SImode, operands)"
10725 [(set_attr "type" "alu1")
10726 (set_attr "mode" "SI")])
10729 [(set (match_operand 0 "flags_reg_operand" "")
10730 (match_operator 2 "compare_operator"
10731 [(not:SI (match_operand:SI 3 "register_operand" ""))
10733 (set (match_operand:DI 1 "register_operand" "")
10734 (zero_extend:DI (not:SI (match_dup 3))))]
10735 "ix86_match_ccmode (insn, CCNOmode)"
10736 [(parallel [(set (match_dup 0)
10737 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10740 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10743 (define_expand "one_cmplhi2"
10744 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10745 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10746 "TARGET_HIMODE_MATH"
10747 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10749 (define_insn "*one_cmplhi2_1"
10750 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10751 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10752 "ix86_unary_operator_ok (NOT, HImode, operands)"
10754 [(set_attr "type" "negnot")
10755 (set_attr "mode" "HI")])
10757 (define_insn "*one_cmplhi2_2"
10758 [(set (reg FLAGS_REG)
10759 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10761 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10762 (not:HI (match_dup 1)))]
10763 "ix86_match_ccmode (insn, CCNOmode)
10764 && ix86_unary_operator_ok (NEG, HImode, operands)"
10766 [(set_attr "type" "alu1")
10767 (set_attr "mode" "HI")])
10770 [(set (match_operand 0 "flags_reg_operand" "")
10771 (match_operator 2 "compare_operator"
10772 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10774 (set (match_operand:HI 1 "nonimmediate_operand" "")
10775 (not:HI (match_dup 3)))]
10776 "ix86_match_ccmode (insn, CCNOmode)"
10777 [(parallel [(set (match_dup 0)
10778 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10781 (xor:HI (match_dup 3) (const_int -1)))])]
10784 ;; %%% Potential partial reg stall on alternative 1. What to do?
10785 (define_expand "one_cmplqi2"
10786 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10787 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10788 "TARGET_QIMODE_MATH"
10789 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10791 (define_insn "*one_cmplqi2_1"
10792 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10793 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10794 "ix86_unary_operator_ok (NOT, QImode, operands)"
10798 [(set_attr "type" "negnot")
10799 (set_attr "mode" "QI,SI")])
10801 (define_insn "*one_cmplqi2_2"
10802 [(set (reg FLAGS_REG)
10803 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10805 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10806 (not:QI (match_dup 1)))]
10807 "ix86_match_ccmode (insn, CCNOmode)
10808 && ix86_unary_operator_ok (NOT, QImode, operands)"
10810 [(set_attr "type" "alu1")
10811 (set_attr "mode" "QI")])
10814 [(set (match_operand 0 "flags_reg_operand" "")
10815 (match_operator 2 "compare_operator"
10816 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10818 (set (match_operand:QI 1 "nonimmediate_operand" "")
10819 (not:QI (match_dup 3)))]
10820 "ix86_match_ccmode (insn, CCNOmode)"
10821 [(parallel [(set (match_dup 0)
10822 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10825 (xor:QI (match_dup 3) (const_int -1)))])]
10828 ;; Arithmetic shift instructions
10830 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10831 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10832 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10833 ;; from the assembler input.
10835 ;; This instruction shifts the target reg/mem as usual, but instead of
10836 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10837 ;; is a left shift double, bits are taken from the high order bits of
10838 ;; reg, else if the insn is a shift right double, bits are taken from the
10839 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10840 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10842 ;; Since sh[lr]d does not change the `reg' operand, that is done
10843 ;; separately, making all shifts emit pairs of shift double and normal
10844 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10845 ;; support a 63 bit shift, each shift where the count is in a reg expands
10846 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10848 ;; If the shift count is a constant, we need never emit more than one
10849 ;; shift pair, instead using moves and sign extension for counts greater
10852 (define_expand "ashlti3"
10853 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10854 (ashift:TI (match_operand:TI 1 "register_operand" "")
10855 (match_operand:QI 2 "nonmemory_operand" "")))
10856 (clobber (reg:CC FLAGS_REG))])]
10859 if (! immediate_operand (operands[2], QImode))
10861 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10864 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10868 (define_insn "ashlti3_1"
10869 [(set (match_operand:TI 0 "register_operand" "=r")
10870 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10871 (match_operand:QI 2 "register_operand" "c")))
10872 (clobber (match_scratch:DI 3 "=&r"))
10873 (clobber (reg:CC FLAGS_REG))]
10876 [(set_attr "type" "multi")])
10878 ;; This pattern must be defined before *ashlti3_2 to prevent
10879 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10881 (define_insn "sse2_ashlti3"
10882 [(set (match_operand:TI 0 "register_operand" "=x")
10883 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10884 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10887 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10888 return "pslldq\t{%2, %0|%0, %2}";
10890 [(set_attr "type" "sseishft")
10891 (set_attr "prefix_data16" "1")
10892 (set_attr "mode" "TI")])
10894 (define_insn "*ashlti3_2"
10895 [(set (match_operand:TI 0 "register_operand" "=r")
10896 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10897 (match_operand:QI 2 "immediate_operand" "O")))
10898 (clobber (reg:CC FLAGS_REG))]
10901 [(set_attr "type" "multi")])
10904 [(set (match_operand:TI 0 "register_operand" "")
10905 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10906 (match_operand:QI 2 "register_operand" "")))
10907 (clobber (match_scratch:DI 3 ""))
10908 (clobber (reg:CC FLAGS_REG))]
10909 "TARGET_64BIT && reload_completed"
10911 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10914 [(set (match_operand:TI 0 "register_operand" "")
10915 (ashift:TI (match_operand:TI 1 "register_operand" "")
10916 (match_operand:QI 2 "immediate_operand" "")))
10917 (clobber (reg:CC FLAGS_REG))]
10918 "TARGET_64BIT && reload_completed"
10920 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10922 (define_insn "x86_64_shld"
10923 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10924 (ior:DI (ashift:DI (match_dup 0)
10925 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10926 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10927 (minus:QI (const_int 64) (match_dup 2)))))
10928 (clobber (reg:CC FLAGS_REG))]
10931 shld{q}\t{%2, %1, %0|%0, %1, %2}
10932 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10933 [(set_attr "type" "ishift")
10934 (set_attr "prefix_0f" "1")
10935 (set_attr "mode" "DI")
10936 (set_attr "athlon_decode" "vector")
10937 (set_attr "amdfam10_decode" "vector")])
10939 (define_expand "x86_64_shift_adj"
10940 [(set (reg:CCZ FLAGS_REG)
10941 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10944 (set (match_operand:DI 0 "register_operand" "")
10945 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10946 (match_operand:DI 1 "register_operand" "")
10949 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10950 (match_operand:DI 3 "register_operand" "r")
10955 (define_expand "ashldi3"
10956 [(set (match_operand:DI 0 "shiftdi_operand" "")
10957 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10958 (match_operand:QI 2 "nonmemory_operand" "")))]
10960 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10962 (define_insn "*ashldi3_1_rex64"
10963 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10964 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10965 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10966 (clobber (reg:CC FLAGS_REG))]
10967 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10969 switch (get_attr_type (insn))
10972 gcc_assert (operands[2] == const1_rtx);
10973 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10974 return "add{q}\t%0, %0";
10977 gcc_assert (CONST_INT_P (operands[2]));
10978 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10979 operands[1] = gen_rtx_MULT (DImode, operands[1],
10980 GEN_INT (1 << INTVAL (operands[2])));
10981 return "lea{q}\t{%a1, %0|%0, %a1}";
10984 if (REG_P (operands[2]))
10985 return "sal{q}\t{%b2, %0|%0, %b2}";
10986 else if (operands[2] == const1_rtx
10987 && (TARGET_SHIFT1 || optimize_size))
10988 return "sal{q}\t%0";
10990 return "sal{q}\t{%2, %0|%0, %2}";
10993 [(set (attr "type")
10994 (cond [(eq_attr "alternative" "1")
10995 (const_string "lea")
10996 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10998 (match_operand 0 "register_operand" ""))
10999 (match_operand 2 "const1_operand" ""))
11000 (const_string "alu")
11002 (const_string "ishift")))
11003 (set_attr "mode" "DI")])
11005 ;; Convert lea to the lea pattern to avoid flags dependency.
11007 [(set (match_operand:DI 0 "register_operand" "")
11008 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11009 (match_operand:QI 2 "immediate_operand" "")))
11010 (clobber (reg:CC FLAGS_REG))]
11011 "TARGET_64BIT && reload_completed
11012 && true_regnum (operands[0]) != true_regnum (operands[1])"
11013 [(set (match_dup 0)
11014 (mult:DI (match_dup 1)
11016 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11018 ;; This pattern can't accept a variable shift count, since shifts by
11019 ;; zero don't affect the flags. We assume that shifts by constant
11020 ;; zero are optimized away.
11021 (define_insn "*ashldi3_cmp_rex64"
11022 [(set (reg FLAGS_REG)
11024 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11025 (match_operand:QI 2 "immediate_operand" "e"))
11027 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11028 (ashift:DI (match_dup 1) (match_dup 2)))]
11031 || !TARGET_PARTIAL_FLAG_REG_STALL
11032 || (operands[2] == const1_rtx
11034 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11035 && ix86_match_ccmode (insn, CCGOCmode)
11036 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11038 switch (get_attr_type (insn))
11041 gcc_assert (operands[2] == const1_rtx);
11042 return "add{q}\t%0, %0";
11045 if (REG_P (operands[2]))
11046 return "sal{q}\t{%b2, %0|%0, %b2}";
11047 else if (operands[2] == const1_rtx
11048 && (TARGET_SHIFT1 || optimize_size))
11049 return "sal{q}\t%0";
11051 return "sal{q}\t{%2, %0|%0, %2}";
11054 [(set (attr "type")
11055 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11057 (match_operand 0 "register_operand" ""))
11058 (match_operand 2 "const1_operand" ""))
11059 (const_string "alu")
11061 (const_string "ishift")))
11062 (set_attr "mode" "DI")])
11064 (define_insn "*ashldi3_cconly_rex64"
11065 [(set (reg FLAGS_REG)
11067 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11068 (match_operand:QI 2 "immediate_operand" "e"))
11070 (clobber (match_scratch:DI 0 "=r"))]
11073 || !TARGET_PARTIAL_FLAG_REG_STALL
11074 || (operands[2] == const1_rtx
11076 || TARGET_DOUBLE_WITH_ADD)))
11077 && ix86_match_ccmode (insn, CCGOCmode)
11078 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11080 switch (get_attr_type (insn))
11083 gcc_assert (operands[2] == const1_rtx);
11084 return "add{q}\t%0, %0";
11087 if (REG_P (operands[2]))
11088 return "sal{q}\t{%b2, %0|%0, %b2}";
11089 else if (operands[2] == const1_rtx
11090 && (TARGET_SHIFT1 || optimize_size))
11091 return "sal{q}\t%0";
11093 return "sal{q}\t{%2, %0|%0, %2}";
11096 [(set (attr "type")
11097 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11099 (match_operand 0 "register_operand" ""))
11100 (match_operand 2 "const1_operand" ""))
11101 (const_string "alu")
11103 (const_string "ishift")))
11104 (set_attr "mode" "DI")])
11106 (define_insn "*ashldi3_1"
11107 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11108 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11109 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11110 (clobber (reg:CC FLAGS_REG))]
11113 [(set_attr "type" "multi")])
11115 ;; By default we don't ask for a scratch register, because when DImode
11116 ;; values are manipulated, registers are already at a premium. But if
11117 ;; we have one handy, we won't turn it away.
11119 [(match_scratch:SI 3 "r")
11120 (parallel [(set (match_operand:DI 0 "register_operand" "")
11121 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11122 (match_operand:QI 2 "nonmemory_operand" "")))
11123 (clobber (reg:CC FLAGS_REG))])
11125 "!TARGET_64BIT && TARGET_CMOVE"
11127 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11130 [(set (match_operand:DI 0 "register_operand" "")
11131 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11132 (match_operand:QI 2 "nonmemory_operand" "")))
11133 (clobber (reg:CC FLAGS_REG))]
11134 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11135 ? epilogue_completed : reload_completed)"
11137 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11139 (define_insn "x86_shld_1"
11140 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11141 (ior:SI (ashift:SI (match_dup 0)
11142 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11143 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11144 (minus:QI (const_int 32) (match_dup 2)))))
11145 (clobber (reg:CC FLAGS_REG))]
11148 shld{l}\t{%2, %1, %0|%0, %1, %2}
11149 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11150 [(set_attr "type" "ishift")
11151 (set_attr "prefix_0f" "1")
11152 (set_attr "mode" "SI")
11153 (set_attr "pent_pair" "np")
11154 (set_attr "athlon_decode" "vector")
11155 (set_attr "amdfam10_decode" "vector")])
11157 (define_expand "x86_shift_adj_1"
11158 [(set (reg:CCZ FLAGS_REG)
11159 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11162 (set (match_operand:SI 0 "register_operand" "")
11163 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11164 (match_operand:SI 1 "register_operand" "")
11167 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11168 (match_operand:SI 3 "register_operand" "r")
11173 (define_expand "x86_shift_adj_2"
11174 [(use (match_operand:SI 0 "register_operand" ""))
11175 (use (match_operand:SI 1 "register_operand" ""))
11176 (use (match_operand:QI 2 "register_operand" ""))]
11179 rtx label = gen_label_rtx ();
11182 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11184 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11185 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11186 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11187 gen_rtx_LABEL_REF (VOIDmode, label),
11189 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11190 JUMP_LABEL (tmp) = label;
11192 emit_move_insn (operands[0], operands[1]);
11193 ix86_expand_clear (operands[1]);
11195 emit_label (label);
11196 LABEL_NUSES (label) = 1;
11201 (define_expand "ashlsi3"
11202 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11203 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11204 (match_operand:QI 2 "nonmemory_operand" "")))
11205 (clobber (reg:CC FLAGS_REG))]
11207 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11209 (define_insn "*ashlsi3_1"
11210 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11211 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11212 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11213 (clobber (reg:CC FLAGS_REG))]
11214 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11216 switch (get_attr_type (insn))
11219 gcc_assert (operands[2] == const1_rtx);
11220 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11221 return "add{l}\t%0, %0";
11227 if (REG_P (operands[2]))
11228 return "sal{l}\t{%b2, %0|%0, %b2}";
11229 else if (operands[2] == const1_rtx
11230 && (TARGET_SHIFT1 || optimize_size))
11231 return "sal{l}\t%0";
11233 return "sal{l}\t{%2, %0|%0, %2}";
11236 [(set (attr "type")
11237 (cond [(eq_attr "alternative" "1")
11238 (const_string "lea")
11239 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11241 (match_operand 0 "register_operand" ""))
11242 (match_operand 2 "const1_operand" ""))
11243 (const_string "alu")
11245 (const_string "ishift")))
11246 (set_attr "mode" "SI")])
11248 ;; Convert lea to the lea pattern to avoid flags dependency.
11250 [(set (match_operand 0 "register_operand" "")
11251 (ashift (match_operand 1 "index_register_operand" "")
11252 (match_operand:QI 2 "const_int_operand" "")))
11253 (clobber (reg:CC FLAGS_REG))]
11255 && true_regnum (operands[0]) != true_regnum (operands[1])
11256 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11260 enum machine_mode mode = GET_MODE (operands[0]);
11262 if (GET_MODE_SIZE (mode) < 4)
11263 operands[0] = gen_lowpart (SImode, operands[0]);
11265 operands[1] = gen_lowpart (Pmode, operands[1]);
11266 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11268 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11269 if (Pmode != SImode)
11270 pat = gen_rtx_SUBREG (SImode, pat, 0);
11271 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11275 ;; Rare case of shifting RSP is handled by generating move and shift
11277 [(set (match_operand 0 "register_operand" "")
11278 (ashift (match_operand 1 "register_operand" "")
11279 (match_operand:QI 2 "const_int_operand" "")))
11280 (clobber (reg:CC FLAGS_REG))]
11282 && true_regnum (operands[0]) != true_regnum (operands[1])"
11286 emit_move_insn (operands[0], operands[1]);
11287 pat = gen_rtx_SET (VOIDmode, operands[0],
11288 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11289 operands[0], operands[2]));
11290 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11291 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11295 (define_insn "*ashlsi3_1_zext"
11296 [(set (match_operand:DI 0 "register_operand" "=r,r")
11297 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11298 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11299 (clobber (reg:CC FLAGS_REG))]
11300 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11302 switch (get_attr_type (insn))
11305 gcc_assert (operands[2] == const1_rtx);
11306 return "add{l}\t%k0, %k0";
11312 if (REG_P (operands[2]))
11313 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11314 else if (operands[2] == const1_rtx
11315 && (TARGET_SHIFT1 || optimize_size))
11316 return "sal{l}\t%k0";
11318 return "sal{l}\t{%2, %k0|%k0, %2}";
11321 [(set (attr "type")
11322 (cond [(eq_attr "alternative" "1")
11323 (const_string "lea")
11324 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11326 (match_operand 2 "const1_operand" ""))
11327 (const_string "alu")
11329 (const_string "ishift")))
11330 (set_attr "mode" "SI")])
11332 ;; Convert lea to the lea pattern to avoid flags dependency.
11334 [(set (match_operand:DI 0 "register_operand" "")
11335 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11336 (match_operand:QI 2 "const_int_operand" ""))))
11337 (clobber (reg:CC FLAGS_REG))]
11338 "TARGET_64BIT && reload_completed
11339 && true_regnum (operands[0]) != true_regnum (operands[1])"
11340 [(set (match_dup 0) (zero_extend:DI
11341 (subreg:SI (mult:SI (match_dup 1)
11342 (match_dup 2)) 0)))]
11344 operands[1] = gen_lowpart (Pmode, operands[1]);
11345 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11348 ;; This pattern can't accept a variable shift count, since shifts by
11349 ;; zero don't affect the flags. We assume that shifts by constant
11350 ;; zero are optimized away.
11351 (define_insn "*ashlsi3_cmp"
11352 [(set (reg FLAGS_REG)
11354 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11355 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11357 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11358 (ashift:SI (match_dup 1) (match_dup 2)))]
11360 || !TARGET_PARTIAL_FLAG_REG_STALL
11361 || (operands[2] == const1_rtx
11363 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11364 && ix86_match_ccmode (insn, CCGOCmode)
11365 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11367 switch (get_attr_type (insn))
11370 gcc_assert (operands[2] == const1_rtx);
11371 return "add{l}\t%0, %0";
11374 if (REG_P (operands[2]))
11375 return "sal{l}\t{%b2, %0|%0, %b2}";
11376 else if (operands[2] == const1_rtx
11377 && (TARGET_SHIFT1 || optimize_size))
11378 return "sal{l}\t%0";
11380 return "sal{l}\t{%2, %0|%0, %2}";
11383 [(set (attr "type")
11384 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11386 (match_operand 0 "register_operand" ""))
11387 (match_operand 2 "const1_operand" ""))
11388 (const_string "alu")
11390 (const_string "ishift")))
11391 (set_attr "mode" "SI")])
11393 (define_insn "*ashlsi3_cconly"
11394 [(set (reg FLAGS_REG)
11396 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11397 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11399 (clobber (match_scratch:SI 0 "=r"))]
11401 || !TARGET_PARTIAL_FLAG_REG_STALL
11402 || (operands[2] == const1_rtx
11404 || TARGET_DOUBLE_WITH_ADD)))
11405 && ix86_match_ccmode (insn, CCGOCmode)
11406 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11408 switch (get_attr_type (insn))
11411 gcc_assert (operands[2] == const1_rtx);
11412 return "add{l}\t%0, %0";
11415 if (REG_P (operands[2]))
11416 return "sal{l}\t{%b2, %0|%0, %b2}";
11417 else if (operands[2] == const1_rtx
11418 && (TARGET_SHIFT1 || optimize_size))
11419 return "sal{l}\t%0";
11421 return "sal{l}\t{%2, %0|%0, %2}";
11424 [(set (attr "type")
11425 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11427 (match_operand 0 "register_operand" ""))
11428 (match_operand 2 "const1_operand" ""))
11429 (const_string "alu")
11431 (const_string "ishift")))
11432 (set_attr "mode" "SI")])
11434 (define_insn "*ashlsi3_cmp_zext"
11435 [(set (reg FLAGS_REG)
11437 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11438 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11440 (set (match_operand:DI 0 "register_operand" "=r")
11441 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11444 || !TARGET_PARTIAL_FLAG_REG_STALL
11445 || (operands[2] == const1_rtx
11447 || TARGET_DOUBLE_WITH_ADD)))
11448 && ix86_match_ccmode (insn, CCGOCmode)
11449 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11451 switch (get_attr_type (insn))
11454 gcc_assert (operands[2] == const1_rtx);
11455 return "add{l}\t%k0, %k0";
11458 if (REG_P (operands[2]))
11459 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11460 else if (operands[2] == const1_rtx
11461 && (TARGET_SHIFT1 || optimize_size))
11462 return "sal{l}\t%k0";
11464 return "sal{l}\t{%2, %k0|%k0, %2}";
11467 [(set (attr "type")
11468 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11470 (match_operand 2 "const1_operand" ""))
11471 (const_string "alu")
11473 (const_string "ishift")))
11474 (set_attr "mode" "SI")])
11476 (define_expand "ashlhi3"
11477 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11478 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11479 (match_operand:QI 2 "nonmemory_operand" "")))
11480 (clobber (reg:CC FLAGS_REG))]
11481 "TARGET_HIMODE_MATH"
11482 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11484 (define_insn "*ashlhi3_1_lea"
11485 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11486 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11487 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11488 (clobber (reg:CC FLAGS_REG))]
11489 "!TARGET_PARTIAL_REG_STALL
11490 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11492 switch (get_attr_type (insn))
11497 gcc_assert (operands[2] == const1_rtx);
11498 return "add{w}\t%0, %0";
11501 if (REG_P (operands[2]))
11502 return "sal{w}\t{%b2, %0|%0, %b2}";
11503 else if (operands[2] == const1_rtx
11504 && (TARGET_SHIFT1 || optimize_size))
11505 return "sal{w}\t%0";
11507 return "sal{w}\t{%2, %0|%0, %2}";
11510 [(set (attr "type")
11511 (cond [(eq_attr "alternative" "1")
11512 (const_string "lea")
11513 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11515 (match_operand 0 "register_operand" ""))
11516 (match_operand 2 "const1_operand" ""))
11517 (const_string "alu")
11519 (const_string "ishift")))
11520 (set_attr "mode" "HI,SI")])
11522 (define_insn "*ashlhi3_1"
11523 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11524 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11525 (match_operand:QI 2 "nonmemory_operand" "cI")))
11526 (clobber (reg:CC FLAGS_REG))]
11527 "TARGET_PARTIAL_REG_STALL
11528 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11530 switch (get_attr_type (insn))
11533 gcc_assert (operands[2] == const1_rtx);
11534 return "add{w}\t%0, %0";
11537 if (REG_P (operands[2]))
11538 return "sal{w}\t{%b2, %0|%0, %b2}";
11539 else if (operands[2] == const1_rtx
11540 && (TARGET_SHIFT1 || optimize_size))
11541 return "sal{w}\t%0";
11543 return "sal{w}\t{%2, %0|%0, %2}";
11546 [(set (attr "type")
11547 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11549 (match_operand 0 "register_operand" ""))
11550 (match_operand 2 "const1_operand" ""))
11551 (const_string "alu")
11553 (const_string "ishift")))
11554 (set_attr "mode" "HI")])
11556 ;; This pattern can't accept a variable shift count, since shifts by
11557 ;; zero don't affect the flags. We assume that shifts by constant
11558 ;; zero are optimized away.
11559 (define_insn "*ashlhi3_cmp"
11560 [(set (reg FLAGS_REG)
11562 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11563 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11565 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11566 (ashift:HI (match_dup 1) (match_dup 2)))]
11568 || !TARGET_PARTIAL_FLAG_REG_STALL
11569 || (operands[2] == const1_rtx
11571 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11572 && ix86_match_ccmode (insn, CCGOCmode)
11573 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11575 switch (get_attr_type (insn))
11578 gcc_assert (operands[2] == const1_rtx);
11579 return "add{w}\t%0, %0";
11582 if (REG_P (operands[2]))
11583 return "sal{w}\t{%b2, %0|%0, %b2}";
11584 else if (operands[2] == const1_rtx
11585 && (TARGET_SHIFT1 || optimize_size))
11586 return "sal{w}\t%0";
11588 return "sal{w}\t{%2, %0|%0, %2}";
11591 [(set (attr "type")
11592 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11594 (match_operand 0 "register_operand" ""))
11595 (match_operand 2 "const1_operand" ""))
11596 (const_string "alu")
11598 (const_string "ishift")))
11599 (set_attr "mode" "HI")])
11601 (define_insn "*ashlhi3_cconly"
11602 [(set (reg FLAGS_REG)
11604 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11605 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11607 (clobber (match_scratch:HI 0 "=r"))]
11609 || !TARGET_PARTIAL_FLAG_REG_STALL
11610 || (operands[2] == const1_rtx
11612 || TARGET_DOUBLE_WITH_ADD)))
11613 && ix86_match_ccmode (insn, CCGOCmode)
11614 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11616 switch (get_attr_type (insn))
11619 gcc_assert (operands[2] == const1_rtx);
11620 return "add{w}\t%0, %0";
11623 if (REG_P (operands[2]))
11624 return "sal{w}\t{%b2, %0|%0, %b2}";
11625 else if (operands[2] == const1_rtx
11626 && (TARGET_SHIFT1 || optimize_size))
11627 return "sal{w}\t%0";
11629 return "sal{w}\t{%2, %0|%0, %2}";
11632 [(set (attr "type")
11633 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11635 (match_operand 0 "register_operand" ""))
11636 (match_operand 2 "const1_operand" ""))
11637 (const_string "alu")
11639 (const_string "ishift")))
11640 (set_attr "mode" "HI")])
11642 (define_expand "ashlqi3"
11643 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11644 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11645 (match_operand:QI 2 "nonmemory_operand" "")))
11646 (clobber (reg:CC FLAGS_REG))]
11647 "TARGET_QIMODE_MATH"
11648 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11650 ;; %%% Potential partial reg stall on alternative 2. What to do?
11652 (define_insn "*ashlqi3_1_lea"
11653 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11654 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11655 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11656 (clobber (reg:CC FLAGS_REG))]
11657 "!TARGET_PARTIAL_REG_STALL
11658 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11660 switch (get_attr_type (insn))
11665 gcc_assert (operands[2] == const1_rtx);
11666 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11667 return "add{l}\t%k0, %k0";
11669 return "add{b}\t%0, %0";
11672 if (REG_P (operands[2]))
11674 if (get_attr_mode (insn) == MODE_SI)
11675 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11677 return "sal{b}\t{%b2, %0|%0, %b2}";
11679 else if (operands[2] == const1_rtx
11680 && (TARGET_SHIFT1 || optimize_size))
11682 if (get_attr_mode (insn) == MODE_SI)
11683 return "sal{l}\t%0";
11685 return "sal{b}\t%0";
11689 if (get_attr_mode (insn) == MODE_SI)
11690 return "sal{l}\t{%2, %k0|%k0, %2}";
11692 return "sal{b}\t{%2, %0|%0, %2}";
11696 [(set (attr "type")
11697 (cond [(eq_attr "alternative" "2")
11698 (const_string "lea")
11699 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11701 (match_operand 0 "register_operand" ""))
11702 (match_operand 2 "const1_operand" ""))
11703 (const_string "alu")
11705 (const_string "ishift")))
11706 (set_attr "mode" "QI,SI,SI")])
11708 (define_insn "*ashlqi3_1"
11709 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11710 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11711 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11712 (clobber (reg:CC FLAGS_REG))]
11713 "TARGET_PARTIAL_REG_STALL
11714 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11716 switch (get_attr_type (insn))
11719 gcc_assert (operands[2] == const1_rtx);
11720 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11721 return "add{l}\t%k0, %k0";
11723 return "add{b}\t%0, %0";
11726 if (REG_P (operands[2]))
11728 if (get_attr_mode (insn) == MODE_SI)
11729 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11731 return "sal{b}\t{%b2, %0|%0, %b2}";
11733 else if (operands[2] == const1_rtx
11734 && (TARGET_SHIFT1 || optimize_size))
11736 if (get_attr_mode (insn) == MODE_SI)
11737 return "sal{l}\t%0";
11739 return "sal{b}\t%0";
11743 if (get_attr_mode (insn) == MODE_SI)
11744 return "sal{l}\t{%2, %k0|%k0, %2}";
11746 return "sal{b}\t{%2, %0|%0, %2}";
11750 [(set (attr "type")
11751 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11753 (match_operand 0 "register_operand" ""))
11754 (match_operand 2 "const1_operand" ""))
11755 (const_string "alu")
11757 (const_string "ishift")))
11758 (set_attr "mode" "QI,SI")])
11760 ;; This pattern can't accept a variable shift count, since shifts by
11761 ;; zero don't affect the flags. We assume that shifts by constant
11762 ;; zero are optimized away.
11763 (define_insn "*ashlqi3_cmp"
11764 [(set (reg FLAGS_REG)
11766 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11767 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11769 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11770 (ashift:QI (match_dup 1) (match_dup 2)))]
11772 || !TARGET_PARTIAL_FLAG_REG_STALL
11773 || (operands[2] == const1_rtx
11775 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11776 && ix86_match_ccmode (insn, CCGOCmode)
11777 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11779 switch (get_attr_type (insn))
11782 gcc_assert (operands[2] == const1_rtx);
11783 return "add{b}\t%0, %0";
11786 if (REG_P (operands[2]))
11787 return "sal{b}\t{%b2, %0|%0, %b2}";
11788 else if (operands[2] == const1_rtx
11789 && (TARGET_SHIFT1 || optimize_size))
11790 return "sal{b}\t%0";
11792 return "sal{b}\t{%2, %0|%0, %2}";
11795 [(set (attr "type")
11796 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11798 (match_operand 0 "register_operand" ""))
11799 (match_operand 2 "const1_operand" ""))
11800 (const_string "alu")
11802 (const_string "ishift")))
11803 (set_attr "mode" "QI")])
11805 (define_insn "*ashlqi3_cconly"
11806 [(set (reg FLAGS_REG)
11808 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11809 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11811 (clobber (match_scratch:QI 0 "=q"))]
11813 || !TARGET_PARTIAL_FLAG_REG_STALL
11814 || (operands[2] == const1_rtx
11816 || TARGET_DOUBLE_WITH_ADD)))
11817 && ix86_match_ccmode (insn, CCGOCmode)
11818 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11820 switch (get_attr_type (insn))
11823 gcc_assert (operands[2] == const1_rtx);
11824 return "add{b}\t%0, %0";
11827 if (REG_P (operands[2]))
11828 return "sal{b}\t{%b2, %0|%0, %b2}";
11829 else if (operands[2] == const1_rtx
11830 && (TARGET_SHIFT1 || optimize_size))
11831 return "sal{b}\t%0";
11833 return "sal{b}\t{%2, %0|%0, %2}";
11836 [(set (attr "type")
11837 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11839 (match_operand 0 "register_operand" ""))
11840 (match_operand 2 "const1_operand" ""))
11841 (const_string "alu")
11843 (const_string "ishift")))
11844 (set_attr "mode" "QI")])
11846 ;; See comment above `ashldi3' about how this works.
11848 (define_expand "ashrti3"
11849 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11850 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11851 (match_operand:QI 2 "nonmemory_operand" "")))
11852 (clobber (reg:CC FLAGS_REG))])]
11855 if (! immediate_operand (operands[2], QImode))
11857 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11860 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11864 (define_insn "ashrti3_1"
11865 [(set (match_operand:TI 0 "register_operand" "=r")
11866 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11867 (match_operand:QI 2 "register_operand" "c")))
11868 (clobber (match_scratch:DI 3 "=&r"))
11869 (clobber (reg:CC FLAGS_REG))]
11872 [(set_attr "type" "multi")])
11874 (define_insn "*ashrti3_2"
11875 [(set (match_operand:TI 0 "register_operand" "=r")
11876 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11877 (match_operand:QI 2 "immediate_operand" "O")))
11878 (clobber (reg:CC FLAGS_REG))]
11881 [(set_attr "type" "multi")])
11884 [(set (match_operand:TI 0 "register_operand" "")
11885 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11886 (match_operand:QI 2 "register_operand" "")))
11887 (clobber (match_scratch:DI 3 ""))
11888 (clobber (reg:CC FLAGS_REG))]
11889 "TARGET_64BIT && reload_completed"
11891 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11894 [(set (match_operand:TI 0 "register_operand" "")
11895 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11896 (match_operand:QI 2 "immediate_operand" "")))
11897 (clobber (reg:CC FLAGS_REG))]
11898 "TARGET_64BIT && reload_completed"
11900 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11902 (define_insn "x86_64_shrd"
11903 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11904 (ior:DI (ashiftrt:DI (match_dup 0)
11905 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11906 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11907 (minus:QI (const_int 64) (match_dup 2)))))
11908 (clobber (reg:CC FLAGS_REG))]
11911 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11912 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11913 [(set_attr "type" "ishift")
11914 (set_attr "prefix_0f" "1")
11915 (set_attr "mode" "DI")
11916 (set_attr "athlon_decode" "vector")
11917 (set_attr "amdfam10_decode" "vector")])
11919 (define_expand "ashrdi3"
11920 [(set (match_operand:DI 0 "shiftdi_operand" "")
11921 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11922 (match_operand:QI 2 "nonmemory_operand" "")))]
11924 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11926 (define_insn "*ashrdi3_63_rex64"
11927 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11928 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11929 (match_operand:DI 2 "const_int_operand" "i,i")))
11930 (clobber (reg:CC FLAGS_REG))]
11931 "TARGET_64BIT && INTVAL (operands[2]) == 63
11932 && (TARGET_USE_CLTD || optimize_size)
11933 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11936 sar{q}\t{%2, %0|%0, %2}"
11937 [(set_attr "type" "imovx,ishift")
11938 (set_attr "prefix_0f" "0,*")
11939 (set_attr "length_immediate" "0,*")
11940 (set_attr "modrm" "0,1")
11941 (set_attr "mode" "DI")])
11943 (define_insn "*ashrdi3_1_one_bit_rex64"
11944 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11945 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11946 (match_operand:QI 2 "const1_operand" "")))
11947 (clobber (reg:CC FLAGS_REG))]
11949 && (TARGET_SHIFT1 || optimize_size)
11950 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11952 [(set_attr "type" "ishift")
11953 (set (attr "length")
11954 (if_then_else (match_operand:DI 0 "register_operand" "")
11956 (const_string "*")))])
11958 (define_insn "*ashrdi3_1_rex64"
11959 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11960 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11961 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11962 (clobber (reg:CC FLAGS_REG))]
11963 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11965 sar{q}\t{%2, %0|%0, %2}
11966 sar{q}\t{%b2, %0|%0, %b2}"
11967 [(set_attr "type" "ishift")
11968 (set_attr "mode" "DI")])
11970 ;; This pattern can't accept a variable shift count, since shifts by
11971 ;; zero don't affect the flags. We assume that shifts by constant
11972 ;; zero are optimized away.
11973 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11974 [(set (reg FLAGS_REG)
11976 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11977 (match_operand:QI 2 "const1_operand" ""))
11979 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11980 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11982 && (TARGET_SHIFT1 || optimize_size)
11983 && ix86_match_ccmode (insn, CCGOCmode)
11984 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11986 [(set_attr "type" "ishift")
11987 (set (attr "length")
11988 (if_then_else (match_operand:DI 0 "register_operand" "")
11990 (const_string "*")))])
11992 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11993 [(set (reg FLAGS_REG)
11995 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11996 (match_operand:QI 2 "const1_operand" ""))
11998 (clobber (match_scratch:DI 0 "=r"))]
12000 && (TARGET_SHIFT1 || optimize_size)
12001 && ix86_match_ccmode (insn, CCGOCmode)
12002 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12004 [(set_attr "type" "ishift")
12005 (set_attr "length" "2")])
12007 ;; This pattern can't accept a variable shift count, since shifts by
12008 ;; zero don't affect the flags. We assume that shifts by constant
12009 ;; zero are optimized away.
12010 (define_insn "*ashrdi3_cmp_rex64"
12011 [(set (reg FLAGS_REG)
12013 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12014 (match_operand:QI 2 "const_int_operand" "n"))
12016 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12017 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12019 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12020 && ix86_match_ccmode (insn, CCGOCmode)
12021 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12022 "sar{q}\t{%2, %0|%0, %2}"
12023 [(set_attr "type" "ishift")
12024 (set_attr "mode" "DI")])
12026 (define_insn "*ashrdi3_cconly_rex64"
12027 [(set (reg FLAGS_REG)
12029 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12030 (match_operand:QI 2 "const_int_operand" "n"))
12032 (clobber (match_scratch:DI 0 "=r"))]
12034 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12035 && ix86_match_ccmode (insn, CCGOCmode)
12036 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12037 "sar{q}\t{%2, %0|%0, %2}"
12038 [(set_attr "type" "ishift")
12039 (set_attr "mode" "DI")])
12041 (define_insn "*ashrdi3_1"
12042 [(set (match_operand:DI 0 "register_operand" "=r")
12043 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12044 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12045 (clobber (reg:CC FLAGS_REG))]
12048 [(set_attr "type" "multi")])
12050 ;; By default we don't ask for a scratch register, because when DImode
12051 ;; values are manipulated, registers are already at a premium. But if
12052 ;; we have one handy, we won't turn it away.
12054 [(match_scratch:SI 3 "r")
12055 (parallel [(set (match_operand:DI 0 "register_operand" "")
12056 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12057 (match_operand:QI 2 "nonmemory_operand" "")))
12058 (clobber (reg:CC FLAGS_REG))])
12060 "!TARGET_64BIT && TARGET_CMOVE"
12062 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12065 [(set (match_operand:DI 0 "register_operand" "")
12066 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12067 (match_operand:QI 2 "nonmemory_operand" "")))
12068 (clobber (reg:CC FLAGS_REG))]
12069 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12070 ? epilogue_completed : reload_completed)"
12072 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12074 (define_insn "x86_shrd_1"
12075 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12076 (ior:SI (ashiftrt:SI (match_dup 0)
12077 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12078 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12079 (minus:QI (const_int 32) (match_dup 2)))))
12080 (clobber (reg:CC FLAGS_REG))]
12083 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12084 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12085 [(set_attr "type" "ishift")
12086 (set_attr "prefix_0f" "1")
12087 (set_attr "pent_pair" "np")
12088 (set_attr "mode" "SI")])
12090 (define_expand "x86_shift_adj_3"
12091 [(use (match_operand:SI 0 "register_operand" ""))
12092 (use (match_operand:SI 1 "register_operand" ""))
12093 (use (match_operand:QI 2 "register_operand" ""))]
12096 rtx label = gen_label_rtx ();
12099 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12101 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12102 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12103 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12104 gen_rtx_LABEL_REF (VOIDmode, label),
12106 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12107 JUMP_LABEL (tmp) = label;
12109 emit_move_insn (operands[0], operands[1]);
12110 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12112 emit_label (label);
12113 LABEL_NUSES (label) = 1;
12118 (define_insn "ashrsi3_31"
12119 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12120 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12121 (match_operand:SI 2 "const_int_operand" "i,i")))
12122 (clobber (reg:CC FLAGS_REG))]
12123 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12124 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12127 sar{l}\t{%2, %0|%0, %2}"
12128 [(set_attr "type" "imovx,ishift")
12129 (set_attr "prefix_0f" "0,*")
12130 (set_attr "length_immediate" "0,*")
12131 (set_attr "modrm" "0,1")
12132 (set_attr "mode" "SI")])
12134 (define_insn "*ashrsi3_31_zext"
12135 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12136 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12137 (match_operand:SI 2 "const_int_operand" "i,i"))))
12138 (clobber (reg:CC FLAGS_REG))]
12139 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12140 && INTVAL (operands[2]) == 31
12141 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12144 sar{l}\t{%2, %k0|%k0, %2}"
12145 [(set_attr "type" "imovx,ishift")
12146 (set_attr "prefix_0f" "0,*")
12147 (set_attr "length_immediate" "0,*")
12148 (set_attr "modrm" "0,1")
12149 (set_attr "mode" "SI")])
12151 (define_expand "ashrsi3"
12152 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12153 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12154 (match_operand:QI 2 "nonmemory_operand" "")))
12155 (clobber (reg:CC FLAGS_REG))]
12157 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12159 (define_insn "*ashrsi3_1_one_bit"
12160 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12161 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12162 (match_operand:QI 2 "const1_operand" "")))
12163 (clobber (reg:CC FLAGS_REG))]
12164 "(TARGET_SHIFT1 || optimize_size)
12165 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12167 [(set_attr "type" "ishift")
12168 (set (attr "length")
12169 (if_then_else (match_operand:SI 0 "register_operand" "")
12171 (const_string "*")))])
12173 (define_insn "*ashrsi3_1_one_bit_zext"
12174 [(set (match_operand:DI 0 "register_operand" "=r")
12175 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12176 (match_operand:QI 2 "const1_operand" ""))))
12177 (clobber (reg:CC FLAGS_REG))]
12179 && (TARGET_SHIFT1 || optimize_size)
12180 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12182 [(set_attr "type" "ishift")
12183 (set_attr "length" "2")])
12185 (define_insn "*ashrsi3_1"
12186 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12187 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12188 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12189 (clobber (reg:CC FLAGS_REG))]
12190 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12192 sar{l}\t{%2, %0|%0, %2}
12193 sar{l}\t{%b2, %0|%0, %b2}"
12194 [(set_attr "type" "ishift")
12195 (set_attr "mode" "SI")])
12197 (define_insn "*ashrsi3_1_zext"
12198 [(set (match_operand:DI 0 "register_operand" "=r,r")
12199 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12200 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12201 (clobber (reg:CC FLAGS_REG))]
12202 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12204 sar{l}\t{%2, %k0|%k0, %2}
12205 sar{l}\t{%b2, %k0|%k0, %b2}"
12206 [(set_attr "type" "ishift")
12207 (set_attr "mode" "SI")])
12209 ;; This pattern can't accept a variable shift count, since shifts by
12210 ;; zero don't affect the flags. We assume that shifts by constant
12211 ;; zero are optimized away.
12212 (define_insn "*ashrsi3_one_bit_cmp"
12213 [(set (reg FLAGS_REG)
12215 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12216 (match_operand:QI 2 "const1_operand" ""))
12218 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12219 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12220 "(TARGET_SHIFT1 || optimize_size)
12221 && ix86_match_ccmode (insn, CCGOCmode)
12222 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12224 [(set_attr "type" "ishift")
12225 (set (attr "length")
12226 (if_then_else (match_operand:SI 0 "register_operand" "")
12228 (const_string "*")))])
12230 (define_insn "*ashrsi3_one_bit_cconly"
12231 [(set (reg FLAGS_REG)
12233 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12234 (match_operand:QI 2 "const1_operand" ""))
12236 (clobber (match_scratch:SI 0 "=r"))]
12237 "(TARGET_SHIFT1 || optimize_size)
12238 && ix86_match_ccmode (insn, CCGOCmode)
12239 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12241 [(set_attr "type" "ishift")
12242 (set_attr "length" "2")])
12244 (define_insn "*ashrsi3_one_bit_cmp_zext"
12245 [(set (reg FLAGS_REG)
12247 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12248 (match_operand:QI 2 "const1_operand" ""))
12250 (set (match_operand:DI 0 "register_operand" "=r")
12251 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12253 && (TARGET_SHIFT1 || optimize_size)
12254 && ix86_match_ccmode (insn, CCmode)
12255 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12257 [(set_attr "type" "ishift")
12258 (set_attr "length" "2")])
12260 ;; This pattern can't accept a variable shift count, since shifts by
12261 ;; zero don't affect the flags. We assume that shifts by constant
12262 ;; zero are optimized away.
12263 (define_insn "*ashrsi3_cmp"
12264 [(set (reg FLAGS_REG)
12266 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12267 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12269 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12270 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12271 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12272 && ix86_match_ccmode (insn, CCGOCmode)
12273 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12274 "sar{l}\t{%2, %0|%0, %2}"
12275 [(set_attr "type" "ishift")
12276 (set_attr "mode" "SI")])
12278 (define_insn "*ashrsi3_cconly"
12279 [(set (reg FLAGS_REG)
12281 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12282 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12284 (clobber (match_scratch:SI 0 "=r"))]
12285 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12286 && ix86_match_ccmode (insn, CCGOCmode)
12287 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12288 "sar{l}\t{%2, %0|%0, %2}"
12289 [(set_attr "type" "ishift")
12290 (set_attr "mode" "SI")])
12292 (define_insn "*ashrsi3_cmp_zext"
12293 [(set (reg FLAGS_REG)
12295 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12296 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12298 (set (match_operand:DI 0 "register_operand" "=r")
12299 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12301 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12302 && ix86_match_ccmode (insn, CCGOCmode)
12303 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12304 "sar{l}\t{%2, %k0|%k0, %2}"
12305 [(set_attr "type" "ishift")
12306 (set_attr "mode" "SI")])
12308 (define_expand "ashrhi3"
12309 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12310 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12311 (match_operand:QI 2 "nonmemory_operand" "")))
12312 (clobber (reg:CC FLAGS_REG))]
12313 "TARGET_HIMODE_MATH"
12314 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12316 (define_insn "*ashrhi3_1_one_bit"
12317 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12318 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12319 (match_operand:QI 2 "const1_operand" "")))
12320 (clobber (reg:CC FLAGS_REG))]
12321 "(TARGET_SHIFT1 || optimize_size)
12322 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12324 [(set_attr "type" "ishift")
12325 (set (attr "length")
12326 (if_then_else (match_operand 0 "register_operand" "")
12328 (const_string "*")))])
12330 (define_insn "*ashrhi3_1"
12331 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12332 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12333 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12334 (clobber (reg:CC FLAGS_REG))]
12335 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12337 sar{w}\t{%2, %0|%0, %2}
12338 sar{w}\t{%b2, %0|%0, %b2}"
12339 [(set_attr "type" "ishift")
12340 (set_attr "mode" "HI")])
12342 ;; This pattern can't accept a variable shift count, since shifts by
12343 ;; zero don't affect the flags. We assume that shifts by constant
12344 ;; zero are optimized away.
12345 (define_insn "*ashrhi3_one_bit_cmp"
12346 [(set (reg FLAGS_REG)
12348 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12349 (match_operand:QI 2 "const1_operand" ""))
12351 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12352 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12353 "(TARGET_SHIFT1 || optimize_size)
12354 && ix86_match_ccmode (insn, CCGOCmode)
12355 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12357 [(set_attr "type" "ishift")
12358 (set (attr "length")
12359 (if_then_else (match_operand 0 "register_operand" "")
12361 (const_string "*")))])
12363 (define_insn "*ashrhi3_one_bit_cconly"
12364 [(set (reg FLAGS_REG)
12366 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12367 (match_operand:QI 2 "const1_operand" ""))
12369 (clobber (match_scratch:HI 0 "=r"))]
12370 "(TARGET_SHIFT1 || optimize_size)
12371 && ix86_match_ccmode (insn, CCGOCmode)
12372 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12374 [(set_attr "type" "ishift")
12375 (set_attr "length" "2")])
12377 ;; This pattern can't accept a variable shift count, since shifts by
12378 ;; zero don't affect the flags. We assume that shifts by constant
12379 ;; zero are optimized away.
12380 (define_insn "*ashrhi3_cmp"
12381 [(set (reg FLAGS_REG)
12383 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12384 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12386 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12387 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12388 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12389 && ix86_match_ccmode (insn, CCGOCmode)
12390 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12391 "sar{w}\t{%2, %0|%0, %2}"
12392 [(set_attr "type" "ishift")
12393 (set_attr "mode" "HI")])
12395 (define_insn "*ashrhi3_cconly"
12396 [(set (reg FLAGS_REG)
12398 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12399 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12401 (clobber (match_scratch:HI 0 "=r"))]
12402 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12403 && ix86_match_ccmode (insn, CCGOCmode)
12404 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12405 "sar{w}\t{%2, %0|%0, %2}"
12406 [(set_attr "type" "ishift")
12407 (set_attr "mode" "HI")])
12409 (define_expand "ashrqi3"
12410 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12411 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12412 (match_operand:QI 2 "nonmemory_operand" "")))
12413 (clobber (reg:CC FLAGS_REG))]
12414 "TARGET_QIMODE_MATH"
12415 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12417 (define_insn "*ashrqi3_1_one_bit"
12418 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12419 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12420 (match_operand:QI 2 "const1_operand" "")))
12421 (clobber (reg:CC FLAGS_REG))]
12422 "(TARGET_SHIFT1 || optimize_size)
12423 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12425 [(set_attr "type" "ishift")
12426 (set (attr "length")
12427 (if_then_else (match_operand 0 "register_operand" "")
12429 (const_string "*")))])
12431 (define_insn "*ashrqi3_1_one_bit_slp"
12432 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12433 (ashiftrt:QI (match_dup 0)
12434 (match_operand:QI 1 "const1_operand" "")))
12435 (clobber (reg:CC FLAGS_REG))]
12436 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12437 && (TARGET_SHIFT1 || optimize_size)
12438 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12440 [(set_attr "type" "ishift1")
12441 (set (attr "length")
12442 (if_then_else (match_operand 0 "register_operand" "")
12444 (const_string "*")))])
12446 (define_insn "*ashrqi3_1"
12447 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12448 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12449 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12450 (clobber (reg:CC FLAGS_REG))]
12451 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12453 sar{b}\t{%2, %0|%0, %2}
12454 sar{b}\t{%b2, %0|%0, %b2}"
12455 [(set_attr "type" "ishift")
12456 (set_attr "mode" "QI")])
12458 (define_insn "*ashrqi3_1_slp"
12459 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12460 (ashiftrt:QI (match_dup 0)
12461 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12462 (clobber (reg:CC FLAGS_REG))]
12463 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12464 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12466 sar{b}\t{%1, %0|%0, %1}
12467 sar{b}\t{%b1, %0|%0, %b1}"
12468 [(set_attr "type" "ishift1")
12469 (set_attr "mode" "QI")])
12471 ;; This pattern can't accept a variable shift count, since shifts by
12472 ;; zero don't affect the flags. We assume that shifts by constant
12473 ;; zero are optimized away.
12474 (define_insn "*ashrqi3_one_bit_cmp"
12475 [(set (reg FLAGS_REG)
12477 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12478 (match_operand:QI 2 "const1_operand" "I"))
12480 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12481 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12482 "(TARGET_SHIFT1 || optimize_size)
12483 && ix86_match_ccmode (insn, CCGOCmode)
12484 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12486 [(set_attr "type" "ishift")
12487 (set (attr "length")
12488 (if_then_else (match_operand 0 "register_operand" "")
12490 (const_string "*")))])
12492 (define_insn "*ashrqi3_one_bit_cconly"
12493 [(set (reg FLAGS_REG)
12495 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12496 (match_operand:QI 2 "const1_operand" "I"))
12498 (clobber (match_scratch:QI 0 "=q"))]
12499 "(TARGET_SHIFT1 || optimize_size)
12500 && ix86_match_ccmode (insn, CCGOCmode)
12501 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12503 [(set_attr "type" "ishift")
12504 (set_attr "length" "2")])
12506 ;; This pattern can't accept a variable shift count, since shifts by
12507 ;; zero don't affect the flags. We assume that shifts by constant
12508 ;; zero are optimized away.
12509 (define_insn "*ashrqi3_cmp"
12510 [(set (reg FLAGS_REG)
12512 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12513 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12515 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12516 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12517 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12518 && ix86_match_ccmode (insn, CCGOCmode)
12519 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12520 "sar{b}\t{%2, %0|%0, %2}"
12521 [(set_attr "type" "ishift")
12522 (set_attr "mode" "QI")])
12524 (define_insn "*ashrqi3_cconly"
12525 [(set (reg FLAGS_REG)
12527 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12528 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12530 (clobber (match_scratch:QI 0 "=q"))]
12531 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12532 && ix86_match_ccmode (insn, CCGOCmode)
12533 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12534 "sar{b}\t{%2, %0|%0, %2}"
12535 [(set_attr "type" "ishift")
12536 (set_attr "mode" "QI")])
12539 ;; Logical shift instructions
12541 ;; See comment above `ashldi3' about how this works.
12543 (define_expand "lshrti3"
12544 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12545 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12546 (match_operand:QI 2 "nonmemory_operand" "")))
12547 (clobber (reg:CC FLAGS_REG))])]
12550 if (! immediate_operand (operands[2], QImode))
12552 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12555 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12559 (define_insn "lshrti3_1"
12560 [(set (match_operand:TI 0 "register_operand" "=r")
12561 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12562 (match_operand:QI 2 "register_operand" "c")))
12563 (clobber (match_scratch:DI 3 "=&r"))
12564 (clobber (reg:CC FLAGS_REG))]
12567 [(set_attr "type" "multi")])
12569 ;; This pattern must be defined before *lshrti3_2 to prevent
12570 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12572 (define_insn "sse2_lshrti3"
12573 [(set (match_operand:TI 0 "register_operand" "=x")
12574 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12575 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12578 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12579 return "psrldq\t{%2, %0|%0, %2}";
12581 [(set_attr "type" "sseishft")
12582 (set_attr "prefix_data16" "1")
12583 (set_attr "mode" "TI")])
12585 (define_insn "*lshrti3_2"
12586 [(set (match_operand:TI 0 "register_operand" "=r")
12587 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12588 (match_operand:QI 2 "immediate_operand" "O")))
12589 (clobber (reg:CC FLAGS_REG))]
12592 [(set_attr "type" "multi")])
12595 [(set (match_operand:TI 0 "register_operand" "")
12596 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12597 (match_operand:QI 2 "register_operand" "")))
12598 (clobber (match_scratch:DI 3 ""))
12599 (clobber (reg:CC FLAGS_REG))]
12600 "TARGET_64BIT && reload_completed"
12602 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12605 [(set (match_operand:TI 0 "register_operand" "")
12606 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12607 (match_operand:QI 2 "immediate_operand" "")))
12608 (clobber (reg:CC FLAGS_REG))]
12609 "TARGET_64BIT && reload_completed"
12611 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12613 (define_expand "lshrdi3"
12614 [(set (match_operand:DI 0 "shiftdi_operand" "")
12615 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12616 (match_operand:QI 2 "nonmemory_operand" "")))]
12618 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12620 (define_insn "*lshrdi3_1_one_bit_rex64"
12621 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12622 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12623 (match_operand:QI 2 "const1_operand" "")))
12624 (clobber (reg:CC FLAGS_REG))]
12626 && (TARGET_SHIFT1 || optimize_size)
12627 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12629 [(set_attr "type" "ishift")
12630 (set (attr "length")
12631 (if_then_else (match_operand:DI 0 "register_operand" "")
12633 (const_string "*")))])
12635 (define_insn "*lshrdi3_1_rex64"
12636 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12637 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12638 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12639 (clobber (reg:CC FLAGS_REG))]
12640 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12642 shr{q}\t{%2, %0|%0, %2}
12643 shr{q}\t{%b2, %0|%0, %b2}"
12644 [(set_attr "type" "ishift")
12645 (set_attr "mode" "DI")])
12647 ;; This pattern can't accept a variable shift count, since shifts by
12648 ;; zero don't affect the flags. We assume that shifts by constant
12649 ;; zero are optimized away.
12650 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12651 [(set (reg FLAGS_REG)
12653 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12654 (match_operand:QI 2 "const1_operand" ""))
12656 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12657 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12659 && (TARGET_SHIFT1 || optimize_size)
12660 && ix86_match_ccmode (insn, CCGOCmode)
12661 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12663 [(set_attr "type" "ishift")
12664 (set (attr "length")
12665 (if_then_else (match_operand:DI 0 "register_operand" "")
12667 (const_string "*")))])
12669 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12670 [(set (reg FLAGS_REG)
12672 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12673 (match_operand:QI 2 "const1_operand" ""))
12675 (clobber (match_scratch:DI 0 "=r"))]
12677 && (TARGET_SHIFT1 || optimize_size)
12678 && ix86_match_ccmode (insn, CCGOCmode)
12679 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12681 [(set_attr "type" "ishift")
12682 (set_attr "length" "2")])
12684 ;; This pattern can't accept a variable shift count, since shifts by
12685 ;; zero don't affect the flags. We assume that shifts by constant
12686 ;; zero are optimized away.
12687 (define_insn "*lshrdi3_cmp_rex64"
12688 [(set (reg FLAGS_REG)
12690 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12691 (match_operand:QI 2 "const_int_operand" "e"))
12693 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12694 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12696 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12697 && ix86_match_ccmode (insn, CCGOCmode)
12698 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12699 "shr{q}\t{%2, %0|%0, %2}"
12700 [(set_attr "type" "ishift")
12701 (set_attr "mode" "DI")])
12703 (define_insn "*lshrdi3_cconly_rex64"
12704 [(set (reg FLAGS_REG)
12706 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12707 (match_operand:QI 2 "const_int_operand" "e"))
12709 (clobber (match_scratch:DI 0 "=r"))]
12711 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12712 && ix86_match_ccmode (insn, CCGOCmode)
12713 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12714 "shr{q}\t{%2, %0|%0, %2}"
12715 [(set_attr "type" "ishift")
12716 (set_attr "mode" "DI")])
12718 (define_insn "*lshrdi3_1"
12719 [(set (match_operand:DI 0 "register_operand" "=r")
12720 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12721 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12722 (clobber (reg:CC FLAGS_REG))]
12725 [(set_attr "type" "multi")])
12727 ;; By default we don't ask for a scratch register, because when DImode
12728 ;; values are manipulated, registers are already at a premium. But if
12729 ;; we have one handy, we won't turn it away.
12731 [(match_scratch:SI 3 "r")
12732 (parallel [(set (match_operand:DI 0 "register_operand" "")
12733 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12734 (match_operand:QI 2 "nonmemory_operand" "")))
12735 (clobber (reg:CC FLAGS_REG))])
12737 "!TARGET_64BIT && TARGET_CMOVE"
12739 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12742 [(set (match_operand:DI 0 "register_operand" "")
12743 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12744 (match_operand:QI 2 "nonmemory_operand" "")))
12745 (clobber (reg:CC FLAGS_REG))]
12746 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12747 ? epilogue_completed : reload_completed)"
12749 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12751 (define_expand "lshrsi3"
12752 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12753 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12754 (match_operand:QI 2 "nonmemory_operand" "")))
12755 (clobber (reg:CC FLAGS_REG))]
12757 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12759 (define_insn "*lshrsi3_1_one_bit"
12760 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12761 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12762 (match_operand:QI 2 "const1_operand" "")))
12763 (clobber (reg:CC FLAGS_REG))]
12764 "(TARGET_SHIFT1 || optimize_size)
12765 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12767 [(set_attr "type" "ishift")
12768 (set (attr "length")
12769 (if_then_else (match_operand:SI 0 "register_operand" "")
12771 (const_string "*")))])
12773 (define_insn "*lshrsi3_1_one_bit_zext"
12774 [(set (match_operand:DI 0 "register_operand" "=r")
12775 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12776 (match_operand:QI 2 "const1_operand" "")))
12777 (clobber (reg:CC FLAGS_REG))]
12779 && (TARGET_SHIFT1 || optimize_size)
12780 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12782 [(set_attr "type" "ishift")
12783 (set_attr "length" "2")])
12785 (define_insn "*lshrsi3_1"
12786 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12787 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12788 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12789 (clobber (reg:CC FLAGS_REG))]
12790 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12792 shr{l}\t{%2, %0|%0, %2}
12793 shr{l}\t{%b2, %0|%0, %b2}"
12794 [(set_attr "type" "ishift")
12795 (set_attr "mode" "SI")])
12797 (define_insn "*lshrsi3_1_zext"
12798 [(set (match_operand:DI 0 "register_operand" "=r,r")
12800 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12801 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12802 (clobber (reg:CC FLAGS_REG))]
12803 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12805 shr{l}\t{%2, %k0|%k0, %2}
12806 shr{l}\t{%b2, %k0|%k0, %b2}"
12807 [(set_attr "type" "ishift")
12808 (set_attr "mode" "SI")])
12810 ;; This pattern can't accept a variable shift count, since shifts by
12811 ;; zero don't affect the flags. We assume that shifts by constant
12812 ;; zero are optimized away.
12813 (define_insn "*lshrsi3_one_bit_cmp"
12814 [(set (reg FLAGS_REG)
12816 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12817 (match_operand:QI 2 "const1_operand" ""))
12819 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12820 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12821 "(TARGET_SHIFT1 || optimize_size)
12822 && ix86_match_ccmode (insn, CCGOCmode)
12823 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12825 [(set_attr "type" "ishift")
12826 (set (attr "length")
12827 (if_then_else (match_operand:SI 0 "register_operand" "")
12829 (const_string "*")))])
12831 (define_insn "*lshrsi3_one_bit_cconly"
12832 [(set (reg FLAGS_REG)
12834 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12835 (match_operand:QI 2 "const1_operand" ""))
12837 (clobber (match_scratch:SI 0 "=r"))]
12838 "(TARGET_SHIFT1 || optimize_size)
12839 && ix86_match_ccmode (insn, CCGOCmode)
12840 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12842 [(set_attr "type" "ishift")
12843 (set_attr "length" "2")])
12845 (define_insn "*lshrsi3_cmp_one_bit_zext"
12846 [(set (reg FLAGS_REG)
12848 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12849 (match_operand:QI 2 "const1_operand" ""))
12851 (set (match_operand:DI 0 "register_operand" "=r")
12852 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12854 && (TARGET_SHIFT1 || optimize_size)
12855 && ix86_match_ccmode (insn, CCGOCmode)
12856 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12858 [(set_attr "type" "ishift")
12859 (set_attr "length" "2")])
12861 ;; This pattern can't accept a variable shift count, since shifts by
12862 ;; zero don't affect the flags. We assume that shifts by constant
12863 ;; zero are optimized away.
12864 (define_insn "*lshrsi3_cmp"
12865 [(set (reg FLAGS_REG)
12867 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12868 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12870 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12871 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12872 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12873 && ix86_match_ccmode (insn, CCGOCmode)
12874 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12875 "shr{l}\t{%2, %0|%0, %2}"
12876 [(set_attr "type" "ishift")
12877 (set_attr "mode" "SI")])
12879 (define_insn "*lshrsi3_cconly"
12880 [(set (reg FLAGS_REG)
12882 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12883 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12885 (clobber (match_scratch:SI 0 "=r"))]
12886 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12887 && ix86_match_ccmode (insn, CCGOCmode)
12888 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12889 "shr{l}\t{%2, %0|%0, %2}"
12890 [(set_attr "type" "ishift")
12891 (set_attr "mode" "SI")])
12893 (define_insn "*lshrsi3_cmp_zext"
12894 [(set (reg FLAGS_REG)
12896 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12897 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12899 (set (match_operand:DI 0 "register_operand" "=r")
12900 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12902 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12903 && ix86_match_ccmode (insn, CCGOCmode)
12904 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12905 "shr{l}\t{%2, %k0|%k0, %2}"
12906 [(set_attr "type" "ishift")
12907 (set_attr "mode" "SI")])
12909 (define_expand "lshrhi3"
12910 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12911 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12912 (match_operand:QI 2 "nonmemory_operand" "")))
12913 (clobber (reg:CC FLAGS_REG))]
12914 "TARGET_HIMODE_MATH"
12915 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12917 (define_insn "*lshrhi3_1_one_bit"
12918 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12919 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12920 (match_operand:QI 2 "const1_operand" "")))
12921 (clobber (reg:CC FLAGS_REG))]
12922 "(TARGET_SHIFT1 || optimize_size)
12923 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12925 [(set_attr "type" "ishift")
12926 (set (attr "length")
12927 (if_then_else (match_operand 0 "register_operand" "")
12929 (const_string "*")))])
12931 (define_insn "*lshrhi3_1"
12932 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12933 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12934 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12935 (clobber (reg:CC FLAGS_REG))]
12936 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12938 shr{w}\t{%2, %0|%0, %2}
12939 shr{w}\t{%b2, %0|%0, %b2}"
12940 [(set_attr "type" "ishift")
12941 (set_attr "mode" "HI")])
12943 ;; This pattern can't accept a variable shift count, since shifts by
12944 ;; zero don't affect the flags. We assume that shifts by constant
12945 ;; zero are optimized away.
12946 (define_insn "*lshrhi3_one_bit_cmp"
12947 [(set (reg FLAGS_REG)
12949 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12950 (match_operand:QI 2 "const1_operand" ""))
12952 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12953 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12954 "(TARGET_SHIFT1 || optimize_size)
12955 && ix86_match_ccmode (insn, CCGOCmode)
12956 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12958 [(set_attr "type" "ishift")
12959 (set (attr "length")
12960 (if_then_else (match_operand:SI 0 "register_operand" "")
12962 (const_string "*")))])
12964 (define_insn "*lshrhi3_one_bit_cconly"
12965 [(set (reg FLAGS_REG)
12967 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12968 (match_operand:QI 2 "const1_operand" ""))
12970 (clobber (match_scratch:HI 0 "=r"))]
12971 "(TARGET_SHIFT1 || optimize_size)
12972 && ix86_match_ccmode (insn, CCGOCmode)
12973 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12975 [(set_attr "type" "ishift")
12976 (set_attr "length" "2")])
12978 ;; This pattern can't accept a variable shift count, since shifts by
12979 ;; zero don't affect the flags. We assume that shifts by constant
12980 ;; zero are optimized away.
12981 (define_insn "*lshrhi3_cmp"
12982 [(set (reg FLAGS_REG)
12984 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12985 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12987 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12988 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12989 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12990 && ix86_match_ccmode (insn, CCGOCmode)
12991 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12992 "shr{w}\t{%2, %0|%0, %2}"
12993 [(set_attr "type" "ishift")
12994 (set_attr "mode" "HI")])
12996 (define_insn "*lshrhi3_cconly"
12997 [(set (reg FLAGS_REG)
12999 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13000 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13002 (clobber (match_scratch:HI 0 "=r"))]
13003 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13004 && ix86_match_ccmode (insn, CCGOCmode)
13005 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13006 "shr{w}\t{%2, %0|%0, %2}"
13007 [(set_attr "type" "ishift")
13008 (set_attr "mode" "HI")])
13010 (define_expand "lshrqi3"
13011 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13012 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13013 (match_operand:QI 2 "nonmemory_operand" "")))
13014 (clobber (reg:CC FLAGS_REG))]
13015 "TARGET_QIMODE_MATH"
13016 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13018 (define_insn "*lshrqi3_1_one_bit"
13019 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13020 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13021 (match_operand:QI 2 "const1_operand" "")))
13022 (clobber (reg:CC FLAGS_REG))]
13023 "(TARGET_SHIFT1 || optimize_size)
13024 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13026 [(set_attr "type" "ishift")
13027 (set (attr "length")
13028 (if_then_else (match_operand 0 "register_operand" "")
13030 (const_string "*")))])
13032 (define_insn "*lshrqi3_1_one_bit_slp"
13033 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13034 (lshiftrt:QI (match_dup 0)
13035 (match_operand:QI 1 "const1_operand" "")))
13036 (clobber (reg:CC FLAGS_REG))]
13037 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13038 && (TARGET_SHIFT1 || optimize_size)"
13040 [(set_attr "type" "ishift1")
13041 (set (attr "length")
13042 (if_then_else (match_operand 0 "register_operand" "")
13044 (const_string "*")))])
13046 (define_insn "*lshrqi3_1"
13047 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13048 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13049 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13050 (clobber (reg:CC FLAGS_REG))]
13051 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13053 shr{b}\t{%2, %0|%0, %2}
13054 shr{b}\t{%b2, %0|%0, %b2}"
13055 [(set_attr "type" "ishift")
13056 (set_attr "mode" "QI")])
13058 (define_insn "*lshrqi3_1_slp"
13059 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13060 (lshiftrt:QI (match_dup 0)
13061 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13062 (clobber (reg:CC FLAGS_REG))]
13063 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13064 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13066 shr{b}\t{%1, %0|%0, %1}
13067 shr{b}\t{%b1, %0|%0, %b1}"
13068 [(set_attr "type" "ishift1")
13069 (set_attr "mode" "QI")])
13071 ;; This pattern can't accept a variable shift count, since shifts by
13072 ;; zero don't affect the flags. We assume that shifts by constant
13073 ;; zero are optimized away.
13074 (define_insn "*lshrqi2_one_bit_cmp"
13075 [(set (reg FLAGS_REG)
13077 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13078 (match_operand:QI 2 "const1_operand" ""))
13080 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13081 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13082 "(TARGET_SHIFT1 || optimize_size)
13083 && ix86_match_ccmode (insn, CCGOCmode)
13084 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13086 [(set_attr "type" "ishift")
13087 (set (attr "length")
13088 (if_then_else (match_operand:SI 0 "register_operand" "")
13090 (const_string "*")))])
13092 (define_insn "*lshrqi2_one_bit_cconly"
13093 [(set (reg FLAGS_REG)
13095 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13096 (match_operand:QI 2 "const1_operand" ""))
13098 (clobber (match_scratch:QI 0 "=q"))]
13099 "(TARGET_SHIFT1 || optimize_size)
13100 && ix86_match_ccmode (insn, CCGOCmode)
13101 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13103 [(set_attr "type" "ishift")
13104 (set_attr "length" "2")])
13106 ;; This pattern can't accept a variable shift count, since shifts by
13107 ;; zero don't affect the flags. We assume that shifts by constant
13108 ;; zero are optimized away.
13109 (define_insn "*lshrqi2_cmp"
13110 [(set (reg FLAGS_REG)
13112 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13113 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13115 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13116 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13117 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13118 && ix86_match_ccmode (insn, CCGOCmode)
13119 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13120 "shr{b}\t{%2, %0|%0, %2}"
13121 [(set_attr "type" "ishift")
13122 (set_attr "mode" "QI")])
13124 (define_insn "*lshrqi2_cconly"
13125 [(set (reg FLAGS_REG)
13127 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13128 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13130 (clobber (match_scratch:QI 0 "=q"))]
13131 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13132 && ix86_match_ccmode (insn, CCGOCmode)
13133 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13134 "shr{b}\t{%2, %0|%0, %2}"
13135 [(set_attr "type" "ishift")
13136 (set_attr "mode" "QI")])
13138 ;; Rotate instructions
13140 (define_expand "rotldi3"
13141 [(set (match_operand:DI 0 "shiftdi_operand" "")
13142 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13143 (match_operand:QI 2 "nonmemory_operand" "")))
13144 (clobber (reg:CC FLAGS_REG))]
13149 ix86_expand_binary_operator (ROTATE, DImode, operands);
13152 if (!const_1_to_31_operand (operands[2], VOIDmode))
13154 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13158 ;; Implement rotation using two double-precision shift instructions
13159 ;; and a scratch register.
13160 (define_insn_and_split "ix86_rotldi3"
13161 [(set (match_operand:DI 0 "register_operand" "=r")
13162 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13163 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13164 (clobber (reg:CC FLAGS_REG))
13165 (clobber (match_scratch:SI 3 "=&r"))]
13168 "&& reload_completed"
13169 [(set (match_dup 3) (match_dup 4))
13171 [(set (match_dup 4)
13172 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13173 (lshiftrt:SI (match_dup 5)
13174 (minus:QI (const_int 32) (match_dup 2)))))
13175 (clobber (reg:CC FLAGS_REG))])
13177 [(set (match_dup 5)
13178 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13179 (lshiftrt:SI (match_dup 3)
13180 (minus:QI (const_int 32) (match_dup 2)))))
13181 (clobber (reg:CC FLAGS_REG))])]
13182 "split_di (operands, 1, operands + 4, operands + 5);")
13184 (define_insn "*rotlsi3_1_one_bit_rex64"
13185 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13186 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13187 (match_operand:QI 2 "const1_operand" "")))
13188 (clobber (reg:CC FLAGS_REG))]
13190 && (TARGET_SHIFT1 || optimize_size)
13191 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13193 [(set_attr "type" "rotate")
13194 (set (attr "length")
13195 (if_then_else (match_operand:DI 0 "register_operand" "")
13197 (const_string "*")))])
13199 (define_insn "*rotldi3_1_rex64"
13200 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13201 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13202 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13203 (clobber (reg:CC FLAGS_REG))]
13204 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13206 rol{q}\t{%2, %0|%0, %2}
13207 rol{q}\t{%b2, %0|%0, %b2}"
13208 [(set_attr "type" "rotate")
13209 (set_attr "mode" "DI")])
13211 (define_expand "rotlsi3"
13212 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13213 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13214 (match_operand:QI 2 "nonmemory_operand" "")))
13215 (clobber (reg:CC FLAGS_REG))]
13217 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13219 (define_insn "*rotlsi3_1_one_bit"
13220 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13221 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13222 (match_operand:QI 2 "const1_operand" "")))
13223 (clobber (reg:CC FLAGS_REG))]
13224 "(TARGET_SHIFT1 || optimize_size)
13225 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13227 [(set_attr "type" "rotate")
13228 (set (attr "length")
13229 (if_then_else (match_operand:SI 0 "register_operand" "")
13231 (const_string "*")))])
13233 (define_insn "*rotlsi3_1_one_bit_zext"
13234 [(set (match_operand:DI 0 "register_operand" "=r")
13236 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13237 (match_operand:QI 2 "const1_operand" ""))))
13238 (clobber (reg:CC FLAGS_REG))]
13240 && (TARGET_SHIFT1 || optimize_size)
13241 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13243 [(set_attr "type" "rotate")
13244 (set_attr "length" "2")])
13246 (define_insn "*rotlsi3_1"
13247 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13248 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13249 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13250 (clobber (reg:CC FLAGS_REG))]
13251 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13253 rol{l}\t{%2, %0|%0, %2}
13254 rol{l}\t{%b2, %0|%0, %b2}"
13255 [(set_attr "type" "rotate")
13256 (set_attr "mode" "SI")])
13258 (define_insn "*rotlsi3_1_zext"
13259 [(set (match_operand:DI 0 "register_operand" "=r,r")
13261 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13262 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13263 (clobber (reg:CC FLAGS_REG))]
13264 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13266 rol{l}\t{%2, %k0|%k0, %2}
13267 rol{l}\t{%b2, %k0|%k0, %b2}"
13268 [(set_attr "type" "rotate")
13269 (set_attr "mode" "SI")])
13271 (define_expand "rotlhi3"
13272 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13273 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13274 (match_operand:QI 2 "nonmemory_operand" "")))
13275 (clobber (reg:CC FLAGS_REG))]
13276 "TARGET_HIMODE_MATH"
13277 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13279 (define_insn "*rotlhi3_1_one_bit"
13280 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13281 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13282 (match_operand:QI 2 "const1_operand" "")))
13283 (clobber (reg:CC FLAGS_REG))]
13284 "(TARGET_SHIFT1 || optimize_size)
13285 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13287 [(set_attr "type" "rotate")
13288 (set (attr "length")
13289 (if_then_else (match_operand 0 "register_operand" "")
13291 (const_string "*")))])
13293 (define_insn "*rotlhi3_1"
13294 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13295 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13296 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13297 (clobber (reg:CC FLAGS_REG))]
13298 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13300 rol{w}\t{%2, %0|%0, %2}
13301 rol{w}\t{%b2, %0|%0, %b2}"
13302 [(set_attr "type" "rotate")
13303 (set_attr "mode" "HI")])
13306 [(set (match_operand:HI 0 "register_operand" "")
13307 (rotate:HI (match_dup 0) (const_int 8)))
13308 (clobber (reg:CC FLAGS_REG))]
13310 [(parallel [(set (strict_low_part (match_dup 0))
13311 (bswap:HI (match_dup 0)))
13312 (clobber (reg:CC FLAGS_REG))])]
13315 (define_expand "rotlqi3"
13316 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13317 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13318 (match_operand:QI 2 "nonmemory_operand" "")))
13319 (clobber (reg:CC FLAGS_REG))]
13320 "TARGET_QIMODE_MATH"
13321 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13323 (define_insn "*rotlqi3_1_one_bit_slp"
13324 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13325 (rotate:QI (match_dup 0)
13326 (match_operand:QI 1 "const1_operand" "")))
13327 (clobber (reg:CC FLAGS_REG))]
13328 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13329 && (TARGET_SHIFT1 || optimize_size)"
13331 [(set_attr "type" "rotate1")
13332 (set (attr "length")
13333 (if_then_else (match_operand 0 "register_operand" "")
13335 (const_string "*")))])
13337 (define_insn "*rotlqi3_1_one_bit"
13338 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13339 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13340 (match_operand:QI 2 "const1_operand" "")))
13341 (clobber (reg:CC FLAGS_REG))]
13342 "(TARGET_SHIFT1 || optimize_size)
13343 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13345 [(set_attr "type" "rotate")
13346 (set (attr "length")
13347 (if_then_else (match_operand 0 "register_operand" "")
13349 (const_string "*")))])
13351 (define_insn "*rotlqi3_1_slp"
13352 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13353 (rotate:QI (match_dup 0)
13354 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13355 (clobber (reg:CC FLAGS_REG))]
13356 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13357 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13359 rol{b}\t{%1, %0|%0, %1}
13360 rol{b}\t{%b1, %0|%0, %b1}"
13361 [(set_attr "type" "rotate1")
13362 (set_attr "mode" "QI")])
13364 (define_insn "*rotlqi3_1"
13365 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13366 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13367 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13368 (clobber (reg:CC FLAGS_REG))]
13369 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13371 rol{b}\t{%2, %0|%0, %2}
13372 rol{b}\t{%b2, %0|%0, %b2}"
13373 [(set_attr "type" "rotate")
13374 (set_attr "mode" "QI")])
13376 (define_expand "rotrdi3"
13377 [(set (match_operand:DI 0 "shiftdi_operand" "")
13378 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13379 (match_operand:QI 2 "nonmemory_operand" "")))
13380 (clobber (reg:CC FLAGS_REG))]
13385 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13388 if (!const_1_to_31_operand (operands[2], VOIDmode))
13390 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13394 ;; Implement rotation using two double-precision shift instructions
13395 ;; and a scratch register.
13396 (define_insn_and_split "ix86_rotrdi3"
13397 [(set (match_operand:DI 0 "register_operand" "=r")
13398 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13399 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13400 (clobber (reg:CC FLAGS_REG))
13401 (clobber (match_scratch:SI 3 "=&r"))]
13404 "&& reload_completed"
13405 [(set (match_dup 3) (match_dup 4))
13407 [(set (match_dup 4)
13408 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13409 (ashift:SI (match_dup 5)
13410 (minus:QI (const_int 32) (match_dup 2)))))
13411 (clobber (reg:CC FLAGS_REG))])
13413 [(set (match_dup 5)
13414 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13415 (ashift:SI (match_dup 3)
13416 (minus:QI (const_int 32) (match_dup 2)))))
13417 (clobber (reg:CC FLAGS_REG))])]
13418 "split_di (operands, 1, operands + 4, operands + 5);")
13420 (define_insn "*rotrdi3_1_one_bit_rex64"
13421 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13422 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13423 (match_operand:QI 2 "const1_operand" "")))
13424 (clobber (reg:CC FLAGS_REG))]
13426 && (TARGET_SHIFT1 || optimize_size)
13427 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13429 [(set_attr "type" "rotate")
13430 (set (attr "length")
13431 (if_then_else (match_operand:DI 0 "register_operand" "")
13433 (const_string "*")))])
13435 (define_insn "*rotrdi3_1_rex64"
13436 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13437 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13438 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13439 (clobber (reg:CC FLAGS_REG))]
13440 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13442 ror{q}\t{%2, %0|%0, %2}
13443 ror{q}\t{%b2, %0|%0, %b2}"
13444 [(set_attr "type" "rotate")
13445 (set_attr "mode" "DI")])
13447 (define_expand "rotrsi3"
13448 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13449 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13450 (match_operand:QI 2 "nonmemory_operand" "")))
13451 (clobber (reg:CC FLAGS_REG))]
13453 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13455 (define_insn "*rotrsi3_1_one_bit"
13456 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13457 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13458 (match_operand:QI 2 "const1_operand" "")))
13459 (clobber (reg:CC FLAGS_REG))]
13460 "(TARGET_SHIFT1 || optimize_size)
13461 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13463 [(set_attr "type" "rotate")
13464 (set (attr "length")
13465 (if_then_else (match_operand:SI 0 "register_operand" "")
13467 (const_string "*")))])
13469 (define_insn "*rotrsi3_1_one_bit_zext"
13470 [(set (match_operand:DI 0 "register_operand" "=r")
13472 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13473 (match_operand:QI 2 "const1_operand" ""))))
13474 (clobber (reg:CC FLAGS_REG))]
13476 && (TARGET_SHIFT1 || optimize_size)
13477 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13479 [(set_attr "type" "rotate")
13480 (set (attr "length")
13481 (if_then_else (match_operand:SI 0 "register_operand" "")
13483 (const_string "*")))])
13485 (define_insn "*rotrsi3_1"
13486 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13487 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13488 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13489 (clobber (reg:CC FLAGS_REG))]
13490 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13492 ror{l}\t{%2, %0|%0, %2}
13493 ror{l}\t{%b2, %0|%0, %b2}"
13494 [(set_attr "type" "rotate")
13495 (set_attr "mode" "SI")])
13497 (define_insn "*rotrsi3_1_zext"
13498 [(set (match_operand:DI 0 "register_operand" "=r,r")
13500 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13501 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13502 (clobber (reg:CC FLAGS_REG))]
13503 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13505 ror{l}\t{%2, %k0|%k0, %2}
13506 ror{l}\t{%b2, %k0|%k0, %b2}"
13507 [(set_attr "type" "rotate")
13508 (set_attr "mode" "SI")])
13510 (define_expand "rotrhi3"
13511 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13512 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13513 (match_operand:QI 2 "nonmemory_operand" "")))
13514 (clobber (reg:CC FLAGS_REG))]
13515 "TARGET_HIMODE_MATH"
13516 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13518 (define_insn "*rotrhi3_one_bit"
13519 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13520 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13521 (match_operand:QI 2 "const1_operand" "")))
13522 (clobber (reg:CC FLAGS_REG))]
13523 "(TARGET_SHIFT1 || optimize_size)
13524 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13526 [(set_attr "type" "rotate")
13527 (set (attr "length")
13528 (if_then_else (match_operand 0 "register_operand" "")
13530 (const_string "*")))])
13532 (define_insn "*rotrhi3_1"
13533 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13534 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13535 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13536 (clobber (reg:CC FLAGS_REG))]
13537 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13539 ror{w}\t{%2, %0|%0, %2}
13540 ror{w}\t{%b2, %0|%0, %b2}"
13541 [(set_attr "type" "rotate")
13542 (set_attr "mode" "HI")])
13545 [(set (match_operand:HI 0 "register_operand" "")
13546 (rotatert:HI (match_dup 0) (const_int 8)))
13547 (clobber (reg:CC FLAGS_REG))]
13549 [(parallel [(set (strict_low_part (match_dup 0))
13550 (bswap:HI (match_dup 0)))
13551 (clobber (reg:CC FLAGS_REG))])]
13554 (define_expand "rotrqi3"
13555 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13556 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13557 (match_operand:QI 2 "nonmemory_operand" "")))
13558 (clobber (reg:CC FLAGS_REG))]
13559 "TARGET_QIMODE_MATH"
13560 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13562 (define_insn "*rotrqi3_1_one_bit"
13563 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13564 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13565 (match_operand:QI 2 "const1_operand" "")))
13566 (clobber (reg:CC FLAGS_REG))]
13567 "(TARGET_SHIFT1 || optimize_size)
13568 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13570 [(set_attr "type" "rotate")
13571 (set (attr "length")
13572 (if_then_else (match_operand 0 "register_operand" "")
13574 (const_string "*")))])
13576 (define_insn "*rotrqi3_1_one_bit_slp"
13577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13578 (rotatert:QI (match_dup 0)
13579 (match_operand:QI 1 "const1_operand" "")))
13580 (clobber (reg:CC FLAGS_REG))]
13581 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13582 && (TARGET_SHIFT1 || optimize_size)"
13584 [(set_attr "type" "rotate1")
13585 (set (attr "length")
13586 (if_then_else (match_operand 0 "register_operand" "")
13588 (const_string "*")))])
13590 (define_insn "*rotrqi3_1"
13591 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13592 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13593 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13594 (clobber (reg:CC FLAGS_REG))]
13595 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13597 ror{b}\t{%2, %0|%0, %2}
13598 ror{b}\t{%b2, %0|%0, %b2}"
13599 [(set_attr "type" "rotate")
13600 (set_attr "mode" "QI")])
13602 (define_insn "*rotrqi3_1_slp"
13603 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13604 (rotatert:QI (match_dup 0)
13605 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13606 (clobber (reg:CC FLAGS_REG))]
13607 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13608 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13610 ror{b}\t{%1, %0|%0, %1}
13611 ror{b}\t{%b1, %0|%0, %b1}"
13612 [(set_attr "type" "rotate1")
13613 (set_attr "mode" "QI")])
13615 ;; Bit set / bit test instructions
13617 (define_expand "extv"
13618 [(set (match_operand:SI 0 "register_operand" "")
13619 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13620 (match_operand:SI 2 "const8_operand" "")
13621 (match_operand:SI 3 "const8_operand" "")))]
13624 /* Handle extractions from %ah et al. */
13625 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13628 /* From mips.md: extract_bit_field doesn't verify that our source
13629 matches the predicate, so check it again here. */
13630 if (! ext_register_operand (operands[1], VOIDmode))
13634 (define_expand "extzv"
13635 [(set (match_operand:SI 0 "register_operand" "")
13636 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13637 (match_operand:SI 2 "const8_operand" "")
13638 (match_operand:SI 3 "const8_operand" "")))]
13641 /* Handle extractions from %ah et al. */
13642 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13645 /* From mips.md: extract_bit_field doesn't verify that our source
13646 matches the predicate, so check it again here. */
13647 if (! ext_register_operand (operands[1], VOIDmode))
13651 (define_expand "insv"
13652 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13653 (match_operand 1 "const8_operand" "")
13654 (match_operand 2 "const8_operand" ""))
13655 (match_operand 3 "register_operand" ""))]
13658 /* Handle insertions to %ah et al. */
13659 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13662 /* From mips.md: insert_bit_field doesn't verify that our source
13663 matches the predicate, so check it again here. */
13664 if (! ext_register_operand (operands[0], VOIDmode))
13668 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13670 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13675 ;; %%% bts, btr, btc, bt.
13676 ;; In general these instructions are *slow* when applied to memory,
13677 ;; since they enforce atomic operation. When applied to registers,
13678 ;; it depends on the cpu implementation. They're never faster than
13679 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13680 ;; no point. But in 64-bit, we can't hold the relevant immediates
13681 ;; within the instruction itself, so operating on bits in the high
13682 ;; 32-bits of a register becomes easier.
13684 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13685 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13686 ;; negdf respectively, so they can never be disabled entirely.
13688 (define_insn "*btsq"
13689 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13691 (match_operand:DI 1 "const_0_to_63_operand" ""))
13693 (clobber (reg:CC FLAGS_REG))]
13694 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13696 [(set_attr "type" "alu1")])
13698 (define_insn "*btrq"
13699 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13701 (match_operand:DI 1 "const_0_to_63_operand" ""))
13703 (clobber (reg:CC FLAGS_REG))]
13704 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13706 [(set_attr "type" "alu1")])
13708 (define_insn "*btcq"
13709 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13711 (match_operand:DI 1 "const_0_to_63_operand" ""))
13712 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13713 (clobber (reg:CC FLAGS_REG))]
13714 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13716 [(set_attr "type" "alu1")])
13718 ;; Allow Nocona to avoid these instructions if a register is available.
13721 [(match_scratch:DI 2 "r")
13722 (parallel [(set (zero_extract:DI
13723 (match_operand:DI 0 "register_operand" "")
13725 (match_operand:DI 1 "const_0_to_63_operand" ""))
13727 (clobber (reg:CC FLAGS_REG))])]
13728 "TARGET_64BIT && !TARGET_USE_BT"
13731 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13734 if (HOST_BITS_PER_WIDE_INT >= 64)
13735 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13736 else if (i < HOST_BITS_PER_WIDE_INT)
13737 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13739 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13741 op1 = immed_double_const (lo, hi, DImode);
13744 emit_move_insn (operands[2], op1);
13748 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13753 [(match_scratch:DI 2 "r")
13754 (parallel [(set (zero_extract:DI
13755 (match_operand:DI 0 "register_operand" "")
13757 (match_operand:DI 1 "const_0_to_63_operand" ""))
13759 (clobber (reg:CC FLAGS_REG))])]
13760 "TARGET_64BIT && !TARGET_USE_BT"
13763 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13766 if (HOST_BITS_PER_WIDE_INT >= 64)
13767 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13768 else if (i < HOST_BITS_PER_WIDE_INT)
13769 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13771 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13773 op1 = immed_double_const (~lo, ~hi, DImode);
13776 emit_move_insn (operands[2], op1);
13780 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13785 [(match_scratch:DI 2 "r")
13786 (parallel [(set (zero_extract:DI
13787 (match_operand:DI 0 "register_operand" "")
13789 (match_operand:DI 1 "const_0_to_63_operand" ""))
13790 (not:DI (zero_extract:DI
13791 (match_dup 0) (const_int 1) (match_dup 1))))
13792 (clobber (reg:CC FLAGS_REG))])]
13793 "TARGET_64BIT && !TARGET_USE_BT"
13796 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13799 if (HOST_BITS_PER_WIDE_INT >= 64)
13800 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13801 else if (i < HOST_BITS_PER_WIDE_INT)
13802 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13804 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13806 op1 = immed_double_const (lo, hi, DImode);
13809 emit_move_insn (operands[2], op1);
13813 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13817 ;; Store-flag instructions.
13819 ;; For all sCOND expanders, also expand the compare or test insn that
13820 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13822 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13823 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13824 ;; way, which can later delete the movzx if only QImode is needed.
13826 (define_expand "s<code>"
13827 [(set (match_operand:QI 0 "register_operand" "")
13828 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13830 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13832 (define_expand "s<code>"
13833 [(set (match_operand:QI 0 "register_operand" "")
13834 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13835 "TARGET_80387 || TARGET_SSE"
13836 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13838 (define_insn "*setcc_1"
13839 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13840 (match_operator:QI 1 "ix86_comparison_operator"
13841 [(reg FLAGS_REG) (const_int 0)]))]
13844 [(set_attr "type" "setcc")
13845 (set_attr "mode" "QI")])
13847 (define_insn "*setcc_2"
13848 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13849 (match_operator:QI 1 "ix86_comparison_operator"
13850 [(reg FLAGS_REG) (const_int 0)]))]
13853 [(set_attr "type" "setcc")
13854 (set_attr "mode" "QI")])
13856 ;; In general it is not safe to assume too much about CCmode registers,
13857 ;; so simplify-rtx stops when it sees a second one. Under certain
13858 ;; conditions this is safe on x86, so help combine not create
13865 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13866 (ne:QI (match_operator 1 "ix86_comparison_operator"
13867 [(reg FLAGS_REG) (const_int 0)])
13870 [(set (match_dup 0) (match_dup 1))]
13872 PUT_MODE (operands[1], QImode);
13876 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13877 (ne:QI (match_operator 1 "ix86_comparison_operator"
13878 [(reg FLAGS_REG) (const_int 0)])
13881 [(set (match_dup 0) (match_dup 1))]
13883 PUT_MODE (operands[1], QImode);
13887 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13888 (eq:QI (match_operator 1 "ix86_comparison_operator"
13889 [(reg FLAGS_REG) (const_int 0)])
13892 [(set (match_dup 0) (match_dup 1))]
13894 rtx new_op1 = copy_rtx (operands[1]);
13895 operands[1] = new_op1;
13896 PUT_MODE (new_op1, QImode);
13897 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13898 GET_MODE (XEXP (new_op1, 0))));
13900 /* Make sure that (a) the CCmode we have for the flags is strong
13901 enough for the reversed compare or (b) we have a valid FP compare. */
13902 if (! ix86_comparison_operator (new_op1, VOIDmode))
13907 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13908 (eq:QI (match_operator 1 "ix86_comparison_operator"
13909 [(reg FLAGS_REG) (const_int 0)])
13912 [(set (match_dup 0) (match_dup 1))]
13914 rtx new_op1 = copy_rtx (operands[1]);
13915 operands[1] = new_op1;
13916 PUT_MODE (new_op1, QImode);
13917 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13918 GET_MODE (XEXP (new_op1, 0))));
13920 /* Make sure that (a) the CCmode we have for the flags is strong
13921 enough for the reversed compare or (b) we have a valid FP compare. */
13922 if (! ix86_comparison_operator (new_op1, VOIDmode))
13926 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13927 ;; subsequent logical operations are used to imitate conditional moves.
13928 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13931 (define_insn "*sse_setcc<mode>"
13932 [(set (match_operand:MODEF 0 "register_operand" "=x")
13933 (match_operator:MODEF 1 "sse_comparison_operator"
13934 [(match_operand:MODEF 2 "register_operand" "0")
13935 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13936 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13937 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13938 [(set_attr "type" "ssecmp")
13939 (set_attr "mode" "<MODE>")])
13941 (define_insn "*sse5_setcc<mode>"
13942 [(set (match_operand:MODEF 0 "register_operand" "=x")
13943 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13944 [(match_operand:MODEF 2 "register_operand" "x")
13945 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13947 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13948 [(set_attr "type" "sse4arg")
13949 (set_attr "mode" "<MODE>")])
13952 ;; Basic conditional jump instructions.
13953 ;; We ignore the overflow flag for signed branch instructions.
13955 ;; For all bCOND expanders, also expand the compare or test insn that
13956 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13958 (define_expand "b<code>"
13960 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13962 (label_ref (match_operand 0 ""))
13965 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13967 (define_expand "b<code>"
13969 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13971 (label_ref (match_operand 0 ""))
13973 "TARGET_80387 || TARGET_SSE_MATH"
13974 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13976 (define_insn "*jcc_1"
13978 (if_then_else (match_operator 1 "ix86_comparison_operator"
13979 [(reg FLAGS_REG) (const_int 0)])
13980 (label_ref (match_operand 0 "" ""))
13984 [(set_attr "type" "ibr")
13985 (set_attr "modrm" "0")
13986 (set (attr "length")
13987 (if_then_else (and (ge (minus (match_dup 0) (pc))
13989 (lt (minus (match_dup 0) (pc))
13994 (define_insn "*jcc_2"
13996 (if_then_else (match_operator 1 "ix86_comparison_operator"
13997 [(reg FLAGS_REG) (const_int 0)])
13999 (label_ref (match_operand 0 "" ""))))]
14002 [(set_attr "type" "ibr")
14003 (set_attr "modrm" "0")
14004 (set (attr "length")
14005 (if_then_else (and (ge (minus (match_dup 0) (pc))
14007 (lt (minus (match_dup 0) (pc))
14012 ;; In general it is not safe to assume too much about CCmode registers,
14013 ;; so simplify-rtx stops when it sees a second one. Under certain
14014 ;; conditions this is safe on x86, so help combine not create
14022 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14023 [(reg FLAGS_REG) (const_int 0)])
14025 (label_ref (match_operand 1 "" ""))
14029 (if_then_else (match_dup 0)
14030 (label_ref (match_dup 1))
14033 PUT_MODE (operands[0], VOIDmode);
14038 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14039 [(reg FLAGS_REG) (const_int 0)])
14041 (label_ref (match_operand 1 "" ""))
14045 (if_then_else (match_dup 0)
14046 (label_ref (match_dup 1))
14049 rtx new_op0 = copy_rtx (operands[0]);
14050 operands[0] = new_op0;
14051 PUT_MODE (new_op0, VOIDmode);
14052 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14053 GET_MODE (XEXP (new_op0, 0))));
14055 /* Make sure that (a) the CCmode we have for the flags is strong
14056 enough for the reversed compare or (b) we have a valid FP compare. */
14057 if (! ix86_comparison_operator (new_op0, VOIDmode))
14061 ;; Define combination compare-and-branch fp compare instructions to use
14062 ;; during early optimization. Splitting the operation apart early makes
14063 ;; for bad code when we want to reverse the operation.
14065 (define_insn "*fp_jcc_1_mixed"
14067 (if_then_else (match_operator 0 "comparison_operator"
14068 [(match_operand 1 "register_operand" "f,x")
14069 (match_operand 2 "nonimmediate_operand" "f,xm")])
14070 (label_ref (match_operand 3 "" ""))
14072 (clobber (reg:CCFP FPSR_REG))
14073 (clobber (reg:CCFP FLAGS_REG))]
14074 "TARGET_MIX_SSE_I387
14075 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14076 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14077 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14080 (define_insn "*fp_jcc_1_sse"
14082 (if_then_else (match_operator 0 "comparison_operator"
14083 [(match_operand 1 "register_operand" "x")
14084 (match_operand 2 "nonimmediate_operand" "xm")])
14085 (label_ref (match_operand 3 "" ""))
14087 (clobber (reg:CCFP FPSR_REG))
14088 (clobber (reg:CCFP FLAGS_REG))]
14090 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14091 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14092 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14095 (define_insn "*fp_jcc_1_387"
14097 (if_then_else (match_operator 0 "comparison_operator"
14098 [(match_operand 1 "register_operand" "f")
14099 (match_operand 2 "register_operand" "f")])
14100 (label_ref (match_operand 3 "" ""))
14102 (clobber (reg:CCFP FPSR_REG))
14103 (clobber (reg:CCFP FLAGS_REG))]
14104 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14106 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14107 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14110 (define_insn "*fp_jcc_2_mixed"
14112 (if_then_else (match_operator 0 "comparison_operator"
14113 [(match_operand 1 "register_operand" "f,x")
14114 (match_operand 2 "nonimmediate_operand" "f,xm")])
14116 (label_ref (match_operand 3 "" ""))))
14117 (clobber (reg:CCFP FPSR_REG))
14118 (clobber (reg:CCFP FLAGS_REG))]
14119 "TARGET_MIX_SSE_I387
14120 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14121 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14122 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14125 (define_insn "*fp_jcc_2_sse"
14127 (if_then_else (match_operator 0 "comparison_operator"
14128 [(match_operand 1 "register_operand" "x")
14129 (match_operand 2 "nonimmediate_operand" "xm")])
14131 (label_ref (match_operand 3 "" ""))))
14132 (clobber (reg:CCFP FPSR_REG))
14133 (clobber (reg:CCFP FLAGS_REG))]
14135 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14136 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14137 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14140 (define_insn "*fp_jcc_2_387"
14142 (if_then_else (match_operator 0 "comparison_operator"
14143 [(match_operand 1 "register_operand" "f")
14144 (match_operand 2 "register_operand" "f")])
14146 (label_ref (match_operand 3 "" ""))))
14147 (clobber (reg:CCFP FPSR_REG))
14148 (clobber (reg:CCFP FLAGS_REG))]
14149 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14151 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14152 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14155 (define_insn "*fp_jcc_3_387"
14157 (if_then_else (match_operator 0 "comparison_operator"
14158 [(match_operand 1 "register_operand" "f")
14159 (match_operand 2 "nonimmediate_operand" "fm")])
14160 (label_ref (match_operand 3 "" ""))
14162 (clobber (reg:CCFP FPSR_REG))
14163 (clobber (reg:CCFP FLAGS_REG))
14164 (clobber (match_scratch:HI 4 "=a"))]
14166 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14167 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14168 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14169 && SELECT_CC_MODE (GET_CODE (operands[0]),
14170 operands[1], operands[2]) == CCFPmode
14171 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14174 (define_insn "*fp_jcc_4_387"
14176 (if_then_else (match_operator 0 "comparison_operator"
14177 [(match_operand 1 "register_operand" "f")
14178 (match_operand 2 "nonimmediate_operand" "fm")])
14180 (label_ref (match_operand 3 "" ""))))
14181 (clobber (reg:CCFP FPSR_REG))
14182 (clobber (reg:CCFP FLAGS_REG))
14183 (clobber (match_scratch:HI 4 "=a"))]
14185 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14186 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14187 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14188 && SELECT_CC_MODE (GET_CODE (operands[0]),
14189 operands[1], operands[2]) == CCFPmode
14190 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14193 (define_insn "*fp_jcc_5_387"
14195 (if_then_else (match_operator 0 "comparison_operator"
14196 [(match_operand 1 "register_operand" "f")
14197 (match_operand 2 "register_operand" "f")])
14198 (label_ref (match_operand 3 "" ""))
14200 (clobber (reg:CCFP FPSR_REG))
14201 (clobber (reg:CCFP FLAGS_REG))
14202 (clobber (match_scratch:HI 4 "=a"))]
14203 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14204 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14205 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14208 (define_insn "*fp_jcc_6_387"
14210 (if_then_else (match_operator 0 "comparison_operator"
14211 [(match_operand 1 "register_operand" "f")
14212 (match_operand 2 "register_operand" "f")])
14214 (label_ref (match_operand 3 "" ""))))
14215 (clobber (reg:CCFP FPSR_REG))
14216 (clobber (reg:CCFP FLAGS_REG))
14217 (clobber (match_scratch:HI 4 "=a"))]
14218 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14219 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14220 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14223 (define_insn "*fp_jcc_7_387"
14225 (if_then_else (match_operator 0 "comparison_operator"
14226 [(match_operand 1 "register_operand" "f")
14227 (match_operand 2 "const0_operand" "X")])
14228 (label_ref (match_operand 3 "" ""))
14230 (clobber (reg:CCFP FPSR_REG))
14231 (clobber (reg:CCFP FLAGS_REG))
14232 (clobber (match_scratch:HI 4 "=a"))]
14233 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14234 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14235 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14236 && SELECT_CC_MODE (GET_CODE (operands[0]),
14237 operands[1], operands[2]) == CCFPmode
14238 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14241 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14242 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14243 ;; with a precedence over other operators and is always put in the first
14244 ;; place. Swap condition and operands to match ficom instruction.
14246 (define_insn "*fp_jcc_8<mode>_387"
14248 (if_then_else (match_operator 0 "comparison_operator"
14249 [(match_operator 1 "float_operator"
14250 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14251 (match_operand 3 "register_operand" "f,f")])
14252 (label_ref (match_operand 4 "" ""))
14254 (clobber (reg:CCFP FPSR_REG))
14255 (clobber (reg:CCFP FLAGS_REG))
14256 (clobber (match_scratch:HI 5 "=a,a"))]
14257 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14258 && TARGET_USE_<MODE>MODE_FIOP
14259 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14260 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14261 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14262 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14267 (if_then_else (match_operator 0 "comparison_operator"
14268 [(match_operand 1 "register_operand" "")
14269 (match_operand 2 "nonimmediate_operand" "")])
14270 (match_operand 3 "" "")
14271 (match_operand 4 "" "")))
14272 (clobber (reg:CCFP FPSR_REG))
14273 (clobber (reg:CCFP FLAGS_REG))]
14277 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14278 operands[3], operands[4], NULL_RTX, NULL_RTX);
14284 (if_then_else (match_operator 0 "comparison_operator"
14285 [(match_operand 1 "register_operand" "")
14286 (match_operand 2 "general_operand" "")])
14287 (match_operand 3 "" "")
14288 (match_operand 4 "" "")))
14289 (clobber (reg:CCFP FPSR_REG))
14290 (clobber (reg:CCFP FLAGS_REG))
14291 (clobber (match_scratch:HI 5 "=a"))]
14295 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14296 operands[3], operands[4], operands[5], NULL_RTX);
14302 (if_then_else (match_operator 0 "comparison_operator"
14303 [(match_operator 1 "float_operator"
14304 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14305 (match_operand 3 "register_operand" "")])
14306 (match_operand 4 "" "")
14307 (match_operand 5 "" "")))
14308 (clobber (reg:CCFP FPSR_REG))
14309 (clobber (reg:CCFP FLAGS_REG))
14310 (clobber (match_scratch:HI 6 "=a"))]
14314 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14315 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14316 operands[3], operands[7],
14317 operands[4], operands[5], operands[6], NULL_RTX);
14321 ;; %%% Kill this when reload knows how to do it.
14324 (if_then_else (match_operator 0 "comparison_operator"
14325 [(match_operator 1 "float_operator"
14326 [(match_operand:X87MODEI12 2 "register_operand" "")])
14327 (match_operand 3 "register_operand" "")])
14328 (match_operand 4 "" "")
14329 (match_operand 5 "" "")))
14330 (clobber (reg:CCFP FPSR_REG))
14331 (clobber (reg:CCFP FLAGS_REG))
14332 (clobber (match_scratch:HI 6 "=a"))]
14336 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14337 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14338 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14339 operands[3], operands[7],
14340 operands[4], operands[5], operands[6], operands[2]);
14344 ;; Unconditional and other jump instructions
14346 (define_insn "jump"
14348 (label_ref (match_operand 0 "" "")))]
14351 [(set_attr "type" "ibr")
14352 (set (attr "length")
14353 (if_then_else (and (ge (minus (match_dup 0) (pc))
14355 (lt (minus (match_dup 0) (pc))
14359 (set_attr "modrm" "0")])
14361 (define_expand "indirect_jump"
14362 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14366 (define_insn "*indirect_jump"
14367 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14370 [(set_attr "type" "ibr")
14371 (set_attr "length_immediate" "0")])
14373 (define_insn "*indirect_jump_rtx64"
14374 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14377 [(set_attr "type" "ibr")
14378 (set_attr "length_immediate" "0")])
14380 (define_expand "tablejump"
14381 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14382 (use (label_ref (match_operand 1 "" "")))])]
14385 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14386 relative. Convert the relative address to an absolute address. */
14390 enum rtx_code code;
14392 /* We can't use @GOTOFF for text labels on VxWorks;
14393 see gotoff_operand. */
14394 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14398 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14400 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14404 op1 = pic_offset_table_rtx;
14409 op0 = pic_offset_table_rtx;
14413 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14418 (define_insn "*tablejump_1"
14419 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14420 (use (label_ref (match_operand 1 "" "")))]
14423 [(set_attr "type" "ibr")
14424 (set_attr "length_immediate" "0")])
14426 (define_insn "*tablejump_1_rtx64"
14427 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14428 (use (label_ref (match_operand 1 "" "")))]
14431 [(set_attr "type" "ibr")
14432 (set_attr "length_immediate" "0")])
14434 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14437 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14438 (set (match_operand:QI 1 "register_operand" "")
14439 (match_operator:QI 2 "ix86_comparison_operator"
14440 [(reg FLAGS_REG) (const_int 0)]))
14441 (set (match_operand 3 "q_regs_operand" "")
14442 (zero_extend (match_dup 1)))]
14443 "(peep2_reg_dead_p (3, operands[1])
14444 || operands_match_p (operands[1], operands[3]))
14445 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14446 [(set (match_dup 4) (match_dup 0))
14447 (set (strict_low_part (match_dup 5))
14450 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14451 operands[5] = gen_lowpart (QImode, operands[3]);
14452 ix86_expand_clear (operands[3]);
14455 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14458 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14459 (set (match_operand:QI 1 "register_operand" "")
14460 (match_operator:QI 2 "ix86_comparison_operator"
14461 [(reg FLAGS_REG) (const_int 0)]))
14462 (parallel [(set (match_operand 3 "q_regs_operand" "")
14463 (zero_extend (match_dup 1)))
14464 (clobber (reg:CC FLAGS_REG))])]
14465 "(peep2_reg_dead_p (3, operands[1])
14466 || operands_match_p (operands[1], operands[3]))
14467 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14468 [(set (match_dup 4) (match_dup 0))
14469 (set (strict_low_part (match_dup 5))
14472 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14473 operands[5] = gen_lowpart (QImode, operands[3]);
14474 ix86_expand_clear (operands[3]);
14477 ;; Call instructions.
14479 ;; The predicates normally associated with named expanders are not properly
14480 ;; checked for calls. This is a bug in the generic code, but it isn't that
14481 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14483 ;; Call subroutine returning no value.
14485 (define_expand "call_pop"
14486 [(parallel [(call (match_operand:QI 0 "" "")
14487 (match_operand:SI 1 "" ""))
14488 (set (reg:SI SP_REG)
14489 (plus:SI (reg:SI SP_REG)
14490 (match_operand:SI 3 "" "")))])]
14493 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14497 (define_insn "*call_pop_0"
14498 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14499 (match_operand:SI 1 "" ""))
14500 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14501 (match_operand:SI 2 "immediate_operand" "")))]
14504 if (SIBLING_CALL_P (insn))
14507 return "call\t%P0";
14509 [(set_attr "type" "call")])
14511 (define_insn "*call_pop_1"
14512 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14513 (match_operand:SI 1 "" ""))
14514 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14515 (match_operand:SI 2 "immediate_operand" "i")))]
14518 if (constant_call_address_operand (operands[0], Pmode))
14520 if (SIBLING_CALL_P (insn))
14523 return "call\t%P0";
14525 if (SIBLING_CALL_P (insn))
14528 return "call\t%A0";
14530 [(set_attr "type" "call")])
14532 (define_expand "call"
14533 [(call (match_operand:QI 0 "" "")
14534 (match_operand 1 "" ""))
14535 (use (match_operand 2 "" ""))]
14538 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14542 (define_expand "sibcall"
14543 [(call (match_operand:QI 0 "" "")
14544 (match_operand 1 "" ""))
14545 (use (match_operand 2 "" ""))]
14548 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14552 (define_insn "*call_0"
14553 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14554 (match_operand 1 "" ""))]
14557 if (SIBLING_CALL_P (insn))
14560 return "call\t%P0";
14562 [(set_attr "type" "call")])
14564 (define_insn "*call_1"
14565 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14566 (match_operand 1 "" ""))]
14567 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14569 if (constant_call_address_operand (operands[0], Pmode))
14570 return "call\t%P0";
14571 return "call\t%A0";
14573 [(set_attr "type" "call")])
14575 (define_insn "*sibcall_1"
14576 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14577 (match_operand 1 "" ""))]
14578 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14580 if (constant_call_address_operand (operands[0], Pmode))
14584 [(set_attr "type" "call")])
14586 (define_insn "*call_1_rex64"
14587 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14588 (match_operand 1 "" ""))]
14589 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14590 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14592 if (constant_call_address_operand (operands[0], Pmode))
14593 return "call\t%P0";
14594 return "call\t%A0";
14596 [(set_attr "type" "call")])
14598 (define_insn "*call_1_rex64_large"
14599 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14600 (match_operand 1 "" ""))]
14601 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14603 [(set_attr "type" "call")])
14605 (define_insn "*sibcall_1_rex64"
14606 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14607 (match_operand 1 "" ""))]
14608 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14610 [(set_attr "type" "call")])
14612 (define_insn "*sibcall_1_rex64_v"
14613 [(call (mem:QI (reg:DI R11_REG))
14614 (match_operand 0 "" ""))]
14615 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14617 [(set_attr "type" "call")])
14620 ;; Call subroutine, returning value in operand 0
14622 (define_expand "call_value_pop"
14623 [(parallel [(set (match_operand 0 "" "")
14624 (call (match_operand:QI 1 "" "")
14625 (match_operand:SI 2 "" "")))
14626 (set (reg:SI SP_REG)
14627 (plus:SI (reg:SI SP_REG)
14628 (match_operand:SI 4 "" "")))])]
14631 ix86_expand_call (operands[0], operands[1], operands[2],
14632 operands[3], operands[4], 0);
14636 (define_expand "call_value"
14637 [(set (match_operand 0 "" "")
14638 (call (match_operand:QI 1 "" "")
14639 (match_operand:SI 2 "" "")))
14640 (use (match_operand:SI 3 "" ""))]
14641 ;; Operand 2 not used on the i386.
14644 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14648 (define_expand "sibcall_value"
14649 [(set (match_operand 0 "" "")
14650 (call (match_operand:QI 1 "" "")
14651 (match_operand:SI 2 "" "")))
14652 (use (match_operand:SI 3 "" ""))]
14653 ;; Operand 2 not used on the i386.
14656 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14660 ;; Call subroutine returning any type.
14662 (define_expand "untyped_call"
14663 [(parallel [(call (match_operand 0 "" "")
14665 (match_operand 1 "" "")
14666 (match_operand 2 "" "")])]
14671 /* In order to give reg-stack an easier job in validating two
14672 coprocessor registers as containing a possible return value,
14673 simply pretend the untyped call returns a complex long double
14676 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14677 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14678 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14681 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14683 rtx set = XVECEXP (operands[2], 0, i);
14684 emit_move_insn (SET_DEST (set), SET_SRC (set));
14687 /* The optimizer does not know that the call sets the function value
14688 registers we stored in the result block. We avoid problems by
14689 claiming that all hard registers are used and clobbered at this
14691 emit_insn (gen_blockage ());
14696 ;; Prologue and epilogue instructions
14698 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14699 ;; all of memory. This blocks insns from being moved across this point.
14701 (define_insn "blockage"
14702 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14705 [(set_attr "length" "0")])
14707 ;; As USE insns aren't meaningful after reload, this is used instead
14708 ;; to prevent deleting instructions setting registers for PIC code
14709 (define_insn "prologue_use"
14710 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14713 [(set_attr "length" "0")])
14715 ;; Insn emitted into the body of a function to return from a function.
14716 ;; This is only done if the function's epilogue is known to be simple.
14717 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14719 (define_expand "return"
14721 "ix86_can_use_return_insn_p ()"
14723 if (current_function_pops_args)
14725 rtx popc = GEN_INT (current_function_pops_args);
14726 emit_jump_insn (gen_return_pop_internal (popc));
14731 (define_insn "return_internal"
14735 [(set_attr "length" "1")
14736 (set_attr "length_immediate" "0")
14737 (set_attr "modrm" "0")])
14739 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14740 ;; instruction Athlon and K8 have.
14742 (define_insn "return_internal_long"
14744 (unspec [(const_int 0)] UNSPEC_REP)]
14747 [(set_attr "length" "1")
14748 (set_attr "length_immediate" "0")
14749 (set_attr "prefix_rep" "1")
14750 (set_attr "modrm" "0")])
14752 (define_insn "return_pop_internal"
14754 (use (match_operand:SI 0 "const_int_operand" ""))]
14757 [(set_attr "length" "3")
14758 (set_attr "length_immediate" "2")
14759 (set_attr "modrm" "0")])
14761 (define_insn "return_indirect_internal"
14763 (use (match_operand:SI 0 "register_operand" "r"))]
14766 [(set_attr "type" "ibr")
14767 (set_attr "length_immediate" "0")])
14773 [(set_attr "length" "1")
14774 (set_attr "length_immediate" "0")
14775 (set_attr "modrm" "0")])
14777 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14778 ;; branch prediction penalty for the third jump in a 16-byte
14781 (define_insn "align"
14782 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14785 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14786 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14788 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14789 The align insn is used to avoid 3 jump instructions in the row to improve
14790 branch prediction and the benefits hardly outweigh the cost of extra 8
14791 nops on the average inserted by full alignment pseudo operation. */
14795 [(set_attr "length" "16")])
14797 (define_expand "prologue"
14800 "ix86_expand_prologue (); DONE;")
14802 (define_insn "set_got"
14803 [(set (match_operand:SI 0 "register_operand" "=r")
14804 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14805 (clobber (reg:CC FLAGS_REG))]
14807 { return output_set_got (operands[0], NULL_RTX); }
14808 [(set_attr "type" "multi")
14809 (set_attr "length" "12")])
14811 (define_insn "set_got_labelled"
14812 [(set (match_operand:SI 0 "register_operand" "=r")
14813 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14815 (clobber (reg:CC FLAGS_REG))]
14817 { return output_set_got (operands[0], operands[1]); }
14818 [(set_attr "type" "multi")
14819 (set_attr "length" "12")])
14821 (define_insn "set_got_rex64"
14822 [(set (match_operand:DI 0 "register_operand" "=r")
14823 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14825 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14826 [(set_attr "type" "lea")
14827 (set_attr "length" "6")])
14829 (define_insn "set_rip_rex64"
14830 [(set (match_operand:DI 0 "register_operand" "=r")
14831 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14833 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14834 [(set_attr "type" "lea")
14835 (set_attr "length" "6")])
14837 (define_insn "set_got_offset_rex64"
14838 [(set (match_operand:DI 0 "register_operand" "=r")
14839 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14841 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14842 [(set_attr "type" "imov")
14843 (set_attr "length" "11")])
14845 (define_expand "epilogue"
14848 "ix86_expand_epilogue (1); DONE;")
14850 (define_expand "sibcall_epilogue"
14853 "ix86_expand_epilogue (0); DONE;")
14855 (define_expand "eh_return"
14856 [(use (match_operand 0 "register_operand" ""))]
14859 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14861 /* Tricky bit: we write the address of the handler to which we will
14862 be returning into someone else's stack frame, one word below the
14863 stack address we wish to restore. */
14864 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14865 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14866 tmp = gen_rtx_MEM (Pmode, tmp);
14867 emit_move_insn (tmp, ra);
14869 if (Pmode == SImode)
14870 emit_jump_insn (gen_eh_return_si (sa));
14872 emit_jump_insn (gen_eh_return_di (sa));
14877 (define_insn_and_split "eh_return_si"
14879 (unspec [(match_operand:SI 0 "register_operand" "c")]
14880 UNSPEC_EH_RETURN))]
14885 "ix86_expand_epilogue (2); DONE;")
14887 (define_insn_and_split "eh_return_di"
14889 (unspec [(match_operand:DI 0 "register_operand" "c")]
14890 UNSPEC_EH_RETURN))]
14895 "ix86_expand_epilogue (2); DONE;")
14897 (define_insn "leave"
14898 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14899 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14900 (clobber (mem:BLK (scratch)))]
14903 [(set_attr "type" "leave")])
14905 (define_insn "leave_rex64"
14906 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14907 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14908 (clobber (mem:BLK (scratch)))]
14911 [(set_attr "type" "leave")])
14913 (define_expand "ffssi2"
14915 [(set (match_operand:SI 0 "register_operand" "")
14916 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14917 (clobber (match_scratch:SI 2 ""))
14918 (clobber (reg:CC FLAGS_REG))])]
14923 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14928 (define_expand "ffs_cmove"
14929 [(set (match_dup 2) (const_int -1))
14930 (parallel [(set (reg:CCZ FLAGS_REG)
14931 (compare:CCZ (match_operand:SI 1 "register_operand" "")
14933 (set (match_operand:SI 0 "nonimmediate_operand" "")
14934 (ctz:SI (match_dup 1)))])
14935 (set (match_dup 0) (if_then_else:SI
14936 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14939 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14940 (clobber (reg:CC FLAGS_REG))])]
14942 "operands[2] = gen_reg_rtx (SImode);")
14944 (define_insn_and_split "*ffs_no_cmove"
14945 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14946 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14947 (clobber (match_scratch:SI 2 "=&q"))
14948 (clobber (reg:CC FLAGS_REG))]
14951 "&& reload_completed"
14952 [(parallel [(set (reg:CCZ FLAGS_REG)
14953 (compare:CCZ (match_dup 1) (const_int 0)))
14954 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14955 (set (strict_low_part (match_dup 3))
14956 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14957 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14958 (clobber (reg:CC FLAGS_REG))])
14959 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14960 (clobber (reg:CC FLAGS_REG))])
14961 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14962 (clobber (reg:CC FLAGS_REG))])]
14964 operands[3] = gen_lowpart (QImode, operands[2]);
14965 ix86_expand_clear (operands[2]);
14968 (define_insn "*ffssi_1"
14969 [(set (reg:CCZ FLAGS_REG)
14970 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14972 (set (match_operand:SI 0 "register_operand" "=r")
14973 (ctz:SI (match_dup 1)))]
14975 "bsf{l}\t{%1, %0|%0, %1}"
14976 [(set_attr "prefix_0f" "1")])
14978 (define_expand "ffsdi2"
14979 [(set (match_dup 2) (const_int -1))
14980 (parallel [(set (reg:CCZ FLAGS_REG)
14981 (compare:CCZ (match_operand:DI 1 "register_operand" "")
14983 (set (match_operand:DI 0 "nonimmediate_operand" "")
14984 (ctz:DI (match_dup 1)))])
14985 (set (match_dup 0) (if_then_else:DI
14986 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14989 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14990 (clobber (reg:CC FLAGS_REG))])]
14992 "operands[2] = gen_reg_rtx (DImode);")
14994 (define_insn "*ffsdi_1"
14995 [(set (reg:CCZ FLAGS_REG)
14996 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14998 (set (match_operand:DI 0 "register_operand" "=r")
14999 (ctz:DI (match_dup 1)))]
15001 "bsf{q}\t{%1, %0|%0, %1}"
15002 [(set_attr "prefix_0f" "1")])
15004 (define_insn "ctzsi2"
15005 [(set (match_operand:SI 0 "register_operand" "=r")
15006 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15007 (clobber (reg:CC FLAGS_REG))]
15009 "bsf{l}\t{%1, %0|%0, %1}"
15010 [(set_attr "prefix_0f" "1")])
15012 (define_insn "ctzdi2"
15013 [(set (match_operand:DI 0 "register_operand" "=r")
15014 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15015 (clobber (reg:CC FLAGS_REG))]
15017 "bsf{q}\t{%1, %0|%0, %1}"
15018 [(set_attr "prefix_0f" "1")])
15020 (define_expand "clzsi2"
15022 [(set (match_operand:SI 0 "register_operand" "")
15023 (minus:SI (const_int 31)
15024 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15025 (clobber (reg:CC FLAGS_REG))])
15027 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15028 (clobber (reg:CC FLAGS_REG))])]
15033 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15038 (define_insn "clzsi2_abm"
15039 [(set (match_operand:SI 0 "register_operand" "=r")
15040 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15041 (clobber (reg:CC FLAGS_REG))]
15043 "lzcnt{l}\t{%1, %0|%0, %1}"
15044 [(set_attr "prefix_rep" "1")
15045 (set_attr "type" "bitmanip")
15046 (set_attr "mode" "SI")])
15048 (define_insn "*bsr"
15049 [(set (match_operand:SI 0 "register_operand" "=r")
15050 (minus:SI (const_int 31)
15051 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15052 (clobber (reg:CC FLAGS_REG))]
15054 "bsr{l}\t{%1, %0|%0, %1}"
15055 [(set_attr "prefix_0f" "1")
15056 (set_attr "mode" "SI")])
15058 (define_insn "popcountsi2"
15059 [(set (match_operand:SI 0 "register_operand" "=r")
15060 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15061 (clobber (reg:CC FLAGS_REG))]
15063 "popcnt{l}\t{%1, %0|%0, %1}"
15064 [(set_attr "prefix_rep" "1")
15065 (set_attr "type" "bitmanip")
15066 (set_attr "mode" "SI")])
15068 (define_insn "*popcountsi2_cmp"
15069 [(set (reg FLAGS_REG)
15071 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15073 (set (match_operand:SI 0 "register_operand" "=r")
15074 (popcount:SI (match_dup 1)))]
15075 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15076 "popcnt{l}\t{%1, %0|%0, %1}"
15077 [(set_attr "prefix_rep" "1")
15078 (set_attr "type" "bitmanip")
15079 (set_attr "mode" "SI")])
15081 (define_insn "*popcountsi2_cmp_zext"
15082 [(set (reg FLAGS_REG)
15084 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15086 (set (match_operand:DI 0 "register_operand" "=r")
15087 (zero_extend:DI(popcount:SI (match_dup 1))))]
15088 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15089 "popcnt{l}\t{%1, %0|%0, %1}"
15090 [(set_attr "prefix_rep" "1")
15091 (set_attr "type" "bitmanip")
15092 (set_attr "mode" "SI")])
15094 (define_expand "bswapsi2"
15095 [(set (match_operand:SI 0 "register_operand" "")
15096 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15101 rtx x = operands[0];
15103 emit_move_insn (x, operands[1]);
15104 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15105 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15106 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15111 (define_insn "*bswapsi_1"
15112 [(set (match_operand:SI 0 "register_operand" "=r")
15113 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15116 [(set_attr "prefix_0f" "1")
15117 (set_attr "length" "2")])
15119 (define_insn "*bswaphi_lowpart_1"
15120 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15121 (bswap:HI (match_dup 0)))
15122 (clobber (reg:CC FLAGS_REG))]
15123 "TARGET_USE_XCHGB || optimize_size"
15125 xchg{b}\t{%h0, %b0|%b0, %h0}
15126 rol{w}\t{$8, %0|%0, 8}"
15127 [(set_attr "length" "2,4")
15128 (set_attr "mode" "QI,HI")])
15130 (define_insn "bswaphi_lowpart"
15131 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15132 (bswap:HI (match_dup 0)))
15133 (clobber (reg:CC FLAGS_REG))]
15135 "rol{w}\t{$8, %0|%0, 8}"
15136 [(set_attr "length" "4")
15137 (set_attr "mode" "HI")])
15139 (define_insn "bswapdi2"
15140 [(set (match_operand:DI 0 "register_operand" "=r")
15141 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15144 [(set_attr "prefix_0f" "1")
15145 (set_attr "length" "3")])
15147 (define_expand "clzdi2"
15149 [(set (match_operand:DI 0 "register_operand" "")
15150 (minus:DI (const_int 63)
15151 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15152 (clobber (reg:CC FLAGS_REG))])
15154 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15155 (clobber (reg:CC FLAGS_REG))])]
15160 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15165 (define_insn "clzdi2_abm"
15166 [(set (match_operand:DI 0 "register_operand" "=r")
15167 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15168 (clobber (reg:CC FLAGS_REG))]
15169 "TARGET_64BIT && TARGET_ABM"
15170 "lzcnt{q}\t{%1, %0|%0, %1}"
15171 [(set_attr "prefix_rep" "1")
15172 (set_attr "type" "bitmanip")
15173 (set_attr "mode" "DI")])
15175 (define_insn "*bsr_rex64"
15176 [(set (match_operand:DI 0 "register_operand" "=r")
15177 (minus:DI (const_int 63)
15178 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15179 (clobber (reg:CC FLAGS_REG))]
15181 "bsr{q}\t{%1, %0|%0, %1}"
15182 [(set_attr "prefix_0f" "1")
15183 (set_attr "mode" "DI")])
15185 (define_insn "popcountdi2"
15186 [(set (match_operand:DI 0 "register_operand" "=r")
15187 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15188 (clobber (reg:CC FLAGS_REG))]
15189 "TARGET_64BIT && TARGET_POPCNT"
15190 "popcnt{q}\t{%1, %0|%0, %1}"
15191 [(set_attr "prefix_rep" "1")
15192 (set_attr "type" "bitmanip")
15193 (set_attr "mode" "DI")])
15195 (define_insn "*popcountdi2_cmp"
15196 [(set (reg FLAGS_REG)
15198 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15200 (set (match_operand:DI 0 "register_operand" "=r")
15201 (popcount:DI (match_dup 1)))]
15202 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15203 "popcnt{q}\t{%1, %0|%0, %1}"
15204 [(set_attr "prefix_rep" "1")
15205 (set_attr "type" "bitmanip")
15206 (set_attr "mode" "DI")])
15208 (define_expand "clzhi2"
15210 [(set (match_operand:HI 0 "register_operand" "")
15211 (minus:HI (const_int 15)
15212 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15213 (clobber (reg:CC FLAGS_REG))])
15215 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15216 (clobber (reg:CC FLAGS_REG))])]
15221 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15226 (define_insn "clzhi2_abm"
15227 [(set (match_operand:HI 0 "register_operand" "=r")
15228 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15229 (clobber (reg:CC FLAGS_REG))]
15231 "lzcnt{w}\t{%1, %0|%0, %1}"
15232 [(set_attr "prefix_rep" "1")
15233 (set_attr "type" "bitmanip")
15234 (set_attr "mode" "HI")])
15236 (define_insn "*bsrhi"
15237 [(set (match_operand:HI 0 "register_operand" "=r")
15238 (minus:HI (const_int 15)
15239 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15240 (clobber (reg:CC FLAGS_REG))]
15242 "bsr{w}\t{%1, %0|%0, %1}"
15243 [(set_attr "prefix_0f" "1")
15244 (set_attr "mode" "HI")])
15246 (define_insn "popcounthi2"
15247 [(set (match_operand:HI 0 "register_operand" "=r")
15248 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15249 (clobber (reg:CC FLAGS_REG))]
15251 "popcnt{w}\t{%1, %0|%0, %1}"
15252 [(set_attr "prefix_rep" "1")
15253 (set_attr "type" "bitmanip")
15254 (set_attr "mode" "HI")])
15256 (define_insn "*popcounthi2_cmp"
15257 [(set (reg FLAGS_REG)
15259 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15261 (set (match_operand:HI 0 "register_operand" "=r")
15262 (popcount:HI (match_dup 1)))]
15263 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15264 "popcnt{w}\t{%1, %0|%0, %1}"
15265 [(set_attr "prefix_rep" "1")
15266 (set_attr "type" "bitmanip")
15267 (set_attr "mode" "HI")])
15269 (define_expand "paritydi2"
15270 [(set (match_operand:DI 0 "register_operand" "")
15271 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15274 rtx scratch = gen_reg_rtx (QImode);
15277 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15278 NULL_RTX, operands[1]));
15280 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15281 gen_rtx_REG (CCmode, FLAGS_REG),
15283 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15286 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15289 rtx tmp = gen_reg_rtx (SImode);
15291 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15292 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15297 (define_insn_and_split "paritydi2_cmp"
15298 [(set (reg:CC FLAGS_REG)
15299 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15300 (clobber (match_scratch:DI 0 "=r"))
15301 (clobber (match_scratch:SI 1 "=&r"))
15302 (clobber (match_scratch:HI 2 "=Q"))]
15305 "&& reload_completed"
15307 [(set (match_dup 1)
15308 (xor:SI (match_dup 1) (match_dup 4)))
15309 (clobber (reg:CC FLAGS_REG))])
15311 [(set (reg:CC FLAGS_REG)
15312 (parity:CC (match_dup 1)))
15313 (clobber (match_dup 1))
15314 (clobber (match_dup 2))])]
15316 operands[4] = gen_lowpart (SImode, operands[3]);
15320 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15321 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15324 operands[1] = gen_highpart (SImode, operands[3]);
15327 (define_expand "paritysi2"
15328 [(set (match_operand:SI 0 "register_operand" "")
15329 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15332 rtx scratch = gen_reg_rtx (QImode);
15335 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15337 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15338 gen_rtx_REG (CCmode, FLAGS_REG),
15340 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15342 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15346 (define_insn_and_split "paritysi2_cmp"
15347 [(set (reg:CC FLAGS_REG)
15348 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15349 (clobber (match_scratch:SI 0 "=r"))
15350 (clobber (match_scratch:HI 1 "=&Q"))]
15353 "&& reload_completed"
15355 [(set (match_dup 1)
15356 (xor:HI (match_dup 1) (match_dup 3)))
15357 (clobber (reg:CC FLAGS_REG))])
15359 [(set (reg:CC FLAGS_REG)
15360 (parity:CC (match_dup 1)))
15361 (clobber (match_dup 1))])]
15363 operands[3] = gen_lowpart (HImode, operands[2]);
15365 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15366 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15369 (define_insn "*parityhi2_cmp"
15370 [(set (reg:CC FLAGS_REG)
15371 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15372 (clobber (match_scratch:HI 0 "=Q"))]
15374 "xor{b}\t{%h0, %b0|%b0, %h0}"
15375 [(set_attr "length" "2")
15376 (set_attr "mode" "HI")])
15378 (define_insn "*parityqi2_cmp"
15379 [(set (reg:CC FLAGS_REG)
15380 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15383 [(set_attr "length" "2")
15384 (set_attr "mode" "QI")])
15386 ;; Thread-local storage patterns for ELF.
15388 ;; Note that these code sequences must appear exactly as shown
15389 ;; in order to allow linker relaxation.
15391 (define_insn "*tls_global_dynamic_32_gnu"
15392 [(set (match_operand:SI 0 "register_operand" "=a")
15393 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15394 (match_operand:SI 2 "tls_symbolic_operand" "")
15395 (match_operand:SI 3 "call_insn_operand" "")]
15397 (clobber (match_scratch:SI 4 "=d"))
15398 (clobber (match_scratch:SI 5 "=c"))
15399 (clobber (reg:CC FLAGS_REG))]
15400 "!TARGET_64BIT && TARGET_GNU_TLS"
15401 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15402 [(set_attr "type" "multi")
15403 (set_attr "length" "12")])
15405 (define_insn "*tls_global_dynamic_32_sun"
15406 [(set (match_operand:SI 0 "register_operand" "=a")
15407 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15408 (match_operand:SI 2 "tls_symbolic_operand" "")
15409 (match_operand:SI 3 "call_insn_operand" "")]
15411 (clobber (match_scratch:SI 4 "=d"))
15412 (clobber (match_scratch:SI 5 "=c"))
15413 (clobber (reg:CC FLAGS_REG))]
15414 "!TARGET_64BIT && TARGET_SUN_TLS"
15415 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15416 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15417 [(set_attr "type" "multi")
15418 (set_attr "length" "14")])
15420 (define_expand "tls_global_dynamic_32"
15421 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15424 (match_operand:SI 1 "tls_symbolic_operand" "")
15427 (clobber (match_scratch:SI 4 ""))
15428 (clobber (match_scratch:SI 5 ""))
15429 (clobber (reg:CC FLAGS_REG))])]
15433 operands[2] = pic_offset_table_rtx;
15436 operands[2] = gen_reg_rtx (Pmode);
15437 emit_insn (gen_set_got (operands[2]));
15439 if (TARGET_GNU2_TLS)
15441 emit_insn (gen_tls_dynamic_gnu2_32
15442 (operands[0], operands[1], operands[2]));
15445 operands[3] = ix86_tls_get_addr ();
15448 (define_insn "*tls_global_dynamic_64"
15449 [(set (match_operand:DI 0 "register_operand" "=a")
15450 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15451 (match_operand:DI 3 "" "")))
15452 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15455 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15456 [(set_attr "type" "multi")
15457 (set_attr "length" "16")])
15459 (define_expand "tls_global_dynamic_64"
15460 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15461 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15462 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15466 if (TARGET_GNU2_TLS)
15468 emit_insn (gen_tls_dynamic_gnu2_64
15469 (operands[0], operands[1]));
15472 operands[2] = ix86_tls_get_addr ();
15475 (define_insn "*tls_local_dynamic_base_32_gnu"
15476 [(set (match_operand:SI 0 "register_operand" "=a")
15477 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15478 (match_operand:SI 2 "call_insn_operand" "")]
15479 UNSPEC_TLS_LD_BASE))
15480 (clobber (match_scratch:SI 3 "=d"))
15481 (clobber (match_scratch:SI 4 "=c"))
15482 (clobber (reg:CC FLAGS_REG))]
15483 "!TARGET_64BIT && TARGET_GNU_TLS"
15484 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15485 [(set_attr "type" "multi")
15486 (set_attr "length" "11")])
15488 (define_insn "*tls_local_dynamic_base_32_sun"
15489 [(set (match_operand:SI 0 "register_operand" "=a")
15490 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15491 (match_operand:SI 2 "call_insn_operand" "")]
15492 UNSPEC_TLS_LD_BASE))
15493 (clobber (match_scratch:SI 3 "=d"))
15494 (clobber (match_scratch:SI 4 "=c"))
15495 (clobber (reg:CC FLAGS_REG))]
15496 "!TARGET_64BIT && TARGET_SUN_TLS"
15497 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15498 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15499 [(set_attr "type" "multi")
15500 (set_attr "length" "13")])
15502 (define_expand "tls_local_dynamic_base_32"
15503 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15504 (unspec:SI [(match_dup 1) (match_dup 2)]
15505 UNSPEC_TLS_LD_BASE))
15506 (clobber (match_scratch:SI 3 ""))
15507 (clobber (match_scratch:SI 4 ""))
15508 (clobber (reg:CC FLAGS_REG))])]
15512 operands[1] = pic_offset_table_rtx;
15515 operands[1] = gen_reg_rtx (Pmode);
15516 emit_insn (gen_set_got (operands[1]));
15518 if (TARGET_GNU2_TLS)
15520 emit_insn (gen_tls_dynamic_gnu2_32
15521 (operands[0], ix86_tls_module_base (), operands[1]));
15524 operands[2] = ix86_tls_get_addr ();
15527 (define_insn "*tls_local_dynamic_base_64"
15528 [(set (match_operand:DI 0 "register_operand" "=a")
15529 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15530 (match_operand:DI 2 "" "")))
15531 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15533 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15534 [(set_attr "type" "multi")
15535 (set_attr "length" "12")])
15537 (define_expand "tls_local_dynamic_base_64"
15538 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15539 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15540 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15543 if (TARGET_GNU2_TLS)
15545 emit_insn (gen_tls_dynamic_gnu2_64
15546 (operands[0], ix86_tls_module_base ()));
15549 operands[1] = ix86_tls_get_addr ();
15552 ;; Local dynamic of a single variable is a lose. Show combine how
15553 ;; to convert that back to global dynamic.
15555 (define_insn_and_split "*tls_local_dynamic_32_once"
15556 [(set (match_operand:SI 0 "register_operand" "=a")
15557 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15558 (match_operand:SI 2 "call_insn_operand" "")]
15559 UNSPEC_TLS_LD_BASE)
15560 (const:SI (unspec:SI
15561 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15563 (clobber (match_scratch:SI 4 "=d"))
15564 (clobber (match_scratch:SI 5 "=c"))
15565 (clobber (reg:CC FLAGS_REG))]
15569 [(parallel [(set (match_dup 0)
15570 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15572 (clobber (match_dup 4))
15573 (clobber (match_dup 5))
15574 (clobber (reg:CC FLAGS_REG))])]
15577 ;; Load and add the thread base pointer from %gs:0.
15579 (define_insn "*load_tp_si"
15580 [(set (match_operand:SI 0 "register_operand" "=r")
15581 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15583 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15584 [(set_attr "type" "imov")
15585 (set_attr "modrm" "0")
15586 (set_attr "length" "7")
15587 (set_attr "memory" "load")
15588 (set_attr "imm_disp" "false")])
15590 (define_insn "*add_tp_si"
15591 [(set (match_operand:SI 0 "register_operand" "=r")
15592 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15593 (match_operand:SI 1 "register_operand" "0")))
15594 (clobber (reg:CC FLAGS_REG))]
15596 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15597 [(set_attr "type" "alu")
15598 (set_attr "modrm" "0")
15599 (set_attr "length" "7")
15600 (set_attr "memory" "load")
15601 (set_attr "imm_disp" "false")])
15603 (define_insn "*load_tp_di"
15604 [(set (match_operand:DI 0 "register_operand" "=r")
15605 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15607 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15608 [(set_attr "type" "imov")
15609 (set_attr "modrm" "0")
15610 (set_attr "length" "7")
15611 (set_attr "memory" "load")
15612 (set_attr "imm_disp" "false")])
15614 (define_insn "*add_tp_di"
15615 [(set (match_operand:DI 0 "register_operand" "=r")
15616 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15617 (match_operand:DI 1 "register_operand" "0")))
15618 (clobber (reg:CC FLAGS_REG))]
15620 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15621 [(set_attr "type" "alu")
15622 (set_attr "modrm" "0")
15623 (set_attr "length" "7")
15624 (set_attr "memory" "load")
15625 (set_attr "imm_disp" "false")])
15627 ;; GNU2 TLS patterns can be split.
15629 (define_expand "tls_dynamic_gnu2_32"
15630 [(set (match_dup 3)
15631 (plus:SI (match_operand:SI 2 "register_operand" "")
15633 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15636 [(set (match_operand:SI 0 "register_operand" "")
15637 (unspec:SI [(match_dup 1) (match_dup 3)
15638 (match_dup 2) (reg:SI SP_REG)]
15640 (clobber (reg:CC FLAGS_REG))])]
15641 "!TARGET_64BIT && TARGET_GNU2_TLS"
15643 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15644 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15647 (define_insn "*tls_dynamic_lea_32"
15648 [(set (match_operand:SI 0 "register_operand" "=r")
15649 (plus:SI (match_operand:SI 1 "register_operand" "b")
15651 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15652 UNSPEC_TLSDESC))))]
15653 "!TARGET_64BIT && TARGET_GNU2_TLS"
15654 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15655 [(set_attr "type" "lea")
15656 (set_attr "mode" "SI")
15657 (set_attr "length" "6")
15658 (set_attr "length_address" "4")])
15660 (define_insn "*tls_dynamic_call_32"
15661 [(set (match_operand:SI 0 "register_operand" "=a")
15662 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15663 (match_operand:SI 2 "register_operand" "0")
15664 ;; we have to make sure %ebx still points to the GOT
15665 (match_operand:SI 3 "register_operand" "b")
15668 (clobber (reg:CC FLAGS_REG))]
15669 "!TARGET_64BIT && TARGET_GNU2_TLS"
15670 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15671 [(set_attr "type" "call")
15672 (set_attr "length" "2")
15673 (set_attr "length_address" "0")])
15675 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15676 [(set (match_operand:SI 0 "register_operand" "=&a")
15678 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15679 (match_operand:SI 4 "" "")
15680 (match_operand:SI 2 "register_operand" "b")
15683 (const:SI (unspec:SI
15684 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15686 (clobber (reg:CC FLAGS_REG))]
15687 "!TARGET_64BIT && TARGET_GNU2_TLS"
15690 [(set (match_dup 0) (match_dup 5))]
15692 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15693 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15696 (define_expand "tls_dynamic_gnu2_64"
15697 [(set (match_dup 2)
15698 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15701 [(set (match_operand:DI 0 "register_operand" "")
15702 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15704 (clobber (reg:CC FLAGS_REG))])]
15705 "TARGET_64BIT && TARGET_GNU2_TLS"
15707 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15708 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15711 (define_insn "*tls_dynamic_lea_64"
15712 [(set (match_operand:DI 0 "register_operand" "=r")
15713 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15715 "TARGET_64BIT && TARGET_GNU2_TLS"
15716 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15717 [(set_attr "type" "lea")
15718 (set_attr "mode" "DI")
15719 (set_attr "length" "7")
15720 (set_attr "length_address" "4")])
15722 (define_insn "*tls_dynamic_call_64"
15723 [(set (match_operand:DI 0 "register_operand" "=a")
15724 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15725 (match_operand:DI 2 "register_operand" "0")
15728 (clobber (reg:CC FLAGS_REG))]
15729 "TARGET_64BIT && TARGET_GNU2_TLS"
15730 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15731 [(set_attr "type" "call")
15732 (set_attr "length" "2")
15733 (set_attr "length_address" "0")])
15735 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15736 [(set (match_operand:DI 0 "register_operand" "=&a")
15738 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15739 (match_operand:DI 3 "" "")
15742 (const:DI (unspec:DI
15743 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15745 (clobber (reg:CC FLAGS_REG))]
15746 "TARGET_64BIT && TARGET_GNU2_TLS"
15749 [(set (match_dup 0) (match_dup 4))]
15751 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15752 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15757 ;; These patterns match the binary 387 instructions for addM3, subM3,
15758 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15759 ;; SFmode. The first is the normal insn, the second the same insn but
15760 ;; with one operand a conversion, and the third the same insn but with
15761 ;; the other operand a conversion. The conversion may be SFmode or
15762 ;; SImode if the target mode DFmode, but only SImode if the target mode
15765 ;; Gcc is slightly more smart about handling normal two address instructions
15766 ;; so use special patterns for add and mull.
15768 (define_insn "*fop_sf_comm_mixed"
15769 [(set (match_operand:SF 0 "register_operand" "=f,x")
15770 (match_operator:SF 3 "binary_fp_operator"
15771 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15772 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15773 "TARGET_MIX_SSE_I387
15774 && COMMUTATIVE_ARITH_P (operands[3])
15775 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15776 "* return output_387_binary_op (insn, operands);"
15777 [(set (attr "type")
15778 (if_then_else (eq_attr "alternative" "1")
15779 (if_then_else (match_operand:SF 3 "mult_operator" "")
15780 (const_string "ssemul")
15781 (const_string "sseadd"))
15782 (if_then_else (match_operand:SF 3 "mult_operator" "")
15783 (const_string "fmul")
15784 (const_string "fop"))))
15785 (set_attr "mode" "SF")])
15787 (define_insn "*fop_sf_comm_sse"
15788 [(set (match_operand:SF 0 "register_operand" "=x")
15789 (match_operator:SF 3 "binary_fp_operator"
15790 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15791 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15793 && COMMUTATIVE_ARITH_P (operands[3])
15794 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15795 "* return output_387_binary_op (insn, operands);"
15796 [(set (attr "type")
15797 (if_then_else (match_operand:SF 3 "mult_operator" "")
15798 (const_string "ssemul")
15799 (const_string "sseadd")))
15800 (set_attr "mode" "SF")])
15802 (define_insn "*fop_sf_comm_i387"
15803 [(set (match_operand:SF 0 "register_operand" "=f")
15804 (match_operator:SF 3 "binary_fp_operator"
15805 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15806 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15808 && COMMUTATIVE_ARITH_P (operands[3])
15809 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15810 "* return output_387_binary_op (insn, operands);"
15811 [(set (attr "type")
15812 (if_then_else (match_operand:SF 3 "mult_operator" "")
15813 (const_string "fmul")
15814 (const_string "fop")))
15815 (set_attr "mode" "SF")])
15817 (define_insn "*fop_sf_1_mixed"
15818 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15819 (match_operator:SF 3 "binary_fp_operator"
15820 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15821 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15822 "TARGET_MIX_SSE_I387
15823 && !COMMUTATIVE_ARITH_P (operands[3])
15824 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15825 "* return output_387_binary_op (insn, operands);"
15826 [(set (attr "type")
15827 (cond [(and (eq_attr "alternative" "2")
15828 (match_operand:SF 3 "mult_operator" ""))
15829 (const_string "ssemul")
15830 (and (eq_attr "alternative" "2")
15831 (match_operand:SF 3 "div_operator" ""))
15832 (const_string "ssediv")
15833 (eq_attr "alternative" "2")
15834 (const_string "sseadd")
15835 (match_operand:SF 3 "mult_operator" "")
15836 (const_string "fmul")
15837 (match_operand:SF 3 "div_operator" "")
15838 (const_string "fdiv")
15840 (const_string "fop")))
15841 (set_attr "mode" "SF")])
15843 (define_insn "*rcpsf2_sse"
15844 [(set (match_operand:SF 0 "register_operand" "=x")
15845 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15848 "rcpss\t{%1, %0|%0, %1}"
15849 [(set_attr "type" "sse")
15850 (set_attr "mode" "SF")])
15852 (define_insn "*fop_sf_1_sse"
15853 [(set (match_operand:SF 0 "register_operand" "=x")
15854 (match_operator:SF 3 "binary_fp_operator"
15855 [(match_operand:SF 1 "register_operand" "0")
15856 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15858 && !COMMUTATIVE_ARITH_P (operands[3])"
15859 "* return output_387_binary_op (insn, operands);"
15860 [(set (attr "type")
15861 (cond [(match_operand:SF 3 "mult_operator" "")
15862 (const_string "ssemul")
15863 (match_operand:SF 3 "div_operator" "")
15864 (const_string "ssediv")
15866 (const_string "sseadd")))
15867 (set_attr "mode" "SF")])
15869 ;; This pattern is not fully shadowed by the pattern above.
15870 (define_insn "*fop_sf_1_i387"
15871 [(set (match_operand:SF 0 "register_operand" "=f,f")
15872 (match_operator:SF 3 "binary_fp_operator"
15873 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15874 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15875 "TARGET_80387 && !TARGET_SSE_MATH
15876 && !COMMUTATIVE_ARITH_P (operands[3])
15877 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15878 "* return output_387_binary_op (insn, operands);"
15879 [(set (attr "type")
15880 (cond [(match_operand:SF 3 "mult_operator" "")
15881 (const_string "fmul")
15882 (match_operand:SF 3 "div_operator" "")
15883 (const_string "fdiv")
15885 (const_string "fop")))
15886 (set_attr "mode" "SF")])
15888 ;; ??? Add SSE splitters for these!
15889 (define_insn "*fop_sf_2<mode>_i387"
15890 [(set (match_operand:SF 0 "register_operand" "=f,f")
15891 (match_operator:SF 3 "binary_fp_operator"
15892 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15893 (match_operand:SF 2 "register_operand" "0,0")]))]
15894 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15895 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15896 [(set (attr "type")
15897 (cond [(match_operand:SF 3 "mult_operator" "")
15898 (const_string "fmul")
15899 (match_operand:SF 3 "div_operator" "")
15900 (const_string "fdiv")
15902 (const_string "fop")))
15903 (set_attr "fp_int_src" "true")
15904 (set_attr "mode" "<MODE>")])
15906 (define_insn "*fop_sf_3<mode>_i387"
15907 [(set (match_operand:SF 0 "register_operand" "=f,f")
15908 (match_operator:SF 3 "binary_fp_operator"
15909 [(match_operand:SF 1 "register_operand" "0,0")
15910 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15911 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15912 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15913 [(set (attr "type")
15914 (cond [(match_operand:SF 3 "mult_operator" "")
15915 (const_string "fmul")
15916 (match_operand:SF 3 "div_operator" "")
15917 (const_string "fdiv")
15919 (const_string "fop")))
15920 (set_attr "fp_int_src" "true")
15921 (set_attr "mode" "<MODE>")])
15923 (define_insn "*fop_df_comm_mixed"
15924 [(set (match_operand:DF 0 "register_operand" "=f,x")
15925 (match_operator:DF 3 "binary_fp_operator"
15926 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15927 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15928 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15929 && COMMUTATIVE_ARITH_P (operands[3])
15930 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15931 "* return output_387_binary_op (insn, operands);"
15932 [(set (attr "type")
15933 (if_then_else (eq_attr "alternative" "1")
15934 (if_then_else (match_operand:DF 3 "mult_operator" "")
15935 (const_string "ssemul")
15936 (const_string "sseadd"))
15937 (if_then_else (match_operand:DF 3 "mult_operator" "")
15938 (const_string "fmul")
15939 (const_string "fop"))))
15940 (set_attr "mode" "DF")])
15942 (define_insn "*fop_df_comm_sse"
15943 [(set (match_operand:DF 0 "register_operand" "=x")
15944 (match_operator:DF 3 "binary_fp_operator"
15945 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15946 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15947 "TARGET_SSE2 && TARGET_SSE_MATH
15948 && COMMUTATIVE_ARITH_P (operands[3])
15949 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15950 "* return output_387_binary_op (insn, operands);"
15951 [(set (attr "type")
15952 (if_then_else (match_operand:DF 3 "mult_operator" "")
15953 (const_string "ssemul")
15954 (const_string "sseadd")))
15955 (set_attr "mode" "DF")])
15957 (define_insn "*fop_df_comm_i387"
15958 [(set (match_operand:DF 0 "register_operand" "=f")
15959 (match_operator:DF 3 "binary_fp_operator"
15960 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15961 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15963 && COMMUTATIVE_ARITH_P (operands[3])
15964 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15965 "* return output_387_binary_op (insn, operands);"
15966 [(set (attr "type")
15967 (if_then_else (match_operand:DF 3 "mult_operator" "")
15968 (const_string "fmul")
15969 (const_string "fop")))
15970 (set_attr "mode" "DF")])
15972 (define_insn "*fop_df_1_mixed"
15973 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15974 (match_operator:DF 3 "binary_fp_operator"
15975 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15976 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15977 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15978 && !COMMUTATIVE_ARITH_P (operands[3])
15979 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15980 "* return output_387_binary_op (insn, operands);"
15981 [(set (attr "type")
15982 (cond [(and (eq_attr "alternative" "2")
15983 (match_operand:DF 3 "mult_operator" ""))
15984 (const_string "ssemul")
15985 (and (eq_attr "alternative" "2")
15986 (match_operand:DF 3 "div_operator" ""))
15987 (const_string "ssediv")
15988 (eq_attr "alternative" "2")
15989 (const_string "sseadd")
15990 (match_operand:DF 3 "mult_operator" "")
15991 (const_string "fmul")
15992 (match_operand:DF 3 "div_operator" "")
15993 (const_string "fdiv")
15995 (const_string "fop")))
15996 (set_attr "mode" "DF")])
15998 (define_insn "*fop_df_1_sse"
15999 [(set (match_operand:DF 0 "register_operand" "=x")
16000 (match_operator:DF 3 "binary_fp_operator"
16001 [(match_operand:DF 1 "register_operand" "0")
16002 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16003 "TARGET_SSE2 && TARGET_SSE_MATH
16004 && !COMMUTATIVE_ARITH_P (operands[3])"
16005 "* return output_387_binary_op (insn, operands);"
16006 [(set_attr "mode" "DF")
16008 (cond [(match_operand:DF 3 "mult_operator" "")
16009 (const_string "ssemul")
16010 (match_operand:DF 3 "div_operator" "")
16011 (const_string "ssediv")
16013 (const_string "sseadd")))])
16015 ;; This pattern is not fully shadowed by the pattern above.
16016 (define_insn "*fop_df_1_i387"
16017 [(set (match_operand:DF 0 "register_operand" "=f,f")
16018 (match_operator:DF 3 "binary_fp_operator"
16019 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16020 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16021 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16022 && !COMMUTATIVE_ARITH_P (operands[3])
16023 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16024 "* return output_387_binary_op (insn, operands);"
16025 [(set (attr "type")
16026 (cond [(match_operand:DF 3 "mult_operator" "")
16027 (const_string "fmul")
16028 (match_operand:DF 3 "div_operator" "")
16029 (const_string "fdiv")
16031 (const_string "fop")))
16032 (set_attr "mode" "DF")])
16034 ;; ??? Add SSE splitters for these!
16035 (define_insn "*fop_df_2<mode>_i387"
16036 [(set (match_operand:DF 0 "register_operand" "=f,f")
16037 (match_operator:DF 3 "binary_fp_operator"
16038 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16039 (match_operand:DF 2 "register_operand" "0,0")]))]
16040 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16041 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16042 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16043 [(set (attr "type")
16044 (cond [(match_operand:DF 3 "mult_operator" "")
16045 (const_string "fmul")
16046 (match_operand:DF 3 "div_operator" "")
16047 (const_string "fdiv")
16049 (const_string "fop")))
16050 (set_attr "fp_int_src" "true")
16051 (set_attr "mode" "<MODE>")])
16053 (define_insn "*fop_df_3<mode>_i387"
16054 [(set (match_operand:DF 0 "register_operand" "=f,f")
16055 (match_operator:DF 3 "binary_fp_operator"
16056 [(match_operand:DF 1 "register_operand" "0,0")
16057 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16058 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16059 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16060 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16061 [(set (attr "type")
16062 (cond [(match_operand:DF 3 "mult_operator" "")
16063 (const_string "fmul")
16064 (match_operand:DF 3 "div_operator" "")
16065 (const_string "fdiv")
16067 (const_string "fop")))
16068 (set_attr "fp_int_src" "true")
16069 (set_attr "mode" "<MODE>")])
16071 (define_insn "*fop_df_4_i387"
16072 [(set (match_operand:DF 0 "register_operand" "=f,f")
16073 (match_operator:DF 3 "binary_fp_operator"
16074 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16075 (match_operand:DF 2 "register_operand" "0,f")]))]
16076 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16077 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16078 "* return output_387_binary_op (insn, operands);"
16079 [(set (attr "type")
16080 (cond [(match_operand:DF 3 "mult_operator" "")
16081 (const_string "fmul")
16082 (match_operand:DF 3 "div_operator" "")
16083 (const_string "fdiv")
16085 (const_string "fop")))
16086 (set_attr "mode" "SF")])
16088 (define_insn "*fop_df_5_i387"
16089 [(set (match_operand:DF 0 "register_operand" "=f,f")
16090 (match_operator:DF 3 "binary_fp_operator"
16091 [(match_operand:DF 1 "register_operand" "0,f")
16093 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16094 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16095 "* return output_387_binary_op (insn, operands);"
16096 [(set (attr "type")
16097 (cond [(match_operand:DF 3 "mult_operator" "")
16098 (const_string "fmul")
16099 (match_operand:DF 3 "div_operator" "")
16100 (const_string "fdiv")
16102 (const_string "fop")))
16103 (set_attr "mode" "SF")])
16105 (define_insn "*fop_df_6_i387"
16106 [(set (match_operand:DF 0 "register_operand" "=f,f")
16107 (match_operator:DF 3 "binary_fp_operator"
16109 (match_operand:SF 1 "register_operand" "0,f"))
16111 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16112 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16113 "* return output_387_binary_op (insn, operands);"
16114 [(set (attr "type")
16115 (cond [(match_operand:DF 3 "mult_operator" "")
16116 (const_string "fmul")
16117 (match_operand:DF 3 "div_operator" "")
16118 (const_string "fdiv")
16120 (const_string "fop")))
16121 (set_attr "mode" "SF")])
16123 (define_insn "*fop_xf_comm_i387"
16124 [(set (match_operand:XF 0 "register_operand" "=f")
16125 (match_operator:XF 3 "binary_fp_operator"
16126 [(match_operand:XF 1 "register_operand" "%0")
16127 (match_operand:XF 2 "register_operand" "f")]))]
16129 && COMMUTATIVE_ARITH_P (operands[3])"
16130 "* return output_387_binary_op (insn, operands);"
16131 [(set (attr "type")
16132 (if_then_else (match_operand:XF 3 "mult_operator" "")
16133 (const_string "fmul")
16134 (const_string "fop")))
16135 (set_attr "mode" "XF")])
16137 (define_insn "*fop_xf_1_i387"
16138 [(set (match_operand:XF 0 "register_operand" "=f,f")
16139 (match_operator:XF 3 "binary_fp_operator"
16140 [(match_operand:XF 1 "register_operand" "0,f")
16141 (match_operand:XF 2 "register_operand" "f,0")]))]
16143 && !COMMUTATIVE_ARITH_P (operands[3])"
16144 "* return output_387_binary_op (insn, operands);"
16145 [(set (attr "type")
16146 (cond [(match_operand:XF 3 "mult_operator" "")
16147 (const_string "fmul")
16148 (match_operand:XF 3 "div_operator" "")
16149 (const_string "fdiv")
16151 (const_string "fop")))
16152 (set_attr "mode" "XF")])
16154 (define_insn "*fop_xf_2<mode>_i387"
16155 [(set (match_operand:XF 0 "register_operand" "=f,f")
16156 (match_operator:XF 3 "binary_fp_operator"
16157 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16158 (match_operand:XF 2 "register_operand" "0,0")]))]
16159 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16160 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16161 [(set (attr "type")
16162 (cond [(match_operand:XF 3 "mult_operator" "")
16163 (const_string "fmul")
16164 (match_operand:XF 3 "div_operator" "")
16165 (const_string "fdiv")
16167 (const_string "fop")))
16168 (set_attr "fp_int_src" "true")
16169 (set_attr "mode" "<MODE>")])
16171 (define_insn "*fop_xf_3<mode>_i387"
16172 [(set (match_operand:XF 0 "register_operand" "=f,f")
16173 (match_operator:XF 3 "binary_fp_operator"
16174 [(match_operand:XF 1 "register_operand" "0,0")
16175 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16176 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16177 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16178 [(set (attr "type")
16179 (cond [(match_operand:XF 3 "mult_operator" "")
16180 (const_string "fmul")
16181 (match_operand:XF 3 "div_operator" "")
16182 (const_string "fdiv")
16184 (const_string "fop")))
16185 (set_attr "fp_int_src" "true")
16186 (set_attr "mode" "<MODE>")])
16188 (define_insn "*fop_xf_4_i387"
16189 [(set (match_operand:XF 0 "register_operand" "=f,f")
16190 (match_operator:XF 3 "binary_fp_operator"
16192 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16193 (match_operand:XF 2 "register_operand" "0,f")]))]
16195 "* return output_387_binary_op (insn, operands);"
16196 [(set (attr "type")
16197 (cond [(match_operand:XF 3 "mult_operator" "")
16198 (const_string "fmul")
16199 (match_operand:XF 3 "div_operator" "")
16200 (const_string "fdiv")
16202 (const_string "fop")))
16203 (set_attr "mode" "SF")])
16205 (define_insn "*fop_xf_5_i387"
16206 [(set (match_operand:XF 0 "register_operand" "=f,f")
16207 (match_operator:XF 3 "binary_fp_operator"
16208 [(match_operand:XF 1 "register_operand" "0,f")
16210 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16212 "* return output_387_binary_op (insn, operands);"
16213 [(set (attr "type")
16214 (cond [(match_operand:XF 3 "mult_operator" "")
16215 (const_string "fmul")
16216 (match_operand:XF 3 "div_operator" "")
16217 (const_string "fdiv")
16219 (const_string "fop")))
16220 (set_attr "mode" "SF")])
16222 (define_insn "*fop_xf_6_i387"
16223 [(set (match_operand:XF 0 "register_operand" "=f,f")
16224 (match_operator:XF 3 "binary_fp_operator"
16226 (match_operand:MODEF 1 "register_operand" "0,f"))
16228 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16230 "* return output_387_binary_op (insn, operands);"
16231 [(set (attr "type")
16232 (cond [(match_operand:XF 3 "mult_operator" "")
16233 (const_string "fmul")
16234 (match_operand:XF 3 "div_operator" "")
16235 (const_string "fdiv")
16237 (const_string "fop")))
16238 (set_attr "mode" "SF")])
16241 [(set (match_operand 0 "register_operand" "")
16242 (match_operator 3 "binary_fp_operator"
16243 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16244 (match_operand 2 "register_operand" "")]))]
16246 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16249 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16250 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16251 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16252 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16253 GET_MODE (operands[3]),
16256 ix86_free_from_memory (GET_MODE (operands[1]));
16261 [(set (match_operand 0 "register_operand" "")
16262 (match_operator 3 "binary_fp_operator"
16263 [(match_operand 1 "register_operand" "")
16264 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16266 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16269 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16270 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16271 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16272 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16273 GET_MODE (operands[3]),
16276 ix86_free_from_memory (GET_MODE (operands[2]));
16280 ;; FPU special functions.
16282 ;; This pattern implements a no-op XFmode truncation for
16283 ;; all fancy i386 XFmode math functions.
16285 (define_insn "truncxf<mode>2_i387_noop_unspec"
16286 [(set (match_operand:MODEF 0 "register_operand" "=f")
16287 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16288 UNSPEC_TRUNC_NOOP))]
16289 "TARGET_USE_FANCY_MATH_387"
16290 "* return output_387_reg_move (insn, operands);"
16291 [(set_attr "type" "fmov")
16292 (set_attr "mode" "<MODE>")])
16294 (define_insn "sqrtxf2"
16295 [(set (match_operand:XF 0 "register_operand" "=f")
16296 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16297 "TARGET_USE_FANCY_MATH_387"
16299 [(set_attr "type" "fpspc")
16300 (set_attr "mode" "XF")
16301 (set_attr "athlon_decode" "direct")
16302 (set_attr "amdfam10_decode" "direct")])
16304 (define_insn "sqrt_extend<mode>xf2_i387"
16305 [(set (match_operand:XF 0 "register_operand" "=f")
16308 (match_operand:MODEF 1 "register_operand" "0"))))]
16309 "TARGET_USE_FANCY_MATH_387"
16311 [(set_attr "type" "fpspc")
16312 (set_attr "mode" "XF")
16313 (set_attr "athlon_decode" "direct")
16314 (set_attr "amdfam10_decode" "direct")])
16316 (define_insn "*rsqrtsf2_sse"
16317 [(set (match_operand:SF 0 "register_operand" "=x")
16318 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16321 "rsqrtss\t{%1, %0|%0, %1}"
16322 [(set_attr "type" "sse")
16323 (set_attr "mode" "SF")])
16325 (define_expand "rsqrtsf2"
16326 [(set (match_operand:SF 0 "register_operand" "")
16327 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16331 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16335 (define_insn "*sqrt<mode>2_sse"
16336 [(set (match_operand:MODEF 0 "register_operand" "=x")
16338 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16339 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16340 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16341 [(set_attr "type" "sse")
16342 (set_attr "mode" "<MODE>")
16343 (set_attr "athlon_decode" "*")
16344 (set_attr "amdfam10_decode" "*")])
16346 (define_expand "sqrt<mode>2"
16347 [(set (match_operand:MODEF 0 "register_operand" "")
16349 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16350 "TARGET_USE_FANCY_MATH_387
16351 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16353 if (<MODE>mode == SFmode
16354 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16355 && flag_finite_math_only && !flag_trapping_math
16356 && flag_unsafe_math_optimizations)
16358 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16362 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16364 rtx op0 = gen_reg_rtx (XFmode);
16365 rtx op1 = force_reg (<MODE>mode, operands[1]);
16367 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16368 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16373 (define_insn "fpremxf4_i387"
16374 [(set (match_operand:XF 0 "register_operand" "=f")
16375 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16376 (match_operand:XF 3 "register_operand" "1")]
16378 (set (match_operand:XF 1 "register_operand" "=u")
16379 (unspec:XF [(match_dup 2) (match_dup 3)]
16381 (set (reg:CCFP FPSR_REG)
16382 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16384 "TARGET_USE_FANCY_MATH_387"
16386 [(set_attr "type" "fpspc")
16387 (set_attr "mode" "XF")])
16389 (define_expand "fmodxf3"
16390 [(use (match_operand:XF 0 "register_operand" ""))
16391 (use (match_operand:XF 1 "register_operand" ""))
16392 (use (match_operand:XF 2 "register_operand" ""))]
16393 "TARGET_USE_FANCY_MATH_387"
16395 rtx label = gen_label_rtx ();
16399 if (rtx_equal_p (operands[1], operands[2]))
16401 op2 = gen_reg_rtx (XFmode);
16402 emit_move_insn (op2, operands[2]);
16407 emit_label (label);
16408 emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16409 ix86_emit_fp_unordered_jump (label);
16410 LABEL_NUSES (label) = 1;
16412 emit_move_insn (operands[0], operands[1]);
16416 (define_expand "fmod<mode>3"
16417 [(use (match_operand:MODEF 0 "register_operand" ""))
16418 (use (match_operand:MODEF 1 "general_operand" ""))
16419 (use (match_operand:MODEF 2 "general_operand" ""))]
16420 "TARGET_USE_FANCY_MATH_387"
16422 rtx label = gen_label_rtx ();
16424 rtx op1 = gen_reg_rtx (XFmode);
16425 rtx op2 = gen_reg_rtx (XFmode);
16427 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16428 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16430 emit_label (label);
16431 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16432 ix86_emit_fp_unordered_jump (label);
16433 LABEL_NUSES (label) = 1;
16435 /* Truncate the result properly for strict SSE math. */
16436 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16437 && !TARGET_MIX_SSE_I387)
16438 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16440 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16445 (define_insn "fprem1xf4_i387"
16446 [(set (match_operand:XF 0 "register_operand" "=f")
16447 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16448 (match_operand:XF 3 "register_operand" "1")]
16450 (set (match_operand:XF 1 "register_operand" "=u")
16451 (unspec:XF [(match_dup 2) (match_dup 3)]
16453 (set (reg:CCFP FPSR_REG)
16454 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16456 "TARGET_USE_FANCY_MATH_387"
16458 [(set_attr "type" "fpspc")
16459 (set_attr "mode" "XF")])
16461 (define_expand "remainderxf3"
16462 [(use (match_operand:XF 0 "register_operand" ""))
16463 (use (match_operand:XF 1 "register_operand" ""))
16464 (use (match_operand:XF 2 "register_operand" ""))]
16465 "TARGET_USE_FANCY_MATH_387"
16467 rtx label = gen_label_rtx ();
16471 if (rtx_equal_p (operands[1], operands[2]))
16473 op2 = gen_reg_rtx (XFmode);
16474 emit_move_insn (op2, operands[2]);
16479 emit_label (label);
16480 emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16481 ix86_emit_fp_unordered_jump (label);
16482 LABEL_NUSES (label) = 1;
16484 emit_move_insn (operands[0], operands[1]);
16488 (define_expand "remainder<mode>3"
16489 [(use (match_operand:MODEF 0 "register_operand" ""))
16490 (use (match_operand:MODEF 1 "general_operand" ""))
16491 (use (match_operand:MODEF 2 "general_operand" ""))]
16492 "TARGET_USE_FANCY_MATH_387"
16494 rtx label = gen_label_rtx ();
16496 rtx op1 = gen_reg_rtx (XFmode);
16497 rtx op2 = gen_reg_rtx (XFmode);
16499 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16500 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16502 emit_label (label);
16504 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16505 ix86_emit_fp_unordered_jump (label);
16506 LABEL_NUSES (label) = 1;
16508 /* Truncate the result properly for strict SSE math. */
16509 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16510 && !TARGET_MIX_SSE_I387)
16511 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16513 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16518 (define_insn "*sinxf2_i387"
16519 [(set (match_operand:XF 0 "register_operand" "=f")
16520 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16521 "TARGET_USE_FANCY_MATH_387
16522 && flag_unsafe_math_optimizations"
16524 [(set_attr "type" "fpspc")
16525 (set_attr "mode" "XF")])
16527 (define_insn "*sin_extend<mode>xf2_i387"
16528 [(set (match_operand:XF 0 "register_operand" "=f")
16529 (unspec:XF [(float_extend:XF
16530 (match_operand:MODEF 1 "register_operand" "0"))]
16532 "TARGET_USE_FANCY_MATH_387
16533 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16534 || TARGET_MIX_SSE_I387)
16535 && flag_unsafe_math_optimizations"
16537 [(set_attr "type" "fpspc")
16538 (set_attr "mode" "XF")])
16540 (define_insn "*cosxf2_i387"
16541 [(set (match_operand:XF 0 "register_operand" "=f")
16542 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16543 "TARGET_USE_FANCY_MATH_387
16544 && flag_unsafe_math_optimizations"
16546 [(set_attr "type" "fpspc")
16547 (set_attr "mode" "XF")])
16549 (define_insn "*cos_extend<mode>xf2_i387"
16550 [(set (match_operand:XF 0 "register_operand" "=f")
16551 (unspec:XF [(float_extend:XF
16552 (match_operand:MODEF 1 "register_operand" "0"))]
16554 "TARGET_USE_FANCY_MATH_387
16555 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16556 || TARGET_MIX_SSE_I387)
16557 && flag_unsafe_math_optimizations"
16559 [(set_attr "type" "fpspc")
16560 (set_attr "mode" "XF")])
16562 ;; When sincos pattern is defined, sin and cos builtin functions will be
16563 ;; expanded to sincos pattern with one of its outputs left unused.
16564 ;; CSE pass will figure out if two sincos patterns can be combined,
16565 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16566 ;; depending on the unused output.
16568 (define_insn "sincosxf3"
16569 [(set (match_operand:XF 0 "register_operand" "=f")
16570 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16571 UNSPEC_SINCOS_COS))
16572 (set (match_operand:XF 1 "register_operand" "=u")
16573 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16574 "TARGET_USE_FANCY_MATH_387
16575 && flag_unsafe_math_optimizations"
16577 [(set_attr "type" "fpspc")
16578 (set_attr "mode" "XF")])
16581 [(set (match_operand:XF 0 "register_operand" "")
16582 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16583 UNSPEC_SINCOS_COS))
16584 (set (match_operand:XF 1 "register_operand" "")
16585 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16586 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16587 && !(reload_completed || reload_in_progress)"
16588 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16592 [(set (match_operand:XF 0 "register_operand" "")
16593 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16594 UNSPEC_SINCOS_COS))
16595 (set (match_operand:XF 1 "register_operand" "")
16596 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16597 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16598 && !(reload_completed || reload_in_progress)"
16599 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16602 (define_insn "sincos_extend<mode>xf3_i387"
16603 [(set (match_operand:XF 0 "register_operand" "=f")
16604 (unspec:XF [(float_extend:XF
16605 (match_operand:MODEF 2 "register_operand" "0"))]
16606 UNSPEC_SINCOS_COS))
16607 (set (match_operand:XF 1 "register_operand" "=u")
16608 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16609 "TARGET_USE_FANCY_MATH_387
16610 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16611 || TARGET_MIX_SSE_I387)
16612 && flag_unsafe_math_optimizations"
16614 [(set_attr "type" "fpspc")
16615 (set_attr "mode" "XF")])
16618 [(set (match_operand:XF 0 "register_operand" "")
16619 (unspec:XF [(float_extend:XF
16620 (match_operand:MODEF 2 "register_operand" ""))]
16621 UNSPEC_SINCOS_COS))
16622 (set (match_operand:XF 1 "register_operand" "")
16623 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16624 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16625 && !(reload_completed || reload_in_progress)"
16626 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16630 [(set (match_operand:XF 0 "register_operand" "")
16631 (unspec:XF [(float_extend:XF
16632 (match_operand:MODEF 2 "register_operand" ""))]
16633 UNSPEC_SINCOS_COS))
16634 (set (match_operand:XF 1 "register_operand" "")
16635 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16636 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16637 && !(reload_completed || reload_in_progress)"
16638 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16641 (define_expand "sincos<mode>3"
16642 [(use (match_operand:MODEF 0 "register_operand" ""))
16643 (use (match_operand:MODEF 1 "register_operand" ""))
16644 (use (match_operand:MODEF 2 "register_operand" ""))]
16645 "TARGET_USE_FANCY_MATH_387
16646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16647 || TARGET_MIX_SSE_I387)
16648 && flag_unsafe_math_optimizations"
16650 rtx op0 = gen_reg_rtx (XFmode);
16651 rtx op1 = gen_reg_rtx (XFmode);
16653 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16654 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16655 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16659 (define_insn "fptanxf4_i387"
16660 [(set (match_operand:XF 0 "register_operand" "=f")
16661 (match_operand:XF 3 "const_double_operand" "F"))
16662 (set (match_operand:XF 1 "register_operand" "=u")
16663 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16665 "TARGET_USE_FANCY_MATH_387
16666 && flag_unsafe_math_optimizations
16667 && standard_80387_constant_p (operands[3]) == 2"
16669 [(set_attr "type" "fpspc")
16670 (set_attr "mode" "XF")])
16672 (define_insn "fptan_extend<mode>xf4_i387"
16673 [(set (match_operand:MODEF 0 "register_operand" "=f")
16674 (match_operand:MODEF 3 "const_double_operand" "F"))
16675 (set (match_operand:XF 1 "register_operand" "=u")
16676 (unspec:XF [(float_extend:XF
16677 (match_operand:MODEF 2 "register_operand" "0"))]
16679 "TARGET_USE_FANCY_MATH_387
16680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16681 || TARGET_MIX_SSE_I387)
16682 && flag_unsafe_math_optimizations
16683 && standard_80387_constant_p (operands[3]) == 2"
16685 [(set_attr "type" "fpspc")
16686 (set_attr "mode" "XF")])
16688 (define_expand "tanxf2"
16689 [(use (match_operand:XF 0 "register_operand" ""))
16690 (use (match_operand:XF 1 "register_operand" ""))]
16691 "TARGET_USE_FANCY_MATH_387
16692 && flag_unsafe_math_optimizations"
16694 rtx one = gen_reg_rtx (XFmode);
16695 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16697 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16701 (define_expand "tan<mode>2"
16702 [(use (match_operand:MODEF 0 "register_operand" ""))
16703 (use (match_operand:MODEF 1 "register_operand" ""))]
16704 "TARGET_USE_FANCY_MATH_387
16705 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16706 || TARGET_MIX_SSE_I387)
16707 && flag_unsafe_math_optimizations"
16709 rtx op0 = gen_reg_rtx (XFmode);
16711 rtx one = gen_reg_rtx (<MODE>mode);
16712 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16714 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16715 operands[1], op2));
16716 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16720 (define_insn "*fpatanxf3_i387"
16721 [(set (match_operand:XF 0 "register_operand" "=f")
16722 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16723 (match_operand:XF 2 "register_operand" "u")]
16725 (clobber (match_scratch:XF 3 "=2"))]
16726 "TARGET_USE_FANCY_MATH_387
16727 && flag_unsafe_math_optimizations"
16729 [(set_attr "type" "fpspc")
16730 (set_attr "mode" "XF")])
16732 (define_insn "fpatan_extend<mode>xf3_i387"
16733 [(set (match_operand:XF 0 "register_operand" "=f")
16734 (unspec:XF [(float_extend:XF
16735 (match_operand:MODEF 1 "register_operand" "0"))
16737 (match_operand:MODEF 2 "register_operand" "u"))]
16739 (clobber (match_scratch:XF 3 "=2"))]
16740 "TARGET_USE_FANCY_MATH_387
16741 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16742 || TARGET_MIX_SSE_I387)
16743 && flag_unsafe_math_optimizations"
16745 [(set_attr "type" "fpspc")
16746 (set_attr "mode" "XF")])
16748 (define_expand "atan2xf3"
16749 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16750 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16751 (match_operand:XF 1 "register_operand" "")]
16753 (clobber (match_scratch:XF 3 ""))])]
16754 "TARGET_USE_FANCY_MATH_387
16755 && flag_unsafe_math_optimizations"
16758 (define_expand "atan2<mode>3"
16759 [(use (match_operand:MODEF 0 "register_operand" ""))
16760 (use (match_operand:MODEF 1 "register_operand" ""))
16761 (use (match_operand:MODEF 2 "register_operand" ""))]
16762 "TARGET_USE_FANCY_MATH_387
16763 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16764 || TARGET_MIX_SSE_I387)
16765 && flag_unsafe_math_optimizations"
16767 rtx op0 = gen_reg_rtx (XFmode);
16769 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16770 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16774 (define_expand "atanxf2"
16775 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16776 (unspec:XF [(match_dup 2)
16777 (match_operand:XF 1 "register_operand" "")]
16779 (clobber (match_scratch:XF 3 ""))])]
16780 "TARGET_USE_FANCY_MATH_387
16781 && flag_unsafe_math_optimizations"
16783 operands[2] = gen_reg_rtx (XFmode);
16784 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16787 (define_expand "atan<mode>2"
16788 [(use (match_operand:MODEF 0 "register_operand" ""))
16789 (use (match_operand:MODEF 1 "register_operand" ""))]
16790 "TARGET_USE_FANCY_MATH_387
16791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16792 || TARGET_MIX_SSE_I387)
16793 && flag_unsafe_math_optimizations"
16795 rtx op0 = gen_reg_rtx (XFmode);
16797 rtx op2 = gen_reg_rtx (<MODE>mode);
16798 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16800 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16801 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16805 (define_expand "asinxf2"
16806 [(set (match_dup 2)
16807 (mult:XF (match_operand:XF 1 "register_operand" "")
16809 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16810 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16811 (parallel [(set (match_operand:XF 0 "register_operand" "")
16812 (unspec:XF [(match_dup 5) (match_dup 1)]
16814 (clobber (match_scratch:XF 6 ""))])]
16815 "TARGET_USE_FANCY_MATH_387
16816 && flag_unsafe_math_optimizations && !optimize_size"
16820 for (i = 2; i < 6; i++)
16821 operands[i] = gen_reg_rtx (XFmode);
16823 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16826 (define_expand "asin<mode>2"
16827 [(use (match_operand:MODEF 0 "register_operand" ""))
16828 (use (match_operand:MODEF 1 "general_operand" ""))]
16829 "TARGET_USE_FANCY_MATH_387
16830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16831 || TARGET_MIX_SSE_I387)
16832 && flag_unsafe_math_optimizations && !optimize_size"
16834 rtx op0 = gen_reg_rtx (XFmode);
16835 rtx op1 = gen_reg_rtx (XFmode);
16837 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16838 emit_insn (gen_asinxf2 (op0, op1));
16839 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16843 (define_expand "acosxf2"
16844 [(set (match_dup 2)
16845 (mult:XF (match_operand:XF 1 "register_operand" "")
16847 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16848 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16849 (parallel [(set (match_operand:XF 0 "register_operand" "")
16850 (unspec:XF [(match_dup 1) (match_dup 5)]
16852 (clobber (match_scratch:XF 6 ""))])]
16853 "TARGET_USE_FANCY_MATH_387
16854 && flag_unsafe_math_optimizations && !optimize_size"
16858 for (i = 2; i < 6; i++)
16859 operands[i] = gen_reg_rtx (XFmode);
16861 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16864 (define_expand "acos<mode>2"
16865 [(use (match_operand:MODEF 0 "register_operand" ""))
16866 (use (match_operand:MODEF 1 "general_operand" ""))]
16867 "TARGET_USE_FANCY_MATH_387
16868 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16869 || TARGET_MIX_SSE_I387)
16870 && flag_unsafe_math_optimizations && !optimize_size"
16872 rtx op0 = gen_reg_rtx (XFmode);
16873 rtx op1 = gen_reg_rtx (XFmode);
16875 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16876 emit_insn (gen_acosxf2 (op0, op1));
16877 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16881 (define_insn "fyl2xxf3_i387"
16882 [(set (match_operand:XF 0 "register_operand" "=f")
16883 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16884 (match_operand:XF 2 "register_operand" "u")]
16886 (clobber (match_scratch:XF 3 "=2"))]
16887 "TARGET_USE_FANCY_MATH_387
16888 && flag_unsafe_math_optimizations"
16890 [(set_attr "type" "fpspc")
16891 (set_attr "mode" "XF")])
16893 (define_insn "fyl2x_extend<mode>xf3_i387"
16894 [(set (match_operand:XF 0 "register_operand" "=f")
16895 (unspec:XF [(float_extend:XF
16896 (match_operand:MODEF 1 "register_operand" "0"))
16897 (match_operand:XF 2 "register_operand" "u")]
16899 (clobber (match_scratch:XF 3 "=2"))]
16900 "TARGET_USE_FANCY_MATH_387
16901 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16902 || TARGET_MIX_SSE_I387)
16903 && flag_unsafe_math_optimizations"
16905 [(set_attr "type" "fpspc")
16906 (set_attr "mode" "XF")])
16908 (define_expand "logxf2"
16909 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16910 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16911 (match_dup 2)] UNSPEC_FYL2X))
16912 (clobber (match_scratch:XF 3 ""))])]
16913 "TARGET_USE_FANCY_MATH_387
16914 && flag_unsafe_math_optimizations"
16916 operands[2] = gen_reg_rtx (XFmode);
16917 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16920 (define_expand "log<mode>2"
16921 [(use (match_operand:MODEF 0 "register_operand" ""))
16922 (use (match_operand:MODEF 1 "register_operand" ""))]
16923 "TARGET_USE_FANCY_MATH_387
16924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16925 || TARGET_MIX_SSE_I387)
16926 && flag_unsafe_math_optimizations"
16928 rtx op0 = gen_reg_rtx (XFmode);
16930 rtx op2 = gen_reg_rtx (XFmode);
16931 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16933 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16934 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16938 (define_expand "log10xf2"
16939 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16940 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16941 (match_dup 2)] UNSPEC_FYL2X))
16942 (clobber (match_scratch:XF 3 ""))])]
16943 "TARGET_USE_FANCY_MATH_387
16944 && flag_unsafe_math_optimizations"
16946 operands[2] = gen_reg_rtx (XFmode);
16947 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16950 (define_expand "log10<mode>2"
16951 [(use (match_operand:MODEF 0 "register_operand" ""))
16952 (use (match_operand:MODEF 1 "register_operand" ""))]
16953 "TARGET_USE_FANCY_MATH_387
16954 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16955 || TARGET_MIX_SSE_I387)
16956 && flag_unsafe_math_optimizations"
16958 rtx op0 = gen_reg_rtx (XFmode);
16960 rtx op2 = gen_reg_rtx (XFmode);
16961 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16963 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16964 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16968 (define_expand "log2xf2"
16969 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16970 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16971 (match_dup 2)] UNSPEC_FYL2X))
16972 (clobber (match_scratch:XF 3 ""))])]
16973 "TARGET_USE_FANCY_MATH_387
16974 && flag_unsafe_math_optimizations"
16976 operands[2] = gen_reg_rtx (XFmode);
16977 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16980 (define_expand "log2<mode>2"
16981 [(use (match_operand:MODEF 0 "register_operand" ""))
16982 (use (match_operand:MODEF 1 "register_operand" ""))]
16983 "TARGET_USE_FANCY_MATH_387
16984 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16985 || TARGET_MIX_SSE_I387)
16986 && flag_unsafe_math_optimizations"
16988 rtx op0 = gen_reg_rtx (XFmode);
16990 rtx op2 = gen_reg_rtx (XFmode);
16991 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16993 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16994 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16998 (define_insn "fyl2xp1xf3_i387"
16999 [(set (match_operand:XF 0 "register_operand" "=f")
17000 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17001 (match_operand:XF 2 "register_operand" "u")]
17003 (clobber (match_scratch:XF 3 "=2"))]
17004 "TARGET_USE_FANCY_MATH_387
17005 && flag_unsafe_math_optimizations"
17007 [(set_attr "type" "fpspc")
17008 (set_attr "mode" "XF")])
17010 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17011 [(set (match_operand:XF 0 "register_operand" "=f")
17012 (unspec:XF [(float_extend:XF
17013 (match_operand:MODEF 1 "register_operand" "0"))
17014 (match_operand:XF 2 "register_operand" "u")]
17016 (clobber (match_scratch:XF 3 "=2"))]
17017 "TARGET_USE_FANCY_MATH_387
17018 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17019 || TARGET_MIX_SSE_I387)
17020 && flag_unsafe_math_optimizations"
17022 [(set_attr "type" "fpspc")
17023 (set_attr "mode" "XF")])
17025 (define_expand "log1pxf2"
17026 [(use (match_operand:XF 0 "register_operand" ""))
17027 (use (match_operand:XF 1 "register_operand" ""))]
17028 "TARGET_USE_FANCY_MATH_387
17029 && flag_unsafe_math_optimizations && !optimize_size"
17031 ix86_emit_i387_log1p (operands[0], operands[1]);
17035 (define_expand "log1p<mode>2"
17036 [(use (match_operand:MODEF 0 "register_operand" ""))
17037 (use (match_operand:MODEF 1 "register_operand" ""))]
17038 "TARGET_USE_FANCY_MATH_387
17039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17040 || TARGET_MIX_SSE_I387)
17041 && flag_unsafe_math_optimizations && !optimize_size"
17043 rtx op0 = gen_reg_rtx (XFmode);
17045 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17047 ix86_emit_i387_log1p (op0, operands[1]);
17048 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17052 (define_insn "fxtractxf3_i387"
17053 [(set (match_operand:XF 0 "register_operand" "=f")
17054 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17055 UNSPEC_XTRACT_FRACT))
17056 (set (match_operand:XF 1 "register_operand" "=u")
17057 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17058 "TARGET_USE_FANCY_MATH_387
17059 && flag_unsafe_math_optimizations"
17061 [(set_attr "type" "fpspc")
17062 (set_attr "mode" "XF")])
17064 (define_insn "fxtract_extend<mode>xf3_i387"
17065 [(set (match_operand:XF 0 "register_operand" "=f")
17066 (unspec:XF [(float_extend:XF
17067 (match_operand:MODEF 2 "register_operand" "0"))]
17068 UNSPEC_XTRACT_FRACT))
17069 (set (match_operand:XF 1 "register_operand" "=u")
17070 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17071 "TARGET_USE_FANCY_MATH_387
17072 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17073 || TARGET_MIX_SSE_I387)
17074 && flag_unsafe_math_optimizations"
17076 [(set_attr "type" "fpspc")
17077 (set_attr "mode" "XF")])
17079 (define_expand "logbxf2"
17080 [(parallel [(set (match_dup 2)
17081 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17082 UNSPEC_XTRACT_FRACT))
17083 (set (match_operand:XF 0 "register_operand" "")
17084 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17085 "TARGET_USE_FANCY_MATH_387
17086 && flag_unsafe_math_optimizations"
17088 operands[2] = gen_reg_rtx (XFmode);
17091 (define_expand "logb<mode>2"
17092 [(use (match_operand:MODEF 0 "register_operand" ""))
17093 (use (match_operand:MODEF 1 "register_operand" ""))]
17094 "TARGET_USE_FANCY_MATH_387
17095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17096 || TARGET_MIX_SSE_I387)
17097 && flag_unsafe_math_optimizations"
17099 rtx op0 = gen_reg_rtx (XFmode);
17100 rtx op1 = gen_reg_rtx (XFmode);
17102 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17103 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17107 (define_expand "ilogbxf2"
17108 [(use (match_operand:SI 0 "register_operand" ""))
17109 (use (match_operand:XF 1 "register_operand" ""))]
17110 "TARGET_USE_FANCY_MATH_387
17111 && flag_unsafe_math_optimizations && !optimize_size"
17113 rtx op0 = gen_reg_rtx (XFmode);
17114 rtx op1 = gen_reg_rtx (XFmode);
17116 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17117 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17121 (define_expand "ilogb<mode>2"
17122 [(use (match_operand:SI 0 "register_operand" ""))
17123 (use (match_operand:MODEF 1 "register_operand" ""))]
17124 "TARGET_USE_FANCY_MATH_387
17125 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17126 || TARGET_MIX_SSE_I387)
17127 && flag_unsafe_math_optimizations && !optimize_size"
17129 rtx op0 = gen_reg_rtx (XFmode);
17130 rtx op1 = gen_reg_rtx (XFmode);
17132 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17133 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17137 (define_insn "*f2xm1xf2_i387"
17138 [(set (match_operand:XF 0 "register_operand" "=f")
17139 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17141 "TARGET_USE_FANCY_MATH_387
17142 && flag_unsafe_math_optimizations"
17144 [(set_attr "type" "fpspc")
17145 (set_attr "mode" "XF")])
17147 (define_insn "*fscalexf4_i387"
17148 [(set (match_operand:XF 0 "register_operand" "=f")
17149 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17150 (match_operand:XF 3 "register_operand" "1")]
17151 UNSPEC_FSCALE_FRACT))
17152 (set (match_operand:XF 1 "register_operand" "=u")
17153 (unspec:XF [(match_dup 2) (match_dup 3)]
17154 UNSPEC_FSCALE_EXP))]
17155 "TARGET_USE_FANCY_MATH_387
17156 && flag_unsafe_math_optimizations"
17158 [(set_attr "type" "fpspc")
17159 (set_attr "mode" "XF")])
17161 (define_expand "expNcorexf3"
17162 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17163 (match_operand:XF 2 "register_operand" "")))
17164 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17165 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17166 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17167 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17168 (parallel [(set (match_operand:XF 0 "register_operand" "")
17169 (unspec:XF [(match_dup 8) (match_dup 4)]
17170 UNSPEC_FSCALE_FRACT))
17172 (unspec:XF [(match_dup 8) (match_dup 4)]
17173 UNSPEC_FSCALE_EXP))])]
17174 "TARGET_USE_FANCY_MATH_387
17175 && flag_unsafe_math_optimizations && !optimize_size"
17179 for (i = 3; i < 10; i++)
17180 operands[i] = gen_reg_rtx (XFmode);
17182 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17185 (define_expand "expxf2"
17186 [(use (match_operand:XF 0 "register_operand" ""))
17187 (use (match_operand:XF 1 "register_operand" ""))]
17188 "TARGET_USE_FANCY_MATH_387
17189 && flag_unsafe_math_optimizations && !optimize_size"
17191 rtx op2 = gen_reg_rtx (XFmode);
17192 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17194 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17198 (define_expand "exp<mode>2"
17199 [(use (match_operand:MODEF 0 "register_operand" ""))
17200 (use (match_operand:MODEF 1 "general_operand" ""))]
17201 "TARGET_USE_FANCY_MATH_387
17202 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17203 || TARGET_MIX_SSE_I387)
17204 && flag_unsafe_math_optimizations && !optimize_size"
17206 rtx op0 = gen_reg_rtx (XFmode);
17207 rtx op1 = gen_reg_rtx (XFmode);
17209 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17210 emit_insn (gen_expxf2 (op0, op1));
17211 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17215 (define_expand "exp10xf2"
17216 [(use (match_operand:XF 0 "register_operand" ""))
17217 (use (match_operand:XF 1 "register_operand" ""))]
17218 "TARGET_USE_FANCY_MATH_387
17219 && flag_unsafe_math_optimizations && !optimize_size"
17221 rtx op2 = gen_reg_rtx (XFmode);
17222 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17224 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17228 (define_expand "exp10<mode>2"
17229 [(use (match_operand:MODEF 0 "register_operand" ""))
17230 (use (match_operand:MODEF 1 "general_operand" ""))]
17231 "TARGET_USE_FANCY_MATH_387
17232 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17233 || TARGET_MIX_SSE_I387)
17234 && flag_unsafe_math_optimizations && !optimize_size"
17236 rtx op0 = gen_reg_rtx (XFmode);
17237 rtx op1 = gen_reg_rtx (XFmode);
17239 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17240 emit_insn (gen_exp10xf2 (op0, op1));
17241 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17245 (define_expand "exp2xf2"
17246 [(use (match_operand:XF 0 "register_operand" ""))
17247 (use (match_operand:XF 1 "register_operand" ""))]
17248 "TARGET_USE_FANCY_MATH_387
17249 && flag_unsafe_math_optimizations && !optimize_size"
17251 rtx op2 = gen_reg_rtx (XFmode);
17252 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17254 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17258 (define_expand "exp2<mode>2"
17259 [(use (match_operand:MODEF 0 "register_operand" ""))
17260 (use (match_operand:MODEF 1 "general_operand" ""))]
17261 "TARGET_USE_FANCY_MATH_387
17262 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17263 || TARGET_MIX_SSE_I387)
17264 && flag_unsafe_math_optimizations && !optimize_size"
17266 rtx op0 = gen_reg_rtx (XFmode);
17267 rtx op1 = gen_reg_rtx (XFmode);
17269 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17270 emit_insn (gen_exp2xf2 (op0, op1));
17271 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17275 (define_expand "expm1xf2"
17276 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17278 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17279 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17280 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17281 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17282 (parallel [(set (match_dup 7)
17283 (unspec:XF [(match_dup 6) (match_dup 4)]
17284 UNSPEC_FSCALE_FRACT))
17286 (unspec:XF [(match_dup 6) (match_dup 4)]
17287 UNSPEC_FSCALE_EXP))])
17288 (parallel [(set (match_dup 10)
17289 (unspec:XF [(match_dup 9) (match_dup 8)]
17290 UNSPEC_FSCALE_FRACT))
17291 (set (match_dup 11)
17292 (unspec:XF [(match_dup 9) (match_dup 8)]
17293 UNSPEC_FSCALE_EXP))])
17294 (set (match_dup 12) (minus:XF (match_dup 10)
17295 (float_extend:XF (match_dup 13))))
17296 (set (match_operand:XF 0 "register_operand" "")
17297 (plus:XF (match_dup 12) (match_dup 7)))]
17298 "TARGET_USE_FANCY_MATH_387
17299 && flag_unsafe_math_optimizations && !optimize_size"
17303 for (i = 2; i < 13; i++)
17304 operands[i] = gen_reg_rtx (XFmode);
17307 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17309 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17312 (define_expand "expm1<mode>2"
17313 [(use (match_operand:MODEF 0 "register_operand" ""))
17314 (use (match_operand:MODEF 1 "general_operand" ""))]
17315 "TARGET_USE_FANCY_MATH_387
17316 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17317 || TARGET_MIX_SSE_I387)
17318 && flag_unsafe_math_optimizations && !optimize_size"
17320 rtx op0 = gen_reg_rtx (XFmode);
17321 rtx op1 = gen_reg_rtx (XFmode);
17323 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17324 emit_insn (gen_expm1xf2 (op0, op1));
17325 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17329 (define_expand "ldexpxf3"
17330 [(set (match_dup 3)
17331 (float:XF (match_operand:SI 2 "register_operand" "")))
17332 (parallel [(set (match_operand:XF 0 " register_operand" "")
17333 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17335 UNSPEC_FSCALE_FRACT))
17337 (unspec:XF [(match_dup 1) (match_dup 3)]
17338 UNSPEC_FSCALE_EXP))])]
17339 "TARGET_USE_FANCY_MATH_387
17340 && flag_unsafe_math_optimizations && !optimize_size"
17342 operands[3] = gen_reg_rtx (XFmode);
17343 operands[4] = gen_reg_rtx (XFmode);
17346 (define_expand "ldexp<mode>3"
17347 [(use (match_operand:MODEF 0 "register_operand" ""))
17348 (use (match_operand:MODEF 1 "general_operand" ""))
17349 (use (match_operand:SI 2 "register_operand" ""))]
17350 "TARGET_USE_FANCY_MATH_387
17351 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17352 || TARGET_MIX_SSE_I387)
17353 && flag_unsafe_math_optimizations && !optimize_size"
17355 rtx op0 = gen_reg_rtx (XFmode);
17356 rtx op1 = gen_reg_rtx (XFmode);
17358 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17359 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17360 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17364 (define_expand "scalbxf3"
17365 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17366 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17367 (match_operand:XF 2 "register_operand" "")]
17368 UNSPEC_FSCALE_FRACT))
17370 (unspec:XF [(match_dup 1) (match_dup 2)]
17371 UNSPEC_FSCALE_EXP))])]
17372 "TARGET_USE_FANCY_MATH_387
17373 && flag_unsafe_math_optimizations && !optimize_size"
17375 operands[3] = gen_reg_rtx (XFmode);
17378 (define_expand "scalb<mode>3"
17379 [(use (match_operand:MODEF 0 "register_operand" ""))
17380 (use (match_operand:MODEF 1 "general_operand" ""))
17381 (use (match_operand:MODEF 2 "register_operand" ""))]
17382 "TARGET_USE_FANCY_MATH_387
17383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17384 || TARGET_MIX_SSE_I387)
17385 && flag_unsafe_math_optimizations && !optimize_size"
17387 rtx op0 = gen_reg_rtx (XFmode);
17388 rtx op1 = gen_reg_rtx (XFmode);
17389 rtx op2 = gen_reg_rtx (XFmode);
17391 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17392 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17393 emit_insn (gen_scalbxf3 (op0, op1, op2));
17394 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17399 (define_insn "sse4_1_round<mode>2"
17400 [(set (match_operand:MODEF 0 "register_operand" "=x")
17401 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17402 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17405 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17406 [(set_attr "type" "ssecvt")
17407 (set_attr "prefix_extra" "1")
17408 (set_attr "mode" "<MODE>")])
17410 (define_insn "rintxf2"
17411 [(set (match_operand:XF 0 "register_operand" "=f")
17412 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17414 "TARGET_USE_FANCY_MATH_387
17415 && flag_unsafe_math_optimizations"
17417 [(set_attr "type" "fpspc")
17418 (set_attr "mode" "XF")])
17420 (define_expand "rint<mode>2"
17421 [(use (match_operand:MODEF 0 "register_operand" ""))
17422 (use (match_operand:MODEF 1 "register_operand" ""))]
17423 "(TARGET_USE_FANCY_MATH_387
17424 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17425 || TARGET_MIX_SSE_I387)
17426 && flag_unsafe_math_optimizations)
17427 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17428 && !flag_trapping_math
17429 && (TARGET_ROUND || !optimize_size))"
17431 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17432 && !flag_trapping_math
17433 && (TARGET_ROUND || !optimize_size))
17436 emit_insn (gen_sse4_1_round<mode>2
17437 (operands[0], operands[1], GEN_INT (0x04)));
17439 ix86_expand_rint (operand0, operand1);
17443 rtx op0 = gen_reg_rtx (XFmode);
17444 rtx op1 = gen_reg_rtx (XFmode);
17446 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17447 emit_insn (gen_rintxf2 (op0, op1));
17449 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17454 (define_expand "round<mode>2"
17455 [(match_operand:MODEF 0 "register_operand" "")
17456 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17457 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17458 && !flag_trapping_math && !flag_rounding_math
17461 if (TARGET_64BIT || (<MODE>mode != DFmode))
17462 ix86_expand_round (operand0, operand1);
17464 ix86_expand_rounddf_32 (operand0, operand1);
17468 (define_insn_and_split "*fistdi2_1"
17469 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17470 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17472 "TARGET_USE_FANCY_MATH_387
17473 && !(reload_completed || reload_in_progress)"
17478 if (memory_operand (operands[0], VOIDmode))
17479 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17482 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17483 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17488 [(set_attr "type" "fpspc")
17489 (set_attr "mode" "DI")])
17491 (define_insn "fistdi2"
17492 [(set (match_operand:DI 0 "memory_operand" "=m")
17493 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17495 (clobber (match_scratch:XF 2 "=&1f"))]
17496 "TARGET_USE_FANCY_MATH_387"
17497 "* return output_fix_trunc (insn, operands, 0);"
17498 [(set_attr "type" "fpspc")
17499 (set_attr "mode" "DI")])
17501 (define_insn "fistdi2_with_temp"
17502 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17503 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17505 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17506 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17507 "TARGET_USE_FANCY_MATH_387"
17509 [(set_attr "type" "fpspc")
17510 (set_attr "mode" "DI")])
17513 [(set (match_operand:DI 0 "register_operand" "")
17514 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17516 (clobber (match_operand:DI 2 "memory_operand" ""))
17517 (clobber (match_scratch 3 ""))]
17519 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17520 (clobber (match_dup 3))])
17521 (set (match_dup 0) (match_dup 2))]
17525 [(set (match_operand:DI 0 "memory_operand" "")
17526 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17528 (clobber (match_operand:DI 2 "memory_operand" ""))
17529 (clobber (match_scratch 3 ""))]
17531 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17532 (clobber (match_dup 3))])]
17535 (define_insn_and_split "*fist<mode>2_1"
17536 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17537 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17539 "TARGET_USE_FANCY_MATH_387
17540 && !(reload_completed || reload_in_progress)"
17545 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17546 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17550 [(set_attr "type" "fpspc")
17551 (set_attr "mode" "<MODE>")])
17553 (define_insn "fist<mode>2"
17554 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17555 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17557 "TARGET_USE_FANCY_MATH_387"
17558 "* return output_fix_trunc (insn, operands, 0);"
17559 [(set_attr "type" "fpspc")
17560 (set_attr "mode" "<MODE>")])
17562 (define_insn "fist<mode>2_with_temp"
17563 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17564 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17566 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17567 "TARGET_USE_FANCY_MATH_387"
17569 [(set_attr "type" "fpspc")
17570 (set_attr "mode" "<MODE>")])
17573 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17574 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17576 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17578 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17579 (set (match_dup 0) (match_dup 2))]
17583 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17584 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17586 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17588 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17591 (define_expand "lrintxf<mode>2"
17592 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17593 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17595 "TARGET_USE_FANCY_MATH_387"
17598 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17599 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17600 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17601 UNSPEC_FIX_NOTRUNC))]
17602 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17603 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17606 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17607 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17608 (match_operand:MODEF 1 "register_operand" "")]
17609 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17610 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17611 && !flag_trapping_math && !flag_rounding_math
17614 ix86_expand_lround (operand0, operand1);
17618 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17619 (define_insn_and_split "frndintxf2_floor"
17620 [(set (match_operand:XF 0 "register_operand" "")
17621 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17622 UNSPEC_FRNDINT_FLOOR))
17623 (clobber (reg:CC FLAGS_REG))]
17624 "TARGET_USE_FANCY_MATH_387
17625 && flag_unsafe_math_optimizations
17626 && !(reload_completed || reload_in_progress)"
17631 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17633 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17634 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17636 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17637 operands[2], operands[3]));
17640 [(set_attr "type" "frndint")
17641 (set_attr "i387_cw" "floor")
17642 (set_attr "mode" "XF")])
17644 (define_insn "frndintxf2_floor_i387"
17645 [(set (match_operand:XF 0 "register_operand" "=f")
17646 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17647 UNSPEC_FRNDINT_FLOOR))
17648 (use (match_operand:HI 2 "memory_operand" "m"))
17649 (use (match_operand:HI 3 "memory_operand" "m"))]
17650 "TARGET_USE_FANCY_MATH_387
17651 && flag_unsafe_math_optimizations"
17652 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17653 [(set_attr "type" "frndint")
17654 (set_attr "i387_cw" "floor")
17655 (set_attr "mode" "XF")])
17657 (define_expand "floorxf2"
17658 [(use (match_operand:XF 0 "register_operand" ""))
17659 (use (match_operand:XF 1 "register_operand" ""))]
17660 "TARGET_USE_FANCY_MATH_387
17661 && flag_unsafe_math_optimizations && !optimize_size"
17663 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17667 (define_expand "floor<mode>2"
17668 [(use (match_operand:MODEF 0 "register_operand" ""))
17669 (use (match_operand:MODEF 1 "register_operand" ""))]
17670 "(TARGET_USE_FANCY_MATH_387
17671 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17672 || TARGET_MIX_SSE_I387)
17673 && flag_unsafe_math_optimizations && !optimize_size)
17674 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17675 && !flag_trapping_math
17676 && (TARGET_ROUND || !optimize_size))"
17678 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17679 && !flag_trapping_math
17680 && (TARGET_ROUND || !optimize_size))
17683 emit_insn (gen_sse4_1_round<mode>2
17684 (operands[0], operands[1], GEN_INT (0x01)));
17685 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17686 ix86_expand_floorceil (operand0, operand1, true);
17688 ix86_expand_floorceildf_32 (operand0, operand1, true);
17692 rtx op0 = gen_reg_rtx (XFmode);
17693 rtx op1 = gen_reg_rtx (XFmode);
17695 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17696 emit_insn (gen_frndintxf2_floor (op0, op1));
17698 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17703 (define_insn_and_split "*fist<mode>2_floor_1"
17704 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17705 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17706 UNSPEC_FIST_FLOOR))
17707 (clobber (reg:CC FLAGS_REG))]
17708 "TARGET_USE_FANCY_MATH_387
17709 && flag_unsafe_math_optimizations
17710 && !(reload_completed || reload_in_progress)"
17715 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17717 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17718 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17719 if (memory_operand (operands[0], VOIDmode))
17720 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17721 operands[2], operands[3]));
17724 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17725 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17726 operands[2], operands[3],
17731 [(set_attr "type" "fistp")
17732 (set_attr "i387_cw" "floor")
17733 (set_attr "mode" "<MODE>")])
17735 (define_insn "fistdi2_floor"
17736 [(set (match_operand:DI 0 "memory_operand" "=m")
17737 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17738 UNSPEC_FIST_FLOOR))
17739 (use (match_operand:HI 2 "memory_operand" "m"))
17740 (use (match_operand:HI 3 "memory_operand" "m"))
17741 (clobber (match_scratch:XF 4 "=&1f"))]
17742 "TARGET_USE_FANCY_MATH_387
17743 && flag_unsafe_math_optimizations"
17744 "* return output_fix_trunc (insn, operands, 0);"
17745 [(set_attr "type" "fistp")
17746 (set_attr "i387_cw" "floor")
17747 (set_attr "mode" "DI")])
17749 (define_insn "fistdi2_floor_with_temp"
17750 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17751 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17752 UNSPEC_FIST_FLOOR))
17753 (use (match_operand:HI 2 "memory_operand" "m,m"))
17754 (use (match_operand:HI 3 "memory_operand" "m,m"))
17755 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17756 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17757 "TARGET_USE_FANCY_MATH_387
17758 && flag_unsafe_math_optimizations"
17760 [(set_attr "type" "fistp")
17761 (set_attr "i387_cw" "floor")
17762 (set_attr "mode" "DI")])
17765 [(set (match_operand:DI 0 "register_operand" "")
17766 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17767 UNSPEC_FIST_FLOOR))
17768 (use (match_operand:HI 2 "memory_operand" ""))
17769 (use (match_operand:HI 3 "memory_operand" ""))
17770 (clobber (match_operand:DI 4 "memory_operand" ""))
17771 (clobber (match_scratch 5 ""))]
17773 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17774 (use (match_dup 2))
17775 (use (match_dup 3))
17776 (clobber (match_dup 5))])
17777 (set (match_dup 0) (match_dup 4))]
17781 [(set (match_operand:DI 0 "memory_operand" "")
17782 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17783 UNSPEC_FIST_FLOOR))
17784 (use (match_operand:HI 2 "memory_operand" ""))
17785 (use (match_operand:HI 3 "memory_operand" ""))
17786 (clobber (match_operand:DI 4 "memory_operand" ""))
17787 (clobber (match_scratch 5 ""))]
17789 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17790 (use (match_dup 2))
17791 (use (match_dup 3))
17792 (clobber (match_dup 5))])]
17795 (define_insn "fist<mode>2_floor"
17796 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17797 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17798 UNSPEC_FIST_FLOOR))
17799 (use (match_operand:HI 2 "memory_operand" "m"))
17800 (use (match_operand:HI 3 "memory_operand" "m"))]
17801 "TARGET_USE_FANCY_MATH_387
17802 && flag_unsafe_math_optimizations"
17803 "* return output_fix_trunc (insn, operands, 0);"
17804 [(set_attr "type" "fistp")
17805 (set_attr "i387_cw" "floor")
17806 (set_attr "mode" "<MODE>")])
17808 (define_insn "fist<mode>2_floor_with_temp"
17809 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17810 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17811 UNSPEC_FIST_FLOOR))
17812 (use (match_operand:HI 2 "memory_operand" "m,m"))
17813 (use (match_operand:HI 3 "memory_operand" "m,m"))
17814 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17815 "TARGET_USE_FANCY_MATH_387
17816 && flag_unsafe_math_optimizations"
17818 [(set_attr "type" "fistp")
17819 (set_attr "i387_cw" "floor")
17820 (set_attr "mode" "<MODE>")])
17823 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17824 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17825 UNSPEC_FIST_FLOOR))
17826 (use (match_operand:HI 2 "memory_operand" ""))
17827 (use (match_operand:HI 3 "memory_operand" ""))
17828 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17830 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17831 UNSPEC_FIST_FLOOR))
17832 (use (match_dup 2))
17833 (use (match_dup 3))])
17834 (set (match_dup 0) (match_dup 4))]
17838 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17839 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17840 UNSPEC_FIST_FLOOR))
17841 (use (match_operand:HI 2 "memory_operand" ""))
17842 (use (match_operand:HI 3 "memory_operand" ""))
17843 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17845 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17846 UNSPEC_FIST_FLOOR))
17847 (use (match_dup 2))
17848 (use (match_dup 3))])]
17851 (define_expand "lfloorxf<mode>2"
17852 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17853 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17854 UNSPEC_FIST_FLOOR))
17855 (clobber (reg:CC FLAGS_REG))])]
17856 "TARGET_USE_FANCY_MATH_387
17857 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17858 && flag_unsafe_math_optimizations"
17861 (define_expand "lfloor<mode>di2"
17862 [(match_operand:DI 0 "nonimmediate_operand" "")
17863 (match_operand:MODEF 1 "register_operand" "")]
17864 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17865 && !flag_trapping_math
17868 ix86_expand_lfloorceil (operand0, operand1, true);
17872 (define_expand "lfloor<mode>si2"
17873 [(match_operand:SI 0 "nonimmediate_operand" "")
17874 (match_operand:MODEF 1 "register_operand" "")]
17875 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17876 && !flag_trapping_math
17877 && (!optimize_size || !TARGET_64BIT)"
17879 ix86_expand_lfloorceil (operand0, operand1, true);
17883 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17884 (define_insn_and_split "frndintxf2_ceil"
17885 [(set (match_operand:XF 0 "register_operand" "")
17886 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17887 UNSPEC_FRNDINT_CEIL))
17888 (clobber (reg:CC FLAGS_REG))]
17889 "TARGET_USE_FANCY_MATH_387
17890 && flag_unsafe_math_optimizations
17891 && !(reload_completed || reload_in_progress)"
17896 ix86_optimize_mode_switching[I387_CEIL] = 1;
17898 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17899 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17901 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17902 operands[2], operands[3]));
17905 [(set_attr "type" "frndint")
17906 (set_attr "i387_cw" "ceil")
17907 (set_attr "mode" "XF")])
17909 (define_insn "frndintxf2_ceil_i387"
17910 [(set (match_operand:XF 0 "register_operand" "=f")
17911 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17912 UNSPEC_FRNDINT_CEIL))
17913 (use (match_operand:HI 2 "memory_operand" "m"))
17914 (use (match_operand:HI 3 "memory_operand" "m"))]
17915 "TARGET_USE_FANCY_MATH_387
17916 && flag_unsafe_math_optimizations"
17917 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17918 [(set_attr "type" "frndint")
17919 (set_attr "i387_cw" "ceil")
17920 (set_attr "mode" "XF")])
17922 (define_expand "ceilxf2"
17923 [(use (match_operand:XF 0 "register_operand" ""))
17924 (use (match_operand:XF 1 "register_operand" ""))]
17925 "TARGET_USE_FANCY_MATH_387
17926 && flag_unsafe_math_optimizations && !optimize_size"
17928 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17932 (define_expand "ceil<mode>2"
17933 [(use (match_operand:MODEF 0 "register_operand" ""))
17934 (use (match_operand:MODEF 1 "register_operand" ""))]
17935 "(TARGET_USE_FANCY_MATH_387
17936 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17937 || TARGET_MIX_SSE_I387)
17938 && flag_unsafe_math_optimizations && !optimize_size)
17939 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17940 && !flag_trapping_math
17941 && (TARGET_ROUND || !optimize_size))"
17943 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17944 && !flag_trapping_math
17945 && (TARGET_ROUND || !optimize_size))
17948 emit_insn (gen_sse4_1_round<mode>2
17949 (operands[0], operands[1], GEN_INT (0x02)));
17950 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17951 ix86_expand_floorceil (operand0, operand1, false);
17953 ix86_expand_floorceildf_32 (operand0, operand1, false);
17957 rtx op0 = gen_reg_rtx (XFmode);
17958 rtx op1 = gen_reg_rtx (XFmode);
17960 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17961 emit_insn (gen_frndintxf2_ceil (op0, op1));
17963 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17968 (define_insn_and_split "*fist<mode>2_ceil_1"
17969 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17970 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17972 (clobber (reg:CC FLAGS_REG))]
17973 "TARGET_USE_FANCY_MATH_387
17974 && flag_unsafe_math_optimizations
17975 && !(reload_completed || reload_in_progress)"
17980 ix86_optimize_mode_switching[I387_CEIL] = 1;
17982 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17983 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17984 if (memory_operand (operands[0], VOIDmode))
17985 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17986 operands[2], operands[3]));
17989 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17990 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17991 operands[2], operands[3],
17996 [(set_attr "type" "fistp")
17997 (set_attr "i387_cw" "ceil")
17998 (set_attr "mode" "<MODE>")])
18000 (define_insn "fistdi2_ceil"
18001 [(set (match_operand:DI 0 "memory_operand" "=m")
18002 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18004 (use (match_operand:HI 2 "memory_operand" "m"))
18005 (use (match_operand:HI 3 "memory_operand" "m"))
18006 (clobber (match_scratch:XF 4 "=&1f"))]
18007 "TARGET_USE_FANCY_MATH_387
18008 && flag_unsafe_math_optimizations"
18009 "* return output_fix_trunc (insn, operands, 0);"
18010 [(set_attr "type" "fistp")
18011 (set_attr "i387_cw" "ceil")
18012 (set_attr "mode" "DI")])
18014 (define_insn "fistdi2_ceil_with_temp"
18015 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18016 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18018 (use (match_operand:HI 2 "memory_operand" "m,m"))
18019 (use (match_operand:HI 3 "memory_operand" "m,m"))
18020 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18021 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18022 "TARGET_USE_FANCY_MATH_387
18023 && flag_unsafe_math_optimizations"
18025 [(set_attr "type" "fistp")
18026 (set_attr "i387_cw" "ceil")
18027 (set_attr "mode" "DI")])
18030 [(set (match_operand:DI 0 "register_operand" "")
18031 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18033 (use (match_operand:HI 2 "memory_operand" ""))
18034 (use (match_operand:HI 3 "memory_operand" ""))
18035 (clobber (match_operand:DI 4 "memory_operand" ""))
18036 (clobber (match_scratch 5 ""))]
18038 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18039 (use (match_dup 2))
18040 (use (match_dup 3))
18041 (clobber (match_dup 5))])
18042 (set (match_dup 0) (match_dup 4))]
18046 [(set (match_operand:DI 0 "memory_operand" "")
18047 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18049 (use (match_operand:HI 2 "memory_operand" ""))
18050 (use (match_operand:HI 3 "memory_operand" ""))
18051 (clobber (match_operand:DI 4 "memory_operand" ""))
18052 (clobber (match_scratch 5 ""))]
18054 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18055 (use (match_dup 2))
18056 (use (match_dup 3))
18057 (clobber (match_dup 5))])]
18060 (define_insn "fist<mode>2_ceil"
18061 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18062 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18064 (use (match_operand:HI 2 "memory_operand" "m"))
18065 (use (match_operand:HI 3 "memory_operand" "m"))]
18066 "TARGET_USE_FANCY_MATH_387
18067 && flag_unsafe_math_optimizations"
18068 "* return output_fix_trunc (insn, operands, 0);"
18069 [(set_attr "type" "fistp")
18070 (set_attr "i387_cw" "ceil")
18071 (set_attr "mode" "<MODE>")])
18073 (define_insn "fist<mode>2_ceil_with_temp"
18074 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18075 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18077 (use (match_operand:HI 2 "memory_operand" "m,m"))
18078 (use (match_operand:HI 3 "memory_operand" "m,m"))
18079 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18080 "TARGET_USE_FANCY_MATH_387
18081 && flag_unsafe_math_optimizations"
18083 [(set_attr "type" "fistp")
18084 (set_attr "i387_cw" "ceil")
18085 (set_attr "mode" "<MODE>")])
18088 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18089 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18091 (use (match_operand:HI 2 "memory_operand" ""))
18092 (use (match_operand:HI 3 "memory_operand" ""))
18093 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18095 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18097 (use (match_dup 2))
18098 (use (match_dup 3))])
18099 (set (match_dup 0) (match_dup 4))]
18103 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18104 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18106 (use (match_operand:HI 2 "memory_operand" ""))
18107 (use (match_operand:HI 3 "memory_operand" ""))
18108 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18110 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18112 (use (match_dup 2))
18113 (use (match_dup 3))])]
18116 (define_expand "lceilxf<mode>2"
18117 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18118 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18120 (clobber (reg:CC FLAGS_REG))])]
18121 "TARGET_USE_FANCY_MATH_387
18122 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18123 && flag_unsafe_math_optimizations"
18126 (define_expand "lceil<mode>di2"
18127 [(match_operand:DI 0 "nonimmediate_operand" "")
18128 (match_operand:MODEF 1 "register_operand" "")]
18129 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18130 && !flag_trapping_math"
18132 ix86_expand_lfloorceil (operand0, operand1, false);
18136 (define_expand "lceil<mode>si2"
18137 [(match_operand:SI 0 "nonimmediate_operand" "")
18138 (match_operand:MODEF 1 "register_operand" "")]
18139 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18140 && !flag_trapping_math"
18142 ix86_expand_lfloorceil (operand0, operand1, false);
18146 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18147 (define_insn_and_split "frndintxf2_trunc"
18148 [(set (match_operand:XF 0 "register_operand" "")
18149 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18150 UNSPEC_FRNDINT_TRUNC))
18151 (clobber (reg:CC FLAGS_REG))]
18152 "TARGET_USE_FANCY_MATH_387
18153 && flag_unsafe_math_optimizations
18154 && !(reload_completed || reload_in_progress)"
18159 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18161 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18162 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18164 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18165 operands[2], operands[3]));
18168 [(set_attr "type" "frndint")
18169 (set_attr "i387_cw" "trunc")
18170 (set_attr "mode" "XF")])
18172 (define_insn "frndintxf2_trunc_i387"
18173 [(set (match_operand:XF 0 "register_operand" "=f")
18174 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18175 UNSPEC_FRNDINT_TRUNC))
18176 (use (match_operand:HI 2 "memory_operand" "m"))
18177 (use (match_operand:HI 3 "memory_operand" "m"))]
18178 "TARGET_USE_FANCY_MATH_387
18179 && flag_unsafe_math_optimizations"
18180 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18181 [(set_attr "type" "frndint")
18182 (set_attr "i387_cw" "trunc")
18183 (set_attr "mode" "XF")])
18185 (define_expand "btruncxf2"
18186 [(use (match_operand:XF 0 "register_operand" ""))
18187 (use (match_operand:XF 1 "register_operand" ""))]
18188 "TARGET_USE_FANCY_MATH_387
18189 && flag_unsafe_math_optimizations && !optimize_size"
18191 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18195 (define_expand "btrunc<mode>2"
18196 [(use (match_operand:MODEF 0 "register_operand" ""))
18197 (use (match_operand:MODEF 1 "register_operand" ""))]
18198 "(TARGET_USE_FANCY_MATH_387
18199 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18200 || TARGET_MIX_SSE_I387)
18201 && flag_unsafe_math_optimizations && !optimize_size)
18202 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18203 && !flag_trapping_math
18204 && (TARGET_ROUND || !optimize_size))"
18206 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18207 && !flag_trapping_math
18208 && (TARGET_ROUND || !optimize_size))
18211 emit_insn (gen_sse4_1_round<mode>2
18212 (operands[0], operands[1], GEN_INT (0x03)));
18213 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18214 ix86_expand_trunc (operand0, operand1);
18216 ix86_expand_truncdf_32 (operand0, operand1);
18220 rtx op0 = gen_reg_rtx (XFmode);
18221 rtx op1 = gen_reg_rtx (XFmode);
18223 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18224 emit_insn (gen_frndintxf2_trunc (op0, op1));
18226 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18231 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18232 (define_insn_and_split "frndintxf2_mask_pm"
18233 [(set (match_operand:XF 0 "register_operand" "")
18234 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18235 UNSPEC_FRNDINT_MASK_PM))
18236 (clobber (reg:CC FLAGS_REG))]
18237 "TARGET_USE_FANCY_MATH_387
18238 && flag_unsafe_math_optimizations
18239 && !(reload_completed || reload_in_progress)"
18244 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18246 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18247 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18249 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18250 operands[2], operands[3]));
18253 [(set_attr "type" "frndint")
18254 (set_attr "i387_cw" "mask_pm")
18255 (set_attr "mode" "XF")])
18257 (define_insn "frndintxf2_mask_pm_i387"
18258 [(set (match_operand:XF 0 "register_operand" "=f")
18259 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18260 UNSPEC_FRNDINT_MASK_PM))
18261 (use (match_operand:HI 2 "memory_operand" "m"))
18262 (use (match_operand:HI 3 "memory_operand" "m"))]
18263 "TARGET_USE_FANCY_MATH_387
18264 && flag_unsafe_math_optimizations"
18265 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18266 [(set_attr "type" "frndint")
18267 (set_attr "i387_cw" "mask_pm")
18268 (set_attr "mode" "XF")])
18270 (define_expand "nearbyintxf2"
18271 [(use (match_operand:XF 0 "register_operand" ""))
18272 (use (match_operand:XF 1 "register_operand" ""))]
18273 "TARGET_USE_FANCY_MATH_387
18274 && flag_unsafe_math_optimizations"
18276 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18281 (define_expand "nearbyint<mode>2"
18282 [(use (match_operand:MODEF 0 "register_operand" ""))
18283 (use (match_operand:MODEF 1 "register_operand" ""))]
18284 "TARGET_USE_FANCY_MATH_387
18285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18286 || TARGET_MIX_SSE_I387)
18287 && flag_unsafe_math_optimizations"
18289 rtx op0 = gen_reg_rtx (XFmode);
18290 rtx op1 = gen_reg_rtx (XFmode);
18292 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18293 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18295 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18299 (define_insn "fxam<mode>2_i387"
18300 [(set (match_operand:HI 0 "register_operand" "=a")
18302 [(match_operand:X87MODEF 1 "register_operand" "f")]
18304 "TARGET_USE_FANCY_MATH_387"
18305 "fxam\n\tfnstsw\t%0"
18306 [(set_attr "type" "multi")
18307 (set_attr "unit" "i387")
18308 (set_attr "mode" "<MODE>")])
18310 (define_expand "isinf<mode>2"
18311 [(use (match_operand:SI 0 "register_operand" ""))
18312 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18313 "TARGET_USE_FANCY_MATH_387
18314 && TARGET_C99_FUNCTIONS
18315 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18317 rtx mask = GEN_INT (0x45);
18318 rtx val = GEN_INT (0x05);
18322 rtx scratch = gen_reg_rtx (HImode);
18323 rtx res = gen_reg_rtx (QImode);
18325 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18326 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18327 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18328 cond = gen_rtx_fmt_ee (EQ, QImode,
18329 gen_rtx_REG (CCmode, FLAGS_REG),
18331 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18332 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18336 (define_expand "signbit<mode>2"
18337 [(use (match_operand:SI 0 "register_operand" ""))
18338 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18339 "TARGET_USE_FANCY_MATH_387
18340 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18342 rtx mask = GEN_INT (0x0200);
18344 rtx scratch = gen_reg_rtx (HImode);
18346 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18347 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18351 ;; Block operation instructions
18353 (define_expand "movmemsi"
18354 [(use (match_operand:BLK 0 "memory_operand" ""))
18355 (use (match_operand:BLK 1 "memory_operand" ""))
18356 (use (match_operand:SI 2 "nonmemory_operand" ""))
18357 (use (match_operand:SI 3 "const_int_operand" ""))
18358 (use (match_operand:SI 4 "const_int_operand" ""))
18359 (use (match_operand:SI 5 "const_int_operand" ""))]
18362 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18363 operands[4], operands[5]))
18369 (define_expand "movmemdi"
18370 [(use (match_operand:BLK 0 "memory_operand" ""))
18371 (use (match_operand:BLK 1 "memory_operand" ""))
18372 (use (match_operand:DI 2 "nonmemory_operand" ""))
18373 (use (match_operand:DI 3 "const_int_operand" ""))
18374 (use (match_operand:SI 4 "const_int_operand" ""))
18375 (use (match_operand:SI 5 "const_int_operand" ""))]
18378 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18379 operands[4], operands[5]))
18385 ;; Most CPUs don't like single string operations
18386 ;; Handle this case here to simplify previous expander.
18388 (define_expand "strmov"
18389 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18390 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18391 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18392 (clobber (reg:CC FLAGS_REG))])
18393 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18394 (clobber (reg:CC FLAGS_REG))])]
18397 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18399 /* If .md ever supports :P for Pmode, these can be directly
18400 in the pattern above. */
18401 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18402 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18404 /* Can't use this if the user has appropriated esi or edi. */
18405 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18406 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18408 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18409 operands[2], operands[3],
18410 operands[5], operands[6]));
18414 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18417 (define_expand "strmov_singleop"
18418 [(parallel [(set (match_operand 1 "memory_operand" "")
18419 (match_operand 3 "memory_operand" ""))
18420 (set (match_operand 0 "register_operand" "")
18421 (match_operand 4 "" ""))
18422 (set (match_operand 2 "register_operand" "")
18423 (match_operand 5 "" ""))])]
18424 "TARGET_SINGLE_STRINGOP || optimize_size"
18427 (define_insn "*strmovdi_rex_1"
18428 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18429 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18430 (set (match_operand:DI 0 "register_operand" "=D")
18431 (plus:DI (match_dup 2)
18433 (set (match_operand:DI 1 "register_operand" "=S")
18434 (plus:DI (match_dup 3)
18436 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18438 [(set_attr "type" "str")
18439 (set_attr "mode" "DI")
18440 (set_attr "memory" "both")])
18442 (define_insn "*strmovsi_1"
18443 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18444 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18445 (set (match_operand:SI 0 "register_operand" "=D")
18446 (plus:SI (match_dup 2)
18448 (set (match_operand:SI 1 "register_operand" "=S")
18449 (plus:SI (match_dup 3)
18451 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18453 [(set_attr "type" "str")
18454 (set_attr "mode" "SI")
18455 (set_attr "memory" "both")])
18457 (define_insn "*strmovsi_rex_1"
18458 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18459 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18460 (set (match_operand:DI 0 "register_operand" "=D")
18461 (plus:DI (match_dup 2)
18463 (set (match_operand:DI 1 "register_operand" "=S")
18464 (plus:DI (match_dup 3)
18466 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18468 [(set_attr "type" "str")
18469 (set_attr "mode" "SI")
18470 (set_attr "memory" "both")])
18472 (define_insn "*strmovhi_1"
18473 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18474 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18475 (set (match_operand:SI 0 "register_operand" "=D")
18476 (plus:SI (match_dup 2)
18478 (set (match_operand:SI 1 "register_operand" "=S")
18479 (plus:SI (match_dup 3)
18481 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18483 [(set_attr "type" "str")
18484 (set_attr "memory" "both")
18485 (set_attr "mode" "HI")])
18487 (define_insn "*strmovhi_rex_1"
18488 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18489 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18490 (set (match_operand:DI 0 "register_operand" "=D")
18491 (plus:DI (match_dup 2)
18493 (set (match_operand:DI 1 "register_operand" "=S")
18494 (plus:DI (match_dup 3)
18496 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18498 [(set_attr "type" "str")
18499 (set_attr "memory" "both")
18500 (set_attr "mode" "HI")])
18502 (define_insn "*strmovqi_1"
18503 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18504 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18505 (set (match_operand:SI 0 "register_operand" "=D")
18506 (plus:SI (match_dup 2)
18508 (set (match_operand:SI 1 "register_operand" "=S")
18509 (plus:SI (match_dup 3)
18511 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18513 [(set_attr "type" "str")
18514 (set_attr "memory" "both")
18515 (set_attr "mode" "QI")])
18517 (define_insn "*strmovqi_rex_1"
18518 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18519 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18520 (set (match_operand:DI 0 "register_operand" "=D")
18521 (plus:DI (match_dup 2)
18523 (set (match_operand:DI 1 "register_operand" "=S")
18524 (plus:DI (match_dup 3)
18526 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18528 [(set_attr "type" "str")
18529 (set_attr "memory" "both")
18530 (set_attr "mode" "QI")])
18532 (define_expand "rep_mov"
18533 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18534 (set (match_operand 0 "register_operand" "")
18535 (match_operand 5 "" ""))
18536 (set (match_operand 2 "register_operand" "")
18537 (match_operand 6 "" ""))
18538 (set (match_operand 1 "memory_operand" "")
18539 (match_operand 3 "memory_operand" ""))
18540 (use (match_dup 4))])]
18544 (define_insn "*rep_movdi_rex64"
18545 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18546 (set (match_operand:DI 0 "register_operand" "=D")
18547 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18549 (match_operand:DI 3 "register_operand" "0")))
18550 (set (match_operand:DI 1 "register_operand" "=S")
18551 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18552 (match_operand:DI 4 "register_operand" "1")))
18553 (set (mem:BLK (match_dup 3))
18554 (mem:BLK (match_dup 4)))
18555 (use (match_dup 5))]
18558 [(set_attr "type" "str")
18559 (set_attr "prefix_rep" "1")
18560 (set_attr "memory" "both")
18561 (set_attr "mode" "DI")])
18563 (define_insn "*rep_movsi"
18564 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18565 (set (match_operand:SI 0 "register_operand" "=D")
18566 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18568 (match_operand:SI 3 "register_operand" "0")))
18569 (set (match_operand:SI 1 "register_operand" "=S")
18570 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18571 (match_operand:SI 4 "register_operand" "1")))
18572 (set (mem:BLK (match_dup 3))
18573 (mem:BLK (match_dup 4)))
18574 (use (match_dup 5))]
18577 [(set_attr "type" "str")
18578 (set_attr "prefix_rep" "1")
18579 (set_attr "memory" "both")
18580 (set_attr "mode" "SI")])
18582 (define_insn "*rep_movsi_rex64"
18583 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18584 (set (match_operand:DI 0 "register_operand" "=D")
18585 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18587 (match_operand:DI 3 "register_operand" "0")))
18588 (set (match_operand:DI 1 "register_operand" "=S")
18589 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18590 (match_operand:DI 4 "register_operand" "1")))
18591 (set (mem:BLK (match_dup 3))
18592 (mem:BLK (match_dup 4)))
18593 (use (match_dup 5))]
18596 [(set_attr "type" "str")
18597 (set_attr "prefix_rep" "1")
18598 (set_attr "memory" "both")
18599 (set_attr "mode" "SI")])
18601 (define_insn "*rep_movqi"
18602 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18603 (set (match_operand:SI 0 "register_operand" "=D")
18604 (plus:SI (match_operand:SI 3 "register_operand" "0")
18605 (match_operand:SI 5 "register_operand" "2")))
18606 (set (match_operand:SI 1 "register_operand" "=S")
18607 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18608 (set (mem:BLK (match_dup 3))
18609 (mem:BLK (match_dup 4)))
18610 (use (match_dup 5))]
18613 [(set_attr "type" "str")
18614 (set_attr "prefix_rep" "1")
18615 (set_attr "memory" "both")
18616 (set_attr "mode" "SI")])
18618 (define_insn "*rep_movqi_rex64"
18619 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18620 (set (match_operand:DI 0 "register_operand" "=D")
18621 (plus:DI (match_operand:DI 3 "register_operand" "0")
18622 (match_operand:DI 5 "register_operand" "2")))
18623 (set (match_operand:DI 1 "register_operand" "=S")
18624 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18625 (set (mem:BLK (match_dup 3))
18626 (mem:BLK (match_dup 4)))
18627 (use (match_dup 5))]
18630 [(set_attr "type" "str")
18631 (set_attr "prefix_rep" "1")
18632 (set_attr "memory" "both")
18633 (set_attr "mode" "SI")])
18635 (define_expand "setmemsi"
18636 [(use (match_operand:BLK 0 "memory_operand" ""))
18637 (use (match_operand:SI 1 "nonmemory_operand" ""))
18638 (use (match_operand 2 "const_int_operand" ""))
18639 (use (match_operand 3 "const_int_operand" ""))
18640 (use (match_operand:SI 4 "const_int_operand" ""))
18641 (use (match_operand:SI 5 "const_int_operand" ""))]
18644 if (ix86_expand_setmem (operands[0], operands[1],
18645 operands[2], operands[3],
18646 operands[4], operands[5]))
18652 (define_expand "setmemdi"
18653 [(use (match_operand:BLK 0 "memory_operand" ""))
18654 (use (match_operand:DI 1 "nonmemory_operand" ""))
18655 (use (match_operand 2 "const_int_operand" ""))
18656 (use (match_operand 3 "const_int_operand" ""))
18657 (use (match_operand 4 "const_int_operand" ""))
18658 (use (match_operand 5 "const_int_operand" ""))]
18661 if (ix86_expand_setmem (operands[0], operands[1],
18662 operands[2], operands[3],
18663 operands[4], operands[5]))
18669 ;; Most CPUs don't like single string operations
18670 ;; Handle this case here to simplify previous expander.
18672 (define_expand "strset"
18673 [(set (match_operand 1 "memory_operand" "")
18674 (match_operand 2 "register_operand" ""))
18675 (parallel [(set (match_operand 0 "register_operand" "")
18677 (clobber (reg:CC FLAGS_REG))])]
18680 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18681 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18683 /* If .md ever supports :P for Pmode, this can be directly
18684 in the pattern above. */
18685 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18686 GEN_INT (GET_MODE_SIZE (GET_MODE
18688 if (TARGET_SINGLE_STRINGOP || optimize_size)
18690 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18696 (define_expand "strset_singleop"
18697 [(parallel [(set (match_operand 1 "memory_operand" "")
18698 (match_operand 2 "register_operand" ""))
18699 (set (match_operand 0 "register_operand" "")
18700 (match_operand 3 "" ""))])]
18701 "TARGET_SINGLE_STRINGOP || optimize_size"
18704 (define_insn "*strsetdi_rex_1"
18705 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18706 (match_operand:DI 2 "register_operand" "a"))
18707 (set (match_operand:DI 0 "register_operand" "=D")
18708 (plus:DI (match_dup 1)
18710 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18712 [(set_attr "type" "str")
18713 (set_attr "memory" "store")
18714 (set_attr "mode" "DI")])
18716 (define_insn "*strsetsi_1"
18717 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18718 (match_operand:SI 2 "register_operand" "a"))
18719 (set (match_operand:SI 0 "register_operand" "=D")
18720 (plus:SI (match_dup 1)
18722 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18724 [(set_attr "type" "str")
18725 (set_attr "memory" "store")
18726 (set_attr "mode" "SI")])
18728 (define_insn "*strsetsi_rex_1"
18729 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18730 (match_operand:SI 2 "register_operand" "a"))
18731 (set (match_operand:DI 0 "register_operand" "=D")
18732 (plus:DI (match_dup 1)
18734 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18736 [(set_attr "type" "str")
18737 (set_attr "memory" "store")
18738 (set_attr "mode" "SI")])
18740 (define_insn "*strsethi_1"
18741 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18742 (match_operand:HI 2 "register_operand" "a"))
18743 (set (match_operand:SI 0 "register_operand" "=D")
18744 (plus:SI (match_dup 1)
18746 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18748 [(set_attr "type" "str")
18749 (set_attr "memory" "store")
18750 (set_attr "mode" "HI")])
18752 (define_insn "*strsethi_rex_1"
18753 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18754 (match_operand:HI 2 "register_operand" "a"))
18755 (set (match_operand:DI 0 "register_operand" "=D")
18756 (plus:DI (match_dup 1)
18758 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18760 [(set_attr "type" "str")
18761 (set_attr "memory" "store")
18762 (set_attr "mode" "HI")])
18764 (define_insn "*strsetqi_1"
18765 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18766 (match_operand:QI 2 "register_operand" "a"))
18767 (set (match_operand:SI 0 "register_operand" "=D")
18768 (plus:SI (match_dup 1)
18770 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18772 [(set_attr "type" "str")
18773 (set_attr "memory" "store")
18774 (set_attr "mode" "QI")])
18776 (define_insn "*strsetqi_rex_1"
18777 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18778 (match_operand:QI 2 "register_operand" "a"))
18779 (set (match_operand:DI 0 "register_operand" "=D")
18780 (plus:DI (match_dup 1)
18782 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18784 [(set_attr "type" "str")
18785 (set_attr "memory" "store")
18786 (set_attr "mode" "QI")])
18788 (define_expand "rep_stos"
18789 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18790 (set (match_operand 0 "register_operand" "")
18791 (match_operand 4 "" ""))
18792 (set (match_operand 2 "memory_operand" "") (const_int 0))
18793 (use (match_operand 3 "register_operand" ""))
18794 (use (match_dup 1))])]
18798 (define_insn "*rep_stosdi_rex64"
18799 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18800 (set (match_operand:DI 0 "register_operand" "=D")
18801 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18803 (match_operand:DI 3 "register_operand" "0")))
18804 (set (mem:BLK (match_dup 3))
18806 (use (match_operand:DI 2 "register_operand" "a"))
18807 (use (match_dup 4))]
18810 [(set_attr "type" "str")
18811 (set_attr "prefix_rep" "1")
18812 (set_attr "memory" "store")
18813 (set_attr "mode" "DI")])
18815 (define_insn "*rep_stossi"
18816 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18817 (set (match_operand:SI 0 "register_operand" "=D")
18818 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18820 (match_operand:SI 3 "register_operand" "0")))
18821 (set (mem:BLK (match_dup 3))
18823 (use (match_operand:SI 2 "register_operand" "a"))
18824 (use (match_dup 4))]
18827 [(set_attr "type" "str")
18828 (set_attr "prefix_rep" "1")
18829 (set_attr "memory" "store")
18830 (set_attr "mode" "SI")])
18832 (define_insn "*rep_stossi_rex64"
18833 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18834 (set (match_operand:DI 0 "register_operand" "=D")
18835 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18837 (match_operand:DI 3 "register_operand" "0")))
18838 (set (mem:BLK (match_dup 3))
18840 (use (match_operand:SI 2 "register_operand" "a"))
18841 (use (match_dup 4))]
18844 [(set_attr "type" "str")
18845 (set_attr "prefix_rep" "1")
18846 (set_attr "memory" "store")
18847 (set_attr "mode" "SI")])
18849 (define_insn "*rep_stosqi"
18850 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18851 (set (match_operand:SI 0 "register_operand" "=D")
18852 (plus:SI (match_operand:SI 3 "register_operand" "0")
18853 (match_operand:SI 4 "register_operand" "1")))
18854 (set (mem:BLK (match_dup 3))
18856 (use (match_operand:QI 2 "register_operand" "a"))
18857 (use (match_dup 4))]
18860 [(set_attr "type" "str")
18861 (set_attr "prefix_rep" "1")
18862 (set_attr "memory" "store")
18863 (set_attr "mode" "QI")])
18865 (define_insn "*rep_stosqi_rex64"
18866 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18867 (set (match_operand:DI 0 "register_operand" "=D")
18868 (plus:DI (match_operand:DI 3 "register_operand" "0")
18869 (match_operand:DI 4 "register_operand" "1")))
18870 (set (mem:BLK (match_dup 3))
18872 (use (match_operand:QI 2 "register_operand" "a"))
18873 (use (match_dup 4))]
18876 [(set_attr "type" "str")
18877 (set_attr "prefix_rep" "1")
18878 (set_attr "memory" "store")
18879 (set_attr "mode" "QI")])
18881 (define_expand "cmpstrnsi"
18882 [(set (match_operand:SI 0 "register_operand" "")
18883 (compare:SI (match_operand:BLK 1 "general_operand" "")
18884 (match_operand:BLK 2 "general_operand" "")))
18885 (use (match_operand 3 "general_operand" ""))
18886 (use (match_operand 4 "immediate_operand" ""))]
18887 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18889 rtx addr1, addr2, out, outlow, count, countreg, align;
18891 /* Can't use this if the user has appropriated esi or edi. */
18892 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18897 out = gen_reg_rtx (SImode);
18899 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18900 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18901 if (addr1 != XEXP (operands[1], 0))
18902 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18903 if (addr2 != XEXP (operands[2], 0))
18904 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18906 count = operands[3];
18907 countreg = ix86_zero_extend_to_Pmode (count);
18909 /* %%% Iff we are testing strict equality, we can use known alignment
18910 to good advantage. This may be possible with combine, particularly
18911 once cc0 is dead. */
18912 align = operands[4];
18914 if (CONST_INT_P (count))
18916 if (INTVAL (count) == 0)
18918 emit_move_insn (operands[0], const0_rtx);
18921 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18922 operands[1], operands[2]));
18927 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18929 emit_insn (gen_cmpsi_1 (countreg, countreg));
18930 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18931 operands[1], operands[2]));
18934 outlow = gen_lowpart (QImode, out);
18935 emit_insn (gen_cmpintqi (outlow));
18936 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18938 if (operands[0] != out)
18939 emit_move_insn (operands[0], out);
18944 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18946 (define_expand "cmpintqi"
18947 [(set (match_dup 1)
18948 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18950 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18951 (parallel [(set (match_operand:QI 0 "register_operand" "")
18952 (minus:QI (match_dup 1)
18954 (clobber (reg:CC FLAGS_REG))])]
18956 "operands[1] = gen_reg_rtx (QImode);
18957 operands[2] = gen_reg_rtx (QImode);")
18959 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18960 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18962 (define_expand "cmpstrnqi_nz_1"
18963 [(parallel [(set (reg:CC FLAGS_REG)
18964 (compare:CC (match_operand 4 "memory_operand" "")
18965 (match_operand 5 "memory_operand" "")))
18966 (use (match_operand 2 "register_operand" ""))
18967 (use (match_operand:SI 3 "immediate_operand" ""))
18968 (clobber (match_operand 0 "register_operand" ""))
18969 (clobber (match_operand 1 "register_operand" ""))
18970 (clobber (match_dup 2))])]
18974 (define_insn "*cmpstrnqi_nz_1"
18975 [(set (reg:CC FLAGS_REG)
18976 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18977 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18978 (use (match_operand:SI 6 "register_operand" "2"))
18979 (use (match_operand:SI 3 "immediate_operand" "i"))
18980 (clobber (match_operand:SI 0 "register_operand" "=S"))
18981 (clobber (match_operand:SI 1 "register_operand" "=D"))
18982 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18985 [(set_attr "type" "str")
18986 (set_attr "mode" "QI")
18987 (set_attr "prefix_rep" "1")])
18989 (define_insn "*cmpstrnqi_nz_rex_1"
18990 [(set (reg:CC FLAGS_REG)
18991 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18992 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18993 (use (match_operand:DI 6 "register_operand" "2"))
18994 (use (match_operand:SI 3 "immediate_operand" "i"))
18995 (clobber (match_operand:DI 0 "register_operand" "=S"))
18996 (clobber (match_operand:DI 1 "register_operand" "=D"))
18997 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19000 [(set_attr "type" "str")
19001 (set_attr "mode" "QI")
19002 (set_attr "prefix_rep" "1")])
19004 ;; The same, but the count is not known to not be zero.
19006 (define_expand "cmpstrnqi_1"
19007 [(parallel [(set (reg:CC FLAGS_REG)
19008 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19010 (compare:CC (match_operand 4 "memory_operand" "")
19011 (match_operand 5 "memory_operand" ""))
19013 (use (match_operand:SI 3 "immediate_operand" ""))
19014 (use (reg:CC FLAGS_REG))
19015 (clobber (match_operand 0 "register_operand" ""))
19016 (clobber (match_operand 1 "register_operand" ""))
19017 (clobber (match_dup 2))])]
19021 (define_insn "*cmpstrnqi_1"
19022 [(set (reg:CC FLAGS_REG)
19023 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19025 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19026 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19028 (use (match_operand:SI 3 "immediate_operand" "i"))
19029 (use (reg:CC FLAGS_REG))
19030 (clobber (match_operand:SI 0 "register_operand" "=S"))
19031 (clobber (match_operand:SI 1 "register_operand" "=D"))
19032 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19035 [(set_attr "type" "str")
19036 (set_attr "mode" "QI")
19037 (set_attr "prefix_rep" "1")])
19039 (define_insn "*cmpstrnqi_rex_1"
19040 [(set (reg:CC FLAGS_REG)
19041 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19043 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19044 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19046 (use (match_operand:SI 3 "immediate_operand" "i"))
19047 (use (reg:CC FLAGS_REG))
19048 (clobber (match_operand:DI 0 "register_operand" "=S"))
19049 (clobber (match_operand:DI 1 "register_operand" "=D"))
19050 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19053 [(set_attr "type" "str")
19054 (set_attr "mode" "QI")
19055 (set_attr "prefix_rep" "1")])
19057 (define_expand "strlensi"
19058 [(set (match_operand:SI 0 "register_operand" "")
19059 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19060 (match_operand:QI 2 "immediate_operand" "")
19061 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19064 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19070 (define_expand "strlendi"
19071 [(set (match_operand:DI 0 "register_operand" "")
19072 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19073 (match_operand:QI 2 "immediate_operand" "")
19074 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19077 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19083 (define_expand "strlenqi_1"
19084 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19085 (clobber (match_operand 1 "register_operand" ""))
19086 (clobber (reg:CC FLAGS_REG))])]
19090 (define_insn "*strlenqi_1"
19091 [(set (match_operand:SI 0 "register_operand" "=&c")
19092 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19093 (match_operand:QI 2 "register_operand" "a")
19094 (match_operand:SI 3 "immediate_operand" "i")
19095 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19096 (clobber (match_operand:SI 1 "register_operand" "=D"))
19097 (clobber (reg:CC FLAGS_REG))]
19100 [(set_attr "type" "str")
19101 (set_attr "mode" "QI")
19102 (set_attr "prefix_rep" "1")])
19104 (define_insn "*strlenqi_rex_1"
19105 [(set (match_operand:DI 0 "register_operand" "=&c")
19106 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19107 (match_operand:QI 2 "register_operand" "a")
19108 (match_operand:DI 3 "immediate_operand" "i")
19109 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19110 (clobber (match_operand:DI 1 "register_operand" "=D"))
19111 (clobber (reg:CC FLAGS_REG))]
19114 [(set_attr "type" "str")
19115 (set_attr "mode" "QI")
19116 (set_attr "prefix_rep" "1")])
19118 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19119 ;; handled in combine, but it is not currently up to the task.
19120 ;; When used for their truth value, the cmpstrn* expanders generate
19129 ;; The intermediate three instructions are unnecessary.
19131 ;; This one handles cmpstrn*_nz_1...
19134 (set (reg:CC FLAGS_REG)
19135 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19136 (mem:BLK (match_operand 5 "register_operand" ""))))
19137 (use (match_operand 6 "register_operand" ""))
19138 (use (match_operand:SI 3 "immediate_operand" ""))
19139 (clobber (match_operand 0 "register_operand" ""))
19140 (clobber (match_operand 1 "register_operand" ""))
19141 (clobber (match_operand 2 "register_operand" ""))])
19142 (set (match_operand:QI 7 "register_operand" "")
19143 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19144 (set (match_operand:QI 8 "register_operand" "")
19145 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19146 (set (reg FLAGS_REG)
19147 (compare (match_dup 7) (match_dup 8)))
19149 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19151 (set (reg:CC FLAGS_REG)
19152 (compare:CC (mem:BLK (match_dup 4))
19153 (mem:BLK (match_dup 5))))
19154 (use (match_dup 6))
19155 (use (match_dup 3))
19156 (clobber (match_dup 0))
19157 (clobber (match_dup 1))
19158 (clobber (match_dup 2))])]
19161 ;; ...and this one handles cmpstrn*_1.
19164 (set (reg:CC FLAGS_REG)
19165 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19167 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19168 (mem:BLK (match_operand 5 "register_operand" "")))
19170 (use (match_operand:SI 3 "immediate_operand" ""))
19171 (use (reg:CC FLAGS_REG))
19172 (clobber (match_operand 0 "register_operand" ""))
19173 (clobber (match_operand 1 "register_operand" ""))
19174 (clobber (match_operand 2 "register_operand" ""))])
19175 (set (match_operand:QI 7 "register_operand" "")
19176 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19177 (set (match_operand:QI 8 "register_operand" "")
19178 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19179 (set (reg FLAGS_REG)
19180 (compare (match_dup 7) (match_dup 8)))
19182 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19184 (set (reg:CC FLAGS_REG)
19185 (if_then_else:CC (ne (match_dup 6)
19187 (compare:CC (mem:BLK (match_dup 4))
19188 (mem:BLK (match_dup 5)))
19190 (use (match_dup 3))
19191 (use (reg:CC FLAGS_REG))
19192 (clobber (match_dup 0))
19193 (clobber (match_dup 1))
19194 (clobber (match_dup 2))])]
19199 ;; Conditional move instructions.
19201 (define_expand "movdicc"
19202 [(set (match_operand:DI 0 "register_operand" "")
19203 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19204 (match_operand:DI 2 "general_operand" "")
19205 (match_operand:DI 3 "general_operand" "")))]
19207 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19209 (define_insn "x86_movdicc_0_m1_rex64"
19210 [(set (match_operand:DI 0 "register_operand" "=r")
19211 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19214 (clobber (reg:CC FLAGS_REG))]
19217 ; Since we don't have the proper number of operands for an alu insn,
19218 ; fill in all the blanks.
19219 [(set_attr "type" "alu")
19220 (set_attr "pent_pair" "pu")
19221 (set_attr "memory" "none")
19222 (set_attr "imm_disp" "false")
19223 (set_attr "mode" "DI")
19224 (set_attr "length_immediate" "0")])
19226 (define_insn "*x86_movdicc_0_m1_se"
19227 [(set (match_operand:DI 0 "register_operand" "=r")
19228 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19231 (clobber (reg:CC FLAGS_REG))]
19234 [(set_attr "type" "alu")
19235 (set_attr "pent_pair" "pu")
19236 (set_attr "memory" "none")
19237 (set_attr "imm_disp" "false")
19238 (set_attr "mode" "DI")
19239 (set_attr "length_immediate" "0")])
19241 (define_insn "*movdicc_c_rex64"
19242 [(set (match_operand:DI 0 "register_operand" "=r,r")
19243 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19244 [(reg FLAGS_REG) (const_int 0)])
19245 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19246 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19247 "TARGET_64BIT && TARGET_CMOVE
19248 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19250 cmov%O2%C1\t{%2, %0|%0, %2}
19251 cmov%O2%c1\t{%3, %0|%0, %3}"
19252 [(set_attr "type" "icmov")
19253 (set_attr "mode" "DI")])
19255 (define_expand "movsicc"
19256 [(set (match_operand:SI 0 "register_operand" "")
19257 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19258 (match_operand:SI 2 "general_operand" "")
19259 (match_operand:SI 3 "general_operand" "")))]
19261 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19263 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19264 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19265 ;; So just document what we're doing explicitly.
19267 (define_insn "x86_movsicc_0_m1"
19268 [(set (match_operand:SI 0 "register_operand" "=r")
19269 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19272 (clobber (reg:CC FLAGS_REG))]
19275 ; Since we don't have the proper number of operands for an alu insn,
19276 ; fill in all the blanks.
19277 [(set_attr "type" "alu")
19278 (set_attr "pent_pair" "pu")
19279 (set_attr "memory" "none")
19280 (set_attr "imm_disp" "false")
19281 (set_attr "mode" "SI")
19282 (set_attr "length_immediate" "0")])
19284 (define_insn "*x86_movsicc_0_m1_se"
19285 [(set (match_operand:SI 0 "register_operand" "=r")
19286 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19289 (clobber (reg:CC FLAGS_REG))]
19292 [(set_attr "type" "alu")
19293 (set_attr "pent_pair" "pu")
19294 (set_attr "memory" "none")
19295 (set_attr "imm_disp" "false")
19296 (set_attr "mode" "SI")
19297 (set_attr "length_immediate" "0")])
19299 (define_insn "*movsicc_noc"
19300 [(set (match_operand:SI 0 "register_operand" "=r,r")
19301 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19302 [(reg FLAGS_REG) (const_int 0)])
19303 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19304 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19306 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19308 cmov%O2%C1\t{%2, %0|%0, %2}
19309 cmov%O2%c1\t{%3, %0|%0, %3}"
19310 [(set_attr "type" "icmov")
19311 (set_attr "mode" "SI")])
19313 (define_expand "movhicc"
19314 [(set (match_operand:HI 0 "register_operand" "")
19315 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19316 (match_operand:HI 2 "general_operand" "")
19317 (match_operand:HI 3 "general_operand" "")))]
19318 "TARGET_HIMODE_MATH"
19319 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19321 (define_insn "*movhicc_noc"
19322 [(set (match_operand:HI 0 "register_operand" "=r,r")
19323 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19324 [(reg FLAGS_REG) (const_int 0)])
19325 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19326 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19328 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19330 cmov%O2%C1\t{%2, %0|%0, %2}
19331 cmov%O2%c1\t{%3, %0|%0, %3}"
19332 [(set_attr "type" "icmov")
19333 (set_attr "mode" "HI")])
19335 (define_expand "movqicc"
19336 [(set (match_operand:QI 0 "register_operand" "")
19337 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19338 (match_operand:QI 2 "general_operand" "")
19339 (match_operand:QI 3 "general_operand" "")))]
19340 "TARGET_QIMODE_MATH"
19341 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19343 (define_insn_and_split "*movqicc_noc"
19344 [(set (match_operand:QI 0 "register_operand" "=r,r")
19345 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19346 [(match_operand 4 "flags_reg_operand" "")
19348 (match_operand:QI 2 "register_operand" "r,0")
19349 (match_operand:QI 3 "register_operand" "0,r")))]
19350 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19352 "&& reload_completed"
19353 [(set (match_dup 0)
19354 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19357 "operands[0] = gen_lowpart (SImode, operands[0]);
19358 operands[2] = gen_lowpart (SImode, operands[2]);
19359 operands[3] = gen_lowpart (SImode, operands[3]);"
19360 [(set_attr "type" "icmov")
19361 (set_attr "mode" "SI")])
19363 (define_expand "mov<mode>cc"
19364 [(set (match_operand:X87MODEF 0 "register_operand" "")
19365 (if_then_else:X87MODEF
19366 (match_operand 1 "comparison_operator" "")
19367 (match_operand:X87MODEF 2 "register_operand" "")
19368 (match_operand:X87MODEF 3 "register_operand" "")))]
19369 "(TARGET_80387 && TARGET_CMOVE)
19370 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19371 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19373 (define_insn "*movsfcc_1_387"
19374 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19375 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19376 [(reg FLAGS_REG) (const_int 0)])
19377 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19378 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19379 "TARGET_80387 && TARGET_CMOVE
19380 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19382 fcmov%F1\t{%2, %0|%0, %2}
19383 fcmov%f1\t{%3, %0|%0, %3}
19384 cmov%O2%C1\t{%2, %0|%0, %2}
19385 cmov%O2%c1\t{%3, %0|%0, %3}"
19386 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19387 (set_attr "mode" "SF,SF,SI,SI")])
19389 (define_insn "*movdfcc_1"
19390 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19391 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19392 [(reg FLAGS_REG) (const_int 0)])
19393 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19394 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19395 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19396 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19398 fcmov%F1\t{%2, %0|%0, %2}
19399 fcmov%f1\t{%3, %0|%0, %3}
19402 [(set_attr "type" "fcmov,fcmov,multi,multi")
19403 (set_attr "mode" "DF")])
19405 (define_insn "*movdfcc_1_rex64"
19406 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19407 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19408 [(reg FLAGS_REG) (const_int 0)])
19409 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19410 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19411 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19412 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19414 fcmov%F1\t{%2, %0|%0, %2}
19415 fcmov%f1\t{%3, %0|%0, %3}
19416 cmov%O2%C1\t{%2, %0|%0, %2}
19417 cmov%O2%c1\t{%3, %0|%0, %3}"
19418 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19419 (set_attr "mode" "DF")])
19422 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19423 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19424 [(match_operand 4 "flags_reg_operand" "")
19426 (match_operand:DF 2 "nonimmediate_operand" "")
19427 (match_operand:DF 3 "nonimmediate_operand" "")))]
19428 "!TARGET_64BIT && reload_completed"
19429 [(set (match_dup 2)
19430 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19434 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19437 "split_di (operands+2, 1, operands+5, operands+6);
19438 split_di (operands+3, 1, operands+7, operands+8);
19439 split_di (operands, 1, operands+2, operands+3);")
19441 (define_insn "*movxfcc_1"
19442 [(set (match_operand:XF 0 "register_operand" "=f,f")
19443 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19444 [(reg FLAGS_REG) (const_int 0)])
19445 (match_operand:XF 2 "register_operand" "f,0")
19446 (match_operand:XF 3 "register_operand" "0,f")))]
19447 "TARGET_80387 && TARGET_CMOVE"
19449 fcmov%F1\t{%2, %0|%0, %2}
19450 fcmov%f1\t{%3, %0|%0, %3}"
19451 [(set_attr "type" "fcmov")
19452 (set_attr "mode" "XF")])
19454 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19455 ;; the scalar versions to have only XMM registers as operands.
19457 ;; SSE5 conditional move
19458 (define_insn "*sse5_pcmov_<mode>"
19459 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19460 (if_then_else:MODEF
19461 (match_operand:MODEF 1 "register_operand" "x,0")
19462 (match_operand:MODEF 2 "register_operand" "0,x")
19463 (match_operand:MODEF 3 "register_operand" "x,x")))]
19464 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19465 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19466 [(set_attr "type" "sse4arg")])
19468 ;; These versions of the min/max patterns are intentionally ignorant of
19469 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19470 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19471 ;; are undefined in this condition, we're certain this is correct.
19473 (define_insn "<code><mode>3"
19474 [(set (match_operand:MODEF 0 "register_operand" "=x")
19476 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19477 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19478 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19479 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19480 [(set_attr "type" "sseadd")
19481 (set_attr "mode" "<MODE>")])
19483 ;; These versions of the min/max patterns implement exactly the operations
19484 ;; min = (op1 < op2 ? op1 : op2)
19485 ;; max = (!(op1 < op2) ? op1 : op2)
19486 ;; Their operands are not commutative, and thus they may be used in the
19487 ;; presence of -0.0 and NaN.
19489 (define_insn "*ieee_smin<mode>3"
19490 [(set (match_operand:MODEF 0 "register_operand" "=x")
19492 [(match_operand:MODEF 1 "register_operand" "0")
19493 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19495 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19496 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19497 [(set_attr "type" "sseadd")
19498 (set_attr "mode" "<MODE>")])
19500 (define_insn "*ieee_smax<mode>3"
19501 [(set (match_operand:MODEF 0 "register_operand" "=x")
19503 [(match_operand:MODEF 1 "register_operand" "0")
19504 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19506 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19507 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19508 [(set_attr "type" "sseadd")
19509 (set_attr "mode" "<MODE>")])
19511 ;; Make two stack loads independent:
19513 ;; fld %st(0) -> fld bb
19514 ;; fmul bb fmul %st(1), %st
19516 ;; Actually we only match the last two instructions for simplicity.
19518 [(set (match_operand 0 "fp_register_operand" "")
19519 (match_operand 1 "fp_register_operand" ""))
19521 (match_operator 2 "binary_fp_operator"
19523 (match_operand 3 "memory_operand" "")]))]
19524 "REGNO (operands[0]) != REGNO (operands[1])"
19525 [(set (match_dup 0) (match_dup 3))
19526 (set (match_dup 0) (match_dup 4))]
19528 ;; The % modifier is not operational anymore in peephole2's, so we have to
19529 ;; swap the operands manually in the case of addition and multiplication.
19530 "if (COMMUTATIVE_ARITH_P (operands[2]))
19531 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19532 operands[0], operands[1]);
19534 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19535 operands[1], operands[0]);")
19537 ;; Conditional addition patterns
19538 (define_expand "addqicc"
19539 [(match_operand:QI 0 "register_operand" "")
19540 (match_operand 1 "comparison_operator" "")
19541 (match_operand:QI 2 "register_operand" "")
19542 (match_operand:QI 3 "const_int_operand" "")]
19544 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19546 (define_expand "addhicc"
19547 [(match_operand:HI 0 "register_operand" "")
19548 (match_operand 1 "comparison_operator" "")
19549 (match_operand:HI 2 "register_operand" "")
19550 (match_operand:HI 3 "const_int_operand" "")]
19552 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19554 (define_expand "addsicc"
19555 [(match_operand:SI 0 "register_operand" "")
19556 (match_operand 1 "comparison_operator" "")
19557 (match_operand:SI 2 "register_operand" "")
19558 (match_operand:SI 3 "const_int_operand" "")]
19560 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19562 (define_expand "adddicc"
19563 [(match_operand:DI 0 "register_operand" "")
19564 (match_operand 1 "comparison_operator" "")
19565 (match_operand:DI 2 "register_operand" "")
19566 (match_operand:DI 3 "const_int_operand" "")]
19568 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19571 ;; Misc patterns (?)
19573 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19574 ;; Otherwise there will be nothing to keep
19576 ;; [(set (reg ebp) (reg esp))]
19577 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19578 ;; (clobber (eflags)]
19579 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19581 ;; in proper program order.
19582 (define_insn "pro_epilogue_adjust_stack_1"
19583 [(set (match_operand:SI 0 "register_operand" "=r,r")
19584 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19585 (match_operand:SI 2 "immediate_operand" "i,i")))
19586 (clobber (reg:CC FLAGS_REG))
19587 (clobber (mem:BLK (scratch)))]
19590 switch (get_attr_type (insn))
19593 return "mov{l}\t{%1, %0|%0, %1}";
19596 if (CONST_INT_P (operands[2])
19597 && (INTVAL (operands[2]) == 128
19598 || (INTVAL (operands[2]) < 0
19599 && INTVAL (operands[2]) != -128)))
19601 operands[2] = GEN_INT (-INTVAL (operands[2]));
19602 return "sub{l}\t{%2, %0|%0, %2}";
19604 return "add{l}\t{%2, %0|%0, %2}";
19607 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19608 return "lea{l}\t{%a2, %0|%0, %a2}";
19611 gcc_unreachable ();
19614 [(set (attr "type")
19615 (cond [(eq_attr "alternative" "0")
19616 (const_string "alu")
19617 (match_operand:SI 2 "const0_operand" "")
19618 (const_string "imov")
19620 (const_string "lea")))
19621 (set_attr "mode" "SI")])
19623 (define_insn "pro_epilogue_adjust_stack_rex64"
19624 [(set (match_operand:DI 0 "register_operand" "=r,r")
19625 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19626 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19627 (clobber (reg:CC FLAGS_REG))
19628 (clobber (mem:BLK (scratch)))]
19631 switch (get_attr_type (insn))
19634 return "mov{q}\t{%1, %0|%0, %1}";
19637 if (CONST_INT_P (operands[2])
19638 /* Avoid overflows. */
19639 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19640 && (INTVAL (operands[2]) == 128
19641 || (INTVAL (operands[2]) < 0
19642 && INTVAL (operands[2]) != -128)))
19644 operands[2] = GEN_INT (-INTVAL (operands[2]));
19645 return "sub{q}\t{%2, %0|%0, %2}";
19647 return "add{q}\t{%2, %0|%0, %2}";
19650 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19651 return "lea{q}\t{%a2, %0|%0, %a2}";
19654 gcc_unreachable ();
19657 [(set (attr "type")
19658 (cond [(eq_attr "alternative" "0")
19659 (const_string "alu")
19660 (match_operand:DI 2 "const0_operand" "")
19661 (const_string "imov")
19663 (const_string "lea")))
19664 (set_attr "mode" "DI")])
19666 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19667 [(set (match_operand:DI 0 "register_operand" "=r,r")
19668 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19669 (match_operand:DI 3 "immediate_operand" "i,i")))
19670 (use (match_operand:DI 2 "register_operand" "r,r"))
19671 (clobber (reg:CC FLAGS_REG))
19672 (clobber (mem:BLK (scratch)))]
19675 switch (get_attr_type (insn))
19678 return "add{q}\t{%2, %0|%0, %2}";
19681 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19682 return "lea{q}\t{%a2, %0|%0, %a2}";
19685 gcc_unreachable ();
19688 [(set_attr "type" "alu,lea")
19689 (set_attr "mode" "DI")])
19691 (define_insn "allocate_stack_worker_32"
19692 [(set (match_operand:SI 0 "register_operand" "+a")
19693 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19694 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19695 (clobber (reg:CC FLAGS_REG))]
19696 "!TARGET_64BIT && TARGET_STACK_PROBE"
19698 [(set_attr "type" "multi")
19699 (set_attr "length" "5")])
19701 (define_insn "allocate_stack_worker_64"
19702 [(set (match_operand:DI 0 "register_operand" "=a")
19703 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19704 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19705 (clobber (reg:DI R10_REG))
19706 (clobber (reg:DI R11_REG))
19707 (clobber (reg:CC FLAGS_REG))]
19708 "TARGET_64BIT && TARGET_STACK_PROBE"
19710 [(set_attr "type" "multi")
19711 (set_attr "length" "5")])
19713 (define_expand "allocate_stack"
19714 [(match_operand 0 "register_operand" "")
19715 (match_operand 1 "general_operand" "")]
19716 "TARGET_STACK_PROBE"
19720 #ifndef CHECK_STACK_LIMIT
19721 #define CHECK_STACK_LIMIT 0
19724 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19725 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19727 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19728 stack_pointer_rtx, 0, OPTAB_DIRECT);
19729 if (x != stack_pointer_rtx)
19730 emit_move_insn (stack_pointer_rtx, x);
19734 x = copy_to_mode_reg (Pmode, operands[1]);
19736 x = gen_allocate_stack_worker_64 (x);
19738 x = gen_allocate_stack_worker_32 (x);
19742 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19746 (define_expand "builtin_setjmp_receiver"
19747 [(label_ref (match_operand 0 "" ""))]
19748 "!TARGET_64BIT && flag_pic"
19753 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19754 rtx label_rtx = gen_label_rtx ();
19755 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19756 xops[0] = xops[1] = picreg;
19757 xops[2] = gen_rtx_CONST (SImode,
19758 gen_rtx_MINUS (SImode,
19759 gen_rtx_LABEL_REF (SImode, label_rtx),
19760 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19761 ix86_expand_binary_operator (MINUS, SImode, xops);
19764 emit_insn (gen_set_got (pic_offset_table_rtx));
19768 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19771 [(set (match_operand 0 "register_operand" "")
19772 (match_operator 3 "promotable_binary_operator"
19773 [(match_operand 1 "register_operand" "")
19774 (match_operand 2 "aligned_operand" "")]))
19775 (clobber (reg:CC FLAGS_REG))]
19776 "! TARGET_PARTIAL_REG_STALL && reload_completed
19777 && ((GET_MODE (operands[0]) == HImode
19778 && ((!optimize_size && !TARGET_FAST_PREFIX)
19779 /* ??? next two lines just !satisfies_constraint_K (...) */
19780 || !CONST_INT_P (operands[2])
19781 || satisfies_constraint_K (operands[2])))
19782 || (GET_MODE (operands[0]) == QImode
19783 && (TARGET_PROMOTE_QImode || optimize_size)))"
19784 [(parallel [(set (match_dup 0)
19785 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19786 (clobber (reg:CC FLAGS_REG))])]
19787 "operands[0] = gen_lowpart (SImode, operands[0]);
19788 operands[1] = gen_lowpart (SImode, operands[1]);
19789 if (GET_CODE (operands[3]) != ASHIFT)
19790 operands[2] = gen_lowpart (SImode, operands[2]);
19791 PUT_MODE (operands[3], SImode);")
19793 ; Promote the QImode tests, as i386 has encoding of the AND
19794 ; instruction with 32-bit sign-extended immediate and thus the
19795 ; instruction size is unchanged, except in the %eax case for
19796 ; which it is increased by one byte, hence the ! optimize_size.
19798 [(set (match_operand 0 "flags_reg_operand" "")
19799 (match_operator 2 "compare_operator"
19800 [(and (match_operand 3 "aligned_operand" "")
19801 (match_operand 4 "const_int_operand" ""))
19803 (set (match_operand 1 "register_operand" "")
19804 (and (match_dup 3) (match_dup 4)))]
19805 "! TARGET_PARTIAL_REG_STALL && reload_completed
19807 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19808 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19809 /* Ensure that the operand will remain sign-extended immediate. */
19810 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19811 [(parallel [(set (match_dup 0)
19812 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19815 (and:SI (match_dup 3) (match_dup 4)))])]
19818 = gen_int_mode (INTVAL (operands[4])
19819 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19820 operands[1] = gen_lowpart (SImode, operands[1]);
19821 operands[3] = gen_lowpart (SImode, operands[3]);
19824 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19825 ; the TEST instruction with 32-bit sign-extended immediate and thus
19826 ; the instruction size would at least double, which is not what we
19827 ; want even with ! optimize_size.
19829 [(set (match_operand 0 "flags_reg_operand" "")
19830 (match_operator 1 "compare_operator"
19831 [(and (match_operand:HI 2 "aligned_operand" "")
19832 (match_operand:HI 3 "const_int_operand" ""))
19834 "! TARGET_PARTIAL_REG_STALL && reload_completed
19835 && ! TARGET_FAST_PREFIX
19837 /* Ensure that the operand will remain sign-extended immediate. */
19838 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19839 [(set (match_dup 0)
19840 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19844 = gen_int_mode (INTVAL (operands[3])
19845 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19846 operands[2] = gen_lowpart (SImode, operands[2]);
19850 [(set (match_operand 0 "register_operand" "")
19851 (neg (match_operand 1 "register_operand" "")))
19852 (clobber (reg:CC FLAGS_REG))]
19853 "! TARGET_PARTIAL_REG_STALL && reload_completed
19854 && (GET_MODE (operands[0]) == HImode
19855 || (GET_MODE (operands[0]) == QImode
19856 && (TARGET_PROMOTE_QImode || optimize_size)))"
19857 [(parallel [(set (match_dup 0)
19858 (neg:SI (match_dup 1)))
19859 (clobber (reg:CC FLAGS_REG))])]
19860 "operands[0] = gen_lowpart (SImode, operands[0]);
19861 operands[1] = gen_lowpart (SImode, operands[1]);")
19864 [(set (match_operand 0 "register_operand" "")
19865 (not (match_operand 1 "register_operand" "")))]
19866 "! TARGET_PARTIAL_REG_STALL && reload_completed
19867 && (GET_MODE (operands[0]) == HImode
19868 || (GET_MODE (operands[0]) == QImode
19869 && (TARGET_PROMOTE_QImode || optimize_size)))"
19870 [(set (match_dup 0)
19871 (not:SI (match_dup 1)))]
19872 "operands[0] = gen_lowpart (SImode, operands[0]);
19873 operands[1] = gen_lowpart (SImode, operands[1]);")
19876 [(set (match_operand 0 "register_operand" "")
19877 (if_then_else (match_operator 1 "comparison_operator"
19878 [(reg FLAGS_REG) (const_int 0)])
19879 (match_operand 2 "register_operand" "")
19880 (match_operand 3 "register_operand" "")))]
19881 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19882 && (GET_MODE (operands[0]) == HImode
19883 || (GET_MODE (operands[0]) == QImode
19884 && (TARGET_PROMOTE_QImode || optimize_size)))"
19885 [(set (match_dup 0)
19886 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19887 "operands[0] = gen_lowpart (SImode, operands[0]);
19888 operands[2] = gen_lowpart (SImode, operands[2]);
19889 operands[3] = gen_lowpart (SImode, operands[3]);")
19892 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19893 ;; transform a complex memory operation into two memory to register operations.
19895 ;; Don't push memory operands
19897 [(set (match_operand:SI 0 "push_operand" "")
19898 (match_operand:SI 1 "memory_operand" ""))
19899 (match_scratch:SI 2 "r")]
19900 "!optimize_size && !TARGET_PUSH_MEMORY
19901 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19902 [(set (match_dup 2) (match_dup 1))
19903 (set (match_dup 0) (match_dup 2))]
19907 [(set (match_operand:DI 0 "push_operand" "")
19908 (match_operand:DI 1 "memory_operand" ""))
19909 (match_scratch:DI 2 "r")]
19910 "!optimize_size && !TARGET_PUSH_MEMORY
19911 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19912 [(set (match_dup 2) (match_dup 1))
19913 (set (match_dup 0) (match_dup 2))]
19916 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19919 [(set (match_operand:SF 0 "push_operand" "")
19920 (match_operand:SF 1 "memory_operand" ""))
19921 (match_scratch:SF 2 "r")]
19922 "!optimize_size && !TARGET_PUSH_MEMORY
19923 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19924 [(set (match_dup 2) (match_dup 1))
19925 (set (match_dup 0) (match_dup 2))]
19929 [(set (match_operand:HI 0 "push_operand" "")
19930 (match_operand:HI 1 "memory_operand" ""))
19931 (match_scratch:HI 2 "r")]
19932 "!optimize_size && !TARGET_PUSH_MEMORY
19933 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19934 [(set (match_dup 2) (match_dup 1))
19935 (set (match_dup 0) (match_dup 2))]
19939 [(set (match_operand:QI 0 "push_operand" "")
19940 (match_operand:QI 1 "memory_operand" ""))
19941 (match_scratch:QI 2 "q")]
19942 "!optimize_size && !TARGET_PUSH_MEMORY
19943 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19944 [(set (match_dup 2) (match_dup 1))
19945 (set (match_dup 0) (match_dup 2))]
19948 ;; Don't move an immediate directly to memory when the instruction
19951 [(match_scratch:SI 1 "r")
19952 (set (match_operand:SI 0 "memory_operand" "")
19955 && ! TARGET_USE_MOV0
19956 && TARGET_SPLIT_LONG_MOVES
19957 && get_attr_length (insn) >= ix86_cost->large_insn
19958 && peep2_regno_dead_p (0, FLAGS_REG)"
19959 [(parallel [(set (match_dup 1) (const_int 0))
19960 (clobber (reg:CC FLAGS_REG))])
19961 (set (match_dup 0) (match_dup 1))]
19965 [(match_scratch:HI 1 "r")
19966 (set (match_operand:HI 0 "memory_operand" "")
19969 && ! TARGET_USE_MOV0
19970 && TARGET_SPLIT_LONG_MOVES
19971 && get_attr_length (insn) >= ix86_cost->large_insn
19972 && peep2_regno_dead_p (0, FLAGS_REG)"
19973 [(parallel [(set (match_dup 2) (const_int 0))
19974 (clobber (reg:CC FLAGS_REG))])
19975 (set (match_dup 0) (match_dup 1))]
19976 "operands[2] = gen_lowpart (SImode, operands[1]);")
19979 [(match_scratch:QI 1 "q")
19980 (set (match_operand:QI 0 "memory_operand" "")
19983 && ! TARGET_USE_MOV0
19984 && TARGET_SPLIT_LONG_MOVES
19985 && get_attr_length (insn) >= ix86_cost->large_insn
19986 && peep2_regno_dead_p (0, FLAGS_REG)"
19987 [(parallel [(set (match_dup 2) (const_int 0))
19988 (clobber (reg:CC FLAGS_REG))])
19989 (set (match_dup 0) (match_dup 1))]
19990 "operands[2] = gen_lowpart (SImode, operands[1]);")
19993 [(match_scratch:SI 2 "r")
19994 (set (match_operand:SI 0 "memory_operand" "")
19995 (match_operand:SI 1 "immediate_operand" ""))]
19997 && TARGET_SPLIT_LONG_MOVES
19998 && get_attr_length (insn) >= ix86_cost->large_insn"
19999 [(set (match_dup 2) (match_dup 1))
20000 (set (match_dup 0) (match_dup 2))]
20004 [(match_scratch:HI 2 "r")
20005 (set (match_operand:HI 0 "memory_operand" "")
20006 (match_operand:HI 1 "immediate_operand" ""))]
20008 && TARGET_SPLIT_LONG_MOVES
20009 && get_attr_length (insn) >= ix86_cost->large_insn"
20010 [(set (match_dup 2) (match_dup 1))
20011 (set (match_dup 0) (match_dup 2))]
20015 [(match_scratch:QI 2 "q")
20016 (set (match_operand:QI 0 "memory_operand" "")
20017 (match_operand:QI 1 "immediate_operand" ""))]
20019 && TARGET_SPLIT_LONG_MOVES
20020 && get_attr_length (insn) >= ix86_cost->large_insn"
20021 [(set (match_dup 2) (match_dup 1))
20022 (set (match_dup 0) (match_dup 2))]
20025 ;; Don't compare memory with zero, load and use a test instead.
20027 [(set (match_operand 0 "flags_reg_operand" "")
20028 (match_operator 1 "compare_operator"
20029 [(match_operand:SI 2 "memory_operand" "")
20031 (match_scratch:SI 3 "r")]
20032 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20033 [(set (match_dup 3) (match_dup 2))
20034 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20037 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20038 ;; Don't split NOTs with a displacement operand, because resulting XOR
20039 ;; will not be pairable anyway.
20041 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20042 ;; represented using a modRM byte. The XOR replacement is long decoded,
20043 ;; so this split helps here as well.
20045 ;; Note: Can't do this as a regular split because we can't get proper
20046 ;; lifetime information then.
20049 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20050 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20052 && ((TARGET_NOT_UNPAIRABLE
20053 && (!MEM_P (operands[0])
20054 || !memory_displacement_operand (operands[0], SImode)))
20055 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20056 && peep2_regno_dead_p (0, FLAGS_REG)"
20057 [(parallel [(set (match_dup 0)
20058 (xor:SI (match_dup 1) (const_int -1)))
20059 (clobber (reg:CC FLAGS_REG))])]
20063 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20064 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20066 && ((TARGET_NOT_UNPAIRABLE
20067 && (!MEM_P (operands[0])
20068 || !memory_displacement_operand (operands[0], HImode)))
20069 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20070 && peep2_regno_dead_p (0, FLAGS_REG)"
20071 [(parallel [(set (match_dup 0)
20072 (xor:HI (match_dup 1) (const_int -1)))
20073 (clobber (reg:CC FLAGS_REG))])]
20077 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20078 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20080 && ((TARGET_NOT_UNPAIRABLE
20081 && (!MEM_P (operands[0])
20082 || !memory_displacement_operand (operands[0], QImode)))
20083 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20084 && peep2_regno_dead_p (0, FLAGS_REG)"
20085 [(parallel [(set (match_dup 0)
20086 (xor:QI (match_dup 1) (const_int -1)))
20087 (clobber (reg:CC FLAGS_REG))])]
20090 ;; Non pairable "test imm, reg" instructions can be translated to
20091 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20092 ;; byte opcode instead of two, have a short form for byte operands),
20093 ;; so do it for other CPUs as well. Given that the value was dead,
20094 ;; this should not create any new dependencies. Pass on the sub-word
20095 ;; versions if we're concerned about partial register stalls.
20098 [(set (match_operand 0 "flags_reg_operand" "")
20099 (match_operator 1 "compare_operator"
20100 [(and:SI (match_operand:SI 2 "register_operand" "")
20101 (match_operand:SI 3 "immediate_operand" ""))
20103 "ix86_match_ccmode (insn, CCNOmode)
20104 && (true_regnum (operands[2]) != AX_REG
20105 || satisfies_constraint_K (operands[3]))
20106 && peep2_reg_dead_p (1, operands[2])"
20108 [(set (match_dup 0)
20109 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20112 (and:SI (match_dup 2) (match_dup 3)))])]
20115 ;; We don't need to handle HImode case, because it will be promoted to SImode
20116 ;; on ! TARGET_PARTIAL_REG_STALL
20119 [(set (match_operand 0 "flags_reg_operand" "")
20120 (match_operator 1 "compare_operator"
20121 [(and:QI (match_operand:QI 2 "register_operand" "")
20122 (match_operand:QI 3 "immediate_operand" ""))
20124 "! TARGET_PARTIAL_REG_STALL
20125 && ix86_match_ccmode (insn, CCNOmode)
20126 && true_regnum (operands[2]) != AX_REG
20127 && peep2_reg_dead_p (1, operands[2])"
20129 [(set (match_dup 0)
20130 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20133 (and:QI (match_dup 2) (match_dup 3)))])]
20137 [(set (match_operand 0 "flags_reg_operand" "")
20138 (match_operator 1 "compare_operator"
20141 (match_operand 2 "ext_register_operand" "")
20144 (match_operand 3 "const_int_operand" ""))
20146 "! TARGET_PARTIAL_REG_STALL
20147 && ix86_match_ccmode (insn, CCNOmode)
20148 && true_regnum (operands[2]) != AX_REG
20149 && peep2_reg_dead_p (1, operands[2])"
20150 [(parallel [(set (match_dup 0)
20159 (set (zero_extract:SI (match_dup 2)
20170 ;; Don't do logical operations with memory inputs.
20172 [(match_scratch:SI 2 "r")
20173 (parallel [(set (match_operand:SI 0 "register_operand" "")
20174 (match_operator:SI 3 "arith_or_logical_operator"
20176 (match_operand:SI 1 "memory_operand" "")]))
20177 (clobber (reg:CC FLAGS_REG))])]
20178 "! optimize_size && ! TARGET_READ_MODIFY"
20179 [(set (match_dup 2) (match_dup 1))
20180 (parallel [(set (match_dup 0)
20181 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20182 (clobber (reg:CC FLAGS_REG))])]
20186 [(match_scratch:SI 2 "r")
20187 (parallel [(set (match_operand:SI 0 "register_operand" "")
20188 (match_operator:SI 3 "arith_or_logical_operator"
20189 [(match_operand:SI 1 "memory_operand" "")
20191 (clobber (reg:CC FLAGS_REG))])]
20192 "! optimize_size && ! TARGET_READ_MODIFY"
20193 [(set (match_dup 2) (match_dup 1))
20194 (parallel [(set (match_dup 0)
20195 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20196 (clobber (reg:CC FLAGS_REG))])]
20199 ; Don't do logical operations with memory outputs
20201 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20202 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20203 ; the same decoder scheduling characteristics as the original.
20206 [(match_scratch:SI 2 "r")
20207 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20208 (match_operator:SI 3 "arith_or_logical_operator"
20210 (match_operand:SI 1 "nonmemory_operand" "")]))
20211 (clobber (reg:CC FLAGS_REG))])]
20212 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20213 [(set (match_dup 2) (match_dup 0))
20214 (parallel [(set (match_dup 2)
20215 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20216 (clobber (reg:CC FLAGS_REG))])
20217 (set (match_dup 0) (match_dup 2))]
20221 [(match_scratch:SI 2 "r")
20222 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20223 (match_operator:SI 3 "arith_or_logical_operator"
20224 [(match_operand:SI 1 "nonmemory_operand" "")
20226 (clobber (reg:CC FLAGS_REG))])]
20227 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20228 [(set (match_dup 2) (match_dup 0))
20229 (parallel [(set (match_dup 2)
20230 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20231 (clobber (reg:CC FLAGS_REG))])
20232 (set (match_dup 0) (match_dup 2))]
20235 ;; Attempt to always use XOR for zeroing registers.
20237 [(set (match_operand 0 "register_operand" "")
20238 (match_operand 1 "const0_operand" ""))]
20239 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20240 && (! TARGET_USE_MOV0 || optimize_size)
20241 && GENERAL_REG_P (operands[0])
20242 && peep2_regno_dead_p (0, FLAGS_REG)"
20243 [(parallel [(set (match_dup 0) (const_int 0))
20244 (clobber (reg:CC FLAGS_REG))])]
20246 operands[0] = gen_lowpart (word_mode, operands[0]);
20250 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20252 "(GET_MODE (operands[0]) == QImode
20253 || GET_MODE (operands[0]) == HImode)
20254 && (! TARGET_USE_MOV0 || optimize_size)
20255 && peep2_regno_dead_p (0, FLAGS_REG)"
20256 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20257 (clobber (reg:CC FLAGS_REG))])])
20259 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20261 [(set (match_operand 0 "register_operand" "")
20263 "(GET_MODE (operands[0]) == HImode
20264 || GET_MODE (operands[0]) == SImode
20265 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20266 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20267 && peep2_regno_dead_p (0, FLAGS_REG)"
20268 [(parallel [(set (match_dup 0) (const_int -1))
20269 (clobber (reg:CC FLAGS_REG))])]
20270 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20273 ;; Attempt to convert simple leas to adds. These can be created by
20276 [(set (match_operand:SI 0 "register_operand" "")
20277 (plus:SI (match_dup 0)
20278 (match_operand:SI 1 "nonmemory_operand" "")))]
20279 "peep2_regno_dead_p (0, FLAGS_REG)"
20280 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20281 (clobber (reg:CC FLAGS_REG))])]
20285 [(set (match_operand:SI 0 "register_operand" "")
20286 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20287 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20288 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20289 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20290 (clobber (reg:CC FLAGS_REG))])]
20291 "operands[2] = gen_lowpart (SImode, operands[2]);")
20294 [(set (match_operand:DI 0 "register_operand" "")
20295 (plus:DI (match_dup 0)
20296 (match_operand:DI 1 "x86_64_general_operand" "")))]
20297 "peep2_regno_dead_p (0, FLAGS_REG)"
20298 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20299 (clobber (reg:CC FLAGS_REG))])]
20303 [(set (match_operand:SI 0 "register_operand" "")
20304 (mult:SI (match_dup 0)
20305 (match_operand:SI 1 "const_int_operand" "")))]
20306 "exact_log2 (INTVAL (operands[1])) >= 0
20307 && peep2_regno_dead_p (0, FLAGS_REG)"
20308 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20309 (clobber (reg:CC FLAGS_REG))])]
20310 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20313 [(set (match_operand:DI 0 "register_operand" "")
20314 (mult:DI (match_dup 0)
20315 (match_operand:DI 1 "const_int_operand" "")))]
20316 "exact_log2 (INTVAL (operands[1])) >= 0
20317 && peep2_regno_dead_p (0, FLAGS_REG)"
20318 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20319 (clobber (reg:CC FLAGS_REG))])]
20320 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20323 [(set (match_operand:SI 0 "register_operand" "")
20324 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20325 (match_operand:DI 2 "const_int_operand" "")) 0))]
20326 "exact_log2 (INTVAL (operands[2])) >= 0
20327 && REGNO (operands[0]) == REGNO (operands[1])
20328 && peep2_regno_dead_p (0, FLAGS_REG)"
20329 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20330 (clobber (reg:CC FLAGS_REG))])]
20331 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20333 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20334 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20335 ;; many CPUs it is also faster, since special hardware to avoid esp
20336 ;; dependencies is present.
20338 ;; While some of these conversions may be done using splitters, we use peepholes
20339 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20341 ;; Convert prologue esp subtractions to push.
20342 ;; We need register to push. In order to keep verify_flow_info happy we have
20344 ;; - use scratch and clobber it in order to avoid dependencies
20345 ;; - use already live register
20346 ;; We can't use the second way right now, since there is no reliable way how to
20347 ;; verify that given register is live. First choice will also most likely in
20348 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20349 ;; call clobbered registers are dead. We may want to use base pointer as an
20350 ;; alternative when no register is available later.
20353 [(match_scratch:SI 0 "r")
20354 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20355 (clobber (reg:CC FLAGS_REG))
20356 (clobber (mem:BLK (scratch)))])]
20357 "optimize_size || !TARGET_SUB_ESP_4"
20358 [(clobber (match_dup 0))
20359 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20360 (clobber (mem:BLK (scratch)))])])
20363 [(match_scratch:SI 0 "r")
20364 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20365 (clobber (reg:CC FLAGS_REG))
20366 (clobber (mem:BLK (scratch)))])]
20367 "optimize_size || !TARGET_SUB_ESP_8"
20368 [(clobber (match_dup 0))
20369 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20370 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20371 (clobber (mem:BLK (scratch)))])])
20373 ;; Convert esp subtractions to push.
20375 [(match_scratch:SI 0 "r")
20376 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20377 (clobber (reg:CC FLAGS_REG))])]
20378 "optimize_size || !TARGET_SUB_ESP_4"
20379 [(clobber (match_dup 0))
20380 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20383 [(match_scratch:SI 0 "r")
20384 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20385 (clobber (reg:CC FLAGS_REG))])]
20386 "optimize_size || !TARGET_SUB_ESP_8"
20387 [(clobber (match_dup 0))
20388 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20389 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20391 ;; Convert epilogue deallocator to pop.
20393 [(match_scratch:SI 0 "r")
20394 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20395 (clobber (reg:CC FLAGS_REG))
20396 (clobber (mem:BLK (scratch)))])]
20397 "optimize_size || !TARGET_ADD_ESP_4"
20398 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20399 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20400 (clobber (mem:BLK (scratch)))])]
20403 ;; Two pops case is tricky, since pop causes dependency on destination register.
20404 ;; We use two registers if available.
20406 [(match_scratch:SI 0 "r")
20407 (match_scratch:SI 1 "r")
20408 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20409 (clobber (reg:CC FLAGS_REG))
20410 (clobber (mem:BLK (scratch)))])]
20411 "optimize_size || !TARGET_ADD_ESP_8"
20412 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20414 (clobber (mem:BLK (scratch)))])
20415 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20416 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20420 [(match_scratch:SI 0 "r")
20421 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20422 (clobber (reg:CC FLAGS_REG))
20423 (clobber (mem:BLK (scratch)))])]
20425 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20426 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20427 (clobber (mem:BLK (scratch)))])
20428 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20429 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20432 ;; Convert esp additions to pop.
20434 [(match_scratch:SI 0 "r")
20435 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20436 (clobber (reg:CC FLAGS_REG))])]
20438 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20439 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20442 ;; Two pops case is tricky, since pop causes dependency on destination register.
20443 ;; We use two registers if available.
20445 [(match_scratch:SI 0 "r")
20446 (match_scratch:SI 1 "r")
20447 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20448 (clobber (reg:CC FLAGS_REG))])]
20450 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20451 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20452 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20453 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20457 [(match_scratch:SI 0 "r")
20458 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20459 (clobber (reg:CC FLAGS_REG))])]
20461 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20462 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20463 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20464 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20467 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20468 ;; required and register dies. Similarly for 128 to plus -128.
20470 [(set (match_operand 0 "flags_reg_operand" "")
20471 (match_operator 1 "compare_operator"
20472 [(match_operand 2 "register_operand" "")
20473 (match_operand 3 "const_int_operand" "")]))]
20474 "(INTVAL (operands[3]) == -1
20475 || INTVAL (operands[3]) == 1
20476 || INTVAL (operands[3]) == 128)
20477 && ix86_match_ccmode (insn, CCGCmode)
20478 && peep2_reg_dead_p (1, operands[2])"
20479 [(parallel [(set (match_dup 0)
20480 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20481 (clobber (match_dup 2))])]
20485 [(match_scratch:DI 0 "r")
20486 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20487 (clobber (reg:CC FLAGS_REG))
20488 (clobber (mem:BLK (scratch)))])]
20489 "optimize_size || !TARGET_SUB_ESP_4"
20490 [(clobber (match_dup 0))
20491 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20492 (clobber (mem:BLK (scratch)))])])
20495 [(match_scratch:DI 0 "r")
20496 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20497 (clobber (reg:CC FLAGS_REG))
20498 (clobber (mem:BLK (scratch)))])]
20499 "optimize_size || !TARGET_SUB_ESP_8"
20500 [(clobber (match_dup 0))
20501 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20502 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20503 (clobber (mem:BLK (scratch)))])])
20505 ;; Convert esp subtractions to push.
20507 [(match_scratch:DI 0 "r")
20508 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20509 (clobber (reg:CC FLAGS_REG))])]
20510 "optimize_size || !TARGET_SUB_ESP_4"
20511 [(clobber (match_dup 0))
20512 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20515 [(match_scratch:DI 0 "r")
20516 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20517 (clobber (reg:CC FLAGS_REG))])]
20518 "optimize_size || !TARGET_SUB_ESP_8"
20519 [(clobber (match_dup 0))
20520 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20521 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20523 ;; Convert epilogue deallocator to pop.
20525 [(match_scratch:DI 0 "r")
20526 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20527 (clobber (reg:CC FLAGS_REG))
20528 (clobber (mem:BLK (scratch)))])]
20529 "optimize_size || !TARGET_ADD_ESP_4"
20530 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20531 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20532 (clobber (mem:BLK (scratch)))])]
20535 ;; Two pops case is tricky, since pop causes dependency on destination register.
20536 ;; We use two registers if available.
20538 [(match_scratch:DI 0 "r")
20539 (match_scratch:DI 1 "r")
20540 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20541 (clobber (reg:CC FLAGS_REG))
20542 (clobber (mem:BLK (scratch)))])]
20543 "optimize_size || !TARGET_ADD_ESP_8"
20544 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20546 (clobber (mem:BLK (scratch)))])
20547 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20548 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20552 [(match_scratch:DI 0 "r")
20553 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20554 (clobber (reg:CC FLAGS_REG))
20555 (clobber (mem:BLK (scratch)))])]
20557 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20558 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20559 (clobber (mem:BLK (scratch)))])
20560 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20561 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20564 ;; Convert esp additions to pop.
20566 [(match_scratch:DI 0 "r")
20567 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20568 (clobber (reg:CC FLAGS_REG))])]
20570 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20571 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20574 ;; Two pops case is tricky, since pop causes dependency on destination register.
20575 ;; We use two registers if available.
20577 [(match_scratch:DI 0 "r")
20578 (match_scratch:DI 1 "r")
20579 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20580 (clobber (reg:CC FLAGS_REG))])]
20582 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20583 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20584 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20585 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20589 [(match_scratch:DI 0 "r")
20590 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20591 (clobber (reg:CC FLAGS_REG))])]
20593 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20594 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20595 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20596 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20599 ;; Convert imul by three, five and nine into lea
20602 [(set (match_operand:SI 0 "register_operand" "")
20603 (mult:SI (match_operand:SI 1 "register_operand" "")
20604 (match_operand:SI 2 "const_int_operand" "")))
20605 (clobber (reg:CC FLAGS_REG))])]
20606 "INTVAL (operands[2]) == 3
20607 || INTVAL (operands[2]) == 5
20608 || INTVAL (operands[2]) == 9"
20609 [(set (match_dup 0)
20610 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20612 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20616 [(set (match_operand:SI 0 "register_operand" "")
20617 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20618 (match_operand:SI 2 "const_int_operand" "")))
20619 (clobber (reg:CC FLAGS_REG))])]
20621 && (INTVAL (operands[2]) == 3
20622 || INTVAL (operands[2]) == 5
20623 || INTVAL (operands[2]) == 9)"
20624 [(set (match_dup 0) (match_dup 1))
20626 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20628 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20632 [(set (match_operand:DI 0 "register_operand" "")
20633 (mult:DI (match_operand:DI 1 "register_operand" "")
20634 (match_operand:DI 2 "const_int_operand" "")))
20635 (clobber (reg:CC FLAGS_REG))])]
20637 && (INTVAL (operands[2]) == 3
20638 || INTVAL (operands[2]) == 5
20639 || INTVAL (operands[2]) == 9)"
20640 [(set (match_dup 0)
20641 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20643 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20647 [(set (match_operand:DI 0 "register_operand" "")
20648 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20649 (match_operand:DI 2 "const_int_operand" "")))
20650 (clobber (reg:CC FLAGS_REG))])]
20653 && (INTVAL (operands[2]) == 3
20654 || INTVAL (operands[2]) == 5
20655 || INTVAL (operands[2]) == 9)"
20656 [(set (match_dup 0) (match_dup 1))
20658 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20660 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20662 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20663 ;; imul $32bit_imm, reg, reg is direct decoded.
20665 [(match_scratch:DI 3 "r")
20666 (parallel [(set (match_operand:DI 0 "register_operand" "")
20667 (mult:DI (match_operand:DI 1 "memory_operand" "")
20668 (match_operand:DI 2 "immediate_operand" "")))
20669 (clobber (reg:CC FLAGS_REG))])]
20670 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20671 && !satisfies_constraint_K (operands[2])"
20672 [(set (match_dup 3) (match_dup 1))
20673 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20674 (clobber (reg:CC FLAGS_REG))])]
20678 [(match_scratch:SI 3 "r")
20679 (parallel [(set (match_operand:SI 0 "register_operand" "")
20680 (mult:SI (match_operand:SI 1 "memory_operand" "")
20681 (match_operand:SI 2 "immediate_operand" "")))
20682 (clobber (reg:CC FLAGS_REG))])]
20683 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20684 && !satisfies_constraint_K (operands[2])"
20685 [(set (match_dup 3) (match_dup 1))
20686 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20687 (clobber (reg:CC FLAGS_REG))])]
20691 [(match_scratch:SI 3 "r")
20692 (parallel [(set (match_operand:DI 0 "register_operand" "")
20694 (mult:SI (match_operand:SI 1 "memory_operand" "")
20695 (match_operand:SI 2 "immediate_operand" ""))))
20696 (clobber (reg:CC FLAGS_REG))])]
20697 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20698 && !satisfies_constraint_K (operands[2])"
20699 [(set (match_dup 3) (match_dup 1))
20700 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20701 (clobber (reg:CC FLAGS_REG))])]
20704 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20705 ;; Convert it into imul reg, reg
20706 ;; It would be better to force assembler to encode instruction using long
20707 ;; immediate, but there is apparently no way to do so.
20709 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20710 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20711 (match_operand:DI 2 "const_int_operand" "")))
20712 (clobber (reg:CC FLAGS_REG))])
20713 (match_scratch:DI 3 "r")]
20714 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20715 && satisfies_constraint_K (operands[2])"
20716 [(set (match_dup 3) (match_dup 2))
20717 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20718 (clobber (reg:CC FLAGS_REG))])]
20720 if (!rtx_equal_p (operands[0], operands[1]))
20721 emit_move_insn (operands[0], operands[1]);
20725 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20726 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20727 (match_operand:SI 2 "const_int_operand" "")))
20728 (clobber (reg:CC FLAGS_REG))])
20729 (match_scratch:SI 3 "r")]
20730 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20731 && satisfies_constraint_K (operands[2])"
20732 [(set (match_dup 3) (match_dup 2))
20733 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20734 (clobber (reg:CC FLAGS_REG))])]
20736 if (!rtx_equal_p (operands[0], operands[1]))
20737 emit_move_insn (operands[0], operands[1]);
20741 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20742 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20743 (match_operand:HI 2 "immediate_operand" "")))
20744 (clobber (reg:CC FLAGS_REG))])
20745 (match_scratch:HI 3 "r")]
20746 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20747 [(set (match_dup 3) (match_dup 2))
20748 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20749 (clobber (reg:CC FLAGS_REG))])]
20751 if (!rtx_equal_p (operands[0], operands[1]))
20752 emit_move_insn (operands[0], operands[1]);
20755 ;; After splitting up read-modify operations, array accesses with memory
20756 ;; operands might end up in form:
20758 ;; movl 4(%esp), %edx
20760 ;; instead of pre-splitting:
20762 ;; addl 4(%esp), %eax
20764 ;; movl 4(%esp), %edx
20765 ;; leal (%edx,%eax,4), %eax
20768 [(parallel [(set (match_operand 0 "register_operand" "")
20769 (ashift (match_operand 1 "register_operand" "")
20770 (match_operand 2 "const_int_operand" "")))
20771 (clobber (reg:CC FLAGS_REG))])
20772 (set (match_operand 3 "register_operand")
20773 (match_operand 4 "x86_64_general_operand" ""))
20774 (parallel [(set (match_operand 5 "register_operand" "")
20775 (plus (match_operand 6 "register_operand" "")
20776 (match_operand 7 "register_operand" "")))
20777 (clobber (reg:CC FLAGS_REG))])]
20778 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20779 /* Validate MODE for lea. */
20780 && ((!TARGET_PARTIAL_REG_STALL
20781 && (GET_MODE (operands[0]) == QImode
20782 || GET_MODE (operands[0]) == HImode))
20783 || GET_MODE (operands[0]) == SImode
20784 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20785 /* We reorder load and the shift. */
20786 && !rtx_equal_p (operands[1], operands[3])
20787 && !reg_overlap_mentioned_p (operands[0], operands[4])
20788 /* Last PLUS must consist of operand 0 and 3. */
20789 && !rtx_equal_p (operands[0], operands[3])
20790 && (rtx_equal_p (operands[3], operands[6])
20791 || rtx_equal_p (operands[3], operands[7]))
20792 && (rtx_equal_p (operands[0], operands[6])
20793 || rtx_equal_p (operands[0], operands[7]))
20794 /* The intermediate operand 0 must die or be same as output. */
20795 && (rtx_equal_p (operands[0], operands[5])
20796 || peep2_reg_dead_p (3, operands[0]))"
20797 [(set (match_dup 3) (match_dup 4))
20798 (set (match_dup 0) (match_dup 1))]
20800 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20801 int scale = 1 << INTVAL (operands[2]);
20802 rtx index = gen_lowpart (Pmode, operands[1]);
20803 rtx base = gen_lowpart (Pmode, operands[3]);
20804 rtx dest = gen_lowpart (mode, operands[5]);
20806 operands[1] = gen_rtx_PLUS (Pmode, base,
20807 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20809 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20810 operands[0] = dest;
20813 ;; Call-value patterns last so that the wildcard operand does not
20814 ;; disrupt insn-recog's switch tables.
20816 (define_insn "*call_value_pop_0"
20817 [(set (match_operand 0 "" "")
20818 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20819 (match_operand:SI 2 "" "")))
20820 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20821 (match_operand:SI 3 "immediate_operand" "")))]
20824 if (SIBLING_CALL_P (insn))
20827 return "call\t%P1";
20829 [(set_attr "type" "callv")])
20831 (define_insn "*call_value_pop_1"
20832 [(set (match_operand 0 "" "")
20833 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20834 (match_operand:SI 2 "" "")))
20835 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20836 (match_operand:SI 3 "immediate_operand" "i")))]
20839 if (constant_call_address_operand (operands[1], Pmode))
20841 if (SIBLING_CALL_P (insn))
20844 return "call\t%P1";
20846 if (SIBLING_CALL_P (insn))
20849 return "call\t%A1";
20851 [(set_attr "type" "callv")])
20853 (define_insn "*call_value_0"
20854 [(set (match_operand 0 "" "")
20855 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20856 (match_operand:SI 2 "" "")))]
20859 if (SIBLING_CALL_P (insn))
20862 return "call\t%P1";
20864 [(set_attr "type" "callv")])
20866 (define_insn "*call_value_0_rex64"
20867 [(set (match_operand 0 "" "")
20868 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20869 (match_operand:DI 2 "const_int_operand" "")))]
20872 if (SIBLING_CALL_P (insn))
20875 return "call\t%P1";
20877 [(set_attr "type" "callv")])
20879 (define_insn "*call_value_1"
20880 [(set (match_operand 0 "" "")
20881 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20882 (match_operand:SI 2 "" "")))]
20883 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20885 if (constant_call_address_operand (operands[1], Pmode))
20886 return "call\t%P1";
20887 return "call\t%A1";
20889 [(set_attr "type" "callv")])
20891 (define_insn "*sibcall_value_1"
20892 [(set (match_operand 0 "" "")
20893 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20894 (match_operand:SI 2 "" "")))]
20895 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20897 if (constant_call_address_operand (operands[1], Pmode))
20901 [(set_attr "type" "callv")])
20903 (define_insn "*call_value_1_rex64"
20904 [(set (match_operand 0 "" "")
20905 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20906 (match_operand:DI 2 "" "")))]
20907 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20908 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20910 if (constant_call_address_operand (operands[1], Pmode))
20911 return "call\t%P1";
20912 return "call\t%A1";
20914 [(set_attr "type" "callv")])
20916 (define_insn "*call_value_1_rex64_large"
20917 [(set (match_operand 0 "" "")
20918 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20919 (match_operand:DI 2 "" "")))]
20920 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20922 [(set_attr "type" "callv")])
20924 (define_insn "*sibcall_value_1_rex64"
20925 [(set (match_operand 0 "" "")
20926 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20927 (match_operand:DI 2 "" "")))]
20928 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20930 [(set_attr "type" "callv")])
20932 (define_insn "*sibcall_value_1_rex64_v"
20933 [(set (match_operand 0 "" "")
20934 (call (mem:QI (reg:DI R11_REG))
20935 (match_operand:DI 1 "" "")))]
20936 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20938 [(set_attr "type" "callv")])
20940 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20941 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20942 ;; caught for use by garbage collectors and the like. Using an insn that
20943 ;; maps to SIGILL makes it more likely the program will rightfully die.
20944 ;; Keeping with tradition, "6" is in honor of #UD.
20945 (define_insn "trap"
20946 [(trap_if (const_int 1) (const_int 6))]
20948 { return ASM_SHORT "0x0b0f"; }
20949 [(set_attr "length" "2")])
20951 (define_expand "sse_prologue_save"
20952 [(parallel [(set (match_operand:BLK 0 "" "")
20953 (unspec:BLK [(reg:DI 21)
20960 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20961 (use (match_operand:DI 1 "register_operand" ""))
20962 (use (match_operand:DI 2 "immediate_operand" ""))
20963 (use (label_ref:DI (match_operand 3 "" "")))])]
20967 (define_insn "*sse_prologue_save_insn"
20968 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20969 (match_operand:DI 4 "const_int_operand" "n")))
20970 (unspec:BLK [(reg:DI 21)
20977 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20978 (use (match_operand:DI 1 "register_operand" "r"))
20979 (use (match_operand:DI 2 "const_int_operand" "i"))
20980 (use (label_ref:DI (match_operand 3 "" "X")))]
20982 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20983 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20987 operands[0] = gen_rtx_MEM (Pmode,
20988 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20989 output_asm_insn (\"jmp\\t%A1\", operands);
20990 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20992 operands[4] = adjust_address (operands[0], DImode, i*16);
20993 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20994 PUT_MODE (operands[4], TImode);
20995 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20996 output_asm_insn (\"rex\", operands);
20997 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20999 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21000 CODE_LABEL_NUMBER (operands[3]));
21004 [(set_attr "type" "other")
21005 (set_attr "length_immediate" "0")
21006 (set_attr "length_address" "0")
21007 (set_attr "length" "135")
21008 (set_attr "memory" "store")
21009 (set_attr "modrm" "0")
21010 (set_attr "mode" "DI")])
21012 (define_expand "prefetch"
21013 [(prefetch (match_operand 0 "address_operand" "")
21014 (match_operand:SI 1 "const_int_operand" "")
21015 (match_operand:SI 2 "const_int_operand" ""))]
21016 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21018 int rw = INTVAL (operands[1]);
21019 int locality = INTVAL (operands[2]);
21021 gcc_assert (rw == 0 || rw == 1);
21022 gcc_assert (locality >= 0 && locality <= 3);
21023 gcc_assert (GET_MODE (operands[0]) == Pmode
21024 || GET_MODE (operands[0]) == VOIDmode);
21026 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21027 supported by SSE counterpart or the SSE prefetch is not available
21028 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21030 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21031 operands[2] = GEN_INT (3);
21033 operands[1] = const0_rtx;
21036 (define_insn "*prefetch_sse"
21037 [(prefetch (match_operand:SI 0 "address_operand" "p")
21039 (match_operand:SI 1 "const_int_operand" ""))]
21040 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21042 static const char * const patterns[4] = {
21043 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21046 int locality = INTVAL (operands[1]);
21047 gcc_assert (locality >= 0 && locality <= 3);
21049 return patterns[locality];
21051 [(set_attr "type" "sse")
21052 (set_attr "memory" "none")])
21054 (define_insn "*prefetch_sse_rex"
21055 [(prefetch (match_operand:DI 0 "address_operand" "p")
21057 (match_operand:SI 1 "const_int_operand" ""))]
21058 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21060 static const char * const patterns[4] = {
21061 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21064 int locality = INTVAL (operands[1]);
21065 gcc_assert (locality >= 0 && locality <= 3);
21067 return patterns[locality];
21069 [(set_attr "type" "sse")
21070 (set_attr "memory" "none")])
21072 (define_insn "*prefetch_3dnow"
21073 [(prefetch (match_operand:SI 0 "address_operand" "p")
21074 (match_operand:SI 1 "const_int_operand" "n")
21076 "TARGET_3DNOW && !TARGET_64BIT"
21078 if (INTVAL (operands[1]) == 0)
21079 return "prefetch\t%a0";
21081 return "prefetchw\t%a0";
21083 [(set_attr "type" "mmx")
21084 (set_attr "memory" "none")])
21086 (define_insn "*prefetch_3dnow_rex"
21087 [(prefetch (match_operand:DI 0 "address_operand" "p")
21088 (match_operand:SI 1 "const_int_operand" "n")
21090 "TARGET_3DNOW && TARGET_64BIT"
21092 if (INTVAL (operands[1]) == 0)
21093 return "prefetch\t%a0";
21095 return "prefetchw\t%a0";
21097 [(set_attr "type" "mmx")
21098 (set_attr "memory" "none")])
21100 (define_expand "stack_protect_set"
21101 [(match_operand 0 "memory_operand" "")
21102 (match_operand 1 "memory_operand" "")]
21105 #ifdef TARGET_THREAD_SSP_OFFSET
21107 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21108 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21110 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21111 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21114 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21116 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21121 (define_insn "stack_protect_set_si"
21122 [(set (match_operand:SI 0 "memory_operand" "=m")
21123 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21124 (set (match_scratch:SI 2 "=&r") (const_int 0))
21125 (clobber (reg:CC FLAGS_REG))]
21127 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21128 [(set_attr "type" "multi")])
21130 (define_insn "stack_protect_set_di"
21131 [(set (match_operand:DI 0 "memory_operand" "=m")
21132 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21133 (set (match_scratch:DI 2 "=&r") (const_int 0))
21134 (clobber (reg:CC FLAGS_REG))]
21136 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21137 [(set_attr "type" "multi")])
21139 (define_insn "stack_tls_protect_set_si"
21140 [(set (match_operand:SI 0 "memory_operand" "=m")
21141 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21142 (set (match_scratch:SI 2 "=&r") (const_int 0))
21143 (clobber (reg:CC FLAGS_REG))]
21145 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21146 [(set_attr "type" "multi")])
21148 (define_insn "stack_tls_protect_set_di"
21149 [(set (match_operand:DI 0 "memory_operand" "=m")
21150 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21151 (set (match_scratch:DI 2 "=&r") (const_int 0))
21152 (clobber (reg:CC FLAGS_REG))]
21155 /* The kernel uses a different segment register for performance reasons; a
21156 system call would not have to trash the userspace segment register,
21157 which would be expensive */
21158 if (ix86_cmodel != CM_KERNEL)
21159 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21161 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21163 [(set_attr "type" "multi")])
21165 (define_expand "stack_protect_test"
21166 [(match_operand 0 "memory_operand" "")
21167 (match_operand 1 "memory_operand" "")
21168 (match_operand 2 "" "")]
21171 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21172 ix86_compare_op0 = operands[0];
21173 ix86_compare_op1 = operands[1];
21174 ix86_compare_emitted = flags;
21176 #ifdef TARGET_THREAD_SSP_OFFSET
21178 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21179 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21181 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21182 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21185 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21187 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21189 emit_jump_insn (gen_beq (operands[2]));
21193 (define_insn "stack_protect_test_si"
21194 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21195 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21196 (match_operand:SI 2 "memory_operand" "m")]
21198 (clobber (match_scratch:SI 3 "=&r"))]
21200 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21201 [(set_attr "type" "multi")])
21203 (define_insn "stack_protect_test_di"
21204 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21205 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21206 (match_operand:DI 2 "memory_operand" "m")]
21208 (clobber (match_scratch:DI 3 "=&r"))]
21210 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21211 [(set_attr "type" "multi")])
21213 (define_insn "stack_tls_protect_test_si"
21214 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21215 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21216 (match_operand:SI 2 "const_int_operand" "i")]
21217 UNSPEC_SP_TLS_TEST))
21218 (clobber (match_scratch:SI 3 "=r"))]
21220 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21221 [(set_attr "type" "multi")])
21223 (define_insn "stack_tls_protect_test_di"
21224 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21225 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21226 (match_operand:DI 2 "const_int_operand" "i")]
21227 UNSPEC_SP_TLS_TEST))
21228 (clobber (match_scratch:DI 3 "=r"))]
21231 /* The kernel uses a different segment register for performance reasons; a
21232 system call would not have to trash the userspace segment register,
21233 which would be expensive */
21234 if (ix86_cmodel != CM_KERNEL)
21235 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21237 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21239 [(set_attr "type" "multi")])
21241 (define_mode_iterator CRC32MODE [QI HI SI])
21242 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21243 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21245 (define_insn "sse4_2_crc32<mode>"
21246 [(set (match_operand:SI 0 "register_operand" "=r")
21248 [(match_operand:SI 1 "register_operand" "0")
21249 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21252 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21253 [(set_attr "type" "sselog1")
21254 (set_attr "prefix_rep" "1")
21255 (set_attr "prefix_extra" "1")
21256 (set_attr "mode" "SI")])
21258 (define_insn "sse4_2_crc32di"
21259 [(set (match_operand:DI 0 "register_operand" "=r")
21261 [(match_operand:DI 1 "register_operand" "0")
21262 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21264 "TARGET_SSE4_2 && TARGET_64BIT"
21265 "crc32q\t{%2, %0|%0, %2}"
21266 [(set_attr "type" "sselog1")
21267 (set_attr "prefix_rep" "1")
21268 (set_attr "prefix_extra" "1")
21269 (set_attr "mode" "DI")])
21273 (include "sync.md")