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 ;; Mapping of parallel logic operators
544 (define_code_iterator plogic [and ior xor])
546 ;; Base name for insn mnemonic.
547 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
549 ;; All single word integer modes.
550 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
552 ;; Instruction suffix for integer modes.
553 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
555 ;; Register class for integer modes.
556 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
558 ;; Immediate operand constraint for integer modes.
559 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
561 ;; General operand predicate for integer modes.
562 (define_mode_attr general_operand
563 [(QI "general_operand")
564 (HI "general_operand")
565 (SI "general_operand")
566 (DI "x86_64_general_operand")])
568 ;; SSE and x87 SFmode and DFmode floating point modes
569 (define_mode_iterator MODEF [SF DF])
571 ;; All x87 floating point modes
572 (define_mode_iterator X87MODEF [SF DF XF])
574 ;; All integer modes handled by x87 fisttp operator.
575 (define_mode_iterator X87MODEI [HI SI DI])
577 ;; All integer modes handled by integer x87 operators.
578 (define_mode_iterator X87MODEI12 [HI SI])
580 ;; All integer modes handled by SSE cvtts?2si* operators.
581 (define_mode_iterator SSEMODEI24 [SI DI])
583 ;; SSE asm suffix for floating point modes
584 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
586 ;; SSE vector mode corresponding to a scalar mode
587 (define_mode_attr ssevecmode
588 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
590 ;; Instruction suffix for REX 64bit operators.
591 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
593 ;; Scheduling descriptions
595 (include "pentium.md")
598 (include "athlon.md")
602 ;; Operand and operator predicates and constraints
604 (include "predicates.md")
605 (include "constraints.md")
608 ;; Compare instructions.
610 ;; All compare insns have expanders that save the operands away without
611 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
612 ;; after the cmp) will actually emit the cmpM.
614 (define_expand "cmpti"
615 [(set (reg:CC FLAGS_REG)
616 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
617 (match_operand:TI 1 "x86_64_general_operand" "")))]
620 if (MEM_P (operands[0]) && MEM_P (operands[1]))
621 operands[0] = force_reg (TImode, operands[0]);
622 ix86_compare_op0 = operands[0];
623 ix86_compare_op1 = operands[1];
627 (define_expand "cmpdi"
628 [(set (reg:CC FLAGS_REG)
629 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
630 (match_operand:DI 1 "x86_64_general_operand" "")))]
633 if (MEM_P (operands[0]) && MEM_P (operands[1]))
634 operands[0] = force_reg (DImode, operands[0]);
635 ix86_compare_op0 = operands[0];
636 ix86_compare_op1 = operands[1];
640 (define_expand "cmpsi"
641 [(set (reg:CC FLAGS_REG)
642 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
643 (match_operand:SI 1 "general_operand" "")))]
646 if (MEM_P (operands[0]) && MEM_P (operands[1]))
647 operands[0] = force_reg (SImode, operands[0]);
648 ix86_compare_op0 = operands[0];
649 ix86_compare_op1 = operands[1];
653 (define_expand "cmphi"
654 [(set (reg:CC FLAGS_REG)
655 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
656 (match_operand:HI 1 "general_operand" "")))]
659 if (MEM_P (operands[0]) && MEM_P (operands[1]))
660 operands[0] = force_reg (HImode, operands[0]);
661 ix86_compare_op0 = operands[0];
662 ix86_compare_op1 = operands[1];
666 (define_expand "cmpqi"
667 [(set (reg:CC FLAGS_REG)
668 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
669 (match_operand:QI 1 "general_operand" "")))]
672 if (MEM_P (operands[0]) && MEM_P (operands[1]))
673 operands[0] = force_reg (QImode, operands[0]);
674 ix86_compare_op0 = operands[0];
675 ix86_compare_op1 = operands[1];
679 (define_insn "cmpdi_ccno_1_rex64"
680 [(set (reg FLAGS_REG)
681 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
682 (match_operand:DI 1 "const0_operand" "n,n")))]
683 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
686 cmp{q}\t{%1, %0|%0, %1}"
687 [(set_attr "type" "test,icmp")
688 (set_attr "length_immediate" "0,1")
689 (set_attr "mode" "DI")])
691 (define_insn "*cmpdi_minus_1_rex64"
692 [(set (reg FLAGS_REG)
693 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
694 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
696 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
697 "cmp{q}\t{%1, %0|%0, %1}"
698 [(set_attr "type" "icmp")
699 (set_attr "mode" "DI")])
701 (define_expand "cmpdi_1_rex64"
702 [(set (reg:CC FLAGS_REG)
703 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
704 (match_operand:DI 1 "general_operand" "")))]
708 (define_insn "cmpdi_1_insn_rex64"
709 [(set (reg FLAGS_REG)
710 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
711 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
712 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
713 "cmp{q}\t{%1, %0|%0, %1}"
714 [(set_attr "type" "icmp")
715 (set_attr "mode" "DI")])
718 (define_insn "*cmpsi_ccno_1"
719 [(set (reg FLAGS_REG)
720 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
721 (match_operand:SI 1 "const0_operand" "n,n")))]
722 "ix86_match_ccmode (insn, CCNOmode)"
725 cmp{l}\t{%1, %0|%0, %1}"
726 [(set_attr "type" "test,icmp")
727 (set_attr "length_immediate" "0,1")
728 (set_attr "mode" "SI")])
730 (define_insn "*cmpsi_minus_1"
731 [(set (reg FLAGS_REG)
732 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
733 (match_operand:SI 1 "general_operand" "ri,mr"))
735 "ix86_match_ccmode (insn, CCGOCmode)"
736 "cmp{l}\t{%1, %0|%0, %1}"
737 [(set_attr "type" "icmp")
738 (set_attr "mode" "SI")])
740 (define_expand "cmpsi_1"
741 [(set (reg:CC FLAGS_REG)
742 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
743 (match_operand:SI 1 "general_operand" "")))]
747 (define_insn "*cmpsi_1_insn"
748 [(set (reg FLAGS_REG)
749 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
750 (match_operand:SI 1 "general_operand" "ri,mr")))]
751 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
752 && ix86_match_ccmode (insn, CCmode)"
753 "cmp{l}\t{%1, %0|%0, %1}"
754 [(set_attr "type" "icmp")
755 (set_attr "mode" "SI")])
757 (define_insn "*cmphi_ccno_1"
758 [(set (reg FLAGS_REG)
759 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
760 (match_operand:HI 1 "const0_operand" "n,n")))]
761 "ix86_match_ccmode (insn, CCNOmode)"
764 cmp{w}\t{%1, %0|%0, %1}"
765 [(set_attr "type" "test,icmp")
766 (set_attr "length_immediate" "0,1")
767 (set_attr "mode" "HI")])
769 (define_insn "*cmphi_minus_1"
770 [(set (reg FLAGS_REG)
771 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
772 (match_operand:HI 1 "general_operand" "ri,mr"))
774 "ix86_match_ccmode (insn, CCGOCmode)"
775 "cmp{w}\t{%1, %0|%0, %1}"
776 [(set_attr "type" "icmp")
777 (set_attr "mode" "HI")])
779 (define_insn "*cmphi_1"
780 [(set (reg FLAGS_REG)
781 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
782 (match_operand:HI 1 "general_operand" "ri,mr")))]
783 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
784 && ix86_match_ccmode (insn, CCmode)"
785 "cmp{w}\t{%1, %0|%0, %1}"
786 [(set_attr "type" "icmp")
787 (set_attr "mode" "HI")])
789 (define_insn "*cmpqi_ccno_1"
790 [(set (reg FLAGS_REG)
791 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
792 (match_operand:QI 1 "const0_operand" "n,n")))]
793 "ix86_match_ccmode (insn, CCNOmode)"
796 cmp{b}\t{$0, %0|%0, 0}"
797 [(set_attr "type" "test,icmp")
798 (set_attr "length_immediate" "0,1")
799 (set_attr "mode" "QI")])
801 (define_insn "*cmpqi_1"
802 [(set (reg FLAGS_REG)
803 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
804 (match_operand:QI 1 "general_operand" "qi,mq")))]
805 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
806 && ix86_match_ccmode (insn, CCmode)"
807 "cmp{b}\t{%1, %0|%0, %1}"
808 [(set_attr "type" "icmp")
809 (set_attr "mode" "QI")])
811 (define_insn "*cmpqi_minus_1"
812 [(set (reg FLAGS_REG)
813 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
814 (match_operand:QI 1 "general_operand" "qi,mq"))
816 "ix86_match_ccmode (insn, CCGOCmode)"
817 "cmp{b}\t{%1, %0|%0, %1}"
818 [(set_attr "type" "icmp")
819 (set_attr "mode" "QI")])
821 (define_insn "*cmpqi_ext_1"
822 [(set (reg FLAGS_REG)
824 (match_operand:QI 0 "general_operand" "Qm")
827 (match_operand 1 "ext_register_operand" "Q")
830 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
831 "cmp{b}\t{%h1, %0|%0, %h1}"
832 [(set_attr "type" "icmp")
833 (set_attr "mode" "QI")])
835 (define_insn "*cmpqi_ext_1_rex64"
836 [(set (reg FLAGS_REG)
838 (match_operand:QI 0 "register_operand" "Q")
841 (match_operand 1 "ext_register_operand" "Q")
844 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
845 "cmp{b}\t{%h1, %0|%0, %h1}"
846 [(set_attr "type" "icmp")
847 (set_attr "mode" "QI")])
849 (define_insn "*cmpqi_ext_2"
850 [(set (reg FLAGS_REG)
854 (match_operand 0 "ext_register_operand" "Q")
857 (match_operand:QI 1 "const0_operand" "n")))]
858 "ix86_match_ccmode (insn, CCNOmode)"
860 [(set_attr "type" "test")
861 (set_attr "length_immediate" "0")
862 (set_attr "mode" "QI")])
864 (define_expand "cmpqi_ext_3"
865 [(set (reg:CC FLAGS_REG)
869 (match_operand 0 "ext_register_operand" "")
872 (match_operand:QI 1 "general_operand" "")))]
876 (define_insn "cmpqi_ext_3_insn"
877 [(set (reg FLAGS_REG)
881 (match_operand 0 "ext_register_operand" "Q")
884 (match_operand:QI 1 "general_operand" "Qmn")))]
885 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
886 "cmp{b}\t{%1, %h0|%h0, %1}"
887 [(set_attr "type" "icmp")
888 (set_attr "mode" "QI")])
890 (define_insn "cmpqi_ext_3_insn_rex64"
891 [(set (reg FLAGS_REG)
895 (match_operand 0 "ext_register_operand" "Q")
898 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
899 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
900 "cmp{b}\t{%1, %h0|%h0, %1}"
901 [(set_attr "type" "icmp")
902 (set_attr "mode" "QI")])
904 (define_insn "*cmpqi_ext_4"
905 [(set (reg FLAGS_REG)
909 (match_operand 0 "ext_register_operand" "Q")
914 (match_operand 1 "ext_register_operand" "Q")
917 "ix86_match_ccmode (insn, CCmode)"
918 "cmp{b}\t{%h1, %h0|%h0, %h1}"
919 [(set_attr "type" "icmp")
920 (set_attr "mode" "QI")])
922 ;; These implement float point compares.
923 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
924 ;; which would allow mix and match FP modes on the compares. Which is what
925 ;; the old patterns did, but with many more of them.
927 (define_expand "cmpxf"
928 [(set (reg:CC FLAGS_REG)
929 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
930 (match_operand:XF 1 "nonmemory_operand" "")))]
933 ix86_compare_op0 = operands[0];
934 ix86_compare_op1 = operands[1];
938 (define_expand "cmp<mode>"
939 [(set (reg:CC FLAGS_REG)
940 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
941 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
942 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
944 ix86_compare_op0 = operands[0];
945 ix86_compare_op1 = operands[1];
949 ;; FP compares, step 1:
950 ;; Set the FP condition codes.
952 ;; CCFPmode compare with exceptions
953 ;; CCFPUmode compare with no exceptions
955 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
956 ;; used to manage the reg stack popping would not be preserved.
958 (define_insn "*cmpfp_0"
959 [(set (match_operand:HI 0 "register_operand" "=a")
962 (match_operand 1 "register_operand" "f")
963 (match_operand 2 "const0_operand" "X"))]
965 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
966 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
967 "* return output_fp_compare (insn, operands, 0, 0);"
968 [(set_attr "type" "multi")
969 (set_attr "unit" "i387")
971 (cond [(match_operand:SF 1 "" "")
973 (match_operand:DF 1 "" "")
976 (const_string "XF")))])
978 (define_insn_and_split "*cmpfp_0_cc"
979 [(set (reg:CCFP FLAGS_REG)
981 (match_operand 1 "register_operand" "f")
982 (match_operand 2 "const0_operand" "X")))
983 (clobber (match_operand:HI 0 "register_operand" "=a"))]
984 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
985 && TARGET_SAHF && !TARGET_CMOVE
986 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
988 "&& reload_completed"
991 [(compare:CCFP (match_dup 1)(match_dup 2))]
993 (set (reg:CC FLAGS_REG)
994 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
996 [(set_attr "type" "multi")
997 (set_attr "unit" "i387")
999 (cond [(match_operand:SF 1 "" "")
1001 (match_operand:DF 1 "" "")
1004 (const_string "XF")))])
1006 (define_insn "*cmpfp_xf"
1007 [(set (match_operand:HI 0 "register_operand" "=a")
1010 (match_operand:XF 1 "register_operand" "f")
1011 (match_operand:XF 2 "register_operand" "f"))]
1014 "* return output_fp_compare (insn, operands, 0, 0);"
1015 [(set_attr "type" "multi")
1016 (set_attr "unit" "i387")
1017 (set_attr "mode" "XF")])
1019 (define_insn_and_split "*cmpfp_xf_cc"
1020 [(set (reg:CCFP FLAGS_REG)
1022 (match_operand:XF 1 "register_operand" "f")
1023 (match_operand:XF 2 "register_operand" "f")))
1024 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1026 && TARGET_SAHF && !TARGET_CMOVE"
1028 "&& reload_completed"
1031 [(compare:CCFP (match_dup 1)(match_dup 2))]
1033 (set (reg:CC FLAGS_REG)
1034 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1036 [(set_attr "type" "multi")
1037 (set_attr "unit" "i387")
1038 (set_attr "mode" "XF")])
1040 (define_insn "*cmpfp_<mode>"
1041 [(set (match_operand:HI 0 "register_operand" "=a")
1044 (match_operand:MODEF 1 "register_operand" "f")
1045 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1048 "* return output_fp_compare (insn, operands, 0, 0);"
1049 [(set_attr "type" "multi")
1050 (set_attr "unit" "i387")
1051 (set_attr "mode" "<MODE>")])
1053 (define_insn_and_split "*cmpfp_<mode>_cc"
1054 [(set (reg:CCFP FLAGS_REG)
1056 (match_operand:MODEF 1 "register_operand" "f")
1057 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1058 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1060 && TARGET_SAHF && !TARGET_CMOVE"
1062 "&& reload_completed"
1065 [(compare:CCFP (match_dup 1)(match_dup 2))]
1067 (set (reg:CC FLAGS_REG)
1068 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1070 [(set_attr "type" "multi")
1071 (set_attr "unit" "i387")
1072 (set_attr "mode" "<MODE>")])
1074 (define_insn "*cmpfp_u"
1075 [(set (match_operand:HI 0 "register_operand" "=a")
1078 (match_operand 1 "register_operand" "f")
1079 (match_operand 2 "register_operand" "f"))]
1081 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1082 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1083 "* return output_fp_compare (insn, operands, 0, 1);"
1084 [(set_attr "type" "multi")
1085 (set_attr "unit" "i387")
1087 (cond [(match_operand:SF 1 "" "")
1089 (match_operand:DF 1 "" "")
1092 (const_string "XF")))])
1094 (define_insn_and_split "*cmpfp_u_cc"
1095 [(set (reg:CCFPU FLAGS_REG)
1097 (match_operand 1 "register_operand" "f")
1098 (match_operand 2 "register_operand" "f")))
1099 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1100 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1101 && TARGET_SAHF && !TARGET_CMOVE
1102 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1104 "&& reload_completed"
1107 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1109 (set (reg:CC FLAGS_REG)
1110 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1112 [(set_attr "type" "multi")
1113 (set_attr "unit" "i387")
1115 (cond [(match_operand:SF 1 "" "")
1117 (match_operand:DF 1 "" "")
1120 (const_string "XF")))])
1122 (define_insn "*cmpfp_<mode>"
1123 [(set (match_operand:HI 0 "register_operand" "=a")
1126 (match_operand 1 "register_operand" "f")
1127 (match_operator 3 "float_operator"
1128 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1130 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1131 && TARGET_USE_<MODE>MODE_FIOP
1132 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1133 "* return output_fp_compare (insn, operands, 0, 0);"
1134 [(set_attr "type" "multi")
1135 (set_attr "unit" "i387")
1136 (set_attr "fp_int_src" "true")
1137 (set_attr "mode" "<MODE>")])
1139 (define_insn_and_split "*cmpfp_<mode>_cc"
1140 [(set (reg:CCFP FLAGS_REG)
1142 (match_operand 1 "register_operand" "f")
1143 (match_operator 3 "float_operator"
1144 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1145 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1146 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1147 && TARGET_SAHF && !TARGET_CMOVE
1148 && TARGET_USE_<MODE>MODE_FIOP
1149 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1151 "&& reload_completed"
1156 (match_op_dup 3 [(match_dup 2)]))]
1158 (set (reg:CC FLAGS_REG)
1159 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1161 [(set_attr "type" "multi")
1162 (set_attr "unit" "i387")
1163 (set_attr "fp_int_src" "true")
1164 (set_attr "mode" "<MODE>")])
1166 ;; FP compares, step 2
1167 ;; Move the fpsw to ax.
1169 (define_insn "x86_fnstsw_1"
1170 [(set (match_operand:HI 0 "register_operand" "=a")
1171 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1174 [(set_attr "length" "2")
1175 (set_attr "mode" "SI")
1176 (set_attr "unit" "i387")])
1178 ;; FP compares, step 3
1179 ;; Get ax into flags, general case.
1181 (define_insn "x86_sahf_1"
1182 [(set (reg:CC FLAGS_REG)
1183 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1187 #ifdef HAVE_AS_IX86_SAHF
1190 return ".byte\t0x9e";
1193 [(set_attr "length" "1")
1194 (set_attr "athlon_decode" "vector")
1195 (set_attr "amdfam10_decode" "direct")
1196 (set_attr "mode" "SI")])
1198 ;; Pentium Pro can do steps 1 through 3 in one go.
1199 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1200 (define_insn "*cmpfp_i_mixed"
1201 [(set (reg:CCFP FLAGS_REG)
1202 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1203 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1204 "TARGET_MIX_SSE_I387
1205 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1206 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1207 "* return output_fp_compare (insn, operands, 1, 0);"
1208 [(set_attr "type" "fcmp,ssecomi")
1210 (if_then_else (match_operand:SF 1 "" "")
1212 (const_string "DF")))
1213 (set_attr "athlon_decode" "vector")
1214 (set_attr "amdfam10_decode" "direct")])
1216 (define_insn "*cmpfp_i_sse"
1217 [(set (reg:CCFP FLAGS_REG)
1218 (compare:CCFP (match_operand 0 "register_operand" "x")
1219 (match_operand 1 "nonimmediate_operand" "xm")))]
1221 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1222 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1223 "* return output_fp_compare (insn, operands, 1, 0);"
1224 [(set_attr "type" "ssecomi")
1226 (if_then_else (match_operand:SF 1 "" "")
1228 (const_string "DF")))
1229 (set_attr "athlon_decode" "vector")
1230 (set_attr "amdfam10_decode" "direct")])
1232 (define_insn "*cmpfp_i_i387"
1233 [(set (reg:CCFP FLAGS_REG)
1234 (compare:CCFP (match_operand 0 "register_operand" "f")
1235 (match_operand 1 "register_operand" "f")))]
1236 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1238 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1239 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1240 "* return output_fp_compare (insn, operands, 1, 0);"
1241 [(set_attr "type" "fcmp")
1243 (cond [(match_operand:SF 1 "" "")
1245 (match_operand:DF 1 "" "")
1248 (const_string "XF")))
1249 (set_attr "athlon_decode" "vector")
1250 (set_attr "amdfam10_decode" "direct")])
1252 (define_insn "*cmpfp_iu_mixed"
1253 [(set (reg:CCFPU FLAGS_REG)
1254 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1255 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1256 "TARGET_MIX_SSE_I387
1257 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1258 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1259 "* return output_fp_compare (insn, operands, 1, 1);"
1260 [(set_attr "type" "fcmp,ssecomi")
1262 (if_then_else (match_operand:SF 1 "" "")
1264 (const_string "DF")))
1265 (set_attr "athlon_decode" "vector")
1266 (set_attr "amdfam10_decode" "direct")])
1268 (define_insn "*cmpfp_iu_sse"
1269 [(set (reg:CCFPU FLAGS_REG)
1270 (compare:CCFPU (match_operand 0 "register_operand" "x")
1271 (match_operand 1 "nonimmediate_operand" "xm")))]
1273 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1274 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1275 "* return output_fp_compare (insn, operands, 1, 1);"
1276 [(set_attr "type" "ssecomi")
1278 (if_then_else (match_operand:SF 1 "" "")
1280 (const_string "DF")))
1281 (set_attr "athlon_decode" "vector")
1282 (set_attr "amdfam10_decode" "direct")])
1284 (define_insn "*cmpfp_iu_387"
1285 [(set (reg:CCFPU FLAGS_REG)
1286 (compare:CCFPU (match_operand 0 "register_operand" "f")
1287 (match_operand 1 "register_operand" "f")))]
1288 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1290 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1291 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1292 "* return output_fp_compare (insn, operands, 1, 1);"
1293 [(set_attr "type" "fcmp")
1295 (cond [(match_operand:SF 1 "" "")
1297 (match_operand:DF 1 "" "")
1300 (const_string "XF")))
1301 (set_attr "athlon_decode" "vector")
1302 (set_attr "amdfam10_decode" "direct")])
1304 ;; Move instructions.
1306 ;; General case of fullword move.
1308 (define_expand "movsi"
1309 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1310 (match_operand:SI 1 "general_operand" ""))]
1312 "ix86_expand_move (SImode, operands); DONE;")
1314 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1317 ;; %%% We don't use a post-inc memory reference because x86 is not a
1318 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1319 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1320 ;; targets without our curiosities, and it is just as easy to represent
1321 ;; this differently.
1323 (define_insn "*pushsi2"
1324 [(set (match_operand:SI 0 "push_operand" "=<")
1325 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1328 [(set_attr "type" "push")
1329 (set_attr "mode" "SI")])
1331 ;; For 64BIT abi we always round up to 8 bytes.
1332 (define_insn "*pushsi2_rex64"
1333 [(set (match_operand:SI 0 "push_operand" "=X")
1334 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1337 [(set_attr "type" "push")
1338 (set_attr "mode" "SI")])
1340 (define_insn "*pushsi2_prologue"
1341 [(set (match_operand:SI 0 "push_operand" "=<")
1342 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1343 (clobber (mem:BLK (scratch)))]
1346 [(set_attr "type" "push")
1347 (set_attr "mode" "SI")])
1349 (define_insn "*popsi1_epilogue"
1350 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1351 (mem:SI (reg:SI SP_REG)))
1352 (set (reg:SI SP_REG)
1353 (plus:SI (reg:SI SP_REG) (const_int 4)))
1354 (clobber (mem:BLK (scratch)))]
1357 [(set_attr "type" "pop")
1358 (set_attr "mode" "SI")])
1360 (define_insn "popsi1"
1361 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1362 (mem:SI (reg:SI SP_REG)))
1363 (set (reg:SI SP_REG)
1364 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1367 [(set_attr "type" "pop")
1368 (set_attr "mode" "SI")])
1370 (define_insn "*movsi_xor"
1371 [(set (match_operand:SI 0 "register_operand" "=r")
1372 (match_operand:SI 1 "const0_operand" "i"))
1373 (clobber (reg:CC FLAGS_REG))]
1374 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1376 [(set_attr "type" "alu1")
1377 (set_attr "mode" "SI")
1378 (set_attr "length_immediate" "0")])
1380 (define_insn "*movsi_or"
1381 [(set (match_operand:SI 0 "register_operand" "=r")
1382 (match_operand:SI 1 "immediate_operand" "i"))
1383 (clobber (reg:CC FLAGS_REG))]
1385 && operands[1] == constm1_rtx
1386 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1388 operands[1] = constm1_rtx;
1389 return "or{l}\t{%1, %0|%0, %1}";
1391 [(set_attr "type" "alu1")
1392 (set_attr "mode" "SI")
1393 (set_attr "length_immediate" "1")])
1395 (define_insn "*movsi_1"
1396 [(set (match_operand:SI 0 "nonimmediate_operand"
1397 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1398 (match_operand:SI 1 "general_operand"
1399 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1400 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1402 switch (get_attr_type (insn))
1405 if (get_attr_mode (insn) == MODE_TI)
1406 return "pxor\t%0, %0";
1407 return "xorps\t%0, %0";
1410 switch (get_attr_mode (insn))
1413 return "movdqa\t{%1, %0|%0, %1}";
1415 return "movaps\t{%1, %0|%0, %1}";
1417 return "movd\t{%1, %0|%0, %1}";
1419 return "movss\t{%1, %0|%0, %1}";
1425 return "pxor\t%0, %0";
1428 if (get_attr_mode (insn) == MODE_DI)
1429 return "movq\t{%1, %0|%0, %1}";
1430 return "movd\t{%1, %0|%0, %1}";
1433 return "lea{l}\t{%1, %0|%0, %1}";
1436 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1437 return "mov{l}\t{%1, %0|%0, %1}";
1441 (cond [(eq_attr "alternative" "2")
1442 (const_string "mmxadd")
1443 (eq_attr "alternative" "3,4,5")
1444 (const_string "mmxmov")
1445 (eq_attr "alternative" "6")
1446 (const_string "sselog1")
1447 (eq_attr "alternative" "7,8,9,10,11")
1448 (const_string "ssemov")
1449 (match_operand:DI 1 "pic_32bit_operand" "")
1450 (const_string "lea")
1452 (const_string "imov")))
1454 (cond [(eq_attr "alternative" "2,3")
1456 (eq_attr "alternative" "6,7")
1458 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1459 (const_string "V4SF")
1460 (const_string "TI"))
1461 (and (eq_attr "alternative" "8,9,10,11")
1462 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1465 (const_string "SI")))])
1467 ;; Stores and loads of ax to arbitrary constant address.
1468 ;; We fake an second form of instruction to force reload to load address
1469 ;; into register when rax is not available
1470 (define_insn "*movabssi_1_rex64"
1471 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1472 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1473 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1475 movabs{l}\t{%1, %P0|%P0, %1}
1476 mov{l}\t{%1, %a0|%a0, %1}"
1477 [(set_attr "type" "imov")
1478 (set_attr "modrm" "0,*")
1479 (set_attr "length_address" "8,0")
1480 (set_attr "length_immediate" "0,*")
1481 (set_attr "memory" "store")
1482 (set_attr "mode" "SI")])
1484 (define_insn "*movabssi_2_rex64"
1485 [(set (match_operand:SI 0 "register_operand" "=a,r")
1486 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1487 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1489 movabs{l}\t{%P1, %0|%0, %P1}
1490 mov{l}\t{%a1, %0|%0, %a1}"
1491 [(set_attr "type" "imov")
1492 (set_attr "modrm" "0,*")
1493 (set_attr "length_address" "8,0")
1494 (set_attr "length_immediate" "0")
1495 (set_attr "memory" "load")
1496 (set_attr "mode" "SI")])
1498 (define_insn "*swapsi"
1499 [(set (match_operand:SI 0 "register_operand" "+r")
1500 (match_operand:SI 1 "register_operand" "+r"))
1505 [(set_attr "type" "imov")
1506 (set_attr "mode" "SI")
1507 (set_attr "pent_pair" "np")
1508 (set_attr "athlon_decode" "vector")
1509 (set_attr "amdfam10_decode" "double")])
1511 (define_expand "movhi"
1512 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1513 (match_operand:HI 1 "general_operand" ""))]
1515 "ix86_expand_move (HImode, operands); DONE;")
1517 (define_insn "*pushhi2"
1518 [(set (match_operand:HI 0 "push_operand" "=X")
1519 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1522 [(set_attr "type" "push")
1523 (set_attr "mode" "SI")])
1525 ;; For 64BIT abi we always round up to 8 bytes.
1526 (define_insn "*pushhi2_rex64"
1527 [(set (match_operand:HI 0 "push_operand" "=X")
1528 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1531 [(set_attr "type" "push")
1532 (set_attr "mode" "DI")])
1534 (define_insn "*movhi_1"
1535 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1536 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1537 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1539 switch (get_attr_type (insn))
1542 /* movzwl is faster than movw on p2 due to partial word stalls,
1543 though not as fast as an aligned movl. */
1544 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1546 if (get_attr_mode (insn) == MODE_SI)
1547 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1549 return "mov{w}\t{%1, %0|%0, %1}";
1553 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1554 (const_string "imov")
1555 (and (eq_attr "alternative" "0")
1556 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1558 (eq (symbol_ref "TARGET_HIMODE_MATH")
1560 (const_string "imov")
1561 (and (eq_attr "alternative" "1,2")
1562 (match_operand:HI 1 "aligned_operand" ""))
1563 (const_string "imov")
1564 (and (ne (symbol_ref "TARGET_MOVX")
1566 (eq_attr "alternative" "0,2"))
1567 (const_string "imovx")
1569 (const_string "imov")))
1571 (cond [(eq_attr "type" "imovx")
1573 (and (eq_attr "alternative" "1,2")
1574 (match_operand:HI 1 "aligned_operand" ""))
1576 (and (eq_attr "alternative" "0")
1577 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1579 (eq (symbol_ref "TARGET_HIMODE_MATH")
1583 (const_string "HI")))])
1585 ;; Stores and loads of ax to arbitrary constant address.
1586 ;; We fake an second form of instruction to force reload to load address
1587 ;; into register when rax is not available
1588 (define_insn "*movabshi_1_rex64"
1589 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1590 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1591 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1593 movabs{w}\t{%1, %P0|%P0, %1}
1594 mov{w}\t{%1, %a0|%a0, %1}"
1595 [(set_attr "type" "imov")
1596 (set_attr "modrm" "0,*")
1597 (set_attr "length_address" "8,0")
1598 (set_attr "length_immediate" "0,*")
1599 (set_attr "memory" "store")
1600 (set_attr "mode" "HI")])
1602 (define_insn "*movabshi_2_rex64"
1603 [(set (match_operand:HI 0 "register_operand" "=a,r")
1604 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1605 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1607 movabs{w}\t{%P1, %0|%0, %P1}
1608 mov{w}\t{%a1, %0|%0, %a1}"
1609 [(set_attr "type" "imov")
1610 (set_attr "modrm" "0,*")
1611 (set_attr "length_address" "8,0")
1612 (set_attr "length_immediate" "0")
1613 (set_attr "memory" "load")
1614 (set_attr "mode" "HI")])
1616 (define_insn "*swaphi_1"
1617 [(set (match_operand:HI 0 "register_operand" "+r")
1618 (match_operand:HI 1 "register_operand" "+r"))
1621 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1623 [(set_attr "type" "imov")
1624 (set_attr "mode" "SI")
1625 (set_attr "pent_pair" "np")
1626 (set_attr "athlon_decode" "vector")
1627 (set_attr "amdfam10_decode" "double")])
1629 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1630 (define_insn "*swaphi_2"
1631 [(set (match_operand:HI 0 "register_operand" "+r")
1632 (match_operand:HI 1 "register_operand" "+r"))
1635 "TARGET_PARTIAL_REG_STALL"
1637 [(set_attr "type" "imov")
1638 (set_attr "mode" "HI")
1639 (set_attr "pent_pair" "np")
1640 (set_attr "athlon_decode" "vector")])
1642 (define_expand "movstricthi"
1643 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1644 (match_operand:HI 1 "general_operand" ""))]
1645 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1647 /* Don't generate memory->memory moves, go through a register */
1648 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1649 operands[1] = force_reg (HImode, operands[1]);
1652 (define_insn "*movstricthi_1"
1653 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1654 (match_operand:HI 1 "general_operand" "rn,m"))]
1655 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1656 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1657 "mov{w}\t{%1, %0|%0, %1}"
1658 [(set_attr "type" "imov")
1659 (set_attr "mode" "HI")])
1661 (define_insn "*movstricthi_xor"
1662 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1663 (match_operand:HI 1 "const0_operand" "i"))
1664 (clobber (reg:CC FLAGS_REG))]
1666 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1668 [(set_attr "type" "alu1")
1669 (set_attr "mode" "HI")
1670 (set_attr "length_immediate" "0")])
1672 (define_expand "movqi"
1673 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1674 (match_operand:QI 1 "general_operand" ""))]
1676 "ix86_expand_move (QImode, operands); DONE;")
1678 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1679 ;; "push a byte". But actually we use pushl, which has the effect
1680 ;; of rounding the amount pushed up to a word.
1682 (define_insn "*pushqi2"
1683 [(set (match_operand:QI 0 "push_operand" "=X")
1684 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1687 [(set_attr "type" "push")
1688 (set_attr "mode" "SI")])
1690 ;; For 64BIT abi we always round up to 8 bytes.
1691 (define_insn "*pushqi2_rex64"
1692 [(set (match_operand:QI 0 "push_operand" "=X")
1693 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1696 [(set_attr "type" "push")
1697 (set_attr "mode" "DI")])
1699 ;; Situation is quite tricky about when to choose full sized (SImode) move
1700 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1701 ;; partial register dependency machines (such as AMD Athlon), where QImode
1702 ;; moves issue extra dependency and for partial register stalls machines
1703 ;; that don't use QImode patterns (and QImode move cause stall on the next
1706 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1707 ;; register stall machines with, where we use QImode instructions, since
1708 ;; partial register stall can be caused there. Then we use movzx.
1709 (define_insn "*movqi_1"
1710 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1711 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1712 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1714 switch (get_attr_type (insn))
1717 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1718 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1720 if (get_attr_mode (insn) == MODE_SI)
1721 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1723 return "mov{b}\t{%1, %0|%0, %1}";
1727 (cond [(and (eq_attr "alternative" "5")
1728 (not (match_operand:QI 1 "aligned_operand" "")))
1729 (const_string "imovx")
1730 (ne (symbol_ref "optimize_size") (const_int 0))
1731 (const_string "imov")
1732 (and (eq_attr "alternative" "3")
1733 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1735 (eq (symbol_ref "TARGET_QIMODE_MATH")
1737 (const_string "imov")
1738 (eq_attr "alternative" "3,5")
1739 (const_string "imovx")
1740 (and (ne (symbol_ref "TARGET_MOVX")
1742 (eq_attr "alternative" "2"))
1743 (const_string "imovx")
1745 (const_string "imov")))
1747 (cond [(eq_attr "alternative" "3,4,5")
1749 (eq_attr "alternative" "6")
1751 (eq_attr "type" "imovx")
1753 (and (eq_attr "type" "imov")
1754 (and (eq_attr "alternative" "0,1")
1755 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1757 (and (eq (symbol_ref "optimize_size")
1759 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1762 ;; Avoid partial register stalls when not using QImode arithmetic
1763 (and (eq_attr "type" "imov")
1764 (and (eq_attr "alternative" "0,1")
1765 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1767 (eq (symbol_ref "TARGET_QIMODE_MATH")
1771 (const_string "QI")))])
1773 (define_expand "reload_outqi"
1774 [(parallel [(match_operand:QI 0 "" "=m")
1775 (match_operand:QI 1 "register_operand" "r")
1776 (match_operand:QI 2 "register_operand" "=&q")])]
1780 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1782 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1783 if (! q_regs_operand (op1, QImode))
1785 emit_insn (gen_movqi (op2, op1));
1788 emit_insn (gen_movqi (op0, op1));
1792 (define_insn "*swapqi_1"
1793 [(set (match_operand:QI 0 "register_operand" "+r")
1794 (match_operand:QI 1 "register_operand" "+r"))
1797 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1799 [(set_attr "type" "imov")
1800 (set_attr "mode" "SI")
1801 (set_attr "pent_pair" "np")
1802 (set_attr "athlon_decode" "vector")
1803 (set_attr "amdfam10_decode" "vector")])
1805 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1806 (define_insn "*swapqi_2"
1807 [(set (match_operand:QI 0 "register_operand" "+q")
1808 (match_operand:QI 1 "register_operand" "+q"))
1811 "TARGET_PARTIAL_REG_STALL"
1813 [(set_attr "type" "imov")
1814 (set_attr "mode" "QI")
1815 (set_attr "pent_pair" "np")
1816 (set_attr "athlon_decode" "vector")])
1818 (define_expand "movstrictqi"
1819 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1820 (match_operand:QI 1 "general_operand" ""))]
1821 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1823 /* Don't generate memory->memory moves, go through a register. */
1824 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1825 operands[1] = force_reg (QImode, operands[1]);
1828 (define_insn "*movstrictqi_1"
1829 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1830 (match_operand:QI 1 "general_operand" "*qn,m"))]
1831 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1832 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1833 "mov{b}\t{%1, %0|%0, %1}"
1834 [(set_attr "type" "imov")
1835 (set_attr "mode" "QI")])
1837 (define_insn "*movstrictqi_xor"
1838 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1839 (match_operand:QI 1 "const0_operand" "i"))
1840 (clobber (reg:CC FLAGS_REG))]
1841 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1843 [(set_attr "type" "alu1")
1844 (set_attr "mode" "QI")
1845 (set_attr "length_immediate" "0")])
1847 (define_insn "*movsi_extv_1"
1848 [(set (match_operand:SI 0 "register_operand" "=R")
1849 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1853 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1854 [(set_attr "type" "imovx")
1855 (set_attr "mode" "SI")])
1857 (define_insn "*movhi_extv_1"
1858 [(set (match_operand:HI 0 "register_operand" "=R")
1859 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1863 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1864 [(set_attr "type" "imovx")
1865 (set_attr "mode" "SI")])
1867 (define_insn "*movqi_extv_1"
1868 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1869 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1874 switch (get_attr_type (insn))
1877 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1879 return "mov{b}\t{%h1, %0|%0, %h1}";
1883 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1884 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1885 (ne (symbol_ref "TARGET_MOVX")
1887 (const_string "imovx")
1888 (const_string "imov")))
1890 (if_then_else (eq_attr "type" "imovx")
1892 (const_string "QI")))])
1894 (define_insn "*movqi_extv_1_rex64"
1895 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1896 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1901 switch (get_attr_type (insn))
1904 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1906 return "mov{b}\t{%h1, %0|%0, %h1}";
1910 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1911 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1912 (ne (symbol_ref "TARGET_MOVX")
1914 (const_string "imovx")
1915 (const_string "imov")))
1917 (if_then_else (eq_attr "type" "imovx")
1919 (const_string "QI")))])
1921 ;; Stores and loads of ax to arbitrary constant address.
1922 ;; We fake an second form of instruction to force reload to load address
1923 ;; into register when rax is not available
1924 (define_insn "*movabsqi_1_rex64"
1925 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1926 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1927 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1929 movabs{b}\t{%1, %P0|%P0, %1}
1930 mov{b}\t{%1, %a0|%a0, %1}"
1931 [(set_attr "type" "imov")
1932 (set_attr "modrm" "0,*")
1933 (set_attr "length_address" "8,0")
1934 (set_attr "length_immediate" "0,*")
1935 (set_attr "memory" "store")
1936 (set_attr "mode" "QI")])
1938 (define_insn "*movabsqi_2_rex64"
1939 [(set (match_operand:QI 0 "register_operand" "=a,r")
1940 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1941 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1943 movabs{b}\t{%P1, %0|%0, %P1}
1944 mov{b}\t{%a1, %0|%0, %a1}"
1945 [(set_attr "type" "imov")
1946 (set_attr "modrm" "0,*")
1947 (set_attr "length_address" "8,0")
1948 (set_attr "length_immediate" "0")
1949 (set_attr "memory" "load")
1950 (set_attr "mode" "QI")])
1952 (define_insn "*movdi_extzv_1"
1953 [(set (match_operand:DI 0 "register_operand" "=R")
1954 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1958 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1959 [(set_attr "type" "imovx")
1960 (set_attr "mode" "DI")])
1962 (define_insn "*movsi_extzv_1"
1963 [(set (match_operand:SI 0 "register_operand" "=R")
1964 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1968 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1969 [(set_attr "type" "imovx")
1970 (set_attr "mode" "SI")])
1972 (define_insn "*movqi_extzv_2"
1973 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1974 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1979 switch (get_attr_type (insn))
1982 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1984 return "mov{b}\t{%h1, %0|%0, %h1}";
1988 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1989 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1990 (ne (symbol_ref "TARGET_MOVX")
1992 (const_string "imovx")
1993 (const_string "imov")))
1995 (if_then_else (eq_attr "type" "imovx")
1997 (const_string "QI")))])
1999 (define_insn "*movqi_extzv_2_rex64"
2000 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2001 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2006 switch (get_attr_type (insn))
2009 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2011 return "mov{b}\t{%h1, %0|%0, %h1}";
2015 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2016 (ne (symbol_ref "TARGET_MOVX")
2018 (const_string "imovx")
2019 (const_string "imov")))
2021 (if_then_else (eq_attr "type" "imovx")
2023 (const_string "QI")))])
2025 (define_insn "movsi_insv_1"
2026 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2029 (match_operand:SI 1 "general_operand" "Qmn"))]
2031 "mov{b}\t{%b1, %h0|%h0, %b1}"
2032 [(set_attr "type" "imov")
2033 (set_attr "mode" "QI")])
2035 (define_insn "*movsi_insv_1_rex64"
2036 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2039 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2041 "mov{b}\t{%b1, %h0|%h0, %b1}"
2042 [(set_attr "type" "imov")
2043 (set_attr "mode" "QI")])
2045 (define_insn "movdi_insv_1_rex64"
2046 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2049 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2051 "mov{b}\t{%b1, %h0|%h0, %b1}"
2052 [(set_attr "type" "imov")
2053 (set_attr "mode" "QI")])
2055 (define_insn "*movqi_insv_2"
2056 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2059 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2062 "mov{b}\t{%h1, %h0|%h0, %h1}"
2063 [(set_attr "type" "imov")
2064 (set_attr "mode" "QI")])
2066 (define_expand "movdi"
2067 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2068 (match_operand:DI 1 "general_operand" ""))]
2070 "ix86_expand_move (DImode, operands); DONE;")
2072 (define_insn "*pushdi"
2073 [(set (match_operand:DI 0 "push_operand" "=<")
2074 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2078 (define_insn "*pushdi2_rex64"
2079 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2080 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2085 [(set_attr "type" "push,multi")
2086 (set_attr "mode" "DI")])
2088 ;; Convert impossible pushes of immediate to existing instructions.
2089 ;; First try to get scratch register and go through it. In case this
2090 ;; fails, push sign extended lower part first and then overwrite
2091 ;; upper part by 32bit move.
2093 [(match_scratch:DI 2 "r")
2094 (set (match_operand:DI 0 "push_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2097 && !x86_64_immediate_operand (operands[1], DImode)"
2098 [(set (match_dup 2) (match_dup 1))
2099 (set (match_dup 0) (match_dup 2))]
2102 ;; We need to define this as both peepholer and splitter for case
2103 ;; peephole2 pass is not run.
2104 ;; "&& 1" is needed to keep it from matching the previous pattern.
2106 [(set (match_operand:DI 0 "push_operand" "")
2107 (match_operand:DI 1 "immediate_operand" ""))]
2108 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2109 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2110 [(set (match_dup 0) (match_dup 1))
2111 (set (match_dup 2) (match_dup 3))]
2112 "split_di (operands + 1, 1, operands + 2, operands + 3);
2113 operands[1] = gen_lowpart (DImode, operands[2]);
2114 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2119 [(set (match_operand:DI 0 "push_operand" "")
2120 (match_operand:DI 1 "immediate_operand" ""))]
2121 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2122 ? epilogue_completed : reload_completed)
2123 && !symbolic_operand (operands[1], DImode)
2124 && !x86_64_immediate_operand (operands[1], DImode)"
2125 [(set (match_dup 0) (match_dup 1))
2126 (set (match_dup 2) (match_dup 3))]
2127 "split_di (operands + 1, 1, operands + 2, operands + 3);
2128 operands[1] = gen_lowpart (DImode, operands[2]);
2129 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2133 (define_insn "*pushdi2_prologue_rex64"
2134 [(set (match_operand:DI 0 "push_operand" "=<")
2135 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2136 (clobber (mem:BLK (scratch)))]
2139 [(set_attr "type" "push")
2140 (set_attr "mode" "DI")])
2142 (define_insn "*popdi1_epilogue_rex64"
2143 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2144 (mem:DI (reg:DI SP_REG)))
2145 (set (reg:DI SP_REG)
2146 (plus:DI (reg:DI SP_REG) (const_int 8)))
2147 (clobber (mem:BLK (scratch)))]
2150 [(set_attr "type" "pop")
2151 (set_attr "mode" "DI")])
2153 (define_insn "popdi1"
2154 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2155 (mem:DI (reg:DI SP_REG)))
2156 (set (reg:DI SP_REG)
2157 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2160 [(set_attr "type" "pop")
2161 (set_attr "mode" "DI")])
2163 (define_insn "*movdi_xor_rex64"
2164 [(set (match_operand:DI 0 "register_operand" "=r")
2165 (match_operand:DI 1 "const0_operand" "i"))
2166 (clobber (reg:CC FLAGS_REG))]
2167 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2168 && reload_completed"
2170 [(set_attr "type" "alu1")
2171 (set_attr "mode" "SI")
2172 (set_attr "length_immediate" "0")])
2174 (define_insn "*movdi_or_rex64"
2175 [(set (match_operand:DI 0 "register_operand" "=r")
2176 (match_operand:DI 1 "const_int_operand" "i"))
2177 (clobber (reg:CC FLAGS_REG))]
2178 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2180 && operands[1] == constm1_rtx"
2182 operands[1] = constm1_rtx;
2183 return "or{q}\t{%1, %0|%0, %1}";
2185 [(set_attr "type" "alu1")
2186 (set_attr "mode" "DI")
2187 (set_attr "length_immediate" "1")])
2189 (define_insn "*movdi_2"
2190 [(set (match_operand:DI 0 "nonimmediate_operand"
2191 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2192 (match_operand:DI 1 "general_operand"
2193 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2194 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2199 movq\t{%1, %0|%0, %1}
2200 movq\t{%1, %0|%0, %1}
2202 movq\t{%1, %0|%0, %1}
2203 movdqa\t{%1, %0|%0, %1}
2204 movq\t{%1, %0|%0, %1}
2206 movlps\t{%1, %0|%0, %1}
2207 movaps\t{%1, %0|%0, %1}
2208 movlps\t{%1, %0|%0, %1}"
2209 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2210 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2213 [(set (match_operand:DI 0 "push_operand" "")
2214 (match_operand:DI 1 "general_operand" ""))]
2215 "!TARGET_64BIT && reload_completed
2216 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2218 "ix86_split_long_move (operands); DONE;")
2220 ;; %%% This multiword shite has got to go.
2222 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2223 (match_operand:DI 1 "general_operand" ""))]
2224 "!TARGET_64BIT && reload_completed
2225 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2226 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2228 "ix86_split_long_move (operands); DONE;")
2230 (define_insn "*movdi_1_rex64"
2231 [(set (match_operand:DI 0 "nonimmediate_operand"
2232 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2233 (match_operand:DI 1 "general_operand"
2234 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2235 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2237 switch (get_attr_type (insn))
2240 if (SSE_REG_P (operands[0]))
2241 return "movq2dq\t{%1, %0|%0, %1}";
2243 return "movdq2q\t{%1, %0|%0, %1}";
2246 if (get_attr_mode (insn) == MODE_TI)
2247 return "movdqa\t{%1, %0|%0, %1}";
2251 /* Moves from and into integer register is done using movd
2252 opcode with REX prefix. */
2253 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2254 return "movd\t{%1, %0|%0, %1}";
2255 return "movq\t{%1, %0|%0, %1}";
2259 return "pxor\t%0, %0";
2265 return "lea{q}\t{%a1, %0|%0, %a1}";
2268 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2269 if (get_attr_mode (insn) == MODE_SI)
2270 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2271 else if (which_alternative == 2)
2272 return "movabs{q}\t{%1, %0|%0, %1}";
2274 return "mov{q}\t{%1, %0|%0, %1}";
2278 (cond [(eq_attr "alternative" "5")
2279 (const_string "mmxadd")
2280 (eq_attr "alternative" "6,7,8,9,10")
2281 (const_string "mmxmov")
2282 (eq_attr "alternative" "11")
2283 (const_string "sselog1")
2284 (eq_attr "alternative" "12,13,14,15,16")
2285 (const_string "ssemov")
2286 (eq_attr "alternative" "17,18")
2287 (const_string "ssecvt")
2288 (eq_attr "alternative" "4")
2289 (const_string "multi")
2290 (match_operand:DI 1 "pic_32bit_operand" "")
2291 (const_string "lea")
2293 (const_string "imov")))
2294 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2295 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2296 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2298 ;; Stores and loads of ax to arbitrary constant address.
2299 ;; We fake an second form of instruction to force reload to load address
2300 ;; into register when rax is not available
2301 (define_insn "*movabsdi_1_rex64"
2302 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2303 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2304 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2306 movabs{q}\t{%1, %P0|%P0, %1}
2307 mov{q}\t{%1, %a0|%a0, %1}"
2308 [(set_attr "type" "imov")
2309 (set_attr "modrm" "0,*")
2310 (set_attr "length_address" "8,0")
2311 (set_attr "length_immediate" "0,*")
2312 (set_attr "memory" "store")
2313 (set_attr "mode" "DI")])
2315 (define_insn "*movabsdi_2_rex64"
2316 [(set (match_operand:DI 0 "register_operand" "=a,r")
2317 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2318 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2320 movabs{q}\t{%P1, %0|%0, %P1}
2321 mov{q}\t{%a1, %0|%0, %a1}"
2322 [(set_attr "type" "imov")
2323 (set_attr "modrm" "0,*")
2324 (set_attr "length_address" "8,0")
2325 (set_attr "length_immediate" "0")
2326 (set_attr "memory" "load")
2327 (set_attr "mode" "DI")])
2329 ;; Convert impossible stores of immediate to existing instructions.
2330 ;; First try to get scratch register and go through it. In case this
2331 ;; fails, move by 32bit parts.
2333 [(match_scratch:DI 2 "r")
2334 (set (match_operand:DI 0 "memory_operand" "")
2335 (match_operand:DI 1 "immediate_operand" ""))]
2336 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2337 && !x86_64_immediate_operand (operands[1], DImode)"
2338 [(set (match_dup 2) (match_dup 1))
2339 (set (match_dup 0) (match_dup 2))]
2342 ;; We need to define this as both peepholer and splitter for case
2343 ;; peephole2 pass is not run.
2344 ;; "&& 1" is needed to keep it from matching the previous pattern.
2346 [(set (match_operand:DI 0 "memory_operand" "")
2347 (match_operand:DI 1 "immediate_operand" ""))]
2348 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2349 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2350 [(set (match_dup 2) (match_dup 3))
2351 (set (match_dup 4) (match_dup 5))]
2352 "split_di (operands, 2, operands + 2, operands + 4);")
2355 [(set (match_operand:DI 0 "memory_operand" "")
2356 (match_operand:DI 1 "immediate_operand" ""))]
2357 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2358 ? epilogue_completed : reload_completed)
2359 && !symbolic_operand (operands[1], DImode)
2360 && !x86_64_immediate_operand (operands[1], DImode)"
2361 [(set (match_dup 2) (match_dup 3))
2362 (set (match_dup 4) (match_dup 5))]
2363 "split_di (operands, 2, operands + 2, operands + 4);")
2365 (define_insn "*swapdi_rex64"
2366 [(set (match_operand:DI 0 "register_operand" "+r")
2367 (match_operand:DI 1 "register_operand" "+r"))
2372 [(set_attr "type" "imov")
2373 (set_attr "mode" "DI")
2374 (set_attr "pent_pair" "np")
2375 (set_attr "athlon_decode" "vector")
2376 (set_attr "amdfam10_decode" "double")])
2378 (define_expand "movti"
2379 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2380 (match_operand:TI 1 "nonimmediate_operand" ""))]
2381 "TARGET_SSE || TARGET_64BIT"
2384 ix86_expand_move (TImode, operands);
2385 else if (push_operand (operands[0], TImode))
2386 ix86_expand_push (TImode, operands[1]);
2388 ix86_expand_vector_move (TImode, operands);
2392 (define_insn "*movti_internal"
2393 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2394 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2395 "TARGET_SSE && !TARGET_64BIT
2396 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2398 switch (which_alternative)
2401 if (get_attr_mode (insn) == MODE_V4SF)
2402 return "xorps\t%0, %0";
2404 return "pxor\t%0, %0";
2407 /* TDmode values are passed as TImode on the stack. Moving them
2408 to stack may result in unaligned memory access. */
2409 if (misaligned_operand (operands[0], TImode)
2410 || misaligned_operand (operands[1], TImode))
2412 if (get_attr_mode (insn) == MODE_V4SF)
2413 return "movups\t{%1, %0|%0, %1}";
2415 return "movdqu\t{%1, %0|%0, %1}";
2419 if (get_attr_mode (insn) == MODE_V4SF)
2420 return "movaps\t{%1, %0|%0, %1}";
2422 return "movdqa\t{%1, %0|%0, %1}";
2428 [(set_attr "type" "sselog1,ssemov,ssemov")
2430 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2431 (ne (symbol_ref "optimize_size") (const_int 0)))
2432 (const_string "V4SF")
2433 (and (eq_attr "alternative" "2")
2434 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2436 (const_string "V4SF")]
2437 (const_string "TI")))])
2439 (define_insn "*movti_rex64"
2440 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2441 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2443 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2445 switch (which_alternative)
2451 if (get_attr_mode (insn) == MODE_V4SF)
2452 return "xorps\t%0, %0";
2454 return "pxor\t%0, %0";
2457 /* TDmode values are passed as TImode on the stack. Moving them
2458 to stack may result in unaligned memory access. */
2459 if (misaligned_operand (operands[0], TImode)
2460 || misaligned_operand (operands[1], TImode))
2462 if (get_attr_mode (insn) == MODE_V4SF)
2463 return "movups\t{%1, %0|%0, %1}";
2465 return "movdqu\t{%1, %0|%0, %1}";
2469 if (get_attr_mode (insn) == MODE_V4SF)
2470 return "movaps\t{%1, %0|%0, %1}";
2472 return "movdqa\t{%1, %0|%0, %1}";
2478 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2480 (cond [(eq_attr "alternative" "2,3")
2482 (ne (symbol_ref "optimize_size")
2484 (const_string "V4SF")
2485 (const_string "TI"))
2486 (eq_attr "alternative" "4")
2488 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2490 (ne (symbol_ref "optimize_size")
2492 (const_string "V4SF")
2493 (const_string "TI"))]
2494 (const_string "DI")))])
2497 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2498 (match_operand:TI 1 "general_operand" ""))]
2499 "reload_completed && !SSE_REG_P (operands[0])
2500 && !SSE_REG_P (operands[1])"
2502 "ix86_split_long_move (operands); DONE;")
2504 ;; This expands to what emit_move_complex would generate if we didn't
2505 ;; have a movti pattern. Having this avoids problems with reload on
2506 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2507 ;; to have around all the time.
2508 (define_expand "movcdi"
2509 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2510 (match_operand:CDI 1 "general_operand" ""))]
2513 if (push_operand (operands[0], CDImode))
2514 emit_move_complex_push (CDImode, operands[0], operands[1]);
2516 emit_move_complex_parts (operands[0], operands[1]);
2520 (define_expand "movsf"
2521 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2522 (match_operand:SF 1 "general_operand" ""))]
2524 "ix86_expand_move (SFmode, operands); DONE;")
2526 (define_insn "*pushsf"
2527 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2528 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2531 /* Anything else should be already split before reg-stack. */
2532 gcc_assert (which_alternative == 1);
2533 return "push{l}\t%1";
2535 [(set_attr "type" "multi,push,multi")
2536 (set_attr "unit" "i387,*,*")
2537 (set_attr "mode" "SF,SI,SF")])
2539 (define_insn "*pushsf_rex64"
2540 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2541 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2544 /* Anything else should be already split before reg-stack. */
2545 gcc_assert (which_alternative == 1);
2546 return "push{q}\t%q1";
2548 [(set_attr "type" "multi,push,multi")
2549 (set_attr "unit" "i387,*,*")
2550 (set_attr "mode" "SF,DI,SF")])
2553 [(set (match_operand:SF 0 "push_operand" "")
2554 (match_operand:SF 1 "memory_operand" ""))]
2556 && MEM_P (operands[1])
2557 && (operands[2] = find_constant_src (insn))"
2562 ;; %%% Kill this when call knows how to work this out.
2564 [(set (match_operand:SF 0 "push_operand" "")
2565 (match_operand:SF 1 "any_fp_register_operand" ""))]
2567 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2568 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2571 [(set (match_operand:SF 0 "push_operand" "")
2572 (match_operand:SF 1 "any_fp_register_operand" ""))]
2574 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2575 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2577 (define_insn "*movsf_1"
2578 [(set (match_operand:SF 0 "nonimmediate_operand"
2579 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2580 (match_operand:SF 1 "general_operand"
2581 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2582 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2583 && (reload_in_progress || reload_completed
2584 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2585 || (!TARGET_SSE_MATH && optimize_size
2586 && standard_80387_constant_p (operands[1]))
2587 || GET_CODE (operands[1]) != CONST_DOUBLE
2588 || memory_operand (operands[0], SFmode))"
2590 switch (which_alternative)
2594 return output_387_reg_move (insn, operands);
2597 return standard_80387_constant_opcode (operands[1]);
2601 return "mov{l}\t{%1, %0|%0, %1}";
2603 if (get_attr_mode (insn) == MODE_TI)
2604 return "pxor\t%0, %0";
2606 return "xorps\t%0, %0";
2608 if (get_attr_mode (insn) == MODE_V4SF)
2609 return "movaps\t{%1, %0|%0, %1}";
2611 return "movss\t{%1, %0|%0, %1}";
2613 return "movss\t{%1, %0|%0, %1}";
2616 case 12: case 13: case 14: case 15:
2617 return "movd\t{%1, %0|%0, %1}";
2620 return "movq\t{%1, %0|%0, %1}";
2626 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2628 (cond [(eq_attr "alternative" "3,4,9,10")
2630 (eq_attr "alternative" "5")
2632 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2634 (ne (symbol_ref "TARGET_SSE2")
2636 (eq (symbol_ref "optimize_size")
2639 (const_string "V4SF"))
2640 /* For architectures resolving dependencies on
2641 whole SSE registers use APS move to break dependency
2642 chains, otherwise use short move to avoid extra work.
2644 Do the same for architectures resolving dependencies on
2645 the parts. While in DF mode it is better to always handle
2646 just register parts, the SF mode is different due to lack
2647 of instructions to load just part of the register. It is
2648 better to maintain the whole registers in single format
2649 to avoid problems on using packed logical operations. */
2650 (eq_attr "alternative" "6")
2652 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2654 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2656 (const_string "V4SF")
2657 (const_string "SF"))
2658 (eq_attr "alternative" "11")
2659 (const_string "DI")]
2660 (const_string "SF")))])
2662 (define_insn "*swapsf"
2663 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2664 (match_operand:SF 1 "fp_register_operand" "+f"))
2667 "reload_completed || TARGET_80387"
2669 if (STACK_TOP_P (operands[0]))
2674 [(set_attr "type" "fxch")
2675 (set_attr "mode" "SF")])
2677 (define_expand "movdf"
2678 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2679 (match_operand:DF 1 "general_operand" ""))]
2681 "ix86_expand_move (DFmode, operands); DONE;")
2683 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2684 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2685 ;; On the average, pushdf using integers can be still shorter. Allow this
2686 ;; pattern for optimize_size too.
2688 (define_insn "*pushdf_nointeger"
2689 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2690 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2691 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2693 /* This insn should be already split before reg-stack. */
2696 [(set_attr "type" "multi")
2697 (set_attr "unit" "i387,*,*,*")
2698 (set_attr "mode" "DF,SI,SI,DF")])
2700 (define_insn "*pushdf_integer"
2701 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2702 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2703 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2705 /* This insn should be already split before reg-stack. */
2708 [(set_attr "type" "multi")
2709 (set_attr "unit" "i387,*,*")
2710 (set_attr "mode" "DF,SI,DF")])
2712 ;; %%% Kill this when call knows how to work this out.
2714 [(set (match_operand:DF 0 "push_operand" "")
2715 (match_operand:DF 1 "any_fp_register_operand" ""))]
2716 "!TARGET_64BIT && reload_completed"
2717 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2718 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2722 [(set (match_operand:DF 0 "push_operand" "")
2723 (match_operand:DF 1 "any_fp_register_operand" ""))]
2724 "TARGET_64BIT && reload_completed"
2725 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2726 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2730 [(set (match_operand:DF 0 "push_operand" "")
2731 (match_operand:DF 1 "general_operand" ""))]
2734 "ix86_split_long_move (operands); DONE;")
2736 ;; Moving is usually shorter when only FP registers are used. This separate
2737 ;; movdf pattern avoids the use of integer registers for FP operations
2738 ;; when optimizing for size.
2740 (define_insn "*movdf_nointeger"
2741 [(set (match_operand:DF 0 "nonimmediate_operand"
2742 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2743 (match_operand:DF 1 "general_operand"
2744 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2745 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2746 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2747 && (reload_in_progress || reload_completed
2748 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2749 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2750 && !memory_operand (operands[0], DFmode)
2751 && standard_80387_constant_p (operands[1]))
2752 || GET_CODE (operands[1]) != CONST_DOUBLE
2754 || !TARGET_MEMORY_MISMATCH_STALL
2755 || reload_in_progress || reload_completed)
2756 && memory_operand (operands[0], DFmode)))"
2758 switch (which_alternative)
2762 return output_387_reg_move (insn, operands);
2765 return standard_80387_constant_opcode (operands[1]);
2771 switch (get_attr_mode (insn))
2774 return "xorps\t%0, %0";
2776 return "xorpd\t%0, %0";
2778 return "pxor\t%0, %0";
2785 switch (get_attr_mode (insn))
2788 return "movaps\t{%1, %0|%0, %1}";
2790 return "movapd\t{%1, %0|%0, %1}";
2792 return "movdqa\t{%1, %0|%0, %1}";
2794 return "movq\t{%1, %0|%0, %1}";
2796 return "movsd\t{%1, %0|%0, %1}";
2798 return "movlpd\t{%1, %0|%0, %1}";
2800 return "movlps\t{%1, %0|%0, %1}";
2809 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2811 (cond [(eq_attr "alternative" "0,1,2")
2813 (eq_attr "alternative" "3,4")
2816 /* For SSE1, we have many fewer alternatives. */
2817 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2818 (cond [(eq_attr "alternative" "5,6")
2819 (const_string "V4SF")
2821 (const_string "V2SF"))
2823 /* xorps is one byte shorter. */
2824 (eq_attr "alternative" "5")
2825 (cond [(ne (symbol_ref "optimize_size")
2827 (const_string "V4SF")
2828 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2832 (const_string "V2DF"))
2834 /* For architectures resolving dependencies on
2835 whole SSE registers use APD move to break dependency
2836 chains, otherwise use short move to avoid extra work.
2838 movaps encodes one byte shorter. */
2839 (eq_attr "alternative" "6")
2841 [(ne (symbol_ref "optimize_size")
2843 (const_string "V4SF")
2844 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2846 (const_string "V2DF")
2848 (const_string "DF"))
2849 /* For architectures resolving dependencies on register
2850 parts we may avoid extra work to zero out upper part
2852 (eq_attr "alternative" "7")
2854 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2856 (const_string "V1DF")
2857 (const_string "DF"))
2859 (const_string "DF")))])
2861 (define_insn "*movdf_integer_rex64"
2862 [(set (match_operand:DF 0 "nonimmediate_operand"
2863 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2864 (match_operand:DF 1 "general_operand"
2865 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2866 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2867 && (reload_in_progress || reload_completed
2868 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2869 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2870 && standard_80387_constant_p (operands[1]))
2871 || GET_CODE (operands[1]) != CONST_DOUBLE
2872 || memory_operand (operands[0], DFmode))"
2874 switch (which_alternative)
2878 return output_387_reg_move (insn, operands);
2881 return standard_80387_constant_opcode (operands[1]);
2888 switch (get_attr_mode (insn))
2891 return "xorps\t%0, %0";
2893 return "xorpd\t%0, %0";
2895 return "pxor\t%0, %0";
2902 switch (get_attr_mode (insn))
2905 return "movaps\t{%1, %0|%0, %1}";
2907 return "movapd\t{%1, %0|%0, %1}";
2909 return "movdqa\t{%1, %0|%0, %1}";
2911 return "movq\t{%1, %0|%0, %1}";
2913 return "movsd\t{%1, %0|%0, %1}";
2915 return "movlpd\t{%1, %0|%0, %1}";
2917 return "movlps\t{%1, %0|%0, %1}";
2924 return "movd\t{%1, %0|%0, %1}";
2930 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2932 (cond [(eq_attr "alternative" "0,1,2")
2934 (eq_attr "alternative" "3,4,9,10")
2937 /* For SSE1, we have many fewer alternatives. */
2938 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2939 (cond [(eq_attr "alternative" "5,6")
2940 (const_string "V4SF")
2942 (const_string "V2SF"))
2944 /* xorps is one byte shorter. */
2945 (eq_attr "alternative" "5")
2946 (cond [(ne (symbol_ref "optimize_size")
2948 (const_string "V4SF")
2949 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2953 (const_string "V2DF"))
2955 /* For architectures resolving dependencies on
2956 whole SSE registers use APD move to break dependency
2957 chains, otherwise use short move to avoid extra work.
2959 movaps encodes one byte shorter. */
2960 (eq_attr "alternative" "6")
2962 [(ne (symbol_ref "optimize_size")
2964 (const_string "V4SF")
2965 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2967 (const_string "V2DF")
2969 (const_string "DF"))
2970 /* For architectures resolving dependencies on register
2971 parts we may avoid extra work to zero out upper part
2973 (eq_attr "alternative" "7")
2975 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2977 (const_string "V1DF")
2978 (const_string "DF"))
2980 (const_string "DF")))])
2982 (define_insn "*movdf_integer"
2983 [(set (match_operand:DF 0 "nonimmediate_operand"
2984 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2985 (match_operand:DF 1 "general_operand"
2986 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2987 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2988 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2989 && (reload_in_progress || reload_completed
2990 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2991 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2992 && standard_80387_constant_p (operands[1]))
2993 || GET_CODE (operands[1]) != CONST_DOUBLE
2994 || memory_operand (operands[0], DFmode))"
2996 switch (which_alternative)
3000 return output_387_reg_move (insn, operands);
3003 return standard_80387_constant_opcode (operands[1]);
3010 switch (get_attr_mode (insn))
3013 return "xorps\t%0, %0";
3015 return "xorpd\t%0, %0";
3017 return "pxor\t%0, %0";
3024 switch (get_attr_mode (insn))
3027 return "movaps\t{%1, %0|%0, %1}";
3029 return "movapd\t{%1, %0|%0, %1}";
3031 return "movdqa\t{%1, %0|%0, %1}";
3033 return "movq\t{%1, %0|%0, %1}";
3035 return "movsd\t{%1, %0|%0, %1}";
3037 return "movlpd\t{%1, %0|%0, %1}";
3039 return "movlps\t{%1, %0|%0, %1}";
3048 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3050 (cond [(eq_attr "alternative" "0,1,2")
3052 (eq_attr "alternative" "3,4")
3055 /* For SSE1, we have many fewer alternatives. */
3056 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3057 (cond [(eq_attr "alternative" "5,6")
3058 (const_string "V4SF")
3060 (const_string "V2SF"))
3062 /* xorps is one byte shorter. */
3063 (eq_attr "alternative" "5")
3064 (cond [(ne (symbol_ref "optimize_size")
3066 (const_string "V4SF")
3067 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3071 (const_string "V2DF"))
3073 /* For architectures resolving dependencies on
3074 whole SSE registers use APD move to break dependency
3075 chains, otherwise use short move to avoid extra work.
3077 movaps encodes one byte shorter. */
3078 (eq_attr "alternative" "6")
3080 [(ne (symbol_ref "optimize_size")
3082 (const_string "V4SF")
3083 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3085 (const_string "V2DF")
3087 (const_string "DF"))
3088 /* For architectures resolving dependencies on register
3089 parts we may avoid extra work to zero out upper part
3091 (eq_attr "alternative" "7")
3093 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3095 (const_string "V1DF")
3096 (const_string "DF"))
3098 (const_string "DF")))])
3101 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3102 (match_operand:DF 1 "general_operand" ""))]
3104 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3105 && ! (ANY_FP_REG_P (operands[0]) ||
3106 (GET_CODE (operands[0]) == SUBREG
3107 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3108 && ! (ANY_FP_REG_P (operands[1]) ||
3109 (GET_CODE (operands[1]) == SUBREG
3110 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3112 "ix86_split_long_move (operands); DONE;")
3114 (define_insn "*swapdf"
3115 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3116 (match_operand:DF 1 "fp_register_operand" "+f"))
3119 "reload_completed || TARGET_80387"
3121 if (STACK_TOP_P (operands[0]))
3126 [(set_attr "type" "fxch")
3127 (set_attr "mode" "DF")])
3129 (define_expand "movxf"
3130 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3131 (match_operand:XF 1 "general_operand" ""))]
3133 "ix86_expand_move (XFmode, operands); DONE;")
3135 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3136 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3137 ;; Pushing using integer instructions is longer except for constants
3138 ;; and direct memory references.
3139 ;; (assuming that any given constant is pushed only once, but this ought to be
3140 ;; handled elsewhere).
3142 (define_insn "*pushxf_nointeger"
3143 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3144 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3147 /* This insn should be already split before reg-stack. */
3150 [(set_attr "type" "multi")
3151 (set_attr "unit" "i387,*,*")
3152 (set_attr "mode" "XF,SI,SI")])
3154 (define_insn "*pushxf_integer"
3155 [(set (match_operand:XF 0 "push_operand" "=<,<")
3156 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3159 /* This insn should be already split before reg-stack. */
3162 [(set_attr "type" "multi")
3163 (set_attr "unit" "i387,*")
3164 (set_attr "mode" "XF,SI")])
3167 [(set (match_operand 0 "push_operand" "")
3168 (match_operand 1 "general_operand" ""))]
3170 && (GET_MODE (operands[0]) == XFmode
3171 || GET_MODE (operands[0]) == DFmode)
3172 && !ANY_FP_REG_P (operands[1])"
3174 "ix86_split_long_move (operands); DONE;")
3177 [(set (match_operand:XF 0 "push_operand" "")
3178 (match_operand:XF 1 "any_fp_register_operand" ""))]
3180 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3181 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3182 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3185 [(set (match_operand:XF 0 "push_operand" "")
3186 (match_operand:XF 1 "any_fp_register_operand" ""))]
3188 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3189 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3190 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3192 ;; Do not use integer registers when optimizing for size
3193 (define_insn "*movxf_nointeger"
3194 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3195 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3197 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3198 && (reload_in_progress || reload_completed
3199 || (optimize_size && standard_80387_constant_p (operands[1]))
3200 || GET_CODE (operands[1]) != CONST_DOUBLE
3201 || memory_operand (operands[0], XFmode))"
3203 switch (which_alternative)
3207 return output_387_reg_move (insn, operands);
3210 return standard_80387_constant_opcode (operands[1]);
3218 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3219 (set_attr "mode" "XF,XF,XF,SI,SI")])
3221 (define_insn "*movxf_integer"
3222 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3223 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3225 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3226 && (reload_in_progress || reload_completed
3227 || (optimize_size && standard_80387_constant_p (operands[1]))
3228 || GET_CODE (operands[1]) != CONST_DOUBLE
3229 || memory_operand (operands[0], XFmode))"
3231 switch (which_alternative)
3235 return output_387_reg_move (insn, operands);
3238 return standard_80387_constant_opcode (operands[1]);
3247 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3248 (set_attr "mode" "XF,XF,XF,SI,SI")])
3250 (define_expand "movtf"
3251 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3252 (match_operand:TF 1 "nonimmediate_operand" ""))]
3255 ix86_expand_move (TFmode, operands);
3259 (define_insn "*movtf_internal"
3260 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3261 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3263 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3265 switch (which_alternative)
3269 if (get_attr_mode (insn) == MODE_V4SF)
3270 return "movaps\t{%1, %0|%0, %1}";
3272 return "movdqa\t{%1, %0|%0, %1}";
3274 if (get_attr_mode (insn) == MODE_V4SF)
3275 return "xorps\t%0, %0";
3277 return "pxor\t%0, %0";
3285 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3287 (cond [(eq_attr "alternative" "0,2")
3289 (ne (symbol_ref "optimize_size")
3291 (const_string "V4SF")
3292 (const_string "TI"))
3293 (eq_attr "alternative" "1")
3295 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3297 (ne (symbol_ref "optimize_size")
3299 (const_string "V4SF")
3300 (const_string "TI"))]
3301 (const_string "DI")))])
3304 [(set (match_operand 0 "nonimmediate_operand" "")
3305 (match_operand 1 "general_operand" ""))]
3307 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3308 && GET_MODE (operands[0]) == XFmode
3309 && ! (ANY_FP_REG_P (operands[0]) ||
3310 (GET_CODE (operands[0]) == SUBREG
3311 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3312 && ! (ANY_FP_REG_P (operands[1]) ||
3313 (GET_CODE (operands[1]) == SUBREG
3314 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3316 "ix86_split_long_move (operands); DONE;")
3319 [(set (match_operand 0 "register_operand" "")
3320 (match_operand 1 "memory_operand" ""))]
3322 && MEM_P (operands[1])
3323 && (GET_MODE (operands[0]) == TFmode
3324 || GET_MODE (operands[0]) == XFmode
3325 || GET_MODE (operands[0]) == SFmode
3326 || GET_MODE (operands[0]) == DFmode)
3327 && (operands[2] = find_constant_src (insn))"
3328 [(set (match_dup 0) (match_dup 2))]
3330 rtx c = operands[2];
3331 rtx r = operands[0];
3333 if (GET_CODE (r) == SUBREG)
3338 if (!standard_sse_constant_p (c))
3341 else if (FP_REG_P (r))
3343 if (!standard_80387_constant_p (c))
3346 else if (MMX_REG_P (r))
3351 [(set (match_operand 0 "register_operand" "")
3352 (float_extend (match_operand 1 "memory_operand" "")))]
3354 && MEM_P (operands[1])
3355 && (GET_MODE (operands[0]) == TFmode
3356 || GET_MODE (operands[0]) == XFmode
3357 || GET_MODE (operands[0]) == SFmode
3358 || GET_MODE (operands[0]) == DFmode)
3359 && (operands[2] = find_constant_src (insn))"
3360 [(set (match_dup 0) (match_dup 2))]
3362 rtx c = operands[2];
3363 rtx r = operands[0];
3365 if (GET_CODE (r) == SUBREG)
3370 if (!standard_sse_constant_p (c))
3373 else if (FP_REG_P (r))
3375 if (!standard_80387_constant_p (c))
3378 else if (MMX_REG_P (r))
3382 (define_insn "swapxf"
3383 [(set (match_operand:XF 0 "register_operand" "+f")
3384 (match_operand:XF 1 "register_operand" "+f"))
3389 if (STACK_TOP_P (operands[0]))
3394 [(set_attr "type" "fxch")
3395 (set_attr "mode" "XF")])
3397 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3399 [(set (match_operand:X87MODEF 0 "register_operand" "")
3400 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3401 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3402 && (standard_80387_constant_p (operands[1]) == 8
3403 || standard_80387_constant_p (operands[1]) == 9)"
3404 [(set (match_dup 0)(match_dup 1))
3406 (neg:X87MODEF (match_dup 0)))]
3410 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3411 if (real_isnegzero (&r))
3412 operands[1] = CONST0_RTX (<MODE>mode);
3414 operands[1] = CONST1_RTX (<MODE>mode);
3418 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3419 (match_operand:TF 1 "general_operand" ""))]
3421 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3423 "ix86_split_long_move (operands); DONE;")
3425 ;; Zero extension instructions
3427 (define_expand "zero_extendhisi2"
3428 [(set (match_operand:SI 0 "register_operand" "")
3429 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3432 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3434 operands[1] = force_reg (HImode, operands[1]);
3435 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3440 (define_insn "zero_extendhisi2_and"
3441 [(set (match_operand:SI 0 "register_operand" "=r")
3442 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3443 (clobber (reg:CC FLAGS_REG))]
3444 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3446 [(set_attr "type" "alu1")
3447 (set_attr "mode" "SI")])
3450 [(set (match_operand:SI 0 "register_operand" "")
3451 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3452 (clobber (reg:CC FLAGS_REG))]
3453 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3454 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3455 (clobber (reg:CC FLAGS_REG))])]
3458 (define_insn "*zero_extendhisi2_movzwl"
3459 [(set (match_operand:SI 0 "register_operand" "=r")
3460 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3461 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3462 "movz{wl|x}\t{%1, %0|%0, %1}"
3463 [(set_attr "type" "imovx")
3464 (set_attr "mode" "SI")])
3466 (define_expand "zero_extendqihi2"
3468 [(set (match_operand:HI 0 "register_operand" "")
3469 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3470 (clobber (reg:CC FLAGS_REG))])]
3474 (define_insn "*zero_extendqihi2_and"
3475 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3476 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3477 (clobber (reg:CC FLAGS_REG))]
3478 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3480 [(set_attr "type" "alu1")
3481 (set_attr "mode" "HI")])
3483 (define_insn "*zero_extendqihi2_movzbw_and"
3484 [(set (match_operand:HI 0 "register_operand" "=r,r")
3485 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3486 (clobber (reg:CC FLAGS_REG))]
3487 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3489 [(set_attr "type" "imovx,alu1")
3490 (set_attr "mode" "HI")])
3492 ; zero extend to SImode here to avoid partial register stalls
3493 (define_insn "*zero_extendqihi2_movzbl"
3494 [(set (match_operand:HI 0 "register_operand" "=r")
3495 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3496 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3497 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3498 [(set_attr "type" "imovx")
3499 (set_attr "mode" "SI")])
3501 ;; For the movzbw case strip only the clobber
3503 [(set (match_operand:HI 0 "register_operand" "")
3504 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3505 (clobber (reg:CC FLAGS_REG))]
3507 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3508 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3509 [(set (match_operand:HI 0 "register_operand" "")
3510 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3512 ;; When source and destination does not overlap, clear destination
3513 ;; first and then do the movb
3515 [(set (match_operand:HI 0 "register_operand" "")
3516 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3517 (clobber (reg:CC FLAGS_REG))]
3519 && ANY_QI_REG_P (operands[0])
3520 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3521 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3522 [(set (match_dup 0) (const_int 0))
3523 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3524 "operands[2] = gen_lowpart (QImode, operands[0]);")
3526 ;; Rest is handled by single and.
3528 [(set (match_operand:HI 0 "register_operand" "")
3529 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3530 (clobber (reg:CC FLAGS_REG))]
3532 && true_regnum (operands[0]) == true_regnum (operands[1])"
3533 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3534 (clobber (reg:CC FLAGS_REG))])]
3537 (define_expand "zero_extendqisi2"
3539 [(set (match_operand:SI 0 "register_operand" "")
3540 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3541 (clobber (reg:CC FLAGS_REG))])]
3545 (define_insn "*zero_extendqisi2_and"
3546 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3547 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3548 (clobber (reg:CC FLAGS_REG))]
3549 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3551 [(set_attr "type" "alu1")
3552 (set_attr "mode" "SI")])
3554 (define_insn "*zero_extendqisi2_movzbw_and"
3555 [(set (match_operand:SI 0 "register_operand" "=r,r")
3556 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3557 (clobber (reg:CC FLAGS_REG))]
3558 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3560 [(set_attr "type" "imovx,alu1")
3561 (set_attr "mode" "SI")])
3563 (define_insn "*zero_extendqisi2_movzbw"
3564 [(set (match_operand:SI 0 "register_operand" "=r")
3565 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3566 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3567 "movz{bl|x}\t{%1, %0|%0, %1}"
3568 [(set_attr "type" "imovx")
3569 (set_attr "mode" "SI")])
3571 ;; For the movzbl case strip only the clobber
3573 [(set (match_operand:SI 0 "register_operand" "")
3574 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3575 (clobber (reg:CC FLAGS_REG))]
3577 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3578 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3580 (zero_extend:SI (match_dup 1)))])
3582 ;; When source and destination does not overlap, clear destination
3583 ;; first and then do the movb
3585 [(set (match_operand:SI 0 "register_operand" "")
3586 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3587 (clobber (reg:CC FLAGS_REG))]
3589 && ANY_QI_REG_P (operands[0])
3590 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3591 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3592 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3593 [(set (match_dup 0) (const_int 0))
3594 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3595 "operands[2] = gen_lowpart (QImode, operands[0]);")
3597 ;; Rest is handled by single and.
3599 [(set (match_operand:SI 0 "register_operand" "")
3600 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3601 (clobber (reg:CC FLAGS_REG))]
3603 && true_regnum (operands[0]) == true_regnum (operands[1])"
3604 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3605 (clobber (reg:CC FLAGS_REG))])]
3608 ;; %%% Kill me once multi-word ops are sane.
3609 (define_expand "zero_extendsidi2"
3610 [(set (match_operand:DI 0 "register_operand" "")
3611 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3616 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3621 (define_insn "zero_extendsidi2_32"
3622 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3624 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3625 (clobber (reg:CC FLAGS_REG))]
3631 movd\t{%1, %0|%0, %1}
3632 movd\t{%1, %0|%0, %1}
3633 movd\t{%1, %0|%0, %1}
3634 movd\t{%1, %0|%0, %1}"
3635 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3636 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3638 (define_insn "zero_extendsidi2_rex64"
3639 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3641 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3644 mov\t{%k1, %k0|%k0, %k1}
3646 movd\t{%1, %0|%0, %1}
3647 movd\t{%1, %0|%0, %1}
3648 movd\t{%1, %0|%0, %1}
3649 movd\t{%1, %0|%0, %1}"
3650 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3651 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3654 [(set (match_operand:DI 0 "memory_operand" "")
3655 (zero_extend:DI (match_dup 0)))]
3657 [(set (match_dup 4) (const_int 0))]
3658 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3661 [(set (match_operand:DI 0 "register_operand" "")
3662 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3663 (clobber (reg:CC FLAGS_REG))]
3664 "!TARGET_64BIT && reload_completed
3665 && true_regnum (operands[0]) == true_regnum (operands[1])"
3666 [(set (match_dup 4) (const_int 0))]
3667 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3670 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3671 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3672 (clobber (reg:CC FLAGS_REG))]
3673 "!TARGET_64BIT && reload_completed
3674 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3675 [(set (match_dup 3) (match_dup 1))
3676 (set (match_dup 4) (const_int 0))]
3677 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3679 (define_insn "zero_extendhidi2"
3680 [(set (match_operand:DI 0 "register_operand" "=r")
3681 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3683 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3684 [(set_attr "type" "imovx")
3685 (set_attr "mode" "DI")])
3687 (define_insn "zero_extendqidi2"
3688 [(set (match_operand:DI 0 "register_operand" "=r")
3689 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3691 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3692 [(set_attr "type" "imovx")
3693 (set_attr "mode" "DI")])
3695 ;; Sign extension instructions
3697 (define_expand "extendsidi2"
3698 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3699 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3700 (clobber (reg:CC FLAGS_REG))
3701 (clobber (match_scratch:SI 2 ""))])]
3706 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3711 (define_insn "*extendsidi2_1"
3712 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3713 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3714 (clobber (reg:CC FLAGS_REG))
3715 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3719 (define_insn "extendsidi2_rex64"
3720 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3721 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3725 movs{lq|x}\t{%1,%0|%0, %1}"
3726 [(set_attr "type" "imovx")
3727 (set_attr "mode" "DI")
3728 (set_attr "prefix_0f" "0")
3729 (set_attr "modrm" "0,1")])
3731 (define_insn "extendhidi2"
3732 [(set (match_operand:DI 0 "register_operand" "=r")
3733 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3735 "movs{wq|x}\t{%1,%0|%0, %1}"
3736 [(set_attr "type" "imovx")
3737 (set_attr "mode" "DI")])
3739 (define_insn "extendqidi2"
3740 [(set (match_operand:DI 0 "register_operand" "=r")
3741 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3743 "movs{bq|x}\t{%1,%0|%0, %1}"
3744 [(set_attr "type" "imovx")
3745 (set_attr "mode" "DI")])
3747 ;; Extend to memory case when source register does die.
3749 [(set (match_operand:DI 0 "memory_operand" "")
3750 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3751 (clobber (reg:CC FLAGS_REG))
3752 (clobber (match_operand:SI 2 "register_operand" ""))]
3754 && dead_or_set_p (insn, operands[1])
3755 && !reg_mentioned_p (operands[1], operands[0]))"
3756 [(set (match_dup 3) (match_dup 1))
3757 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3758 (clobber (reg:CC FLAGS_REG))])
3759 (set (match_dup 4) (match_dup 1))]
3760 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3762 ;; Extend to memory case when source register does not die.
3764 [(set (match_operand:DI 0 "memory_operand" "")
3765 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3766 (clobber (reg:CC FLAGS_REG))
3767 (clobber (match_operand:SI 2 "register_operand" ""))]
3771 split_di (&operands[0], 1, &operands[3], &operands[4]);
3773 emit_move_insn (operands[3], operands[1]);
3775 /* Generate a cltd if possible and doing so it profitable. */
3776 if ((optimize_size || TARGET_USE_CLTD)
3777 && true_regnum (operands[1]) == AX_REG
3778 && true_regnum (operands[2]) == DX_REG)
3780 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3784 emit_move_insn (operands[2], operands[1]);
3785 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3787 emit_move_insn (operands[4], operands[2]);
3791 ;; Extend to register case. Optimize case where source and destination
3792 ;; registers match and cases where we can use cltd.
3794 [(set (match_operand:DI 0 "register_operand" "")
3795 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3796 (clobber (reg:CC FLAGS_REG))
3797 (clobber (match_scratch:SI 2 ""))]
3801 split_di (&operands[0], 1, &operands[3], &operands[4]);
3803 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3804 emit_move_insn (operands[3], operands[1]);
3806 /* Generate a cltd if possible and doing so it profitable. */
3807 if ((optimize_size || TARGET_USE_CLTD)
3808 && true_regnum (operands[3]) == AX_REG)
3810 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3814 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3815 emit_move_insn (operands[4], operands[1]);
3817 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3821 (define_insn "extendhisi2"
3822 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3823 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3826 switch (get_attr_prefix_0f (insn))
3829 return "{cwtl|cwde}";
3831 return "movs{wl|x}\t{%1,%0|%0, %1}";
3834 [(set_attr "type" "imovx")
3835 (set_attr "mode" "SI")
3836 (set (attr "prefix_0f")
3837 ;; movsx is short decodable while cwtl is vector decoded.
3838 (if_then_else (and (eq_attr "cpu" "!k6")
3839 (eq_attr "alternative" "0"))
3841 (const_string "1")))
3843 (if_then_else (eq_attr "prefix_0f" "0")
3845 (const_string "1")))])
3847 (define_insn "*extendhisi2_zext"
3848 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3850 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3853 switch (get_attr_prefix_0f (insn))
3856 return "{cwtl|cwde}";
3858 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3861 [(set_attr "type" "imovx")
3862 (set_attr "mode" "SI")
3863 (set (attr "prefix_0f")
3864 ;; movsx is short decodable while cwtl is vector decoded.
3865 (if_then_else (and (eq_attr "cpu" "!k6")
3866 (eq_attr "alternative" "0"))
3868 (const_string "1")))
3870 (if_then_else (eq_attr "prefix_0f" "0")
3872 (const_string "1")))])
3874 (define_insn "extendqihi2"
3875 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3876 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3879 switch (get_attr_prefix_0f (insn))
3882 return "{cbtw|cbw}";
3884 return "movs{bw|x}\t{%1,%0|%0, %1}";
3887 [(set_attr "type" "imovx")
3888 (set_attr "mode" "HI")
3889 (set (attr "prefix_0f")
3890 ;; movsx is short decodable while cwtl is vector decoded.
3891 (if_then_else (and (eq_attr "cpu" "!k6")
3892 (eq_attr "alternative" "0"))
3894 (const_string "1")))
3896 (if_then_else (eq_attr "prefix_0f" "0")
3898 (const_string "1")))])
3900 (define_insn "extendqisi2"
3901 [(set (match_operand:SI 0 "register_operand" "=r")
3902 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3904 "movs{bl|x}\t{%1,%0|%0, %1}"
3905 [(set_attr "type" "imovx")
3906 (set_attr "mode" "SI")])
3908 (define_insn "*extendqisi2_zext"
3909 [(set (match_operand:DI 0 "register_operand" "=r")
3911 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3913 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3914 [(set_attr "type" "imovx")
3915 (set_attr "mode" "SI")])
3917 ;; Conversions between float and double.
3919 ;; These are all no-ops in the model used for the 80387. So just
3922 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3923 (define_insn "*dummy_extendsfdf2"
3924 [(set (match_operand:DF 0 "push_operand" "=<")
3925 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3930 [(set (match_operand:DF 0 "push_operand" "")
3931 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3933 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3934 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3937 [(set (match_operand:DF 0 "push_operand" "")
3938 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3940 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3941 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3943 (define_insn "*dummy_extendsfxf2"
3944 [(set (match_operand:XF 0 "push_operand" "=<")
3945 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3950 [(set (match_operand:XF 0 "push_operand" "")
3951 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3953 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3954 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3955 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3958 [(set (match_operand:XF 0 "push_operand" "")
3959 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3961 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3962 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3963 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3966 [(set (match_operand:XF 0 "push_operand" "")
3967 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3969 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3970 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3971 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3974 [(set (match_operand:XF 0 "push_operand" "")
3975 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3977 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3978 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3979 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3981 (define_expand "extendsfdf2"
3982 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3983 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3984 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3986 /* ??? Needed for compress_float_constant since all fp constants
3987 are LEGITIMATE_CONSTANT_P. */
3988 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3990 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3991 && standard_80387_constant_p (operands[1]) > 0)
3993 operands[1] = simplify_const_unary_operation
3994 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3995 emit_move_insn_1 (operands[0], operands[1]);
3998 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4002 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4004 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4006 We do the conversion post reload to avoid producing of 128bit spills
4007 that might lead to ICE on 32bit target. The sequence unlikely combine
4010 [(set (match_operand:DF 0 "register_operand" "")
4012 (match_operand:SF 1 "nonimmediate_operand" "")))]
4013 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4014 && reload_completed && SSE_REG_P (operands[0])"
4019 (parallel [(const_int 0) (const_int 1)]))))]
4021 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4022 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4023 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4024 Try to avoid move when unpacking can be done in source. */
4025 if (REG_P (operands[1]))
4027 /* If it is unsafe to overwrite upper half of source, we need
4028 to move to destination and unpack there. */
4029 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4030 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4031 && true_regnum (operands[0]) != true_regnum (operands[1]))
4033 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4034 emit_move_insn (tmp, operands[1]);
4037 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4038 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4041 emit_insn (gen_vec_setv4sf_0 (operands[3],
4042 CONST0_RTX (V4SFmode), operands[1]));
4045 (define_insn "*extendsfdf2_mixed"
4046 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4048 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4049 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4051 switch (which_alternative)
4055 return output_387_reg_move (insn, operands);
4058 return "cvtss2sd\t{%1, %0|%0, %1}";
4064 [(set_attr "type" "fmov,fmov,ssecvt")
4065 (set_attr "mode" "SF,XF,DF")])
4067 (define_insn "*extendsfdf2_sse"
4068 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4069 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4070 "TARGET_SSE2 && TARGET_SSE_MATH"
4071 "cvtss2sd\t{%1, %0|%0, %1}"
4072 [(set_attr "type" "ssecvt")
4073 (set_attr "mode" "DF")])
4075 (define_insn "*extendsfdf2_i387"
4076 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4077 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4079 "* return output_387_reg_move (insn, operands);"
4080 [(set_attr "type" "fmov")
4081 (set_attr "mode" "SF,XF")])
4083 (define_expand "extend<mode>xf2"
4084 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4085 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4088 /* ??? Needed for compress_float_constant since all fp constants
4089 are LEGITIMATE_CONSTANT_P. */
4090 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4092 if (standard_80387_constant_p (operands[1]) > 0)
4094 operands[1] = simplify_const_unary_operation
4095 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4096 emit_move_insn_1 (operands[0], operands[1]);
4099 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4103 (define_insn "*extend<mode>xf2_i387"
4104 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4106 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4108 "* return output_387_reg_move (insn, operands);"
4109 [(set_attr "type" "fmov")
4110 (set_attr "mode" "<MODE>,XF")])
4112 ;; %%% This seems bad bad news.
4113 ;; This cannot output into an f-reg because there is no way to be sure
4114 ;; of truncating in that case. Otherwise this is just like a simple move
4115 ;; insn. So we pretend we can output to a reg in order to get better
4116 ;; register preferencing, but we really use a stack slot.
4118 ;; Conversion from DFmode to SFmode.
4120 (define_expand "truncdfsf2"
4121 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4123 (match_operand:DF 1 "nonimmediate_operand" "")))]
4124 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4126 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4128 else if (flag_unsafe_math_optimizations)
4132 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4133 rtx temp = assign_386_stack_local (SFmode, slot);
4134 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4139 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4141 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4143 We do the conversion post reload to avoid producing of 128bit spills
4144 that might lead to ICE on 32bit target. The sequence unlikely combine
4147 [(set (match_operand:SF 0 "register_operand" "")
4149 (match_operand:DF 1 "nonimmediate_operand" "")))]
4150 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4151 && reload_completed && SSE_REG_P (operands[0])"
4154 (float_truncate:V2SF
4158 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4159 operands[3] = CONST0_RTX (V2SFmode);
4160 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4161 /* Use movsd for loading from memory, unpcklpd for registers.
4162 Try to avoid move when unpacking can be done in source, or SSE3
4163 movddup is available. */
4164 if (REG_P (operands[1]))
4167 && true_regnum (operands[0]) != true_regnum (operands[1])
4168 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4169 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4171 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4172 emit_move_insn (tmp, operands[1]);
4175 else if (!TARGET_SSE3)
4176 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4177 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4180 emit_insn (gen_sse2_loadlpd (operands[4],
4181 CONST0_RTX (V2DFmode), operands[1]));
4184 (define_expand "truncdfsf2_with_temp"
4185 [(parallel [(set (match_operand:SF 0 "" "")
4186 (float_truncate:SF (match_operand:DF 1 "" "")))
4187 (clobber (match_operand:SF 2 "" ""))])]
4190 (define_insn "*truncdfsf_fast_mixed"
4191 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4193 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4194 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4196 switch (which_alternative)
4200 return output_387_reg_move (insn, operands);
4202 return "cvtsd2ss\t{%1, %0|%0, %1}";
4207 [(set_attr "type" "fmov,fmov,ssecvt")
4208 (set_attr "mode" "SF")])
4210 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4211 ;; because nothing we do here is unsafe.
4212 (define_insn "*truncdfsf_fast_sse"
4213 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4215 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4216 "TARGET_SSE2 && TARGET_SSE_MATH"
4217 "cvtsd2ss\t{%1, %0|%0, %1}"
4218 [(set_attr "type" "ssecvt")
4219 (set_attr "mode" "SF")])
4221 (define_insn "*truncdfsf_fast_i387"
4222 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4224 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4225 "TARGET_80387 && flag_unsafe_math_optimizations"
4226 "* return output_387_reg_move (insn, operands);"
4227 [(set_attr "type" "fmov")
4228 (set_attr "mode" "SF")])
4230 (define_insn "*truncdfsf_mixed"
4231 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4233 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4234 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4235 "TARGET_MIX_SSE_I387"
4237 switch (which_alternative)
4240 return output_387_reg_move (insn, operands);
4245 return "cvtsd2ss\t{%1, %0|%0, %1}";
4250 [(set_attr "type" "fmov,multi,ssecvt")
4251 (set_attr "unit" "*,i387,*")
4252 (set_attr "mode" "SF")])
4254 (define_insn "*truncdfsf_i387"
4255 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4257 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4258 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4261 switch (which_alternative)
4264 return output_387_reg_move (insn, operands);
4272 [(set_attr "type" "fmov,multi")
4273 (set_attr "unit" "*,i387")
4274 (set_attr "mode" "SF")])
4276 (define_insn "*truncdfsf2_i387_1"
4277 [(set (match_operand:SF 0 "memory_operand" "=m")
4279 (match_operand:DF 1 "register_operand" "f")))]
4281 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4282 && !TARGET_MIX_SSE_I387"
4283 "* return output_387_reg_move (insn, operands);"
4284 [(set_attr "type" "fmov")
4285 (set_attr "mode" "SF")])
4288 [(set (match_operand:SF 0 "register_operand" "")
4290 (match_operand:DF 1 "fp_register_operand" "")))
4291 (clobber (match_operand 2 "" ""))]
4293 [(set (match_dup 2) (match_dup 1))
4294 (set (match_dup 0) (match_dup 2))]
4296 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4299 ;; Conversion from XFmode to {SF,DF}mode
4301 (define_expand "truncxf<mode>2"
4302 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4303 (float_truncate:MODEF
4304 (match_operand:XF 1 "register_operand" "")))
4305 (clobber (match_dup 2))])]
4308 if (flag_unsafe_math_optimizations)
4310 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4311 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4312 if (reg != operands[0])
4313 emit_move_insn (operands[0], reg);
4318 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4319 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4323 (define_insn "*truncxfsf2_mixed"
4324 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4326 (match_operand:XF 1 "register_operand" "f,f")))
4327 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4330 gcc_assert (!which_alternative);
4331 return output_387_reg_move (insn, operands);
4333 [(set_attr "type" "fmov,multi")
4334 (set_attr "unit" "*,i387")
4335 (set_attr "mode" "SF")])
4337 (define_insn "*truncxfdf2_mixed"
4338 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4340 (match_operand:XF 1 "register_operand" "f,f")))
4341 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4344 gcc_assert (!which_alternative);
4345 return output_387_reg_move (insn, operands);
4347 [(set_attr "type" "fmov,multi")
4348 (set_attr "unit" "*,i387")
4349 (set_attr "mode" "DF")])
4351 (define_insn "truncxf<mode>2_i387_noop"
4352 [(set (match_operand:MODEF 0 "register_operand" "=f")
4353 (float_truncate:MODEF
4354 (match_operand:XF 1 "register_operand" "f")))]
4355 "TARGET_80387 && flag_unsafe_math_optimizations"
4356 "* return output_387_reg_move (insn, operands);"
4357 [(set_attr "type" "fmov")
4358 (set_attr "mode" "<MODE>")])
4360 (define_insn "*truncxf<mode>2_i387"
4361 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4362 (float_truncate:MODEF
4363 (match_operand:XF 1 "register_operand" "f")))]
4365 "* return output_387_reg_move (insn, operands);"
4366 [(set_attr "type" "fmov")
4367 (set_attr "mode" "<MODE>")])
4370 [(set (match_operand:MODEF 0 "register_operand" "")
4371 (float_truncate:MODEF
4372 (match_operand:XF 1 "register_operand" "")))
4373 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4374 "TARGET_80387 && reload_completed"
4375 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4376 (set (match_dup 0) (match_dup 2))]
4380 [(set (match_operand:MODEF 0 "memory_operand" "")
4381 (float_truncate:MODEF
4382 (match_operand:XF 1 "register_operand" "")))
4383 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4385 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4388 ;; Signed conversion to DImode.
4390 (define_expand "fix_truncxfdi2"
4391 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4392 (fix:DI (match_operand:XF 1 "register_operand" "")))
4393 (clobber (reg:CC FLAGS_REG))])]
4398 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4403 (define_expand "fix_trunc<mode>di2"
4404 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4405 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4406 (clobber (reg:CC FLAGS_REG))])]
4407 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4410 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4412 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4415 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4417 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4418 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4419 if (out != operands[0])
4420 emit_move_insn (operands[0], out);
4425 ;; Signed conversion to SImode.
4427 (define_expand "fix_truncxfsi2"
4428 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4429 (fix:SI (match_operand:XF 1 "register_operand" "")))
4430 (clobber (reg:CC FLAGS_REG))])]
4435 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4440 (define_expand "fix_trunc<mode>si2"
4441 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4442 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4443 (clobber (reg:CC FLAGS_REG))])]
4444 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4447 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4449 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4452 if (SSE_FLOAT_MODE_P (<MODE>mode))
4454 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4455 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4456 if (out != operands[0])
4457 emit_move_insn (operands[0], out);
4462 ;; Signed conversion to HImode.
4464 (define_expand "fix_trunc<mode>hi2"
4465 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4466 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4467 (clobber (reg:CC FLAGS_REG))])]
4469 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4473 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4478 ;; Unsigned conversion to SImode.
4480 (define_expand "fixuns_trunc<mode>si2"
4482 [(set (match_operand:SI 0 "register_operand" "")
4484 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4486 (clobber (match_scratch:<ssevecmode> 3 ""))
4487 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4488 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4490 enum machine_mode mode = <MODE>mode;
4491 enum machine_mode vecmode = <ssevecmode>mode;
4492 REAL_VALUE_TYPE TWO31r;
4495 real_ldexp (&TWO31r, &dconst1, 31);
4496 two31 = const_double_from_real_value (TWO31r, mode);
4497 two31 = ix86_build_const_vector (mode, true, two31);
4498 operands[2] = force_reg (vecmode, two31);
4501 (define_insn_and_split "*fixuns_trunc<mode>_1"
4502 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4504 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4505 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4506 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4507 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4508 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4510 "&& reload_completed"
4513 ix86_split_convert_uns_si_sse (operands);
4517 ;; Unsigned conversion to HImode.
4518 ;; Without these patterns, we'll try the unsigned SI conversion which
4519 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4521 (define_expand "fixuns_trunc<mode>hi2"
4523 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4524 (set (match_operand:HI 0 "nonimmediate_operand" "")
4525 (subreg:HI (match_dup 2) 0))]
4526 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4527 "operands[2] = gen_reg_rtx (SImode);")
4529 ;; When SSE is available, it is always faster to use it!
4530 (define_insn "fix_trunc<mode>di_sse"
4531 [(set (match_operand:DI 0 "register_operand" "=r,r")
4532 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4533 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4534 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4535 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4536 [(set_attr "type" "sseicvt")
4537 (set_attr "mode" "<MODE>")
4538 (set_attr "athlon_decode" "double,vector")
4539 (set_attr "amdfam10_decode" "double,double")])
4541 (define_insn "fix_trunc<mode>si_sse"
4542 [(set (match_operand:SI 0 "register_operand" "=r,r")
4543 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4544 "SSE_FLOAT_MODE_P (<MODE>mode)
4545 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4546 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4547 [(set_attr "type" "sseicvt")
4548 (set_attr "mode" "<MODE>")
4549 (set_attr "athlon_decode" "double,vector")
4550 (set_attr "amdfam10_decode" "double,double")])
4552 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4554 [(set (match_operand:MODEF 0 "register_operand" "")
4555 (match_operand:MODEF 1 "memory_operand" ""))
4556 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4557 (fix:SSEMODEI24 (match_dup 0)))]
4558 "TARGET_SHORTEN_X87_SSE
4559 && peep2_reg_dead_p (2, operands[0])"
4560 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4563 ;; Avoid vector decoded forms of the instruction.
4565 [(match_scratch:DF 2 "Y2")
4566 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4567 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4568 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4569 [(set (match_dup 2) (match_dup 1))
4570 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4574 [(match_scratch:SF 2 "x")
4575 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4576 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4577 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4578 [(set (match_dup 2) (match_dup 1))
4579 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4582 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4583 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4584 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4585 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4587 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4588 && (TARGET_64BIT || <MODE>mode != DImode))
4590 && !(reload_completed || reload_in_progress)"
4595 if (memory_operand (operands[0], VOIDmode))
4596 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4599 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4600 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4606 [(set_attr "type" "fisttp")
4607 (set_attr "mode" "<MODE>")])
4609 (define_insn "fix_trunc<mode>_i387_fisttp"
4610 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4611 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4612 (clobber (match_scratch:XF 2 "=&1f"))]
4613 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4615 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && (TARGET_64BIT || <MODE>mode != DImode))
4617 && TARGET_SSE_MATH)"
4618 "* return output_fix_trunc (insn, operands, 1);"
4619 [(set_attr "type" "fisttp")
4620 (set_attr "mode" "<MODE>")])
4622 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4623 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4624 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4625 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4626 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4627 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4629 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4630 && (TARGET_64BIT || <MODE>mode != DImode))
4631 && TARGET_SSE_MATH)"
4633 [(set_attr "type" "fisttp")
4634 (set_attr "mode" "<MODE>")])
4637 [(set (match_operand:X87MODEI 0 "register_operand" "")
4638 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4639 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4640 (clobber (match_scratch 3 ""))]
4642 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4643 (clobber (match_dup 3))])
4644 (set (match_dup 0) (match_dup 2))]
4648 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4649 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4650 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4651 (clobber (match_scratch 3 ""))]
4653 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4654 (clobber (match_dup 3))])]
4657 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4658 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4659 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4660 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4661 ;; function in i386.c.
4662 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4663 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4664 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4665 (clobber (reg:CC FLAGS_REG))]
4666 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4668 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4669 && (TARGET_64BIT || <MODE>mode != DImode))
4670 && !(reload_completed || reload_in_progress)"
4675 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4677 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4678 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4679 if (memory_operand (operands[0], VOIDmode))
4680 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4681 operands[2], operands[3]));
4684 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4685 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4686 operands[2], operands[3],
4691 [(set_attr "type" "fistp")
4692 (set_attr "i387_cw" "trunc")
4693 (set_attr "mode" "<MODE>")])
4695 (define_insn "fix_truncdi_i387"
4696 [(set (match_operand:DI 0 "memory_operand" "=m")
4697 (fix:DI (match_operand 1 "register_operand" "f")))
4698 (use (match_operand:HI 2 "memory_operand" "m"))
4699 (use (match_operand:HI 3 "memory_operand" "m"))
4700 (clobber (match_scratch:XF 4 "=&1f"))]
4701 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4703 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4704 "* return output_fix_trunc (insn, operands, 0);"
4705 [(set_attr "type" "fistp")
4706 (set_attr "i387_cw" "trunc")
4707 (set_attr "mode" "DI")])
4709 (define_insn "fix_truncdi_i387_with_temp"
4710 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4711 (fix:DI (match_operand 1 "register_operand" "f,f")))
4712 (use (match_operand:HI 2 "memory_operand" "m,m"))
4713 (use (match_operand:HI 3 "memory_operand" "m,m"))
4714 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4715 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4716 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4718 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4720 [(set_attr "type" "fistp")
4721 (set_attr "i387_cw" "trunc")
4722 (set_attr "mode" "DI")])
4725 [(set (match_operand:DI 0 "register_operand" "")
4726 (fix:DI (match_operand 1 "register_operand" "")))
4727 (use (match_operand:HI 2 "memory_operand" ""))
4728 (use (match_operand:HI 3 "memory_operand" ""))
4729 (clobber (match_operand:DI 4 "memory_operand" ""))
4730 (clobber (match_scratch 5 ""))]
4732 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4735 (clobber (match_dup 5))])
4736 (set (match_dup 0) (match_dup 4))]
4740 [(set (match_operand:DI 0 "memory_operand" "")
4741 (fix:DI (match_operand 1 "register_operand" "")))
4742 (use (match_operand:HI 2 "memory_operand" ""))
4743 (use (match_operand:HI 3 "memory_operand" ""))
4744 (clobber (match_operand:DI 4 "memory_operand" ""))
4745 (clobber (match_scratch 5 ""))]
4747 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4750 (clobber (match_dup 5))])]
4753 (define_insn "fix_trunc<mode>_i387"
4754 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4755 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4756 (use (match_operand:HI 2 "memory_operand" "m"))
4757 (use (match_operand:HI 3 "memory_operand" "m"))]
4758 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4760 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4761 "* return output_fix_trunc (insn, operands, 0);"
4762 [(set_attr "type" "fistp")
4763 (set_attr "i387_cw" "trunc")
4764 (set_attr "mode" "<MODE>")])
4766 (define_insn "fix_trunc<mode>_i387_with_temp"
4767 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4768 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4769 (use (match_operand:HI 2 "memory_operand" "m,m"))
4770 (use (match_operand:HI 3 "memory_operand" "m,m"))
4771 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4772 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4774 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4776 [(set_attr "type" "fistp")
4777 (set_attr "i387_cw" "trunc")
4778 (set_attr "mode" "<MODE>")])
4781 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4782 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4783 (use (match_operand:HI 2 "memory_operand" ""))
4784 (use (match_operand:HI 3 "memory_operand" ""))
4785 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4787 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4789 (use (match_dup 3))])
4790 (set (match_dup 0) (match_dup 4))]
4794 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4795 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4796 (use (match_operand:HI 2 "memory_operand" ""))
4797 (use (match_operand:HI 3 "memory_operand" ""))
4798 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4800 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4802 (use (match_dup 3))])]
4805 (define_insn "x86_fnstcw_1"
4806 [(set (match_operand:HI 0 "memory_operand" "=m")
4807 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4810 [(set_attr "length" "2")
4811 (set_attr "mode" "HI")
4812 (set_attr "unit" "i387")])
4814 (define_insn "x86_fldcw_1"
4815 [(set (reg:HI FPCR_REG)
4816 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4819 [(set_attr "length" "2")
4820 (set_attr "mode" "HI")
4821 (set_attr "unit" "i387")
4822 (set_attr "athlon_decode" "vector")
4823 (set_attr "amdfam10_decode" "vector")])
4825 ;; Conversion between fixed point and floating point.
4827 ;; Even though we only accept memory inputs, the backend _really_
4828 ;; wants to be able to do this between registers.
4830 (define_expand "floathi<mode>2"
4831 [(set (match_operand:X87MODEF 0 "register_operand" "")
4832 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4834 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4835 || TARGET_MIX_SSE_I387)"
4838 ;; Pre-reload splitter to add memory clobber to the pattern.
4839 (define_insn_and_split "*floathi<mode>2_1"
4840 [(set (match_operand:X87MODEF 0 "register_operand" "")
4841 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4843 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4844 || TARGET_MIX_SSE_I387)
4845 && !(reload_completed || reload_in_progress)"
4848 [(parallel [(set (match_dup 0)
4849 (float:X87MODEF (match_dup 1)))
4850 (clobber (match_dup 2))])]
4851 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4853 (define_insn "*floathi<mode>2_i387_with_temp"
4854 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4855 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4856 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4859 || TARGET_MIX_SSE_I387)"
4861 [(set_attr "type" "fmov,multi")
4862 (set_attr "mode" "<MODE>")
4863 (set_attr "unit" "*,i387")
4864 (set_attr "fp_int_src" "true")])
4866 (define_insn "*floathi<mode>2_i387"
4867 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4868 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4871 || TARGET_MIX_SSE_I387)"
4873 [(set_attr "type" "fmov")
4874 (set_attr "mode" "<MODE>")
4875 (set_attr "fp_int_src" "true")])
4878 [(set (match_operand:X87MODEF 0 "register_operand" "")
4879 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4880 (clobber (match_operand:HI 2 "memory_operand" ""))]
4882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4883 || TARGET_MIX_SSE_I387)
4884 && reload_completed"
4885 [(set (match_dup 2) (match_dup 1))
4886 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4890 [(set (match_operand:X87MODEF 0 "register_operand" "")
4891 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4892 (clobber (match_operand:HI 2 "memory_operand" ""))]
4894 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4895 || TARGET_MIX_SSE_I387)
4896 && reload_completed"
4897 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4900 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4901 [(set (match_operand:X87MODEF 0 "register_operand" "")
4903 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4905 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4906 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4909 ;; Pre-reload splitter to add memory clobber to the pattern.
4910 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4911 [(set (match_operand:X87MODEF 0 "register_operand" "")
4912 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4914 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4915 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4916 || TARGET_MIX_SSE_I387))
4917 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4918 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4919 && ((<SSEMODEI24:MODE>mode == SImode
4920 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4921 && flag_trapping_math)
4922 || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4923 && !(reload_completed || reload_in_progress)"
4926 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4927 (clobber (match_dup 2))])]
4928 "operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);")
4930 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4931 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4933 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4934 (clobber (match_operand:SI 2 "memory_operand" "=m,m,m,m,m"))]
4935 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4936 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4938 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4939 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4940 (set_attr "unit" "*,i387,*,*,*")
4941 (set_attr "athlon_decode" "*,*,double,direct,double")
4942 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4943 (set_attr "fp_int_src" "true")])
4945 (define_insn "*floatsi<mode>2_vector_mixed"
4946 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4947 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4948 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4949 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4953 [(set_attr "type" "fmov,sseicvt")
4954 (set_attr "mode" "<MODE>,<ssevecmode>")
4955 (set_attr "unit" "i387,*")
4956 (set_attr "athlon_decode" "*,direct")
4957 (set_attr "amdfam10_decode" "*,double")
4958 (set_attr "fp_int_src" "true")])
4960 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4961 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4963 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4964 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m,m,m"))]
4965 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4966 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4968 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4969 (set_attr "mode" "<MODEF:MODE>")
4970 (set_attr "unit" "*,i387,*,*")
4971 (set_attr "athlon_decode" "*,*,double,direct")
4972 (set_attr "amdfam10_decode" "*,*,vector,double")
4973 (set_attr "fp_int_src" "true")])
4976 [(set (match_operand:MODEF 0 "register_operand" "")
4977 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4978 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4979 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4980 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4981 && TARGET_INTER_UNIT_CONVERSIONS
4983 && (SSE_REG_P (operands[0])
4984 || (GET_CODE (operands[0]) == SUBREG
4985 && SSE_REG_P (operands[0])))"
4986 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
4990 [(set (match_operand:MODEF 0 "register_operand" "")
4991 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4992 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4993 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4994 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4995 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
4997 && (SSE_REG_P (operands[0])
4998 || (GET_CODE (operands[0]) == SUBREG
4999 && SSE_REG_P (operands[0])))"
5000 [(set (match_dup 2) (match_dup 1))
5001 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5004 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5005 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5007 (match_operand:SSEMODEI24 1 "register_operand" "m,r,m")))]
5008 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5009 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5010 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5013 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5014 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5015 [(set_attr "type" "fmov,sseicvt,sseicvt")
5016 (set_attr "mode" "<MODEF:MODE>")
5017 (set_attr "unit" "i387,*,*")
5018 (set_attr "athlon_decode" "*,double,direct")
5019 (set_attr "amdfam10_decode" "*,vector,double")
5020 (set_attr "fp_int_src" "true")])
5022 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5023 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5025 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5026 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5027 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5028 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5031 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5032 [(set_attr "type" "fmov,sseicvt")
5033 (set_attr "mode" "<MODEF:MODE>")
5034 (set_attr "athlon_decode" "*,direct")
5035 (set_attr "amdfam10_decode" "*,double")
5036 (set_attr "fp_int_src" "true")])
5038 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5039 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5041 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5042 (clobber (match_operand:SI 2 "memory_operand" "=m,m,m"))]
5043 "TARGET_SSE2 && TARGET_SSE_MATH
5044 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5046 [(set_attr "type" "sseicvt")
5047 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5048 (set_attr "athlon_decode" "double,direct,double")
5049 (set_attr "amdfam10_decode" "vector,double,double")
5050 (set_attr "fp_int_src" "true")])
5052 (define_insn "*floatsi<mode>2_vector_sse"
5053 [(set (match_operand:MODEF 0 "register_operand" "=x")
5054 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5055 "TARGET_SSE2 && TARGET_SSE_MATH
5056 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5058 [(set_attr "type" "sseicvt")
5059 (set_attr "mode" "<MODE>")
5060 (set_attr "athlon_decode" "direct")
5061 (set_attr "amdfam10_decode" "double")
5062 (set_attr "fp_int_src" "true")])
5065 [(set (match_operand:MODEF 0 "register_operand" "")
5066 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5067 (clobber (match_operand:SI 2 "memory_operand" ""))]
5068 "TARGET_SSE2 && TARGET_SSE_MATH
5069 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5071 && (SSE_REG_P (operands[0])
5072 || (GET_CODE (operands[0]) == SUBREG
5073 && SSE_REG_P (operands[0])))"
5076 rtx op1 = operands[1];
5078 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5080 if (GET_CODE (op1) == SUBREG)
5081 op1 = SUBREG_REG (op1);
5083 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5085 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5086 emit_insn (gen_sse2_loadld (operands[4],
5087 CONST0_RTX (V4SImode), operands[1]));
5089 /* We can ignore possible trapping value in the
5090 high part of SSE register for non-trapping math. */
5091 else if (SSE_REG_P (op1) && !flag_trapping_math)
5092 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5095 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5096 emit_move_insn (operands[2], operands[1]);
5097 emit_insn (gen_sse2_loadld (operands[4],
5098 CONST0_RTX (V4SImode), operands[2]));
5101 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5106 [(set (match_operand:MODEF 0 "register_operand" "")
5107 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5108 (clobber (match_operand:SI 2 "memory_operand" ""))]
5109 "TARGET_SSE2 && TARGET_SSE_MATH
5110 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5112 && (SSE_REG_P (operands[0])
5113 || (GET_CODE (operands[0]) == SUBREG
5114 && SSE_REG_P (operands[0])))"
5117 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5119 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5121 emit_insn (gen_sse2_loadld (operands[4],
5122 CONST0_RTX (V4SImode), operands[1]));
5124 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5129 [(set (match_operand:MODEF 0 "register_operand" "")
5130 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5131 "TARGET_SSE2 && TARGET_SSE_MATH
5132 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5134 && (SSE_REG_P (operands[0])
5135 || (GET_CODE (operands[0]) == SUBREG
5136 && SSE_REG_P (operands[0])))"
5139 rtx op1 = operands[1];
5141 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5143 if (GET_CODE (op1) == SUBREG)
5144 op1 = SUBREG_REG (op1);
5146 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5148 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5149 emit_insn (gen_sse2_loadld (operands[4],
5150 CONST0_RTX (V4SImode), operands[1]));
5152 /* We can ignore possible trapping value in the
5153 high part of SSE register for non-trapping math. */
5154 else if (SSE_REG_P (op1) && !flag_trapping_math)
5155 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5161 [(set (match_operand:MODEF 0 "register_operand" "")
5162 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5163 "TARGET_SSE2 && TARGET_SSE_MATH
5164 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5166 && (SSE_REG_P (operands[0])
5167 || (GET_CODE (operands[0]) == SUBREG
5168 && SSE_REG_P (operands[0])))"
5171 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5173 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5175 emit_insn (gen_sse2_loadld (operands[4],
5176 CONST0_RTX (V4SImode), operands[1]));
5178 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5182 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5183 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5185 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5186 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m"))]
5187 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5188 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5190 [(set_attr "type" "sseicvt")
5191 (set_attr "mode" "<MODEF:MODE>")
5192 (set_attr "athlon_decode" "double,direct")
5193 (set_attr "amdfam10_decode" "vector,double")
5194 (set_attr "fp_int_src" "true")])
5196 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5197 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5199 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5200 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5201 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5202 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5204 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5205 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5206 [(set_attr "type" "sseicvt")
5207 (set_attr "mode" "<MODEF:MODE>")
5208 (set_attr "athlon_decode" "double,direct")
5209 (set_attr "amdfam10_decode" "vector,double")
5210 (set_attr "fp_int_src" "true")])
5213 [(set (match_operand:MODEF 0 "register_operand" "")
5214 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5215 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5216 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5217 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5218 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5220 && (SSE_REG_P (operands[0])
5221 || (GET_CODE (operands[0]) == SUBREG
5222 && SSE_REG_P (operands[0])))"
5223 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5226 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5227 [(set (match_operand:MODEF 0 "register_operand" "=x")
5229 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5230 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5231 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5232 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5233 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5234 [(set_attr "type" "sseicvt")
5235 (set_attr "mode" "<MODEF:MODE>")
5236 (set_attr "athlon_decode" "direct")
5237 (set_attr "amdfam10_decode" "double")
5238 (set_attr "fp_int_src" "true")])
5241 [(set (match_operand:MODEF 0 "register_operand" "")
5242 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5243 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5244 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5245 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5246 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5248 && (SSE_REG_P (operands[0])
5249 || (GET_CODE (operands[0]) == SUBREG
5250 && SSE_REG_P (operands[0])))"
5251 [(set (match_dup 2) (match_dup 1))
5252 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5256 [(set (match_operand:MODEF 0 "register_operand" "")
5257 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5258 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5259 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5260 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5262 && (SSE_REG_P (operands[0])
5263 || (GET_CODE (operands[0]) == SUBREG
5264 && SSE_REG_P (operands[0])))"
5265 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5268 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5269 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5271 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5272 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m"))]
5277 [(set_attr "type" "fmov,multi")
5278 (set_attr "mode" "<X87MODEF:MODE>")
5279 (set_attr "unit" "*,i387")
5280 (set_attr "fp_int_src" "true")])
5282 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5283 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5285 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5288 [(set_attr "type" "fmov")
5289 (set_attr "mode" "<X87MODEF:MODE>")
5290 (set_attr "fp_int_src" "true")])
5293 [(set (match_operand:X87MODEF 0 "register_operand" "")
5294 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5295 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5298 && FP_REG_P (operands[0])"
5299 [(set (match_dup 2) (match_dup 1))
5300 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5304 [(set (match_operand:X87MODEF 0 "register_operand" "")
5305 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5306 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5309 && FP_REG_P (operands[0])"
5310 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5313 ;; Avoid store forwarding (partial memory) stall penalty by extending
5314 ;; SImode value to DImode through XMM register instead of pushing two
5315 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5316 ;; targets benefit from this optimization. Also note that fild
5317 ;; loads from memory only.
5319 (define_insn "*floatunssi<mode>2_1"
5320 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5321 (unsigned_float:X87MODEF
5322 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5323 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5324 (clobber (match_scratch:SI 3 "=X,x"))]
5326 && TARGET_80387 && TARGET_SSE"
5328 [(set_attr "type" "multi")
5329 (set_attr "mode" "<MODE>")])
5332 [(set (match_operand:X87MODEF 0 "register_operand" "")
5333 (unsigned_float:X87MODEF
5334 (match_operand:SI 1 "register_operand" "")))
5335 (clobber (match_operand:DI 2 "memory_operand" ""))
5336 (clobber (match_scratch:SI 3 ""))]
5338 && TARGET_80387 && TARGET_SSE
5339 && reload_completed"
5340 [(set (match_dup 2) (match_dup 1))
5342 (float:X87MODEF (match_dup 2)))]
5343 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5346 [(set (match_operand:X87MODEF 0 "register_operand" "")
5347 (unsigned_float:X87MODEF
5348 (match_operand:SI 1 "memory_operand" "")))
5349 (clobber (match_operand:DI 2 "memory_operand" ""))
5350 (clobber (match_scratch:SI 3 ""))]
5352 && TARGET_80387 && TARGET_SSE
5353 && reload_completed"
5354 [(set (match_dup 2) (match_dup 3))
5356 (float:X87MODEF (match_dup 2)))]
5358 emit_move_insn (operands[3], operands[1]);
5359 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5362 (define_expand "floatunssi<mode>2"
5364 [(set (match_operand:X87MODEF 0 "register_operand" "")
5365 (unsigned_float:X87MODEF
5366 (match_operand:SI 1 "nonimmediate_operand" "")))
5367 (clobber (match_dup 2))
5368 (clobber (match_scratch:SI 3 ""))])]
5370 && ((TARGET_80387 && TARGET_SSE)
5371 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5373 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5375 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5380 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5381 operands[2] = assign_386_stack_local (DImode, slot);
5385 (define_expand "floatunsdisf2"
5386 [(use (match_operand:SF 0 "register_operand" ""))
5387 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5388 "TARGET_64BIT && TARGET_SSE_MATH"
5389 "x86_emit_floatuns (operands); DONE;")
5391 (define_expand "floatunsdidf2"
5392 [(use (match_operand:DF 0 "register_operand" ""))
5393 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5394 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5395 && TARGET_SSE2 && TARGET_SSE_MATH"
5398 x86_emit_floatuns (operands);
5400 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5406 ;; %%% splits for addditi3
5408 (define_expand "addti3"
5409 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5410 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5411 (match_operand:TI 2 "x86_64_general_operand" "")))
5412 (clobber (reg:CC FLAGS_REG))]
5414 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5416 (define_insn "*addti3_1"
5417 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5418 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5419 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5420 (clobber (reg:CC FLAGS_REG))]
5421 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5425 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5426 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5427 (match_operand:TI 2 "x86_64_general_operand" "")))
5428 (clobber (reg:CC FLAGS_REG))]
5429 "TARGET_64BIT && reload_completed"
5430 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5432 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5433 (parallel [(set (match_dup 3)
5434 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5437 (clobber (reg:CC FLAGS_REG))])]
5438 "split_ti (operands+0, 1, operands+0, operands+3);
5439 split_ti (operands+1, 1, operands+1, operands+4);
5440 split_ti (operands+2, 1, operands+2, operands+5);")
5442 ;; %%% splits for addsidi3
5443 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5444 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5445 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5447 (define_expand "adddi3"
5448 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5449 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5450 (match_operand:DI 2 "x86_64_general_operand" "")))
5451 (clobber (reg:CC FLAGS_REG))]
5453 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5455 (define_insn "*adddi3_1"
5456 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5457 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5458 (match_operand:DI 2 "general_operand" "roiF,riF")))
5459 (clobber (reg:CC FLAGS_REG))]
5460 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5464 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5465 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5466 (match_operand:DI 2 "general_operand" "")))
5467 (clobber (reg:CC FLAGS_REG))]
5468 "!TARGET_64BIT && reload_completed"
5469 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5471 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5472 (parallel [(set (match_dup 3)
5473 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5476 (clobber (reg:CC FLAGS_REG))])]
5477 "split_di (operands+0, 1, operands+0, operands+3);
5478 split_di (operands+1, 1, operands+1, operands+4);
5479 split_di (operands+2, 1, operands+2, operands+5);")
5481 (define_insn "adddi3_carry_rex64"
5482 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5483 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5484 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5485 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5486 (clobber (reg:CC FLAGS_REG))]
5487 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5488 "adc{q}\t{%2, %0|%0, %2}"
5489 [(set_attr "type" "alu")
5490 (set_attr "pent_pair" "pu")
5491 (set_attr "mode" "DI")])
5493 (define_insn "*adddi3_cc_rex64"
5494 [(set (reg:CC FLAGS_REG)
5495 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5496 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5498 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5499 (plus:DI (match_dup 1) (match_dup 2)))]
5500 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5501 "add{q}\t{%2, %0|%0, %2}"
5502 [(set_attr "type" "alu")
5503 (set_attr "mode" "DI")])
5505 (define_insn "*<addsub><mode>3_cc_overflow"
5506 [(set (reg:CCC FLAGS_REG)
5509 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5510 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5512 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5513 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5514 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5515 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5516 [(set_attr "type" "alu")
5517 (set_attr "mode" "<MODE>")])
5519 (define_insn "*add<mode>3_cconly_overflow"
5520 [(set (reg:CCC FLAGS_REG)
5522 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5523 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5525 (clobber (match_scratch:SWI 0 "=<r>"))]
5526 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5527 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5528 [(set_attr "type" "alu")
5529 (set_attr "mode" "<MODE>")])
5531 (define_insn "*sub<mode>3_cconly_overflow"
5532 [(set (reg:CCC FLAGS_REG)
5534 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5535 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5538 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5539 [(set_attr "type" "icmp")
5540 (set_attr "mode" "<MODE>")])
5542 (define_insn "*<addsub>si3_zext_cc_overflow"
5543 [(set (reg:CCC FLAGS_REG)
5545 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5546 (match_operand:SI 2 "general_operand" "g"))
5548 (set (match_operand:DI 0 "register_operand" "=r")
5549 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5550 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5551 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5552 [(set_attr "type" "alu")
5553 (set_attr "mode" "SI")])
5555 (define_insn "addqi3_carry"
5556 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5557 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5558 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5559 (match_operand:QI 2 "general_operand" "qi,qm")))
5560 (clobber (reg:CC FLAGS_REG))]
5561 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5562 "adc{b}\t{%2, %0|%0, %2}"
5563 [(set_attr "type" "alu")
5564 (set_attr "pent_pair" "pu")
5565 (set_attr "mode" "QI")])
5567 (define_insn "addhi3_carry"
5568 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5569 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5570 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5571 (match_operand:HI 2 "general_operand" "ri,rm")))
5572 (clobber (reg:CC FLAGS_REG))]
5573 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5574 "adc{w}\t{%2, %0|%0, %2}"
5575 [(set_attr "type" "alu")
5576 (set_attr "pent_pair" "pu")
5577 (set_attr "mode" "HI")])
5579 (define_insn "addsi3_carry"
5580 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5581 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5582 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5583 (match_operand:SI 2 "general_operand" "ri,rm")))
5584 (clobber (reg:CC FLAGS_REG))]
5585 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5586 "adc{l}\t{%2, %0|%0, %2}"
5587 [(set_attr "type" "alu")
5588 (set_attr "pent_pair" "pu")
5589 (set_attr "mode" "SI")])
5591 (define_insn "*addsi3_carry_zext"
5592 [(set (match_operand:DI 0 "register_operand" "=r")
5594 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5595 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5596 (match_operand:SI 2 "general_operand" "g"))))
5597 (clobber (reg:CC FLAGS_REG))]
5598 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5599 "adc{l}\t{%2, %k0|%k0, %2}"
5600 [(set_attr "type" "alu")
5601 (set_attr "pent_pair" "pu")
5602 (set_attr "mode" "SI")])
5604 (define_insn "*addsi3_cc"
5605 [(set (reg:CC FLAGS_REG)
5606 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5607 (match_operand:SI 2 "general_operand" "ri,rm")]
5609 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5610 (plus:SI (match_dup 1) (match_dup 2)))]
5611 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5612 "add{l}\t{%2, %0|%0, %2}"
5613 [(set_attr "type" "alu")
5614 (set_attr "mode" "SI")])
5616 (define_insn "addqi3_cc"
5617 [(set (reg:CC FLAGS_REG)
5618 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5619 (match_operand:QI 2 "general_operand" "qi,qm")]
5621 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5622 (plus:QI (match_dup 1) (match_dup 2)))]
5623 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5624 "add{b}\t{%2, %0|%0, %2}"
5625 [(set_attr "type" "alu")
5626 (set_attr "mode" "QI")])
5628 (define_expand "addsi3"
5629 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5630 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5631 (match_operand:SI 2 "general_operand" "")))
5632 (clobber (reg:CC FLAGS_REG))])]
5634 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5636 (define_insn "*lea_1"
5637 [(set (match_operand:SI 0 "register_operand" "=r")
5638 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5640 "lea{l}\t{%a1, %0|%0, %a1}"
5641 [(set_attr "type" "lea")
5642 (set_attr "mode" "SI")])
5644 (define_insn "*lea_1_rex64"
5645 [(set (match_operand:SI 0 "register_operand" "=r")
5646 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5648 "lea{l}\t{%a1, %0|%0, %a1}"
5649 [(set_attr "type" "lea")
5650 (set_attr "mode" "SI")])
5652 (define_insn "*lea_1_zext"
5653 [(set (match_operand:DI 0 "register_operand" "=r")
5655 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5657 "lea{l}\t{%a1, %k0|%k0, %a1}"
5658 [(set_attr "type" "lea")
5659 (set_attr "mode" "SI")])
5661 (define_insn "*lea_2_rex64"
5662 [(set (match_operand:DI 0 "register_operand" "=r")
5663 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5665 "lea{q}\t{%a1, %0|%0, %a1}"
5666 [(set_attr "type" "lea")
5667 (set_attr "mode" "DI")])
5669 ;; The lea patterns for non-Pmodes needs to be matched by several
5670 ;; insns converted to real lea by splitters.
5672 (define_insn_and_split "*lea_general_1"
5673 [(set (match_operand 0 "register_operand" "=r")
5674 (plus (plus (match_operand 1 "index_register_operand" "l")
5675 (match_operand 2 "register_operand" "r"))
5676 (match_operand 3 "immediate_operand" "i")))]
5677 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5678 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5679 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5680 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5681 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5682 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5683 || GET_MODE (operands[3]) == VOIDmode)"
5685 "&& reload_completed"
5689 operands[0] = gen_lowpart (SImode, operands[0]);
5690 operands[1] = gen_lowpart (Pmode, operands[1]);
5691 operands[2] = gen_lowpart (Pmode, operands[2]);
5692 operands[3] = gen_lowpart (Pmode, operands[3]);
5693 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5695 if (Pmode != SImode)
5696 pat = gen_rtx_SUBREG (SImode, pat, 0);
5697 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5700 [(set_attr "type" "lea")
5701 (set_attr "mode" "SI")])
5703 (define_insn_and_split "*lea_general_1_zext"
5704 [(set (match_operand:DI 0 "register_operand" "=r")
5706 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5707 (match_operand:SI 2 "register_operand" "r"))
5708 (match_operand:SI 3 "immediate_operand" "i"))))]
5711 "&& reload_completed"
5713 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5715 (match_dup 3)) 0)))]
5717 operands[1] = gen_lowpart (Pmode, operands[1]);
5718 operands[2] = gen_lowpart (Pmode, operands[2]);
5719 operands[3] = gen_lowpart (Pmode, operands[3]);
5721 [(set_attr "type" "lea")
5722 (set_attr "mode" "SI")])
5724 (define_insn_and_split "*lea_general_2"
5725 [(set (match_operand 0 "register_operand" "=r")
5726 (plus (mult (match_operand 1 "index_register_operand" "l")
5727 (match_operand 2 "const248_operand" "i"))
5728 (match_operand 3 "nonmemory_operand" "ri")))]
5729 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5730 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5731 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5732 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5733 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5734 || GET_MODE (operands[3]) == VOIDmode)"
5736 "&& reload_completed"
5740 operands[0] = gen_lowpart (SImode, operands[0]);
5741 operands[1] = gen_lowpart (Pmode, operands[1]);
5742 operands[3] = gen_lowpart (Pmode, operands[3]);
5743 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5745 if (Pmode != SImode)
5746 pat = gen_rtx_SUBREG (SImode, pat, 0);
5747 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5750 [(set_attr "type" "lea")
5751 (set_attr "mode" "SI")])
5753 (define_insn_and_split "*lea_general_2_zext"
5754 [(set (match_operand:DI 0 "register_operand" "=r")
5756 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5757 (match_operand:SI 2 "const248_operand" "n"))
5758 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5761 "&& reload_completed"
5763 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5765 (match_dup 3)) 0)))]
5767 operands[1] = gen_lowpart (Pmode, operands[1]);
5768 operands[3] = gen_lowpart (Pmode, operands[3]);
5770 [(set_attr "type" "lea")
5771 (set_attr "mode" "SI")])
5773 (define_insn_and_split "*lea_general_3"
5774 [(set (match_operand 0 "register_operand" "=r")
5775 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5776 (match_operand 2 "const248_operand" "i"))
5777 (match_operand 3 "register_operand" "r"))
5778 (match_operand 4 "immediate_operand" "i")))]
5779 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5780 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5781 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5782 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5783 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5785 "&& reload_completed"
5789 operands[0] = gen_lowpart (SImode, operands[0]);
5790 operands[1] = gen_lowpart (Pmode, operands[1]);
5791 operands[3] = gen_lowpart (Pmode, operands[3]);
5792 operands[4] = gen_lowpart (Pmode, operands[4]);
5793 pat = gen_rtx_PLUS (Pmode,
5794 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5798 if (Pmode != SImode)
5799 pat = gen_rtx_SUBREG (SImode, pat, 0);
5800 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5803 [(set_attr "type" "lea")
5804 (set_attr "mode" "SI")])
5806 (define_insn_and_split "*lea_general_3_zext"
5807 [(set (match_operand:DI 0 "register_operand" "=r")
5809 (plus:SI (plus:SI (mult:SI
5810 (match_operand:SI 1 "index_register_operand" "l")
5811 (match_operand:SI 2 "const248_operand" "n"))
5812 (match_operand:SI 3 "register_operand" "r"))
5813 (match_operand:SI 4 "immediate_operand" "i"))))]
5816 "&& reload_completed"
5818 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5821 (match_dup 4)) 0)))]
5823 operands[1] = gen_lowpart (Pmode, operands[1]);
5824 operands[3] = gen_lowpart (Pmode, operands[3]);
5825 operands[4] = gen_lowpart (Pmode, operands[4]);
5827 [(set_attr "type" "lea")
5828 (set_attr "mode" "SI")])
5830 (define_insn "*adddi_1_rex64"
5831 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5832 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5833 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5834 (clobber (reg:CC FLAGS_REG))]
5835 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5837 switch (get_attr_type (insn))
5840 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5841 return "lea{q}\t{%a2, %0|%0, %a2}";
5844 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5845 if (operands[2] == const1_rtx)
5846 return "inc{q}\t%0";
5849 gcc_assert (operands[2] == constm1_rtx);
5850 return "dec{q}\t%0";
5854 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5856 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5857 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5858 if (CONST_INT_P (operands[2])
5859 /* Avoid overflows. */
5860 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5861 && (INTVAL (operands[2]) == 128
5862 || (INTVAL (operands[2]) < 0
5863 && INTVAL (operands[2]) != -128)))
5865 operands[2] = GEN_INT (-INTVAL (operands[2]));
5866 return "sub{q}\t{%2, %0|%0, %2}";
5868 return "add{q}\t{%2, %0|%0, %2}";
5872 (cond [(eq_attr "alternative" "2")
5873 (const_string "lea")
5874 ; Current assemblers are broken and do not allow @GOTOFF in
5875 ; ought but a memory context.
5876 (match_operand:DI 2 "pic_symbolic_operand" "")
5877 (const_string "lea")
5878 (match_operand:DI 2 "incdec_operand" "")
5879 (const_string "incdec")
5881 (const_string "alu")))
5882 (set_attr "mode" "DI")])
5884 ;; Convert lea to the lea pattern to avoid flags dependency.
5886 [(set (match_operand:DI 0 "register_operand" "")
5887 (plus:DI (match_operand:DI 1 "register_operand" "")
5888 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5889 (clobber (reg:CC FLAGS_REG))]
5890 "TARGET_64BIT && reload_completed
5891 && true_regnum (operands[0]) != true_regnum (operands[1])"
5893 (plus:DI (match_dup 1)
5897 (define_insn "*adddi_2_rex64"
5898 [(set (reg FLAGS_REG)
5900 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5901 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5903 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5904 (plus:DI (match_dup 1) (match_dup 2)))]
5905 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5906 && ix86_binary_operator_ok (PLUS, DImode, operands)
5907 /* Current assemblers are broken and do not allow @GOTOFF in
5908 ought but a memory context. */
5909 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5911 switch (get_attr_type (insn))
5914 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5915 if (operands[2] == const1_rtx)
5916 return "inc{q}\t%0";
5919 gcc_assert (operands[2] == constm1_rtx);
5920 return "dec{q}\t%0";
5924 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5925 /* ???? We ought to handle there the 32bit case too
5926 - do we need new constraint? */
5927 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5928 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5929 if (CONST_INT_P (operands[2])
5930 /* Avoid overflows. */
5931 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5932 && (INTVAL (operands[2]) == 128
5933 || (INTVAL (operands[2]) < 0
5934 && INTVAL (operands[2]) != -128)))
5936 operands[2] = GEN_INT (-INTVAL (operands[2]));
5937 return "sub{q}\t{%2, %0|%0, %2}";
5939 return "add{q}\t{%2, %0|%0, %2}";
5943 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5944 (const_string "incdec")
5945 (const_string "alu")))
5946 (set_attr "mode" "DI")])
5948 (define_insn "*adddi_3_rex64"
5949 [(set (reg FLAGS_REG)
5950 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5951 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5952 (clobber (match_scratch:DI 0 "=r"))]
5954 && ix86_match_ccmode (insn, CCZmode)
5955 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5956 /* Current assemblers are broken and do not allow @GOTOFF in
5957 ought but a memory context. */
5958 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5960 switch (get_attr_type (insn))
5963 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5964 if (operands[2] == const1_rtx)
5965 return "inc{q}\t%0";
5968 gcc_assert (operands[2] == constm1_rtx);
5969 return "dec{q}\t%0";
5973 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5974 /* ???? We ought to handle there the 32bit case too
5975 - do we need new constraint? */
5976 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5977 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5978 if (CONST_INT_P (operands[2])
5979 /* Avoid overflows. */
5980 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5981 && (INTVAL (operands[2]) == 128
5982 || (INTVAL (operands[2]) < 0
5983 && INTVAL (operands[2]) != -128)))
5985 operands[2] = GEN_INT (-INTVAL (operands[2]));
5986 return "sub{q}\t{%2, %0|%0, %2}";
5988 return "add{q}\t{%2, %0|%0, %2}";
5992 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5993 (const_string "incdec")
5994 (const_string "alu")))
5995 (set_attr "mode" "DI")])
5997 ; For comparisons against 1, -1 and 128, we may generate better code
5998 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5999 ; is matched then. We can't accept general immediate, because for
6000 ; case of overflows, the result is messed up.
6001 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6003 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6004 ; only for comparisons not depending on it.
6005 (define_insn "*adddi_4_rex64"
6006 [(set (reg FLAGS_REG)
6007 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6008 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6009 (clobber (match_scratch:DI 0 "=rm"))]
6011 && ix86_match_ccmode (insn, CCGCmode)"
6013 switch (get_attr_type (insn))
6016 if (operands[2] == constm1_rtx)
6017 return "inc{q}\t%0";
6020 gcc_assert (operands[2] == const1_rtx);
6021 return "dec{q}\t%0";
6025 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6026 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6027 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6028 if ((INTVAL (operands[2]) == -128
6029 || (INTVAL (operands[2]) > 0
6030 && INTVAL (operands[2]) != 128))
6031 /* Avoid overflows. */
6032 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6033 return "sub{q}\t{%2, %0|%0, %2}";
6034 operands[2] = GEN_INT (-INTVAL (operands[2]));
6035 return "add{q}\t{%2, %0|%0, %2}";
6039 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6040 (const_string "incdec")
6041 (const_string "alu")))
6042 (set_attr "mode" "DI")])
6044 (define_insn "*adddi_5_rex64"
6045 [(set (reg FLAGS_REG)
6047 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6048 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6050 (clobber (match_scratch:DI 0 "=r"))]
6052 && ix86_match_ccmode (insn, CCGOCmode)
6053 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6054 /* Current assemblers are broken and do not allow @GOTOFF in
6055 ought but a memory context. */
6056 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6058 switch (get_attr_type (insn))
6061 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6062 if (operands[2] == const1_rtx)
6063 return "inc{q}\t%0";
6066 gcc_assert (operands[2] == constm1_rtx);
6067 return "dec{q}\t%0";
6071 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6072 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6073 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6074 if (CONST_INT_P (operands[2])
6075 /* Avoid overflows. */
6076 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6077 && (INTVAL (operands[2]) == 128
6078 || (INTVAL (operands[2]) < 0
6079 && INTVAL (operands[2]) != -128)))
6081 operands[2] = GEN_INT (-INTVAL (operands[2]));
6082 return "sub{q}\t{%2, %0|%0, %2}";
6084 return "add{q}\t{%2, %0|%0, %2}";
6088 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6089 (const_string "incdec")
6090 (const_string "alu")))
6091 (set_attr "mode" "DI")])
6094 (define_insn "*addsi_1"
6095 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6096 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6097 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6098 (clobber (reg:CC FLAGS_REG))]
6099 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6101 switch (get_attr_type (insn))
6104 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6105 return "lea{l}\t{%a2, %0|%0, %a2}";
6108 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6109 if (operands[2] == const1_rtx)
6110 return "inc{l}\t%0";
6113 gcc_assert (operands[2] == constm1_rtx);
6114 return "dec{l}\t%0";
6118 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6120 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6121 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6122 if (CONST_INT_P (operands[2])
6123 && (INTVAL (operands[2]) == 128
6124 || (INTVAL (operands[2]) < 0
6125 && INTVAL (operands[2]) != -128)))
6127 operands[2] = GEN_INT (-INTVAL (operands[2]));
6128 return "sub{l}\t{%2, %0|%0, %2}";
6130 return "add{l}\t{%2, %0|%0, %2}";
6134 (cond [(eq_attr "alternative" "2")
6135 (const_string "lea")
6136 ; Current assemblers are broken and do not allow @GOTOFF in
6137 ; ought but a memory context.
6138 (match_operand:SI 2 "pic_symbolic_operand" "")
6139 (const_string "lea")
6140 (match_operand:SI 2 "incdec_operand" "")
6141 (const_string "incdec")
6143 (const_string "alu")))
6144 (set_attr "mode" "SI")])
6146 ;; Convert lea to the lea pattern to avoid flags dependency.
6148 [(set (match_operand 0 "register_operand" "")
6149 (plus (match_operand 1 "register_operand" "")
6150 (match_operand 2 "nonmemory_operand" "")))
6151 (clobber (reg:CC FLAGS_REG))]
6153 && true_regnum (operands[0]) != true_regnum (operands[1])"
6157 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6158 may confuse gen_lowpart. */
6159 if (GET_MODE (operands[0]) != Pmode)
6161 operands[1] = gen_lowpart (Pmode, operands[1]);
6162 operands[2] = gen_lowpart (Pmode, operands[2]);
6164 operands[0] = gen_lowpart (SImode, operands[0]);
6165 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6166 if (Pmode != SImode)
6167 pat = gen_rtx_SUBREG (SImode, pat, 0);
6168 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6172 ;; It may seem that nonimmediate operand is proper one for operand 1.
6173 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6174 ;; we take care in ix86_binary_operator_ok to not allow two memory
6175 ;; operands so proper swapping will be done in reload. This allow
6176 ;; patterns constructed from addsi_1 to match.
6177 (define_insn "addsi_1_zext"
6178 [(set (match_operand:DI 0 "register_operand" "=r,r")
6180 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6181 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6182 (clobber (reg:CC FLAGS_REG))]
6183 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6185 switch (get_attr_type (insn))
6188 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6189 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6192 if (operands[2] == const1_rtx)
6193 return "inc{l}\t%k0";
6196 gcc_assert (operands[2] == constm1_rtx);
6197 return "dec{l}\t%k0";
6201 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6202 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6203 if (CONST_INT_P (operands[2])
6204 && (INTVAL (operands[2]) == 128
6205 || (INTVAL (operands[2]) < 0
6206 && INTVAL (operands[2]) != -128)))
6208 operands[2] = GEN_INT (-INTVAL (operands[2]));
6209 return "sub{l}\t{%2, %k0|%k0, %2}";
6211 return "add{l}\t{%2, %k0|%k0, %2}";
6215 (cond [(eq_attr "alternative" "1")
6216 (const_string "lea")
6217 ; Current assemblers are broken and do not allow @GOTOFF in
6218 ; ought but a memory context.
6219 (match_operand:SI 2 "pic_symbolic_operand" "")
6220 (const_string "lea")
6221 (match_operand:SI 2 "incdec_operand" "")
6222 (const_string "incdec")
6224 (const_string "alu")))
6225 (set_attr "mode" "SI")])
6227 ;; Convert lea to the lea pattern to avoid flags dependency.
6229 [(set (match_operand:DI 0 "register_operand" "")
6231 (plus:SI (match_operand:SI 1 "register_operand" "")
6232 (match_operand:SI 2 "nonmemory_operand" ""))))
6233 (clobber (reg:CC FLAGS_REG))]
6234 "TARGET_64BIT && reload_completed
6235 && true_regnum (operands[0]) != true_regnum (operands[1])"
6237 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6239 operands[1] = gen_lowpart (Pmode, operands[1]);
6240 operands[2] = gen_lowpart (Pmode, operands[2]);
6243 (define_insn "*addsi_2"
6244 [(set (reg FLAGS_REG)
6246 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6247 (match_operand:SI 2 "general_operand" "rmni,rni"))
6249 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6250 (plus:SI (match_dup 1) (match_dup 2)))]
6251 "ix86_match_ccmode (insn, CCGOCmode)
6252 && ix86_binary_operator_ok (PLUS, SImode, operands)
6253 /* Current assemblers are broken and do not allow @GOTOFF in
6254 ought but a memory context. */
6255 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6257 switch (get_attr_type (insn))
6260 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6261 if (operands[2] == const1_rtx)
6262 return "inc{l}\t%0";
6265 gcc_assert (operands[2] == constm1_rtx);
6266 return "dec{l}\t%0";
6270 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6271 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6272 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6273 if (CONST_INT_P (operands[2])
6274 && (INTVAL (operands[2]) == 128
6275 || (INTVAL (operands[2]) < 0
6276 && INTVAL (operands[2]) != -128)))
6278 operands[2] = GEN_INT (-INTVAL (operands[2]));
6279 return "sub{l}\t{%2, %0|%0, %2}";
6281 return "add{l}\t{%2, %0|%0, %2}";
6285 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6286 (const_string "incdec")
6287 (const_string "alu")))
6288 (set_attr "mode" "SI")])
6290 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6291 (define_insn "*addsi_2_zext"
6292 [(set (reg FLAGS_REG)
6294 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6295 (match_operand:SI 2 "general_operand" "rmni"))
6297 (set (match_operand:DI 0 "register_operand" "=r")
6298 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6299 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6300 && ix86_binary_operator_ok (PLUS, SImode, operands)
6301 /* Current assemblers are broken and do not allow @GOTOFF in
6302 ought but a memory context. */
6303 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6305 switch (get_attr_type (insn))
6308 if (operands[2] == const1_rtx)
6309 return "inc{l}\t%k0";
6312 gcc_assert (operands[2] == constm1_rtx);
6313 return "dec{l}\t%k0";
6317 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6318 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6319 if (CONST_INT_P (operands[2])
6320 && (INTVAL (operands[2]) == 128
6321 || (INTVAL (operands[2]) < 0
6322 && INTVAL (operands[2]) != -128)))
6324 operands[2] = GEN_INT (-INTVAL (operands[2]));
6325 return "sub{l}\t{%2, %k0|%k0, %2}";
6327 return "add{l}\t{%2, %k0|%k0, %2}";
6331 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6332 (const_string "incdec")
6333 (const_string "alu")))
6334 (set_attr "mode" "SI")])
6336 (define_insn "*addsi_3"
6337 [(set (reg FLAGS_REG)
6338 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6339 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6340 (clobber (match_scratch:SI 0 "=r"))]
6341 "ix86_match_ccmode (insn, CCZmode)
6342 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6343 /* Current assemblers are broken and do not allow @GOTOFF in
6344 ought but a memory context. */
6345 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6347 switch (get_attr_type (insn))
6350 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6351 if (operands[2] == const1_rtx)
6352 return "inc{l}\t%0";
6355 gcc_assert (operands[2] == constm1_rtx);
6356 return "dec{l}\t%0";
6360 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6361 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6362 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6363 if (CONST_INT_P (operands[2])
6364 && (INTVAL (operands[2]) == 128
6365 || (INTVAL (operands[2]) < 0
6366 && INTVAL (operands[2]) != -128)))
6368 operands[2] = GEN_INT (-INTVAL (operands[2]));
6369 return "sub{l}\t{%2, %0|%0, %2}";
6371 return "add{l}\t{%2, %0|%0, %2}";
6375 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6376 (const_string "incdec")
6377 (const_string "alu")))
6378 (set_attr "mode" "SI")])
6380 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6381 (define_insn "*addsi_3_zext"
6382 [(set (reg FLAGS_REG)
6383 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6384 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6385 (set (match_operand:DI 0 "register_operand" "=r")
6386 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6387 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6388 && ix86_binary_operator_ok (PLUS, SImode, operands)
6389 /* Current assemblers are broken and do not allow @GOTOFF in
6390 ought but a memory context. */
6391 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6393 switch (get_attr_type (insn))
6396 if (operands[2] == const1_rtx)
6397 return "inc{l}\t%k0";
6400 gcc_assert (operands[2] == constm1_rtx);
6401 return "dec{l}\t%k0";
6405 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6406 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6407 if (CONST_INT_P (operands[2])
6408 && (INTVAL (operands[2]) == 128
6409 || (INTVAL (operands[2]) < 0
6410 && INTVAL (operands[2]) != -128)))
6412 operands[2] = GEN_INT (-INTVAL (operands[2]));
6413 return "sub{l}\t{%2, %k0|%k0, %2}";
6415 return "add{l}\t{%2, %k0|%k0, %2}";
6419 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6420 (const_string "incdec")
6421 (const_string "alu")))
6422 (set_attr "mode" "SI")])
6424 ; For comparisons against 1, -1 and 128, we may generate better code
6425 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6426 ; is matched then. We can't accept general immediate, because for
6427 ; case of overflows, the result is messed up.
6428 ; This pattern also don't hold of 0x80000000, since the value overflows
6430 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6431 ; only for comparisons not depending on it.
6432 (define_insn "*addsi_4"
6433 [(set (reg FLAGS_REG)
6434 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6435 (match_operand:SI 2 "const_int_operand" "n")))
6436 (clobber (match_scratch:SI 0 "=rm"))]
6437 "ix86_match_ccmode (insn, CCGCmode)
6438 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6440 switch (get_attr_type (insn))
6443 if (operands[2] == constm1_rtx)
6444 return "inc{l}\t%0";
6447 gcc_assert (operands[2] == const1_rtx);
6448 return "dec{l}\t%0";
6452 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6453 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6454 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6455 if ((INTVAL (operands[2]) == -128
6456 || (INTVAL (operands[2]) > 0
6457 && INTVAL (operands[2]) != 128)))
6458 return "sub{l}\t{%2, %0|%0, %2}";
6459 operands[2] = GEN_INT (-INTVAL (operands[2]));
6460 return "add{l}\t{%2, %0|%0, %2}";
6464 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6465 (const_string "incdec")
6466 (const_string "alu")))
6467 (set_attr "mode" "SI")])
6469 (define_insn "*addsi_5"
6470 [(set (reg FLAGS_REG)
6472 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6473 (match_operand:SI 2 "general_operand" "rmni"))
6475 (clobber (match_scratch:SI 0 "=r"))]
6476 "ix86_match_ccmode (insn, CCGOCmode)
6477 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6478 /* Current assemblers are broken and do not allow @GOTOFF in
6479 ought but a memory context. */
6480 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6482 switch (get_attr_type (insn))
6485 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6486 if (operands[2] == const1_rtx)
6487 return "inc{l}\t%0";
6490 gcc_assert (operands[2] == constm1_rtx);
6491 return "dec{l}\t%0";
6495 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6496 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6497 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6498 if (CONST_INT_P (operands[2])
6499 && (INTVAL (operands[2]) == 128
6500 || (INTVAL (operands[2]) < 0
6501 && INTVAL (operands[2]) != -128)))
6503 operands[2] = GEN_INT (-INTVAL (operands[2]));
6504 return "sub{l}\t{%2, %0|%0, %2}";
6506 return "add{l}\t{%2, %0|%0, %2}";
6510 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6511 (const_string "incdec")
6512 (const_string "alu")))
6513 (set_attr "mode" "SI")])
6515 (define_expand "addhi3"
6516 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6517 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6518 (match_operand:HI 2 "general_operand" "")))
6519 (clobber (reg:CC FLAGS_REG))])]
6520 "TARGET_HIMODE_MATH"
6521 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6523 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6524 ;; type optimizations enabled by define-splits. This is not important
6525 ;; for PII, and in fact harmful because of partial register stalls.
6527 (define_insn "*addhi_1_lea"
6528 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6529 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6530 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6531 (clobber (reg:CC FLAGS_REG))]
6532 "!TARGET_PARTIAL_REG_STALL
6533 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6535 switch (get_attr_type (insn))
6540 if (operands[2] == const1_rtx)
6541 return "inc{w}\t%0";
6544 gcc_assert (operands[2] == constm1_rtx);
6545 return "dec{w}\t%0";
6549 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6550 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6551 if (CONST_INT_P (operands[2])
6552 && (INTVAL (operands[2]) == 128
6553 || (INTVAL (operands[2]) < 0
6554 && INTVAL (operands[2]) != -128)))
6556 operands[2] = GEN_INT (-INTVAL (operands[2]));
6557 return "sub{w}\t{%2, %0|%0, %2}";
6559 return "add{w}\t{%2, %0|%0, %2}";
6563 (if_then_else (eq_attr "alternative" "2")
6564 (const_string "lea")
6565 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6566 (const_string "incdec")
6567 (const_string "alu"))))
6568 (set_attr "mode" "HI,HI,SI")])
6570 (define_insn "*addhi_1"
6571 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6572 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6573 (match_operand:HI 2 "general_operand" "ri,rm")))
6574 (clobber (reg:CC FLAGS_REG))]
6575 "TARGET_PARTIAL_REG_STALL
6576 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6578 switch (get_attr_type (insn))
6581 if (operands[2] == const1_rtx)
6582 return "inc{w}\t%0";
6585 gcc_assert (operands[2] == constm1_rtx);
6586 return "dec{w}\t%0";
6590 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6591 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6592 if (CONST_INT_P (operands[2])
6593 && (INTVAL (operands[2]) == 128
6594 || (INTVAL (operands[2]) < 0
6595 && INTVAL (operands[2]) != -128)))
6597 operands[2] = GEN_INT (-INTVAL (operands[2]));
6598 return "sub{w}\t{%2, %0|%0, %2}";
6600 return "add{w}\t{%2, %0|%0, %2}";
6604 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6605 (const_string "incdec")
6606 (const_string "alu")))
6607 (set_attr "mode" "HI")])
6609 (define_insn "*addhi_2"
6610 [(set (reg FLAGS_REG)
6612 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6613 (match_operand:HI 2 "general_operand" "rmni,rni"))
6615 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6616 (plus:HI (match_dup 1) (match_dup 2)))]
6617 "ix86_match_ccmode (insn, CCGOCmode)
6618 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6620 switch (get_attr_type (insn))
6623 if (operands[2] == const1_rtx)
6624 return "inc{w}\t%0";
6627 gcc_assert (operands[2] == constm1_rtx);
6628 return "dec{w}\t%0";
6632 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6633 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6634 if (CONST_INT_P (operands[2])
6635 && (INTVAL (operands[2]) == 128
6636 || (INTVAL (operands[2]) < 0
6637 && INTVAL (operands[2]) != -128)))
6639 operands[2] = GEN_INT (-INTVAL (operands[2]));
6640 return "sub{w}\t{%2, %0|%0, %2}";
6642 return "add{w}\t{%2, %0|%0, %2}";
6646 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6647 (const_string "incdec")
6648 (const_string "alu")))
6649 (set_attr "mode" "HI")])
6651 (define_insn "*addhi_3"
6652 [(set (reg FLAGS_REG)
6653 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6654 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6655 (clobber (match_scratch:HI 0 "=r"))]
6656 "ix86_match_ccmode (insn, CCZmode)
6657 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6659 switch (get_attr_type (insn))
6662 if (operands[2] == const1_rtx)
6663 return "inc{w}\t%0";
6666 gcc_assert (operands[2] == constm1_rtx);
6667 return "dec{w}\t%0";
6671 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6672 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6673 if (CONST_INT_P (operands[2])
6674 && (INTVAL (operands[2]) == 128
6675 || (INTVAL (operands[2]) < 0
6676 && INTVAL (operands[2]) != -128)))
6678 operands[2] = GEN_INT (-INTVAL (operands[2]));
6679 return "sub{w}\t{%2, %0|%0, %2}";
6681 return "add{w}\t{%2, %0|%0, %2}";
6685 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6686 (const_string "incdec")
6687 (const_string "alu")))
6688 (set_attr "mode" "HI")])
6690 ; See comments above addsi_4 for details.
6691 (define_insn "*addhi_4"
6692 [(set (reg FLAGS_REG)
6693 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6694 (match_operand:HI 2 "const_int_operand" "n")))
6695 (clobber (match_scratch:HI 0 "=rm"))]
6696 "ix86_match_ccmode (insn, CCGCmode)
6697 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6699 switch (get_attr_type (insn))
6702 if (operands[2] == constm1_rtx)
6703 return "inc{w}\t%0";
6706 gcc_assert (operands[2] == const1_rtx);
6707 return "dec{w}\t%0";
6711 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6712 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6713 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6714 if ((INTVAL (operands[2]) == -128
6715 || (INTVAL (operands[2]) > 0
6716 && INTVAL (operands[2]) != 128)))
6717 return "sub{w}\t{%2, %0|%0, %2}";
6718 operands[2] = GEN_INT (-INTVAL (operands[2]));
6719 return "add{w}\t{%2, %0|%0, %2}";
6723 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6724 (const_string "incdec")
6725 (const_string "alu")))
6726 (set_attr "mode" "SI")])
6729 (define_insn "*addhi_5"
6730 [(set (reg FLAGS_REG)
6732 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6733 (match_operand:HI 2 "general_operand" "rmni"))
6735 (clobber (match_scratch:HI 0 "=r"))]
6736 "ix86_match_ccmode (insn, CCGOCmode)
6737 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6739 switch (get_attr_type (insn))
6742 if (operands[2] == const1_rtx)
6743 return "inc{w}\t%0";
6746 gcc_assert (operands[2] == constm1_rtx);
6747 return "dec{w}\t%0";
6751 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6752 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6753 if (CONST_INT_P (operands[2])
6754 && (INTVAL (operands[2]) == 128
6755 || (INTVAL (operands[2]) < 0
6756 && INTVAL (operands[2]) != -128)))
6758 operands[2] = GEN_INT (-INTVAL (operands[2]));
6759 return "sub{w}\t{%2, %0|%0, %2}";
6761 return "add{w}\t{%2, %0|%0, %2}";
6765 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6766 (const_string "incdec")
6767 (const_string "alu")))
6768 (set_attr "mode" "HI")])
6770 (define_expand "addqi3"
6771 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6772 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6773 (match_operand:QI 2 "general_operand" "")))
6774 (clobber (reg:CC FLAGS_REG))])]
6775 "TARGET_QIMODE_MATH"
6776 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6778 ;; %%% Potential partial reg stall on alternative 2. What to do?
6779 (define_insn "*addqi_1_lea"
6780 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6781 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6782 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6783 (clobber (reg:CC FLAGS_REG))]
6784 "!TARGET_PARTIAL_REG_STALL
6785 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6787 int widen = (which_alternative == 2);
6788 switch (get_attr_type (insn))
6793 if (operands[2] == const1_rtx)
6794 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6797 gcc_assert (operands[2] == constm1_rtx);
6798 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6802 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6803 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6804 if (CONST_INT_P (operands[2])
6805 && (INTVAL (operands[2]) == 128
6806 || (INTVAL (operands[2]) < 0
6807 && INTVAL (operands[2]) != -128)))
6809 operands[2] = GEN_INT (-INTVAL (operands[2]));
6811 return "sub{l}\t{%2, %k0|%k0, %2}";
6813 return "sub{b}\t{%2, %0|%0, %2}";
6816 return "add{l}\t{%k2, %k0|%k0, %k2}";
6818 return "add{b}\t{%2, %0|%0, %2}";
6822 (if_then_else (eq_attr "alternative" "3")
6823 (const_string "lea")
6824 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6825 (const_string "incdec")
6826 (const_string "alu"))))
6827 (set_attr "mode" "QI,QI,SI,SI")])
6829 (define_insn "*addqi_1"
6830 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6831 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6832 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6833 (clobber (reg:CC FLAGS_REG))]
6834 "TARGET_PARTIAL_REG_STALL
6835 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6837 int widen = (which_alternative == 2);
6838 switch (get_attr_type (insn))
6841 if (operands[2] == const1_rtx)
6842 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6845 gcc_assert (operands[2] == constm1_rtx);
6846 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6850 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6851 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6852 if (CONST_INT_P (operands[2])
6853 && (INTVAL (operands[2]) == 128
6854 || (INTVAL (operands[2]) < 0
6855 && INTVAL (operands[2]) != -128)))
6857 operands[2] = GEN_INT (-INTVAL (operands[2]));
6859 return "sub{l}\t{%2, %k0|%k0, %2}";
6861 return "sub{b}\t{%2, %0|%0, %2}";
6864 return "add{l}\t{%k2, %k0|%k0, %k2}";
6866 return "add{b}\t{%2, %0|%0, %2}";
6870 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6871 (const_string "incdec")
6872 (const_string "alu")))
6873 (set_attr "mode" "QI,QI,SI")])
6875 (define_insn "*addqi_1_slp"
6876 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6877 (plus:QI (match_dup 0)
6878 (match_operand:QI 1 "general_operand" "qn,qnm")))
6879 (clobber (reg:CC FLAGS_REG))]
6880 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6881 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6883 switch (get_attr_type (insn))
6886 if (operands[1] == const1_rtx)
6887 return "inc{b}\t%0";
6890 gcc_assert (operands[1] == constm1_rtx);
6891 return "dec{b}\t%0";
6895 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6896 if (CONST_INT_P (operands[1])
6897 && INTVAL (operands[1]) < 0)
6899 operands[1] = GEN_INT (-INTVAL (operands[1]));
6900 return "sub{b}\t{%1, %0|%0, %1}";
6902 return "add{b}\t{%1, %0|%0, %1}";
6906 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6907 (const_string "incdec")
6908 (const_string "alu1")))
6909 (set (attr "memory")
6910 (if_then_else (match_operand 1 "memory_operand" "")
6911 (const_string "load")
6912 (const_string "none")))
6913 (set_attr "mode" "QI")])
6915 (define_insn "*addqi_2"
6916 [(set (reg FLAGS_REG)
6918 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6919 (match_operand:QI 2 "general_operand" "qmni,qni"))
6921 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6922 (plus:QI (match_dup 1) (match_dup 2)))]
6923 "ix86_match_ccmode (insn, CCGOCmode)
6924 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6926 switch (get_attr_type (insn))
6929 if (operands[2] == const1_rtx)
6930 return "inc{b}\t%0";
6933 gcc_assert (operands[2] == constm1_rtx
6934 || (CONST_INT_P (operands[2])
6935 && INTVAL (operands[2]) == 255));
6936 return "dec{b}\t%0";
6940 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6941 if (CONST_INT_P (operands[2])
6942 && INTVAL (operands[2]) < 0)
6944 operands[2] = GEN_INT (-INTVAL (operands[2]));
6945 return "sub{b}\t{%2, %0|%0, %2}";
6947 return "add{b}\t{%2, %0|%0, %2}";
6951 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6952 (const_string "incdec")
6953 (const_string "alu")))
6954 (set_attr "mode" "QI")])
6956 (define_insn "*addqi_3"
6957 [(set (reg FLAGS_REG)
6958 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6959 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6960 (clobber (match_scratch:QI 0 "=q"))]
6961 "ix86_match_ccmode (insn, CCZmode)
6962 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6964 switch (get_attr_type (insn))
6967 if (operands[2] == const1_rtx)
6968 return "inc{b}\t%0";
6971 gcc_assert (operands[2] == constm1_rtx
6972 || (CONST_INT_P (operands[2])
6973 && INTVAL (operands[2]) == 255));
6974 return "dec{b}\t%0";
6978 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6979 if (CONST_INT_P (operands[2])
6980 && INTVAL (operands[2]) < 0)
6982 operands[2] = GEN_INT (-INTVAL (operands[2]));
6983 return "sub{b}\t{%2, %0|%0, %2}";
6985 return "add{b}\t{%2, %0|%0, %2}";
6989 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6990 (const_string "incdec")
6991 (const_string "alu")))
6992 (set_attr "mode" "QI")])
6994 ; See comments above addsi_4 for details.
6995 (define_insn "*addqi_4"
6996 [(set (reg FLAGS_REG)
6997 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6998 (match_operand:QI 2 "const_int_operand" "n")))
6999 (clobber (match_scratch:QI 0 "=qm"))]
7000 "ix86_match_ccmode (insn, CCGCmode)
7001 && (INTVAL (operands[2]) & 0xff) != 0x80"
7003 switch (get_attr_type (insn))
7006 if (operands[2] == constm1_rtx
7007 || (CONST_INT_P (operands[2])
7008 && INTVAL (operands[2]) == 255))
7009 return "inc{b}\t%0";
7012 gcc_assert (operands[2] == const1_rtx);
7013 return "dec{b}\t%0";
7017 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7018 if (INTVAL (operands[2]) < 0)
7020 operands[2] = GEN_INT (-INTVAL (operands[2]));
7021 return "add{b}\t{%2, %0|%0, %2}";
7023 return "sub{b}\t{%2, %0|%0, %2}";
7027 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7028 (const_string "incdec")
7029 (const_string "alu")))
7030 (set_attr "mode" "QI")])
7033 (define_insn "*addqi_5"
7034 [(set (reg FLAGS_REG)
7036 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7037 (match_operand:QI 2 "general_operand" "qmni"))
7039 (clobber (match_scratch:QI 0 "=q"))]
7040 "ix86_match_ccmode (insn, CCGOCmode)
7041 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7043 switch (get_attr_type (insn))
7046 if (operands[2] == const1_rtx)
7047 return "inc{b}\t%0";
7050 gcc_assert (operands[2] == constm1_rtx
7051 || (CONST_INT_P (operands[2])
7052 && INTVAL (operands[2]) == 255));
7053 return "dec{b}\t%0";
7057 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7058 if (CONST_INT_P (operands[2])
7059 && INTVAL (operands[2]) < 0)
7061 operands[2] = GEN_INT (-INTVAL (operands[2]));
7062 return "sub{b}\t{%2, %0|%0, %2}";
7064 return "add{b}\t{%2, %0|%0, %2}";
7068 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7069 (const_string "incdec")
7070 (const_string "alu")))
7071 (set_attr "mode" "QI")])
7074 (define_insn "addqi_ext_1"
7075 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7080 (match_operand 1 "ext_register_operand" "0")
7083 (match_operand:QI 2 "general_operand" "Qmn")))
7084 (clobber (reg:CC FLAGS_REG))]
7087 switch (get_attr_type (insn))
7090 if (operands[2] == const1_rtx)
7091 return "inc{b}\t%h0";
7094 gcc_assert (operands[2] == constm1_rtx
7095 || (CONST_INT_P (operands[2])
7096 && INTVAL (operands[2]) == 255));
7097 return "dec{b}\t%h0";
7101 return "add{b}\t{%2, %h0|%h0, %2}";
7105 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7106 (const_string "incdec")
7107 (const_string "alu")))
7108 (set_attr "mode" "QI")])
7110 (define_insn "*addqi_ext_1_rex64"
7111 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7116 (match_operand 1 "ext_register_operand" "0")
7119 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7120 (clobber (reg:CC FLAGS_REG))]
7123 switch (get_attr_type (insn))
7126 if (operands[2] == const1_rtx)
7127 return "inc{b}\t%h0";
7130 gcc_assert (operands[2] == constm1_rtx
7131 || (CONST_INT_P (operands[2])
7132 && INTVAL (operands[2]) == 255));
7133 return "dec{b}\t%h0";
7137 return "add{b}\t{%2, %h0|%h0, %2}";
7141 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7142 (const_string "incdec")
7143 (const_string "alu")))
7144 (set_attr "mode" "QI")])
7146 (define_insn "*addqi_ext_2"
7147 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7152 (match_operand 1 "ext_register_operand" "%0")
7156 (match_operand 2 "ext_register_operand" "Q")
7159 (clobber (reg:CC FLAGS_REG))]
7161 "add{b}\t{%h2, %h0|%h0, %h2}"
7162 [(set_attr "type" "alu")
7163 (set_attr "mode" "QI")])
7165 ;; The patterns that match these are at the end of this file.
7167 (define_expand "addxf3"
7168 [(set (match_operand:XF 0 "register_operand" "")
7169 (plus:XF (match_operand:XF 1 "register_operand" "")
7170 (match_operand:XF 2 "register_operand" "")))]
7174 (define_expand "add<mode>3"
7175 [(set (match_operand:MODEF 0 "register_operand" "")
7176 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7177 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7178 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7181 ;; Subtract instructions
7183 ;; %%% splits for subditi3
7185 (define_expand "subti3"
7186 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7187 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7188 (match_operand:TI 2 "x86_64_general_operand" "")))
7189 (clobber (reg:CC FLAGS_REG))])]
7191 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7193 (define_insn "*subti3_1"
7194 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7195 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7196 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7197 (clobber (reg:CC FLAGS_REG))]
7198 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7202 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7203 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7204 (match_operand:TI 2 "x86_64_general_operand" "")))
7205 (clobber (reg:CC FLAGS_REG))]
7206 "TARGET_64BIT && reload_completed"
7207 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7208 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7209 (parallel [(set (match_dup 3)
7210 (minus:DI (match_dup 4)
7211 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7213 (clobber (reg:CC FLAGS_REG))])]
7214 "split_ti (operands+0, 1, operands+0, operands+3);
7215 split_ti (operands+1, 1, operands+1, operands+4);
7216 split_ti (operands+2, 1, operands+2, operands+5);")
7218 ;; %%% splits for subsidi3
7220 (define_expand "subdi3"
7221 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7222 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7223 (match_operand:DI 2 "x86_64_general_operand" "")))
7224 (clobber (reg:CC FLAGS_REG))])]
7226 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7228 (define_insn "*subdi3_1"
7229 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7230 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7231 (match_operand:DI 2 "general_operand" "roiF,riF")))
7232 (clobber (reg:CC FLAGS_REG))]
7233 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7237 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7238 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7239 (match_operand:DI 2 "general_operand" "")))
7240 (clobber (reg:CC FLAGS_REG))]
7241 "!TARGET_64BIT && reload_completed"
7242 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7243 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7244 (parallel [(set (match_dup 3)
7245 (minus:SI (match_dup 4)
7246 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7248 (clobber (reg:CC FLAGS_REG))])]
7249 "split_di (operands+0, 1, operands+0, operands+3);
7250 split_di (operands+1, 1, operands+1, operands+4);
7251 split_di (operands+2, 1, operands+2, operands+5);")
7253 (define_insn "subdi3_carry_rex64"
7254 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7255 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7256 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7257 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7258 (clobber (reg:CC FLAGS_REG))]
7259 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7260 "sbb{q}\t{%2, %0|%0, %2}"
7261 [(set_attr "type" "alu")
7262 (set_attr "pent_pair" "pu")
7263 (set_attr "mode" "DI")])
7265 (define_insn "*subdi_1_rex64"
7266 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7267 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7268 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7269 (clobber (reg:CC FLAGS_REG))]
7270 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7271 "sub{q}\t{%2, %0|%0, %2}"
7272 [(set_attr "type" "alu")
7273 (set_attr "mode" "DI")])
7275 (define_insn "*subdi_2_rex64"
7276 [(set (reg FLAGS_REG)
7278 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7279 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7281 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7282 (minus:DI (match_dup 1) (match_dup 2)))]
7283 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7284 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7285 "sub{q}\t{%2, %0|%0, %2}"
7286 [(set_attr "type" "alu")
7287 (set_attr "mode" "DI")])
7289 (define_insn "*subdi_3_rex63"
7290 [(set (reg FLAGS_REG)
7291 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7292 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7293 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7294 (minus:DI (match_dup 1) (match_dup 2)))]
7295 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7296 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7297 "sub{q}\t{%2, %0|%0, %2}"
7298 [(set_attr "type" "alu")
7299 (set_attr "mode" "DI")])
7301 (define_insn "subqi3_carry"
7302 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7303 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7304 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7305 (match_operand:QI 2 "general_operand" "qi,qm"))))
7306 (clobber (reg:CC FLAGS_REG))]
7307 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7308 "sbb{b}\t{%2, %0|%0, %2}"
7309 [(set_attr "type" "alu")
7310 (set_attr "pent_pair" "pu")
7311 (set_attr "mode" "QI")])
7313 (define_insn "subhi3_carry"
7314 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7315 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7316 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7317 (match_operand:HI 2 "general_operand" "ri,rm"))))
7318 (clobber (reg:CC FLAGS_REG))]
7319 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7320 "sbb{w}\t{%2, %0|%0, %2}"
7321 [(set_attr "type" "alu")
7322 (set_attr "pent_pair" "pu")
7323 (set_attr "mode" "HI")])
7325 (define_insn "subsi3_carry"
7326 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7327 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7328 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7329 (match_operand:SI 2 "general_operand" "ri,rm"))))
7330 (clobber (reg:CC FLAGS_REG))]
7331 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7332 "sbb{l}\t{%2, %0|%0, %2}"
7333 [(set_attr "type" "alu")
7334 (set_attr "pent_pair" "pu")
7335 (set_attr "mode" "SI")])
7337 (define_insn "subsi3_carry_zext"
7338 [(set (match_operand:DI 0 "register_operand" "=r")
7340 (minus:SI (match_operand:SI 1 "register_operand" "0")
7341 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7342 (match_operand:SI 2 "general_operand" "g")))))
7343 (clobber (reg:CC FLAGS_REG))]
7344 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7345 "sbb{l}\t{%2, %k0|%k0, %2}"
7346 [(set_attr "type" "alu")
7347 (set_attr "pent_pair" "pu")
7348 (set_attr "mode" "SI")])
7350 (define_expand "subsi3"
7351 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7352 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7353 (match_operand:SI 2 "general_operand" "")))
7354 (clobber (reg:CC FLAGS_REG))])]
7356 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7358 (define_insn "*subsi_1"
7359 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7360 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7361 (match_operand:SI 2 "general_operand" "ri,rm")))
7362 (clobber (reg:CC FLAGS_REG))]
7363 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7364 "sub{l}\t{%2, %0|%0, %2}"
7365 [(set_attr "type" "alu")
7366 (set_attr "mode" "SI")])
7368 (define_insn "*subsi_1_zext"
7369 [(set (match_operand:DI 0 "register_operand" "=r")
7371 (minus:SI (match_operand:SI 1 "register_operand" "0")
7372 (match_operand:SI 2 "general_operand" "g"))))
7373 (clobber (reg:CC FLAGS_REG))]
7374 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7375 "sub{l}\t{%2, %k0|%k0, %2}"
7376 [(set_attr "type" "alu")
7377 (set_attr "mode" "SI")])
7379 (define_insn "*subsi_2"
7380 [(set (reg FLAGS_REG)
7382 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7383 (match_operand:SI 2 "general_operand" "ri,rm"))
7385 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7386 (minus:SI (match_dup 1) (match_dup 2)))]
7387 "ix86_match_ccmode (insn, CCGOCmode)
7388 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7389 "sub{l}\t{%2, %0|%0, %2}"
7390 [(set_attr "type" "alu")
7391 (set_attr "mode" "SI")])
7393 (define_insn "*subsi_2_zext"
7394 [(set (reg FLAGS_REG)
7396 (minus:SI (match_operand:SI 1 "register_operand" "0")
7397 (match_operand:SI 2 "general_operand" "g"))
7399 (set (match_operand:DI 0 "register_operand" "=r")
7401 (minus:SI (match_dup 1)
7403 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7404 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7405 "sub{l}\t{%2, %k0|%k0, %2}"
7406 [(set_attr "type" "alu")
7407 (set_attr "mode" "SI")])
7409 (define_insn "*subsi_3"
7410 [(set (reg FLAGS_REG)
7411 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7412 (match_operand:SI 2 "general_operand" "ri,rm")))
7413 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7414 (minus:SI (match_dup 1) (match_dup 2)))]
7415 "ix86_match_ccmode (insn, CCmode)
7416 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7417 "sub{l}\t{%2, %0|%0, %2}"
7418 [(set_attr "type" "alu")
7419 (set_attr "mode" "SI")])
7421 (define_insn "*subsi_3_zext"
7422 [(set (reg FLAGS_REG)
7423 (compare (match_operand:SI 1 "register_operand" "0")
7424 (match_operand:SI 2 "general_operand" "g")))
7425 (set (match_operand:DI 0 "register_operand" "=r")
7427 (minus:SI (match_dup 1)
7429 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7430 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7431 "sub{l}\t{%2, %1|%1, %2}"
7432 [(set_attr "type" "alu")
7433 (set_attr "mode" "DI")])
7435 (define_expand "subhi3"
7436 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7437 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7438 (match_operand:HI 2 "general_operand" "")))
7439 (clobber (reg:CC FLAGS_REG))])]
7440 "TARGET_HIMODE_MATH"
7441 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7443 (define_insn "*subhi_1"
7444 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7445 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7446 (match_operand:HI 2 "general_operand" "ri,rm")))
7447 (clobber (reg:CC FLAGS_REG))]
7448 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7449 "sub{w}\t{%2, %0|%0, %2}"
7450 [(set_attr "type" "alu")
7451 (set_attr "mode" "HI")])
7453 (define_insn "*subhi_2"
7454 [(set (reg FLAGS_REG)
7456 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7457 (match_operand:HI 2 "general_operand" "ri,rm"))
7459 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7460 (minus:HI (match_dup 1) (match_dup 2)))]
7461 "ix86_match_ccmode (insn, CCGOCmode)
7462 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7463 "sub{w}\t{%2, %0|%0, %2}"
7464 [(set_attr "type" "alu")
7465 (set_attr "mode" "HI")])
7467 (define_insn "*subhi_3"
7468 [(set (reg FLAGS_REG)
7469 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7470 (match_operand:HI 2 "general_operand" "ri,rm")))
7471 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7472 (minus:HI (match_dup 1) (match_dup 2)))]
7473 "ix86_match_ccmode (insn, CCmode)
7474 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7475 "sub{w}\t{%2, %0|%0, %2}"
7476 [(set_attr "type" "alu")
7477 (set_attr "mode" "HI")])
7479 (define_expand "subqi3"
7480 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7481 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7482 (match_operand:QI 2 "general_operand" "")))
7483 (clobber (reg:CC FLAGS_REG))])]
7484 "TARGET_QIMODE_MATH"
7485 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7487 (define_insn "*subqi_1"
7488 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7489 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7490 (match_operand:QI 2 "general_operand" "qn,qmn")))
7491 (clobber (reg:CC FLAGS_REG))]
7492 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7493 "sub{b}\t{%2, %0|%0, %2}"
7494 [(set_attr "type" "alu")
7495 (set_attr "mode" "QI")])
7497 (define_insn "*subqi_1_slp"
7498 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7499 (minus:QI (match_dup 0)
7500 (match_operand:QI 1 "general_operand" "qn,qmn")))
7501 (clobber (reg:CC FLAGS_REG))]
7502 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7503 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7504 "sub{b}\t{%1, %0|%0, %1}"
7505 [(set_attr "type" "alu1")
7506 (set_attr "mode" "QI")])
7508 (define_insn "*subqi_2"
7509 [(set (reg FLAGS_REG)
7511 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7512 (match_operand:QI 2 "general_operand" "qi,qm"))
7514 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7515 (minus:HI (match_dup 1) (match_dup 2)))]
7516 "ix86_match_ccmode (insn, CCGOCmode)
7517 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7518 "sub{b}\t{%2, %0|%0, %2}"
7519 [(set_attr "type" "alu")
7520 (set_attr "mode" "QI")])
7522 (define_insn "*subqi_3"
7523 [(set (reg FLAGS_REG)
7524 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7525 (match_operand:QI 2 "general_operand" "qi,qm")))
7526 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7527 (minus:HI (match_dup 1) (match_dup 2)))]
7528 "ix86_match_ccmode (insn, CCmode)
7529 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7530 "sub{b}\t{%2, %0|%0, %2}"
7531 [(set_attr "type" "alu")
7532 (set_attr "mode" "QI")])
7534 ;; The patterns that match these are at the end of this file.
7536 (define_expand "subxf3"
7537 [(set (match_operand:XF 0 "register_operand" "")
7538 (minus:XF (match_operand:XF 1 "register_operand" "")
7539 (match_operand:XF 2 "register_operand" "")))]
7543 (define_expand "sub<mode>3"
7544 [(set (match_operand:MODEF 0 "register_operand" "")
7545 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7546 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7547 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7550 ;; Multiply instructions
7552 (define_expand "muldi3"
7553 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7554 (mult:DI (match_operand:DI 1 "register_operand" "")
7555 (match_operand:DI 2 "x86_64_general_operand" "")))
7556 (clobber (reg:CC FLAGS_REG))])]
7561 ;; IMUL reg64, reg64, imm8 Direct
7562 ;; IMUL reg64, mem64, imm8 VectorPath
7563 ;; IMUL reg64, reg64, imm32 Direct
7564 ;; IMUL reg64, mem64, imm32 VectorPath
7565 ;; IMUL reg64, reg64 Direct
7566 ;; IMUL reg64, mem64 Direct
7568 (define_insn "*muldi3_1_rex64"
7569 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7570 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7571 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7572 (clobber (reg:CC FLAGS_REG))]
7574 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7576 imul{q}\t{%2, %1, %0|%0, %1, %2}
7577 imul{q}\t{%2, %1, %0|%0, %1, %2}
7578 imul{q}\t{%2, %0|%0, %2}"
7579 [(set_attr "type" "imul")
7580 (set_attr "prefix_0f" "0,0,1")
7581 (set (attr "athlon_decode")
7582 (cond [(eq_attr "cpu" "athlon")
7583 (const_string "vector")
7584 (eq_attr "alternative" "1")
7585 (const_string "vector")
7586 (and (eq_attr "alternative" "2")
7587 (match_operand 1 "memory_operand" ""))
7588 (const_string "vector")]
7589 (const_string "direct")))
7590 (set (attr "amdfam10_decode")
7591 (cond [(and (eq_attr "alternative" "0,1")
7592 (match_operand 1 "memory_operand" ""))
7593 (const_string "vector")]
7594 (const_string "direct")))
7595 (set_attr "mode" "DI")])
7597 (define_expand "mulsi3"
7598 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7599 (mult:SI (match_operand:SI 1 "register_operand" "")
7600 (match_operand:SI 2 "general_operand" "")))
7601 (clobber (reg:CC FLAGS_REG))])]
7606 ;; IMUL reg32, reg32, imm8 Direct
7607 ;; IMUL reg32, mem32, imm8 VectorPath
7608 ;; IMUL reg32, reg32, imm32 Direct
7609 ;; IMUL reg32, mem32, imm32 VectorPath
7610 ;; IMUL reg32, reg32 Direct
7611 ;; IMUL reg32, mem32 Direct
7613 (define_insn "*mulsi3_1"
7614 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7615 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7616 (match_operand:SI 2 "general_operand" "K,i,mr")))
7617 (clobber (reg:CC FLAGS_REG))]
7618 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7620 imul{l}\t{%2, %1, %0|%0, %1, %2}
7621 imul{l}\t{%2, %1, %0|%0, %1, %2}
7622 imul{l}\t{%2, %0|%0, %2}"
7623 [(set_attr "type" "imul")
7624 (set_attr "prefix_0f" "0,0,1")
7625 (set (attr "athlon_decode")
7626 (cond [(eq_attr "cpu" "athlon")
7627 (const_string "vector")
7628 (eq_attr "alternative" "1")
7629 (const_string "vector")
7630 (and (eq_attr "alternative" "2")
7631 (match_operand 1 "memory_operand" ""))
7632 (const_string "vector")]
7633 (const_string "direct")))
7634 (set (attr "amdfam10_decode")
7635 (cond [(and (eq_attr "alternative" "0,1")
7636 (match_operand 1 "memory_operand" ""))
7637 (const_string "vector")]
7638 (const_string "direct")))
7639 (set_attr "mode" "SI")])
7641 (define_insn "*mulsi3_1_zext"
7642 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7644 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7645 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7646 (clobber (reg:CC FLAGS_REG))]
7648 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7650 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7651 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7652 imul{l}\t{%2, %k0|%k0, %2}"
7653 [(set_attr "type" "imul")
7654 (set_attr "prefix_0f" "0,0,1")
7655 (set (attr "athlon_decode")
7656 (cond [(eq_attr "cpu" "athlon")
7657 (const_string "vector")
7658 (eq_attr "alternative" "1")
7659 (const_string "vector")
7660 (and (eq_attr "alternative" "2")
7661 (match_operand 1 "memory_operand" ""))
7662 (const_string "vector")]
7663 (const_string "direct")))
7664 (set (attr "amdfam10_decode")
7665 (cond [(and (eq_attr "alternative" "0,1")
7666 (match_operand 1 "memory_operand" ""))
7667 (const_string "vector")]
7668 (const_string "direct")))
7669 (set_attr "mode" "SI")])
7671 (define_expand "mulhi3"
7672 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7673 (mult:HI (match_operand:HI 1 "register_operand" "")
7674 (match_operand:HI 2 "general_operand" "")))
7675 (clobber (reg:CC FLAGS_REG))])]
7676 "TARGET_HIMODE_MATH"
7680 ;; IMUL reg16, reg16, imm8 VectorPath
7681 ;; IMUL reg16, mem16, imm8 VectorPath
7682 ;; IMUL reg16, reg16, imm16 VectorPath
7683 ;; IMUL reg16, mem16, imm16 VectorPath
7684 ;; IMUL reg16, reg16 Direct
7685 ;; IMUL reg16, mem16 Direct
7686 (define_insn "*mulhi3_1"
7687 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7688 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7689 (match_operand:HI 2 "general_operand" "K,i,mr")))
7690 (clobber (reg:CC FLAGS_REG))]
7691 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7693 imul{w}\t{%2, %1, %0|%0, %1, %2}
7694 imul{w}\t{%2, %1, %0|%0, %1, %2}
7695 imul{w}\t{%2, %0|%0, %2}"
7696 [(set_attr "type" "imul")
7697 (set_attr "prefix_0f" "0,0,1")
7698 (set (attr "athlon_decode")
7699 (cond [(eq_attr "cpu" "athlon")
7700 (const_string "vector")
7701 (eq_attr "alternative" "1,2")
7702 (const_string "vector")]
7703 (const_string "direct")))
7704 (set (attr "amdfam10_decode")
7705 (cond [(eq_attr "alternative" "0,1")
7706 (const_string "vector")]
7707 (const_string "direct")))
7708 (set_attr "mode" "HI")])
7710 (define_expand "mulqi3"
7711 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7712 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7713 (match_operand:QI 2 "register_operand" "")))
7714 (clobber (reg:CC FLAGS_REG))])]
7715 "TARGET_QIMODE_MATH"
7722 (define_insn "*mulqi3_1"
7723 [(set (match_operand:QI 0 "register_operand" "=a")
7724 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7725 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7726 (clobber (reg:CC FLAGS_REG))]
7728 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7730 [(set_attr "type" "imul")
7731 (set_attr "length_immediate" "0")
7732 (set (attr "athlon_decode")
7733 (if_then_else (eq_attr "cpu" "athlon")
7734 (const_string "vector")
7735 (const_string "direct")))
7736 (set_attr "amdfam10_decode" "direct")
7737 (set_attr "mode" "QI")])
7739 (define_expand "umulqihi3"
7740 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7741 (mult:HI (zero_extend:HI
7742 (match_operand:QI 1 "nonimmediate_operand" ""))
7744 (match_operand:QI 2 "register_operand" ""))))
7745 (clobber (reg:CC FLAGS_REG))])]
7746 "TARGET_QIMODE_MATH"
7749 (define_insn "*umulqihi3_1"
7750 [(set (match_operand:HI 0 "register_operand" "=a")
7751 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7752 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7753 (clobber (reg:CC FLAGS_REG))]
7755 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7757 [(set_attr "type" "imul")
7758 (set_attr "length_immediate" "0")
7759 (set (attr "athlon_decode")
7760 (if_then_else (eq_attr "cpu" "athlon")
7761 (const_string "vector")
7762 (const_string "direct")))
7763 (set_attr "amdfam10_decode" "direct")
7764 (set_attr "mode" "QI")])
7766 (define_expand "mulqihi3"
7767 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7768 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7769 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7770 (clobber (reg:CC FLAGS_REG))])]
7771 "TARGET_QIMODE_MATH"
7774 (define_insn "*mulqihi3_insn"
7775 [(set (match_operand:HI 0 "register_operand" "=a")
7776 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7777 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7778 (clobber (reg:CC FLAGS_REG))]
7780 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7782 [(set_attr "type" "imul")
7783 (set_attr "length_immediate" "0")
7784 (set (attr "athlon_decode")
7785 (if_then_else (eq_attr "cpu" "athlon")
7786 (const_string "vector")
7787 (const_string "direct")))
7788 (set_attr "amdfam10_decode" "direct")
7789 (set_attr "mode" "QI")])
7791 (define_expand "umulditi3"
7792 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7793 (mult:TI (zero_extend:TI
7794 (match_operand:DI 1 "nonimmediate_operand" ""))
7796 (match_operand:DI 2 "register_operand" ""))))
7797 (clobber (reg:CC FLAGS_REG))])]
7801 (define_insn "*umulditi3_insn"
7802 [(set (match_operand:TI 0 "register_operand" "=A")
7803 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7804 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7805 (clobber (reg:CC FLAGS_REG))]
7807 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7809 [(set_attr "type" "imul")
7810 (set_attr "length_immediate" "0")
7811 (set (attr "athlon_decode")
7812 (if_then_else (eq_attr "cpu" "athlon")
7813 (const_string "vector")
7814 (const_string "double")))
7815 (set_attr "amdfam10_decode" "double")
7816 (set_attr "mode" "DI")])
7818 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7819 (define_expand "umulsidi3"
7820 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7821 (mult:DI (zero_extend:DI
7822 (match_operand:SI 1 "nonimmediate_operand" ""))
7824 (match_operand:SI 2 "register_operand" ""))))
7825 (clobber (reg:CC FLAGS_REG))])]
7829 (define_insn "*umulsidi3_insn"
7830 [(set (match_operand:DI 0 "register_operand" "=A")
7831 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7832 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7833 (clobber (reg:CC FLAGS_REG))]
7835 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7837 [(set_attr "type" "imul")
7838 (set_attr "length_immediate" "0")
7839 (set (attr "athlon_decode")
7840 (if_then_else (eq_attr "cpu" "athlon")
7841 (const_string "vector")
7842 (const_string "double")))
7843 (set_attr "amdfam10_decode" "double")
7844 (set_attr "mode" "SI")])
7846 (define_expand "mulditi3"
7847 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7848 (mult:TI (sign_extend:TI
7849 (match_operand:DI 1 "nonimmediate_operand" ""))
7851 (match_operand:DI 2 "register_operand" ""))))
7852 (clobber (reg:CC FLAGS_REG))])]
7856 (define_insn "*mulditi3_insn"
7857 [(set (match_operand:TI 0 "register_operand" "=A")
7858 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7859 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7860 (clobber (reg:CC FLAGS_REG))]
7862 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7864 [(set_attr "type" "imul")
7865 (set_attr "length_immediate" "0")
7866 (set (attr "athlon_decode")
7867 (if_then_else (eq_attr "cpu" "athlon")
7868 (const_string "vector")
7869 (const_string "double")))
7870 (set_attr "amdfam10_decode" "double")
7871 (set_attr "mode" "DI")])
7873 (define_expand "mulsidi3"
7874 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7875 (mult:DI (sign_extend:DI
7876 (match_operand:SI 1 "nonimmediate_operand" ""))
7878 (match_operand:SI 2 "register_operand" ""))))
7879 (clobber (reg:CC FLAGS_REG))])]
7883 (define_insn "*mulsidi3_insn"
7884 [(set (match_operand:DI 0 "register_operand" "=A")
7885 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7886 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7887 (clobber (reg:CC FLAGS_REG))]
7889 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7891 [(set_attr "type" "imul")
7892 (set_attr "length_immediate" "0")
7893 (set (attr "athlon_decode")
7894 (if_then_else (eq_attr "cpu" "athlon")
7895 (const_string "vector")
7896 (const_string "double")))
7897 (set_attr "amdfam10_decode" "double")
7898 (set_attr "mode" "SI")])
7900 (define_expand "umuldi3_highpart"
7901 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7904 (mult:TI (zero_extend:TI
7905 (match_operand:DI 1 "nonimmediate_operand" ""))
7907 (match_operand:DI 2 "register_operand" "")))
7909 (clobber (match_scratch:DI 3 ""))
7910 (clobber (reg:CC FLAGS_REG))])]
7914 (define_insn "*umuldi3_highpart_rex64"
7915 [(set (match_operand:DI 0 "register_operand" "=d")
7918 (mult:TI (zero_extend:TI
7919 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7921 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7923 (clobber (match_scratch:DI 3 "=1"))
7924 (clobber (reg:CC FLAGS_REG))]
7926 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7928 [(set_attr "type" "imul")
7929 (set_attr "length_immediate" "0")
7930 (set (attr "athlon_decode")
7931 (if_then_else (eq_attr "cpu" "athlon")
7932 (const_string "vector")
7933 (const_string "double")))
7934 (set_attr "amdfam10_decode" "double")
7935 (set_attr "mode" "DI")])
7937 (define_expand "umulsi3_highpart"
7938 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7941 (mult:DI (zero_extend:DI
7942 (match_operand:SI 1 "nonimmediate_operand" ""))
7944 (match_operand:SI 2 "register_operand" "")))
7946 (clobber (match_scratch:SI 3 ""))
7947 (clobber (reg:CC FLAGS_REG))])]
7951 (define_insn "*umulsi3_highpart_insn"
7952 [(set (match_operand:SI 0 "register_operand" "=d")
7955 (mult:DI (zero_extend:DI
7956 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7958 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7960 (clobber (match_scratch:SI 3 "=1"))
7961 (clobber (reg:CC FLAGS_REG))]
7962 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7964 [(set_attr "type" "imul")
7965 (set_attr "length_immediate" "0")
7966 (set (attr "athlon_decode")
7967 (if_then_else (eq_attr "cpu" "athlon")
7968 (const_string "vector")
7969 (const_string "double")))
7970 (set_attr "amdfam10_decode" "double")
7971 (set_attr "mode" "SI")])
7973 (define_insn "*umulsi3_highpart_zext"
7974 [(set (match_operand:DI 0 "register_operand" "=d")
7975 (zero_extend:DI (truncate:SI
7977 (mult:DI (zero_extend:DI
7978 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7980 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7982 (clobber (match_scratch:SI 3 "=1"))
7983 (clobber (reg:CC FLAGS_REG))]
7985 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7987 [(set_attr "type" "imul")
7988 (set_attr "length_immediate" "0")
7989 (set (attr "athlon_decode")
7990 (if_then_else (eq_attr "cpu" "athlon")
7991 (const_string "vector")
7992 (const_string "double")))
7993 (set_attr "amdfam10_decode" "double")
7994 (set_attr "mode" "SI")])
7996 (define_expand "smuldi3_highpart"
7997 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8000 (mult:TI (sign_extend:TI
8001 (match_operand:DI 1 "nonimmediate_operand" ""))
8003 (match_operand:DI 2 "register_operand" "")))
8005 (clobber (match_scratch:DI 3 ""))
8006 (clobber (reg:CC FLAGS_REG))])]
8010 (define_insn "*smuldi3_highpart_rex64"
8011 [(set (match_operand:DI 0 "register_operand" "=d")
8014 (mult:TI (sign_extend:TI
8015 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8017 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8019 (clobber (match_scratch:DI 3 "=1"))
8020 (clobber (reg:CC FLAGS_REG))]
8022 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8024 [(set_attr "type" "imul")
8025 (set (attr "athlon_decode")
8026 (if_then_else (eq_attr "cpu" "athlon")
8027 (const_string "vector")
8028 (const_string "double")))
8029 (set_attr "amdfam10_decode" "double")
8030 (set_attr "mode" "DI")])
8032 (define_expand "smulsi3_highpart"
8033 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8036 (mult:DI (sign_extend:DI
8037 (match_operand:SI 1 "nonimmediate_operand" ""))
8039 (match_operand:SI 2 "register_operand" "")))
8041 (clobber (match_scratch:SI 3 ""))
8042 (clobber (reg:CC FLAGS_REG))])]
8046 (define_insn "*smulsi3_highpart_insn"
8047 [(set (match_operand:SI 0 "register_operand" "=d")
8050 (mult:DI (sign_extend:DI
8051 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8053 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8055 (clobber (match_scratch:SI 3 "=1"))
8056 (clobber (reg:CC FLAGS_REG))]
8057 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8059 [(set_attr "type" "imul")
8060 (set (attr "athlon_decode")
8061 (if_then_else (eq_attr "cpu" "athlon")
8062 (const_string "vector")
8063 (const_string "double")))
8064 (set_attr "amdfam10_decode" "double")
8065 (set_attr "mode" "SI")])
8067 (define_insn "*smulsi3_highpart_zext"
8068 [(set (match_operand:DI 0 "register_operand" "=d")
8069 (zero_extend:DI (truncate:SI
8071 (mult:DI (sign_extend:DI
8072 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8074 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8076 (clobber (match_scratch:SI 3 "=1"))
8077 (clobber (reg:CC FLAGS_REG))]
8079 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8081 [(set_attr "type" "imul")
8082 (set (attr "athlon_decode")
8083 (if_then_else (eq_attr "cpu" "athlon")
8084 (const_string "vector")
8085 (const_string "double")))
8086 (set_attr "amdfam10_decode" "double")
8087 (set_attr "mode" "SI")])
8089 ;; The patterns that match these are at the end of this file.
8091 (define_expand "mulxf3"
8092 [(set (match_operand:XF 0 "register_operand" "")
8093 (mult:XF (match_operand:XF 1 "register_operand" "")
8094 (match_operand:XF 2 "register_operand" "")))]
8098 (define_expand "mul<mode>3"
8099 [(set (match_operand:MODEF 0 "register_operand" "")
8100 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8101 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8102 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8105 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8108 ;; Divide instructions
8110 (define_insn "divqi3"
8111 [(set (match_operand:QI 0 "register_operand" "=a")
8112 (div:QI (match_operand:HI 1 "register_operand" "0")
8113 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8114 (clobber (reg:CC FLAGS_REG))]
8115 "TARGET_QIMODE_MATH"
8117 [(set_attr "type" "idiv")
8118 (set_attr "mode" "QI")])
8120 (define_insn "udivqi3"
8121 [(set (match_operand:QI 0 "register_operand" "=a")
8122 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8123 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8124 (clobber (reg:CC FLAGS_REG))]
8125 "TARGET_QIMODE_MATH"
8127 [(set_attr "type" "idiv")
8128 (set_attr "mode" "QI")])
8130 ;; The patterns that match these are at the end of this file.
8132 (define_expand "divxf3"
8133 [(set (match_operand:XF 0 "register_operand" "")
8134 (div:XF (match_operand:XF 1 "register_operand" "")
8135 (match_operand:XF 2 "register_operand" "")))]
8139 (define_expand "divdf3"
8140 [(set (match_operand:DF 0 "register_operand" "")
8141 (div:DF (match_operand:DF 1 "register_operand" "")
8142 (match_operand:DF 2 "nonimmediate_operand" "")))]
8143 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8146 (define_expand "divsf3"
8147 [(set (match_operand:SF 0 "register_operand" "")
8148 (div:SF (match_operand:SF 1 "register_operand" "")
8149 (match_operand:SF 2 "nonimmediate_operand" "")))]
8150 "TARGET_80387 || TARGET_SSE_MATH"
8152 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8153 && flag_finite_math_only && !flag_trapping_math
8154 && flag_unsafe_math_optimizations)
8156 ix86_emit_swdivsf (operands[0], operands[1],
8157 operands[2], SFmode);
8162 ;; Remainder instructions.
8164 (define_expand "divmoddi4"
8165 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8166 (div:DI (match_operand:DI 1 "register_operand" "")
8167 (match_operand:DI 2 "nonimmediate_operand" "")))
8168 (set (match_operand:DI 3 "register_operand" "")
8169 (mod:DI (match_dup 1) (match_dup 2)))
8170 (clobber (reg:CC FLAGS_REG))])]
8174 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8175 ;; Penalize eax case slightly because it results in worse scheduling
8177 (define_insn "*divmoddi4_nocltd_rex64"
8178 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8179 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8180 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8181 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8182 (mod:DI (match_dup 2) (match_dup 3)))
8183 (clobber (reg:CC FLAGS_REG))]
8184 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8186 [(set_attr "type" "multi")])
8188 (define_insn "*divmoddi4_cltd_rex64"
8189 [(set (match_operand:DI 0 "register_operand" "=a")
8190 (div:DI (match_operand:DI 2 "register_operand" "a")
8191 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8192 (set (match_operand:DI 1 "register_operand" "=&d")
8193 (mod:DI (match_dup 2) (match_dup 3)))
8194 (clobber (reg:CC FLAGS_REG))]
8195 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8197 [(set_attr "type" "multi")])
8199 (define_insn "*divmoddi_noext_rex64"
8200 [(set (match_operand:DI 0 "register_operand" "=a")
8201 (div:DI (match_operand:DI 1 "register_operand" "0")
8202 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8203 (set (match_operand:DI 3 "register_operand" "=d")
8204 (mod:DI (match_dup 1) (match_dup 2)))
8205 (use (match_operand:DI 4 "register_operand" "3"))
8206 (clobber (reg:CC FLAGS_REG))]
8209 [(set_attr "type" "idiv")
8210 (set_attr "mode" "DI")])
8213 [(set (match_operand:DI 0 "register_operand" "")
8214 (div:DI (match_operand:DI 1 "register_operand" "")
8215 (match_operand:DI 2 "nonimmediate_operand" "")))
8216 (set (match_operand:DI 3 "register_operand" "")
8217 (mod:DI (match_dup 1) (match_dup 2)))
8218 (clobber (reg:CC FLAGS_REG))]
8219 "TARGET_64BIT && reload_completed"
8220 [(parallel [(set (match_dup 3)
8221 (ashiftrt:DI (match_dup 4) (const_int 63)))
8222 (clobber (reg:CC FLAGS_REG))])
8223 (parallel [(set (match_dup 0)
8224 (div:DI (reg:DI 0) (match_dup 2)))
8226 (mod:DI (reg:DI 0) (match_dup 2)))
8228 (clobber (reg:CC FLAGS_REG))])]
8230 /* Avoid use of cltd in favor of a mov+shift. */
8231 if (!TARGET_USE_CLTD && !optimize_size)
8233 if (true_regnum (operands[1]))
8234 emit_move_insn (operands[0], operands[1]);
8236 emit_move_insn (operands[3], operands[1]);
8237 operands[4] = operands[3];
8241 gcc_assert (!true_regnum (operands[1]));
8242 operands[4] = operands[1];
8247 (define_expand "divmodsi4"
8248 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8249 (div:SI (match_operand:SI 1 "register_operand" "")
8250 (match_operand:SI 2 "nonimmediate_operand" "")))
8251 (set (match_operand:SI 3 "register_operand" "")
8252 (mod:SI (match_dup 1) (match_dup 2)))
8253 (clobber (reg:CC FLAGS_REG))])]
8257 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8258 ;; Penalize eax case slightly because it results in worse scheduling
8260 (define_insn "*divmodsi4_nocltd"
8261 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8262 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8263 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8264 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8265 (mod:SI (match_dup 2) (match_dup 3)))
8266 (clobber (reg:CC FLAGS_REG))]
8267 "!optimize_size && !TARGET_USE_CLTD"
8269 [(set_attr "type" "multi")])
8271 (define_insn "*divmodsi4_cltd"
8272 [(set (match_operand:SI 0 "register_operand" "=a")
8273 (div:SI (match_operand:SI 2 "register_operand" "a")
8274 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8275 (set (match_operand:SI 1 "register_operand" "=&d")
8276 (mod:SI (match_dup 2) (match_dup 3)))
8277 (clobber (reg:CC FLAGS_REG))]
8278 "optimize_size || TARGET_USE_CLTD"
8280 [(set_attr "type" "multi")])
8282 (define_insn "*divmodsi_noext"
8283 [(set (match_operand:SI 0 "register_operand" "=a")
8284 (div:SI (match_operand:SI 1 "register_operand" "0")
8285 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8286 (set (match_operand:SI 3 "register_operand" "=d")
8287 (mod:SI (match_dup 1) (match_dup 2)))
8288 (use (match_operand:SI 4 "register_operand" "3"))
8289 (clobber (reg:CC FLAGS_REG))]
8292 [(set_attr "type" "idiv")
8293 (set_attr "mode" "SI")])
8296 [(set (match_operand:SI 0 "register_operand" "")
8297 (div:SI (match_operand:SI 1 "register_operand" "")
8298 (match_operand:SI 2 "nonimmediate_operand" "")))
8299 (set (match_operand:SI 3 "register_operand" "")
8300 (mod:SI (match_dup 1) (match_dup 2)))
8301 (clobber (reg:CC FLAGS_REG))]
8303 [(parallel [(set (match_dup 3)
8304 (ashiftrt:SI (match_dup 4) (const_int 31)))
8305 (clobber (reg:CC FLAGS_REG))])
8306 (parallel [(set (match_dup 0)
8307 (div:SI (reg:SI 0) (match_dup 2)))
8309 (mod:SI (reg:SI 0) (match_dup 2)))
8311 (clobber (reg:CC FLAGS_REG))])]
8313 /* Avoid use of cltd in favor of a mov+shift. */
8314 if (!TARGET_USE_CLTD && !optimize_size)
8316 if (true_regnum (operands[1]))
8317 emit_move_insn (operands[0], operands[1]);
8319 emit_move_insn (operands[3], operands[1]);
8320 operands[4] = operands[3];
8324 gcc_assert (!true_regnum (operands[1]));
8325 operands[4] = operands[1];
8329 (define_insn "divmodhi4"
8330 [(set (match_operand:HI 0 "register_operand" "=a")
8331 (div:HI (match_operand:HI 1 "register_operand" "0")
8332 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8333 (set (match_operand:HI 3 "register_operand" "=&d")
8334 (mod:HI (match_dup 1) (match_dup 2)))
8335 (clobber (reg:CC FLAGS_REG))]
8336 "TARGET_HIMODE_MATH"
8338 [(set_attr "type" "multi")
8339 (set_attr "length_immediate" "0")
8340 (set_attr "mode" "SI")])
8342 (define_insn "udivmoddi4"
8343 [(set (match_operand:DI 0 "register_operand" "=a")
8344 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8345 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8346 (set (match_operand:DI 3 "register_operand" "=&d")
8347 (umod:DI (match_dup 1) (match_dup 2)))
8348 (clobber (reg:CC FLAGS_REG))]
8350 "xor{q}\t%3, %3\;div{q}\t%2"
8351 [(set_attr "type" "multi")
8352 (set_attr "length_immediate" "0")
8353 (set_attr "mode" "DI")])
8355 (define_insn "*udivmoddi4_noext"
8356 [(set (match_operand:DI 0 "register_operand" "=a")
8357 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8358 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8359 (set (match_operand:DI 3 "register_operand" "=d")
8360 (umod:DI (match_dup 1) (match_dup 2)))
8362 (clobber (reg:CC FLAGS_REG))]
8365 [(set_attr "type" "idiv")
8366 (set_attr "mode" "DI")])
8369 [(set (match_operand:DI 0 "register_operand" "")
8370 (udiv:DI (match_operand:DI 1 "register_operand" "")
8371 (match_operand:DI 2 "nonimmediate_operand" "")))
8372 (set (match_operand:DI 3 "register_operand" "")
8373 (umod:DI (match_dup 1) (match_dup 2)))
8374 (clobber (reg:CC FLAGS_REG))]
8375 "TARGET_64BIT && reload_completed"
8376 [(set (match_dup 3) (const_int 0))
8377 (parallel [(set (match_dup 0)
8378 (udiv:DI (match_dup 1) (match_dup 2)))
8380 (umod:DI (match_dup 1) (match_dup 2)))
8382 (clobber (reg:CC FLAGS_REG))])]
8385 (define_insn "udivmodsi4"
8386 [(set (match_operand:SI 0 "register_operand" "=a")
8387 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8388 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8389 (set (match_operand:SI 3 "register_operand" "=&d")
8390 (umod:SI (match_dup 1) (match_dup 2)))
8391 (clobber (reg:CC FLAGS_REG))]
8393 "xor{l}\t%3, %3\;div{l}\t%2"
8394 [(set_attr "type" "multi")
8395 (set_attr "length_immediate" "0")
8396 (set_attr "mode" "SI")])
8398 (define_insn "*udivmodsi4_noext"
8399 [(set (match_operand:SI 0 "register_operand" "=a")
8400 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8401 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8402 (set (match_operand:SI 3 "register_operand" "=d")
8403 (umod:SI (match_dup 1) (match_dup 2)))
8405 (clobber (reg:CC FLAGS_REG))]
8408 [(set_attr "type" "idiv")
8409 (set_attr "mode" "SI")])
8412 [(set (match_operand:SI 0 "register_operand" "")
8413 (udiv:SI (match_operand:SI 1 "register_operand" "")
8414 (match_operand:SI 2 "nonimmediate_operand" "")))
8415 (set (match_operand:SI 3 "register_operand" "")
8416 (umod:SI (match_dup 1) (match_dup 2)))
8417 (clobber (reg:CC FLAGS_REG))]
8419 [(set (match_dup 3) (const_int 0))
8420 (parallel [(set (match_dup 0)
8421 (udiv:SI (match_dup 1) (match_dup 2)))
8423 (umod:SI (match_dup 1) (match_dup 2)))
8425 (clobber (reg:CC FLAGS_REG))])]
8428 (define_expand "udivmodhi4"
8429 [(set (match_dup 4) (const_int 0))
8430 (parallel [(set (match_operand:HI 0 "register_operand" "")
8431 (udiv:HI (match_operand:HI 1 "register_operand" "")
8432 (match_operand:HI 2 "nonimmediate_operand" "")))
8433 (set (match_operand:HI 3 "register_operand" "")
8434 (umod:HI (match_dup 1) (match_dup 2)))
8436 (clobber (reg:CC FLAGS_REG))])]
8437 "TARGET_HIMODE_MATH"
8438 "operands[4] = gen_reg_rtx (HImode);")
8440 (define_insn "*udivmodhi_noext"
8441 [(set (match_operand:HI 0 "register_operand" "=a")
8442 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8443 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8444 (set (match_operand:HI 3 "register_operand" "=d")
8445 (umod:HI (match_dup 1) (match_dup 2)))
8446 (use (match_operand:HI 4 "register_operand" "3"))
8447 (clobber (reg:CC FLAGS_REG))]
8450 [(set_attr "type" "idiv")
8451 (set_attr "mode" "HI")])
8453 ;; We cannot use div/idiv for double division, because it causes
8454 ;; "division by zero" on the overflow and that's not what we expect
8455 ;; from truncate. Because true (non truncating) double division is
8456 ;; never generated, we can't create this insn anyway.
8459 ; [(set (match_operand:SI 0 "register_operand" "=a")
8461 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8463 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8464 ; (set (match_operand:SI 3 "register_operand" "=d")
8466 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8467 ; (clobber (reg:CC FLAGS_REG))]
8469 ; "div{l}\t{%2, %0|%0, %2}"
8470 ; [(set_attr "type" "idiv")])
8472 ;;- Logical AND instructions
8474 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8475 ;; Note that this excludes ah.
8477 (define_insn "*testdi_1_rex64"
8478 [(set (reg FLAGS_REG)
8480 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8481 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8483 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8484 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8486 test{l}\t{%k1, %k0|%k0, %k1}
8487 test{l}\t{%k1, %k0|%k0, %k1}
8488 test{q}\t{%1, %0|%0, %1}
8489 test{q}\t{%1, %0|%0, %1}
8490 test{q}\t{%1, %0|%0, %1}"
8491 [(set_attr "type" "test")
8492 (set_attr "modrm" "0,1,0,1,1")
8493 (set_attr "mode" "SI,SI,DI,DI,DI")
8494 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8496 (define_insn "testsi_1"
8497 [(set (reg FLAGS_REG)
8499 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8500 (match_operand:SI 1 "general_operand" "in,in,rin"))
8502 "ix86_match_ccmode (insn, CCNOmode)
8503 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8504 "test{l}\t{%1, %0|%0, %1}"
8505 [(set_attr "type" "test")
8506 (set_attr "modrm" "0,1,1")
8507 (set_attr "mode" "SI")
8508 (set_attr "pent_pair" "uv,np,uv")])
8510 (define_expand "testsi_ccno_1"
8511 [(set (reg:CCNO FLAGS_REG)
8513 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8514 (match_operand:SI 1 "nonmemory_operand" ""))
8519 (define_insn "*testhi_1"
8520 [(set (reg FLAGS_REG)
8521 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8522 (match_operand:HI 1 "general_operand" "n,n,rn"))
8524 "ix86_match_ccmode (insn, CCNOmode)
8525 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8526 "test{w}\t{%1, %0|%0, %1}"
8527 [(set_attr "type" "test")
8528 (set_attr "modrm" "0,1,1")
8529 (set_attr "mode" "HI")
8530 (set_attr "pent_pair" "uv,np,uv")])
8532 (define_expand "testqi_ccz_1"
8533 [(set (reg:CCZ FLAGS_REG)
8534 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8535 (match_operand:QI 1 "nonmemory_operand" ""))
8540 (define_insn "*testqi_1_maybe_si"
8541 [(set (reg FLAGS_REG)
8544 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8545 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8547 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8548 && ix86_match_ccmode (insn,
8549 CONST_INT_P (operands[1])
8550 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8552 if (which_alternative == 3)
8554 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8555 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8556 return "test{l}\t{%1, %k0|%k0, %1}";
8558 return "test{b}\t{%1, %0|%0, %1}";
8560 [(set_attr "type" "test")
8561 (set_attr "modrm" "0,1,1,1")
8562 (set_attr "mode" "QI,QI,QI,SI")
8563 (set_attr "pent_pair" "uv,np,uv,np")])
8565 (define_insn "*testqi_1"
8566 [(set (reg FLAGS_REG)
8569 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8570 (match_operand:QI 1 "general_operand" "n,n,qn"))
8572 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8573 && ix86_match_ccmode (insn, CCNOmode)"
8574 "test{b}\t{%1, %0|%0, %1}"
8575 [(set_attr "type" "test")
8576 (set_attr "modrm" "0,1,1")
8577 (set_attr "mode" "QI")
8578 (set_attr "pent_pair" "uv,np,uv")])
8580 (define_expand "testqi_ext_ccno_0"
8581 [(set (reg:CCNO FLAGS_REG)
8585 (match_operand 0 "ext_register_operand" "")
8588 (match_operand 1 "const_int_operand" ""))
8593 (define_insn "*testqi_ext_0"
8594 [(set (reg FLAGS_REG)
8598 (match_operand 0 "ext_register_operand" "Q")
8601 (match_operand 1 "const_int_operand" "n"))
8603 "ix86_match_ccmode (insn, CCNOmode)"
8604 "test{b}\t{%1, %h0|%h0, %1}"
8605 [(set_attr "type" "test")
8606 (set_attr "mode" "QI")
8607 (set_attr "length_immediate" "1")
8608 (set_attr "pent_pair" "np")])
8610 (define_insn "*testqi_ext_1"
8611 [(set (reg FLAGS_REG)
8615 (match_operand 0 "ext_register_operand" "Q")
8619 (match_operand:QI 1 "general_operand" "Qm")))
8621 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8622 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8623 "test{b}\t{%1, %h0|%h0, %1}"
8624 [(set_attr "type" "test")
8625 (set_attr "mode" "QI")])
8627 (define_insn "*testqi_ext_1_rex64"
8628 [(set (reg FLAGS_REG)
8632 (match_operand 0 "ext_register_operand" "Q")
8636 (match_operand:QI 1 "register_operand" "Q")))
8638 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8639 "test{b}\t{%1, %h0|%h0, %1}"
8640 [(set_attr "type" "test")
8641 (set_attr "mode" "QI")])
8643 (define_insn "*testqi_ext_2"
8644 [(set (reg FLAGS_REG)
8648 (match_operand 0 "ext_register_operand" "Q")
8652 (match_operand 1 "ext_register_operand" "Q")
8656 "ix86_match_ccmode (insn, CCNOmode)"
8657 "test{b}\t{%h1, %h0|%h0, %h1}"
8658 [(set_attr "type" "test")
8659 (set_attr "mode" "QI")])
8661 ;; Combine likes to form bit extractions for some tests. Humor it.
8662 (define_insn "*testqi_ext_3"
8663 [(set (reg FLAGS_REG)
8664 (compare (zero_extract:SI
8665 (match_operand 0 "nonimmediate_operand" "rm")
8666 (match_operand:SI 1 "const_int_operand" "")
8667 (match_operand:SI 2 "const_int_operand" ""))
8669 "ix86_match_ccmode (insn, CCNOmode)
8670 && INTVAL (operands[1]) > 0
8671 && INTVAL (operands[2]) >= 0
8672 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8673 && (GET_MODE (operands[0]) == SImode
8674 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8675 || GET_MODE (operands[0]) == HImode
8676 || GET_MODE (operands[0]) == QImode)"
8679 (define_insn "*testqi_ext_3_rex64"
8680 [(set (reg FLAGS_REG)
8681 (compare (zero_extract:DI
8682 (match_operand 0 "nonimmediate_operand" "rm")
8683 (match_operand:DI 1 "const_int_operand" "")
8684 (match_operand:DI 2 "const_int_operand" ""))
8687 && ix86_match_ccmode (insn, CCNOmode)
8688 && INTVAL (operands[1]) > 0
8689 && INTVAL (operands[2]) >= 0
8690 /* Ensure that resulting mask is zero or sign extended operand. */
8691 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8692 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8693 && INTVAL (operands[1]) > 32))
8694 && (GET_MODE (operands[0]) == SImode
8695 || GET_MODE (operands[0]) == DImode
8696 || GET_MODE (operands[0]) == HImode
8697 || GET_MODE (operands[0]) == QImode)"
8701 [(set (match_operand 0 "flags_reg_operand" "")
8702 (match_operator 1 "compare_operator"
8704 (match_operand 2 "nonimmediate_operand" "")
8705 (match_operand 3 "const_int_operand" "")
8706 (match_operand 4 "const_int_operand" ""))
8708 "ix86_match_ccmode (insn, CCNOmode)"
8709 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8711 rtx val = operands[2];
8712 HOST_WIDE_INT len = INTVAL (operands[3]);
8713 HOST_WIDE_INT pos = INTVAL (operands[4]);
8715 enum machine_mode mode, submode;
8717 mode = GET_MODE (val);
8720 /* ??? Combine likes to put non-volatile mem extractions in QImode
8721 no matter the size of the test. So find a mode that works. */
8722 if (! MEM_VOLATILE_P (val))
8724 mode = smallest_mode_for_size (pos + len, MODE_INT);
8725 val = adjust_address (val, mode, 0);
8728 else if (GET_CODE (val) == SUBREG
8729 && (submode = GET_MODE (SUBREG_REG (val)),
8730 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8731 && pos + len <= GET_MODE_BITSIZE (submode))
8733 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8735 val = SUBREG_REG (val);
8737 else if (mode == HImode && pos + len <= 8)
8739 /* Small HImode tests can be converted to QImode. */
8741 val = gen_lowpart (QImode, val);
8744 if (len == HOST_BITS_PER_WIDE_INT)
8747 mask = ((HOST_WIDE_INT)1 << len) - 1;
8750 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8753 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8754 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8755 ;; this is relatively important trick.
8756 ;; Do the conversion only post-reload to avoid limiting of the register class
8759 [(set (match_operand 0 "flags_reg_operand" "")
8760 (match_operator 1 "compare_operator"
8761 [(and (match_operand 2 "register_operand" "")
8762 (match_operand 3 "const_int_operand" ""))
8765 && QI_REG_P (operands[2])
8766 && GET_MODE (operands[2]) != QImode
8767 && ((ix86_match_ccmode (insn, CCZmode)
8768 && !(INTVAL (operands[3]) & ~(255 << 8)))
8769 || (ix86_match_ccmode (insn, CCNOmode)
8770 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8773 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8776 "operands[2] = gen_lowpart (SImode, operands[2]);
8777 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8780 [(set (match_operand 0 "flags_reg_operand" "")
8781 (match_operator 1 "compare_operator"
8782 [(and (match_operand 2 "nonimmediate_operand" "")
8783 (match_operand 3 "const_int_operand" ""))
8786 && GET_MODE (operands[2]) != QImode
8787 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8788 && ((ix86_match_ccmode (insn, CCZmode)
8789 && !(INTVAL (operands[3]) & ~255))
8790 || (ix86_match_ccmode (insn, CCNOmode)
8791 && !(INTVAL (operands[3]) & ~127)))"
8793 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8795 "operands[2] = gen_lowpart (QImode, operands[2]);
8796 operands[3] = gen_lowpart (QImode, operands[3]);")
8799 ;; %%% This used to optimize known byte-wide and operations to memory,
8800 ;; and sometimes to QImode registers. If this is considered useful,
8801 ;; it should be done with splitters.
8803 (define_expand "anddi3"
8804 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8805 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8806 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8807 (clobber (reg:CC FLAGS_REG))]
8809 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8811 (define_insn "*anddi_1_rex64"
8812 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8813 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8814 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8815 (clobber (reg:CC FLAGS_REG))]
8816 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8818 switch (get_attr_type (insn))
8822 enum machine_mode mode;
8824 gcc_assert (CONST_INT_P (operands[2]));
8825 if (INTVAL (operands[2]) == 0xff)
8829 gcc_assert (INTVAL (operands[2]) == 0xffff);
8833 operands[1] = gen_lowpart (mode, operands[1]);
8835 return "movz{bq|x}\t{%1,%0|%0, %1}";
8837 return "movz{wq|x}\t{%1,%0|%0, %1}";
8841 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8842 if (get_attr_mode (insn) == MODE_SI)
8843 return "and{l}\t{%k2, %k0|%k0, %k2}";
8845 return "and{q}\t{%2, %0|%0, %2}";
8848 [(set_attr "type" "alu,alu,alu,imovx")
8849 (set_attr "length_immediate" "*,*,*,0")
8850 (set_attr "mode" "SI,DI,DI,DI")])
8852 (define_insn "*anddi_2"
8853 [(set (reg FLAGS_REG)
8854 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8855 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8857 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8858 (and:DI (match_dup 1) (match_dup 2)))]
8859 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8860 && ix86_binary_operator_ok (AND, DImode, operands)"
8862 and{l}\t{%k2, %k0|%k0, %k2}
8863 and{q}\t{%2, %0|%0, %2}
8864 and{q}\t{%2, %0|%0, %2}"
8865 [(set_attr "type" "alu")
8866 (set_attr "mode" "SI,DI,DI")])
8868 (define_expand "andsi3"
8869 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8870 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8871 (match_operand:SI 2 "general_operand" "")))
8872 (clobber (reg:CC FLAGS_REG))]
8874 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8876 (define_insn "*andsi_1"
8877 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8878 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8879 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8880 (clobber (reg:CC FLAGS_REG))]
8881 "ix86_binary_operator_ok (AND, SImode, operands)"
8883 switch (get_attr_type (insn))
8887 enum machine_mode mode;
8889 gcc_assert (CONST_INT_P (operands[2]));
8890 if (INTVAL (operands[2]) == 0xff)
8894 gcc_assert (INTVAL (operands[2]) == 0xffff);
8898 operands[1] = gen_lowpart (mode, operands[1]);
8900 return "movz{bl|x}\t{%1,%0|%0, %1}";
8902 return "movz{wl|x}\t{%1,%0|%0, %1}";
8906 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8907 return "and{l}\t{%2, %0|%0, %2}";
8910 [(set_attr "type" "alu,alu,imovx")
8911 (set_attr "length_immediate" "*,*,0")
8912 (set_attr "mode" "SI")])
8915 [(set (match_operand 0 "register_operand" "")
8917 (const_int -65536)))
8918 (clobber (reg:CC FLAGS_REG))]
8919 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8920 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8921 "operands[1] = gen_lowpart (HImode, operands[0]);")
8924 [(set (match_operand 0 "ext_register_operand" "")
8927 (clobber (reg:CC FLAGS_REG))]
8928 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8929 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8930 "operands[1] = gen_lowpart (QImode, operands[0]);")
8933 [(set (match_operand 0 "ext_register_operand" "")
8935 (const_int -65281)))
8936 (clobber (reg:CC FLAGS_REG))]
8937 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8938 [(parallel [(set (zero_extract:SI (match_dup 0)
8942 (zero_extract:SI (match_dup 0)
8945 (zero_extract:SI (match_dup 0)
8948 (clobber (reg:CC FLAGS_REG))])]
8949 "operands[0] = gen_lowpart (SImode, operands[0]);")
8951 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8952 (define_insn "*andsi_1_zext"
8953 [(set (match_operand:DI 0 "register_operand" "=r")
8955 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956 (match_operand:SI 2 "general_operand" "g"))))
8957 (clobber (reg:CC FLAGS_REG))]
8958 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8959 "and{l}\t{%2, %k0|%k0, %2}"
8960 [(set_attr "type" "alu")
8961 (set_attr "mode" "SI")])
8963 (define_insn "*andsi_2"
8964 [(set (reg FLAGS_REG)
8965 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8966 (match_operand:SI 2 "general_operand" "g,ri"))
8968 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8969 (and:SI (match_dup 1) (match_dup 2)))]
8970 "ix86_match_ccmode (insn, CCNOmode)
8971 && ix86_binary_operator_ok (AND, SImode, operands)"
8972 "and{l}\t{%2, %0|%0, %2}"
8973 [(set_attr "type" "alu")
8974 (set_attr "mode" "SI")])
8976 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8977 (define_insn "*andsi_2_zext"
8978 [(set (reg FLAGS_REG)
8979 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8980 (match_operand:SI 2 "general_operand" "g"))
8982 (set (match_operand:DI 0 "register_operand" "=r")
8983 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8984 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8985 && ix86_binary_operator_ok (AND, SImode, operands)"
8986 "and{l}\t{%2, %k0|%k0, %2}"
8987 [(set_attr "type" "alu")
8988 (set_attr "mode" "SI")])
8990 (define_expand "andhi3"
8991 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8992 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8993 (match_operand:HI 2 "general_operand" "")))
8994 (clobber (reg:CC FLAGS_REG))]
8995 "TARGET_HIMODE_MATH"
8996 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8998 (define_insn "*andhi_1"
8999 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9000 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9001 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9002 (clobber (reg:CC FLAGS_REG))]
9003 "ix86_binary_operator_ok (AND, HImode, operands)"
9005 switch (get_attr_type (insn))
9008 gcc_assert (CONST_INT_P (operands[2]));
9009 gcc_assert (INTVAL (operands[2]) == 0xff);
9010 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9013 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9015 return "and{w}\t{%2, %0|%0, %2}";
9018 [(set_attr "type" "alu,alu,imovx")
9019 (set_attr "length_immediate" "*,*,0")
9020 (set_attr "mode" "HI,HI,SI")])
9022 (define_insn "*andhi_2"
9023 [(set (reg FLAGS_REG)
9024 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9025 (match_operand:HI 2 "general_operand" "g,ri"))
9027 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9028 (and:HI (match_dup 1) (match_dup 2)))]
9029 "ix86_match_ccmode (insn, CCNOmode)
9030 && ix86_binary_operator_ok (AND, HImode, operands)"
9031 "and{w}\t{%2, %0|%0, %2}"
9032 [(set_attr "type" "alu")
9033 (set_attr "mode" "HI")])
9035 (define_expand "andqi3"
9036 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9037 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9038 (match_operand:QI 2 "general_operand" "")))
9039 (clobber (reg:CC FLAGS_REG))]
9040 "TARGET_QIMODE_MATH"
9041 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9043 ;; %%% Potential partial reg stall on alternative 2. What to do?
9044 (define_insn "*andqi_1"
9045 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9046 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9047 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9048 (clobber (reg:CC FLAGS_REG))]
9049 "ix86_binary_operator_ok (AND, QImode, operands)"
9051 and{b}\t{%2, %0|%0, %2}
9052 and{b}\t{%2, %0|%0, %2}
9053 and{l}\t{%k2, %k0|%k0, %k2}"
9054 [(set_attr "type" "alu")
9055 (set_attr "mode" "QI,QI,SI")])
9057 (define_insn "*andqi_1_slp"
9058 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9059 (and:QI (match_dup 0)
9060 (match_operand:QI 1 "general_operand" "qi,qmi")))
9061 (clobber (reg:CC FLAGS_REG))]
9062 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9063 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9064 "and{b}\t{%1, %0|%0, %1}"
9065 [(set_attr "type" "alu1")
9066 (set_attr "mode" "QI")])
9068 (define_insn "*andqi_2_maybe_si"
9069 [(set (reg FLAGS_REG)
9071 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9072 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9074 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9075 (and:QI (match_dup 1) (match_dup 2)))]
9076 "ix86_binary_operator_ok (AND, QImode, operands)
9077 && ix86_match_ccmode (insn,
9078 CONST_INT_P (operands[2])
9079 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9081 if (which_alternative == 2)
9083 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9084 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9085 return "and{l}\t{%2, %k0|%k0, %2}";
9087 return "and{b}\t{%2, %0|%0, %2}";
9089 [(set_attr "type" "alu")
9090 (set_attr "mode" "QI,QI,SI")])
9092 (define_insn "*andqi_2"
9093 [(set (reg FLAGS_REG)
9095 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9096 (match_operand:QI 2 "general_operand" "qim,qi"))
9098 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9099 (and:QI (match_dup 1) (match_dup 2)))]
9100 "ix86_match_ccmode (insn, CCNOmode)
9101 && ix86_binary_operator_ok (AND, QImode, operands)"
9102 "and{b}\t{%2, %0|%0, %2}"
9103 [(set_attr "type" "alu")
9104 (set_attr "mode" "QI")])
9106 (define_insn "*andqi_2_slp"
9107 [(set (reg FLAGS_REG)
9109 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9110 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9112 (set (strict_low_part (match_dup 0))
9113 (and:QI (match_dup 0) (match_dup 1)))]
9114 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9115 && ix86_match_ccmode (insn, CCNOmode)
9116 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9117 "and{b}\t{%1, %0|%0, %1}"
9118 [(set_attr "type" "alu1")
9119 (set_attr "mode" "QI")])
9121 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9122 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9123 ;; for a QImode operand, which of course failed.
9125 (define_insn "andqi_ext_0"
9126 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9131 (match_operand 1 "ext_register_operand" "0")
9134 (match_operand 2 "const_int_operand" "n")))
9135 (clobber (reg:CC FLAGS_REG))]
9137 "and{b}\t{%2, %h0|%h0, %2}"
9138 [(set_attr "type" "alu")
9139 (set_attr "length_immediate" "1")
9140 (set_attr "mode" "QI")])
9142 ;; Generated by peephole translating test to and. This shows up
9143 ;; often in fp comparisons.
9145 (define_insn "*andqi_ext_0_cc"
9146 [(set (reg FLAGS_REG)
9150 (match_operand 1 "ext_register_operand" "0")
9153 (match_operand 2 "const_int_operand" "n"))
9155 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9164 "ix86_match_ccmode (insn, CCNOmode)"
9165 "and{b}\t{%2, %h0|%h0, %2}"
9166 [(set_attr "type" "alu")
9167 (set_attr "length_immediate" "1")
9168 (set_attr "mode" "QI")])
9170 (define_insn "*andqi_ext_1"
9171 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9176 (match_operand 1 "ext_register_operand" "0")
9180 (match_operand:QI 2 "general_operand" "Qm"))))
9181 (clobber (reg:CC FLAGS_REG))]
9183 "and{b}\t{%2, %h0|%h0, %2}"
9184 [(set_attr "type" "alu")
9185 (set_attr "length_immediate" "0")
9186 (set_attr "mode" "QI")])
9188 (define_insn "*andqi_ext_1_rex64"
9189 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9194 (match_operand 1 "ext_register_operand" "0")
9198 (match_operand 2 "ext_register_operand" "Q"))))
9199 (clobber (reg:CC FLAGS_REG))]
9201 "and{b}\t{%2, %h0|%h0, %2}"
9202 [(set_attr "type" "alu")
9203 (set_attr "length_immediate" "0")
9204 (set_attr "mode" "QI")])
9206 (define_insn "*andqi_ext_2"
9207 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9212 (match_operand 1 "ext_register_operand" "%0")
9216 (match_operand 2 "ext_register_operand" "Q")
9219 (clobber (reg:CC FLAGS_REG))]
9221 "and{b}\t{%h2, %h0|%h0, %h2}"
9222 [(set_attr "type" "alu")
9223 (set_attr "length_immediate" "0")
9224 (set_attr "mode" "QI")])
9226 ;; Convert wide AND instructions with immediate operand to shorter QImode
9227 ;; equivalents when possible.
9228 ;; Don't do the splitting with memory operands, since it introduces risk
9229 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9230 ;; for size, but that can (should?) be handled by generic code instead.
9232 [(set (match_operand 0 "register_operand" "")
9233 (and (match_operand 1 "register_operand" "")
9234 (match_operand 2 "const_int_operand" "")))
9235 (clobber (reg:CC FLAGS_REG))]
9237 && QI_REG_P (operands[0])
9238 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9239 && !(~INTVAL (operands[2]) & ~(255 << 8))
9240 && GET_MODE (operands[0]) != QImode"
9241 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9242 (and:SI (zero_extract:SI (match_dup 1)
9243 (const_int 8) (const_int 8))
9245 (clobber (reg:CC FLAGS_REG))])]
9246 "operands[0] = gen_lowpart (SImode, operands[0]);
9247 operands[1] = gen_lowpart (SImode, operands[1]);
9248 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9250 ;; Since AND can be encoded with sign extended immediate, this is only
9251 ;; profitable when 7th bit is not set.
9253 [(set (match_operand 0 "register_operand" "")
9254 (and (match_operand 1 "general_operand" "")
9255 (match_operand 2 "const_int_operand" "")))
9256 (clobber (reg:CC FLAGS_REG))]
9258 && ANY_QI_REG_P (operands[0])
9259 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9260 && !(~INTVAL (operands[2]) & ~255)
9261 && !(INTVAL (operands[2]) & 128)
9262 && GET_MODE (operands[0]) != QImode"
9263 [(parallel [(set (strict_low_part (match_dup 0))
9264 (and:QI (match_dup 1)
9266 (clobber (reg:CC FLAGS_REG))])]
9267 "operands[0] = gen_lowpart (QImode, operands[0]);
9268 operands[1] = gen_lowpart (QImode, operands[1]);
9269 operands[2] = gen_lowpart (QImode, operands[2]);")
9271 ;; Logical inclusive OR instructions
9273 ;; %%% This used to optimize known byte-wide and operations to memory.
9274 ;; If this is considered useful, it should be done with splitters.
9276 (define_expand "iordi3"
9277 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9278 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9279 (match_operand:DI 2 "x86_64_general_operand" "")))
9280 (clobber (reg:CC FLAGS_REG))]
9282 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9284 (define_insn "*iordi_1_rex64"
9285 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9286 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9287 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9288 (clobber (reg:CC FLAGS_REG))]
9290 && ix86_binary_operator_ok (IOR, DImode, operands)"
9291 "or{q}\t{%2, %0|%0, %2}"
9292 [(set_attr "type" "alu")
9293 (set_attr "mode" "DI")])
9295 (define_insn "*iordi_2_rex64"
9296 [(set (reg FLAGS_REG)
9297 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9298 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9300 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9301 (ior:DI (match_dup 1) (match_dup 2)))]
9303 && ix86_match_ccmode (insn, CCNOmode)
9304 && ix86_binary_operator_ok (IOR, DImode, operands)"
9305 "or{q}\t{%2, %0|%0, %2}"
9306 [(set_attr "type" "alu")
9307 (set_attr "mode" "DI")])
9309 (define_insn "*iordi_3_rex64"
9310 [(set (reg FLAGS_REG)
9311 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9312 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9314 (clobber (match_scratch:DI 0 "=r"))]
9316 && ix86_match_ccmode (insn, CCNOmode)
9317 && ix86_binary_operator_ok (IOR, DImode, operands)"
9318 "or{q}\t{%2, %0|%0, %2}"
9319 [(set_attr "type" "alu")
9320 (set_attr "mode" "DI")])
9323 (define_expand "iorsi3"
9324 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9325 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9326 (match_operand:SI 2 "general_operand" "")))
9327 (clobber (reg:CC FLAGS_REG))]
9329 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9331 (define_insn "*iorsi_1"
9332 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9333 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9334 (match_operand:SI 2 "general_operand" "ri,g")))
9335 (clobber (reg:CC FLAGS_REG))]
9336 "ix86_binary_operator_ok (IOR, SImode, operands)"
9337 "or{l}\t{%2, %0|%0, %2}"
9338 [(set_attr "type" "alu")
9339 (set_attr "mode" "SI")])
9341 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9342 (define_insn "*iorsi_1_zext"
9343 [(set (match_operand:DI 0 "register_operand" "=r")
9345 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9346 (match_operand:SI 2 "general_operand" "g"))))
9347 (clobber (reg:CC FLAGS_REG))]
9348 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9349 "or{l}\t{%2, %k0|%k0, %2}"
9350 [(set_attr "type" "alu")
9351 (set_attr "mode" "SI")])
9353 (define_insn "*iorsi_1_zext_imm"
9354 [(set (match_operand:DI 0 "register_operand" "=r")
9355 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9356 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9357 (clobber (reg:CC FLAGS_REG))]
9359 "or{l}\t{%2, %k0|%k0, %2}"
9360 [(set_attr "type" "alu")
9361 (set_attr "mode" "SI")])
9363 (define_insn "*iorsi_2"
9364 [(set (reg FLAGS_REG)
9365 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9366 (match_operand:SI 2 "general_operand" "g,ri"))
9368 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9369 (ior:SI (match_dup 1) (match_dup 2)))]
9370 "ix86_match_ccmode (insn, CCNOmode)
9371 && ix86_binary_operator_ok (IOR, SImode, operands)"
9372 "or{l}\t{%2, %0|%0, %2}"
9373 [(set_attr "type" "alu")
9374 (set_attr "mode" "SI")])
9376 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9377 ;; ??? Special case for immediate operand is missing - it is tricky.
9378 (define_insn "*iorsi_2_zext"
9379 [(set (reg FLAGS_REG)
9380 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9381 (match_operand:SI 2 "general_operand" "g"))
9383 (set (match_operand:DI 0 "register_operand" "=r")
9384 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9385 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9386 && ix86_binary_operator_ok (IOR, SImode, operands)"
9387 "or{l}\t{%2, %k0|%k0, %2}"
9388 [(set_attr "type" "alu")
9389 (set_attr "mode" "SI")])
9391 (define_insn "*iorsi_2_zext_imm"
9392 [(set (reg FLAGS_REG)
9393 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9394 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9396 (set (match_operand:DI 0 "register_operand" "=r")
9397 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9398 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9399 && ix86_binary_operator_ok (IOR, SImode, operands)"
9400 "or{l}\t{%2, %k0|%k0, %2}"
9401 [(set_attr "type" "alu")
9402 (set_attr "mode" "SI")])
9404 (define_insn "*iorsi_3"
9405 [(set (reg FLAGS_REG)
9406 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9407 (match_operand:SI 2 "general_operand" "g"))
9409 (clobber (match_scratch:SI 0 "=r"))]
9410 "ix86_match_ccmode (insn, CCNOmode)
9411 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9412 "or{l}\t{%2, %0|%0, %2}"
9413 [(set_attr "type" "alu")
9414 (set_attr "mode" "SI")])
9416 (define_expand "iorhi3"
9417 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9418 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9419 (match_operand:HI 2 "general_operand" "")))
9420 (clobber (reg:CC FLAGS_REG))]
9421 "TARGET_HIMODE_MATH"
9422 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9424 (define_insn "*iorhi_1"
9425 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9426 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9427 (match_operand:HI 2 "general_operand" "g,ri")))
9428 (clobber (reg:CC FLAGS_REG))]
9429 "ix86_binary_operator_ok (IOR, HImode, operands)"
9430 "or{w}\t{%2, %0|%0, %2}"
9431 [(set_attr "type" "alu")
9432 (set_attr "mode" "HI")])
9434 (define_insn "*iorhi_2"
9435 [(set (reg FLAGS_REG)
9436 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9437 (match_operand:HI 2 "general_operand" "g,ri"))
9439 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9440 (ior:HI (match_dup 1) (match_dup 2)))]
9441 "ix86_match_ccmode (insn, CCNOmode)
9442 && ix86_binary_operator_ok (IOR, HImode, operands)"
9443 "or{w}\t{%2, %0|%0, %2}"
9444 [(set_attr "type" "alu")
9445 (set_attr "mode" "HI")])
9447 (define_insn "*iorhi_3"
9448 [(set (reg FLAGS_REG)
9449 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9450 (match_operand:HI 2 "general_operand" "g"))
9452 (clobber (match_scratch:HI 0 "=r"))]
9453 "ix86_match_ccmode (insn, CCNOmode)
9454 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9455 "or{w}\t{%2, %0|%0, %2}"
9456 [(set_attr "type" "alu")
9457 (set_attr "mode" "HI")])
9459 (define_expand "iorqi3"
9460 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9461 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9462 (match_operand:QI 2 "general_operand" "")))
9463 (clobber (reg:CC FLAGS_REG))]
9464 "TARGET_QIMODE_MATH"
9465 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9467 ;; %%% Potential partial reg stall on alternative 2. What to do?
9468 (define_insn "*iorqi_1"
9469 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9470 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9471 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9472 (clobber (reg:CC FLAGS_REG))]
9473 "ix86_binary_operator_ok (IOR, QImode, operands)"
9475 or{b}\t{%2, %0|%0, %2}
9476 or{b}\t{%2, %0|%0, %2}
9477 or{l}\t{%k2, %k0|%k0, %k2}"
9478 [(set_attr "type" "alu")
9479 (set_attr "mode" "QI,QI,SI")])
9481 (define_insn "*iorqi_1_slp"
9482 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9483 (ior:QI (match_dup 0)
9484 (match_operand:QI 1 "general_operand" "qmi,qi")))
9485 (clobber (reg:CC FLAGS_REG))]
9486 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9487 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9488 "or{b}\t{%1, %0|%0, %1}"
9489 [(set_attr "type" "alu1")
9490 (set_attr "mode" "QI")])
9492 (define_insn "*iorqi_2"
9493 [(set (reg FLAGS_REG)
9494 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9495 (match_operand:QI 2 "general_operand" "qim,qi"))
9497 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9498 (ior:QI (match_dup 1) (match_dup 2)))]
9499 "ix86_match_ccmode (insn, CCNOmode)
9500 && ix86_binary_operator_ok (IOR, QImode, operands)"
9501 "or{b}\t{%2, %0|%0, %2}"
9502 [(set_attr "type" "alu")
9503 (set_attr "mode" "QI")])
9505 (define_insn "*iorqi_2_slp"
9506 [(set (reg FLAGS_REG)
9507 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9508 (match_operand:QI 1 "general_operand" "qim,qi"))
9510 (set (strict_low_part (match_dup 0))
9511 (ior:QI (match_dup 0) (match_dup 1)))]
9512 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9513 && ix86_match_ccmode (insn, CCNOmode)
9514 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9515 "or{b}\t{%1, %0|%0, %1}"
9516 [(set_attr "type" "alu1")
9517 (set_attr "mode" "QI")])
9519 (define_insn "*iorqi_3"
9520 [(set (reg FLAGS_REG)
9521 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9522 (match_operand:QI 2 "general_operand" "qim"))
9524 (clobber (match_scratch:QI 0 "=q"))]
9525 "ix86_match_ccmode (insn, CCNOmode)
9526 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9527 "or{b}\t{%2, %0|%0, %2}"
9528 [(set_attr "type" "alu")
9529 (set_attr "mode" "QI")])
9531 (define_insn "iorqi_ext_0"
9532 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9537 (match_operand 1 "ext_register_operand" "0")
9540 (match_operand 2 "const_int_operand" "n")))
9541 (clobber (reg:CC FLAGS_REG))]
9542 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9543 "or{b}\t{%2, %h0|%h0, %2}"
9544 [(set_attr "type" "alu")
9545 (set_attr "length_immediate" "1")
9546 (set_attr "mode" "QI")])
9548 (define_insn "*iorqi_ext_1"
9549 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9554 (match_operand 1 "ext_register_operand" "0")
9558 (match_operand:QI 2 "general_operand" "Qm"))))
9559 (clobber (reg:CC FLAGS_REG))]
9561 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9562 "or{b}\t{%2, %h0|%h0, %2}"
9563 [(set_attr "type" "alu")
9564 (set_attr "length_immediate" "0")
9565 (set_attr "mode" "QI")])
9567 (define_insn "*iorqi_ext_1_rex64"
9568 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9573 (match_operand 1 "ext_register_operand" "0")
9577 (match_operand 2 "ext_register_operand" "Q"))))
9578 (clobber (reg:CC FLAGS_REG))]
9580 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9581 "or{b}\t{%2, %h0|%h0, %2}"
9582 [(set_attr "type" "alu")
9583 (set_attr "length_immediate" "0")
9584 (set_attr "mode" "QI")])
9586 (define_insn "*iorqi_ext_2"
9587 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9591 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9594 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9597 (clobber (reg:CC FLAGS_REG))]
9598 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9599 "ior{b}\t{%h2, %h0|%h0, %h2}"
9600 [(set_attr "type" "alu")
9601 (set_attr "length_immediate" "0")
9602 (set_attr "mode" "QI")])
9605 [(set (match_operand 0 "register_operand" "")
9606 (ior (match_operand 1 "register_operand" "")
9607 (match_operand 2 "const_int_operand" "")))
9608 (clobber (reg:CC FLAGS_REG))]
9610 && QI_REG_P (operands[0])
9611 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9612 && !(INTVAL (operands[2]) & ~(255 << 8))
9613 && GET_MODE (operands[0]) != QImode"
9614 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9615 (ior:SI (zero_extract:SI (match_dup 1)
9616 (const_int 8) (const_int 8))
9618 (clobber (reg:CC FLAGS_REG))])]
9619 "operands[0] = gen_lowpart (SImode, operands[0]);
9620 operands[1] = gen_lowpart (SImode, operands[1]);
9621 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9623 ;; Since OR can be encoded with sign extended immediate, this is only
9624 ;; profitable when 7th bit is set.
9626 [(set (match_operand 0 "register_operand" "")
9627 (ior (match_operand 1 "general_operand" "")
9628 (match_operand 2 "const_int_operand" "")))
9629 (clobber (reg:CC FLAGS_REG))]
9631 && ANY_QI_REG_P (operands[0])
9632 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9633 && !(INTVAL (operands[2]) & ~255)
9634 && (INTVAL (operands[2]) & 128)
9635 && GET_MODE (operands[0]) != QImode"
9636 [(parallel [(set (strict_low_part (match_dup 0))
9637 (ior:QI (match_dup 1)
9639 (clobber (reg:CC FLAGS_REG))])]
9640 "operands[0] = gen_lowpart (QImode, operands[0]);
9641 operands[1] = gen_lowpart (QImode, operands[1]);
9642 operands[2] = gen_lowpart (QImode, operands[2]);")
9644 ;; Logical XOR instructions
9646 ;; %%% This used to optimize known byte-wide and operations to memory.
9647 ;; If this is considered useful, it should be done with splitters.
9649 (define_expand "xordi3"
9650 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9651 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9652 (match_operand:DI 2 "x86_64_general_operand" "")))
9653 (clobber (reg:CC FLAGS_REG))]
9655 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9657 (define_insn "*xordi_1_rex64"
9658 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9659 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9660 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9661 (clobber (reg:CC FLAGS_REG))]
9663 && ix86_binary_operator_ok (XOR, DImode, operands)"
9665 xor{q}\t{%2, %0|%0, %2}
9666 xor{q}\t{%2, %0|%0, %2}"
9667 [(set_attr "type" "alu")
9668 (set_attr "mode" "DI,DI")])
9670 (define_insn "*xordi_2_rex64"
9671 [(set (reg FLAGS_REG)
9672 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9673 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9675 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9676 (xor:DI (match_dup 1) (match_dup 2)))]
9678 && ix86_match_ccmode (insn, CCNOmode)
9679 && ix86_binary_operator_ok (XOR, DImode, operands)"
9681 xor{q}\t{%2, %0|%0, %2}
9682 xor{q}\t{%2, %0|%0, %2}"
9683 [(set_attr "type" "alu")
9684 (set_attr "mode" "DI,DI")])
9686 (define_insn "*xordi_3_rex64"
9687 [(set (reg FLAGS_REG)
9688 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9689 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9691 (clobber (match_scratch:DI 0 "=r"))]
9693 && ix86_match_ccmode (insn, CCNOmode)
9694 && ix86_binary_operator_ok (XOR, DImode, operands)"
9695 "xor{q}\t{%2, %0|%0, %2}"
9696 [(set_attr "type" "alu")
9697 (set_attr "mode" "DI")])
9699 (define_expand "xorsi3"
9700 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9701 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9702 (match_operand:SI 2 "general_operand" "")))
9703 (clobber (reg:CC FLAGS_REG))]
9705 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9707 (define_insn "*xorsi_1"
9708 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9709 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9710 (match_operand:SI 2 "general_operand" "ri,rm")))
9711 (clobber (reg:CC FLAGS_REG))]
9712 "ix86_binary_operator_ok (XOR, SImode, operands)"
9713 "xor{l}\t{%2, %0|%0, %2}"
9714 [(set_attr "type" "alu")
9715 (set_attr "mode" "SI")])
9717 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9718 ;; Add speccase for immediates
9719 (define_insn "*xorsi_1_zext"
9720 [(set (match_operand:DI 0 "register_operand" "=r")
9722 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9723 (match_operand:SI 2 "general_operand" "g"))))
9724 (clobber (reg:CC FLAGS_REG))]
9725 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9726 "xor{l}\t{%2, %k0|%k0, %2}"
9727 [(set_attr "type" "alu")
9728 (set_attr "mode" "SI")])
9730 (define_insn "*xorsi_1_zext_imm"
9731 [(set (match_operand:DI 0 "register_operand" "=r")
9732 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9733 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9734 (clobber (reg:CC FLAGS_REG))]
9735 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9736 "xor{l}\t{%2, %k0|%k0, %2}"
9737 [(set_attr "type" "alu")
9738 (set_attr "mode" "SI")])
9740 (define_insn "*xorsi_2"
9741 [(set (reg FLAGS_REG)
9742 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9743 (match_operand:SI 2 "general_operand" "g,ri"))
9745 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9746 (xor:SI (match_dup 1) (match_dup 2)))]
9747 "ix86_match_ccmode (insn, CCNOmode)
9748 && ix86_binary_operator_ok (XOR, SImode, operands)"
9749 "xor{l}\t{%2, %0|%0, %2}"
9750 [(set_attr "type" "alu")
9751 (set_attr "mode" "SI")])
9753 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9754 ;; ??? Special case for immediate operand is missing - it is tricky.
9755 (define_insn "*xorsi_2_zext"
9756 [(set (reg FLAGS_REG)
9757 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9758 (match_operand:SI 2 "general_operand" "g"))
9760 (set (match_operand:DI 0 "register_operand" "=r")
9761 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9762 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9763 && ix86_binary_operator_ok (XOR, SImode, operands)"
9764 "xor{l}\t{%2, %k0|%k0, %2}"
9765 [(set_attr "type" "alu")
9766 (set_attr "mode" "SI")])
9768 (define_insn "*xorsi_2_zext_imm"
9769 [(set (reg FLAGS_REG)
9770 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9771 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9773 (set (match_operand:DI 0 "register_operand" "=r")
9774 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9775 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9776 && ix86_binary_operator_ok (XOR, SImode, operands)"
9777 "xor{l}\t{%2, %k0|%k0, %2}"
9778 [(set_attr "type" "alu")
9779 (set_attr "mode" "SI")])
9781 (define_insn "*xorsi_3"
9782 [(set (reg FLAGS_REG)
9783 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9784 (match_operand:SI 2 "general_operand" "g"))
9786 (clobber (match_scratch:SI 0 "=r"))]
9787 "ix86_match_ccmode (insn, CCNOmode)
9788 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9789 "xor{l}\t{%2, %0|%0, %2}"
9790 [(set_attr "type" "alu")
9791 (set_attr "mode" "SI")])
9793 (define_expand "xorhi3"
9794 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9795 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9796 (match_operand:HI 2 "general_operand" "")))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "TARGET_HIMODE_MATH"
9799 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9801 (define_insn "*xorhi_1"
9802 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9803 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9804 (match_operand:HI 2 "general_operand" "g,ri")))
9805 (clobber (reg:CC FLAGS_REG))]
9806 "ix86_binary_operator_ok (XOR, HImode, operands)"
9807 "xor{w}\t{%2, %0|%0, %2}"
9808 [(set_attr "type" "alu")
9809 (set_attr "mode" "HI")])
9811 (define_insn "*xorhi_2"
9812 [(set (reg FLAGS_REG)
9813 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9814 (match_operand:HI 2 "general_operand" "g,ri"))
9816 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9817 (xor:HI (match_dup 1) (match_dup 2)))]
9818 "ix86_match_ccmode (insn, CCNOmode)
9819 && ix86_binary_operator_ok (XOR, HImode, operands)"
9820 "xor{w}\t{%2, %0|%0, %2}"
9821 [(set_attr "type" "alu")
9822 (set_attr "mode" "HI")])
9824 (define_insn "*xorhi_3"
9825 [(set (reg FLAGS_REG)
9826 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9827 (match_operand:HI 2 "general_operand" "g"))
9829 (clobber (match_scratch:HI 0 "=r"))]
9830 "ix86_match_ccmode (insn, CCNOmode)
9831 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9832 "xor{w}\t{%2, %0|%0, %2}"
9833 [(set_attr "type" "alu")
9834 (set_attr "mode" "HI")])
9836 (define_expand "xorqi3"
9837 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9838 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9839 (match_operand:QI 2 "general_operand" "")))
9840 (clobber (reg:CC FLAGS_REG))]
9841 "TARGET_QIMODE_MATH"
9842 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9844 ;; %%% Potential partial reg stall on alternative 2. What to do?
9845 (define_insn "*xorqi_1"
9846 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9847 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9848 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9849 (clobber (reg:CC FLAGS_REG))]
9850 "ix86_binary_operator_ok (XOR, QImode, operands)"
9852 xor{b}\t{%2, %0|%0, %2}
9853 xor{b}\t{%2, %0|%0, %2}
9854 xor{l}\t{%k2, %k0|%k0, %k2}"
9855 [(set_attr "type" "alu")
9856 (set_attr "mode" "QI,QI,SI")])
9858 (define_insn "*xorqi_1_slp"
9859 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9860 (xor:QI (match_dup 0)
9861 (match_operand:QI 1 "general_operand" "qi,qmi")))
9862 (clobber (reg:CC FLAGS_REG))]
9863 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9864 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9865 "xor{b}\t{%1, %0|%0, %1}"
9866 [(set_attr "type" "alu1")
9867 (set_attr "mode" "QI")])
9869 (define_insn "xorqi_ext_0"
9870 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9875 (match_operand 1 "ext_register_operand" "0")
9878 (match_operand 2 "const_int_operand" "n")))
9879 (clobber (reg:CC FLAGS_REG))]
9880 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9881 "xor{b}\t{%2, %h0|%h0, %2}"
9882 [(set_attr "type" "alu")
9883 (set_attr "length_immediate" "1")
9884 (set_attr "mode" "QI")])
9886 (define_insn "*xorqi_ext_1"
9887 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9892 (match_operand 1 "ext_register_operand" "0")
9896 (match_operand:QI 2 "general_operand" "Qm"))))
9897 (clobber (reg:CC FLAGS_REG))]
9899 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9900 "xor{b}\t{%2, %h0|%h0, %2}"
9901 [(set_attr "type" "alu")
9902 (set_attr "length_immediate" "0")
9903 (set_attr "mode" "QI")])
9905 (define_insn "*xorqi_ext_1_rex64"
9906 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9911 (match_operand 1 "ext_register_operand" "0")
9915 (match_operand 2 "ext_register_operand" "Q"))))
9916 (clobber (reg:CC FLAGS_REG))]
9918 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9919 "xor{b}\t{%2, %h0|%h0, %2}"
9920 [(set_attr "type" "alu")
9921 (set_attr "length_immediate" "0")
9922 (set_attr "mode" "QI")])
9924 (define_insn "*xorqi_ext_2"
9925 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9929 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9932 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9935 (clobber (reg:CC FLAGS_REG))]
9936 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9937 "xor{b}\t{%h2, %h0|%h0, %h2}"
9938 [(set_attr "type" "alu")
9939 (set_attr "length_immediate" "0")
9940 (set_attr "mode" "QI")])
9942 (define_insn "*xorqi_cc_1"
9943 [(set (reg FLAGS_REG)
9945 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9946 (match_operand:QI 2 "general_operand" "qim,qi"))
9948 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9949 (xor:QI (match_dup 1) (match_dup 2)))]
9950 "ix86_match_ccmode (insn, CCNOmode)
9951 && ix86_binary_operator_ok (XOR, QImode, operands)"
9952 "xor{b}\t{%2, %0|%0, %2}"
9953 [(set_attr "type" "alu")
9954 (set_attr "mode" "QI")])
9956 (define_insn "*xorqi_2_slp"
9957 [(set (reg FLAGS_REG)
9958 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9959 (match_operand:QI 1 "general_operand" "qim,qi"))
9961 (set (strict_low_part (match_dup 0))
9962 (xor:QI (match_dup 0) (match_dup 1)))]
9963 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9964 && ix86_match_ccmode (insn, CCNOmode)
9965 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9966 "xor{b}\t{%1, %0|%0, %1}"
9967 [(set_attr "type" "alu1")
9968 (set_attr "mode" "QI")])
9970 (define_insn "*xorqi_cc_2"
9971 [(set (reg FLAGS_REG)
9973 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9974 (match_operand:QI 2 "general_operand" "qim"))
9976 (clobber (match_scratch:QI 0 "=q"))]
9977 "ix86_match_ccmode (insn, CCNOmode)
9978 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9979 "xor{b}\t{%2, %0|%0, %2}"
9980 [(set_attr "type" "alu")
9981 (set_attr "mode" "QI")])
9983 (define_insn "*xorqi_cc_ext_1"
9984 [(set (reg FLAGS_REG)
9988 (match_operand 1 "ext_register_operand" "0")
9991 (match_operand:QI 2 "general_operand" "qmn"))
9993 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9997 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9999 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10000 "xor{b}\t{%2, %h0|%h0, %2}"
10001 [(set_attr "type" "alu")
10002 (set_attr "mode" "QI")])
10004 (define_insn "*xorqi_cc_ext_1_rex64"
10005 [(set (reg FLAGS_REG)
10009 (match_operand 1 "ext_register_operand" "0")
10012 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10014 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10018 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10020 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10021 "xor{b}\t{%2, %h0|%h0, %2}"
10022 [(set_attr "type" "alu")
10023 (set_attr "mode" "QI")])
10025 (define_expand "xorqi_cc_ext_1"
10027 (set (reg:CCNO FLAGS_REG)
10031 (match_operand 1 "ext_register_operand" "")
10034 (match_operand:QI 2 "general_operand" ""))
10036 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10040 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10046 [(set (match_operand 0 "register_operand" "")
10047 (xor (match_operand 1 "register_operand" "")
10048 (match_operand 2 "const_int_operand" "")))
10049 (clobber (reg:CC FLAGS_REG))]
10051 && QI_REG_P (operands[0])
10052 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10053 && !(INTVAL (operands[2]) & ~(255 << 8))
10054 && GET_MODE (operands[0]) != QImode"
10055 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10056 (xor:SI (zero_extract:SI (match_dup 1)
10057 (const_int 8) (const_int 8))
10059 (clobber (reg:CC FLAGS_REG))])]
10060 "operands[0] = gen_lowpart (SImode, operands[0]);
10061 operands[1] = gen_lowpart (SImode, operands[1]);
10062 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10064 ;; Since XOR can be encoded with sign extended immediate, this is only
10065 ;; profitable when 7th bit is set.
10067 [(set (match_operand 0 "register_operand" "")
10068 (xor (match_operand 1 "general_operand" "")
10069 (match_operand 2 "const_int_operand" "")))
10070 (clobber (reg:CC FLAGS_REG))]
10072 && ANY_QI_REG_P (operands[0])
10073 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10074 && !(INTVAL (operands[2]) & ~255)
10075 && (INTVAL (operands[2]) & 128)
10076 && GET_MODE (operands[0]) != QImode"
10077 [(parallel [(set (strict_low_part (match_dup 0))
10078 (xor:QI (match_dup 1)
10080 (clobber (reg:CC FLAGS_REG))])]
10081 "operands[0] = gen_lowpart (QImode, operands[0]);
10082 operands[1] = gen_lowpart (QImode, operands[1]);
10083 operands[2] = gen_lowpart (QImode, operands[2]);")
10085 ;; Negation instructions
10087 (define_expand "negti2"
10088 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10089 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10090 (clobber (reg:CC FLAGS_REG))])]
10092 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10094 (define_insn "*negti2_1"
10095 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10096 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10097 (clobber (reg:CC FLAGS_REG))]
10099 && ix86_unary_operator_ok (NEG, TImode, operands)"
10103 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10104 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10105 (clobber (reg:CC FLAGS_REG))]
10106 "TARGET_64BIT && reload_completed"
10108 [(set (reg:CCZ FLAGS_REG)
10109 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10110 (set (match_dup 0) (neg:DI (match_dup 2)))])
10112 [(set (match_dup 1)
10113 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10116 (clobber (reg:CC FLAGS_REG))])
10118 [(set (match_dup 1)
10119 (neg:DI (match_dup 1)))
10120 (clobber (reg:CC FLAGS_REG))])]
10121 "split_ti (operands+1, 1, operands+2, operands+3);
10122 split_ti (operands+0, 1, operands+0, operands+1);")
10124 (define_expand "negdi2"
10125 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10126 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10127 (clobber (reg:CC FLAGS_REG))])]
10129 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10131 (define_insn "*negdi2_1"
10132 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10133 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10134 (clobber (reg:CC FLAGS_REG))]
10136 && ix86_unary_operator_ok (NEG, DImode, operands)"
10140 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10141 (neg:DI (match_operand:DI 1 "general_operand" "")))
10142 (clobber (reg:CC FLAGS_REG))]
10143 "!TARGET_64BIT && reload_completed"
10145 [(set (reg:CCZ FLAGS_REG)
10146 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10147 (set (match_dup 0) (neg:SI (match_dup 2)))])
10149 [(set (match_dup 1)
10150 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10153 (clobber (reg:CC FLAGS_REG))])
10155 [(set (match_dup 1)
10156 (neg:SI (match_dup 1)))
10157 (clobber (reg:CC FLAGS_REG))])]
10158 "split_di (operands+1, 1, operands+2, operands+3);
10159 split_di (operands+0, 1, operands+0, operands+1);")
10161 (define_insn "*negdi2_1_rex64"
10162 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10163 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10164 (clobber (reg:CC FLAGS_REG))]
10165 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10167 [(set_attr "type" "negnot")
10168 (set_attr "mode" "DI")])
10170 ;; The problem with neg is that it does not perform (compare x 0),
10171 ;; it really performs (compare 0 x), which leaves us with the zero
10172 ;; flag being the only useful item.
10174 (define_insn "*negdi2_cmpz_rex64"
10175 [(set (reg:CCZ FLAGS_REG)
10176 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10178 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10179 (neg:DI (match_dup 1)))]
10180 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10182 [(set_attr "type" "negnot")
10183 (set_attr "mode" "DI")])
10186 (define_expand "negsi2"
10187 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10188 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10189 (clobber (reg:CC FLAGS_REG))])]
10191 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10193 (define_insn "*negsi2_1"
10194 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10195 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10196 (clobber (reg:CC FLAGS_REG))]
10197 "ix86_unary_operator_ok (NEG, SImode, operands)"
10199 [(set_attr "type" "negnot")
10200 (set_attr "mode" "SI")])
10202 ;; Combine is quite creative about this pattern.
10203 (define_insn "*negsi2_1_zext"
10204 [(set (match_operand:DI 0 "register_operand" "=r")
10205 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10208 (clobber (reg:CC FLAGS_REG))]
10209 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10211 [(set_attr "type" "negnot")
10212 (set_attr "mode" "SI")])
10214 ;; The problem with neg is that it does not perform (compare x 0),
10215 ;; it really performs (compare 0 x), which leaves us with the zero
10216 ;; flag being the only useful item.
10218 (define_insn "*negsi2_cmpz"
10219 [(set (reg:CCZ FLAGS_REG)
10220 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10222 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10223 (neg:SI (match_dup 1)))]
10224 "ix86_unary_operator_ok (NEG, SImode, operands)"
10226 [(set_attr "type" "negnot")
10227 (set_attr "mode" "SI")])
10229 (define_insn "*negsi2_cmpz_zext"
10230 [(set (reg:CCZ FLAGS_REG)
10231 (compare:CCZ (lshiftrt:DI
10233 (match_operand:DI 1 "register_operand" "0")
10237 (set (match_operand:DI 0 "register_operand" "=r")
10238 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10241 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10243 [(set_attr "type" "negnot")
10244 (set_attr "mode" "SI")])
10246 (define_expand "neghi2"
10247 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10248 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10249 (clobber (reg:CC FLAGS_REG))])]
10250 "TARGET_HIMODE_MATH"
10251 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10253 (define_insn "*neghi2_1"
10254 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10255 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10256 (clobber (reg:CC FLAGS_REG))]
10257 "ix86_unary_operator_ok (NEG, HImode, operands)"
10259 [(set_attr "type" "negnot")
10260 (set_attr "mode" "HI")])
10262 (define_insn "*neghi2_cmpz"
10263 [(set (reg:CCZ FLAGS_REG)
10264 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10266 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10267 (neg:HI (match_dup 1)))]
10268 "ix86_unary_operator_ok (NEG, HImode, operands)"
10270 [(set_attr "type" "negnot")
10271 (set_attr "mode" "HI")])
10273 (define_expand "negqi2"
10274 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10275 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10276 (clobber (reg:CC FLAGS_REG))])]
10277 "TARGET_QIMODE_MATH"
10278 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10280 (define_insn "*negqi2_1"
10281 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10282 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10283 (clobber (reg:CC FLAGS_REG))]
10284 "ix86_unary_operator_ok (NEG, QImode, operands)"
10286 [(set_attr "type" "negnot")
10287 (set_attr "mode" "QI")])
10289 (define_insn "*negqi2_cmpz"
10290 [(set (reg:CCZ FLAGS_REG)
10291 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10293 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10294 (neg:QI (match_dup 1)))]
10295 "ix86_unary_operator_ok (NEG, QImode, operands)"
10297 [(set_attr "type" "negnot")
10298 (set_attr "mode" "QI")])
10300 ;; Changing of sign for FP values is doable using integer unit too.
10302 (define_expand "neg<mode>2"
10303 [(set (match_operand:X87MODEF 0 "register_operand" "")
10304 (neg: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 (NEG, <MODE>mode, operands); DONE;")
10308 (define_expand "abs<mode>2"
10309 [(set (match_operand:X87MODEF 0 "register_operand" "")
10310 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10311 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10312 "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10314 (define_insn "*absneg<mode>2_mixed"
10315 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10316 (match_operator:MODEF 3 "absneg_operator"
10317 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10318 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10319 (clobber (reg:CC FLAGS_REG))]
10320 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10323 (define_insn "*absneg<mode>2_sse"
10324 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10325 (match_operator:MODEF 3 "absneg_operator"
10326 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10327 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10328 (clobber (reg:CC FLAGS_REG))]
10329 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10332 (define_insn "*absneg<mode>2_i387"
10333 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10334 (match_operator:X87MODEF 3 "absneg_operator"
10335 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10336 (use (match_operand 2 "" ""))
10337 (clobber (reg:CC FLAGS_REG))]
10338 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10341 (define_expand "negtf2"
10342 [(set (match_operand:TF 0 "register_operand" "")
10343 (neg:TF (match_operand:TF 1 "register_operand" "")))]
10345 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10347 (define_expand "abstf2"
10348 [(set (match_operand:TF 0 "register_operand" "")
10349 (abs:TF (match_operand:TF 1 "register_operand" "")))]
10351 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10353 (define_insn "*absnegtf2_sse"
10354 [(set (match_operand:TF 0 "register_operand" "=x,x")
10355 (match_operator:TF 3 "absneg_operator"
10356 [(match_operand:TF 1 "register_operand" "0,x")]))
10357 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10358 (clobber (reg:CC FLAGS_REG))]
10362 ;; Splitters for fp abs and neg.
10365 [(set (match_operand 0 "fp_register_operand" "")
10366 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10367 (use (match_operand 2 "" ""))
10368 (clobber (reg:CC FLAGS_REG))]
10370 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10373 [(set (match_operand 0 "register_operand" "")
10374 (match_operator 3 "absneg_operator"
10375 [(match_operand 1 "register_operand" "")]))
10376 (use (match_operand 2 "nonimmediate_operand" ""))
10377 (clobber (reg:CC FLAGS_REG))]
10378 "reload_completed && SSE_REG_P (operands[0])"
10379 [(set (match_dup 0) (match_dup 3))]
10381 enum machine_mode mode = GET_MODE (operands[0]);
10382 enum machine_mode vmode = GET_MODE (operands[2]);
10385 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10386 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10387 if (operands_match_p (operands[0], operands[2]))
10390 operands[1] = operands[2];
10393 if (GET_CODE (operands[3]) == ABS)
10394 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10396 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10401 [(set (match_operand:SF 0 "register_operand" "")
10402 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10403 (use (match_operand:V4SF 2 "" ""))
10404 (clobber (reg:CC FLAGS_REG))]
10406 [(parallel [(set (match_dup 0) (match_dup 1))
10407 (clobber (reg:CC FLAGS_REG))])]
10410 operands[0] = gen_lowpart (SImode, operands[0]);
10411 if (GET_CODE (operands[1]) == ABS)
10413 tmp = gen_int_mode (0x7fffffff, SImode);
10414 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10418 tmp = gen_int_mode (0x80000000, SImode);
10419 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10425 [(set (match_operand:DF 0 "register_operand" "")
10426 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10427 (use (match_operand 2 "" ""))
10428 (clobber (reg:CC FLAGS_REG))]
10430 [(parallel [(set (match_dup 0) (match_dup 1))
10431 (clobber (reg:CC FLAGS_REG))])]
10436 tmp = gen_lowpart (DImode, operands[0]);
10437 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10440 if (GET_CODE (operands[1]) == ABS)
10443 tmp = gen_rtx_NOT (DImode, tmp);
10447 operands[0] = gen_highpart (SImode, operands[0]);
10448 if (GET_CODE (operands[1]) == ABS)
10450 tmp = gen_int_mode (0x7fffffff, SImode);
10451 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10455 tmp = gen_int_mode (0x80000000, SImode);
10456 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10463 [(set (match_operand:XF 0 "register_operand" "")
10464 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10465 (use (match_operand 2 "" ""))
10466 (clobber (reg:CC FLAGS_REG))]
10468 [(parallel [(set (match_dup 0) (match_dup 1))
10469 (clobber (reg:CC FLAGS_REG))])]
10472 operands[0] = gen_rtx_REG (SImode,
10473 true_regnum (operands[0])
10474 + (TARGET_64BIT ? 1 : 2));
10475 if (GET_CODE (operands[1]) == ABS)
10477 tmp = GEN_INT (0x7fff);
10478 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10482 tmp = GEN_INT (0x8000);
10483 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10488 ;; Conditionalize these after reload. If they match before reload, we
10489 ;; lose the clobber and ability to use integer instructions.
10491 (define_insn "*neg<mode>2_1"
10492 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10493 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10495 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10497 [(set_attr "type" "fsgn")
10498 (set_attr "mode" "<MODE>")])
10500 (define_insn "*abs<mode>2_1"
10501 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10502 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10504 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10506 [(set_attr "type" "fsgn")
10507 (set_attr "mode" "<MODE>")])
10509 (define_insn "*negextendsfdf2"
10510 [(set (match_operand:DF 0 "register_operand" "=f")
10511 (neg:DF (float_extend:DF
10512 (match_operand:SF 1 "register_operand" "0"))))]
10513 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10515 [(set_attr "type" "fsgn")
10516 (set_attr "mode" "DF")])
10518 (define_insn "*negextenddfxf2"
10519 [(set (match_operand:XF 0 "register_operand" "=f")
10520 (neg:XF (float_extend:XF
10521 (match_operand:DF 1 "register_operand" "0"))))]
10524 [(set_attr "type" "fsgn")
10525 (set_attr "mode" "XF")])
10527 (define_insn "*negextendsfxf2"
10528 [(set (match_operand:XF 0 "register_operand" "=f")
10529 (neg:XF (float_extend:XF
10530 (match_operand:SF 1 "register_operand" "0"))))]
10533 [(set_attr "type" "fsgn")
10534 (set_attr "mode" "XF")])
10536 (define_insn "*absextendsfdf2"
10537 [(set (match_operand:DF 0 "register_operand" "=f")
10538 (abs:DF (float_extend:DF
10539 (match_operand:SF 1 "register_operand" "0"))))]
10540 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10542 [(set_attr "type" "fsgn")
10543 (set_attr "mode" "DF")])
10545 (define_insn "*absextenddfxf2"
10546 [(set (match_operand:XF 0 "register_operand" "=f")
10547 (abs:XF (float_extend:XF
10548 (match_operand:DF 1 "register_operand" "0"))))]
10551 [(set_attr "type" "fsgn")
10552 (set_attr "mode" "XF")])
10554 (define_insn "*absextendsfxf2"
10555 [(set (match_operand:XF 0 "register_operand" "=f")
10556 (abs:XF (float_extend:XF
10557 (match_operand:SF 1 "register_operand" "0"))))]
10560 [(set_attr "type" "fsgn")
10561 (set_attr "mode" "XF")])
10563 ;; Copysign instructions
10565 (define_mode_iterator CSGNMODE [SF DF TF])
10566 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10568 (define_expand "copysign<mode>3"
10569 [(match_operand:CSGNMODE 0 "register_operand" "")
10570 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10571 (match_operand:CSGNMODE 2 "register_operand" "")]
10572 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10573 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10575 ix86_expand_copysign (operands);
10579 (define_insn_and_split "copysign<mode>3_const"
10580 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10582 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10583 (match_operand:CSGNMODE 2 "register_operand" "0")
10584 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10586 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10587 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10589 "&& reload_completed"
10592 ix86_split_copysign_const (operands);
10596 (define_insn "copysign<mode>3_var"
10597 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10599 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10600 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10601 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10602 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10604 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10605 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10606 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10610 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10612 [(match_operand:CSGNMODE 2 "register_operand" "")
10613 (match_operand:CSGNMODE 3 "register_operand" "")
10614 (match_operand:<CSGNVMODE> 4 "" "")
10615 (match_operand:<CSGNVMODE> 5 "" "")]
10617 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10618 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10619 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10620 && reload_completed"
10623 ix86_split_copysign_var (operands);
10627 ;; One complement instructions
10629 (define_expand "one_cmpldi2"
10630 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10631 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10633 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10635 (define_insn "*one_cmpldi2_1_rex64"
10636 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10637 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10638 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10640 [(set_attr "type" "negnot")
10641 (set_attr "mode" "DI")])
10643 (define_insn "*one_cmpldi2_2_rex64"
10644 [(set (reg FLAGS_REG)
10645 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10647 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10648 (not:DI (match_dup 1)))]
10649 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10650 && ix86_unary_operator_ok (NOT, DImode, operands)"
10652 [(set_attr "type" "alu1")
10653 (set_attr "mode" "DI")])
10656 [(set (match_operand 0 "flags_reg_operand" "")
10657 (match_operator 2 "compare_operator"
10658 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10660 (set (match_operand:DI 1 "nonimmediate_operand" "")
10661 (not:DI (match_dup 3)))]
10662 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10663 [(parallel [(set (match_dup 0)
10665 [(xor:DI (match_dup 3) (const_int -1))
10668 (xor:DI (match_dup 3) (const_int -1)))])]
10671 (define_expand "one_cmplsi2"
10672 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10673 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10675 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10677 (define_insn "*one_cmplsi2_1"
10678 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10679 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10680 "ix86_unary_operator_ok (NOT, SImode, operands)"
10682 [(set_attr "type" "negnot")
10683 (set_attr "mode" "SI")])
10685 ;; ??? Currently never generated - xor is used instead.
10686 (define_insn "*one_cmplsi2_1_zext"
10687 [(set (match_operand:DI 0 "register_operand" "=r")
10688 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10689 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10691 [(set_attr "type" "negnot")
10692 (set_attr "mode" "SI")])
10694 (define_insn "*one_cmplsi2_2"
10695 [(set (reg FLAGS_REG)
10696 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10698 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10699 (not:SI (match_dup 1)))]
10700 "ix86_match_ccmode (insn, CCNOmode)
10701 && ix86_unary_operator_ok (NOT, SImode, operands)"
10703 [(set_attr "type" "alu1")
10704 (set_attr "mode" "SI")])
10707 [(set (match_operand 0 "flags_reg_operand" "")
10708 (match_operator 2 "compare_operator"
10709 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10711 (set (match_operand:SI 1 "nonimmediate_operand" "")
10712 (not:SI (match_dup 3)))]
10713 "ix86_match_ccmode (insn, CCNOmode)"
10714 [(parallel [(set (match_dup 0)
10715 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10718 (xor:SI (match_dup 3) (const_int -1)))])]
10721 ;; ??? Currently never generated - xor is used instead.
10722 (define_insn "*one_cmplsi2_2_zext"
10723 [(set (reg FLAGS_REG)
10724 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10726 (set (match_operand:DI 0 "register_operand" "=r")
10727 (zero_extend:DI (not:SI (match_dup 1))))]
10728 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10729 && ix86_unary_operator_ok (NOT, SImode, operands)"
10731 [(set_attr "type" "alu1")
10732 (set_attr "mode" "SI")])
10735 [(set (match_operand 0 "flags_reg_operand" "")
10736 (match_operator 2 "compare_operator"
10737 [(not:SI (match_operand:SI 3 "register_operand" ""))
10739 (set (match_operand:DI 1 "register_operand" "")
10740 (zero_extend:DI (not:SI (match_dup 3))))]
10741 "ix86_match_ccmode (insn, CCNOmode)"
10742 [(parallel [(set (match_dup 0)
10743 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10746 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10749 (define_expand "one_cmplhi2"
10750 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10751 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10752 "TARGET_HIMODE_MATH"
10753 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10755 (define_insn "*one_cmplhi2_1"
10756 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10757 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10758 "ix86_unary_operator_ok (NOT, HImode, operands)"
10760 [(set_attr "type" "negnot")
10761 (set_attr "mode" "HI")])
10763 (define_insn "*one_cmplhi2_2"
10764 [(set (reg FLAGS_REG)
10765 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10767 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10768 (not:HI (match_dup 1)))]
10769 "ix86_match_ccmode (insn, CCNOmode)
10770 && ix86_unary_operator_ok (NEG, HImode, operands)"
10772 [(set_attr "type" "alu1")
10773 (set_attr "mode" "HI")])
10776 [(set (match_operand 0 "flags_reg_operand" "")
10777 (match_operator 2 "compare_operator"
10778 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10780 (set (match_operand:HI 1 "nonimmediate_operand" "")
10781 (not:HI (match_dup 3)))]
10782 "ix86_match_ccmode (insn, CCNOmode)"
10783 [(parallel [(set (match_dup 0)
10784 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10787 (xor:HI (match_dup 3) (const_int -1)))])]
10790 ;; %%% Potential partial reg stall on alternative 1. What to do?
10791 (define_expand "one_cmplqi2"
10792 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10793 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10794 "TARGET_QIMODE_MATH"
10795 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10797 (define_insn "*one_cmplqi2_1"
10798 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10799 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10800 "ix86_unary_operator_ok (NOT, QImode, operands)"
10804 [(set_attr "type" "negnot")
10805 (set_attr "mode" "QI,SI")])
10807 (define_insn "*one_cmplqi2_2"
10808 [(set (reg FLAGS_REG)
10809 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10811 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10812 (not:QI (match_dup 1)))]
10813 "ix86_match_ccmode (insn, CCNOmode)
10814 && ix86_unary_operator_ok (NOT, QImode, operands)"
10816 [(set_attr "type" "alu1")
10817 (set_attr "mode" "QI")])
10820 [(set (match_operand 0 "flags_reg_operand" "")
10821 (match_operator 2 "compare_operator"
10822 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10824 (set (match_operand:QI 1 "nonimmediate_operand" "")
10825 (not:QI (match_dup 3)))]
10826 "ix86_match_ccmode (insn, CCNOmode)"
10827 [(parallel [(set (match_dup 0)
10828 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10831 (xor:QI (match_dup 3) (const_int -1)))])]
10834 ;; Arithmetic shift instructions
10836 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10837 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10838 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10839 ;; from the assembler input.
10841 ;; This instruction shifts the target reg/mem as usual, but instead of
10842 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10843 ;; is a left shift double, bits are taken from the high order bits of
10844 ;; reg, else if the insn is a shift right double, bits are taken from the
10845 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10846 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10848 ;; Since sh[lr]d does not change the `reg' operand, that is done
10849 ;; separately, making all shifts emit pairs of shift double and normal
10850 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10851 ;; support a 63 bit shift, each shift where the count is in a reg expands
10852 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10854 ;; If the shift count is a constant, we need never emit more than one
10855 ;; shift pair, instead using moves and sign extension for counts greater
10858 (define_expand "ashlti3"
10859 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10860 (ashift:TI (match_operand:TI 1 "register_operand" "")
10861 (match_operand:QI 2 "nonmemory_operand" "")))
10862 (clobber (reg:CC FLAGS_REG))])]
10865 if (! immediate_operand (operands[2], QImode))
10867 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10870 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10874 (define_insn "ashlti3_1"
10875 [(set (match_operand:TI 0 "register_operand" "=r")
10876 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10877 (match_operand:QI 2 "register_operand" "c")))
10878 (clobber (match_scratch:DI 3 "=&r"))
10879 (clobber (reg:CC FLAGS_REG))]
10882 [(set_attr "type" "multi")])
10884 ;; This pattern must be defined before *ashlti3_2 to prevent
10885 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10887 (define_insn "sse2_ashlti3"
10888 [(set (match_operand:TI 0 "register_operand" "=x")
10889 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10890 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10893 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10894 return "pslldq\t{%2, %0|%0, %2}";
10896 [(set_attr "type" "sseishft")
10897 (set_attr "prefix_data16" "1")
10898 (set_attr "mode" "TI")])
10900 (define_insn "*ashlti3_2"
10901 [(set (match_operand:TI 0 "register_operand" "=r")
10902 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10903 (match_operand:QI 2 "immediate_operand" "O")))
10904 (clobber (reg:CC FLAGS_REG))]
10907 [(set_attr "type" "multi")])
10910 [(set (match_operand:TI 0 "register_operand" "")
10911 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10912 (match_operand:QI 2 "register_operand" "")))
10913 (clobber (match_scratch:DI 3 ""))
10914 (clobber (reg:CC FLAGS_REG))]
10915 "TARGET_64BIT && reload_completed"
10917 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10920 [(set (match_operand:TI 0 "register_operand" "")
10921 (ashift:TI (match_operand:TI 1 "register_operand" "")
10922 (match_operand:QI 2 "immediate_operand" "")))
10923 (clobber (reg:CC FLAGS_REG))]
10924 "TARGET_64BIT && reload_completed"
10926 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10928 (define_insn "x86_64_shld"
10929 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10930 (ior:DI (ashift:DI (match_dup 0)
10931 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10932 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10933 (minus:QI (const_int 64) (match_dup 2)))))
10934 (clobber (reg:CC FLAGS_REG))]
10937 shld{q}\t{%2, %1, %0|%0, %1, %2}
10938 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10939 [(set_attr "type" "ishift")
10940 (set_attr "prefix_0f" "1")
10941 (set_attr "mode" "DI")
10942 (set_attr "athlon_decode" "vector")
10943 (set_attr "amdfam10_decode" "vector")])
10945 (define_expand "x86_64_shift_adj"
10946 [(set (reg:CCZ FLAGS_REG)
10947 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10950 (set (match_operand:DI 0 "register_operand" "")
10951 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10952 (match_operand:DI 1 "register_operand" "")
10955 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10956 (match_operand:DI 3 "register_operand" "r")
10961 (define_expand "ashldi3"
10962 [(set (match_operand:DI 0 "shiftdi_operand" "")
10963 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10964 (match_operand:QI 2 "nonmemory_operand" "")))]
10966 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10968 (define_insn "*ashldi3_1_rex64"
10969 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10970 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10971 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10972 (clobber (reg:CC FLAGS_REG))]
10973 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10975 switch (get_attr_type (insn))
10978 gcc_assert (operands[2] == const1_rtx);
10979 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10980 return "add{q}\t%0, %0";
10983 gcc_assert (CONST_INT_P (operands[2]));
10984 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10985 operands[1] = gen_rtx_MULT (DImode, operands[1],
10986 GEN_INT (1 << INTVAL (operands[2])));
10987 return "lea{q}\t{%a1, %0|%0, %a1}";
10990 if (REG_P (operands[2]))
10991 return "sal{q}\t{%b2, %0|%0, %b2}";
10992 else if (operands[2] == const1_rtx
10993 && (TARGET_SHIFT1 || optimize_size))
10994 return "sal{q}\t%0";
10996 return "sal{q}\t{%2, %0|%0, %2}";
10999 [(set (attr "type")
11000 (cond [(eq_attr "alternative" "1")
11001 (const_string "lea")
11002 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11004 (match_operand 0 "register_operand" ""))
11005 (match_operand 2 "const1_operand" ""))
11006 (const_string "alu")
11008 (const_string "ishift")))
11009 (set_attr "mode" "DI")])
11011 ;; Convert lea to the lea pattern to avoid flags dependency.
11013 [(set (match_operand:DI 0 "register_operand" "")
11014 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11015 (match_operand:QI 2 "immediate_operand" "")))
11016 (clobber (reg:CC FLAGS_REG))]
11017 "TARGET_64BIT && reload_completed
11018 && true_regnum (operands[0]) != true_regnum (operands[1])"
11019 [(set (match_dup 0)
11020 (mult:DI (match_dup 1)
11022 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11024 ;; This pattern can't accept a variable shift count, since shifts by
11025 ;; zero don't affect the flags. We assume that shifts by constant
11026 ;; zero are optimized away.
11027 (define_insn "*ashldi3_cmp_rex64"
11028 [(set (reg FLAGS_REG)
11030 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11031 (match_operand:QI 2 "immediate_operand" "e"))
11033 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11034 (ashift:DI (match_dup 1) (match_dup 2)))]
11037 || !TARGET_PARTIAL_FLAG_REG_STALL
11038 || (operands[2] == const1_rtx
11040 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11041 && ix86_match_ccmode (insn, CCGOCmode)
11042 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11044 switch (get_attr_type (insn))
11047 gcc_assert (operands[2] == const1_rtx);
11048 return "add{q}\t%0, %0";
11051 if (REG_P (operands[2]))
11052 return "sal{q}\t{%b2, %0|%0, %b2}";
11053 else if (operands[2] == const1_rtx
11054 && (TARGET_SHIFT1 || optimize_size))
11055 return "sal{q}\t%0";
11057 return "sal{q}\t{%2, %0|%0, %2}";
11060 [(set (attr "type")
11061 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11063 (match_operand 0 "register_operand" ""))
11064 (match_operand 2 "const1_operand" ""))
11065 (const_string "alu")
11067 (const_string "ishift")))
11068 (set_attr "mode" "DI")])
11070 (define_insn "*ashldi3_cconly_rex64"
11071 [(set (reg FLAGS_REG)
11073 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11074 (match_operand:QI 2 "immediate_operand" "e"))
11076 (clobber (match_scratch:DI 0 "=r"))]
11079 || !TARGET_PARTIAL_FLAG_REG_STALL
11080 || (operands[2] == const1_rtx
11082 || TARGET_DOUBLE_WITH_ADD)))
11083 && ix86_match_ccmode (insn, CCGOCmode)
11084 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11086 switch (get_attr_type (insn))
11089 gcc_assert (operands[2] == const1_rtx);
11090 return "add{q}\t%0, %0";
11093 if (REG_P (operands[2]))
11094 return "sal{q}\t{%b2, %0|%0, %b2}";
11095 else if (operands[2] == const1_rtx
11096 && (TARGET_SHIFT1 || optimize_size))
11097 return "sal{q}\t%0";
11099 return "sal{q}\t{%2, %0|%0, %2}";
11102 [(set (attr "type")
11103 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11105 (match_operand 0 "register_operand" ""))
11106 (match_operand 2 "const1_operand" ""))
11107 (const_string "alu")
11109 (const_string "ishift")))
11110 (set_attr "mode" "DI")])
11112 (define_insn "*ashldi3_1"
11113 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11114 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11115 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11116 (clobber (reg:CC FLAGS_REG))]
11119 [(set_attr "type" "multi")])
11121 ;; By default we don't ask for a scratch register, because when DImode
11122 ;; values are manipulated, registers are already at a premium. But if
11123 ;; we have one handy, we won't turn it away.
11125 [(match_scratch:SI 3 "r")
11126 (parallel [(set (match_operand:DI 0 "register_operand" "")
11127 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11128 (match_operand:QI 2 "nonmemory_operand" "")))
11129 (clobber (reg:CC FLAGS_REG))])
11131 "!TARGET_64BIT && TARGET_CMOVE"
11133 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11136 [(set (match_operand:DI 0 "register_operand" "")
11137 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11138 (match_operand:QI 2 "nonmemory_operand" "")))
11139 (clobber (reg:CC FLAGS_REG))]
11140 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11141 ? epilogue_completed : reload_completed)"
11143 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11145 (define_insn "x86_shld_1"
11146 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11147 (ior:SI (ashift:SI (match_dup 0)
11148 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11149 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11150 (minus:QI (const_int 32) (match_dup 2)))))
11151 (clobber (reg:CC FLAGS_REG))]
11154 shld{l}\t{%2, %1, %0|%0, %1, %2}
11155 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11156 [(set_attr "type" "ishift")
11157 (set_attr "prefix_0f" "1")
11158 (set_attr "mode" "SI")
11159 (set_attr "pent_pair" "np")
11160 (set_attr "athlon_decode" "vector")
11161 (set_attr "amdfam10_decode" "vector")])
11163 (define_expand "x86_shift_adj_1"
11164 [(set (reg:CCZ FLAGS_REG)
11165 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11168 (set (match_operand:SI 0 "register_operand" "")
11169 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11170 (match_operand:SI 1 "register_operand" "")
11173 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11174 (match_operand:SI 3 "register_operand" "r")
11179 (define_expand "x86_shift_adj_2"
11180 [(use (match_operand:SI 0 "register_operand" ""))
11181 (use (match_operand:SI 1 "register_operand" ""))
11182 (use (match_operand:QI 2 "register_operand" ""))]
11185 rtx label = gen_label_rtx ();
11188 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11190 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11191 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11192 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11193 gen_rtx_LABEL_REF (VOIDmode, label),
11195 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11196 JUMP_LABEL (tmp) = label;
11198 emit_move_insn (operands[0], operands[1]);
11199 ix86_expand_clear (operands[1]);
11201 emit_label (label);
11202 LABEL_NUSES (label) = 1;
11207 (define_expand "ashlsi3"
11208 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11209 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11210 (match_operand:QI 2 "nonmemory_operand" "")))
11211 (clobber (reg:CC FLAGS_REG))]
11213 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11215 (define_insn "*ashlsi3_1"
11216 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11217 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11218 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11219 (clobber (reg:CC FLAGS_REG))]
11220 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11222 switch (get_attr_type (insn))
11225 gcc_assert (operands[2] == const1_rtx);
11226 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11227 return "add{l}\t%0, %0";
11233 if (REG_P (operands[2]))
11234 return "sal{l}\t{%b2, %0|%0, %b2}";
11235 else if (operands[2] == const1_rtx
11236 && (TARGET_SHIFT1 || optimize_size))
11237 return "sal{l}\t%0";
11239 return "sal{l}\t{%2, %0|%0, %2}";
11242 [(set (attr "type")
11243 (cond [(eq_attr "alternative" "1")
11244 (const_string "lea")
11245 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11247 (match_operand 0 "register_operand" ""))
11248 (match_operand 2 "const1_operand" ""))
11249 (const_string "alu")
11251 (const_string "ishift")))
11252 (set_attr "mode" "SI")])
11254 ;; Convert lea to the lea pattern to avoid flags dependency.
11256 [(set (match_operand 0 "register_operand" "")
11257 (ashift (match_operand 1 "index_register_operand" "")
11258 (match_operand:QI 2 "const_int_operand" "")))
11259 (clobber (reg:CC FLAGS_REG))]
11261 && true_regnum (operands[0]) != true_regnum (operands[1])
11262 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11266 enum machine_mode mode = GET_MODE (operands[0]);
11268 if (GET_MODE_SIZE (mode) < 4)
11269 operands[0] = gen_lowpart (SImode, operands[0]);
11271 operands[1] = gen_lowpart (Pmode, operands[1]);
11272 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11274 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11275 if (Pmode != SImode)
11276 pat = gen_rtx_SUBREG (SImode, pat, 0);
11277 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11281 ;; Rare case of shifting RSP is handled by generating move and shift
11283 [(set (match_operand 0 "register_operand" "")
11284 (ashift (match_operand 1 "register_operand" "")
11285 (match_operand:QI 2 "const_int_operand" "")))
11286 (clobber (reg:CC FLAGS_REG))]
11288 && true_regnum (operands[0]) != true_regnum (operands[1])"
11292 emit_move_insn (operands[0], operands[1]);
11293 pat = gen_rtx_SET (VOIDmode, operands[0],
11294 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11295 operands[0], operands[2]));
11296 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11297 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11301 (define_insn "*ashlsi3_1_zext"
11302 [(set (match_operand:DI 0 "register_operand" "=r,r")
11303 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11304 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11305 (clobber (reg:CC FLAGS_REG))]
11306 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11308 switch (get_attr_type (insn))
11311 gcc_assert (operands[2] == const1_rtx);
11312 return "add{l}\t%k0, %k0";
11318 if (REG_P (operands[2]))
11319 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11320 else if (operands[2] == const1_rtx
11321 && (TARGET_SHIFT1 || optimize_size))
11322 return "sal{l}\t%k0";
11324 return "sal{l}\t{%2, %k0|%k0, %2}";
11327 [(set (attr "type")
11328 (cond [(eq_attr "alternative" "1")
11329 (const_string "lea")
11330 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11332 (match_operand 2 "const1_operand" ""))
11333 (const_string "alu")
11335 (const_string "ishift")))
11336 (set_attr "mode" "SI")])
11338 ;; Convert lea to the lea pattern to avoid flags dependency.
11340 [(set (match_operand:DI 0 "register_operand" "")
11341 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11342 (match_operand:QI 2 "const_int_operand" ""))))
11343 (clobber (reg:CC FLAGS_REG))]
11344 "TARGET_64BIT && reload_completed
11345 && true_regnum (operands[0]) != true_regnum (operands[1])"
11346 [(set (match_dup 0) (zero_extend:DI
11347 (subreg:SI (mult:SI (match_dup 1)
11348 (match_dup 2)) 0)))]
11350 operands[1] = gen_lowpart (Pmode, operands[1]);
11351 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11354 ;; This pattern can't accept a variable shift count, since shifts by
11355 ;; zero don't affect the flags. We assume that shifts by constant
11356 ;; zero are optimized away.
11357 (define_insn "*ashlsi3_cmp"
11358 [(set (reg FLAGS_REG)
11360 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11361 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11363 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11364 (ashift:SI (match_dup 1) (match_dup 2)))]
11366 || !TARGET_PARTIAL_FLAG_REG_STALL
11367 || (operands[2] == const1_rtx
11369 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11370 && ix86_match_ccmode (insn, CCGOCmode)
11371 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11373 switch (get_attr_type (insn))
11376 gcc_assert (operands[2] == const1_rtx);
11377 return "add{l}\t%0, %0";
11380 if (REG_P (operands[2]))
11381 return "sal{l}\t{%b2, %0|%0, %b2}";
11382 else if (operands[2] == const1_rtx
11383 && (TARGET_SHIFT1 || optimize_size))
11384 return "sal{l}\t%0";
11386 return "sal{l}\t{%2, %0|%0, %2}";
11389 [(set (attr "type")
11390 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11392 (match_operand 0 "register_operand" ""))
11393 (match_operand 2 "const1_operand" ""))
11394 (const_string "alu")
11396 (const_string "ishift")))
11397 (set_attr "mode" "SI")])
11399 (define_insn "*ashlsi3_cconly"
11400 [(set (reg FLAGS_REG)
11402 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11403 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11405 (clobber (match_scratch:SI 0 "=r"))]
11407 || !TARGET_PARTIAL_FLAG_REG_STALL
11408 || (operands[2] == const1_rtx
11410 || TARGET_DOUBLE_WITH_ADD)))
11411 && ix86_match_ccmode (insn, CCGOCmode)
11412 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11414 switch (get_attr_type (insn))
11417 gcc_assert (operands[2] == const1_rtx);
11418 return "add{l}\t%0, %0";
11421 if (REG_P (operands[2]))
11422 return "sal{l}\t{%b2, %0|%0, %b2}";
11423 else if (operands[2] == const1_rtx
11424 && (TARGET_SHIFT1 || optimize_size))
11425 return "sal{l}\t%0";
11427 return "sal{l}\t{%2, %0|%0, %2}";
11430 [(set (attr "type")
11431 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11433 (match_operand 0 "register_operand" ""))
11434 (match_operand 2 "const1_operand" ""))
11435 (const_string "alu")
11437 (const_string "ishift")))
11438 (set_attr "mode" "SI")])
11440 (define_insn "*ashlsi3_cmp_zext"
11441 [(set (reg FLAGS_REG)
11443 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11444 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11446 (set (match_operand:DI 0 "register_operand" "=r")
11447 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11450 || !TARGET_PARTIAL_FLAG_REG_STALL
11451 || (operands[2] == const1_rtx
11453 || TARGET_DOUBLE_WITH_ADD)))
11454 && ix86_match_ccmode (insn, CCGOCmode)
11455 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11457 switch (get_attr_type (insn))
11460 gcc_assert (operands[2] == const1_rtx);
11461 return "add{l}\t%k0, %k0";
11464 if (REG_P (operands[2]))
11465 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11466 else if (operands[2] == const1_rtx
11467 && (TARGET_SHIFT1 || optimize_size))
11468 return "sal{l}\t%k0";
11470 return "sal{l}\t{%2, %k0|%k0, %2}";
11473 [(set (attr "type")
11474 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11476 (match_operand 2 "const1_operand" ""))
11477 (const_string "alu")
11479 (const_string "ishift")))
11480 (set_attr "mode" "SI")])
11482 (define_expand "ashlhi3"
11483 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11484 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11485 (match_operand:QI 2 "nonmemory_operand" "")))
11486 (clobber (reg:CC FLAGS_REG))]
11487 "TARGET_HIMODE_MATH"
11488 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11490 (define_insn "*ashlhi3_1_lea"
11491 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11492 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11493 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11494 (clobber (reg:CC FLAGS_REG))]
11495 "!TARGET_PARTIAL_REG_STALL
11496 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11498 switch (get_attr_type (insn))
11503 gcc_assert (operands[2] == const1_rtx);
11504 return "add{w}\t%0, %0";
11507 if (REG_P (operands[2]))
11508 return "sal{w}\t{%b2, %0|%0, %b2}";
11509 else if (operands[2] == const1_rtx
11510 && (TARGET_SHIFT1 || optimize_size))
11511 return "sal{w}\t%0";
11513 return "sal{w}\t{%2, %0|%0, %2}";
11516 [(set (attr "type")
11517 (cond [(eq_attr "alternative" "1")
11518 (const_string "lea")
11519 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11521 (match_operand 0 "register_operand" ""))
11522 (match_operand 2 "const1_operand" ""))
11523 (const_string "alu")
11525 (const_string "ishift")))
11526 (set_attr "mode" "HI,SI")])
11528 (define_insn "*ashlhi3_1"
11529 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11530 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11531 (match_operand:QI 2 "nonmemory_operand" "cI")))
11532 (clobber (reg:CC FLAGS_REG))]
11533 "TARGET_PARTIAL_REG_STALL
11534 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11536 switch (get_attr_type (insn))
11539 gcc_assert (operands[2] == const1_rtx);
11540 return "add{w}\t%0, %0";
11543 if (REG_P (operands[2]))
11544 return "sal{w}\t{%b2, %0|%0, %b2}";
11545 else if (operands[2] == const1_rtx
11546 && (TARGET_SHIFT1 || optimize_size))
11547 return "sal{w}\t%0";
11549 return "sal{w}\t{%2, %0|%0, %2}";
11552 [(set (attr "type")
11553 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11555 (match_operand 0 "register_operand" ""))
11556 (match_operand 2 "const1_operand" ""))
11557 (const_string "alu")
11559 (const_string "ishift")))
11560 (set_attr "mode" "HI")])
11562 ;; This pattern can't accept a variable shift count, since shifts by
11563 ;; zero don't affect the flags. We assume that shifts by constant
11564 ;; zero are optimized away.
11565 (define_insn "*ashlhi3_cmp"
11566 [(set (reg FLAGS_REG)
11568 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11569 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11571 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11572 (ashift:HI (match_dup 1) (match_dup 2)))]
11574 || !TARGET_PARTIAL_FLAG_REG_STALL
11575 || (operands[2] == const1_rtx
11577 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11578 && ix86_match_ccmode (insn, CCGOCmode)
11579 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11581 switch (get_attr_type (insn))
11584 gcc_assert (operands[2] == const1_rtx);
11585 return "add{w}\t%0, %0";
11588 if (REG_P (operands[2]))
11589 return "sal{w}\t{%b2, %0|%0, %b2}";
11590 else if (operands[2] == const1_rtx
11591 && (TARGET_SHIFT1 || optimize_size))
11592 return "sal{w}\t%0";
11594 return "sal{w}\t{%2, %0|%0, %2}";
11597 [(set (attr "type")
11598 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11600 (match_operand 0 "register_operand" ""))
11601 (match_operand 2 "const1_operand" ""))
11602 (const_string "alu")
11604 (const_string "ishift")))
11605 (set_attr "mode" "HI")])
11607 (define_insn "*ashlhi3_cconly"
11608 [(set (reg FLAGS_REG)
11610 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11611 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11613 (clobber (match_scratch:HI 0 "=r"))]
11615 || !TARGET_PARTIAL_FLAG_REG_STALL
11616 || (operands[2] == const1_rtx
11618 || TARGET_DOUBLE_WITH_ADD)))
11619 && ix86_match_ccmode (insn, CCGOCmode)
11620 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11622 switch (get_attr_type (insn))
11625 gcc_assert (operands[2] == const1_rtx);
11626 return "add{w}\t%0, %0";
11629 if (REG_P (operands[2]))
11630 return "sal{w}\t{%b2, %0|%0, %b2}";
11631 else if (operands[2] == const1_rtx
11632 && (TARGET_SHIFT1 || optimize_size))
11633 return "sal{w}\t%0";
11635 return "sal{w}\t{%2, %0|%0, %2}";
11638 [(set (attr "type")
11639 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11641 (match_operand 0 "register_operand" ""))
11642 (match_operand 2 "const1_operand" ""))
11643 (const_string "alu")
11645 (const_string "ishift")))
11646 (set_attr "mode" "HI")])
11648 (define_expand "ashlqi3"
11649 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11650 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11651 (match_operand:QI 2 "nonmemory_operand" "")))
11652 (clobber (reg:CC FLAGS_REG))]
11653 "TARGET_QIMODE_MATH"
11654 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11656 ;; %%% Potential partial reg stall on alternative 2. What to do?
11658 (define_insn "*ashlqi3_1_lea"
11659 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11660 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11661 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11662 (clobber (reg:CC FLAGS_REG))]
11663 "!TARGET_PARTIAL_REG_STALL
11664 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11666 switch (get_attr_type (insn))
11671 gcc_assert (operands[2] == const1_rtx);
11672 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11673 return "add{l}\t%k0, %k0";
11675 return "add{b}\t%0, %0";
11678 if (REG_P (operands[2]))
11680 if (get_attr_mode (insn) == MODE_SI)
11681 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11683 return "sal{b}\t{%b2, %0|%0, %b2}";
11685 else if (operands[2] == const1_rtx
11686 && (TARGET_SHIFT1 || optimize_size))
11688 if (get_attr_mode (insn) == MODE_SI)
11689 return "sal{l}\t%0";
11691 return "sal{b}\t%0";
11695 if (get_attr_mode (insn) == MODE_SI)
11696 return "sal{l}\t{%2, %k0|%k0, %2}";
11698 return "sal{b}\t{%2, %0|%0, %2}";
11702 [(set (attr "type")
11703 (cond [(eq_attr "alternative" "2")
11704 (const_string "lea")
11705 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11707 (match_operand 0 "register_operand" ""))
11708 (match_operand 2 "const1_operand" ""))
11709 (const_string "alu")
11711 (const_string "ishift")))
11712 (set_attr "mode" "QI,SI,SI")])
11714 (define_insn "*ashlqi3_1"
11715 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11716 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11717 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11718 (clobber (reg:CC FLAGS_REG))]
11719 "TARGET_PARTIAL_REG_STALL
11720 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11722 switch (get_attr_type (insn))
11725 gcc_assert (operands[2] == const1_rtx);
11726 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11727 return "add{l}\t%k0, %k0";
11729 return "add{b}\t%0, %0";
11732 if (REG_P (operands[2]))
11734 if (get_attr_mode (insn) == MODE_SI)
11735 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11737 return "sal{b}\t{%b2, %0|%0, %b2}";
11739 else if (operands[2] == const1_rtx
11740 && (TARGET_SHIFT1 || optimize_size))
11742 if (get_attr_mode (insn) == MODE_SI)
11743 return "sal{l}\t%0";
11745 return "sal{b}\t%0";
11749 if (get_attr_mode (insn) == MODE_SI)
11750 return "sal{l}\t{%2, %k0|%k0, %2}";
11752 return "sal{b}\t{%2, %0|%0, %2}";
11756 [(set (attr "type")
11757 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11759 (match_operand 0 "register_operand" ""))
11760 (match_operand 2 "const1_operand" ""))
11761 (const_string "alu")
11763 (const_string "ishift")))
11764 (set_attr "mode" "QI,SI")])
11766 ;; This pattern can't accept a variable shift count, since shifts by
11767 ;; zero don't affect the flags. We assume that shifts by constant
11768 ;; zero are optimized away.
11769 (define_insn "*ashlqi3_cmp"
11770 [(set (reg FLAGS_REG)
11772 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11773 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11775 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11776 (ashift:QI (match_dup 1) (match_dup 2)))]
11778 || !TARGET_PARTIAL_FLAG_REG_STALL
11779 || (operands[2] == const1_rtx
11781 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11782 && ix86_match_ccmode (insn, CCGOCmode)
11783 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11785 switch (get_attr_type (insn))
11788 gcc_assert (operands[2] == const1_rtx);
11789 return "add{b}\t%0, %0";
11792 if (REG_P (operands[2]))
11793 return "sal{b}\t{%b2, %0|%0, %b2}";
11794 else if (operands[2] == const1_rtx
11795 && (TARGET_SHIFT1 || optimize_size))
11796 return "sal{b}\t%0";
11798 return "sal{b}\t{%2, %0|%0, %2}";
11801 [(set (attr "type")
11802 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11804 (match_operand 0 "register_operand" ""))
11805 (match_operand 2 "const1_operand" ""))
11806 (const_string "alu")
11808 (const_string "ishift")))
11809 (set_attr "mode" "QI")])
11811 (define_insn "*ashlqi3_cconly"
11812 [(set (reg FLAGS_REG)
11814 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11815 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11817 (clobber (match_scratch:QI 0 "=q"))]
11819 || !TARGET_PARTIAL_FLAG_REG_STALL
11820 || (operands[2] == const1_rtx
11822 || TARGET_DOUBLE_WITH_ADD)))
11823 && ix86_match_ccmode (insn, CCGOCmode)
11824 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11826 switch (get_attr_type (insn))
11829 gcc_assert (operands[2] == const1_rtx);
11830 return "add{b}\t%0, %0";
11833 if (REG_P (operands[2]))
11834 return "sal{b}\t{%b2, %0|%0, %b2}";
11835 else if (operands[2] == const1_rtx
11836 && (TARGET_SHIFT1 || optimize_size))
11837 return "sal{b}\t%0";
11839 return "sal{b}\t{%2, %0|%0, %2}";
11842 [(set (attr "type")
11843 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11845 (match_operand 0 "register_operand" ""))
11846 (match_operand 2 "const1_operand" ""))
11847 (const_string "alu")
11849 (const_string "ishift")))
11850 (set_attr "mode" "QI")])
11852 ;; See comment above `ashldi3' about how this works.
11854 (define_expand "ashrti3"
11855 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11856 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11857 (match_operand:QI 2 "nonmemory_operand" "")))
11858 (clobber (reg:CC FLAGS_REG))])]
11861 if (! immediate_operand (operands[2], QImode))
11863 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11866 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11870 (define_insn "ashrti3_1"
11871 [(set (match_operand:TI 0 "register_operand" "=r")
11872 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11873 (match_operand:QI 2 "register_operand" "c")))
11874 (clobber (match_scratch:DI 3 "=&r"))
11875 (clobber (reg:CC FLAGS_REG))]
11878 [(set_attr "type" "multi")])
11880 (define_insn "*ashrti3_2"
11881 [(set (match_operand:TI 0 "register_operand" "=r")
11882 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11883 (match_operand:QI 2 "immediate_operand" "O")))
11884 (clobber (reg:CC FLAGS_REG))]
11887 [(set_attr "type" "multi")])
11890 [(set (match_operand:TI 0 "register_operand" "")
11891 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11892 (match_operand:QI 2 "register_operand" "")))
11893 (clobber (match_scratch:DI 3 ""))
11894 (clobber (reg:CC FLAGS_REG))]
11895 "TARGET_64BIT && reload_completed"
11897 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11900 [(set (match_operand:TI 0 "register_operand" "")
11901 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11902 (match_operand:QI 2 "immediate_operand" "")))
11903 (clobber (reg:CC FLAGS_REG))]
11904 "TARGET_64BIT && reload_completed"
11906 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11908 (define_insn "x86_64_shrd"
11909 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11910 (ior:DI (ashiftrt:DI (match_dup 0)
11911 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11912 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11913 (minus:QI (const_int 64) (match_dup 2)))))
11914 (clobber (reg:CC FLAGS_REG))]
11917 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11918 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11919 [(set_attr "type" "ishift")
11920 (set_attr "prefix_0f" "1")
11921 (set_attr "mode" "DI")
11922 (set_attr "athlon_decode" "vector")
11923 (set_attr "amdfam10_decode" "vector")])
11925 (define_expand "ashrdi3"
11926 [(set (match_operand:DI 0 "shiftdi_operand" "")
11927 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11928 (match_operand:QI 2 "nonmemory_operand" "")))]
11930 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11932 (define_insn "*ashrdi3_63_rex64"
11933 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11934 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11935 (match_operand:DI 2 "const_int_operand" "i,i")))
11936 (clobber (reg:CC FLAGS_REG))]
11937 "TARGET_64BIT && INTVAL (operands[2]) == 63
11938 && (TARGET_USE_CLTD || optimize_size)
11939 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11942 sar{q}\t{%2, %0|%0, %2}"
11943 [(set_attr "type" "imovx,ishift")
11944 (set_attr "prefix_0f" "0,*")
11945 (set_attr "length_immediate" "0,*")
11946 (set_attr "modrm" "0,1")
11947 (set_attr "mode" "DI")])
11949 (define_insn "*ashrdi3_1_one_bit_rex64"
11950 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11951 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11952 (match_operand:QI 2 "const1_operand" "")))
11953 (clobber (reg:CC FLAGS_REG))]
11955 && (TARGET_SHIFT1 || optimize_size)
11956 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11958 [(set_attr "type" "ishift")
11959 (set (attr "length")
11960 (if_then_else (match_operand:DI 0 "register_operand" "")
11962 (const_string "*")))])
11964 (define_insn "*ashrdi3_1_rex64"
11965 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11966 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11967 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11968 (clobber (reg:CC FLAGS_REG))]
11969 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11971 sar{q}\t{%2, %0|%0, %2}
11972 sar{q}\t{%b2, %0|%0, %b2}"
11973 [(set_attr "type" "ishift")
11974 (set_attr "mode" "DI")])
11976 ;; This pattern can't accept a variable shift count, since shifts by
11977 ;; zero don't affect the flags. We assume that shifts by constant
11978 ;; zero are optimized away.
11979 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11980 [(set (reg FLAGS_REG)
11982 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11983 (match_operand:QI 2 "const1_operand" ""))
11985 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11986 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11988 && (TARGET_SHIFT1 || optimize_size)
11989 && ix86_match_ccmode (insn, CCGOCmode)
11990 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11992 [(set_attr "type" "ishift")
11993 (set (attr "length")
11994 (if_then_else (match_operand:DI 0 "register_operand" "")
11996 (const_string "*")))])
11998 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11999 [(set (reg FLAGS_REG)
12001 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12002 (match_operand:QI 2 "const1_operand" ""))
12004 (clobber (match_scratch:DI 0 "=r"))]
12006 && (TARGET_SHIFT1 || optimize_size)
12007 && ix86_match_ccmode (insn, CCGOCmode)
12008 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12010 [(set_attr "type" "ishift")
12011 (set_attr "length" "2")])
12013 ;; This pattern can't accept a variable shift count, since shifts by
12014 ;; zero don't affect the flags. We assume that shifts by constant
12015 ;; zero are optimized away.
12016 (define_insn "*ashrdi3_cmp_rex64"
12017 [(set (reg FLAGS_REG)
12019 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12020 (match_operand:QI 2 "const_int_operand" "n"))
12022 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12023 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12025 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12026 && ix86_match_ccmode (insn, CCGOCmode)
12027 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12028 "sar{q}\t{%2, %0|%0, %2}"
12029 [(set_attr "type" "ishift")
12030 (set_attr "mode" "DI")])
12032 (define_insn "*ashrdi3_cconly_rex64"
12033 [(set (reg FLAGS_REG)
12035 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12036 (match_operand:QI 2 "const_int_operand" "n"))
12038 (clobber (match_scratch:DI 0 "=r"))]
12040 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12041 && ix86_match_ccmode (insn, CCGOCmode)
12042 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12043 "sar{q}\t{%2, %0|%0, %2}"
12044 [(set_attr "type" "ishift")
12045 (set_attr "mode" "DI")])
12047 (define_insn "*ashrdi3_1"
12048 [(set (match_operand:DI 0 "register_operand" "=r")
12049 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12050 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12051 (clobber (reg:CC FLAGS_REG))]
12054 [(set_attr "type" "multi")])
12056 ;; By default we don't ask for a scratch register, because when DImode
12057 ;; values are manipulated, registers are already at a premium. But if
12058 ;; we have one handy, we won't turn it away.
12060 [(match_scratch:SI 3 "r")
12061 (parallel [(set (match_operand:DI 0 "register_operand" "")
12062 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12063 (match_operand:QI 2 "nonmemory_operand" "")))
12064 (clobber (reg:CC FLAGS_REG))])
12066 "!TARGET_64BIT && TARGET_CMOVE"
12068 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12071 [(set (match_operand:DI 0 "register_operand" "")
12072 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12073 (match_operand:QI 2 "nonmemory_operand" "")))
12074 (clobber (reg:CC FLAGS_REG))]
12075 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12076 ? epilogue_completed : reload_completed)"
12078 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12080 (define_insn "x86_shrd_1"
12081 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12082 (ior:SI (ashiftrt:SI (match_dup 0)
12083 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12084 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12085 (minus:QI (const_int 32) (match_dup 2)))))
12086 (clobber (reg:CC FLAGS_REG))]
12089 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12090 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12091 [(set_attr "type" "ishift")
12092 (set_attr "prefix_0f" "1")
12093 (set_attr "pent_pair" "np")
12094 (set_attr "mode" "SI")])
12096 (define_expand "x86_shift_adj_3"
12097 [(use (match_operand:SI 0 "register_operand" ""))
12098 (use (match_operand:SI 1 "register_operand" ""))
12099 (use (match_operand:QI 2 "register_operand" ""))]
12102 rtx label = gen_label_rtx ();
12105 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12107 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12108 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12109 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12110 gen_rtx_LABEL_REF (VOIDmode, label),
12112 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12113 JUMP_LABEL (tmp) = label;
12115 emit_move_insn (operands[0], operands[1]);
12116 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12118 emit_label (label);
12119 LABEL_NUSES (label) = 1;
12124 (define_insn "ashrsi3_31"
12125 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12126 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12127 (match_operand:SI 2 "const_int_operand" "i,i")))
12128 (clobber (reg:CC FLAGS_REG))]
12129 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12130 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12133 sar{l}\t{%2, %0|%0, %2}"
12134 [(set_attr "type" "imovx,ishift")
12135 (set_attr "prefix_0f" "0,*")
12136 (set_attr "length_immediate" "0,*")
12137 (set_attr "modrm" "0,1")
12138 (set_attr "mode" "SI")])
12140 (define_insn "*ashrsi3_31_zext"
12141 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12142 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12143 (match_operand:SI 2 "const_int_operand" "i,i"))))
12144 (clobber (reg:CC FLAGS_REG))]
12145 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12146 && INTVAL (operands[2]) == 31
12147 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12150 sar{l}\t{%2, %k0|%k0, %2}"
12151 [(set_attr "type" "imovx,ishift")
12152 (set_attr "prefix_0f" "0,*")
12153 (set_attr "length_immediate" "0,*")
12154 (set_attr "modrm" "0,1")
12155 (set_attr "mode" "SI")])
12157 (define_expand "ashrsi3"
12158 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12159 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12160 (match_operand:QI 2 "nonmemory_operand" "")))
12161 (clobber (reg:CC FLAGS_REG))]
12163 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12165 (define_insn "*ashrsi3_1_one_bit"
12166 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12167 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12168 (match_operand:QI 2 "const1_operand" "")))
12169 (clobber (reg:CC FLAGS_REG))]
12170 "(TARGET_SHIFT1 || optimize_size)
12171 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12173 [(set_attr "type" "ishift")
12174 (set (attr "length")
12175 (if_then_else (match_operand:SI 0 "register_operand" "")
12177 (const_string "*")))])
12179 (define_insn "*ashrsi3_1_one_bit_zext"
12180 [(set (match_operand:DI 0 "register_operand" "=r")
12181 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12182 (match_operand:QI 2 "const1_operand" ""))))
12183 (clobber (reg:CC FLAGS_REG))]
12185 && (TARGET_SHIFT1 || optimize_size)
12186 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12188 [(set_attr "type" "ishift")
12189 (set_attr "length" "2")])
12191 (define_insn "*ashrsi3_1"
12192 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12193 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12194 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12195 (clobber (reg:CC FLAGS_REG))]
12196 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12198 sar{l}\t{%2, %0|%0, %2}
12199 sar{l}\t{%b2, %0|%0, %b2}"
12200 [(set_attr "type" "ishift")
12201 (set_attr "mode" "SI")])
12203 (define_insn "*ashrsi3_1_zext"
12204 [(set (match_operand:DI 0 "register_operand" "=r,r")
12205 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12206 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12207 (clobber (reg:CC FLAGS_REG))]
12208 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12210 sar{l}\t{%2, %k0|%k0, %2}
12211 sar{l}\t{%b2, %k0|%k0, %b2}"
12212 [(set_attr "type" "ishift")
12213 (set_attr "mode" "SI")])
12215 ;; This pattern can't accept a variable shift count, since shifts by
12216 ;; zero don't affect the flags. We assume that shifts by constant
12217 ;; zero are optimized away.
12218 (define_insn "*ashrsi3_one_bit_cmp"
12219 [(set (reg FLAGS_REG)
12221 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12222 (match_operand:QI 2 "const1_operand" ""))
12224 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12225 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12226 "(TARGET_SHIFT1 || optimize_size)
12227 && ix86_match_ccmode (insn, CCGOCmode)
12228 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12230 [(set_attr "type" "ishift")
12231 (set (attr "length")
12232 (if_then_else (match_operand:SI 0 "register_operand" "")
12234 (const_string "*")))])
12236 (define_insn "*ashrsi3_one_bit_cconly"
12237 [(set (reg FLAGS_REG)
12239 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12240 (match_operand:QI 2 "const1_operand" ""))
12242 (clobber (match_scratch:SI 0 "=r"))]
12243 "(TARGET_SHIFT1 || optimize_size)
12244 && ix86_match_ccmode (insn, CCGOCmode)
12245 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12247 [(set_attr "type" "ishift")
12248 (set_attr "length" "2")])
12250 (define_insn "*ashrsi3_one_bit_cmp_zext"
12251 [(set (reg FLAGS_REG)
12253 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12254 (match_operand:QI 2 "const1_operand" ""))
12256 (set (match_operand:DI 0 "register_operand" "=r")
12257 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12259 && (TARGET_SHIFT1 || optimize_size)
12260 && ix86_match_ccmode (insn, CCmode)
12261 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12263 [(set_attr "type" "ishift")
12264 (set_attr "length" "2")])
12266 ;; This pattern can't accept a variable shift count, since shifts by
12267 ;; zero don't affect the flags. We assume that shifts by constant
12268 ;; zero are optimized away.
12269 (define_insn "*ashrsi3_cmp"
12270 [(set (reg FLAGS_REG)
12272 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12273 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12275 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12276 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12277 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12278 && ix86_match_ccmode (insn, CCGOCmode)
12279 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12280 "sar{l}\t{%2, %0|%0, %2}"
12281 [(set_attr "type" "ishift")
12282 (set_attr "mode" "SI")])
12284 (define_insn "*ashrsi3_cconly"
12285 [(set (reg FLAGS_REG)
12287 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12288 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12290 (clobber (match_scratch:SI 0 "=r"))]
12291 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12292 && ix86_match_ccmode (insn, CCGOCmode)
12293 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12294 "sar{l}\t{%2, %0|%0, %2}"
12295 [(set_attr "type" "ishift")
12296 (set_attr "mode" "SI")])
12298 (define_insn "*ashrsi3_cmp_zext"
12299 [(set (reg FLAGS_REG)
12301 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12302 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12304 (set (match_operand:DI 0 "register_operand" "=r")
12305 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12307 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12308 && ix86_match_ccmode (insn, CCGOCmode)
12309 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12310 "sar{l}\t{%2, %k0|%k0, %2}"
12311 [(set_attr "type" "ishift")
12312 (set_attr "mode" "SI")])
12314 (define_expand "ashrhi3"
12315 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12316 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12317 (match_operand:QI 2 "nonmemory_operand" "")))
12318 (clobber (reg:CC FLAGS_REG))]
12319 "TARGET_HIMODE_MATH"
12320 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12322 (define_insn "*ashrhi3_1_one_bit"
12323 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12324 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12325 (match_operand:QI 2 "const1_operand" "")))
12326 (clobber (reg:CC FLAGS_REG))]
12327 "(TARGET_SHIFT1 || optimize_size)
12328 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12330 [(set_attr "type" "ishift")
12331 (set (attr "length")
12332 (if_then_else (match_operand 0 "register_operand" "")
12334 (const_string "*")))])
12336 (define_insn "*ashrhi3_1"
12337 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12338 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12339 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12340 (clobber (reg:CC FLAGS_REG))]
12341 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12343 sar{w}\t{%2, %0|%0, %2}
12344 sar{w}\t{%b2, %0|%0, %b2}"
12345 [(set_attr "type" "ishift")
12346 (set_attr "mode" "HI")])
12348 ;; This pattern can't accept a variable shift count, since shifts by
12349 ;; zero don't affect the flags. We assume that shifts by constant
12350 ;; zero are optimized away.
12351 (define_insn "*ashrhi3_one_bit_cmp"
12352 [(set (reg FLAGS_REG)
12354 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12355 (match_operand:QI 2 "const1_operand" ""))
12357 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12358 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12359 "(TARGET_SHIFT1 || optimize_size)
12360 && ix86_match_ccmode (insn, CCGOCmode)
12361 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12363 [(set_attr "type" "ishift")
12364 (set (attr "length")
12365 (if_then_else (match_operand 0 "register_operand" "")
12367 (const_string "*")))])
12369 (define_insn "*ashrhi3_one_bit_cconly"
12370 [(set (reg FLAGS_REG)
12372 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12373 (match_operand:QI 2 "const1_operand" ""))
12375 (clobber (match_scratch:HI 0 "=r"))]
12376 "(TARGET_SHIFT1 || optimize_size)
12377 && ix86_match_ccmode (insn, CCGOCmode)
12378 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12380 [(set_attr "type" "ishift")
12381 (set_attr "length" "2")])
12383 ;; This pattern can't accept a variable shift count, since shifts by
12384 ;; zero don't affect the flags. We assume that shifts by constant
12385 ;; zero are optimized away.
12386 (define_insn "*ashrhi3_cmp"
12387 [(set (reg FLAGS_REG)
12389 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12390 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12392 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12393 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12394 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12395 && ix86_match_ccmode (insn, CCGOCmode)
12396 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12397 "sar{w}\t{%2, %0|%0, %2}"
12398 [(set_attr "type" "ishift")
12399 (set_attr "mode" "HI")])
12401 (define_insn "*ashrhi3_cconly"
12402 [(set (reg FLAGS_REG)
12404 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12405 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12407 (clobber (match_scratch:HI 0 "=r"))]
12408 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12409 && ix86_match_ccmode (insn, CCGOCmode)
12410 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12411 "sar{w}\t{%2, %0|%0, %2}"
12412 [(set_attr "type" "ishift")
12413 (set_attr "mode" "HI")])
12415 (define_expand "ashrqi3"
12416 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12417 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12418 (match_operand:QI 2 "nonmemory_operand" "")))
12419 (clobber (reg:CC FLAGS_REG))]
12420 "TARGET_QIMODE_MATH"
12421 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12423 (define_insn "*ashrqi3_1_one_bit"
12424 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12425 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12426 (match_operand:QI 2 "const1_operand" "")))
12427 (clobber (reg:CC FLAGS_REG))]
12428 "(TARGET_SHIFT1 || optimize_size)
12429 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12431 [(set_attr "type" "ishift")
12432 (set (attr "length")
12433 (if_then_else (match_operand 0 "register_operand" "")
12435 (const_string "*")))])
12437 (define_insn "*ashrqi3_1_one_bit_slp"
12438 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12439 (ashiftrt:QI (match_dup 0)
12440 (match_operand:QI 1 "const1_operand" "")))
12441 (clobber (reg:CC FLAGS_REG))]
12442 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12443 && (TARGET_SHIFT1 || optimize_size)
12444 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12446 [(set_attr "type" "ishift1")
12447 (set (attr "length")
12448 (if_then_else (match_operand 0 "register_operand" "")
12450 (const_string "*")))])
12452 (define_insn "*ashrqi3_1"
12453 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12454 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12455 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12456 (clobber (reg:CC FLAGS_REG))]
12457 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12459 sar{b}\t{%2, %0|%0, %2}
12460 sar{b}\t{%b2, %0|%0, %b2}"
12461 [(set_attr "type" "ishift")
12462 (set_attr "mode" "QI")])
12464 (define_insn "*ashrqi3_1_slp"
12465 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12466 (ashiftrt:QI (match_dup 0)
12467 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12468 (clobber (reg:CC FLAGS_REG))]
12469 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12470 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12472 sar{b}\t{%1, %0|%0, %1}
12473 sar{b}\t{%b1, %0|%0, %b1}"
12474 [(set_attr "type" "ishift1")
12475 (set_attr "mode" "QI")])
12477 ;; This pattern can't accept a variable shift count, since shifts by
12478 ;; zero don't affect the flags. We assume that shifts by constant
12479 ;; zero are optimized away.
12480 (define_insn "*ashrqi3_one_bit_cmp"
12481 [(set (reg FLAGS_REG)
12483 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12484 (match_operand:QI 2 "const1_operand" "I"))
12486 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12487 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12488 "(TARGET_SHIFT1 || optimize_size)
12489 && ix86_match_ccmode (insn, CCGOCmode)
12490 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12492 [(set_attr "type" "ishift")
12493 (set (attr "length")
12494 (if_then_else (match_operand 0 "register_operand" "")
12496 (const_string "*")))])
12498 (define_insn "*ashrqi3_one_bit_cconly"
12499 [(set (reg FLAGS_REG)
12501 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12502 (match_operand:QI 2 "const1_operand" "I"))
12504 (clobber (match_scratch:QI 0 "=q"))]
12505 "(TARGET_SHIFT1 || optimize_size)
12506 && ix86_match_ccmode (insn, CCGOCmode)
12507 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12509 [(set_attr "type" "ishift")
12510 (set_attr "length" "2")])
12512 ;; This pattern can't accept a variable shift count, since shifts by
12513 ;; zero don't affect the flags. We assume that shifts by constant
12514 ;; zero are optimized away.
12515 (define_insn "*ashrqi3_cmp"
12516 [(set (reg FLAGS_REG)
12518 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12519 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12521 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12522 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12523 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12524 && ix86_match_ccmode (insn, CCGOCmode)
12525 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12526 "sar{b}\t{%2, %0|%0, %2}"
12527 [(set_attr "type" "ishift")
12528 (set_attr "mode" "QI")])
12530 (define_insn "*ashrqi3_cconly"
12531 [(set (reg FLAGS_REG)
12533 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12534 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12536 (clobber (match_scratch:QI 0 "=q"))]
12537 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12538 && ix86_match_ccmode (insn, CCGOCmode)
12539 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12540 "sar{b}\t{%2, %0|%0, %2}"
12541 [(set_attr "type" "ishift")
12542 (set_attr "mode" "QI")])
12545 ;; Logical shift instructions
12547 ;; See comment above `ashldi3' about how this works.
12549 (define_expand "lshrti3"
12550 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12551 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12552 (match_operand:QI 2 "nonmemory_operand" "")))
12553 (clobber (reg:CC FLAGS_REG))])]
12556 if (! immediate_operand (operands[2], QImode))
12558 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12561 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12565 (define_insn "lshrti3_1"
12566 [(set (match_operand:TI 0 "register_operand" "=r")
12567 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12568 (match_operand:QI 2 "register_operand" "c")))
12569 (clobber (match_scratch:DI 3 "=&r"))
12570 (clobber (reg:CC FLAGS_REG))]
12573 [(set_attr "type" "multi")])
12575 ;; This pattern must be defined before *lshrti3_2 to prevent
12576 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12578 (define_insn "sse2_lshrti3"
12579 [(set (match_operand:TI 0 "register_operand" "=x")
12580 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12581 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12584 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12585 return "psrldq\t{%2, %0|%0, %2}";
12587 [(set_attr "type" "sseishft")
12588 (set_attr "prefix_data16" "1")
12589 (set_attr "mode" "TI")])
12591 (define_insn "*lshrti3_2"
12592 [(set (match_operand:TI 0 "register_operand" "=r")
12593 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12594 (match_operand:QI 2 "immediate_operand" "O")))
12595 (clobber (reg:CC FLAGS_REG))]
12598 [(set_attr "type" "multi")])
12601 [(set (match_operand:TI 0 "register_operand" "")
12602 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12603 (match_operand:QI 2 "register_operand" "")))
12604 (clobber (match_scratch:DI 3 ""))
12605 (clobber (reg:CC FLAGS_REG))]
12606 "TARGET_64BIT && reload_completed"
12608 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12611 [(set (match_operand:TI 0 "register_operand" "")
12612 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12613 (match_operand:QI 2 "immediate_operand" "")))
12614 (clobber (reg:CC FLAGS_REG))]
12615 "TARGET_64BIT && reload_completed"
12617 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12619 (define_expand "lshrdi3"
12620 [(set (match_operand:DI 0 "shiftdi_operand" "")
12621 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12622 (match_operand:QI 2 "nonmemory_operand" "")))]
12624 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12626 (define_insn "*lshrdi3_1_one_bit_rex64"
12627 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12628 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12629 (match_operand:QI 2 "const1_operand" "")))
12630 (clobber (reg:CC FLAGS_REG))]
12632 && (TARGET_SHIFT1 || optimize_size)
12633 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12635 [(set_attr "type" "ishift")
12636 (set (attr "length")
12637 (if_then_else (match_operand:DI 0 "register_operand" "")
12639 (const_string "*")))])
12641 (define_insn "*lshrdi3_1_rex64"
12642 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12643 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12644 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12645 (clobber (reg:CC FLAGS_REG))]
12646 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12648 shr{q}\t{%2, %0|%0, %2}
12649 shr{q}\t{%b2, %0|%0, %b2}"
12650 [(set_attr "type" "ishift")
12651 (set_attr "mode" "DI")])
12653 ;; This pattern can't accept a variable shift count, since shifts by
12654 ;; zero don't affect the flags. We assume that shifts by constant
12655 ;; zero are optimized away.
12656 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12657 [(set (reg FLAGS_REG)
12659 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12660 (match_operand:QI 2 "const1_operand" ""))
12662 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12663 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12665 && (TARGET_SHIFT1 || optimize_size)
12666 && ix86_match_ccmode (insn, CCGOCmode)
12667 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12669 [(set_attr "type" "ishift")
12670 (set (attr "length")
12671 (if_then_else (match_operand:DI 0 "register_operand" "")
12673 (const_string "*")))])
12675 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12676 [(set (reg FLAGS_REG)
12678 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12679 (match_operand:QI 2 "const1_operand" ""))
12681 (clobber (match_scratch:DI 0 "=r"))]
12683 && (TARGET_SHIFT1 || optimize_size)
12684 && ix86_match_ccmode (insn, CCGOCmode)
12685 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12687 [(set_attr "type" "ishift")
12688 (set_attr "length" "2")])
12690 ;; This pattern can't accept a variable shift count, since shifts by
12691 ;; zero don't affect the flags. We assume that shifts by constant
12692 ;; zero are optimized away.
12693 (define_insn "*lshrdi3_cmp_rex64"
12694 [(set (reg FLAGS_REG)
12696 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12697 (match_operand:QI 2 "const_int_operand" "e"))
12699 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12700 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12702 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12703 && ix86_match_ccmode (insn, CCGOCmode)
12704 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12705 "shr{q}\t{%2, %0|%0, %2}"
12706 [(set_attr "type" "ishift")
12707 (set_attr "mode" "DI")])
12709 (define_insn "*lshrdi3_cconly_rex64"
12710 [(set (reg FLAGS_REG)
12712 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12713 (match_operand:QI 2 "const_int_operand" "e"))
12715 (clobber (match_scratch:DI 0 "=r"))]
12717 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12718 && ix86_match_ccmode (insn, CCGOCmode)
12719 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12720 "shr{q}\t{%2, %0|%0, %2}"
12721 [(set_attr "type" "ishift")
12722 (set_attr "mode" "DI")])
12724 (define_insn "*lshrdi3_1"
12725 [(set (match_operand:DI 0 "register_operand" "=r")
12726 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12727 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12728 (clobber (reg:CC FLAGS_REG))]
12731 [(set_attr "type" "multi")])
12733 ;; By default we don't ask for a scratch register, because when DImode
12734 ;; values are manipulated, registers are already at a premium. But if
12735 ;; we have one handy, we won't turn it away.
12737 [(match_scratch:SI 3 "r")
12738 (parallel [(set (match_operand:DI 0 "register_operand" "")
12739 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12740 (match_operand:QI 2 "nonmemory_operand" "")))
12741 (clobber (reg:CC FLAGS_REG))])
12743 "!TARGET_64BIT && TARGET_CMOVE"
12745 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12748 [(set (match_operand:DI 0 "register_operand" "")
12749 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12750 (match_operand:QI 2 "nonmemory_operand" "")))
12751 (clobber (reg:CC FLAGS_REG))]
12752 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12753 ? epilogue_completed : reload_completed)"
12755 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12757 (define_expand "lshrsi3"
12758 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12759 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12760 (match_operand:QI 2 "nonmemory_operand" "")))
12761 (clobber (reg:CC FLAGS_REG))]
12763 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12765 (define_insn "*lshrsi3_1_one_bit"
12766 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12767 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12768 (match_operand:QI 2 "const1_operand" "")))
12769 (clobber (reg:CC FLAGS_REG))]
12770 "(TARGET_SHIFT1 || optimize_size)
12771 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12773 [(set_attr "type" "ishift")
12774 (set (attr "length")
12775 (if_then_else (match_operand:SI 0 "register_operand" "")
12777 (const_string "*")))])
12779 (define_insn "*lshrsi3_1_one_bit_zext"
12780 [(set (match_operand:DI 0 "register_operand" "=r")
12781 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12782 (match_operand:QI 2 "const1_operand" "")))
12783 (clobber (reg:CC FLAGS_REG))]
12785 && (TARGET_SHIFT1 || optimize_size)
12786 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12788 [(set_attr "type" "ishift")
12789 (set_attr "length" "2")])
12791 (define_insn "*lshrsi3_1"
12792 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12793 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12794 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12795 (clobber (reg:CC FLAGS_REG))]
12796 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12798 shr{l}\t{%2, %0|%0, %2}
12799 shr{l}\t{%b2, %0|%0, %b2}"
12800 [(set_attr "type" "ishift")
12801 (set_attr "mode" "SI")])
12803 (define_insn "*lshrsi3_1_zext"
12804 [(set (match_operand:DI 0 "register_operand" "=r,r")
12806 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12807 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12808 (clobber (reg:CC FLAGS_REG))]
12809 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12811 shr{l}\t{%2, %k0|%k0, %2}
12812 shr{l}\t{%b2, %k0|%k0, %b2}"
12813 [(set_attr "type" "ishift")
12814 (set_attr "mode" "SI")])
12816 ;; This pattern can't accept a variable shift count, since shifts by
12817 ;; zero don't affect the flags. We assume that shifts by constant
12818 ;; zero are optimized away.
12819 (define_insn "*lshrsi3_one_bit_cmp"
12820 [(set (reg FLAGS_REG)
12822 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12823 (match_operand:QI 2 "const1_operand" ""))
12825 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12826 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12827 "(TARGET_SHIFT1 || optimize_size)
12828 && ix86_match_ccmode (insn, CCGOCmode)
12829 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12831 [(set_attr "type" "ishift")
12832 (set (attr "length")
12833 (if_then_else (match_operand:SI 0 "register_operand" "")
12835 (const_string "*")))])
12837 (define_insn "*lshrsi3_one_bit_cconly"
12838 [(set (reg FLAGS_REG)
12840 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12841 (match_operand:QI 2 "const1_operand" ""))
12843 (clobber (match_scratch:SI 0 "=r"))]
12844 "(TARGET_SHIFT1 || optimize_size)
12845 && ix86_match_ccmode (insn, CCGOCmode)
12846 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12848 [(set_attr "type" "ishift")
12849 (set_attr "length" "2")])
12851 (define_insn "*lshrsi3_cmp_one_bit_zext"
12852 [(set (reg FLAGS_REG)
12854 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12855 (match_operand:QI 2 "const1_operand" ""))
12857 (set (match_operand:DI 0 "register_operand" "=r")
12858 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12860 && (TARGET_SHIFT1 || optimize_size)
12861 && ix86_match_ccmode (insn, CCGOCmode)
12862 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12864 [(set_attr "type" "ishift")
12865 (set_attr "length" "2")])
12867 ;; This pattern can't accept a variable shift count, since shifts by
12868 ;; zero don't affect the flags. We assume that shifts by constant
12869 ;; zero are optimized away.
12870 (define_insn "*lshrsi3_cmp"
12871 [(set (reg FLAGS_REG)
12873 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12874 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12876 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12877 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12878 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12879 && ix86_match_ccmode (insn, CCGOCmode)
12880 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12881 "shr{l}\t{%2, %0|%0, %2}"
12882 [(set_attr "type" "ishift")
12883 (set_attr "mode" "SI")])
12885 (define_insn "*lshrsi3_cconly"
12886 [(set (reg FLAGS_REG)
12888 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12889 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12891 (clobber (match_scratch:SI 0 "=r"))]
12892 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12893 && ix86_match_ccmode (insn, CCGOCmode)
12894 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12895 "shr{l}\t{%2, %0|%0, %2}"
12896 [(set_attr "type" "ishift")
12897 (set_attr "mode" "SI")])
12899 (define_insn "*lshrsi3_cmp_zext"
12900 [(set (reg FLAGS_REG)
12902 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12903 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12905 (set (match_operand:DI 0 "register_operand" "=r")
12906 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12908 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12909 && ix86_match_ccmode (insn, CCGOCmode)
12910 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12911 "shr{l}\t{%2, %k0|%k0, %2}"
12912 [(set_attr "type" "ishift")
12913 (set_attr "mode" "SI")])
12915 (define_expand "lshrhi3"
12916 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12917 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12918 (match_operand:QI 2 "nonmemory_operand" "")))
12919 (clobber (reg:CC FLAGS_REG))]
12920 "TARGET_HIMODE_MATH"
12921 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12923 (define_insn "*lshrhi3_1_one_bit"
12924 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12925 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12926 (match_operand:QI 2 "const1_operand" "")))
12927 (clobber (reg:CC FLAGS_REG))]
12928 "(TARGET_SHIFT1 || optimize_size)
12929 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12931 [(set_attr "type" "ishift")
12932 (set (attr "length")
12933 (if_then_else (match_operand 0 "register_operand" "")
12935 (const_string "*")))])
12937 (define_insn "*lshrhi3_1"
12938 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12939 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12940 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12941 (clobber (reg:CC FLAGS_REG))]
12942 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12944 shr{w}\t{%2, %0|%0, %2}
12945 shr{w}\t{%b2, %0|%0, %b2}"
12946 [(set_attr "type" "ishift")
12947 (set_attr "mode" "HI")])
12949 ;; This pattern can't accept a variable shift count, since shifts by
12950 ;; zero don't affect the flags. We assume that shifts by constant
12951 ;; zero are optimized away.
12952 (define_insn "*lshrhi3_one_bit_cmp"
12953 [(set (reg FLAGS_REG)
12955 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12956 (match_operand:QI 2 "const1_operand" ""))
12958 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12959 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12960 "(TARGET_SHIFT1 || optimize_size)
12961 && ix86_match_ccmode (insn, CCGOCmode)
12962 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12964 [(set_attr "type" "ishift")
12965 (set (attr "length")
12966 (if_then_else (match_operand:SI 0 "register_operand" "")
12968 (const_string "*")))])
12970 (define_insn "*lshrhi3_one_bit_cconly"
12971 [(set (reg FLAGS_REG)
12973 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12974 (match_operand:QI 2 "const1_operand" ""))
12976 (clobber (match_scratch:HI 0 "=r"))]
12977 "(TARGET_SHIFT1 || optimize_size)
12978 && ix86_match_ccmode (insn, CCGOCmode)
12979 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12981 [(set_attr "type" "ishift")
12982 (set_attr "length" "2")])
12984 ;; This pattern can't accept a variable shift count, since shifts by
12985 ;; zero don't affect the flags. We assume that shifts by constant
12986 ;; zero are optimized away.
12987 (define_insn "*lshrhi3_cmp"
12988 [(set (reg FLAGS_REG)
12990 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12991 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12993 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12994 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12995 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12996 && ix86_match_ccmode (insn, CCGOCmode)
12997 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12998 "shr{w}\t{%2, %0|%0, %2}"
12999 [(set_attr "type" "ishift")
13000 (set_attr "mode" "HI")])
13002 (define_insn "*lshrhi3_cconly"
13003 [(set (reg FLAGS_REG)
13005 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13006 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13008 (clobber (match_scratch:HI 0 "=r"))]
13009 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13010 && ix86_match_ccmode (insn, CCGOCmode)
13011 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13012 "shr{w}\t{%2, %0|%0, %2}"
13013 [(set_attr "type" "ishift")
13014 (set_attr "mode" "HI")])
13016 (define_expand "lshrqi3"
13017 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13018 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13019 (match_operand:QI 2 "nonmemory_operand" "")))
13020 (clobber (reg:CC FLAGS_REG))]
13021 "TARGET_QIMODE_MATH"
13022 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13024 (define_insn "*lshrqi3_1_one_bit"
13025 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13026 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13027 (match_operand:QI 2 "const1_operand" "")))
13028 (clobber (reg:CC FLAGS_REG))]
13029 "(TARGET_SHIFT1 || optimize_size)
13030 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13032 [(set_attr "type" "ishift")
13033 (set (attr "length")
13034 (if_then_else (match_operand 0 "register_operand" "")
13036 (const_string "*")))])
13038 (define_insn "*lshrqi3_1_one_bit_slp"
13039 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13040 (lshiftrt:QI (match_dup 0)
13041 (match_operand:QI 1 "const1_operand" "")))
13042 (clobber (reg:CC FLAGS_REG))]
13043 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13044 && (TARGET_SHIFT1 || optimize_size)"
13046 [(set_attr "type" "ishift1")
13047 (set (attr "length")
13048 (if_then_else (match_operand 0 "register_operand" "")
13050 (const_string "*")))])
13052 (define_insn "*lshrqi3_1"
13053 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13054 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13055 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13056 (clobber (reg:CC FLAGS_REG))]
13057 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13059 shr{b}\t{%2, %0|%0, %2}
13060 shr{b}\t{%b2, %0|%0, %b2}"
13061 [(set_attr "type" "ishift")
13062 (set_attr "mode" "QI")])
13064 (define_insn "*lshrqi3_1_slp"
13065 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13066 (lshiftrt:QI (match_dup 0)
13067 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13068 (clobber (reg:CC FLAGS_REG))]
13069 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13070 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13072 shr{b}\t{%1, %0|%0, %1}
13073 shr{b}\t{%b1, %0|%0, %b1}"
13074 [(set_attr "type" "ishift1")
13075 (set_attr "mode" "QI")])
13077 ;; This pattern can't accept a variable shift count, since shifts by
13078 ;; zero don't affect the flags. We assume that shifts by constant
13079 ;; zero are optimized away.
13080 (define_insn "*lshrqi2_one_bit_cmp"
13081 [(set (reg FLAGS_REG)
13083 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13084 (match_operand:QI 2 "const1_operand" ""))
13086 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13087 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13088 "(TARGET_SHIFT1 || optimize_size)
13089 && ix86_match_ccmode (insn, CCGOCmode)
13090 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13092 [(set_attr "type" "ishift")
13093 (set (attr "length")
13094 (if_then_else (match_operand:SI 0 "register_operand" "")
13096 (const_string "*")))])
13098 (define_insn "*lshrqi2_one_bit_cconly"
13099 [(set (reg FLAGS_REG)
13101 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13102 (match_operand:QI 2 "const1_operand" ""))
13104 (clobber (match_scratch:QI 0 "=q"))]
13105 "(TARGET_SHIFT1 || optimize_size)
13106 && ix86_match_ccmode (insn, CCGOCmode)
13107 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13109 [(set_attr "type" "ishift")
13110 (set_attr "length" "2")])
13112 ;; This pattern can't accept a variable shift count, since shifts by
13113 ;; zero don't affect the flags. We assume that shifts by constant
13114 ;; zero are optimized away.
13115 (define_insn "*lshrqi2_cmp"
13116 [(set (reg FLAGS_REG)
13118 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13119 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13121 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13122 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13123 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13124 && ix86_match_ccmode (insn, CCGOCmode)
13125 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13126 "shr{b}\t{%2, %0|%0, %2}"
13127 [(set_attr "type" "ishift")
13128 (set_attr "mode" "QI")])
13130 (define_insn "*lshrqi2_cconly"
13131 [(set (reg FLAGS_REG)
13133 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13134 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13136 (clobber (match_scratch:QI 0 "=q"))]
13137 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13138 && ix86_match_ccmode (insn, CCGOCmode)
13139 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13140 "shr{b}\t{%2, %0|%0, %2}"
13141 [(set_attr "type" "ishift")
13142 (set_attr "mode" "QI")])
13144 ;; Rotate instructions
13146 (define_expand "rotldi3"
13147 [(set (match_operand:DI 0 "shiftdi_operand" "")
13148 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13149 (match_operand:QI 2 "nonmemory_operand" "")))
13150 (clobber (reg:CC FLAGS_REG))]
13155 ix86_expand_binary_operator (ROTATE, DImode, operands);
13158 if (!const_1_to_31_operand (operands[2], VOIDmode))
13160 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13164 ;; Implement rotation using two double-precision shift instructions
13165 ;; and a scratch register.
13166 (define_insn_and_split "ix86_rotldi3"
13167 [(set (match_operand:DI 0 "register_operand" "=r")
13168 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13169 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13170 (clobber (reg:CC FLAGS_REG))
13171 (clobber (match_scratch:SI 3 "=&r"))]
13174 "&& reload_completed"
13175 [(set (match_dup 3) (match_dup 4))
13177 [(set (match_dup 4)
13178 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13179 (lshiftrt:SI (match_dup 5)
13180 (minus:QI (const_int 32) (match_dup 2)))))
13181 (clobber (reg:CC FLAGS_REG))])
13183 [(set (match_dup 5)
13184 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13185 (lshiftrt:SI (match_dup 3)
13186 (minus:QI (const_int 32) (match_dup 2)))))
13187 (clobber (reg:CC FLAGS_REG))])]
13188 "split_di (operands, 1, operands + 4, operands + 5);")
13190 (define_insn "*rotlsi3_1_one_bit_rex64"
13191 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13192 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13193 (match_operand:QI 2 "const1_operand" "")))
13194 (clobber (reg:CC FLAGS_REG))]
13196 && (TARGET_SHIFT1 || optimize_size)
13197 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13199 [(set_attr "type" "rotate")
13200 (set (attr "length")
13201 (if_then_else (match_operand:DI 0 "register_operand" "")
13203 (const_string "*")))])
13205 (define_insn "*rotldi3_1_rex64"
13206 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13207 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13208 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13209 (clobber (reg:CC FLAGS_REG))]
13210 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13212 rol{q}\t{%2, %0|%0, %2}
13213 rol{q}\t{%b2, %0|%0, %b2}"
13214 [(set_attr "type" "rotate")
13215 (set_attr "mode" "DI")])
13217 (define_expand "rotlsi3"
13218 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13219 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13220 (match_operand:QI 2 "nonmemory_operand" "")))
13221 (clobber (reg:CC FLAGS_REG))]
13223 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13225 (define_insn "*rotlsi3_1_one_bit"
13226 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13227 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13228 (match_operand:QI 2 "const1_operand" "")))
13229 (clobber (reg:CC FLAGS_REG))]
13230 "(TARGET_SHIFT1 || optimize_size)
13231 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13233 [(set_attr "type" "rotate")
13234 (set (attr "length")
13235 (if_then_else (match_operand:SI 0 "register_operand" "")
13237 (const_string "*")))])
13239 (define_insn "*rotlsi3_1_one_bit_zext"
13240 [(set (match_operand:DI 0 "register_operand" "=r")
13242 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13243 (match_operand:QI 2 "const1_operand" ""))))
13244 (clobber (reg:CC FLAGS_REG))]
13246 && (TARGET_SHIFT1 || optimize_size)
13247 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13249 [(set_attr "type" "rotate")
13250 (set_attr "length" "2")])
13252 (define_insn "*rotlsi3_1"
13253 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13254 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13255 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13256 (clobber (reg:CC FLAGS_REG))]
13257 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13259 rol{l}\t{%2, %0|%0, %2}
13260 rol{l}\t{%b2, %0|%0, %b2}"
13261 [(set_attr "type" "rotate")
13262 (set_attr "mode" "SI")])
13264 (define_insn "*rotlsi3_1_zext"
13265 [(set (match_operand:DI 0 "register_operand" "=r,r")
13267 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13268 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13269 (clobber (reg:CC FLAGS_REG))]
13270 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13272 rol{l}\t{%2, %k0|%k0, %2}
13273 rol{l}\t{%b2, %k0|%k0, %b2}"
13274 [(set_attr "type" "rotate")
13275 (set_attr "mode" "SI")])
13277 (define_expand "rotlhi3"
13278 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13279 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13280 (match_operand:QI 2 "nonmemory_operand" "")))
13281 (clobber (reg:CC FLAGS_REG))]
13282 "TARGET_HIMODE_MATH"
13283 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13285 (define_insn "*rotlhi3_1_one_bit"
13286 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13287 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13288 (match_operand:QI 2 "const1_operand" "")))
13289 (clobber (reg:CC FLAGS_REG))]
13290 "(TARGET_SHIFT1 || optimize_size)
13291 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13293 [(set_attr "type" "rotate")
13294 (set (attr "length")
13295 (if_then_else (match_operand 0 "register_operand" "")
13297 (const_string "*")))])
13299 (define_insn "*rotlhi3_1"
13300 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13301 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13302 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13303 (clobber (reg:CC FLAGS_REG))]
13304 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13306 rol{w}\t{%2, %0|%0, %2}
13307 rol{w}\t{%b2, %0|%0, %b2}"
13308 [(set_attr "type" "rotate")
13309 (set_attr "mode" "HI")])
13312 [(set (match_operand:HI 0 "register_operand" "")
13313 (rotate:HI (match_dup 0) (const_int 8)))
13314 (clobber (reg:CC FLAGS_REG))]
13316 [(parallel [(set (strict_low_part (match_dup 0))
13317 (bswap:HI (match_dup 0)))
13318 (clobber (reg:CC FLAGS_REG))])]
13321 (define_expand "rotlqi3"
13322 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13323 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13324 (match_operand:QI 2 "nonmemory_operand" "")))
13325 (clobber (reg:CC FLAGS_REG))]
13326 "TARGET_QIMODE_MATH"
13327 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13329 (define_insn "*rotlqi3_1_one_bit_slp"
13330 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13331 (rotate:QI (match_dup 0)
13332 (match_operand:QI 1 "const1_operand" "")))
13333 (clobber (reg:CC FLAGS_REG))]
13334 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13335 && (TARGET_SHIFT1 || optimize_size)"
13337 [(set_attr "type" "rotate1")
13338 (set (attr "length")
13339 (if_then_else (match_operand 0 "register_operand" "")
13341 (const_string "*")))])
13343 (define_insn "*rotlqi3_1_one_bit"
13344 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13345 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13346 (match_operand:QI 2 "const1_operand" "")))
13347 (clobber (reg:CC FLAGS_REG))]
13348 "(TARGET_SHIFT1 || optimize_size)
13349 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13351 [(set_attr "type" "rotate")
13352 (set (attr "length")
13353 (if_then_else (match_operand 0 "register_operand" "")
13355 (const_string "*")))])
13357 (define_insn "*rotlqi3_1_slp"
13358 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13359 (rotate:QI (match_dup 0)
13360 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13361 (clobber (reg:CC FLAGS_REG))]
13362 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13363 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13365 rol{b}\t{%1, %0|%0, %1}
13366 rol{b}\t{%b1, %0|%0, %b1}"
13367 [(set_attr "type" "rotate1")
13368 (set_attr "mode" "QI")])
13370 (define_insn "*rotlqi3_1"
13371 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13372 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13373 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13374 (clobber (reg:CC FLAGS_REG))]
13375 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13377 rol{b}\t{%2, %0|%0, %2}
13378 rol{b}\t{%b2, %0|%0, %b2}"
13379 [(set_attr "type" "rotate")
13380 (set_attr "mode" "QI")])
13382 (define_expand "rotrdi3"
13383 [(set (match_operand:DI 0 "shiftdi_operand" "")
13384 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13385 (match_operand:QI 2 "nonmemory_operand" "")))
13386 (clobber (reg:CC FLAGS_REG))]
13391 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13394 if (!const_1_to_31_operand (operands[2], VOIDmode))
13396 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13400 ;; Implement rotation using two double-precision shift instructions
13401 ;; and a scratch register.
13402 (define_insn_and_split "ix86_rotrdi3"
13403 [(set (match_operand:DI 0 "register_operand" "=r")
13404 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13405 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13406 (clobber (reg:CC FLAGS_REG))
13407 (clobber (match_scratch:SI 3 "=&r"))]
13410 "&& reload_completed"
13411 [(set (match_dup 3) (match_dup 4))
13413 [(set (match_dup 4)
13414 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13415 (ashift:SI (match_dup 5)
13416 (minus:QI (const_int 32) (match_dup 2)))))
13417 (clobber (reg:CC FLAGS_REG))])
13419 [(set (match_dup 5)
13420 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13421 (ashift:SI (match_dup 3)
13422 (minus:QI (const_int 32) (match_dup 2)))))
13423 (clobber (reg:CC FLAGS_REG))])]
13424 "split_di (operands, 1, operands + 4, operands + 5);")
13426 (define_insn "*rotrdi3_1_one_bit_rex64"
13427 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13428 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13429 (match_operand:QI 2 "const1_operand" "")))
13430 (clobber (reg:CC FLAGS_REG))]
13432 && (TARGET_SHIFT1 || optimize_size)
13433 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13435 [(set_attr "type" "rotate")
13436 (set (attr "length")
13437 (if_then_else (match_operand:DI 0 "register_operand" "")
13439 (const_string "*")))])
13441 (define_insn "*rotrdi3_1_rex64"
13442 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13443 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13444 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13445 (clobber (reg:CC FLAGS_REG))]
13446 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13448 ror{q}\t{%2, %0|%0, %2}
13449 ror{q}\t{%b2, %0|%0, %b2}"
13450 [(set_attr "type" "rotate")
13451 (set_attr "mode" "DI")])
13453 (define_expand "rotrsi3"
13454 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13455 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13456 (match_operand:QI 2 "nonmemory_operand" "")))
13457 (clobber (reg:CC FLAGS_REG))]
13459 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13461 (define_insn "*rotrsi3_1_one_bit"
13462 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13463 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13464 (match_operand:QI 2 "const1_operand" "")))
13465 (clobber (reg:CC FLAGS_REG))]
13466 "(TARGET_SHIFT1 || optimize_size)
13467 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13469 [(set_attr "type" "rotate")
13470 (set (attr "length")
13471 (if_then_else (match_operand:SI 0 "register_operand" "")
13473 (const_string "*")))])
13475 (define_insn "*rotrsi3_1_one_bit_zext"
13476 [(set (match_operand:DI 0 "register_operand" "=r")
13478 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13479 (match_operand:QI 2 "const1_operand" ""))))
13480 (clobber (reg:CC FLAGS_REG))]
13482 && (TARGET_SHIFT1 || optimize_size)
13483 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13485 [(set_attr "type" "rotate")
13486 (set (attr "length")
13487 (if_then_else (match_operand:SI 0 "register_operand" "")
13489 (const_string "*")))])
13491 (define_insn "*rotrsi3_1"
13492 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13493 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13494 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13495 (clobber (reg:CC FLAGS_REG))]
13496 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13498 ror{l}\t{%2, %0|%0, %2}
13499 ror{l}\t{%b2, %0|%0, %b2}"
13500 [(set_attr "type" "rotate")
13501 (set_attr "mode" "SI")])
13503 (define_insn "*rotrsi3_1_zext"
13504 [(set (match_operand:DI 0 "register_operand" "=r,r")
13506 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13507 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13508 (clobber (reg:CC FLAGS_REG))]
13509 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13511 ror{l}\t{%2, %k0|%k0, %2}
13512 ror{l}\t{%b2, %k0|%k0, %b2}"
13513 [(set_attr "type" "rotate")
13514 (set_attr "mode" "SI")])
13516 (define_expand "rotrhi3"
13517 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13518 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13519 (match_operand:QI 2 "nonmemory_operand" "")))
13520 (clobber (reg:CC FLAGS_REG))]
13521 "TARGET_HIMODE_MATH"
13522 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13524 (define_insn "*rotrhi3_one_bit"
13525 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13526 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13527 (match_operand:QI 2 "const1_operand" "")))
13528 (clobber (reg:CC FLAGS_REG))]
13529 "(TARGET_SHIFT1 || optimize_size)
13530 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13532 [(set_attr "type" "rotate")
13533 (set (attr "length")
13534 (if_then_else (match_operand 0 "register_operand" "")
13536 (const_string "*")))])
13538 (define_insn "*rotrhi3_1"
13539 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13540 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13541 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13542 (clobber (reg:CC FLAGS_REG))]
13543 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13545 ror{w}\t{%2, %0|%0, %2}
13546 ror{w}\t{%b2, %0|%0, %b2}"
13547 [(set_attr "type" "rotate")
13548 (set_attr "mode" "HI")])
13551 [(set (match_operand:HI 0 "register_operand" "")
13552 (rotatert:HI (match_dup 0) (const_int 8)))
13553 (clobber (reg:CC FLAGS_REG))]
13555 [(parallel [(set (strict_low_part (match_dup 0))
13556 (bswap:HI (match_dup 0)))
13557 (clobber (reg:CC FLAGS_REG))])]
13560 (define_expand "rotrqi3"
13561 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13562 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13563 (match_operand:QI 2 "nonmemory_operand" "")))
13564 (clobber (reg:CC FLAGS_REG))]
13565 "TARGET_QIMODE_MATH"
13566 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13568 (define_insn "*rotrqi3_1_one_bit"
13569 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13570 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13571 (match_operand:QI 2 "const1_operand" "")))
13572 (clobber (reg:CC FLAGS_REG))]
13573 "(TARGET_SHIFT1 || optimize_size)
13574 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13576 [(set_attr "type" "rotate")
13577 (set (attr "length")
13578 (if_then_else (match_operand 0 "register_operand" "")
13580 (const_string "*")))])
13582 (define_insn "*rotrqi3_1_one_bit_slp"
13583 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13584 (rotatert:QI (match_dup 0)
13585 (match_operand:QI 1 "const1_operand" "")))
13586 (clobber (reg:CC FLAGS_REG))]
13587 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13588 && (TARGET_SHIFT1 || optimize_size)"
13590 [(set_attr "type" "rotate1")
13591 (set (attr "length")
13592 (if_then_else (match_operand 0 "register_operand" "")
13594 (const_string "*")))])
13596 (define_insn "*rotrqi3_1"
13597 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13598 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13599 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13600 (clobber (reg:CC FLAGS_REG))]
13601 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13603 ror{b}\t{%2, %0|%0, %2}
13604 ror{b}\t{%b2, %0|%0, %b2}"
13605 [(set_attr "type" "rotate")
13606 (set_attr "mode" "QI")])
13608 (define_insn "*rotrqi3_1_slp"
13609 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13610 (rotatert:QI (match_dup 0)
13611 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13612 (clobber (reg:CC FLAGS_REG))]
13613 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13614 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13616 ror{b}\t{%1, %0|%0, %1}
13617 ror{b}\t{%b1, %0|%0, %b1}"
13618 [(set_attr "type" "rotate1")
13619 (set_attr "mode" "QI")])
13621 ;; Bit set / bit test instructions
13623 (define_expand "extv"
13624 [(set (match_operand:SI 0 "register_operand" "")
13625 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13626 (match_operand:SI 2 "const8_operand" "")
13627 (match_operand:SI 3 "const8_operand" "")))]
13630 /* Handle extractions from %ah et al. */
13631 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13634 /* From mips.md: extract_bit_field doesn't verify that our source
13635 matches the predicate, so check it again here. */
13636 if (! ext_register_operand (operands[1], VOIDmode))
13640 (define_expand "extzv"
13641 [(set (match_operand:SI 0 "register_operand" "")
13642 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13643 (match_operand:SI 2 "const8_operand" "")
13644 (match_operand:SI 3 "const8_operand" "")))]
13647 /* Handle extractions from %ah et al. */
13648 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13651 /* From mips.md: extract_bit_field doesn't verify that our source
13652 matches the predicate, so check it again here. */
13653 if (! ext_register_operand (operands[1], VOIDmode))
13657 (define_expand "insv"
13658 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13659 (match_operand 1 "const8_operand" "")
13660 (match_operand 2 "const8_operand" ""))
13661 (match_operand 3 "register_operand" ""))]
13664 /* Handle insertions to %ah et al. */
13665 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13668 /* From mips.md: insert_bit_field doesn't verify that our source
13669 matches the predicate, so check it again here. */
13670 if (! ext_register_operand (operands[0], VOIDmode))
13674 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13676 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13681 ;; %%% bts, btr, btc, bt.
13682 ;; In general these instructions are *slow* when applied to memory,
13683 ;; since they enforce atomic operation. When applied to registers,
13684 ;; it depends on the cpu implementation. They're never faster than
13685 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13686 ;; no point. But in 64-bit, we can't hold the relevant immediates
13687 ;; within the instruction itself, so operating on bits in the high
13688 ;; 32-bits of a register becomes easier.
13690 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13691 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13692 ;; negdf respectively, so they can never be disabled entirely.
13694 (define_insn "*btsq"
13695 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13697 (match_operand:DI 1 "const_0_to_63_operand" ""))
13699 (clobber (reg:CC FLAGS_REG))]
13700 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13702 [(set_attr "type" "alu1")])
13704 (define_insn "*btrq"
13705 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13707 (match_operand:DI 1 "const_0_to_63_operand" ""))
13709 (clobber (reg:CC FLAGS_REG))]
13710 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13712 [(set_attr "type" "alu1")])
13714 (define_insn "*btcq"
13715 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13717 (match_operand:DI 1 "const_0_to_63_operand" ""))
13718 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13719 (clobber (reg:CC FLAGS_REG))]
13720 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13722 [(set_attr "type" "alu1")])
13724 ;; Allow Nocona to avoid these instructions if a register is available.
13727 [(match_scratch:DI 2 "r")
13728 (parallel [(set (zero_extract:DI
13729 (match_operand:DI 0 "register_operand" "")
13731 (match_operand:DI 1 "const_0_to_63_operand" ""))
13733 (clobber (reg:CC FLAGS_REG))])]
13734 "TARGET_64BIT && !TARGET_USE_BT"
13737 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13740 if (HOST_BITS_PER_WIDE_INT >= 64)
13741 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13742 else if (i < HOST_BITS_PER_WIDE_INT)
13743 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13745 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13747 op1 = immed_double_const (lo, hi, DImode);
13750 emit_move_insn (operands[2], op1);
13754 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13759 [(match_scratch:DI 2 "r")
13760 (parallel [(set (zero_extract:DI
13761 (match_operand:DI 0 "register_operand" "")
13763 (match_operand:DI 1 "const_0_to_63_operand" ""))
13765 (clobber (reg:CC FLAGS_REG))])]
13766 "TARGET_64BIT && !TARGET_USE_BT"
13769 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13772 if (HOST_BITS_PER_WIDE_INT >= 64)
13773 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13774 else if (i < HOST_BITS_PER_WIDE_INT)
13775 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13777 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13779 op1 = immed_double_const (~lo, ~hi, DImode);
13782 emit_move_insn (operands[2], op1);
13786 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13791 [(match_scratch:DI 2 "r")
13792 (parallel [(set (zero_extract:DI
13793 (match_operand:DI 0 "register_operand" "")
13795 (match_operand:DI 1 "const_0_to_63_operand" ""))
13796 (not:DI (zero_extract:DI
13797 (match_dup 0) (const_int 1) (match_dup 1))))
13798 (clobber (reg:CC FLAGS_REG))])]
13799 "TARGET_64BIT && !TARGET_USE_BT"
13802 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13805 if (HOST_BITS_PER_WIDE_INT >= 64)
13806 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13807 else if (i < HOST_BITS_PER_WIDE_INT)
13808 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13810 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13812 op1 = immed_double_const (lo, hi, DImode);
13815 emit_move_insn (operands[2], op1);
13819 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13823 ;; Store-flag instructions.
13825 ;; For all sCOND expanders, also expand the compare or test insn that
13826 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13828 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13829 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13830 ;; way, which can later delete the movzx if only QImode is needed.
13832 (define_expand "s<code>"
13833 [(set (match_operand:QI 0 "register_operand" "")
13834 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13836 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13838 (define_expand "s<code>"
13839 [(set (match_operand:QI 0 "register_operand" "")
13840 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13841 "TARGET_80387 || TARGET_SSE"
13842 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13844 (define_insn "*setcc_1"
13845 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13846 (match_operator:QI 1 "ix86_comparison_operator"
13847 [(reg FLAGS_REG) (const_int 0)]))]
13850 [(set_attr "type" "setcc")
13851 (set_attr "mode" "QI")])
13853 (define_insn "*setcc_2"
13854 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13855 (match_operator:QI 1 "ix86_comparison_operator"
13856 [(reg FLAGS_REG) (const_int 0)]))]
13859 [(set_attr "type" "setcc")
13860 (set_attr "mode" "QI")])
13862 ;; In general it is not safe to assume too much about CCmode registers,
13863 ;; so simplify-rtx stops when it sees a second one. Under certain
13864 ;; conditions this is safe on x86, so help combine not create
13871 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13872 (ne:QI (match_operator 1 "ix86_comparison_operator"
13873 [(reg FLAGS_REG) (const_int 0)])
13876 [(set (match_dup 0) (match_dup 1))]
13878 PUT_MODE (operands[1], QImode);
13882 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13883 (ne:QI (match_operator 1 "ix86_comparison_operator"
13884 [(reg FLAGS_REG) (const_int 0)])
13887 [(set (match_dup 0) (match_dup 1))]
13889 PUT_MODE (operands[1], QImode);
13893 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13894 (eq:QI (match_operator 1 "ix86_comparison_operator"
13895 [(reg FLAGS_REG) (const_int 0)])
13898 [(set (match_dup 0) (match_dup 1))]
13900 rtx new_op1 = copy_rtx (operands[1]);
13901 operands[1] = new_op1;
13902 PUT_MODE (new_op1, QImode);
13903 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13904 GET_MODE (XEXP (new_op1, 0))));
13906 /* Make sure that (a) the CCmode we have for the flags is strong
13907 enough for the reversed compare or (b) we have a valid FP compare. */
13908 if (! ix86_comparison_operator (new_op1, VOIDmode))
13913 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13914 (eq:QI (match_operator 1 "ix86_comparison_operator"
13915 [(reg FLAGS_REG) (const_int 0)])
13918 [(set (match_dup 0) (match_dup 1))]
13920 rtx new_op1 = copy_rtx (operands[1]);
13921 operands[1] = new_op1;
13922 PUT_MODE (new_op1, QImode);
13923 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13924 GET_MODE (XEXP (new_op1, 0))));
13926 /* Make sure that (a) the CCmode we have for the flags is strong
13927 enough for the reversed compare or (b) we have a valid FP compare. */
13928 if (! ix86_comparison_operator (new_op1, VOIDmode))
13932 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13933 ;; subsequent logical operations are used to imitate conditional moves.
13934 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13937 (define_insn "*sse_setcc<mode>"
13938 [(set (match_operand:MODEF 0 "register_operand" "=x")
13939 (match_operator:MODEF 1 "sse_comparison_operator"
13940 [(match_operand:MODEF 2 "register_operand" "0")
13941 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13942 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13943 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13944 [(set_attr "type" "ssecmp")
13945 (set_attr "mode" "<MODE>")])
13947 (define_insn "*sse5_setcc<mode>"
13948 [(set (match_operand:MODEF 0 "register_operand" "=x")
13949 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13950 [(match_operand:MODEF 2 "register_operand" "x")
13951 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13953 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13954 [(set_attr "type" "sse4arg")
13955 (set_attr "mode" "<MODE>")])
13958 ;; Basic conditional jump instructions.
13959 ;; We ignore the overflow flag for signed branch instructions.
13961 ;; For all bCOND expanders, also expand the compare or test insn that
13962 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13964 (define_expand "b<code>"
13966 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13968 (label_ref (match_operand 0 ""))
13971 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13973 (define_expand "b<code>"
13975 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13977 (label_ref (match_operand 0 ""))
13979 "TARGET_80387 || TARGET_SSE_MATH"
13980 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13982 (define_insn "*jcc_1"
13984 (if_then_else (match_operator 1 "ix86_comparison_operator"
13985 [(reg FLAGS_REG) (const_int 0)])
13986 (label_ref (match_operand 0 "" ""))
13990 [(set_attr "type" "ibr")
13991 (set_attr "modrm" "0")
13992 (set (attr "length")
13993 (if_then_else (and (ge (minus (match_dup 0) (pc))
13995 (lt (minus (match_dup 0) (pc))
14000 (define_insn "*jcc_2"
14002 (if_then_else (match_operator 1 "ix86_comparison_operator"
14003 [(reg FLAGS_REG) (const_int 0)])
14005 (label_ref (match_operand 0 "" ""))))]
14008 [(set_attr "type" "ibr")
14009 (set_attr "modrm" "0")
14010 (set (attr "length")
14011 (if_then_else (and (ge (minus (match_dup 0) (pc))
14013 (lt (minus (match_dup 0) (pc))
14018 ;; In general it is not safe to assume too much about CCmode registers,
14019 ;; so simplify-rtx stops when it sees a second one. Under certain
14020 ;; conditions this is safe on x86, so help combine not create
14028 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14029 [(reg FLAGS_REG) (const_int 0)])
14031 (label_ref (match_operand 1 "" ""))
14035 (if_then_else (match_dup 0)
14036 (label_ref (match_dup 1))
14039 PUT_MODE (operands[0], VOIDmode);
14044 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14045 [(reg FLAGS_REG) (const_int 0)])
14047 (label_ref (match_operand 1 "" ""))
14051 (if_then_else (match_dup 0)
14052 (label_ref (match_dup 1))
14055 rtx new_op0 = copy_rtx (operands[0]);
14056 operands[0] = new_op0;
14057 PUT_MODE (new_op0, VOIDmode);
14058 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14059 GET_MODE (XEXP (new_op0, 0))));
14061 /* Make sure that (a) the CCmode we have for the flags is strong
14062 enough for the reversed compare or (b) we have a valid FP compare. */
14063 if (! ix86_comparison_operator (new_op0, VOIDmode))
14067 ;; Define combination compare-and-branch fp compare instructions to use
14068 ;; during early optimization. Splitting the operation apart early makes
14069 ;; for bad code when we want to reverse the operation.
14071 (define_insn "*fp_jcc_1_mixed"
14073 (if_then_else (match_operator 0 "comparison_operator"
14074 [(match_operand 1 "register_operand" "f,x")
14075 (match_operand 2 "nonimmediate_operand" "f,xm")])
14076 (label_ref (match_operand 3 "" ""))
14078 (clobber (reg:CCFP FPSR_REG))
14079 (clobber (reg:CCFP FLAGS_REG))]
14080 "TARGET_MIX_SSE_I387
14081 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14082 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14083 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14086 (define_insn "*fp_jcc_1_sse"
14088 (if_then_else (match_operator 0 "comparison_operator"
14089 [(match_operand 1 "register_operand" "x")
14090 (match_operand 2 "nonimmediate_operand" "xm")])
14091 (label_ref (match_operand 3 "" ""))
14093 (clobber (reg:CCFP FPSR_REG))
14094 (clobber (reg:CCFP FLAGS_REG))]
14096 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14097 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14098 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14101 (define_insn "*fp_jcc_1_387"
14103 (if_then_else (match_operator 0 "comparison_operator"
14104 [(match_operand 1 "register_operand" "f")
14105 (match_operand 2 "register_operand" "f")])
14106 (label_ref (match_operand 3 "" ""))
14108 (clobber (reg:CCFP FPSR_REG))
14109 (clobber (reg:CCFP FLAGS_REG))]
14110 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14112 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14113 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14116 (define_insn "*fp_jcc_2_mixed"
14118 (if_then_else (match_operator 0 "comparison_operator"
14119 [(match_operand 1 "register_operand" "f,x")
14120 (match_operand 2 "nonimmediate_operand" "f,xm")])
14122 (label_ref (match_operand 3 "" ""))))
14123 (clobber (reg:CCFP FPSR_REG))
14124 (clobber (reg:CCFP FLAGS_REG))]
14125 "TARGET_MIX_SSE_I387
14126 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14127 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14128 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14131 (define_insn "*fp_jcc_2_sse"
14133 (if_then_else (match_operator 0 "comparison_operator"
14134 [(match_operand 1 "register_operand" "x")
14135 (match_operand 2 "nonimmediate_operand" "xm")])
14137 (label_ref (match_operand 3 "" ""))))
14138 (clobber (reg:CCFP FPSR_REG))
14139 (clobber (reg:CCFP FLAGS_REG))]
14141 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14142 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14143 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14146 (define_insn "*fp_jcc_2_387"
14148 (if_then_else (match_operator 0 "comparison_operator"
14149 [(match_operand 1 "register_operand" "f")
14150 (match_operand 2 "register_operand" "f")])
14152 (label_ref (match_operand 3 "" ""))))
14153 (clobber (reg:CCFP FPSR_REG))
14154 (clobber (reg:CCFP FLAGS_REG))]
14155 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14157 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14158 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14161 (define_insn "*fp_jcc_3_387"
14163 (if_then_else (match_operator 0 "comparison_operator"
14164 [(match_operand 1 "register_operand" "f")
14165 (match_operand 2 "nonimmediate_operand" "fm")])
14166 (label_ref (match_operand 3 "" ""))
14168 (clobber (reg:CCFP FPSR_REG))
14169 (clobber (reg:CCFP FLAGS_REG))
14170 (clobber (match_scratch:HI 4 "=a"))]
14172 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14173 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14174 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14175 && SELECT_CC_MODE (GET_CODE (operands[0]),
14176 operands[1], operands[2]) == CCFPmode
14177 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14180 (define_insn "*fp_jcc_4_387"
14182 (if_then_else (match_operator 0 "comparison_operator"
14183 [(match_operand 1 "register_operand" "f")
14184 (match_operand 2 "nonimmediate_operand" "fm")])
14186 (label_ref (match_operand 3 "" ""))))
14187 (clobber (reg:CCFP FPSR_REG))
14188 (clobber (reg:CCFP FLAGS_REG))
14189 (clobber (match_scratch:HI 4 "=a"))]
14191 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14192 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14193 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14194 && SELECT_CC_MODE (GET_CODE (operands[0]),
14195 operands[1], operands[2]) == CCFPmode
14196 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14199 (define_insn "*fp_jcc_5_387"
14201 (if_then_else (match_operator 0 "comparison_operator"
14202 [(match_operand 1 "register_operand" "f")
14203 (match_operand 2 "register_operand" "f")])
14204 (label_ref (match_operand 3 "" ""))
14206 (clobber (reg:CCFP FPSR_REG))
14207 (clobber (reg:CCFP FLAGS_REG))
14208 (clobber (match_scratch:HI 4 "=a"))]
14209 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14210 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14211 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14214 (define_insn "*fp_jcc_6_387"
14216 (if_then_else (match_operator 0 "comparison_operator"
14217 [(match_operand 1 "register_operand" "f")
14218 (match_operand 2 "register_operand" "f")])
14220 (label_ref (match_operand 3 "" ""))))
14221 (clobber (reg:CCFP FPSR_REG))
14222 (clobber (reg:CCFP FLAGS_REG))
14223 (clobber (match_scratch:HI 4 "=a"))]
14224 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14225 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14226 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14229 (define_insn "*fp_jcc_7_387"
14231 (if_then_else (match_operator 0 "comparison_operator"
14232 [(match_operand 1 "register_operand" "f")
14233 (match_operand 2 "const0_operand" "X")])
14234 (label_ref (match_operand 3 "" ""))
14236 (clobber (reg:CCFP FPSR_REG))
14237 (clobber (reg:CCFP FLAGS_REG))
14238 (clobber (match_scratch:HI 4 "=a"))]
14239 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14240 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14241 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14242 && SELECT_CC_MODE (GET_CODE (operands[0]),
14243 operands[1], operands[2]) == CCFPmode
14244 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14247 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14248 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14249 ;; with a precedence over other operators and is always put in the first
14250 ;; place. Swap condition and operands to match ficom instruction.
14252 (define_insn "*fp_jcc_8<mode>_387"
14254 (if_then_else (match_operator 0 "comparison_operator"
14255 [(match_operator 1 "float_operator"
14256 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14257 (match_operand 3 "register_operand" "f,f")])
14258 (label_ref (match_operand 4 "" ""))
14260 (clobber (reg:CCFP FPSR_REG))
14261 (clobber (reg:CCFP FLAGS_REG))
14262 (clobber (match_scratch:HI 5 "=a,a"))]
14263 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14264 && TARGET_USE_<MODE>MODE_FIOP
14265 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14266 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14267 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14268 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14273 (if_then_else (match_operator 0 "comparison_operator"
14274 [(match_operand 1 "register_operand" "")
14275 (match_operand 2 "nonimmediate_operand" "")])
14276 (match_operand 3 "" "")
14277 (match_operand 4 "" "")))
14278 (clobber (reg:CCFP FPSR_REG))
14279 (clobber (reg:CCFP FLAGS_REG))]
14283 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14284 operands[3], operands[4], NULL_RTX, NULL_RTX);
14290 (if_then_else (match_operator 0 "comparison_operator"
14291 [(match_operand 1 "register_operand" "")
14292 (match_operand 2 "general_operand" "")])
14293 (match_operand 3 "" "")
14294 (match_operand 4 "" "")))
14295 (clobber (reg:CCFP FPSR_REG))
14296 (clobber (reg:CCFP FLAGS_REG))
14297 (clobber (match_scratch:HI 5 "=a"))]
14301 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14302 operands[3], operands[4], operands[5], NULL_RTX);
14308 (if_then_else (match_operator 0 "comparison_operator"
14309 [(match_operator 1 "float_operator"
14310 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14311 (match_operand 3 "register_operand" "")])
14312 (match_operand 4 "" "")
14313 (match_operand 5 "" "")))
14314 (clobber (reg:CCFP FPSR_REG))
14315 (clobber (reg:CCFP FLAGS_REG))
14316 (clobber (match_scratch:HI 6 "=a"))]
14320 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14321 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14322 operands[3], operands[7],
14323 operands[4], operands[5], operands[6], NULL_RTX);
14327 ;; %%% Kill this when reload knows how to do it.
14330 (if_then_else (match_operator 0 "comparison_operator"
14331 [(match_operator 1 "float_operator"
14332 [(match_operand:X87MODEI12 2 "register_operand" "")])
14333 (match_operand 3 "register_operand" "")])
14334 (match_operand 4 "" "")
14335 (match_operand 5 "" "")))
14336 (clobber (reg:CCFP FPSR_REG))
14337 (clobber (reg:CCFP FLAGS_REG))
14338 (clobber (match_scratch:HI 6 "=a"))]
14342 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14343 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14344 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14345 operands[3], operands[7],
14346 operands[4], operands[5], operands[6], operands[2]);
14350 ;; Unconditional and other jump instructions
14352 (define_insn "jump"
14354 (label_ref (match_operand 0 "" "")))]
14357 [(set_attr "type" "ibr")
14358 (set (attr "length")
14359 (if_then_else (and (ge (minus (match_dup 0) (pc))
14361 (lt (minus (match_dup 0) (pc))
14365 (set_attr "modrm" "0")])
14367 (define_expand "indirect_jump"
14368 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14372 (define_insn "*indirect_jump"
14373 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14376 [(set_attr "type" "ibr")
14377 (set_attr "length_immediate" "0")])
14379 (define_insn "*indirect_jump_rtx64"
14380 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14383 [(set_attr "type" "ibr")
14384 (set_attr "length_immediate" "0")])
14386 (define_expand "tablejump"
14387 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14388 (use (label_ref (match_operand 1 "" "")))])]
14391 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14392 relative. Convert the relative address to an absolute address. */
14396 enum rtx_code code;
14398 /* We can't use @GOTOFF for text labels on VxWorks;
14399 see gotoff_operand. */
14400 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14404 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14406 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14410 op1 = pic_offset_table_rtx;
14415 op0 = pic_offset_table_rtx;
14419 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14424 (define_insn "*tablejump_1"
14425 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14426 (use (label_ref (match_operand 1 "" "")))]
14429 [(set_attr "type" "ibr")
14430 (set_attr "length_immediate" "0")])
14432 (define_insn "*tablejump_1_rtx64"
14433 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14434 (use (label_ref (match_operand 1 "" "")))]
14437 [(set_attr "type" "ibr")
14438 (set_attr "length_immediate" "0")])
14440 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14443 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14444 (set (match_operand:QI 1 "register_operand" "")
14445 (match_operator:QI 2 "ix86_comparison_operator"
14446 [(reg FLAGS_REG) (const_int 0)]))
14447 (set (match_operand 3 "q_regs_operand" "")
14448 (zero_extend (match_dup 1)))]
14449 "(peep2_reg_dead_p (3, operands[1])
14450 || operands_match_p (operands[1], operands[3]))
14451 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14452 [(set (match_dup 4) (match_dup 0))
14453 (set (strict_low_part (match_dup 5))
14456 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14457 operands[5] = gen_lowpart (QImode, operands[3]);
14458 ix86_expand_clear (operands[3]);
14461 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14464 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14465 (set (match_operand:QI 1 "register_operand" "")
14466 (match_operator:QI 2 "ix86_comparison_operator"
14467 [(reg FLAGS_REG) (const_int 0)]))
14468 (parallel [(set (match_operand 3 "q_regs_operand" "")
14469 (zero_extend (match_dup 1)))
14470 (clobber (reg:CC FLAGS_REG))])]
14471 "(peep2_reg_dead_p (3, operands[1])
14472 || operands_match_p (operands[1], operands[3]))
14473 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14474 [(set (match_dup 4) (match_dup 0))
14475 (set (strict_low_part (match_dup 5))
14478 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14479 operands[5] = gen_lowpart (QImode, operands[3]);
14480 ix86_expand_clear (operands[3]);
14483 ;; Call instructions.
14485 ;; The predicates normally associated with named expanders are not properly
14486 ;; checked for calls. This is a bug in the generic code, but it isn't that
14487 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14489 ;; Call subroutine returning no value.
14491 (define_expand "call_pop"
14492 [(parallel [(call (match_operand:QI 0 "" "")
14493 (match_operand:SI 1 "" ""))
14494 (set (reg:SI SP_REG)
14495 (plus:SI (reg:SI SP_REG)
14496 (match_operand:SI 3 "" "")))])]
14499 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14503 (define_insn "*call_pop_0"
14504 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14505 (match_operand:SI 1 "" ""))
14506 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14507 (match_operand:SI 2 "immediate_operand" "")))]
14510 if (SIBLING_CALL_P (insn))
14513 return "call\t%P0";
14515 [(set_attr "type" "call")])
14517 (define_insn "*call_pop_1"
14518 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14519 (match_operand:SI 1 "" ""))
14520 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14521 (match_operand:SI 2 "immediate_operand" "i")))]
14524 if (constant_call_address_operand (operands[0], Pmode))
14526 if (SIBLING_CALL_P (insn))
14529 return "call\t%P0";
14531 if (SIBLING_CALL_P (insn))
14534 return "call\t%A0";
14536 [(set_attr "type" "call")])
14538 (define_expand "call"
14539 [(call (match_operand:QI 0 "" "")
14540 (match_operand 1 "" ""))
14541 (use (match_operand 2 "" ""))]
14544 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14548 (define_expand "sibcall"
14549 [(call (match_operand:QI 0 "" "")
14550 (match_operand 1 "" ""))
14551 (use (match_operand 2 "" ""))]
14554 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14558 (define_insn "*call_0"
14559 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14560 (match_operand 1 "" ""))]
14563 if (SIBLING_CALL_P (insn))
14566 return "call\t%P0";
14568 [(set_attr "type" "call")])
14570 (define_insn "*call_1"
14571 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14572 (match_operand 1 "" ""))]
14573 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14575 if (constant_call_address_operand (operands[0], Pmode))
14576 return "call\t%P0";
14577 return "call\t%A0";
14579 [(set_attr "type" "call")])
14581 (define_insn "*sibcall_1"
14582 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14583 (match_operand 1 "" ""))]
14584 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14586 if (constant_call_address_operand (operands[0], Pmode))
14590 [(set_attr "type" "call")])
14592 (define_insn "*call_1_rex64"
14593 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14594 (match_operand 1 "" ""))]
14595 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14596 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14598 if (constant_call_address_operand (operands[0], Pmode))
14599 return "call\t%P0";
14600 return "call\t%A0";
14602 [(set_attr "type" "call")])
14604 (define_insn "*call_1_rex64_large"
14605 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14606 (match_operand 1 "" ""))]
14607 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14609 [(set_attr "type" "call")])
14611 (define_insn "*sibcall_1_rex64"
14612 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14613 (match_operand 1 "" ""))]
14614 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14616 [(set_attr "type" "call")])
14618 (define_insn "*sibcall_1_rex64_v"
14619 [(call (mem:QI (reg:DI R11_REG))
14620 (match_operand 0 "" ""))]
14621 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14623 [(set_attr "type" "call")])
14626 ;; Call subroutine, returning value in operand 0
14628 (define_expand "call_value_pop"
14629 [(parallel [(set (match_operand 0 "" "")
14630 (call (match_operand:QI 1 "" "")
14631 (match_operand:SI 2 "" "")))
14632 (set (reg:SI SP_REG)
14633 (plus:SI (reg:SI SP_REG)
14634 (match_operand:SI 4 "" "")))])]
14637 ix86_expand_call (operands[0], operands[1], operands[2],
14638 operands[3], operands[4], 0);
14642 (define_expand "call_value"
14643 [(set (match_operand 0 "" "")
14644 (call (match_operand:QI 1 "" "")
14645 (match_operand:SI 2 "" "")))
14646 (use (match_operand:SI 3 "" ""))]
14647 ;; Operand 2 not used on the i386.
14650 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14654 (define_expand "sibcall_value"
14655 [(set (match_operand 0 "" "")
14656 (call (match_operand:QI 1 "" "")
14657 (match_operand:SI 2 "" "")))
14658 (use (match_operand:SI 3 "" ""))]
14659 ;; Operand 2 not used on the i386.
14662 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14666 ;; Call subroutine returning any type.
14668 (define_expand "untyped_call"
14669 [(parallel [(call (match_operand 0 "" "")
14671 (match_operand 1 "" "")
14672 (match_operand 2 "" "")])]
14677 /* In order to give reg-stack an easier job in validating two
14678 coprocessor registers as containing a possible return value,
14679 simply pretend the untyped call returns a complex long double
14682 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14683 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14684 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14687 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14689 rtx set = XVECEXP (operands[2], 0, i);
14690 emit_move_insn (SET_DEST (set), SET_SRC (set));
14693 /* The optimizer does not know that the call sets the function value
14694 registers we stored in the result block. We avoid problems by
14695 claiming that all hard registers are used and clobbered at this
14697 emit_insn (gen_blockage ());
14702 ;; Prologue and epilogue instructions
14704 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14705 ;; all of memory. This blocks insns from being moved across this point.
14707 (define_insn "blockage"
14708 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14711 [(set_attr "length" "0")])
14713 ;; As USE insns aren't meaningful after reload, this is used instead
14714 ;; to prevent deleting instructions setting registers for PIC code
14715 (define_insn "prologue_use"
14716 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14719 [(set_attr "length" "0")])
14721 ;; Insn emitted into the body of a function to return from a function.
14722 ;; This is only done if the function's epilogue is known to be simple.
14723 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14725 (define_expand "return"
14727 "ix86_can_use_return_insn_p ()"
14729 if (current_function_pops_args)
14731 rtx popc = GEN_INT (current_function_pops_args);
14732 emit_jump_insn (gen_return_pop_internal (popc));
14737 (define_insn "return_internal"
14741 [(set_attr "length" "1")
14742 (set_attr "length_immediate" "0")
14743 (set_attr "modrm" "0")])
14745 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14746 ;; instruction Athlon and K8 have.
14748 (define_insn "return_internal_long"
14750 (unspec [(const_int 0)] UNSPEC_REP)]
14753 [(set_attr "length" "1")
14754 (set_attr "length_immediate" "0")
14755 (set_attr "prefix_rep" "1")
14756 (set_attr "modrm" "0")])
14758 (define_insn "return_pop_internal"
14760 (use (match_operand:SI 0 "const_int_operand" ""))]
14763 [(set_attr "length" "3")
14764 (set_attr "length_immediate" "2")
14765 (set_attr "modrm" "0")])
14767 (define_insn "return_indirect_internal"
14769 (use (match_operand:SI 0 "register_operand" "r"))]
14772 [(set_attr "type" "ibr")
14773 (set_attr "length_immediate" "0")])
14779 [(set_attr "length" "1")
14780 (set_attr "length_immediate" "0")
14781 (set_attr "modrm" "0")])
14783 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14784 ;; branch prediction penalty for the third jump in a 16-byte
14787 (define_insn "align"
14788 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14791 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14792 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14794 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14795 The align insn is used to avoid 3 jump instructions in the row to improve
14796 branch prediction and the benefits hardly outweigh the cost of extra 8
14797 nops on the average inserted by full alignment pseudo operation. */
14801 [(set_attr "length" "16")])
14803 (define_expand "prologue"
14806 "ix86_expand_prologue (); DONE;")
14808 (define_insn "set_got"
14809 [(set (match_operand:SI 0 "register_operand" "=r")
14810 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14811 (clobber (reg:CC FLAGS_REG))]
14813 { return output_set_got (operands[0], NULL_RTX); }
14814 [(set_attr "type" "multi")
14815 (set_attr "length" "12")])
14817 (define_insn "set_got_labelled"
14818 [(set (match_operand:SI 0 "register_operand" "=r")
14819 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14821 (clobber (reg:CC FLAGS_REG))]
14823 { return output_set_got (operands[0], operands[1]); }
14824 [(set_attr "type" "multi")
14825 (set_attr "length" "12")])
14827 (define_insn "set_got_rex64"
14828 [(set (match_operand:DI 0 "register_operand" "=r")
14829 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14831 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14832 [(set_attr "type" "lea")
14833 (set_attr "length" "6")])
14835 (define_insn "set_rip_rex64"
14836 [(set (match_operand:DI 0 "register_operand" "=r")
14837 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14839 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14840 [(set_attr "type" "lea")
14841 (set_attr "length" "6")])
14843 (define_insn "set_got_offset_rex64"
14844 [(set (match_operand:DI 0 "register_operand" "=r")
14845 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14847 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14848 [(set_attr "type" "imov")
14849 (set_attr "length" "11")])
14851 (define_expand "epilogue"
14854 "ix86_expand_epilogue (1); DONE;")
14856 (define_expand "sibcall_epilogue"
14859 "ix86_expand_epilogue (0); DONE;")
14861 (define_expand "eh_return"
14862 [(use (match_operand 0 "register_operand" ""))]
14865 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14867 /* Tricky bit: we write the address of the handler to which we will
14868 be returning into someone else's stack frame, one word below the
14869 stack address we wish to restore. */
14870 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14871 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14872 tmp = gen_rtx_MEM (Pmode, tmp);
14873 emit_move_insn (tmp, ra);
14875 if (Pmode == SImode)
14876 emit_jump_insn (gen_eh_return_si (sa));
14878 emit_jump_insn (gen_eh_return_di (sa));
14883 (define_insn_and_split "eh_return_si"
14885 (unspec [(match_operand:SI 0 "register_operand" "c")]
14886 UNSPEC_EH_RETURN))]
14891 "ix86_expand_epilogue (2); DONE;")
14893 (define_insn_and_split "eh_return_di"
14895 (unspec [(match_operand:DI 0 "register_operand" "c")]
14896 UNSPEC_EH_RETURN))]
14901 "ix86_expand_epilogue (2); DONE;")
14903 (define_insn "leave"
14904 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14905 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14906 (clobber (mem:BLK (scratch)))]
14909 [(set_attr "type" "leave")])
14911 (define_insn "leave_rex64"
14912 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14913 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14914 (clobber (mem:BLK (scratch)))]
14917 [(set_attr "type" "leave")])
14919 (define_expand "ffssi2"
14921 [(set (match_operand:SI 0 "register_operand" "")
14922 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14923 (clobber (match_scratch:SI 2 ""))
14924 (clobber (reg:CC FLAGS_REG))])]
14929 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14934 (define_expand "ffs_cmove"
14935 [(set (match_dup 2) (const_int -1))
14936 (parallel [(set (reg:CCZ FLAGS_REG)
14937 (compare:CCZ (match_operand:SI 1 "register_operand" "")
14939 (set (match_operand:SI 0 "nonimmediate_operand" "")
14940 (ctz:SI (match_dup 1)))])
14941 (set (match_dup 0) (if_then_else:SI
14942 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14945 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14946 (clobber (reg:CC FLAGS_REG))])]
14948 "operands[2] = gen_reg_rtx (SImode);")
14950 (define_insn_and_split "*ffs_no_cmove"
14951 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14952 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14953 (clobber (match_scratch:SI 2 "=&q"))
14954 (clobber (reg:CC FLAGS_REG))]
14957 "&& reload_completed"
14958 [(parallel [(set (reg:CCZ FLAGS_REG)
14959 (compare:CCZ (match_dup 1) (const_int 0)))
14960 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14961 (set (strict_low_part (match_dup 3))
14962 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14963 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14964 (clobber (reg:CC FLAGS_REG))])
14965 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14966 (clobber (reg:CC FLAGS_REG))])
14967 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14968 (clobber (reg:CC FLAGS_REG))])]
14970 operands[3] = gen_lowpart (QImode, operands[2]);
14971 ix86_expand_clear (operands[2]);
14974 (define_insn "*ffssi_1"
14975 [(set (reg:CCZ FLAGS_REG)
14976 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14978 (set (match_operand:SI 0 "register_operand" "=r")
14979 (ctz:SI (match_dup 1)))]
14981 "bsf{l}\t{%1, %0|%0, %1}"
14982 [(set_attr "prefix_0f" "1")])
14984 (define_expand "ffsdi2"
14985 [(set (match_dup 2) (const_int -1))
14986 (parallel [(set (reg:CCZ FLAGS_REG)
14987 (compare:CCZ (match_operand:DI 1 "register_operand" "")
14989 (set (match_operand:DI 0 "nonimmediate_operand" "")
14990 (ctz:DI (match_dup 1)))])
14991 (set (match_dup 0) (if_then_else:DI
14992 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14995 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14996 (clobber (reg:CC FLAGS_REG))])]
14998 "operands[2] = gen_reg_rtx (DImode);")
15000 (define_insn "*ffsdi_1"
15001 [(set (reg:CCZ FLAGS_REG)
15002 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15004 (set (match_operand:DI 0 "register_operand" "=r")
15005 (ctz:DI (match_dup 1)))]
15007 "bsf{q}\t{%1, %0|%0, %1}"
15008 [(set_attr "prefix_0f" "1")])
15010 (define_insn "ctzsi2"
15011 [(set (match_operand:SI 0 "register_operand" "=r")
15012 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15013 (clobber (reg:CC FLAGS_REG))]
15015 "bsf{l}\t{%1, %0|%0, %1}"
15016 [(set_attr "prefix_0f" "1")])
15018 (define_insn "ctzdi2"
15019 [(set (match_operand:DI 0 "register_operand" "=r")
15020 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15021 (clobber (reg:CC FLAGS_REG))]
15023 "bsf{q}\t{%1, %0|%0, %1}"
15024 [(set_attr "prefix_0f" "1")])
15026 (define_expand "clzsi2"
15028 [(set (match_operand:SI 0 "register_operand" "")
15029 (minus:SI (const_int 31)
15030 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15031 (clobber (reg:CC FLAGS_REG))])
15033 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15034 (clobber (reg:CC FLAGS_REG))])]
15039 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15044 (define_insn "clzsi2_abm"
15045 [(set (match_operand:SI 0 "register_operand" "=r")
15046 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15047 (clobber (reg:CC FLAGS_REG))]
15049 "lzcnt{l}\t{%1, %0|%0, %1}"
15050 [(set_attr "prefix_rep" "1")
15051 (set_attr "type" "bitmanip")
15052 (set_attr "mode" "SI")])
15054 (define_insn "*bsr"
15055 [(set (match_operand:SI 0 "register_operand" "=r")
15056 (minus:SI (const_int 31)
15057 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15058 (clobber (reg:CC FLAGS_REG))]
15060 "bsr{l}\t{%1, %0|%0, %1}"
15061 [(set_attr "prefix_0f" "1")
15062 (set_attr "mode" "SI")])
15064 (define_insn "popcountsi2"
15065 [(set (match_operand:SI 0 "register_operand" "=r")
15066 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15067 (clobber (reg:CC FLAGS_REG))]
15069 "popcnt{l}\t{%1, %0|%0, %1}"
15070 [(set_attr "prefix_rep" "1")
15071 (set_attr "type" "bitmanip")
15072 (set_attr "mode" "SI")])
15074 (define_insn "*popcountsi2_cmp"
15075 [(set (reg FLAGS_REG)
15077 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15079 (set (match_operand:SI 0 "register_operand" "=r")
15080 (popcount:SI (match_dup 1)))]
15081 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15082 "popcnt{l}\t{%1, %0|%0, %1}"
15083 [(set_attr "prefix_rep" "1")
15084 (set_attr "type" "bitmanip")
15085 (set_attr "mode" "SI")])
15087 (define_insn "*popcountsi2_cmp_zext"
15088 [(set (reg FLAGS_REG)
15090 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15092 (set (match_operand:DI 0 "register_operand" "=r")
15093 (zero_extend:DI(popcount:SI (match_dup 1))))]
15094 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15095 "popcnt{l}\t{%1, %0|%0, %1}"
15096 [(set_attr "prefix_rep" "1")
15097 (set_attr "type" "bitmanip")
15098 (set_attr "mode" "SI")])
15100 (define_expand "bswapsi2"
15101 [(set (match_operand:SI 0 "register_operand" "")
15102 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15107 rtx x = operands[0];
15109 emit_move_insn (x, operands[1]);
15110 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15111 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15112 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15117 (define_insn "*bswapsi_1"
15118 [(set (match_operand:SI 0 "register_operand" "=r")
15119 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15122 [(set_attr "prefix_0f" "1")
15123 (set_attr "length" "2")])
15125 (define_insn "*bswaphi_lowpart_1"
15126 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15127 (bswap:HI (match_dup 0)))
15128 (clobber (reg:CC FLAGS_REG))]
15129 "TARGET_USE_XCHGB || optimize_size"
15131 xchg{b}\t{%h0, %b0|%b0, %h0}
15132 rol{w}\t{$8, %0|%0, 8}"
15133 [(set_attr "length" "2,4")
15134 (set_attr "mode" "QI,HI")])
15136 (define_insn "bswaphi_lowpart"
15137 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15138 (bswap:HI (match_dup 0)))
15139 (clobber (reg:CC FLAGS_REG))]
15141 "rol{w}\t{$8, %0|%0, 8}"
15142 [(set_attr "length" "4")
15143 (set_attr "mode" "HI")])
15145 (define_insn "bswapdi2"
15146 [(set (match_operand:DI 0 "register_operand" "=r")
15147 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15150 [(set_attr "prefix_0f" "1")
15151 (set_attr "length" "3")])
15153 (define_expand "clzdi2"
15155 [(set (match_operand:DI 0 "register_operand" "")
15156 (minus:DI (const_int 63)
15157 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15158 (clobber (reg:CC FLAGS_REG))])
15160 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15161 (clobber (reg:CC FLAGS_REG))])]
15166 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15171 (define_insn "clzdi2_abm"
15172 [(set (match_operand:DI 0 "register_operand" "=r")
15173 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15174 (clobber (reg:CC FLAGS_REG))]
15175 "TARGET_64BIT && TARGET_ABM"
15176 "lzcnt{q}\t{%1, %0|%0, %1}"
15177 [(set_attr "prefix_rep" "1")
15178 (set_attr "type" "bitmanip")
15179 (set_attr "mode" "DI")])
15181 (define_insn "*bsr_rex64"
15182 [(set (match_operand:DI 0 "register_operand" "=r")
15183 (minus:DI (const_int 63)
15184 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15185 (clobber (reg:CC FLAGS_REG))]
15187 "bsr{q}\t{%1, %0|%0, %1}"
15188 [(set_attr "prefix_0f" "1")
15189 (set_attr "mode" "DI")])
15191 (define_insn "popcountdi2"
15192 [(set (match_operand:DI 0 "register_operand" "=r")
15193 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15194 (clobber (reg:CC FLAGS_REG))]
15195 "TARGET_64BIT && TARGET_POPCNT"
15196 "popcnt{q}\t{%1, %0|%0, %1}"
15197 [(set_attr "prefix_rep" "1")
15198 (set_attr "type" "bitmanip")
15199 (set_attr "mode" "DI")])
15201 (define_insn "*popcountdi2_cmp"
15202 [(set (reg FLAGS_REG)
15204 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15206 (set (match_operand:DI 0 "register_operand" "=r")
15207 (popcount:DI (match_dup 1)))]
15208 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15209 "popcnt{q}\t{%1, %0|%0, %1}"
15210 [(set_attr "prefix_rep" "1")
15211 (set_attr "type" "bitmanip")
15212 (set_attr "mode" "DI")])
15214 (define_expand "clzhi2"
15216 [(set (match_operand:HI 0 "register_operand" "")
15217 (minus:HI (const_int 15)
15218 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15219 (clobber (reg:CC FLAGS_REG))])
15221 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15222 (clobber (reg:CC FLAGS_REG))])]
15227 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15232 (define_insn "clzhi2_abm"
15233 [(set (match_operand:HI 0 "register_operand" "=r")
15234 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15235 (clobber (reg:CC FLAGS_REG))]
15237 "lzcnt{w}\t{%1, %0|%0, %1}"
15238 [(set_attr "prefix_rep" "1")
15239 (set_attr "type" "bitmanip")
15240 (set_attr "mode" "HI")])
15242 (define_insn "*bsrhi"
15243 [(set (match_operand:HI 0 "register_operand" "=r")
15244 (minus:HI (const_int 15)
15245 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15246 (clobber (reg:CC FLAGS_REG))]
15248 "bsr{w}\t{%1, %0|%0, %1}"
15249 [(set_attr "prefix_0f" "1")
15250 (set_attr "mode" "HI")])
15252 (define_insn "popcounthi2"
15253 [(set (match_operand:HI 0 "register_operand" "=r")
15254 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15255 (clobber (reg:CC FLAGS_REG))]
15257 "popcnt{w}\t{%1, %0|%0, %1}"
15258 [(set_attr "prefix_rep" "1")
15259 (set_attr "type" "bitmanip")
15260 (set_attr "mode" "HI")])
15262 (define_insn "*popcounthi2_cmp"
15263 [(set (reg FLAGS_REG)
15265 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15267 (set (match_operand:HI 0 "register_operand" "=r")
15268 (popcount:HI (match_dup 1)))]
15269 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15270 "popcnt{w}\t{%1, %0|%0, %1}"
15271 [(set_attr "prefix_rep" "1")
15272 (set_attr "type" "bitmanip")
15273 (set_attr "mode" "HI")])
15275 (define_expand "paritydi2"
15276 [(set (match_operand:DI 0 "register_operand" "")
15277 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15280 rtx scratch = gen_reg_rtx (QImode);
15283 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15284 NULL_RTX, operands[1]));
15286 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15287 gen_rtx_REG (CCmode, FLAGS_REG),
15289 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15292 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15295 rtx tmp = gen_reg_rtx (SImode);
15297 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15298 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15303 (define_insn_and_split "paritydi2_cmp"
15304 [(set (reg:CC FLAGS_REG)
15305 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15306 (clobber (match_scratch:DI 0 "=r"))
15307 (clobber (match_scratch:SI 1 "=&r"))
15308 (clobber (match_scratch:HI 2 "=Q"))]
15311 "&& reload_completed"
15313 [(set (match_dup 1)
15314 (xor:SI (match_dup 1) (match_dup 4)))
15315 (clobber (reg:CC FLAGS_REG))])
15317 [(set (reg:CC FLAGS_REG)
15318 (parity:CC (match_dup 1)))
15319 (clobber (match_dup 1))
15320 (clobber (match_dup 2))])]
15322 operands[4] = gen_lowpart (SImode, operands[3]);
15326 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15327 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15330 operands[1] = gen_highpart (SImode, operands[3]);
15333 (define_expand "paritysi2"
15334 [(set (match_operand:SI 0 "register_operand" "")
15335 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15338 rtx scratch = gen_reg_rtx (QImode);
15341 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15343 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15344 gen_rtx_REG (CCmode, FLAGS_REG),
15346 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15348 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15352 (define_insn_and_split "paritysi2_cmp"
15353 [(set (reg:CC FLAGS_REG)
15354 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15355 (clobber (match_scratch:SI 0 "=r"))
15356 (clobber (match_scratch:HI 1 "=&Q"))]
15359 "&& reload_completed"
15361 [(set (match_dup 1)
15362 (xor:HI (match_dup 1) (match_dup 3)))
15363 (clobber (reg:CC FLAGS_REG))])
15365 [(set (reg:CC FLAGS_REG)
15366 (parity:CC (match_dup 1)))
15367 (clobber (match_dup 1))])]
15369 operands[3] = gen_lowpart (HImode, operands[2]);
15371 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15372 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15375 (define_insn "*parityhi2_cmp"
15376 [(set (reg:CC FLAGS_REG)
15377 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15378 (clobber (match_scratch:HI 0 "=Q"))]
15380 "xor{b}\t{%h0, %b0|%b0, %h0}"
15381 [(set_attr "length" "2")
15382 (set_attr "mode" "HI")])
15384 (define_insn "*parityqi2_cmp"
15385 [(set (reg:CC FLAGS_REG)
15386 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15389 [(set_attr "length" "2")
15390 (set_attr "mode" "QI")])
15392 ;; Thread-local storage patterns for ELF.
15394 ;; Note that these code sequences must appear exactly as shown
15395 ;; in order to allow linker relaxation.
15397 (define_insn "*tls_global_dynamic_32_gnu"
15398 [(set (match_operand:SI 0 "register_operand" "=a")
15399 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15400 (match_operand:SI 2 "tls_symbolic_operand" "")
15401 (match_operand:SI 3 "call_insn_operand" "")]
15403 (clobber (match_scratch:SI 4 "=d"))
15404 (clobber (match_scratch:SI 5 "=c"))
15405 (clobber (reg:CC FLAGS_REG))]
15406 "!TARGET_64BIT && TARGET_GNU_TLS"
15407 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15408 [(set_attr "type" "multi")
15409 (set_attr "length" "12")])
15411 (define_insn "*tls_global_dynamic_32_sun"
15412 [(set (match_operand:SI 0 "register_operand" "=a")
15413 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15414 (match_operand:SI 2 "tls_symbolic_operand" "")
15415 (match_operand:SI 3 "call_insn_operand" "")]
15417 (clobber (match_scratch:SI 4 "=d"))
15418 (clobber (match_scratch:SI 5 "=c"))
15419 (clobber (reg:CC FLAGS_REG))]
15420 "!TARGET_64BIT && TARGET_SUN_TLS"
15421 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15422 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15423 [(set_attr "type" "multi")
15424 (set_attr "length" "14")])
15426 (define_expand "tls_global_dynamic_32"
15427 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15430 (match_operand:SI 1 "tls_symbolic_operand" "")
15433 (clobber (match_scratch:SI 4 ""))
15434 (clobber (match_scratch:SI 5 ""))
15435 (clobber (reg:CC FLAGS_REG))])]
15439 operands[2] = pic_offset_table_rtx;
15442 operands[2] = gen_reg_rtx (Pmode);
15443 emit_insn (gen_set_got (operands[2]));
15445 if (TARGET_GNU2_TLS)
15447 emit_insn (gen_tls_dynamic_gnu2_32
15448 (operands[0], operands[1], operands[2]));
15451 operands[3] = ix86_tls_get_addr ();
15454 (define_insn "*tls_global_dynamic_64"
15455 [(set (match_operand:DI 0 "register_operand" "=a")
15456 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15457 (match_operand:DI 3 "" "")))
15458 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15461 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15462 [(set_attr "type" "multi")
15463 (set_attr "length" "16")])
15465 (define_expand "tls_global_dynamic_64"
15466 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15467 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15468 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15472 if (TARGET_GNU2_TLS)
15474 emit_insn (gen_tls_dynamic_gnu2_64
15475 (operands[0], operands[1]));
15478 operands[2] = ix86_tls_get_addr ();
15481 (define_insn "*tls_local_dynamic_base_32_gnu"
15482 [(set (match_operand:SI 0 "register_operand" "=a")
15483 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15484 (match_operand:SI 2 "call_insn_operand" "")]
15485 UNSPEC_TLS_LD_BASE))
15486 (clobber (match_scratch:SI 3 "=d"))
15487 (clobber (match_scratch:SI 4 "=c"))
15488 (clobber (reg:CC FLAGS_REG))]
15489 "!TARGET_64BIT && TARGET_GNU_TLS"
15490 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15491 [(set_attr "type" "multi")
15492 (set_attr "length" "11")])
15494 (define_insn "*tls_local_dynamic_base_32_sun"
15495 [(set (match_operand:SI 0 "register_operand" "=a")
15496 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15497 (match_operand:SI 2 "call_insn_operand" "")]
15498 UNSPEC_TLS_LD_BASE))
15499 (clobber (match_scratch:SI 3 "=d"))
15500 (clobber (match_scratch:SI 4 "=c"))
15501 (clobber (reg:CC FLAGS_REG))]
15502 "!TARGET_64BIT && TARGET_SUN_TLS"
15503 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15504 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15505 [(set_attr "type" "multi")
15506 (set_attr "length" "13")])
15508 (define_expand "tls_local_dynamic_base_32"
15509 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15510 (unspec:SI [(match_dup 1) (match_dup 2)]
15511 UNSPEC_TLS_LD_BASE))
15512 (clobber (match_scratch:SI 3 ""))
15513 (clobber (match_scratch:SI 4 ""))
15514 (clobber (reg:CC FLAGS_REG))])]
15518 operands[1] = pic_offset_table_rtx;
15521 operands[1] = gen_reg_rtx (Pmode);
15522 emit_insn (gen_set_got (operands[1]));
15524 if (TARGET_GNU2_TLS)
15526 emit_insn (gen_tls_dynamic_gnu2_32
15527 (operands[0], ix86_tls_module_base (), operands[1]));
15530 operands[2] = ix86_tls_get_addr ();
15533 (define_insn "*tls_local_dynamic_base_64"
15534 [(set (match_operand:DI 0 "register_operand" "=a")
15535 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15536 (match_operand:DI 2 "" "")))
15537 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15539 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15540 [(set_attr "type" "multi")
15541 (set_attr "length" "12")])
15543 (define_expand "tls_local_dynamic_base_64"
15544 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15545 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15546 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15549 if (TARGET_GNU2_TLS)
15551 emit_insn (gen_tls_dynamic_gnu2_64
15552 (operands[0], ix86_tls_module_base ()));
15555 operands[1] = ix86_tls_get_addr ();
15558 ;; Local dynamic of a single variable is a lose. Show combine how
15559 ;; to convert that back to global dynamic.
15561 (define_insn_and_split "*tls_local_dynamic_32_once"
15562 [(set (match_operand:SI 0 "register_operand" "=a")
15563 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15564 (match_operand:SI 2 "call_insn_operand" "")]
15565 UNSPEC_TLS_LD_BASE)
15566 (const:SI (unspec:SI
15567 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15569 (clobber (match_scratch:SI 4 "=d"))
15570 (clobber (match_scratch:SI 5 "=c"))
15571 (clobber (reg:CC FLAGS_REG))]
15575 [(parallel [(set (match_dup 0)
15576 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15578 (clobber (match_dup 4))
15579 (clobber (match_dup 5))
15580 (clobber (reg:CC FLAGS_REG))])]
15583 ;; Load and add the thread base pointer from %gs:0.
15585 (define_insn "*load_tp_si"
15586 [(set (match_operand:SI 0 "register_operand" "=r")
15587 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15589 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15590 [(set_attr "type" "imov")
15591 (set_attr "modrm" "0")
15592 (set_attr "length" "7")
15593 (set_attr "memory" "load")
15594 (set_attr "imm_disp" "false")])
15596 (define_insn "*add_tp_si"
15597 [(set (match_operand:SI 0 "register_operand" "=r")
15598 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15599 (match_operand:SI 1 "register_operand" "0")))
15600 (clobber (reg:CC FLAGS_REG))]
15602 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15603 [(set_attr "type" "alu")
15604 (set_attr "modrm" "0")
15605 (set_attr "length" "7")
15606 (set_attr "memory" "load")
15607 (set_attr "imm_disp" "false")])
15609 (define_insn "*load_tp_di"
15610 [(set (match_operand:DI 0 "register_operand" "=r")
15611 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15613 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15614 [(set_attr "type" "imov")
15615 (set_attr "modrm" "0")
15616 (set_attr "length" "7")
15617 (set_attr "memory" "load")
15618 (set_attr "imm_disp" "false")])
15620 (define_insn "*add_tp_di"
15621 [(set (match_operand:DI 0 "register_operand" "=r")
15622 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15623 (match_operand:DI 1 "register_operand" "0")))
15624 (clobber (reg:CC FLAGS_REG))]
15626 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15627 [(set_attr "type" "alu")
15628 (set_attr "modrm" "0")
15629 (set_attr "length" "7")
15630 (set_attr "memory" "load")
15631 (set_attr "imm_disp" "false")])
15633 ;; GNU2 TLS patterns can be split.
15635 (define_expand "tls_dynamic_gnu2_32"
15636 [(set (match_dup 3)
15637 (plus:SI (match_operand:SI 2 "register_operand" "")
15639 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15642 [(set (match_operand:SI 0 "register_operand" "")
15643 (unspec:SI [(match_dup 1) (match_dup 3)
15644 (match_dup 2) (reg:SI SP_REG)]
15646 (clobber (reg:CC FLAGS_REG))])]
15647 "!TARGET_64BIT && TARGET_GNU2_TLS"
15649 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15650 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15653 (define_insn "*tls_dynamic_lea_32"
15654 [(set (match_operand:SI 0 "register_operand" "=r")
15655 (plus:SI (match_operand:SI 1 "register_operand" "b")
15657 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15658 UNSPEC_TLSDESC))))]
15659 "!TARGET_64BIT && TARGET_GNU2_TLS"
15660 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15661 [(set_attr "type" "lea")
15662 (set_attr "mode" "SI")
15663 (set_attr "length" "6")
15664 (set_attr "length_address" "4")])
15666 (define_insn "*tls_dynamic_call_32"
15667 [(set (match_operand:SI 0 "register_operand" "=a")
15668 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15669 (match_operand:SI 2 "register_operand" "0")
15670 ;; we have to make sure %ebx still points to the GOT
15671 (match_operand:SI 3 "register_operand" "b")
15674 (clobber (reg:CC FLAGS_REG))]
15675 "!TARGET_64BIT && TARGET_GNU2_TLS"
15676 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15677 [(set_attr "type" "call")
15678 (set_attr "length" "2")
15679 (set_attr "length_address" "0")])
15681 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15682 [(set (match_operand:SI 0 "register_operand" "=&a")
15684 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15685 (match_operand:SI 4 "" "")
15686 (match_operand:SI 2 "register_operand" "b")
15689 (const:SI (unspec:SI
15690 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15692 (clobber (reg:CC FLAGS_REG))]
15693 "!TARGET_64BIT && TARGET_GNU2_TLS"
15696 [(set (match_dup 0) (match_dup 5))]
15698 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15699 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15702 (define_expand "tls_dynamic_gnu2_64"
15703 [(set (match_dup 2)
15704 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15707 [(set (match_operand:DI 0 "register_operand" "")
15708 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15710 (clobber (reg:CC FLAGS_REG))])]
15711 "TARGET_64BIT && TARGET_GNU2_TLS"
15713 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15714 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15717 (define_insn "*tls_dynamic_lea_64"
15718 [(set (match_operand:DI 0 "register_operand" "=r")
15719 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15721 "TARGET_64BIT && TARGET_GNU2_TLS"
15722 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15723 [(set_attr "type" "lea")
15724 (set_attr "mode" "DI")
15725 (set_attr "length" "7")
15726 (set_attr "length_address" "4")])
15728 (define_insn "*tls_dynamic_call_64"
15729 [(set (match_operand:DI 0 "register_operand" "=a")
15730 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15731 (match_operand:DI 2 "register_operand" "0")
15734 (clobber (reg:CC FLAGS_REG))]
15735 "TARGET_64BIT && TARGET_GNU2_TLS"
15736 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15737 [(set_attr "type" "call")
15738 (set_attr "length" "2")
15739 (set_attr "length_address" "0")])
15741 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15742 [(set (match_operand:DI 0 "register_operand" "=&a")
15744 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15745 (match_operand:DI 3 "" "")
15748 (const:DI (unspec:DI
15749 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15751 (clobber (reg:CC FLAGS_REG))]
15752 "TARGET_64BIT && TARGET_GNU2_TLS"
15755 [(set (match_dup 0) (match_dup 4))]
15757 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15758 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15763 ;; These patterns match the binary 387 instructions for addM3, subM3,
15764 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15765 ;; SFmode. The first is the normal insn, the second the same insn but
15766 ;; with one operand a conversion, and the third the same insn but with
15767 ;; the other operand a conversion. The conversion may be SFmode or
15768 ;; SImode if the target mode DFmode, but only SImode if the target mode
15771 ;; Gcc is slightly more smart about handling normal two address instructions
15772 ;; so use special patterns for add and mull.
15774 (define_insn "*fop_sf_comm_mixed"
15775 [(set (match_operand:SF 0 "register_operand" "=f,x")
15776 (match_operator:SF 3 "binary_fp_operator"
15777 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15778 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15779 "TARGET_MIX_SSE_I387
15780 && COMMUTATIVE_ARITH_P (operands[3])
15781 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15782 "* return output_387_binary_op (insn, operands);"
15783 [(set (attr "type")
15784 (if_then_else (eq_attr "alternative" "1")
15785 (if_then_else (match_operand:SF 3 "mult_operator" "")
15786 (const_string "ssemul")
15787 (const_string "sseadd"))
15788 (if_then_else (match_operand:SF 3 "mult_operator" "")
15789 (const_string "fmul")
15790 (const_string "fop"))))
15791 (set_attr "mode" "SF")])
15793 (define_insn "*fop_sf_comm_sse"
15794 [(set (match_operand:SF 0 "register_operand" "=x")
15795 (match_operator:SF 3 "binary_fp_operator"
15796 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15797 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15799 && COMMUTATIVE_ARITH_P (operands[3])
15800 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15801 "* return output_387_binary_op (insn, operands);"
15802 [(set (attr "type")
15803 (if_then_else (match_operand:SF 3 "mult_operator" "")
15804 (const_string "ssemul")
15805 (const_string "sseadd")))
15806 (set_attr "mode" "SF")])
15808 (define_insn "*fop_sf_comm_i387"
15809 [(set (match_operand:SF 0 "register_operand" "=f")
15810 (match_operator:SF 3 "binary_fp_operator"
15811 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15812 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15814 && COMMUTATIVE_ARITH_P (operands[3])
15815 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15816 "* return output_387_binary_op (insn, operands);"
15817 [(set (attr "type")
15818 (if_then_else (match_operand:SF 3 "mult_operator" "")
15819 (const_string "fmul")
15820 (const_string "fop")))
15821 (set_attr "mode" "SF")])
15823 (define_insn "*fop_sf_1_mixed"
15824 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15825 (match_operator:SF 3 "binary_fp_operator"
15826 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15827 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15828 "TARGET_MIX_SSE_I387
15829 && !COMMUTATIVE_ARITH_P (operands[3])
15830 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15831 "* return output_387_binary_op (insn, operands);"
15832 [(set (attr "type")
15833 (cond [(and (eq_attr "alternative" "2")
15834 (match_operand:SF 3 "mult_operator" ""))
15835 (const_string "ssemul")
15836 (and (eq_attr "alternative" "2")
15837 (match_operand:SF 3 "div_operator" ""))
15838 (const_string "ssediv")
15839 (eq_attr "alternative" "2")
15840 (const_string "sseadd")
15841 (match_operand:SF 3 "mult_operator" "")
15842 (const_string "fmul")
15843 (match_operand:SF 3 "div_operator" "")
15844 (const_string "fdiv")
15846 (const_string "fop")))
15847 (set_attr "mode" "SF")])
15849 (define_insn "*rcpsf2_sse"
15850 [(set (match_operand:SF 0 "register_operand" "=x")
15851 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15854 "rcpss\t{%1, %0|%0, %1}"
15855 [(set_attr "type" "sse")
15856 (set_attr "mode" "SF")])
15858 (define_insn "*fop_sf_1_sse"
15859 [(set (match_operand:SF 0 "register_operand" "=x")
15860 (match_operator:SF 3 "binary_fp_operator"
15861 [(match_operand:SF 1 "register_operand" "0")
15862 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15864 && !COMMUTATIVE_ARITH_P (operands[3])"
15865 "* return output_387_binary_op (insn, operands);"
15866 [(set (attr "type")
15867 (cond [(match_operand:SF 3 "mult_operator" "")
15868 (const_string "ssemul")
15869 (match_operand:SF 3 "div_operator" "")
15870 (const_string "ssediv")
15872 (const_string "sseadd")))
15873 (set_attr "mode" "SF")])
15875 ;; This pattern is not fully shadowed by the pattern above.
15876 (define_insn "*fop_sf_1_i387"
15877 [(set (match_operand:SF 0 "register_operand" "=f,f")
15878 (match_operator:SF 3 "binary_fp_operator"
15879 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15880 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15881 "TARGET_80387 && !TARGET_SSE_MATH
15882 && !COMMUTATIVE_ARITH_P (operands[3])
15883 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15884 "* return output_387_binary_op (insn, operands);"
15885 [(set (attr "type")
15886 (cond [(match_operand:SF 3 "mult_operator" "")
15887 (const_string "fmul")
15888 (match_operand:SF 3 "div_operator" "")
15889 (const_string "fdiv")
15891 (const_string "fop")))
15892 (set_attr "mode" "SF")])
15894 ;; ??? Add SSE splitters for these!
15895 (define_insn "*fop_sf_2<mode>_i387"
15896 [(set (match_operand:SF 0 "register_operand" "=f,f")
15897 (match_operator:SF 3 "binary_fp_operator"
15898 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15899 (match_operand:SF 2 "register_operand" "0,0")]))]
15900 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15901 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15902 [(set (attr "type")
15903 (cond [(match_operand:SF 3 "mult_operator" "")
15904 (const_string "fmul")
15905 (match_operand:SF 3 "div_operator" "")
15906 (const_string "fdiv")
15908 (const_string "fop")))
15909 (set_attr "fp_int_src" "true")
15910 (set_attr "mode" "<MODE>")])
15912 (define_insn "*fop_sf_3<mode>_i387"
15913 [(set (match_operand:SF 0 "register_operand" "=f,f")
15914 (match_operator:SF 3 "binary_fp_operator"
15915 [(match_operand:SF 1 "register_operand" "0,0")
15916 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15917 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15918 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15919 [(set (attr "type")
15920 (cond [(match_operand:SF 3 "mult_operator" "")
15921 (const_string "fmul")
15922 (match_operand:SF 3 "div_operator" "")
15923 (const_string "fdiv")
15925 (const_string "fop")))
15926 (set_attr "fp_int_src" "true")
15927 (set_attr "mode" "<MODE>")])
15929 (define_insn "*fop_df_comm_mixed"
15930 [(set (match_operand:DF 0 "register_operand" "=f,x")
15931 (match_operator:DF 3 "binary_fp_operator"
15932 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15933 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15934 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15935 && COMMUTATIVE_ARITH_P (operands[3])
15936 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15937 "* return output_387_binary_op (insn, operands);"
15938 [(set (attr "type")
15939 (if_then_else (eq_attr "alternative" "1")
15940 (if_then_else (match_operand:DF 3 "mult_operator" "")
15941 (const_string "ssemul")
15942 (const_string "sseadd"))
15943 (if_then_else (match_operand:DF 3 "mult_operator" "")
15944 (const_string "fmul")
15945 (const_string "fop"))))
15946 (set_attr "mode" "DF")])
15948 (define_insn "*fop_df_comm_sse"
15949 [(set (match_operand:DF 0 "register_operand" "=x")
15950 (match_operator:DF 3 "binary_fp_operator"
15951 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15952 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15953 "TARGET_SSE2 && TARGET_SSE_MATH
15954 && COMMUTATIVE_ARITH_P (operands[3])
15955 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15956 "* return output_387_binary_op (insn, operands);"
15957 [(set (attr "type")
15958 (if_then_else (match_operand:DF 3 "mult_operator" "")
15959 (const_string "ssemul")
15960 (const_string "sseadd")))
15961 (set_attr "mode" "DF")])
15963 (define_insn "*fop_df_comm_i387"
15964 [(set (match_operand:DF 0 "register_operand" "=f")
15965 (match_operator:DF 3 "binary_fp_operator"
15966 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15967 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15969 && COMMUTATIVE_ARITH_P (operands[3])
15970 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15971 "* return output_387_binary_op (insn, operands);"
15972 [(set (attr "type")
15973 (if_then_else (match_operand:DF 3 "mult_operator" "")
15974 (const_string "fmul")
15975 (const_string "fop")))
15976 (set_attr "mode" "DF")])
15978 (define_insn "*fop_df_1_mixed"
15979 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15980 (match_operator:DF 3 "binary_fp_operator"
15981 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15982 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15983 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15984 && !COMMUTATIVE_ARITH_P (operands[3])
15985 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15986 "* return output_387_binary_op (insn, operands);"
15987 [(set (attr "type")
15988 (cond [(and (eq_attr "alternative" "2")
15989 (match_operand:DF 3 "mult_operator" ""))
15990 (const_string "ssemul")
15991 (and (eq_attr "alternative" "2")
15992 (match_operand:DF 3 "div_operator" ""))
15993 (const_string "ssediv")
15994 (eq_attr "alternative" "2")
15995 (const_string "sseadd")
15996 (match_operand:DF 3 "mult_operator" "")
15997 (const_string "fmul")
15998 (match_operand:DF 3 "div_operator" "")
15999 (const_string "fdiv")
16001 (const_string "fop")))
16002 (set_attr "mode" "DF")])
16004 (define_insn "*fop_df_1_sse"
16005 [(set (match_operand:DF 0 "register_operand" "=x")
16006 (match_operator:DF 3 "binary_fp_operator"
16007 [(match_operand:DF 1 "register_operand" "0")
16008 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16009 "TARGET_SSE2 && TARGET_SSE_MATH
16010 && !COMMUTATIVE_ARITH_P (operands[3])"
16011 "* return output_387_binary_op (insn, operands);"
16012 [(set_attr "mode" "DF")
16014 (cond [(match_operand:DF 3 "mult_operator" "")
16015 (const_string "ssemul")
16016 (match_operand:DF 3 "div_operator" "")
16017 (const_string "ssediv")
16019 (const_string "sseadd")))])
16021 ;; This pattern is not fully shadowed by the pattern above.
16022 (define_insn "*fop_df_1_i387"
16023 [(set (match_operand:DF 0 "register_operand" "=f,f")
16024 (match_operator:DF 3 "binary_fp_operator"
16025 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16026 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16027 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16028 && !COMMUTATIVE_ARITH_P (operands[3])
16029 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16030 "* return output_387_binary_op (insn, operands);"
16031 [(set (attr "type")
16032 (cond [(match_operand:DF 3 "mult_operator" "")
16033 (const_string "fmul")
16034 (match_operand:DF 3 "div_operator" "")
16035 (const_string "fdiv")
16037 (const_string "fop")))
16038 (set_attr "mode" "DF")])
16040 ;; ??? Add SSE splitters for these!
16041 (define_insn "*fop_df_2<mode>_i387"
16042 [(set (match_operand:DF 0 "register_operand" "=f,f")
16043 (match_operator:DF 3 "binary_fp_operator"
16044 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16045 (match_operand:DF 2 "register_operand" "0,0")]))]
16046 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16047 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16048 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16049 [(set (attr "type")
16050 (cond [(match_operand:DF 3 "mult_operator" "")
16051 (const_string "fmul")
16052 (match_operand:DF 3 "div_operator" "")
16053 (const_string "fdiv")
16055 (const_string "fop")))
16056 (set_attr "fp_int_src" "true")
16057 (set_attr "mode" "<MODE>")])
16059 (define_insn "*fop_df_3<mode>_i387"
16060 [(set (match_operand:DF 0 "register_operand" "=f,f")
16061 (match_operator:DF 3 "binary_fp_operator"
16062 [(match_operand:DF 1 "register_operand" "0,0")
16063 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16064 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16065 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16066 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16067 [(set (attr "type")
16068 (cond [(match_operand:DF 3 "mult_operator" "")
16069 (const_string "fmul")
16070 (match_operand:DF 3 "div_operator" "")
16071 (const_string "fdiv")
16073 (const_string "fop")))
16074 (set_attr "fp_int_src" "true")
16075 (set_attr "mode" "<MODE>")])
16077 (define_insn "*fop_df_4_i387"
16078 [(set (match_operand:DF 0 "register_operand" "=f,f")
16079 (match_operator:DF 3 "binary_fp_operator"
16080 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16081 (match_operand:DF 2 "register_operand" "0,f")]))]
16082 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16083 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16084 "* return output_387_binary_op (insn, operands);"
16085 [(set (attr "type")
16086 (cond [(match_operand:DF 3 "mult_operator" "")
16087 (const_string "fmul")
16088 (match_operand:DF 3 "div_operator" "")
16089 (const_string "fdiv")
16091 (const_string "fop")))
16092 (set_attr "mode" "SF")])
16094 (define_insn "*fop_df_5_i387"
16095 [(set (match_operand:DF 0 "register_operand" "=f,f")
16096 (match_operator:DF 3 "binary_fp_operator"
16097 [(match_operand:DF 1 "register_operand" "0,f")
16099 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16100 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16101 "* return output_387_binary_op (insn, operands);"
16102 [(set (attr "type")
16103 (cond [(match_operand:DF 3 "mult_operator" "")
16104 (const_string "fmul")
16105 (match_operand:DF 3 "div_operator" "")
16106 (const_string "fdiv")
16108 (const_string "fop")))
16109 (set_attr "mode" "SF")])
16111 (define_insn "*fop_df_6_i387"
16112 [(set (match_operand:DF 0 "register_operand" "=f,f")
16113 (match_operator:DF 3 "binary_fp_operator"
16115 (match_operand:SF 1 "register_operand" "0,f"))
16117 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16118 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16119 "* return output_387_binary_op (insn, operands);"
16120 [(set (attr "type")
16121 (cond [(match_operand:DF 3 "mult_operator" "")
16122 (const_string "fmul")
16123 (match_operand:DF 3 "div_operator" "")
16124 (const_string "fdiv")
16126 (const_string "fop")))
16127 (set_attr "mode" "SF")])
16129 (define_insn "*fop_xf_comm_i387"
16130 [(set (match_operand:XF 0 "register_operand" "=f")
16131 (match_operator:XF 3 "binary_fp_operator"
16132 [(match_operand:XF 1 "register_operand" "%0")
16133 (match_operand:XF 2 "register_operand" "f")]))]
16135 && COMMUTATIVE_ARITH_P (operands[3])"
16136 "* return output_387_binary_op (insn, operands);"
16137 [(set (attr "type")
16138 (if_then_else (match_operand:XF 3 "mult_operator" "")
16139 (const_string "fmul")
16140 (const_string "fop")))
16141 (set_attr "mode" "XF")])
16143 (define_insn "*fop_xf_1_i387"
16144 [(set (match_operand:XF 0 "register_operand" "=f,f")
16145 (match_operator:XF 3 "binary_fp_operator"
16146 [(match_operand:XF 1 "register_operand" "0,f")
16147 (match_operand:XF 2 "register_operand" "f,0")]))]
16149 && !COMMUTATIVE_ARITH_P (operands[3])"
16150 "* return output_387_binary_op (insn, operands);"
16151 [(set (attr "type")
16152 (cond [(match_operand:XF 3 "mult_operator" "")
16153 (const_string "fmul")
16154 (match_operand:XF 3 "div_operator" "")
16155 (const_string "fdiv")
16157 (const_string "fop")))
16158 (set_attr "mode" "XF")])
16160 (define_insn "*fop_xf_2<mode>_i387"
16161 [(set (match_operand:XF 0 "register_operand" "=f,f")
16162 (match_operator:XF 3 "binary_fp_operator"
16163 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16164 (match_operand:XF 2 "register_operand" "0,0")]))]
16165 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16166 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16167 [(set (attr "type")
16168 (cond [(match_operand:XF 3 "mult_operator" "")
16169 (const_string "fmul")
16170 (match_operand:XF 3 "div_operator" "")
16171 (const_string "fdiv")
16173 (const_string "fop")))
16174 (set_attr "fp_int_src" "true")
16175 (set_attr "mode" "<MODE>")])
16177 (define_insn "*fop_xf_3<mode>_i387"
16178 [(set (match_operand:XF 0 "register_operand" "=f,f")
16179 (match_operator:XF 3 "binary_fp_operator"
16180 [(match_operand:XF 1 "register_operand" "0,0")
16181 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16182 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16183 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16184 [(set (attr "type")
16185 (cond [(match_operand:XF 3 "mult_operator" "")
16186 (const_string "fmul")
16187 (match_operand:XF 3 "div_operator" "")
16188 (const_string "fdiv")
16190 (const_string "fop")))
16191 (set_attr "fp_int_src" "true")
16192 (set_attr "mode" "<MODE>")])
16194 (define_insn "*fop_xf_4_i387"
16195 [(set (match_operand:XF 0 "register_operand" "=f,f")
16196 (match_operator:XF 3 "binary_fp_operator"
16198 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16199 (match_operand:XF 2 "register_operand" "0,f")]))]
16201 "* return output_387_binary_op (insn, operands);"
16202 [(set (attr "type")
16203 (cond [(match_operand:XF 3 "mult_operator" "")
16204 (const_string "fmul")
16205 (match_operand:XF 3 "div_operator" "")
16206 (const_string "fdiv")
16208 (const_string "fop")))
16209 (set_attr "mode" "SF")])
16211 (define_insn "*fop_xf_5_i387"
16212 [(set (match_operand:XF 0 "register_operand" "=f,f")
16213 (match_operator:XF 3 "binary_fp_operator"
16214 [(match_operand:XF 1 "register_operand" "0,f")
16216 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16218 "* return output_387_binary_op (insn, operands);"
16219 [(set (attr "type")
16220 (cond [(match_operand:XF 3 "mult_operator" "")
16221 (const_string "fmul")
16222 (match_operand:XF 3 "div_operator" "")
16223 (const_string "fdiv")
16225 (const_string "fop")))
16226 (set_attr "mode" "SF")])
16228 (define_insn "*fop_xf_6_i387"
16229 [(set (match_operand:XF 0 "register_operand" "=f,f")
16230 (match_operator:XF 3 "binary_fp_operator"
16232 (match_operand:MODEF 1 "register_operand" "0,f"))
16234 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16236 "* return output_387_binary_op (insn, operands);"
16237 [(set (attr "type")
16238 (cond [(match_operand:XF 3 "mult_operator" "")
16239 (const_string "fmul")
16240 (match_operand:XF 3 "div_operator" "")
16241 (const_string "fdiv")
16243 (const_string "fop")))
16244 (set_attr "mode" "SF")])
16247 [(set (match_operand 0 "register_operand" "")
16248 (match_operator 3 "binary_fp_operator"
16249 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16250 (match_operand 2 "register_operand" "")]))]
16252 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16255 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16256 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16257 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16258 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16259 GET_MODE (operands[3]),
16262 ix86_free_from_memory (GET_MODE (operands[1]));
16267 [(set (match_operand 0 "register_operand" "")
16268 (match_operator 3 "binary_fp_operator"
16269 [(match_operand 1 "register_operand" "")
16270 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16272 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16275 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16276 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16277 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16278 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16279 GET_MODE (operands[3]),
16282 ix86_free_from_memory (GET_MODE (operands[2]));
16286 ;; FPU special functions.
16288 ;; This pattern implements a no-op XFmode truncation for
16289 ;; all fancy i386 XFmode math functions.
16291 (define_insn "truncxf<mode>2_i387_noop_unspec"
16292 [(set (match_operand:MODEF 0 "register_operand" "=f")
16293 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16294 UNSPEC_TRUNC_NOOP))]
16295 "TARGET_USE_FANCY_MATH_387"
16296 "* return output_387_reg_move (insn, operands);"
16297 [(set_attr "type" "fmov")
16298 (set_attr "mode" "<MODE>")])
16300 (define_insn "sqrtxf2"
16301 [(set (match_operand:XF 0 "register_operand" "=f")
16302 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16303 "TARGET_USE_FANCY_MATH_387"
16305 [(set_attr "type" "fpspc")
16306 (set_attr "mode" "XF")
16307 (set_attr "athlon_decode" "direct")
16308 (set_attr "amdfam10_decode" "direct")])
16310 (define_insn "sqrt_extend<mode>xf2_i387"
16311 [(set (match_operand:XF 0 "register_operand" "=f")
16314 (match_operand:MODEF 1 "register_operand" "0"))))]
16315 "TARGET_USE_FANCY_MATH_387"
16317 [(set_attr "type" "fpspc")
16318 (set_attr "mode" "XF")
16319 (set_attr "athlon_decode" "direct")
16320 (set_attr "amdfam10_decode" "direct")])
16322 (define_insn "*rsqrtsf2_sse"
16323 [(set (match_operand:SF 0 "register_operand" "=x")
16324 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16327 "rsqrtss\t{%1, %0|%0, %1}"
16328 [(set_attr "type" "sse")
16329 (set_attr "mode" "SF")])
16331 (define_expand "rsqrtsf2"
16332 [(set (match_operand:SF 0 "register_operand" "")
16333 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16337 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16341 (define_insn "*sqrt<mode>2_sse"
16342 [(set (match_operand:MODEF 0 "register_operand" "=x")
16344 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16345 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16346 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16347 [(set_attr "type" "sse")
16348 (set_attr "mode" "<MODE>")
16349 (set_attr "athlon_decode" "*")
16350 (set_attr "amdfam10_decode" "*")])
16352 (define_expand "sqrt<mode>2"
16353 [(set (match_operand:MODEF 0 "register_operand" "")
16355 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16356 "TARGET_USE_FANCY_MATH_387
16357 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16359 if (<MODE>mode == SFmode
16360 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16361 && flag_finite_math_only && !flag_trapping_math
16362 && flag_unsafe_math_optimizations)
16364 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16368 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16370 rtx op0 = gen_reg_rtx (XFmode);
16371 rtx op1 = force_reg (<MODE>mode, operands[1]);
16373 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16374 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16379 (define_insn "fpremxf4_i387"
16380 [(set (match_operand:XF 0 "register_operand" "=f")
16381 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16382 (match_operand:XF 3 "register_operand" "1")]
16384 (set (match_operand:XF 1 "register_operand" "=u")
16385 (unspec:XF [(match_dup 2) (match_dup 3)]
16387 (set (reg:CCFP FPSR_REG)
16388 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16390 "TARGET_USE_FANCY_MATH_387"
16392 [(set_attr "type" "fpspc")
16393 (set_attr "mode" "XF")])
16395 (define_expand "fmodxf3"
16396 [(use (match_operand:XF 0 "register_operand" ""))
16397 (use (match_operand:XF 1 "register_operand" ""))
16398 (use (match_operand:XF 2 "register_operand" ""))]
16399 "TARGET_USE_FANCY_MATH_387"
16401 rtx label = gen_label_rtx ();
16405 if (rtx_equal_p (operands[1], operands[2]))
16407 op2 = gen_reg_rtx (XFmode);
16408 emit_move_insn (op2, operands[2]);
16413 emit_label (label);
16414 emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16415 ix86_emit_fp_unordered_jump (label);
16416 LABEL_NUSES (label) = 1;
16418 emit_move_insn (operands[0], operands[1]);
16422 (define_expand "fmod<mode>3"
16423 [(use (match_operand:MODEF 0 "register_operand" ""))
16424 (use (match_operand:MODEF 1 "general_operand" ""))
16425 (use (match_operand:MODEF 2 "general_operand" ""))]
16426 "TARGET_USE_FANCY_MATH_387"
16428 rtx label = gen_label_rtx ();
16430 rtx op1 = gen_reg_rtx (XFmode);
16431 rtx op2 = gen_reg_rtx (XFmode);
16433 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16434 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16436 emit_label (label);
16437 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16438 ix86_emit_fp_unordered_jump (label);
16439 LABEL_NUSES (label) = 1;
16441 /* Truncate the result properly for strict SSE math. */
16442 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16443 && !TARGET_MIX_SSE_I387)
16444 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16446 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16451 (define_insn "fprem1xf4_i387"
16452 [(set (match_operand:XF 0 "register_operand" "=f")
16453 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16454 (match_operand:XF 3 "register_operand" "1")]
16456 (set (match_operand:XF 1 "register_operand" "=u")
16457 (unspec:XF [(match_dup 2) (match_dup 3)]
16459 (set (reg:CCFP FPSR_REG)
16460 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16462 "TARGET_USE_FANCY_MATH_387"
16464 [(set_attr "type" "fpspc")
16465 (set_attr "mode" "XF")])
16467 (define_expand "remainderxf3"
16468 [(use (match_operand:XF 0 "register_operand" ""))
16469 (use (match_operand:XF 1 "register_operand" ""))
16470 (use (match_operand:XF 2 "register_operand" ""))]
16471 "TARGET_USE_FANCY_MATH_387"
16473 rtx label = gen_label_rtx ();
16477 if (rtx_equal_p (operands[1], operands[2]))
16479 op2 = gen_reg_rtx (XFmode);
16480 emit_move_insn (op2, operands[2]);
16485 emit_label (label);
16486 emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16487 ix86_emit_fp_unordered_jump (label);
16488 LABEL_NUSES (label) = 1;
16490 emit_move_insn (operands[0], operands[1]);
16494 (define_expand "remainder<mode>3"
16495 [(use (match_operand:MODEF 0 "register_operand" ""))
16496 (use (match_operand:MODEF 1 "general_operand" ""))
16497 (use (match_operand:MODEF 2 "general_operand" ""))]
16498 "TARGET_USE_FANCY_MATH_387"
16500 rtx label = gen_label_rtx ();
16502 rtx op1 = gen_reg_rtx (XFmode);
16503 rtx op2 = gen_reg_rtx (XFmode);
16505 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16506 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16508 emit_label (label);
16510 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16511 ix86_emit_fp_unordered_jump (label);
16512 LABEL_NUSES (label) = 1;
16514 /* Truncate the result properly for strict SSE math. */
16515 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16516 && !TARGET_MIX_SSE_I387)
16517 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16519 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16524 (define_insn "*sinxf2_i387"
16525 [(set (match_operand:XF 0 "register_operand" "=f")
16526 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16527 "TARGET_USE_FANCY_MATH_387
16528 && flag_unsafe_math_optimizations"
16530 [(set_attr "type" "fpspc")
16531 (set_attr "mode" "XF")])
16533 (define_insn "*sin_extend<mode>xf2_i387"
16534 [(set (match_operand:XF 0 "register_operand" "=f")
16535 (unspec:XF [(float_extend:XF
16536 (match_operand:MODEF 1 "register_operand" "0"))]
16538 "TARGET_USE_FANCY_MATH_387
16539 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16540 || TARGET_MIX_SSE_I387)
16541 && flag_unsafe_math_optimizations"
16543 [(set_attr "type" "fpspc")
16544 (set_attr "mode" "XF")])
16546 (define_insn "*cosxf2_i387"
16547 [(set (match_operand:XF 0 "register_operand" "=f")
16548 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16549 "TARGET_USE_FANCY_MATH_387
16550 && flag_unsafe_math_optimizations"
16552 [(set_attr "type" "fpspc")
16553 (set_attr "mode" "XF")])
16555 (define_insn "*cos_extend<mode>xf2_i387"
16556 [(set (match_operand:XF 0 "register_operand" "=f")
16557 (unspec:XF [(float_extend:XF
16558 (match_operand:MODEF 1 "register_operand" "0"))]
16560 "TARGET_USE_FANCY_MATH_387
16561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16562 || TARGET_MIX_SSE_I387)
16563 && flag_unsafe_math_optimizations"
16565 [(set_attr "type" "fpspc")
16566 (set_attr "mode" "XF")])
16568 ;; When sincos pattern is defined, sin and cos builtin functions will be
16569 ;; expanded to sincos pattern with one of its outputs left unused.
16570 ;; CSE pass will figure out if two sincos patterns can be combined,
16571 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16572 ;; depending on the unused output.
16574 (define_insn "sincosxf3"
16575 [(set (match_operand:XF 0 "register_operand" "=f")
16576 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16577 UNSPEC_SINCOS_COS))
16578 (set (match_operand:XF 1 "register_operand" "=u")
16579 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16580 "TARGET_USE_FANCY_MATH_387
16581 && flag_unsafe_math_optimizations"
16583 [(set_attr "type" "fpspc")
16584 (set_attr "mode" "XF")])
16587 [(set (match_operand:XF 0 "register_operand" "")
16588 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16589 UNSPEC_SINCOS_COS))
16590 (set (match_operand:XF 1 "register_operand" "")
16591 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16592 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16593 && !(reload_completed || reload_in_progress)"
16594 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16598 [(set (match_operand:XF 0 "register_operand" "")
16599 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16600 UNSPEC_SINCOS_COS))
16601 (set (match_operand:XF 1 "register_operand" "")
16602 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16603 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16604 && !(reload_completed || reload_in_progress)"
16605 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16608 (define_insn "sincos_extend<mode>xf3_i387"
16609 [(set (match_operand:XF 0 "register_operand" "=f")
16610 (unspec:XF [(float_extend:XF
16611 (match_operand:MODEF 2 "register_operand" "0"))]
16612 UNSPEC_SINCOS_COS))
16613 (set (match_operand:XF 1 "register_operand" "=u")
16614 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16615 "TARGET_USE_FANCY_MATH_387
16616 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16617 || TARGET_MIX_SSE_I387)
16618 && flag_unsafe_math_optimizations"
16620 [(set_attr "type" "fpspc")
16621 (set_attr "mode" "XF")])
16624 [(set (match_operand:XF 0 "register_operand" "")
16625 (unspec:XF [(float_extend:XF
16626 (match_operand:MODEF 2 "register_operand" ""))]
16627 UNSPEC_SINCOS_COS))
16628 (set (match_operand:XF 1 "register_operand" "")
16629 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16630 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16631 && !(reload_completed || reload_in_progress)"
16632 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16636 [(set (match_operand:XF 0 "register_operand" "")
16637 (unspec:XF [(float_extend:XF
16638 (match_operand:MODEF 2 "register_operand" ""))]
16639 UNSPEC_SINCOS_COS))
16640 (set (match_operand:XF 1 "register_operand" "")
16641 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16642 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16643 && !(reload_completed || reload_in_progress)"
16644 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16647 (define_expand "sincos<mode>3"
16648 [(use (match_operand:MODEF 0 "register_operand" ""))
16649 (use (match_operand:MODEF 1 "register_operand" ""))
16650 (use (match_operand:MODEF 2 "register_operand" ""))]
16651 "TARGET_USE_FANCY_MATH_387
16652 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16653 || TARGET_MIX_SSE_I387)
16654 && flag_unsafe_math_optimizations"
16656 rtx op0 = gen_reg_rtx (XFmode);
16657 rtx op1 = gen_reg_rtx (XFmode);
16659 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16660 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16661 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16665 (define_insn "fptanxf4_i387"
16666 [(set (match_operand:XF 0 "register_operand" "=f")
16667 (match_operand:XF 3 "const_double_operand" "F"))
16668 (set (match_operand:XF 1 "register_operand" "=u")
16669 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16671 "TARGET_USE_FANCY_MATH_387
16672 && flag_unsafe_math_optimizations
16673 && standard_80387_constant_p (operands[3]) == 2"
16675 [(set_attr "type" "fpspc")
16676 (set_attr "mode" "XF")])
16678 (define_insn "fptan_extend<mode>xf4_i387"
16679 [(set (match_operand:MODEF 0 "register_operand" "=f")
16680 (match_operand:MODEF 3 "const_double_operand" "F"))
16681 (set (match_operand:XF 1 "register_operand" "=u")
16682 (unspec:XF [(float_extend:XF
16683 (match_operand:MODEF 2 "register_operand" "0"))]
16685 "TARGET_USE_FANCY_MATH_387
16686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16687 || TARGET_MIX_SSE_I387)
16688 && flag_unsafe_math_optimizations
16689 && standard_80387_constant_p (operands[3]) == 2"
16691 [(set_attr "type" "fpspc")
16692 (set_attr "mode" "XF")])
16694 (define_expand "tanxf2"
16695 [(use (match_operand:XF 0 "register_operand" ""))
16696 (use (match_operand:XF 1 "register_operand" ""))]
16697 "TARGET_USE_FANCY_MATH_387
16698 && flag_unsafe_math_optimizations"
16700 rtx one = gen_reg_rtx (XFmode);
16701 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16703 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16707 (define_expand "tan<mode>2"
16708 [(use (match_operand:MODEF 0 "register_operand" ""))
16709 (use (match_operand:MODEF 1 "register_operand" ""))]
16710 "TARGET_USE_FANCY_MATH_387
16711 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16712 || TARGET_MIX_SSE_I387)
16713 && flag_unsafe_math_optimizations"
16715 rtx op0 = gen_reg_rtx (XFmode);
16717 rtx one = gen_reg_rtx (<MODE>mode);
16718 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16720 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16721 operands[1], op2));
16722 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16726 (define_insn "*fpatanxf3_i387"
16727 [(set (match_operand:XF 0 "register_operand" "=f")
16728 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16729 (match_operand:XF 2 "register_operand" "u")]
16731 (clobber (match_scratch:XF 3 "=2"))]
16732 "TARGET_USE_FANCY_MATH_387
16733 && flag_unsafe_math_optimizations"
16735 [(set_attr "type" "fpspc")
16736 (set_attr "mode" "XF")])
16738 (define_insn "fpatan_extend<mode>xf3_i387"
16739 [(set (match_operand:XF 0 "register_operand" "=f")
16740 (unspec:XF [(float_extend:XF
16741 (match_operand:MODEF 1 "register_operand" "0"))
16743 (match_operand:MODEF 2 "register_operand" "u"))]
16745 (clobber (match_scratch:XF 3 "=2"))]
16746 "TARGET_USE_FANCY_MATH_387
16747 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16748 || TARGET_MIX_SSE_I387)
16749 && flag_unsafe_math_optimizations"
16751 [(set_attr "type" "fpspc")
16752 (set_attr "mode" "XF")])
16754 (define_expand "atan2xf3"
16755 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16756 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16757 (match_operand:XF 1 "register_operand" "")]
16759 (clobber (match_scratch:XF 3 ""))])]
16760 "TARGET_USE_FANCY_MATH_387
16761 && flag_unsafe_math_optimizations"
16764 (define_expand "atan2<mode>3"
16765 [(use (match_operand:MODEF 0 "register_operand" ""))
16766 (use (match_operand:MODEF 1 "register_operand" ""))
16767 (use (match_operand:MODEF 2 "register_operand" ""))]
16768 "TARGET_USE_FANCY_MATH_387
16769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16770 || TARGET_MIX_SSE_I387)
16771 && flag_unsafe_math_optimizations"
16773 rtx op0 = gen_reg_rtx (XFmode);
16775 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16776 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16780 (define_expand "atanxf2"
16781 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16782 (unspec:XF [(match_dup 2)
16783 (match_operand:XF 1 "register_operand" "")]
16785 (clobber (match_scratch:XF 3 ""))])]
16786 "TARGET_USE_FANCY_MATH_387
16787 && flag_unsafe_math_optimizations"
16789 operands[2] = gen_reg_rtx (XFmode);
16790 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16793 (define_expand "atan<mode>2"
16794 [(use (match_operand:MODEF 0 "register_operand" ""))
16795 (use (match_operand:MODEF 1 "register_operand" ""))]
16796 "TARGET_USE_FANCY_MATH_387
16797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16798 || TARGET_MIX_SSE_I387)
16799 && flag_unsafe_math_optimizations"
16801 rtx op0 = gen_reg_rtx (XFmode);
16803 rtx op2 = gen_reg_rtx (<MODE>mode);
16804 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16806 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16807 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16811 (define_expand "asinxf2"
16812 [(set (match_dup 2)
16813 (mult:XF (match_operand:XF 1 "register_operand" "")
16815 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16816 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16817 (parallel [(set (match_operand:XF 0 "register_operand" "")
16818 (unspec:XF [(match_dup 5) (match_dup 1)]
16820 (clobber (match_scratch:XF 6 ""))])]
16821 "TARGET_USE_FANCY_MATH_387
16822 && flag_unsafe_math_optimizations && !optimize_size"
16826 for (i = 2; i < 6; i++)
16827 operands[i] = gen_reg_rtx (XFmode);
16829 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16832 (define_expand "asin<mode>2"
16833 [(use (match_operand:MODEF 0 "register_operand" ""))
16834 (use (match_operand:MODEF 1 "general_operand" ""))]
16835 "TARGET_USE_FANCY_MATH_387
16836 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16837 || TARGET_MIX_SSE_I387)
16838 && flag_unsafe_math_optimizations && !optimize_size"
16840 rtx op0 = gen_reg_rtx (XFmode);
16841 rtx op1 = gen_reg_rtx (XFmode);
16843 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16844 emit_insn (gen_asinxf2 (op0, op1));
16845 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16849 (define_expand "acosxf2"
16850 [(set (match_dup 2)
16851 (mult:XF (match_operand:XF 1 "register_operand" "")
16853 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16854 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16855 (parallel [(set (match_operand:XF 0 "register_operand" "")
16856 (unspec:XF [(match_dup 1) (match_dup 5)]
16858 (clobber (match_scratch:XF 6 ""))])]
16859 "TARGET_USE_FANCY_MATH_387
16860 && flag_unsafe_math_optimizations && !optimize_size"
16864 for (i = 2; i < 6; i++)
16865 operands[i] = gen_reg_rtx (XFmode);
16867 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16870 (define_expand "acos<mode>2"
16871 [(use (match_operand:MODEF 0 "register_operand" ""))
16872 (use (match_operand:MODEF 1 "general_operand" ""))]
16873 "TARGET_USE_FANCY_MATH_387
16874 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16875 || TARGET_MIX_SSE_I387)
16876 && flag_unsafe_math_optimizations && !optimize_size"
16878 rtx op0 = gen_reg_rtx (XFmode);
16879 rtx op1 = gen_reg_rtx (XFmode);
16881 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16882 emit_insn (gen_acosxf2 (op0, op1));
16883 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16887 (define_insn "fyl2xxf3_i387"
16888 [(set (match_operand:XF 0 "register_operand" "=f")
16889 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16890 (match_operand:XF 2 "register_operand" "u")]
16892 (clobber (match_scratch:XF 3 "=2"))]
16893 "TARGET_USE_FANCY_MATH_387
16894 && flag_unsafe_math_optimizations"
16896 [(set_attr "type" "fpspc")
16897 (set_attr "mode" "XF")])
16899 (define_insn "fyl2x_extend<mode>xf3_i387"
16900 [(set (match_operand:XF 0 "register_operand" "=f")
16901 (unspec:XF [(float_extend:XF
16902 (match_operand:MODEF 1 "register_operand" "0"))
16903 (match_operand:XF 2 "register_operand" "u")]
16905 (clobber (match_scratch:XF 3 "=2"))]
16906 "TARGET_USE_FANCY_MATH_387
16907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16908 || TARGET_MIX_SSE_I387)
16909 && flag_unsafe_math_optimizations"
16911 [(set_attr "type" "fpspc")
16912 (set_attr "mode" "XF")])
16914 (define_expand "logxf2"
16915 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16916 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16917 (match_dup 2)] UNSPEC_FYL2X))
16918 (clobber (match_scratch:XF 3 ""))])]
16919 "TARGET_USE_FANCY_MATH_387
16920 && flag_unsafe_math_optimizations"
16922 operands[2] = gen_reg_rtx (XFmode);
16923 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16926 (define_expand "log<mode>2"
16927 [(use (match_operand:MODEF 0 "register_operand" ""))
16928 (use (match_operand:MODEF 1 "register_operand" ""))]
16929 "TARGET_USE_FANCY_MATH_387
16930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16931 || TARGET_MIX_SSE_I387)
16932 && flag_unsafe_math_optimizations"
16934 rtx op0 = gen_reg_rtx (XFmode);
16936 rtx op2 = gen_reg_rtx (XFmode);
16937 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16939 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16940 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16944 (define_expand "log10xf2"
16945 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16946 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16947 (match_dup 2)] UNSPEC_FYL2X))
16948 (clobber (match_scratch:XF 3 ""))])]
16949 "TARGET_USE_FANCY_MATH_387
16950 && flag_unsafe_math_optimizations"
16952 operands[2] = gen_reg_rtx (XFmode);
16953 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16956 (define_expand "log10<mode>2"
16957 [(use (match_operand:MODEF 0 "register_operand" ""))
16958 (use (match_operand:MODEF 1 "register_operand" ""))]
16959 "TARGET_USE_FANCY_MATH_387
16960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16961 || TARGET_MIX_SSE_I387)
16962 && flag_unsafe_math_optimizations"
16964 rtx op0 = gen_reg_rtx (XFmode);
16966 rtx op2 = gen_reg_rtx (XFmode);
16967 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16969 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16970 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16974 (define_expand "log2xf2"
16975 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16976 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16977 (match_dup 2)] UNSPEC_FYL2X))
16978 (clobber (match_scratch:XF 3 ""))])]
16979 "TARGET_USE_FANCY_MATH_387
16980 && flag_unsafe_math_optimizations"
16982 operands[2] = gen_reg_rtx (XFmode);
16983 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16986 (define_expand "log2<mode>2"
16987 [(use (match_operand:MODEF 0 "register_operand" ""))
16988 (use (match_operand:MODEF 1 "register_operand" ""))]
16989 "TARGET_USE_FANCY_MATH_387
16990 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16991 || TARGET_MIX_SSE_I387)
16992 && flag_unsafe_math_optimizations"
16994 rtx op0 = gen_reg_rtx (XFmode);
16996 rtx op2 = gen_reg_rtx (XFmode);
16997 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16999 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17000 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17004 (define_insn "fyl2xp1xf3_i387"
17005 [(set (match_operand:XF 0 "register_operand" "=f")
17006 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17007 (match_operand:XF 2 "register_operand" "u")]
17009 (clobber (match_scratch:XF 3 "=2"))]
17010 "TARGET_USE_FANCY_MATH_387
17011 && flag_unsafe_math_optimizations"
17013 [(set_attr "type" "fpspc")
17014 (set_attr "mode" "XF")])
17016 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17017 [(set (match_operand:XF 0 "register_operand" "=f")
17018 (unspec:XF [(float_extend:XF
17019 (match_operand:MODEF 1 "register_operand" "0"))
17020 (match_operand:XF 2 "register_operand" "u")]
17022 (clobber (match_scratch:XF 3 "=2"))]
17023 "TARGET_USE_FANCY_MATH_387
17024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17025 || TARGET_MIX_SSE_I387)
17026 && flag_unsafe_math_optimizations"
17028 [(set_attr "type" "fpspc")
17029 (set_attr "mode" "XF")])
17031 (define_expand "log1pxf2"
17032 [(use (match_operand:XF 0 "register_operand" ""))
17033 (use (match_operand:XF 1 "register_operand" ""))]
17034 "TARGET_USE_FANCY_MATH_387
17035 && flag_unsafe_math_optimizations && !optimize_size"
17037 ix86_emit_i387_log1p (operands[0], operands[1]);
17041 (define_expand "log1p<mode>2"
17042 [(use (match_operand:MODEF 0 "register_operand" ""))
17043 (use (match_operand:MODEF 1 "register_operand" ""))]
17044 "TARGET_USE_FANCY_MATH_387
17045 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17046 || TARGET_MIX_SSE_I387)
17047 && flag_unsafe_math_optimizations && !optimize_size"
17049 rtx op0 = gen_reg_rtx (XFmode);
17051 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17053 ix86_emit_i387_log1p (op0, operands[1]);
17054 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17058 (define_insn "fxtractxf3_i387"
17059 [(set (match_operand:XF 0 "register_operand" "=f")
17060 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17061 UNSPEC_XTRACT_FRACT))
17062 (set (match_operand:XF 1 "register_operand" "=u")
17063 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17064 "TARGET_USE_FANCY_MATH_387
17065 && flag_unsafe_math_optimizations"
17067 [(set_attr "type" "fpspc")
17068 (set_attr "mode" "XF")])
17070 (define_insn "fxtract_extend<mode>xf3_i387"
17071 [(set (match_operand:XF 0 "register_operand" "=f")
17072 (unspec:XF [(float_extend:XF
17073 (match_operand:MODEF 2 "register_operand" "0"))]
17074 UNSPEC_XTRACT_FRACT))
17075 (set (match_operand:XF 1 "register_operand" "=u")
17076 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17077 "TARGET_USE_FANCY_MATH_387
17078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17079 || TARGET_MIX_SSE_I387)
17080 && flag_unsafe_math_optimizations"
17082 [(set_attr "type" "fpspc")
17083 (set_attr "mode" "XF")])
17085 (define_expand "logbxf2"
17086 [(parallel [(set (match_dup 2)
17087 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17088 UNSPEC_XTRACT_FRACT))
17089 (set (match_operand:XF 0 "register_operand" "")
17090 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17091 "TARGET_USE_FANCY_MATH_387
17092 && flag_unsafe_math_optimizations"
17094 operands[2] = gen_reg_rtx (XFmode);
17097 (define_expand "logb<mode>2"
17098 [(use (match_operand:MODEF 0 "register_operand" ""))
17099 (use (match_operand:MODEF 1 "register_operand" ""))]
17100 "TARGET_USE_FANCY_MATH_387
17101 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17102 || TARGET_MIX_SSE_I387)
17103 && flag_unsafe_math_optimizations"
17105 rtx op0 = gen_reg_rtx (XFmode);
17106 rtx op1 = gen_reg_rtx (XFmode);
17108 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17109 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17113 (define_expand "ilogbxf2"
17114 [(use (match_operand:SI 0 "register_operand" ""))
17115 (use (match_operand:XF 1 "register_operand" ""))]
17116 "TARGET_USE_FANCY_MATH_387
17117 && flag_unsafe_math_optimizations && !optimize_size"
17119 rtx op0 = gen_reg_rtx (XFmode);
17120 rtx op1 = gen_reg_rtx (XFmode);
17122 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17123 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17127 (define_expand "ilogb<mode>2"
17128 [(use (match_operand:SI 0 "register_operand" ""))
17129 (use (match_operand:MODEF 1 "register_operand" ""))]
17130 "TARGET_USE_FANCY_MATH_387
17131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17132 || TARGET_MIX_SSE_I387)
17133 && flag_unsafe_math_optimizations && !optimize_size"
17135 rtx op0 = gen_reg_rtx (XFmode);
17136 rtx op1 = gen_reg_rtx (XFmode);
17138 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17139 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17143 (define_insn "*f2xm1xf2_i387"
17144 [(set (match_operand:XF 0 "register_operand" "=f")
17145 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17147 "TARGET_USE_FANCY_MATH_387
17148 && flag_unsafe_math_optimizations"
17150 [(set_attr "type" "fpspc")
17151 (set_attr "mode" "XF")])
17153 (define_insn "*fscalexf4_i387"
17154 [(set (match_operand:XF 0 "register_operand" "=f")
17155 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17156 (match_operand:XF 3 "register_operand" "1")]
17157 UNSPEC_FSCALE_FRACT))
17158 (set (match_operand:XF 1 "register_operand" "=u")
17159 (unspec:XF [(match_dup 2) (match_dup 3)]
17160 UNSPEC_FSCALE_EXP))]
17161 "TARGET_USE_FANCY_MATH_387
17162 && flag_unsafe_math_optimizations"
17164 [(set_attr "type" "fpspc")
17165 (set_attr "mode" "XF")])
17167 (define_expand "expNcorexf3"
17168 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17169 (match_operand:XF 2 "register_operand" "")))
17170 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17171 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17172 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17173 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17174 (parallel [(set (match_operand:XF 0 "register_operand" "")
17175 (unspec:XF [(match_dup 8) (match_dup 4)]
17176 UNSPEC_FSCALE_FRACT))
17178 (unspec:XF [(match_dup 8) (match_dup 4)]
17179 UNSPEC_FSCALE_EXP))])]
17180 "TARGET_USE_FANCY_MATH_387
17181 && flag_unsafe_math_optimizations && !optimize_size"
17185 for (i = 3; i < 10; i++)
17186 operands[i] = gen_reg_rtx (XFmode);
17188 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17191 (define_expand "expxf2"
17192 [(use (match_operand:XF 0 "register_operand" ""))
17193 (use (match_operand:XF 1 "register_operand" ""))]
17194 "TARGET_USE_FANCY_MATH_387
17195 && flag_unsafe_math_optimizations && !optimize_size"
17197 rtx op2 = gen_reg_rtx (XFmode);
17198 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17200 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17204 (define_expand "exp<mode>2"
17205 [(use (match_operand:MODEF 0 "register_operand" ""))
17206 (use (match_operand:MODEF 1 "general_operand" ""))]
17207 "TARGET_USE_FANCY_MATH_387
17208 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17209 || TARGET_MIX_SSE_I387)
17210 && flag_unsafe_math_optimizations && !optimize_size"
17212 rtx op0 = gen_reg_rtx (XFmode);
17213 rtx op1 = gen_reg_rtx (XFmode);
17215 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17216 emit_insn (gen_expxf2 (op0, op1));
17217 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17221 (define_expand "exp10xf2"
17222 [(use (match_operand:XF 0 "register_operand" ""))
17223 (use (match_operand:XF 1 "register_operand" ""))]
17224 "TARGET_USE_FANCY_MATH_387
17225 && flag_unsafe_math_optimizations && !optimize_size"
17227 rtx op2 = gen_reg_rtx (XFmode);
17228 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17230 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17234 (define_expand "exp10<mode>2"
17235 [(use (match_operand:MODEF 0 "register_operand" ""))
17236 (use (match_operand:MODEF 1 "general_operand" ""))]
17237 "TARGET_USE_FANCY_MATH_387
17238 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17239 || TARGET_MIX_SSE_I387)
17240 && flag_unsafe_math_optimizations && !optimize_size"
17242 rtx op0 = gen_reg_rtx (XFmode);
17243 rtx op1 = gen_reg_rtx (XFmode);
17245 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17246 emit_insn (gen_exp10xf2 (op0, op1));
17247 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17251 (define_expand "exp2xf2"
17252 [(use (match_operand:XF 0 "register_operand" ""))
17253 (use (match_operand:XF 1 "register_operand" ""))]
17254 "TARGET_USE_FANCY_MATH_387
17255 && flag_unsafe_math_optimizations && !optimize_size"
17257 rtx op2 = gen_reg_rtx (XFmode);
17258 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17260 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17264 (define_expand "exp2<mode>2"
17265 [(use (match_operand:MODEF 0 "register_operand" ""))
17266 (use (match_operand:MODEF 1 "general_operand" ""))]
17267 "TARGET_USE_FANCY_MATH_387
17268 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17269 || TARGET_MIX_SSE_I387)
17270 && flag_unsafe_math_optimizations && !optimize_size"
17272 rtx op0 = gen_reg_rtx (XFmode);
17273 rtx op1 = gen_reg_rtx (XFmode);
17275 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17276 emit_insn (gen_exp2xf2 (op0, op1));
17277 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17281 (define_expand "expm1xf2"
17282 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17284 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17285 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17286 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17287 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17288 (parallel [(set (match_dup 7)
17289 (unspec:XF [(match_dup 6) (match_dup 4)]
17290 UNSPEC_FSCALE_FRACT))
17292 (unspec:XF [(match_dup 6) (match_dup 4)]
17293 UNSPEC_FSCALE_EXP))])
17294 (parallel [(set (match_dup 10)
17295 (unspec:XF [(match_dup 9) (match_dup 8)]
17296 UNSPEC_FSCALE_FRACT))
17297 (set (match_dup 11)
17298 (unspec:XF [(match_dup 9) (match_dup 8)]
17299 UNSPEC_FSCALE_EXP))])
17300 (set (match_dup 12) (minus:XF (match_dup 10)
17301 (float_extend:XF (match_dup 13))))
17302 (set (match_operand:XF 0 "register_operand" "")
17303 (plus:XF (match_dup 12) (match_dup 7)))]
17304 "TARGET_USE_FANCY_MATH_387
17305 && flag_unsafe_math_optimizations && !optimize_size"
17309 for (i = 2; i < 13; i++)
17310 operands[i] = gen_reg_rtx (XFmode);
17313 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17315 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17318 (define_expand "expm1<mode>2"
17319 [(use (match_operand:MODEF 0 "register_operand" ""))
17320 (use (match_operand:MODEF 1 "general_operand" ""))]
17321 "TARGET_USE_FANCY_MATH_387
17322 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17323 || TARGET_MIX_SSE_I387)
17324 && flag_unsafe_math_optimizations && !optimize_size"
17326 rtx op0 = gen_reg_rtx (XFmode);
17327 rtx op1 = gen_reg_rtx (XFmode);
17329 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17330 emit_insn (gen_expm1xf2 (op0, op1));
17331 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17335 (define_expand "ldexpxf3"
17336 [(set (match_dup 3)
17337 (float:XF (match_operand:SI 2 "register_operand" "")))
17338 (parallel [(set (match_operand:XF 0 " register_operand" "")
17339 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17341 UNSPEC_FSCALE_FRACT))
17343 (unspec:XF [(match_dup 1) (match_dup 3)]
17344 UNSPEC_FSCALE_EXP))])]
17345 "TARGET_USE_FANCY_MATH_387
17346 && flag_unsafe_math_optimizations && !optimize_size"
17348 operands[3] = gen_reg_rtx (XFmode);
17349 operands[4] = gen_reg_rtx (XFmode);
17352 (define_expand "ldexp<mode>3"
17353 [(use (match_operand:MODEF 0 "register_operand" ""))
17354 (use (match_operand:MODEF 1 "general_operand" ""))
17355 (use (match_operand:SI 2 "register_operand" ""))]
17356 "TARGET_USE_FANCY_MATH_387
17357 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17358 || TARGET_MIX_SSE_I387)
17359 && flag_unsafe_math_optimizations && !optimize_size"
17361 rtx op0 = gen_reg_rtx (XFmode);
17362 rtx op1 = gen_reg_rtx (XFmode);
17364 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17365 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17366 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17370 (define_expand "scalbxf3"
17371 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17372 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17373 (match_operand:XF 2 "register_operand" "")]
17374 UNSPEC_FSCALE_FRACT))
17376 (unspec:XF [(match_dup 1) (match_dup 2)]
17377 UNSPEC_FSCALE_EXP))])]
17378 "TARGET_USE_FANCY_MATH_387
17379 && flag_unsafe_math_optimizations && !optimize_size"
17381 operands[3] = gen_reg_rtx (XFmode);
17384 (define_expand "scalb<mode>3"
17385 [(use (match_operand:MODEF 0 "register_operand" ""))
17386 (use (match_operand:MODEF 1 "general_operand" ""))
17387 (use (match_operand:MODEF 2 "register_operand" ""))]
17388 "TARGET_USE_FANCY_MATH_387
17389 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17390 || TARGET_MIX_SSE_I387)
17391 && flag_unsafe_math_optimizations && !optimize_size"
17393 rtx op0 = gen_reg_rtx (XFmode);
17394 rtx op1 = gen_reg_rtx (XFmode);
17395 rtx op2 = gen_reg_rtx (XFmode);
17397 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17398 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17399 emit_insn (gen_scalbxf3 (op0, op1, op2));
17400 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17405 (define_insn "sse4_1_round<mode>2"
17406 [(set (match_operand:MODEF 0 "register_operand" "=x")
17407 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17408 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17411 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17412 [(set_attr "type" "ssecvt")
17413 (set_attr "prefix_extra" "1")
17414 (set_attr "mode" "<MODE>")])
17416 (define_insn "rintxf2"
17417 [(set (match_operand:XF 0 "register_operand" "=f")
17418 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17420 "TARGET_USE_FANCY_MATH_387
17421 && flag_unsafe_math_optimizations"
17423 [(set_attr "type" "fpspc")
17424 (set_attr "mode" "XF")])
17426 (define_expand "rint<mode>2"
17427 [(use (match_operand:MODEF 0 "register_operand" ""))
17428 (use (match_operand:MODEF 1 "register_operand" ""))]
17429 "(TARGET_USE_FANCY_MATH_387
17430 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17431 || TARGET_MIX_SSE_I387)
17432 && flag_unsafe_math_optimizations)
17433 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17434 && !flag_trapping_math
17435 && (TARGET_ROUND || !optimize_size))"
17437 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17438 && !flag_trapping_math
17439 && (TARGET_ROUND || !optimize_size))
17442 emit_insn (gen_sse4_1_round<mode>2
17443 (operands[0], operands[1], GEN_INT (0x04)));
17445 ix86_expand_rint (operand0, operand1);
17449 rtx op0 = gen_reg_rtx (XFmode);
17450 rtx op1 = gen_reg_rtx (XFmode);
17452 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17453 emit_insn (gen_rintxf2 (op0, op1));
17455 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17460 (define_expand "round<mode>2"
17461 [(match_operand:MODEF 0 "register_operand" "")
17462 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17463 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17464 && !flag_trapping_math && !flag_rounding_math
17467 if (TARGET_64BIT || (<MODE>mode != DFmode))
17468 ix86_expand_round (operand0, operand1);
17470 ix86_expand_rounddf_32 (operand0, operand1);
17474 (define_insn_and_split "*fistdi2_1"
17475 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17476 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17478 "TARGET_USE_FANCY_MATH_387
17479 && !(reload_completed || reload_in_progress)"
17484 if (memory_operand (operands[0], VOIDmode))
17485 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17488 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17489 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17494 [(set_attr "type" "fpspc")
17495 (set_attr "mode" "DI")])
17497 (define_insn "fistdi2"
17498 [(set (match_operand:DI 0 "memory_operand" "=m")
17499 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17501 (clobber (match_scratch:XF 2 "=&1f"))]
17502 "TARGET_USE_FANCY_MATH_387"
17503 "* return output_fix_trunc (insn, operands, 0);"
17504 [(set_attr "type" "fpspc")
17505 (set_attr "mode" "DI")])
17507 (define_insn "fistdi2_with_temp"
17508 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17509 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17511 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17512 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17513 "TARGET_USE_FANCY_MATH_387"
17515 [(set_attr "type" "fpspc")
17516 (set_attr "mode" "DI")])
17519 [(set (match_operand:DI 0 "register_operand" "")
17520 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17522 (clobber (match_operand:DI 2 "memory_operand" ""))
17523 (clobber (match_scratch 3 ""))]
17525 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17526 (clobber (match_dup 3))])
17527 (set (match_dup 0) (match_dup 2))]
17531 [(set (match_operand:DI 0 "memory_operand" "")
17532 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17534 (clobber (match_operand:DI 2 "memory_operand" ""))
17535 (clobber (match_scratch 3 ""))]
17537 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17538 (clobber (match_dup 3))])]
17541 (define_insn_and_split "*fist<mode>2_1"
17542 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17543 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17545 "TARGET_USE_FANCY_MATH_387
17546 && !(reload_completed || reload_in_progress)"
17551 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17552 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17556 [(set_attr "type" "fpspc")
17557 (set_attr "mode" "<MODE>")])
17559 (define_insn "fist<mode>2"
17560 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17561 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17563 "TARGET_USE_FANCY_MATH_387"
17564 "* return output_fix_trunc (insn, operands, 0);"
17565 [(set_attr "type" "fpspc")
17566 (set_attr "mode" "<MODE>")])
17568 (define_insn "fist<mode>2_with_temp"
17569 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17570 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17572 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17573 "TARGET_USE_FANCY_MATH_387"
17575 [(set_attr "type" "fpspc")
17576 (set_attr "mode" "<MODE>")])
17579 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17580 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17582 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17584 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17585 (set (match_dup 0) (match_dup 2))]
17589 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17590 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17592 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17594 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17597 (define_expand "lrintxf<mode>2"
17598 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17599 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17601 "TARGET_USE_FANCY_MATH_387"
17604 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17605 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17606 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17607 UNSPEC_FIX_NOTRUNC))]
17608 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17609 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17612 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17613 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17614 (match_operand:MODEF 1 "register_operand" "")]
17615 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17616 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17617 && !flag_trapping_math && !flag_rounding_math
17620 ix86_expand_lround (operand0, operand1);
17624 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17625 (define_insn_and_split "frndintxf2_floor"
17626 [(set (match_operand:XF 0 "register_operand" "")
17627 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17628 UNSPEC_FRNDINT_FLOOR))
17629 (clobber (reg:CC FLAGS_REG))]
17630 "TARGET_USE_FANCY_MATH_387
17631 && flag_unsafe_math_optimizations
17632 && !(reload_completed || reload_in_progress)"
17637 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17639 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17640 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17642 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17643 operands[2], operands[3]));
17646 [(set_attr "type" "frndint")
17647 (set_attr "i387_cw" "floor")
17648 (set_attr "mode" "XF")])
17650 (define_insn "frndintxf2_floor_i387"
17651 [(set (match_operand:XF 0 "register_operand" "=f")
17652 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17653 UNSPEC_FRNDINT_FLOOR))
17654 (use (match_operand:HI 2 "memory_operand" "m"))
17655 (use (match_operand:HI 3 "memory_operand" "m"))]
17656 "TARGET_USE_FANCY_MATH_387
17657 && flag_unsafe_math_optimizations"
17658 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17659 [(set_attr "type" "frndint")
17660 (set_attr "i387_cw" "floor")
17661 (set_attr "mode" "XF")])
17663 (define_expand "floorxf2"
17664 [(use (match_operand:XF 0 "register_operand" ""))
17665 (use (match_operand:XF 1 "register_operand" ""))]
17666 "TARGET_USE_FANCY_MATH_387
17667 && flag_unsafe_math_optimizations && !optimize_size"
17669 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17673 (define_expand "floor<mode>2"
17674 [(use (match_operand:MODEF 0 "register_operand" ""))
17675 (use (match_operand:MODEF 1 "register_operand" ""))]
17676 "(TARGET_USE_FANCY_MATH_387
17677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17678 || TARGET_MIX_SSE_I387)
17679 && flag_unsafe_math_optimizations && !optimize_size)
17680 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17681 && !flag_trapping_math
17682 && (TARGET_ROUND || !optimize_size))"
17684 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17685 && !flag_trapping_math
17686 && (TARGET_ROUND || !optimize_size))
17689 emit_insn (gen_sse4_1_round<mode>2
17690 (operands[0], operands[1], GEN_INT (0x01)));
17691 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17692 ix86_expand_floorceil (operand0, operand1, true);
17694 ix86_expand_floorceildf_32 (operand0, operand1, true);
17698 rtx op0 = gen_reg_rtx (XFmode);
17699 rtx op1 = gen_reg_rtx (XFmode);
17701 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17702 emit_insn (gen_frndintxf2_floor (op0, op1));
17704 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17709 (define_insn_and_split "*fist<mode>2_floor_1"
17710 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17711 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17712 UNSPEC_FIST_FLOOR))
17713 (clobber (reg:CC FLAGS_REG))]
17714 "TARGET_USE_FANCY_MATH_387
17715 && flag_unsafe_math_optimizations
17716 && !(reload_completed || reload_in_progress)"
17721 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17723 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17724 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17725 if (memory_operand (operands[0], VOIDmode))
17726 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17727 operands[2], operands[3]));
17730 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17731 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17732 operands[2], operands[3],
17737 [(set_attr "type" "fistp")
17738 (set_attr "i387_cw" "floor")
17739 (set_attr "mode" "<MODE>")])
17741 (define_insn "fistdi2_floor"
17742 [(set (match_operand:DI 0 "memory_operand" "=m")
17743 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17744 UNSPEC_FIST_FLOOR))
17745 (use (match_operand:HI 2 "memory_operand" "m"))
17746 (use (match_operand:HI 3 "memory_operand" "m"))
17747 (clobber (match_scratch:XF 4 "=&1f"))]
17748 "TARGET_USE_FANCY_MATH_387
17749 && flag_unsafe_math_optimizations"
17750 "* return output_fix_trunc (insn, operands, 0);"
17751 [(set_attr "type" "fistp")
17752 (set_attr "i387_cw" "floor")
17753 (set_attr "mode" "DI")])
17755 (define_insn "fistdi2_floor_with_temp"
17756 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17757 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17758 UNSPEC_FIST_FLOOR))
17759 (use (match_operand:HI 2 "memory_operand" "m,m"))
17760 (use (match_operand:HI 3 "memory_operand" "m,m"))
17761 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17762 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17763 "TARGET_USE_FANCY_MATH_387
17764 && flag_unsafe_math_optimizations"
17766 [(set_attr "type" "fistp")
17767 (set_attr "i387_cw" "floor")
17768 (set_attr "mode" "DI")])
17771 [(set (match_operand:DI 0 "register_operand" "")
17772 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17773 UNSPEC_FIST_FLOOR))
17774 (use (match_operand:HI 2 "memory_operand" ""))
17775 (use (match_operand:HI 3 "memory_operand" ""))
17776 (clobber (match_operand:DI 4 "memory_operand" ""))
17777 (clobber (match_scratch 5 ""))]
17779 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17780 (use (match_dup 2))
17781 (use (match_dup 3))
17782 (clobber (match_dup 5))])
17783 (set (match_dup 0) (match_dup 4))]
17787 [(set (match_operand:DI 0 "memory_operand" "")
17788 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17789 UNSPEC_FIST_FLOOR))
17790 (use (match_operand:HI 2 "memory_operand" ""))
17791 (use (match_operand:HI 3 "memory_operand" ""))
17792 (clobber (match_operand:DI 4 "memory_operand" ""))
17793 (clobber (match_scratch 5 ""))]
17795 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17796 (use (match_dup 2))
17797 (use (match_dup 3))
17798 (clobber (match_dup 5))])]
17801 (define_insn "fist<mode>2_floor"
17802 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17803 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17804 UNSPEC_FIST_FLOOR))
17805 (use (match_operand:HI 2 "memory_operand" "m"))
17806 (use (match_operand:HI 3 "memory_operand" "m"))]
17807 "TARGET_USE_FANCY_MATH_387
17808 && flag_unsafe_math_optimizations"
17809 "* return output_fix_trunc (insn, operands, 0);"
17810 [(set_attr "type" "fistp")
17811 (set_attr "i387_cw" "floor")
17812 (set_attr "mode" "<MODE>")])
17814 (define_insn "fist<mode>2_floor_with_temp"
17815 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17816 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17817 UNSPEC_FIST_FLOOR))
17818 (use (match_operand:HI 2 "memory_operand" "m,m"))
17819 (use (match_operand:HI 3 "memory_operand" "m,m"))
17820 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17821 "TARGET_USE_FANCY_MATH_387
17822 && flag_unsafe_math_optimizations"
17824 [(set_attr "type" "fistp")
17825 (set_attr "i387_cw" "floor")
17826 (set_attr "mode" "<MODE>")])
17829 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17830 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17831 UNSPEC_FIST_FLOOR))
17832 (use (match_operand:HI 2 "memory_operand" ""))
17833 (use (match_operand:HI 3 "memory_operand" ""))
17834 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17836 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17837 UNSPEC_FIST_FLOOR))
17838 (use (match_dup 2))
17839 (use (match_dup 3))])
17840 (set (match_dup 0) (match_dup 4))]
17844 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17845 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17846 UNSPEC_FIST_FLOOR))
17847 (use (match_operand:HI 2 "memory_operand" ""))
17848 (use (match_operand:HI 3 "memory_operand" ""))
17849 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17851 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17852 UNSPEC_FIST_FLOOR))
17853 (use (match_dup 2))
17854 (use (match_dup 3))])]
17857 (define_expand "lfloorxf<mode>2"
17858 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17859 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17860 UNSPEC_FIST_FLOOR))
17861 (clobber (reg:CC FLAGS_REG))])]
17862 "TARGET_USE_FANCY_MATH_387
17863 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17864 && flag_unsafe_math_optimizations"
17867 (define_expand "lfloor<mode>di2"
17868 [(match_operand:DI 0 "nonimmediate_operand" "")
17869 (match_operand:MODEF 1 "register_operand" "")]
17870 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17871 && !flag_trapping_math
17874 ix86_expand_lfloorceil (operand0, operand1, true);
17878 (define_expand "lfloor<mode>si2"
17879 [(match_operand:SI 0 "nonimmediate_operand" "")
17880 (match_operand:MODEF 1 "register_operand" "")]
17881 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17882 && !flag_trapping_math
17883 && (!optimize_size || !TARGET_64BIT)"
17885 ix86_expand_lfloorceil (operand0, operand1, true);
17889 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17890 (define_insn_and_split "frndintxf2_ceil"
17891 [(set (match_operand:XF 0 "register_operand" "")
17892 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17893 UNSPEC_FRNDINT_CEIL))
17894 (clobber (reg:CC FLAGS_REG))]
17895 "TARGET_USE_FANCY_MATH_387
17896 && flag_unsafe_math_optimizations
17897 && !(reload_completed || reload_in_progress)"
17902 ix86_optimize_mode_switching[I387_CEIL] = 1;
17904 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17905 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17907 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17908 operands[2], operands[3]));
17911 [(set_attr "type" "frndint")
17912 (set_attr "i387_cw" "ceil")
17913 (set_attr "mode" "XF")])
17915 (define_insn "frndintxf2_ceil_i387"
17916 [(set (match_operand:XF 0 "register_operand" "=f")
17917 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17918 UNSPEC_FRNDINT_CEIL))
17919 (use (match_operand:HI 2 "memory_operand" "m"))
17920 (use (match_operand:HI 3 "memory_operand" "m"))]
17921 "TARGET_USE_FANCY_MATH_387
17922 && flag_unsafe_math_optimizations"
17923 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17924 [(set_attr "type" "frndint")
17925 (set_attr "i387_cw" "ceil")
17926 (set_attr "mode" "XF")])
17928 (define_expand "ceilxf2"
17929 [(use (match_operand:XF 0 "register_operand" ""))
17930 (use (match_operand:XF 1 "register_operand" ""))]
17931 "TARGET_USE_FANCY_MATH_387
17932 && flag_unsafe_math_optimizations && !optimize_size"
17934 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17938 (define_expand "ceil<mode>2"
17939 [(use (match_operand:MODEF 0 "register_operand" ""))
17940 (use (match_operand:MODEF 1 "register_operand" ""))]
17941 "(TARGET_USE_FANCY_MATH_387
17942 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17943 || TARGET_MIX_SSE_I387)
17944 && flag_unsafe_math_optimizations && !optimize_size)
17945 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17946 && !flag_trapping_math
17947 && (TARGET_ROUND || !optimize_size))"
17949 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17950 && !flag_trapping_math
17951 && (TARGET_ROUND || !optimize_size))
17954 emit_insn (gen_sse4_1_round<mode>2
17955 (operands[0], operands[1], GEN_INT (0x02)));
17956 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17957 ix86_expand_floorceil (operand0, operand1, false);
17959 ix86_expand_floorceildf_32 (operand0, operand1, false);
17963 rtx op0 = gen_reg_rtx (XFmode);
17964 rtx op1 = gen_reg_rtx (XFmode);
17966 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17967 emit_insn (gen_frndintxf2_ceil (op0, op1));
17969 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17974 (define_insn_and_split "*fist<mode>2_ceil_1"
17975 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17976 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17978 (clobber (reg:CC FLAGS_REG))]
17979 "TARGET_USE_FANCY_MATH_387
17980 && flag_unsafe_math_optimizations
17981 && !(reload_completed || reload_in_progress)"
17986 ix86_optimize_mode_switching[I387_CEIL] = 1;
17988 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17989 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17990 if (memory_operand (operands[0], VOIDmode))
17991 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17992 operands[2], operands[3]));
17995 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17996 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17997 operands[2], operands[3],
18002 [(set_attr "type" "fistp")
18003 (set_attr "i387_cw" "ceil")
18004 (set_attr "mode" "<MODE>")])
18006 (define_insn "fistdi2_ceil"
18007 [(set (match_operand:DI 0 "memory_operand" "=m")
18008 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18010 (use (match_operand:HI 2 "memory_operand" "m"))
18011 (use (match_operand:HI 3 "memory_operand" "m"))
18012 (clobber (match_scratch:XF 4 "=&1f"))]
18013 "TARGET_USE_FANCY_MATH_387
18014 && flag_unsafe_math_optimizations"
18015 "* return output_fix_trunc (insn, operands, 0);"
18016 [(set_attr "type" "fistp")
18017 (set_attr "i387_cw" "ceil")
18018 (set_attr "mode" "DI")])
18020 (define_insn "fistdi2_ceil_with_temp"
18021 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18022 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18024 (use (match_operand:HI 2 "memory_operand" "m,m"))
18025 (use (match_operand:HI 3 "memory_operand" "m,m"))
18026 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18027 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18028 "TARGET_USE_FANCY_MATH_387
18029 && flag_unsafe_math_optimizations"
18031 [(set_attr "type" "fistp")
18032 (set_attr "i387_cw" "ceil")
18033 (set_attr "mode" "DI")])
18036 [(set (match_operand:DI 0 "register_operand" "")
18037 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18039 (use (match_operand:HI 2 "memory_operand" ""))
18040 (use (match_operand:HI 3 "memory_operand" ""))
18041 (clobber (match_operand:DI 4 "memory_operand" ""))
18042 (clobber (match_scratch 5 ""))]
18044 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18045 (use (match_dup 2))
18046 (use (match_dup 3))
18047 (clobber (match_dup 5))])
18048 (set (match_dup 0) (match_dup 4))]
18052 [(set (match_operand:DI 0 "memory_operand" "")
18053 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18055 (use (match_operand:HI 2 "memory_operand" ""))
18056 (use (match_operand:HI 3 "memory_operand" ""))
18057 (clobber (match_operand:DI 4 "memory_operand" ""))
18058 (clobber (match_scratch 5 ""))]
18060 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18061 (use (match_dup 2))
18062 (use (match_dup 3))
18063 (clobber (match_dup 5))])]
18066 (define_insn "fist<mode>2_ceil"
18067 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18068 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18070 (use (match_operand:HI 2 "memory_operand" "m"))
18071 (use (match_operand:HI 3 "memory_operand" "m"))]
18072 "TARGET_USE_FANCY_MATH_387
18073 && flag_unsafe_math_optimizations"
18074 "* return output_fix_trunc (insn, operands, 0);"
18075 [(set_attr "type" "fistp")
18076 (set_attr "i387_cw" "ceil")
18077 (set_attr "mode" "<MODE>")])
18079 (define_insn "fist<mode>2_ceil_with_temp"
18080 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18081 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18083 (use (match_operand:HI 2 "memory_operand" "m,m"))
18084 (use (match_operand:HI 3 "memory_operand" "m,m"))
18085 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18086 "TARGET_USE_FANCY_MATH_387
18087 && flag_unsafe_math_optimizations"
18089 [(set_attr "type" "fistp")
18090 (set_attr "i387_cw" "ceil")
18091 (set_attr "mode" "<MODE>")])
18094 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18095 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18097 (use (match_operand:HI 2 "memory_operand" ""))
18098 (use (match_operand:HI 3 "memory_operand" ""))
18099 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18101 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18103 (use (match_dup 2))
18104 (use (match_dup 3))])
18105 (set (match_dup 0) (match_dup 4))]
18109 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18110 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18112 (use (match_operand:HI 2 "memory_operand" ""))
18113 (use (match_operand:HI 3 "memory_operand" ""))
18114 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18116 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18118 (use (match_dup 2))
18119 (use (match_dup 3))])]
18122 (define_expand "lceilxf<mode>2"
18123 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18124 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18126 (clobber (reg:CC FLAGS_REG))])]
18127 "TARGET_USE_FANCY_MATH_387
18128 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18129 && flag_unsafe_math_optimizations"
18132 (define_expand "lceil<mode>di2"
18133 [(match_operand:DI 0 "nonimmediate_operand" "")
18134 (match_operand:MODEF 1 "register_operand" "")]
18135 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18136 && !flag_trapping_math"
18138 ix86_expand_lfloorceil (operand0, operand1, false);
18142 (define_expand "lceil<mode>si2"
18143 [(match_operand:SI 0 "nonimmediate_operand" "")
18144 (match_operand:MODEF 1 "register_operand" "")]
18145 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18146 && !flag_trapping_math"
18148 ix86_expand_lfloorceil (operand0, operand1, false);
18152 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18153 (define_insn_and_split "frndintxf2_trunc"
18154 [(set (match_operand:XF 0 "register_operand" "")
18155 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18156 UNSPEC_FRNDINT_TRUNC))
18157 (clobber (reg:CC FLAGS_REG))]
18158 "TARGET_USE_FANCY_MATH_387
18159 && flag_unsafe_math_optimizations
18160 && !(reload_completed || reload_in_progress)"
18165 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18167 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18168 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18170 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18171 operands[2], operands[3]));
18174 [(set_attr "type" "frndint")
18175 (set_attr "i387_cw" "trunc")
18176 (set_attr "mode" "XF")])
18178 (define_insn "frndintxf2_trunc_i387"
18179 [(set (match_operand:XF 0 "register_operand" "=f")
18180 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18181 UNSPEC_FRNDINT_TRUNC))
18182 (use (match_operand:HI 2 "memory_operand" "m"))
18183 (use (match_operand:HI 3 "memory_operand" "m"))]
18184 "TARGET_USE_FANCY_MATH_387
18185 && flag_unsafe_math_optimizations"
18186 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18187 [(set_attr "type" "frndint")
18188 (set_attr "i387_cw" "trunc")
18189 (set_attr "mode" "XF")])
18191 (define_expand "btruncxf2"
18192 [(use (match_operand:XF 0 "register_operand" ""))
18193 (use (match_operand:XF 1 "register_operand" ""))]
18194 "TARGET_USE_FANCY_MATH_387
18195 && flag_unsafe_math_optimizations && !optimize_size"
18197 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18201 (define_expand "btrunc<mode>2"
18202 [(use (match_operand:MODEF 0 "register_operand" ""))
18203 (use (match_operand:MODEF 1 "register_operand" ""))]
18204 "(TARGET_USE_FANCY_MATH_387
18205 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18206 || TARGET_MIX_SSE_I387)
18207 && flag_unsafe_math_optimizations && !optimize_size)
18208 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18209 && !flag_trapping_math
18210 && (TARGET_ROUND || !optimize_size))"
18212 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18213 && !flag_trapping_math
18214 && (TARGET_ROUND || !optimize_size))
18217 emit_insn (gen_sse4_1_round<mode>2
18218 (operands[0], operands[1], GEN_INT (0x03)));
18219 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18220 ix86_expand_trunc (operand0, operand1);
18222 ix86_expand_truncdf_32 (operand0, operand1);
18226 rtx op0 = gen_reg_rtx (XFmode);
18227 rtx op1 = gen_reg_rtx (XFmode);
18229 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18230 emit_insn (gen_frndintxf2_trunc (op0, op1));
18232 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18237 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18238 (define_insn_and_split "frndintxf2_mask_pm"
18239 [(set (match_operand:XF 0 "register_operand" "")
18240 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18241 UNSPEC_FRNDINT_MASK_PM))
18242 (clobber (reg:CC FLAGS_REG))]
18243 "TARGET_USE_FANCY_MATH_387
18244 && flag_unsafe_math_optimizations
18245 && !(reload_completed || reload_in_progress)"
18250 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18252 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18253 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18255 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18256 operands[2], operands[3]));
18259 [(set_attr "type" "frndint")
18260 (set_attr "i387_cw" "mask_pm")
18261 (set_attr "mode" "XF")])
18263 (define_insn "frndintxf2_mask_pm_i387"
18264 [(set (match_operand:XF 0 "register_operand" "=f")
18265 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18266 UNSPEC_FRNDINT_MASK_PM))
18267 (use (match_operand:HI 2 "memory_operand" "m"))
18268 (use (match_operand:HI 3 "memory_operand" "m"))]
18269 "TARGET_USE_FANCY_MATH_387
18270 && flag_unsafe_math_optimizations"
18271 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18272 [(set_attr "type" "frndint")
18273 (set_attr "i387_cw" "mask_pm")
18274 (set_attr "mode" "XF")])
18276 (define_expand "nearbyintxf2"
18277 [(use (match_operand:XF 0 "register_operand" ""))
18278 (use (match_operand:XF 1 "register_operand" ""))]
18279 "TARGET_USE_FANCY_MATH_387
18280 && flag_unsafe_math_optimizations"
18282 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18287 (define_expand "nearbyint<mode>2"
18288 [(use (match_operand:MODEF 0 "register_operand" ""))
18289 (use (match_operand:MODEF 1 "register_operand" ""))]
18290 "TARGET_USE_FANCY_MATH_387
18291 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18292 || TARGET_MIX_SSE_I387)
18293 && flag_unsafe_math_optimizations"
18295 rtx op0 = gen_reg_rtx (XFmode);
18296 rtx op1 = gen_reg_rtx (XFmode);
18298 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18299 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18301 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18305 (define_insn "fxam<mode>2_i387"
18306 [(set (match_operand:HI 0 "register_operand" "=a")
18308 [(match_operand:X87MODEF 1 "register_operand" "f")]
18310 "TARGET_USE_FANCY_MATH_387"
18311 "fxam\n\tfnstsw\t%0"
18312 [(set_attr "type" "multi")
18313 (set_attr "unit" "i387")
18314 (set_attr "mode" "<MODE>")])
18316 (define_expand "isinf<mode>2"
18317 [(use (match_operand:SI 0 "register_operand" ""))
18318 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18319 "TARGET_USE_FANCY_MATH_387
18320 && TARGET_C99_FUNCTIONS
18321 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18323 rtx mask = GEN_INT (0x45);
18324 rtx val = GEN_INT (0x05);
18328 rtx scratch = gen_reg_rtx (HImode);
18329 rtx res = gen_reg_rtx (QImode);
18331 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18332 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18333 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18334 cond = gen_rtx_fmt_ee (EQ, QImode,
18335 gen_rtx_REG (CCmode, FLAGS_REG),
18337 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18338 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18342 (define_expand "signbit<mode>2"
18343 [(use (match_operand:SI 0 "register_operand" ""))
18344 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18345 "TARGET_USE_FANCY_MATH_387
18346 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18348 rtx mask = GEN_INT (0x0200);
18350 rtx scratch = gen_reg_rtx (HImode);
18352 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18353 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18357 ;; Block operation instructions
18359 (define_expand "movmemsi"
18360 [(use (match_operand:BLK 0 "memory_operand" ""))
18361 (use (match_operand:BLK 1 "memory_operand" ""))
18362 (use (match_operand:SI 2 "nonmemory_operand" ""))
18363 (use (match_operand:SI 3 "const_int_operand" ""))
18364 (use (match_operand:SI 4 "const_int_operand" ""))
18365 (use (match_operand:SI 5 "const_int_operand" ""))]
18368 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18369 operands[4], operands[5]))
18375 (define_expand "movmemdi"
18376 [(use (match_operand:BLK 0 "memory_operand" ""))
18377 (use (match_operand:BLK 1 "memory_operand" ""))
18378 (use (match_operand:DI 2 "nonmemory_operand" ""))
18379 (use (match_operand:DI 3 "const_int_operand" ""))
18380 (use (match_operand:SI 4 "const_int_operand" ""))
18381 (use (match_operand:SI 5 "const_int_operand" ""))]
18384 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18385 operands[4], operands[5]))
18391 ;; Most CPUs don't like single string operations
18392 ;; Handle this case here to simplify previous expander.
18394 (define_expand "strmov"
18395 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18396 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18397 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18398 (clobber (reg:CC FLAGS_REG))])
18399 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18400 (clobber (reg:CC FLAGS_REG))])]
18403 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18405 /* If .md ever supports :P for Pmode, these can be directly
18406 in the pattern above. */
18407 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18408 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18410 /* Can't use this if the user has appropriated esi or edi. */
18411 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18412 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18414 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18415 operands[2], operands[3],
18416 operands[5], operands[6]));
18420 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18423 (define_expand "strmov_singleop"
18424 [(parallel [(set (match_operand 1 "memory_operand" "")
18425 (match_operand 3 "memory_operand" ""))
18426 (set (match_operand 0 "register_operand" "")
18427 (match_operand 4 "" ""))
18428 (set (match_operand 2 "register_operand" "")
18429 (match_operand 5 "" ""))])]
18430 "TARGET_SINGLE_STRINGOP || optimize_size"
18433 (define_insn "*strmovdi_rex_1"
18434 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18435 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18436 (set (match_operand:DI 0 "register_operand" "=D")
18437 (plus:DI (match_dup 2)
18439 (set (match_operand:DI 1 "register_operand" "=S")
18440 (plus:DI (match_dup 3)
18442 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18444 [(set_attr "type" "str")
18445 (set_attr "mode" "DI")
18446 (set_attr "memory" "both")])
18448 (define_insn "*strmovsi_1"
18449 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18450 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18451 (set (match_operand:SI 0 "register_operand" "=D")
18452 (plus:SI (match_dup 2)
18454 (set (match_operand:SI 1 "register_operand" "=S")
18455 (plus:SI (match_dup 3)
18457 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18459 [(set_attr "type" "str")
18460 (set_attr "mode" "SI")
18461 (set_attr "memory" "both")])
18463 (define_insn "*strmovsi_rex_1"
18464 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18465 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18466 (set (match_operand:DI 0 "register_operand" "=D")
18467 (plus:DI (match_dup 2)
18469 (set (match_operand:DI 1 "register_operand" "=S")
18470 (plus:DI (match_dup 3)
18472 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18474 [(set_attr "type" "str")
18475 (set_attr "mode" "SI")
18476 (set_attr "memory" "both")])
18478 (define_insn "*strmovhi_1"
18479 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18480 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18481 (set (match_operand:SI 0 "register_operand" "=D")
18482 (plus:SI (match_dup 2)
18484 (set (match_operand:SI 1 "register_operand" "=S")
18485 (plus:SI (match_dup 3)
18487 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18489 [(set_attr "type" "str")
18490 (set_attr "memory" "both")
18491 (set_attr "mode" "HI")])
18493 (define_insn "*strmovhi_rex_1"
18494 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18495 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18496 (set (match_operand:DI 0 "register_operand" "=D")
18497 (plus:DI (match_dup 2)
18499 (set (match_operand:DI 1 "register_operand" "=S")
18500 (plus:DI (match_dup 3)
18502 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18504 [(set_attr "type" "str")
18505 (set_attr "memory" "both")
18506 (set_attr "mode" "HI")])
18508 (define_insn "*strmovqi_1"
18509 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18510 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18511 (set (match_operand:SI 0 "register_operand" "=D")
18512 (plus:SI (match_dup 2)
18514 (set (match_operand:SI 1 "register_operand" "=S")
18515 (plus:SI (match_dup 3)
18517 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18519 [(set_attr "type" "str")
18520 (set_attr "memory" "both")
18521 (set_attr "mode" "QI")])
18523 (define_insn "*strmovqi_rex_1"
18524 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18525 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18526 (set (match_operand:DI 0 "register_operand" "=D")
18527 (plus:DI (match_dup 2)
18529 (set (match_operand:DI 1 "register_operand" "=S")
18530 (plus:DI (match_dup 3)
18532 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18534 [(set_attr "type" "str")
18535 (set_attr "memory" "both")
18536 (set_attr "mode" "QI")])
18538 (define_expand "rep_mov"
18539 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18540 (set (match_operand 0 "register_operand" "")
18541 (match_operand 5 "" ""))
18542 (set (match_operand 2 "register_operand" "")
18543 (match_operand 6 "" ""))
18544 (set (match_operand 1 "memory_operand" "")
18545 (match_operand 3 "memory_operand" ""))
18546 (use (match_dup 4))])]
18550 (define_insn "*rep_movdi_rex64"
18551 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18552 (set (match_operand:DI 0 "register_operand" "=D")
18553 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18555 (match_operand:DI 3 "register_operand" "0")))
18556 (set (match_operand:DI 1 "register_operand" "=S")
18557 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18558 (match_operand:DI 4 "register_operand" "1")))
18559 (set (mem:BLK (match_dup 3))
18560 (mem:BLK (match_dup 4)))
18561 (use (match_dup 5))]
18564 [(set_attr "type" "str")
18565 (set_attr "prefix_rep" "1")
18566 (set_attr "memory" "both")
18567 (set_attr "mode" "DI")])
18569 (define_insn "*rep_movsi"
18570 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18571 (set (match_operand:SI 0 "register_operand" "=D")
18572 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18574 (match_operand:SI 3 "register_operand" "0")))
18575 (set (match_operand:SI 1 "register_operand" "=S")
18576 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18577 (match_operand:SI 4 "register_operand" "1")))
18578 (set (mem:BLK (match_dup 3))
18579 (mem:BLK (match_dup 4)))
18580 (use (match_dup 5))]
18583 [(set_attr "type" "str")
18584 (set_attr "prefix_rep" "1")
18585 (set_attr "memory" "both")
18586 (set_attr "mode" "SI")])
18588 (define_insn "*rep_movsi_rex64"
18589 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18590 (set (match_operand:DI 0 "register_operand" "=D")
18591 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18593 (match_operand:DI 3 "register_operand" "0")))
18594 (set (match_operand:DI 1 "register_operand" "=S")
18595 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18596 (match_operand:DI 4 "register_operand" "1")))
18597 (set (mem:BLK (match_dup 3))
18598 (mem:BLK (match_dup 4)))
18599 (use (match_dup 5))]
18602 [(set_attr "type" "str")
18603 (set_attr "prefix_rep" "1")
18604 (set_attr "memory" "both")
18605 (set_attr "mode" "SI")])
18607 (define_insn "*rep_movqi"
18608 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18609 (set (match_operand:SI 0 "register_operand" "=D")
18610 (plus:SI (match_operand:SI 3 "register_operand" "0")
18611 (match_operand:SI 5 "register_operand" "2")))
18612 (set (match_operand:SI 1 "register_operand" "=S")
18613 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18614 (set (mem:BLK (match_dup 3))
18615 (mem:BLK (match_dup 4)))
18616 (use (match_dup 5))]
18619 [(set_attr "type" "str")
18620 (set_attr "prefix_rep" "1")
18621 (set_attr "memory" "both")
18622 (set_attr "mode" "SI")])
18624 (define_insn "*rep_movqi_rex64"
18625 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18626 (set (match_operand:DI 0 "register_operand" "=D")
18627 (plus:DI (match_operand:DI 3 "register_operand" "0")
18628 (match_operand:DI 5 "register_operand" "2")))
18629 (set (match_operand:DI 1 "register_operand" "=S")
18630 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18631 (set (mem:BLK (match_dup 3))
18632 (mem:BLK (match_dup 4)))
18633 (use (match_dup 5))]
18636 [(set_attr "type" "str")
18637 (set_attr "prefix_rep" "1")
18638 (set_attr "memory" "both")
18639 (set_attr "mode" "SI")])
18641 (define_expand "setmemsi"
18642 [(use (match_operand:BLK 0 "memory_operand" ""))
18643 (use (match_operand:SI 1 "nonmemory_operand" ""))
18644 (use (match_operand 2 "const_int_operand" ""))
18645 (use (match_operand 3 "const_int_operand" ""))
18646 (use (match_operand:SI 4 "const_int_operand" ""))
18647 (use (match_operand:SI 5 "const_int_operand" ""))]
18650 if (ix86_expand_setmem (operands[0], operands[1],
18651 operands[2], operands[3],
18652 operands[4], operands[5]))
18658 (define_expand "setmemdi"
18659 [(use (match_operand:BLK 0 "memory_operand" ""))
18660 (use (match_operand:DI 1 "nonmemory_operand" ""))
18661 (use (match_operand 2 "const_int_operand" ""))
18662 (use (match_operand 3 "const_int_operand" ""))
18663 (use (match_operand 4 "const_int_operand" ""))
18664 (use (match_operand 5 "const_int_operand" ""))]
18667 if (ix86_expand_setmem (operands[0], operands[1],
18668 operands[2], operands[3],
18669 operands[4], operands[5]))
18675 ;; Most CPUs don't like single string operations
18676 ;; Handle this case here to simplify previous expander.
18678 (define_expand "strset"
18679 [(set (match_operand 1 "memory_operand" "")
18680 (match_operand 2 "register_operand" ""))
18681 (parallel [(set (match_operand 0 "register_operand" "")
18683 (clobber (reg:CC FLAGS_REG))])]
18686 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18687 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18689 /* If .md ever supports :P for Pmode, this can be directly
18690 in the pattern above. */
18691 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18692 GEN_INT (GET_MODE_SIZE (GET_MODE
18694 if (TARGET_SINGLE_STRINGOP || optimize_size)
18696 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18702 (define_expand "strset_singleop"
18703 [(parallel [(set (match_operand 1 "memory_operand" "")
18704 (match_operand 2 "register_operand" ""))
18705 (set (match_operand 0 "register_operand" "")
18706 (match_operand 3 "" ""))])]
18707 "TARGET_SINGLE_STRINGOP || optimize_size"
18710 (define_insn "*strsetdi_rex_1"
18711 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18712 (match_operand:DI 2 "register_operand" "a"))
18713 (set (match_operand:DI 0 "register_operand" "=D")
18714 (plus:DI (match_dup 1)
18716 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18718 [(set_attr "type" "str")
18719 (set_attr "memory" "store")
18720 (set_attr "mode" "DI")])
18722 (define_insn "*strsetsi_1"
18723 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18724 (match_operand:SI 2 "register_operand" "a"))
18725 (set (match_operand:SI 0 "register_operand" "=D")
18726 (plus:SI (match_dup 1)
18728 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18730 [(set_attr "type" "str")
18731 (set_attr "memory" "store")
18732 (set_attr "mode" "SI")])
18734 (define_insn "*strsetsi_rex_1"
18735 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18736 (match_operand:SI 2 "register_operand" "a"))
18737 (set (match_operand:DI 0 "register_operand" "=D")
18738 (plus:DI (match_dup 1)
18740 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18742 [(set_attr "type" "str")
18743 (set_attr "memory" "store")
18744 (set_attr "mode" "SI")])
18746 (define_insn "*strsethi_1"
18747 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18748 (match_operand:HI 2 "register_operand" "a"))
18749 (set (match_operand:SI 0 "register_operand" "=D")
18750 (plus:SI (match_dup 1)
18752 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18754 [(set_attr "type" "str")
18755 (set_attr "memory" "store")
18756 (set_attr "mode" "HI")])
18758 (define_insn "*strsethi_rex_1"
18759 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18760 (match_operand:HI 2 "register_operand" "a"))
18761 (set (match_operand:DI 0 "register_operand" "=D")
18762 (plus:DI (match_dup 1)
18764 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18766 [(set_attr "type" "str")
18767 (set_attr "memory" "store")
18768 (set_attr "mode" "HI")])
18770 (define_insn "*strsetqi_1"
18771 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18772 (match_operand:QI 2 "register_operand" "a"))
18773 (set (match_operand:SI 0 "register_operand" "=D")
18774 (plus:SI (match_dup 1)
18776 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18778 [(set_attr "type" "str")
18779 (set_attr "memory" "store")
18780 (set_attr "mode" "QI")])
18782 (define_insn "*strsetqi_rex_1"
18783 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18784 (match_operand:QI 2 "register_operand" "a"))
18785 (set (match_operand:DI 0 "register_operand" "=D")
18786 (plus:DI (match_dup 1)
18788 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18790 [(set_attr "type" "str")
18791 (set_attr "memory" "store")
18792 (set_attr "mode" "QI")])
18794 (define_expand "rep_stos"
18795 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18796 (set (match_operand 0 "register_operand" "")
18797 (match_operand 4 "" ""))
18798 (set (match_operand 2 "memory_operand" "") (const_int 0))
18799 (use (match_operand 3 "register_operand" ""))
18800 (use (match_dup 1))])]
18804 (define_insn "*rep_stosdi_rex64"
18805 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18806 (set (match_operand:DI 0 "register_operand" "=D")
18807 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18809 (match_operand:DI 3 "register_operand" "0")))
18810 (set (mem:BLK (match_dup 3))
18812 (use (match_operand:DI 2 "register_operand" "a"))
18813 (use (match_dup 4))]
18816 [(set_attr "type" "str")
18817 (set_attr "prefix_rep" "1")
18818 (set_attr "memory" "store")
18819 (set_attr "mode" "DI")])
18821 (define_insn "*rep_stossi"
18822 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18823 (set (match_operand:SI 0 "register_operand" "=D")
18824 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18826 (match_operand:SI 3 "register_operand" "0")))
18827 (set (mem:BLK (match_dup 3))
18829 (use (match_operand:SI 2 "register_operand" "a"))
18830 (use (match_dup 4))]
18833 [(set_attr "type" "str")
18834 (set_attr "prefix_rep" "1")
18835 (set_attr "memory" "store")
18836 (set_attr "mode" "SI")])
18838 (define_insn "*rep_stossi_rex64"
18839 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18840 (set (match_operand:DI 0 "register_operand" "=D")
18841 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18843 (match_operand:DI 3 "register_operand" "0")))
18844 (set (mem:BLK (match_dup 3))
18846 (use (match_operand:SI 2 "register_operand" "a"))
18847 (use (match_dup 4))]
18850 [(set_attr "type" "str")
18851 (set_attr "prefix_rep" "1")
18852 (set_attr "memory" "store")
18853 (set_attr "mode" "SI")])
18855 (define_insn "*rep_stosqi"
18856 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18857 (set (match_operand:SI 0 "register_operand" "=D")
18858 (plus:SI (match_operand:SI 3 "register_operand" "0")
18859 (match_operand:SI 4 "register_operand" "1")))
18860 (set (mem:BLK (match_dup 3))
18862 (use (match_operand:QI 2 "register_operand" "a"))
18863 (use (match_dup 4))]
18866 [(set_attr "type" "str")
18867 (set_attr "prefix_rep" "1")
18868 (set_attr "memory" "store")
18869 (set_attr "mode" "QI")])
18871 (define_insn "*rep_stosqi_rex64"
18872 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18873 (set (match_operand:DI 0 "register_operand" "=D")
18874 (plus:DI (match_operand:DI 3 "register_operand" "0")
18875 (match_operand:DI 4 "register_operand" "1")))
18876 (set (mem:BLK (match_dup 3))
18878 (use (match_operand:QI 2 "register_operand" "a"))
18879 (use (match_dup 4))]
18882 [(set_attr "type" "str")
18883 (set_attr "prefix_rep" "1")
18884 (set_attr "memory" "store")
18885 (set_attr "mode" "QI")])
18887 (define_expand "cmpstrnsi"
18888 [(set (match_operand:SI 0 "register_operand" "")
18889 (compare:SI (match_operand:BLK 1 "general_operand" "")
18890 (match_operand:BLK 2 "general_operand" "")))
18891 (use (match_operand 3 "general_operand" ""))
18892 (use (match_operand 4 "immediate_operand" ""))]
18893 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18895 rtx addr1, addr2, out, outlow, count, countreg, align;
18897 /* Can't use this if the user has appropriated esi or edi. */
18898 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18903 out = gen_reg_rtx (SImode);
18905 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18906 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18907 if (addr1 != XEXP (operands[1], 0))
18908 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18909 if (addr2 != XEXP (operands[2], 0))
18910 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18912 count = operands[3];
18913 countreg = ix86_zero_extend_to_Pmode (count);
18915 /* %%% Iff we are testing strict equality, we can use known alignment
18916 to good advantage. This may be possible with combine, particularly
18917 once cc0 is dead. */
18918 align = operands[4];
18920 if (CONST_INT_P (count))
18922 if (INTVAL (count) == 0)
18924 emit_move_insn (operands[0], const0_rtx);
18927 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18928 operands[1], operands[2]));
18933 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18935 emit_insn (gen_cmpsi_1 (countreg, countreg));
18936 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18937 operands[1], operands[2]));
18940 outlow = gen_lowpart (QImode, out);
18941 emit_insn (gen_cmpintqi (outlow));
18942 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18944 if (operands[0] != out)
18945 emit_move_insn (operands[0], out);
18950 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18952 (define_expand "cmpintqi"
18953 [(set (match_dup 1)
18954 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18956 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18957 (parallel [(set (match_operand:QI 0 "register_operand" "")
18958 (minus:QI (match_dup 1)
18960 (clobber (reg:CC FLAGS_REG))])]
18962 "operands[1] = gen_reg_rtx (QImode);
18963 operands[2] = gen_reg_rtx (QImode);")
18965 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18966 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18968 (define_expand "cmpstrnqi_nz_1"
18969 [(parallel [(set (reg:CC FLAGS_REG)
18970 (compare:CC (match_operand 4 "memory_operand" "")
18971 (match_operand 5 "memory_operand" "")))
18972 (use (match_operand 2 "register_operand" ""))
18973 (use (match_operand:SI 3 "immediate_operand" ""))
18974 (clobber (match_operand 0 "register_operand" ""))
18975 (clobber (match_operand 1 "register_operand" ""))
18976 (clobber (match_dup 2))])]
18980 (define_insn "*cmpstrnqi_nz_1"
18981 [(set (reg:CC FLAGS_REG)
18982 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18983 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18984 (use (match_operand:SI 6 "register_operand" "2"))
18985 (use (match_operand:SI 3 "immediate_operand" "i"))
18986 (clobber (match_operand:SI 0 "register_operand" "=S"))
18987 (clobber (match_operand:SI 1 "register_operand" "=D"))
18988 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18991 [(set_attr "type" "str")
18992 (set_attr "mode" "QI")
18993 (set_attr "prefix_rep" "1")])
18995 (define_insn "*cmpstrnqi_nz_rex_1"
18996 [(set (reg:CC FLAGS_REG)
18997 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18998 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18999 (use (match_operand:DI 6 "register_operand" "2"))
19000 (use (match_operand:SI 3 "immediate_operand" "i"))
19001 (clobber (match_operand:DI 0 "register_operand" "=S"))
19002 (clobber (match_operand:DI 1 "register_operand" "=D"))
19003 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19006 [(set_attr "type" "str")
19007 (set_attr "mode" "QI")
19008 (set_attr "prefix_rep" "1")])
19010 ;; The same, but the count is not known to not be zero.
19012 (define_expand "cmpstrnqi_1"
19013 [(parallel [(set (reg:CC FLAGS_REG)
19014 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19016 (compare:CC (match_operand 4 "memory_operand" "")
19017 (match_operand 5 "memory_operand" ""))
19019 (use (match_operand:SI 3 "immediate_operand" ""))
19020 (use (reg:CC FLAGS_REG))
19021 (clobber (match_operand 0 "register_operand" ""))
19022 (clobber (match_operand 1 "register_operand" ""))
19023 (clobber (match_dup 2))])]
19027 (define_insn "*cmpstrnqi_1"
19028 [(set (reg:CC FLAGS_REG)
19029 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19031 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19032 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19034 (use (match_operand:SI 3 "immediate_operand" "i"))
19035 (use (reg:CC FLAGS_REG))
19036 (clobber (match_operand:SI 0 "register_operand" "=S"))
19037 (clobber (match_operand:SI 1 "register_operand" "=D"))
19038 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19041 [(set_attr "type" "str")
19042 (set_attr "mode" "QI")
19043 (set_attr "prefix_rep" "1")])
19045 (define_insn "*cmpstrnqi_rex_1"
19046 [(set (reg:CC FLAGS_REG)
19047 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19049 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19050 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19052 (use (match_operand:SI 3 "immediate_operand" "i"))
19053 (use (reg:CC FLAGS_REG))
19054 (clobber (match_operand:DI 0 "register_operand" "=S"))
19055 (clobber (match_operand:DI 1 "register_operand" "=D"))
19056 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19059 [(set_attr "type" "str")
19060 (set_attr "mode" "QI")
19061 (set_attr "prefix_rep" "1")])
19063 (define_expand "strlensi"
19064 [(set (match_operand:SI 0 "register_operand" "")
19065 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19066 (match_operand:QI 2 "immediate_operand" "")
19067 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19070 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19076 (define_expand "strlendi"
19077 [(set (match_operand:DI 0 "register_operand" "")
19078 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19079 (match_operand:QI 2 "immediate_operand" "")
19080 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19083 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19089 (define_expand "strlenqi_1"
19090 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19091 (clobber (match_operand 1 "register_operand" ""))
19092 (clobber (reg:CC FLAGS_REG))])]
19096 (define_insn "*strlenqi_1"
19097 [(set (match_operand:SI 0 "register_operand" "=&c")
19098 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19099 (match_operand:QI 2 "register_operand" "a")
19100 (match_operand:SI 3 "immediate_operand" "i")
19101 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19102 (clobber (match_operand:SI 1 "register_operand" "=D"))
19103 (clobber (reg:CC FLAGS_REG))]
19106 [(set_attr "type" "str")
19107 (set_attr "mode" "QI")
19108 (set_attr "prefix_rep" "1")])
19110 (define_insn "*strlenqi_rex_1"
19111 [(set (match_operand:DI 0 "register_operand" "=&c")
19112 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19113 (match_operand:QI 2 "register_operand" "a")
19114 (match_operand:DI 3 "immediate_operand" "i")
19115 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19116 (clobber (match_operand:DI 1 "register_operand" "=D"))
19117 (clobber (reg:CC FLAGS_REG))]
19120 [(set_attr "type" "str")
19121 (set_attr "mode" "QI")
19122 (set_attr "prefix_rep" "1")])
19124 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19125 ;; handled in combine, but it is not currently up to the task.
19126 ;; When used for their truth value, the cmpstrn* expanders generate
19135 ;; The intermediate three instructions are unnecessary.
19137 ;; This one handles cmpstrn*_nz_1...
19140 (set (reg:CC FLAGS_REG)
19141 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19142 (mem:BLK (match_operand 5 "register_operand" ""))))
19143 (use (match_operand 6 "register_operand" ""))
19144 (use (match_operand:SI 3 "immediate_operand" ""))
19145 (clobber (match_operand 0 "register_operand" ""))
19146 (clobber (match_operand 1 "register_operand" ""))
19147 (clobber (match_operand 2 "register_operand" ""))])
19148 (set (match_operand:QI 7 "register_operand" "")
19149 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19150 (set (match_operand:QI 8 "register_operand" "")
19151 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19152 (set (reg FLAGS_REG)
19153 (compare (match_dup 7) (match_dup 8)))
19155 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19157 (set (reg:CC FLAGS_REG)
19158 (compare:CC (mem:BLK (match_dup 4))
19159 (mem:BLK (match_dup 5))))
19160 (use (match_dup 6))
19161 (use (match_dup 3))
19162 (clobber (match_dup 0))
19163 (clobber (match_dup 1))
19164 (clobber (match_dup 2))])]
19167 ;; ...and this one handles cmpstrn*_1.
19170 (set (reg:CC FLAGS_REG)
19171 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19173 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19174 (mem:BLK (match_operand 5 "register_operand" "")))
19176 (use (match_operand:SI 3 "immediate_operand" ""))
19177 (use (reg:CC FLAGS_REG))
19178 (clobber (match_operand 0 "register_operand" ""))
19179 (clobber (match_operand 1 "register_operand" ""))
19180 (clobber (match_operand 2 "register_operand" ""))])
19181 (set (match_operand:QI 7 "register_operand" "")
19182 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19183 (set (match_operand:QI 8 "register_operand" "")
19184 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19185 (set (reg FLAGS_REG)
19186 (compare (match_dup 7) (match_dup 8)))
19188 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19190 (set (reg:CC FLAGS_REG)
19191 (if_then_else:CC (ne (match_dup 6)
19193 (compare:CC (mem:BLK (match_dup 4))
19194 (mem:BLK (match_dup 5)))
19196 (use (match_dup 3))
19197 (use (reg:CC FLAGS_REG))
19198 (clobber (match_dup 0))
19199 (clobber (match_dup 1))
19200 (clobber (match_dup 2))])]
19205 ;; Conditional move instructions.
19207 (define_expand "movdicc"
19208 [(set (match_operand:DI 0 "register_operand" "")
19209 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19210 (match_operand:DI 2 "general_operand" "")
19211 (match_operand:DI 3 "general_operand" "")))]
19213 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19215 (define_insn "x86_movdicc_0_m1_rex64"
19216 [(set (match_operand:DI 0 "register_operand" "=r")
19217 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19220 (clobber (reg:CC FLAGS_REG))]
19223 ; Since we don't have the proper number of operands for an alu insn,
19224 ; fill in all the blanks.
19225 [(set_attr "type" "alu")
19226 (set_attr "pent_pair" "pu")
19227 (set_attr "memory" "none")
19228 (set_attr "imm_disp" "false")
19229 (set_attr "mode" "DI")
19230 (set_attr "length_immediate" "0")])
19232 (define_insn "*x86_movdicc_0_m1_se"
19233 [(set (match_operand:DI 0 "register_operand" "=r")
19234 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19237 (clobber (reg:CC FLAGS_REG))]
19240 [(set_attr "type" "alu")
19241 (set_attr "pent_pair" "pu")
19242 (set_attr "memory" "none")
19243 (set_attr "imm_disp" "false")
19244 (set_attr "mode" "DI")
19245 (set_attr "length_immediate" "0")])
19247 (define_insn "*movdicc_c_rex64"
19248 [(set (match_operand:DI 0 "register_operand" "=r,r")
19249 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19250 [(reg FLAGS_REG) (const_int 0)])
19251 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19252 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19253 "TARGET_64BIT && TARGET_CMOVE
19254 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19256 cmov%O2%C1\t{%2, %0|%0, %2}
19257 cmov%O2%c1\t{%3, %0|%0, %3}"
19258 [(set_attr "type" "icmov")
19259 (set_attr "mode" "DI")])
19261 (define_expand "movsicc"
19262 [(set (match_operand:SI 0 "register_operand" "")
19263 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19264 (match_operand:SI 2 "general_operand" "")
19265 (match_operand:SI 3 "general_operand" "")))]
19267 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19269 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19270 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19271 ;; So just document what we're doing explicitly.
19273 (define_insn "x86_movsicc_0_m1"
19274 [(set (match_operand:SI 0 "register_operand" "=r")
19275 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19278 (clobber (reg:CC FLAGS_REG))]
19281 ; Since we don't have the proper number of operands for an alu insn,
19282 ; fill in all the blanks.
19283 [(set_attr "type" "alu")
19284 (set_attr "pent_pair" "pu")
19285 (set_attr "memory" "none")
19286 (set_attr "imm_disp" "false")
19287 (set_attr "mode" "SI")
19288 (set_attr "length_immediate" "0")])
19290 (define_insn "*x86_movsicc_0_m1_se"
19291 [(set (match_operand:SI 0 "register_operand" "=r")
19292 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19295 (clobber (reg:CC FLAGS_REG))]
19298 [(set_attr "type" "alu")
19299 (set_attr "pent_pair" "pu")
19300 (set_attr "memory" "none")
19301 (set_attr "imm_disp" "false")
19302 (set_attr "mode" "SI")
19303 (set_attr "length_immediate" "0")])
19305 (define_insn "*movsicc_noc"
19306 [(set (match_operand:SI 0 "register_operand" "=r,r")
19307 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19308 [(reg FLAGS_REG) (const_int 0)])
19309 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19310 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19312 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19314 cmov%O2%C1\t{%2, %0|%0, %2}
19315 cmov%O2%c1\t{%3, %0|%0, %3}"
19316 [(set_attr "type" "icmov")
19317 (set_attr "mode" "SI")])
19319 (define_expand "movhicc"
19320 [(set (match_operand:HI 0 "register_operand" "")
19321 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19322 (match_operand:HI 2 "general_operand" "")
19323 (match_operand:HI 3 "general_operand" "")))]
19324 "TARGET_HIMODE_MATH"
19325 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19327 (define_insn "*movhicc_noc"
19328 [(set (match_operand:HI 0 "register_operand" "=r,r")
19329 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19330 [(reg FLAGS_REG) (const_int 0)])
19331 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19332 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19334 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19336 cmov%O2%C1\t{%2, %0|%0, %2}
19337 cmov%O2%c1\t{%3, %0|%0, %3}"
19338 [(set_attr "type" "icmov")
19339 (set_attr "mode" "HI")])
19341 (define_expand "movqicc"
19342 [(set (match_operand:QI 0 "register_operand" "")
19343 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19344 (match_operand:QI 2 "general_operand" "")
19345 (match_operand:QI 3 "general_operand" "")))]
19346 "TARGET_QIMODE_MATH"
19347 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19349 (define_insn_and_split "*movqicc_noc"
19350 [(set (match_operand:QI 0 "register_operand" "=r,r")
19351 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19352 [(match_operand 4 "flags_reg_operand" "")
19354 (match_operand:QI 2 "register_operand" "r,0")
19355 (match_operand:QI 3 "register_operand" "0,r")))]
19356 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19358 "&& reload_completed"
19359 [(set (match_dup 0)
19360 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19363 "operands[0] = gen_lowpart (SImode, operands[0]);
19364 operands[2] = gen_lowpart (SImode, operands[2]);
19365 operands[3] = gen_lowpart (SImode, operands[3]);"
19366 [(set_attr "type" "icmov")
19367 (set_attr "mode" "SI")])
19369 (define_expand "mov<mode>cc"
19370 [(set (match_operand:X87MODEF 0 "register_operand" "")
19371 (if_then_else:X87MODEF
19372 (match_operand 1 "comparison_operator" "")
19373 (match_operand:X87MODEF 2 "register_operand" "")
19374 (match_operand:X87MODEF 3 "register_operand" "")))]
19375 "(TARGET_80387 && TARGET_CMOVE)
19376 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19377 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19379 (define_insn "*movsfcc_1_387"
19380 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19381 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19382 [(reg FLAGS_REG) (const_int 0)])
19383 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19384 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19385 "TARGET_80387 && TARGET_CMOVE
19386 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19388 fcmov%F1\t{%2, %0|%0, %2}
19389 fcmov%f1\t{%3, %0|%0, %3}
19390 cmov%O2%C1\t{%2, %0|%0, %2}
19391 cmov%O2%c1\t{%3, %0|%0, %3}"
19392 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19393 (set_attr "mode" "SF,SF,SI,SI")])
19395 (define_insn "*movdfcc_1"
19396 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19397 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19398 [(reg FLAGS_REG) (const_int 0)])
19399 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19400 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19401 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19402 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19404 fcmov%F1\t{%2, %0|%0, %2}
19405 fcmov%f1\t{%3, %0|%0, %3}
19408 [(set_attr "type" "fcmov,fcmov,multi,multi")
19409 (set_attr "mode" "DF")])
19411 (define_insn "*movdfcc_1_rex64"
19412 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19413 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19414 [(reg FLAGS_REG) (const_int 0)])
19415 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19416 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19417 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19418 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19420 fcmov%F1\t{%2, %0|%0, %2}
19421 fcmov%f1\t{%3, %0|%0, %3}
19422 cmov%O2%C1\t{%2, %0|%0, %2}
19423 cmov%O2%c1\t{%3, %0|%0, %3}"
19424 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19425 (set_attr "mode" "DF")])
19428 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19429 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19430 [(match_operand 4 "flags_reg_operand" "")
19432 (match_operand:DF 2 "nonimmediate_operand" "")
19433 (match_operand:DF 3 "nonimmediate_operand" "")))]
19434 "!TARGET_64BIT && reload_completed"
19435 [(set (match_dup 2)
19436 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19440 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19443 "split_di (operands+2, 1, operands+5, operands+6);
19444 split_di (operands+3, 1, operands+7, operands+8);
19445 split_di (operands, 1, operands+2, operands+3);")
19447 (define_insn "*movxfcc_1"
19448 [(set (match_operand:XF 0 "register_operand" "=f,f")
19449 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19450 [(reg FLAGS_REG) (const_int 0)])
19451 (match_operand:XF 2 "register_operand" "f,0")
19452 (match_operand:XF 3 "register_operand" "0,f")))]
19453 "TARGET_80387 && TARGET_CMOVE"
19455 fcmov%F1\t{%2, %0|%0, %2}
19456 fcmov%f1\t{%3, %0|%0, %3}"
19457 [(set_attr "type" "fcmov")
19458 (set_attr "mode" "XF")])
19460 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19461 ;; the scalar versions to have only XMM registers as operands.
19463 ;; SSE5 conditional move
19464 (define_insn "*sse5_pcmov_<mode>"
19465 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19466 (if_then_else:MODEF
19467 (match_operand:MODEF 1 "register_operand" "x,0")
19468 (match_operand:MODEF 2 "register_operand" "0,x")
19469 (match_operand:MODEF 3 "register_operand" "x,x")))]
19470 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19471 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19472 [(set_attr "type" "sse4arg")])
19474 ;; These versions of the min/max patterns are intentionally ignorant of
19475 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19476 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19477 ;; are undefined in this condition, we're certain this is correct.
19479 (define_insn "<code><mode>3"
19480 [(set (match_operand:MODEF 0 "register_operand" "=x")
19482 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19483 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19484 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19485 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19486 [(set_attr "type" "sseadd")
19487 (set_attr "mode" "<MODE>")])
19489 ;; These versions of the min/max patterns implement exactly the operations
19490 ;; min = (op1 < op2 ? op1 : op2)
19491 ;; max = (!(op1 < op2) ? op1 : op2)
19492 ;; Their operands are not commutative, and thus they may be used in the
19493 ;; presence of -0.0 and NaN.
19495 (define_insn "*ieee_smin<mode>3"
19496 [(set (match_operand:MODEF 0 "register_operand" "=x")
19498 [(match_operand:MODEF 1 "register_operand" "0")
19499 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19501 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19502 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19503 [(set_attr "type" "sseadd")
19504 (set_attr "mode" "<MODE>")])
19506 (define_insn "*ieee_smax<mode>3"
19507 [(set (match_operand:MODEF 0 "register_operand" "=x")
19509 [(match_operand:MODEF 1 "register_operand" "0")
19510 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19512 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19513 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19514 [(set_attr "type" "sseadd")
19515 (set_attr "mode" "<MODE>")])
19517 ;; Make two stack loads independent:
19519 ;; fld %st(0) -> fld bb
19520 ;; fmul bb fmul %st(1), %st
19522 ;; Actually we only match the last two instructions for simplicity.
19524 [(set (match_operand 0 "fp_register_operand" "")
19525 (match_operand 1 "fp_register_operand" ""))
19527 (match_operator 2 "binary_fp_operator"
19529 (match_operand 3 "memory_operand" "")]))]
19530 "REGNO (operands[0]) != REGNO (operands[1])"
19531 [(set (match_dup 0) (match_dup 3))
19532 (set (match_dup 0) (match_dup 4))]
19534 ;; The % modifier is not operational anymore in peephole2's, so we have to
19535 ;; swap the operands manually in the case of addition and multiplication.
19536 "if (COMMUTATIVE_ARITH_P (operands[2]))
19537 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19538 operands[0], operands[1]);
19540 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19541 operands[1], operands[0]);")
19543 ;; Conditional addition patterns
19544 (define_expand "addqicc"
19545 [(match_operand:QI 0 "register_operand" "")
19546 (match_operand 1 "comparison_operator" "")
19547 (match_operand:QI 2 "register_operand" "")
19548 (match_operand:QI 3 "const_int_operand" "")]
19550 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19552 (define_expand "addhicc"
19553 [(match_operand:HI 0 "register_operand" "")
19554 (match_operand 1 "comparison_operator" "")
19555 (match_operand:HI 2 "register_operand" "")
19556 (match_operand:HI 3 "const_int_operand" "")]
19558 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19560 (define_expand "addsicc"
19561 [(match_operand:SI 0 "register_operand" "")
19562 (match_operand 1 "comparison_operator" "")
19563 (match_operand:SI 2 "register_operand" "")
19564 (match_operand:SI 3 "const_int_operand" "")]
19566 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19568 (define_expand "adddicc"
19569 [(match_operand:DI 0 "register_operand" "")
19570 (match_operand 1 "comparison_operator" "")
19571 (match_operand:DI 2 "register_operand" "")
19572 (match_operand:DI 3 "const_int_operand" "")]
19574 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19577 ;; Misc patterns (?)
19579 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19580 ;; Otherwise there will be nothing to keep
19582 ;; [(set (reg ebp) (reg esp))]
19583 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19584 ;; (clobber (eflags)]
19585 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19587 ;; in proper program order.
19588 (define_insn "pro_epilogue_adjust_stack_1"
19589 [(set (match_operand:SI 0 "register_operand" "=r,r")
19590 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19591 (match_operand:SI 2 "immediate_operand" "i,i")))
19592 (clobber (reg:CC FLAGS_REG))
19593 (clobber (mem:BLK (scratch)))]
19596 switch (get_attr_type (insn))
19599 return "mov{l}\t{%1, %0|%0, %1}";
19602 if (CONST_INT_P (operands[2])
19603 && (INTVAL (operands[2]) == 128
19604 || (INTVAL (operands[2]) < 0
19605 && INTVAL (operands[2]) != -128)))
19607 operands[2] = GEN_INT (-INTVAL (operands[2]));
19608 return "sub{l}\t{%2, %0|%0, %2}";
19610 return "add{l}\t{%2, %0|%0, %2}";
19613 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19614 return "lea{l}\t{%a2, %0|%0, %a2}";
19617 gcc_unreachable ();
19620 [(set (attr "type")
19621 (cond [(eq_attr "alternative" "0")
19622 (const_string "alu")
19623 (match_operand:SI 2 "const0_operand" "")
19624 (const_string "imov")
19626 (const_string "lea")))
19627 (set_attr "mode" "SI")])
19629 (define_insn "pro_epilogue_adjust_stack_rex64"
19630 [(set (match_operand:DI 0 "register_operand" "=r,r")
19631 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19632 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19633 (clobber (reg:CC FLAGS_REG))
19634 (clobber (mem:BLK (scratch)))]
19637 switch (get_attr_type (insn))
19640 return "mov{q}\t{%1, %0|%0, %1}";
19643 if (CONST_INT_P (operands[2])
19644 /* Avoid overflows. */
19645 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19646 && (INTVAL (operands[2]) == 128
19647 || (INTVAL (operands[2]) < 0
19648 && INTVAL (operands[2]) != -128)))
19650 operands[2] = GEN_INT (-INTVAL (operands[2]));
19651 return "sub{q}\t{%2, %0|%0, %2}";
19653 return "add{q}\t{%2, %0|%0, %2}";
19656 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19657 return "lea{q}\t{%a2, %0|%0, %a2}";
19660 gcc_unreachable ();
19663 [(set (attr "type")
19664 (cond [(eq_attr "alternative" "0")
19665 (const_string "alu")
19666 (match_operand:DI 2 "const0_operand" "")
19667 (const_string "imov")
19669 (const_string "lea")))
19670 (set_attr "mode" "DI")])
19672 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19673 [(set (match_operand:DI 0 "register_operand" "=r,r")
19674 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19675 (match_operand:DI 3 "immediate_operand" "i,i")))
19676 (use (match_operand:DI 2 "register_operand" "r,r"))
19677 (clobber (reg:CC FLAGS_REG))
19678 (clobber (mem:BLK (scratch)))]
19681 switch (get_attr_type (insn))
19684 return "add{q}\t{%2, %0|%0, %2}";
19687 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19688 return "lea{q}\t{%a2, %0|%0, %a2}";
19691 gcc_unreachable ();
19694 [(set_attr "type" "alu,lea")
19695 (set_attr "mode" "DI")])
19697 (define_insn "allocate_stack_worker_32"
19698 [(set (match_operand:SI 0 "register_operand" "+a")
19699 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19700 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19701 (clobber (reg:CC FLAGS_REG))]
19702 "!TARGET_64BIT && TARGET_STACK_PROBE"
19704 [(set_attr "type" "multi")
19705 (set_attr "length" "5")])
19707 (define_insn "allocate_stack_worker_64"
19708 [(set (match_operand:DI 0 "register_operand" "=a")
19709 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19710 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19711 (clobber (reg:DI R10_REG))
19712 (clobber (reg:DI R11_REG))
19713 (clobber (reg:CC FLAGS_REG))]
19714 "TARGET_64BIT && TARGET_STACK_PROBE"
19716 [(set_attr "type" "multi")
19717 (set_attr "length" "5")])
19719 (define_expand "allocate_stack"
19720 [(match_operand 0 "register_operand" "")
19721 (match_operand 1 "general_operand" "")]
19722 "TARGET_STACK_PROBE"
19726 #ifndef CHECK_STACK_LIMIT
19727 #define CHECK_STACK_LIMIT 0
19730 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19731 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19733 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19734 stack_pointer_rtx, 0, OPTAB_DIRECT);
19735 if (x != stack_pointer_rtx)
19736 emit_move_insn (stack_pointer_rtx, x);
19740 x = copy_to_mode_reg (Pmode, operands[1]);
19742 x = gen_allocate_stack_worker_64 (x);
19744 x = gen_allocate_stack_worker_32 (x);
19748 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19752 (define_expand "builtin_setjmp_receiver"
19753 [(label_ref (match_operand 0 "" ""))]
19754 "!TARGET_64BIT && flag_pic"
19759 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19760 rtx label_rtx = gen_label_rtx ();
19761 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19762 xops[0] = xops[1] = picreg;
19763 xops[2] = gen_rtx_CONST (SImode,
19764 gen_rtx_MINUS (SImode,
19765 gen_rtx_LABEL_REF (SImode, label_rtx),
19766 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19767 ix86_expand_binary_operator (MINUS, SImode, xops);
19770 emit_insn (gen_set_got (pic_offset_table_rtx));
19774 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19777 [(set (match_operand 0 "register_operand" "")
19778 (match_operator 3 "promotable_binary_operator"
19779 [(match_operand 1 "register_operand" "")
19780 (match_operand 2 "aligned_operand" "")]))
19781 (clobber (reg:CC FLAGS_REG))]
19782 "! TARGET_PARTIAL_REG_STALL && reload_completed
19783 && ((GET_MODE (operands[0]) == HImode
19784 && ((!optimize_size && !TARGET_FAST_PREFIX)
19785 /* ??? next two lines just !satisfies_constraint_K (...) */
19786 || !CONST_INT_P (operands[2])
19787 || satisfies_constraint_K (operands[2])))
19788 || (GET_MODE (operands[0]) == QImode
19789 && (TARGET_PROMOTE_QImode || optimize_size)))"
19790 [(parallel [(set (match_dup 0)
19791 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19792 (clobber (reg:CC FLAGS_REG))])]
19793 "operands[0] = gen_lowpart (SImode, operands[0]);
19794 operands[1] = gen_lowpart (SImode, operands[1]);
19795 if (GET_CODE (operands[3]) != ASHIFT)
19796 operands[2] = gen_lowpart (SImode, operands[2]);
19797 PUT_MODE (operands[3], SImode);")
19799 ; Promote the QImode tests, as i386 has encoding of the AND
19800 ; instruction with 32-bit sign-extended immediate and thus the
19801 ; instruction size is unchanged, except in the %eax case for
19802 ; which it is increased by one byte, hence the ! optimize_size.
19804 [(set (match_operand 0 "flags_reg_operand" "")
19805 (match_operator 2 "compare_operator"
19806 [(and (match_operand 3 "aligned_operand" "")
19807 (match_operand 4 "const_int_operand" ""))
19809 (set (match_operand 1 "register_operand" "")
19810 (and (match_dup 3) (match_dup 4)))]
19811 "! TARGET_PARTIAL_REG_STALL && reload_completed
19813 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19814 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19815 /* Ensure that the operand will remain sign-extended immediate. */
19816 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19817 [(parallel [(set (match_dup 0)
19818 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19821 (and:SI (match_dup 3) (match_dup 4)))])]
19824 = gen_int_mode (INTVAL (operands[4])
19825 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19826 operands[1] = gen_lowpart (SImode, operands[1]);
19827 operands[3] = gen_lowpart (SImode, operands[3]);
19830 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19831 ; the TEST instruction with 32-bit sign-extended immediate and thus
19832 ; the instruction size would at least double, which is not what we
19833 ; want even with ! optimize_size.
19835 [(set (match_operand 0 "flags_reg_operand" "")
19836 (match_operator 1 "compare_operator"
19837 [(and (match_operand:HI 2 "aligned_operand" "")
19838 (match_operand:HI 3 "const_int_operand" ""))
19840 "! TARGET_PARTIAL_REG_STALL && reload_completed
19841 && ! TARGET_FAST_PREFIX
19843 /* Ensure that the operand will remain sign-extended immediate. */
19844 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19845 [(set (match_dup 0)
19846 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19850 = gen_int_mode (INTVAL (operands[3])
19851 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19852 operands[2] = gen_lowpart (SImode, operands[2]);
19856 [(set (match_operand 0 "register_operand" "")
19857 (neg (match_operand 1 "register_operand" "")))
19858 (clobber (reg:CC FLAGS_REG))]
19859 "! TARGET_PARTIAL_REG_STALL && reload_completed
19860 && (GET_MODE (operands[0]) == HImode
19861 || (GET_MODE (operands[0]) == QImode
19862 && (TARGET_PROMOTE_QImode || optimize_size)))"
19863 [(parallel [(set (match_dup 0)
19864 (neg:SI (match_dup 1)))
19865 (clobber (reg:CC FLAGS_REG))])]
19866 "operands[0] = gen_lowpart (SImode, operands[0]);
19867 operands[1] = gen_lowpart (SImode, operands[1]);")
19870 [(set (match_operand 0 "register_operand" "")
19871 (not (match_operand 1 "register_operand" "")))]
19872 "! TARGET_PARTIAL_REG_STALL && reload_completed
19873 && (GET_MODE (operands[0]) == HImode
19874 || (GET_MODE (operands[0]) == QImode
19875 && (TARGET_PROMOTE_QImode || optimize_size)))"
19876 [(set (match_dup 0)
19877 (not:SI (match_dup 1)))]
19878 "operands[0] = gen_lowpart (SImode, operands[0]);
19879 operands[1] = gen_lowpart (SImode, operands[1]);")
19882 [(set (match_operand 0 "register_operand" "")
19883 (if_then_else (match_operator 1 "comparison_operator"
19884 [(reg FLAGS_REG) (const_int 0)])
19885 (match_operand 2 "register_operand" "")
19886 (match_operand 3 "register_operand" "")))]
19887 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19888 && (GET_MODE (operands[0]) == HImode
19889 || (GET_MODE (operands[0]) == QImode
19890 && (TARGET_PROMOTE_QImode || optimize_size)))"
19891 [(set (match_dup 0)
19892 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19893 "operands[0] = gen_lowpart (SImode, operands[0]);
19894 operands[2] = gen_lowpart (SImode, operands[2]);
19895 operands[3] = gen_lowpart (SImode, operands[3]);")
19898 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19899 ;; transform a complex memory operation into two memory to register operations.
19901 ;; Don't push memory operands
19903 [(set (match_operand:SI 0 "push_operand" "")
19904 (match_operand:SI 1 "memory_operand" ""))
19905 (match_scratch:SI 2 "r")]
19906 "!optimize_size && !TARGET_PUSH_MEMORY
19907 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19908 [(set (match_dup 2) (match_dup 1))
19909 (set (match_dup 0) (match_dup 2))]
19913 [(set (match_operand:DI 0 "push_operand" "")
19914 (match_operand:DI 1 "memory_operand" ""))
19915 (match_scratch:DI 2 "r")]
19916 "!optimize_size && !TARGET_PUSH_MEMORY
19917 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19918 [(set (match_dup 2) (match_dup 1))
19919 (set (match_dup 0) (match_dup 2))]
19922 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19925 [(set (match_operand:SF 0 "push_operand" "")
19926 (match_operand:SF 1 "memory_operand" ""))
19927 (match_scratch:SF 2 "r")]
19928 "!optimize_size && !TARGET_PUSH_MEMORY
19929 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19930 [(set (match_dup 2) (match_dup 1))
19931 (set (match_dup 0) (match_dup 2))]
19935 [(set (match_operand:HI 0 "push_operand" "")
19936 (match_operand:HI 1 "memory_operand" ""))
19937 (match_scratch:HI 2 "r")]
19938 "!optimize_size && !TARGET_PUSH_MEMORY
19939 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19940 [(set (match_dup 2) (match_dup 1))
19941 (set (match_dup 0) (match_dup 2))]
19945 [(set (match_operand:QI 0 "push_operand" "")
19946 (match_operand:QI 1 "memory_operand" ""))
19947 (match_scratch:QI 2 "q")]
19948 "!optimize_size && !TARGET_PUSH_MEMORY
19949 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19950 [(set (match_dup 2) (match_dup 1))
19951 (set (match_dup 0) (match_dup 2))]
19954 ;; Don't move an immediate directly to memory when the instruction
19957 [(match_scratch:SI 1 "r")
19958 (set (match_operand:SI 0 "memory_operand" "")
19961 && ! TARGET_USE_MOV0
19962 && TARGET_SPLIT_LONG_MOVES
19963 && get_attr_length (insn) >= ix86_cost->large_insn
19964 && peep2_regno_dead_p (0, FLAGS_REG)"
19965 [(parallel [(set (match_dup 1) (const_int 0))
19966 (clobber (reg:CC FLAGS_REG))])
19967 (set (match_dup 0) (match_dup 1))]
19971 [(match_scratch:HI 1 "r")
19972 (set (match_operand:HI 0 "memory_operand" "")
19975 && ! TARGET_USE_MOV0
19976 && TARGET_SPLIT_LONG_MOVES
19977 && get_attr_length (insn) >= ix86_cost->large_insn
19978 && peep2_regno_dead_p (0, FLAGS_REG)"
19979 [(parallel [(set (match_dup 2) (const_int 0))
19980 (clobber (reg:CC FLAGS_REG))])
19981 (set (match_dup 0) (match_dup 1))]
19982 "operands[2] = gen_lowpart (SImode, operands[1]);")
19985 [(match_scratch:QI 1 "q")
19986 (set (match_operand:QI 0 "memory_operand" "")
19989 && ! TARGET_USE_MOV0
19990 && TARGET_SPLIT_LONG_MOVES
19991 && get_attr_length (insn) >= ix86_cost->large_insn
19992 && peep2_regno_dead_p (0, FLAGS_REG)"
19993 [(parallel [(set (match_dup 2) (const_int 0))
19994 (clobber (reg:CC FLAGS_REG))])
19995 (set (match_dup 0) (match_dup 1))]
19996 "operands[2] = gen_lowpart (SImode, operands[1]);")
19999 [(match_scratch:SI 2 "r")
20000 (set (match_operand:SI 0 "memory_operand" "")
20001 (match_operand:SI 1 "immediate_operand" ""))]
20003 && TARGET_SPLIT_LONG_MOVES
20004 && get_attr_length (insn) >= ix86_cost->large_insn"
20005 [(set (match_dup 2) (match_dup 1))
20006 (set (match_dup 0) (match_dup 2))]
20010 [(match_scratch:HI 2 "r")
20011 (set (match_operand:HI 0 "memory_operand" "")
20012 (match_operand:HI 1 "immediate_operand" ""))]
20014 && TARGET_SPLIT_LONG_MOVES
20015 && get_attr_length (insn) >= ix86_cost->large_insn"
20016 [(set (match_dup 2) (match_dup 1))
20017 (set (match_dup 0) (match_dup 2))]
20021 [(match_scratch:QI 2 "q")
20022 (set (match_operand:QI 0 "memory_operand" "")
20023 (match_operand:QI 1 "immediate_operand" ""))]
20025 && TARGET_SPLIT_LONG_MOVES
20026 && get_attr_length (insn) >= ix86_cost->large_insn"
20027 [(set (match_dup 2) (match_dup 1))
20028 (set (match_dup 0) (match_dup 2))]
20031 ;; Don't compare memory with zero, load and use a test instead.
20033 [(set (match_operand 0 "flags_reg_operand" "")
20034 (match_operator 1 "compare_operator"
20035 [(match_operand:SI 2 "memory_operand" "")
20037 (match_scratch:SI 3 "r")]
20038 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20039 [(set (match_dup 3) (match_dup 2))
20040 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20043 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20044 ;; Don't split NOTs with a displacement operand, because resulting XOR
20045 ;; will not be pairable anyway.
20047 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20048 ;; represented using a modRM byte. The XOR replacement is long decoded,
20049 ;; so this split helps here as well.
20051 ;; Note: Can't do this as a regular split because we can't get proper
20052 ;; lifetime information then.
20055 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20056 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20058 && ((TARGET_NOT_UNPAIRABLE
20059 && (!MEM_P (operands[0])
20060 || !memory_displacement_operand (operands[0], SImode)))
20061 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20062 && peep2_regno_dead_p (0, FLAGS_REG)"
20063 [(parallel [(set (match_dup 0)
20064 (xor:SI (match_dup 1) (const_int -1)))
20065 (clobber (reg:CC FLAGS_REG))])]
20069 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20070 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20072 && ((TARGET_NOT_UNPAIRABLE
20073 && (!MEM_P (operands[0])
20074 || !memory_displacement_operand (operands[0], HImode)))
20075 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20076 && peep2_regno_dead_p (0, FLAGS_REG)"
20077 [(parallel [(set (match_dup 0)
20078 (xor:HI (match_dup 1) (const_int -1)))
20079 (clobber (reg:CC FLAGS_REG))])]
20083 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20084 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20086 && ((TARGET_NOT_UNPAIRABLE
20087 && (!MEM_P (operands[0])
20088 || !memory_displacement_operand (operands[0], QImode)))
20089 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20090 && peep2_regno_dead_p (0, FLAGS_REG)"
20091 [(parallel [(set (match_dup 0)
20092 (xor:QI (match_dup 1) (const_int -1)))
20093 (clobber (reg:CC FLAGS_REG))])]
20096 ;; Non pairable "test imm, reg" instructions can be translated to
20097 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20098 ;; byte opcode instead of two, have a short form for byte operands),
20099 ;; so do it for other CPUs as well. Given that the value was dead,
20100 ;; this should not create any new dependencies. Pass on the sub-word
20101 ;; versions if we're concerned about partial register stalls.
20104 [(set (match_operand 0 "flags_reg_operand" "")
20105 (match_operator 1 "compare_operator"
20106 [(and:SI (match_operand:SI 2 "register_operand" "")
20107 (match_operand:SI 3 "immediate_operand" ""))
20109 "ix86_match_ccmode (insn, CCNOmode)
20110 && (true_regnum (operands[2]) != AX_REG
20111 || satisfies_constraint_K (operands[3]))
20112 && peep2_reg_dead_p (1, operands[2])"
20114 [(set (match_dup 0)
20115 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20118 (and:SI (match_dup 2) (match_dup 3)))])]
20121 ;; We don't need to handle HImode case, because it will be promoted to SImode
20122 ;; on ! TARGET_PARTIAL_REG_STALL
20125 [(set (match_operand 0 "flags_reg_operand" "")
20126 (match_operator 1 "compare_operator"
20127 [(and:QI (match_operand:QI 2 "register_operand" "")
20128 (match_operand:QI 3 "immediate_operand" ""))
20130 "! TARGET_PARTIAL_REG_STALL
20131 && ix86_match_ccmode (insn, CCNOmode)
20132 && true_regnum (operands[2]) != AX_REG
20133 && peep2_reg_dead_p (1, operands[2])"
20135 [(set (match_dup 0)
20136 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20139 (and:QI (match_dup 2) (match_dup 3)))])]
20143 [(set (match_operand 0 "flags_reg_operand" "")
20144 (match_operator 1 "compare_operator"
20147 (match_operand 2 "ext_register_operand" "")
20150 (match_operand 3 "const_int_operand" ""))
20152 "! TARGET_PARTIAL_REG_STALL
20153 && ix86_match_ccmode (insn, CCNOmode)
20154 && true_regnum (operands[2]) != AX_REG
20155 && peep2_reg_dead_p (1, operands[2])"
20156 [(parallel [(set (match_dup 0)
20165 (set (zero_extract:SI (match_dup 2)
20176 ;; Don't do logical operations with memory inputs.
20178 [(match_scratch:SI 2 "r")
20179 (parallel [(set (match_operand:SI 0 "register_operand" "")
20180 (match_operator:SI 3 "arith_or_logical_operator"
20182 (match_operand:SI 1 "memory_operand" "")]))
20183 (clobber (reg:CC FLAGS_REG))])]
20184 "! optimize_size && ! TARGET_READ_MODIFY"
20185 [(set (match_dup 2) (match_dup 1))
20186 (parallel [(set (match_dup 0)
20187 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20188 (clobber (reg:CC FLAGS_REG))])]
20192 [(match_scratch:SI 2 "r")
20193 (parallel [(set (match_operand:SI 0 "register_operand" "")
20194 (match_operator:SI 3 "arith_or_logical_operator"
20195 [(match_operand:SI 1 "memory_operand" "")
20197 (clobber (reg:CC FLAGS_REG))])]
20198 "! optimize_size && ! TARGET_READ_MODIFY"
20199 [(set (match_dup 2) (match_dup 1))
20200 (parallel [(set (match_dup 0)
20201 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20202 (clobber (reg:CC FLAGS_REG))])]
20205 ; Don't do logical operations with memory outputs
20207 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20208 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20209 ; the same decoder scheduling characteristics as the original.
20212 [(match_scratch:SI 2 "r")
20213 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20214 (match_operator:SI 3 "arith_or_logical_operator"
20216 (match_operand:SI 1 "nonmemory_operand" "")]))
20217 (clobber (reg:CC FLAGS_REG))])]
20218 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20219 [(set (match_dup 2) (match_dup 0))
20220 (parallel [(set (match_dup 2)
20221 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20222 (clobber (reg:CC FLAGS_REG))])
20223 (set (match_dup 0) (match_dup 2))]
20227 [(match_scratch:SI 2 "r")
20228 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20229 (match_operator:SI 3 "arith_or_logical_operator"
20230 [(match_operand:SI 1 "nonmemory_operand" "")
20232 (clobber (reg:CC FLAGS_REG))])]
20233 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20234 [(set (match_dup 2) (match_dup 0))
20235 (parallel [(set (match_dup 2)
20236 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20237 (clobber (reg:CC FLAGS_REG))])
20238 (set (match_dup 0) (match_dup 2))]
20241 ;; Attempt to always use XOR for zeroing registers.
20243 [(set (match_operand 0 "register_operand" "")
20244 (match_operand 1 "const0_operand" ""))]
20245 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20246 && (! TARGET_USE_MOV0 || optimize_size)
20247 && GENERAL_REG_P (operands[0])
20248 && peep2_regno_dead_p (0, FLAGS_REG)"
20249 [(parallel [(set (match_dup 0) (const_int 0))
20250 (clobber (reg:CC FLAGS_REG))])]
20252 operands[0] = gen_lowpart (word_mode, operands[0]);
20256 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20258 "(GET_MODE (operands[0]) == QImode
20259 || GET_MODE (operands[0]) == HImode)
20260 && (! TARGET_USE_MOV0 || optimize_size)
20261 && peep2_regno_dead_p (0, FLAGS_REG)"
20262 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20263 (clobber (reg:CC FLAGS_REG))])])
20265 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20267 [(set (match_operand 0 "register_operand" "")
20269 "(GET_MODE (operands[0]) == HImode
20270 || GET_MODE (operands[0]) == SImode
20271 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20272 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20273 && peep2_regno_dead_p (0, FLAGS_REG)"
20274 [(parallel [(set (match_dup 0) (const_int -1))
20275 (clobber (reg:CC FLAGS_REG))])]
20276 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20279 ;; Attempt to convert simple leas to adds. These can be created by
20282 [(set (match_operand:SI 0 "register_operand" "")
20283 (plus:SI (match_dup 0)
20284 (match_operand:SI 1 "nonmemory_operand" "")))]
20285 "peep2_regno_dead_p (0, FLAGS_REG)"
20286 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20287 (clobber (reg:CC FLAGS_REG))])]
20291 [(set (match_operand:SI 0 "register_operand" "")
20292 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20293 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20294 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20295 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20296 (clobber (reg:CC FLAGS_REG))])]
20297 "operands[2] = gen_lowpart (SImode, operands[2]);")
20300 [(set (match_operand:DI 0 "register_operand" "")
20301 (plus:DI (match_dup 0)
20302 (match_operand:DI 1 "x86_64_general_operand" "")))]
20303 "peep2_regno_dead_p (0, FLAGS_REG)"
20304 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20305 (clobber (reg:CC FLAGS_REG))])]
20309 [(set (match_operand:SI 0 "register_operand" "")
20310 (mult:SI (match_dup 0)
20311 (match_operand:SI 1 "const_int_operand" "")))]
20312 "exact_log2 (INTVAL (operands[1])) >= 0
20313 && peep2_regno_dead_p (0, FLAGS_REG)"
20314 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20315 (clobber (reg:CC FLAGS_REG))])]
20316 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20319 [(set (match_operand:DI 0 "register_operand" "")
20320 (mult:DI (match_dup 0)
20321 (match_operand:DI 1 "const_int_operand" "")))]
20322 "exact_log2 (INTVAL (operands[1])) >= 0
20323 && peep2_regno_dead_p (0, FLAGS_REG)"
20324 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20325 (clobber (reg:CC FLAGS_REG))])]
20326 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20329 [(set (match_operand:SI 0 "register_operand" "")
20330 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20331 (match_operand:DI 2 "const_int_operand" "")) 0))]
20332 "exact_log2 (INTVAL (operands[2])) >= 0
20333 && REGNO (operands[0]) == REGNO (operands[1])
20334 && peep2_regno_dead_p (0, FLAGS_REG)"
20335 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20336 (clobber (reg:CC FLAGS_REG))])]
20337 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20339 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20340 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20341 ;; many CPUs it is also faster, since special hardware to avoid esp
20342 ;; dependencies is present.
20344 ;; While some of these conversions may be done using splitters, we use peepholes
20345 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20347 ;; Convert prologue esp subtractions to push.
20348 ;; We need register to push. In order to keep verify_flow_info happy we have
20350 ;; - use scratch and clobber it in order to avoid dependencies
20351 ;; - use already live register
20352 ;; We can't use the second way right now, since there is no reliable way how to
20353 ;; verify that given register is live. First choice will also most likely in
20354 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20355 ;; call clobbered registers are dead. We may want to use base pointer as an
20356 ;; alternative when no register is available later.
20359 [(match_scratch:SI 0 "r")
20360 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20361 (clobber (reg:CC FLAGS_REG))
20362 (clobber (mem:BLK (scratch)))])]
20363 "optimize_size || !TARGET_SUB_ESP_4"
20364 [(clobber (match_dup 0))
20365 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20366 (clobber (mem:BLK (scratch)))])])
20369 [(match_scratch:SI 0 "r")
20370 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20371 (clobber (reg:CC FLAGS_REG))
20372 (clobber (mem:BLK (scratch)))])]
20373 "optimize_size || !TARGET_SUB_ESP_8"
20374 [(clobber (match_dup 0))
20375 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20376 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20377 (clobber (mem:BLK (scratch)))])])
20379 ;; Convert esp subtractions to push.
20381 [(match_scratch:SI 0 "r")
20382 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20383 (clobber (reg:CC FLAGS_REG))])]
20384 "optimize_size || !TARGET_SUB_ESP_4"
20385 [(clobber (match_dup 0))
20386 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20389 [(match_scratch:SI 0 "r")
20390 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20391 (clobber (reg:CC FLAGS_REG))])]
20392 "optimize_size || !TARGET_SUB_ESP_8"
20393 [(clobber (match_dup 0))
20394 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20395 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20397 ;; Convert epilogue deallocator to pop.
20399 [(match_scratch:SI 0 "r")
20400 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20401 (clobber (reg:CC FLAGS_REG))
20402 (clobber (mem:BLK (scratch)))])]
20403 "optimize_size || !TARGET_ADD_ESP_4"
20404 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20405 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20406 (clobber (mem:BLK (scratch)))])]
20409 ;; Two pops case is tricky, since pop causes dependency on destination register.
20410 ;; We use two registers if available.
20412 [(match_scratch:SI 0 "r")
20413 (match_scratch:SI 1 "r")
20414 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20415 (clobber (reg:CC FLAGS_REG))
20416 (clobber (mem:BLK (scratch)))])]
20417 "optimize_size || !TARGET_ADD_ESP_8"
20418 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20419 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20420 (clobber (mem:BLK (scratch)))])
20421 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20422 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20426 [(match_scratch:SI 0 "r")
20427 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20428 (clobber (reg:CC FLAGS_REG))
20429 (clobber (mem:BLK (scratch)))])]
20431 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20432 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20433 (clobber (mem:BLK (scratch)))])
20434 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20435 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20438 ;; Convert esp additions to pop.
20440 [(match_scratch:SI 0 "r")
20441 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20442 (clobber (reg:CC FLAGS_REG))])]
20444 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20445 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20448 ;; Two pops case is tricky, since pop causes dependency on destination register.
20449 ;; We use two registers if available.
20451 [(match_scratch:SI 0 "r")
20452 (match_scratch:SI 1 "r")
20453 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20454 (clobber (reg:CC FLAGS_REG))])]
20456 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20457 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20458 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20459 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20463 [(match_scratch:SI 0 "r")
20464 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20465 (clobber (reg:CC FLAGS_REG))])]
20467 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20468 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20469 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20470 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20473 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20474 ;; required and register dies. Similarly for 128 to plus -128.
20476 [(set (match_operand 0 "flags_reg_operand" "")
20477 (match_operator 1 "compare_operator"
20478 [(match_operand 2 "register_operand" "")
20479 (match_operand 3 "const_int_operand" "")]))]
20480 "(INTVAL (operands[3]) == -1
20481 || INTVAL (operands[3]) == 1
20482 || INTVAL (operands[3]) == 128)
20483 && ix86_match_ccmode (insn, CCGCmode)
20484 && peep2_reg_dead_p (1, operands[2])"
20485 [(parallel [(set (match_dup 0)
20486 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20487 (clobber (match_dup 2))])]
20491 [(match_scratch:DI 0 "r")
20492 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20493 (clobber (reg:CC FLAGS_REG))
20494 (clobber (mem:BLK (scratch)))])]
20495 "optimize_size || !TARGET_SUB_ESP_4"
20496 [(clobber (match_dup 0))
20497 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20498 (clobber (mem:BLK (scratch)))])])
20501 [(match_scratch:DI 0 "r")
20502 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20503 (clobber (reg:CC FLAGS_REG))
20504 (clobber (mem:BLK (scratch)))])]
20505 "optimize_size || !TARGET_SUB_ESP_8"
20506 [(clobber (match_dup 0))
20507 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20508 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20509 (clobber (mem:BLK (scratch)))])])
20511 ;; Convert esp subtractions to push.
20513 [(match_scratch:DI 0 "r")
20514 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20515 (clobber (reg:CC FLAGS_REG))])]
20516 "optimize_size || !TARGET_SUB_ESP_4"
20517 [(clobber (match_dup 0))
20518 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20521 [(match_scratch:DI 0 "r")
20522 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20523 (clobber (reg:CC FLAGS_REG))])]
20524 "optimize_size || !TARGET_SUB_ESP_8"
20525 [(clobber (match_dup 0))
20526 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20527 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20529 ;; Convert epilogue deallocator to pop.
20531 [(match_scratch:DI 0 "r")
20532 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20533 (clobber (reg:CC FLAGS_REG))
20534 (clobber (mem:BLK (scratch)))])]
20535 "optimize_size || !TARGET_ADD_ESP_4"
20536 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20537 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20538 (clobber (mem:BLK (scratch)))])]
20541 ;; Two pops case is tricky, since pop causes dependency on destination register.
20542 ;; We use two registers if available.
20544 [(match_scratch:DI 0 "r")
20545 (match_scratch:DI 1 "r")
20546 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20547 (clobber (reg:CC FLAGS_REG))
20548 (clobber (mem:BLK (scratch)))])]
20549 "optimize_size || !TARGET_ADD_ESP_8"
20550 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20551 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20552 (clobber (mem:BLK (scratch)))])
20553 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20554 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20558 [(match_scratch:DI 0 "r")
20559 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20560 (clobber (reg:CC FLAGS_REG))
20561 (clobber (mem:BLK (scratch)))])]
20563 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20564 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20565 (clobber (mem:BLK (scratch)))])
20566 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20567 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20570 ;; Convert esp additions to pop.
20572 [(match_scratch:DI 0 "r")
20573 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20574 (clobber (reg:CC FLAGS_REG))])]
20576 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20577 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20580 ;; Two pops case is tricky, since pop causes dependency on destination register.
20581 ;; We use two registers if available.
20583 [(match_scratch:DI 0 "r")
20584 (match_scratch:DI 1 "r")
20585 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20586 (clobber (reg:CC FLAGS_REG))])]
20588 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20589 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20590 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20591 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20595 [(match_scratch:DI 0 "r")
20596 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20597 (clobber (reg:CC FLAGS_REG))])]
20599 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20600 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20601 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20602 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20605 ;; Convert imul by three, five and nine into lea
20608 [(set (match_operand:SI 0 "register_operand" "")
20609 (mult:SI (match_operand:SI 1 "register_operand" "")
20610 (match_operand:SI 2 "const_int_operand" "")))
20611 (clobber (reg:CC FLAGS_REG))])]
20612 "INTVAL (operands[2]) == 3
20613 || INTVAL (operands[2]) == 5
20614 || INTVAL (operands[2]) == 9"
20615 [(set (match_dup 0)
20616 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20618 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20622 [(set (match_operand:SI 0 "register_operand" "")
20623 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20624 (match_operand:SI 2 "const_int_operand" "")))
20625 (clobber (reg:CC FLAGS_REG))])]
20627 && (INTVAL (operands[2]) == 3
20628 || INTVAL (operands[2]) == 5
20629 || INTVAL (operands[2]) == 9)"
20630 [(set (match_dup 0) (match_dup 1))
20632 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20634 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20638 [(set (match_operand:DI 0 "register_operand" "")
20639 (mult:DI (match_operand:DI 1 "register_operand" "")
20640 (match_operand:DI 2 "const_int_operand" "")))
20641 (clobber (reg:CC FLAGS_REG))])]
20643 && (INTVAL (operands[2]) == 3
20644 || INTVAL (operands[2]) == 5
20645 || INTVAL (operands[2]) == 9)"
20646 [(set (match_dup 0)
20647 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20649 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20653 [(set (match_operand:DI 0 "register_operand" "")
20654 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20655 (match_operand:DI 2 "const_int_operand" "")))
20656 (clobber (reg:CC FLAGS_REG))])]
20659 && (INTVAL (operands[2]) == 3
20660 || INTVAL (operands[2]) == 5
20661 || INTVAL (operands[2]) == 9)"
20662 [(set (match_dup 0) (match_dup 1))
20664 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20666 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20668 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20669 ;; imul $32bit_imm, reg, reg is direct decoded.
20671 [(match_scratch:DI 3 "r")
20672 (parallel [(set (match_operand:DI 0 "register_operand" "")
20673 (mult:DI (match_operand:DI 1 "memory_operand" "")
20674 (match_operand:DI 2 "immediate_operand" "")))
20675 (clobber (reg:CC FLAGS_REG))])]
20676 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20677 && !satisfies_constraint_K (operands[2])"
20678 [(set (match_dup 3) (match_dup 1))
20679 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20680 (clobber (reg:CC FLAGS_REG))])]
20684 [(match_scratch:SI 3 "r")
20685 (parallel [(set (match_operand:SI 0 "register_operand" "")
20686 (mult:SI (match_operand:SI 1 "memory_operand" "")
20687 (match_operand:SI 2 "immediate_operand" "")))
20688 (clobber (reg:CC FLAGS_REG))])]
20689 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20690 && !satisfies_constraint_K (operands[2])"
20691 [(set (match_dup 3) (match_dup 1))
20692 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20693 (clobber (reg:CC FLAGS_REG))])]
20697 [(match_scratch:SI 3 "r")
20698 (parallel [(set (match_operand:DI 0 "register_operand" "")
20700 (mult:SI (match_operand:SI 1 "memory_operand" "")
20701 (match_operand:SI 2 "immediate_operand" ""))))
20702 (clobber (reg:CC FLAGS_REG))])]
20703 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20704 && !satisfies_constraint_K (operands[2])"
20705 [(set (match_dup 3) (match_dup 1))
20706 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20707 (clobber (reg:CC FLAGS_REG))])]
20710 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20711 ;; Convert it into imul reg, reg
20712 ;; It would be better to force assembler to encode instruction using long
20713 ;; immediate, but there is apparently no way to do so.
20715 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20716 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20717 (match_operand:DI 2 "const_int_operand" "")))
20718 (clobber (reg:CC FLAGS_REG))])
20719 (match_scratch:DI 3 "r")]
20720 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20721 && satisfies_constraint_K (operands[2])"
20722 [(set (match_dup 3) (match_dup 2))
20723 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20724 (clobber (reg:CC FLAGS_REG))])]
20726 if (!rtx_equal_p (operands[0], operands[1]))
20727 emit_move_insn (operands[0], operands[1]);
20731 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20732 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20733 (match_operand:SI 2 "const_int_operand" "")))
20734 (clobber (reg:CC FLAGS_REG))])
20735 (match_scratch:SI 3 "r")]
20736 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20737 && satisfies_constraint_K (operands[2])"
20738 [(set (match_dup 3) (match_dup 2))
20739 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20740 (clobber (reg:CC FLAGS_REG))])]
20742 if (!rtx_equal_p (operands[0], operands[1]))
20743 emit_move_insn (operands[0], operands[1]);
20747 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20748 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20749 (match_operand:HI 2 "immediate_operand" "")))
20750 (clobber (reg:CC FLAGS_REG))])
20751 (match_scratch:HI 3 "r")]
20752 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20753 [(set (match_dup 3) (match_dup 2))
20754 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20755 (clobber (reg:CC FLAGS_REG))])]
20757 if (!rtx_equal_p (operands[0], operands[1]))
20758 emit_move_insn (operands[0], operands[1]);
20761 ;; After splitting up read-modify operations, array accesses with memory
20762 ;; operands might end up in form:
20764 ;; movl 4(%esp), %edx
20766 ;; instead of pre-splitting:
20768 ;; addl 4(%esp), %eax
20770 ;; movl 4(%esp), %edx
20771 ;; leal (%edx,%eax,4), %eax
20774 [(parallel [(set (match_operand 0 "register_operand" "")
20775 (ashift (match_operand 1 "register_operand" "")
20776 (match_operand 2 "const_int_operand" "")))
20777 (clobber (reg:CC FLAGS_REG))])
20778 (set (match_operand 3 "register_operand")
20779 (match_operand 4 "x86_64_general_operand" ""))
20780 (parallel [(set (match_operand 5 "register_operand" "")
20781 (plus (match_operand 6 "register_operand" "")
20782 (match_operand 7 "register_operand" "")))
20783 (clobber (reg:CC FLAGS_REG))])]
20784 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20785 /* Validate MODE for lea. */
20786 && ((!TARGET_PARTIAL_REG_STALL
20787 && (GET_MODE (operands[0]) == QImode
20788 || GET_MODE (operands[0]) == HImode))
20789 || GET_MODE (operands[0]) == SImode
20790 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20791 /* We reorder load and the shift. */
20792 && !rtx_equal_p (operands[1], operands[3])
20793 && !reg_overlap_mentioned_p (operands[0], operands[4])
20794 /* Last PLUS must consist of operand 0 and 3. */
20795 && !rtx_equal_p (operands[0], operands[3])
20796 && (rtx_equal_p (operands[3], operands[6])
20797 || rtx_equal_p (operands[3], operands[7]))
20798 && (rtx_equal_p (operands[0], operands[6])
20799 || rtx_equal_p (operands[0], operands[7]))
20800 /* The intermediate operand 0 must die or be same as output. */
20801 && (rtx_equal_p (operands[0], operands[5])
20802 || peep2_reg_dead_p (3, operands[0]))"
20803 [(set (match_dup 3) (match_dup 4))
20804 (set (match_dup 0) (match_dup 1))]
20806 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20807 int scale = 1 << INTVAL (operands[2]);
20808 rtx index = gen_lowpart (Pmode, operands[1]);
20809 rtx base = gen_lowpart (Pmode, operands[3]);
20810 rtx dest = gen_lowpart (mode, operands[5]);
20812 operands[1] = gen_rtx_PLUS (Pmode, base,
20813 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20815 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20816 operands[0] = dest;
20819 ;; Call-value patterns last so that the wildcard operand does not
20820 ;; disrupt insn-recog's switch tables.
20822 (define_insn "*call_value_pop_0"
20823 [(set (match_operand 0 "" "")
20824 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20825 (match_operand:SI 2 "" "")))
20826 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20827 (match_operand:SI 3 "immediate_operand" "")))]
20830 if (SIBLING_CALL_P (insn))
20833 return "call\t%P1";
20835 [(set_attr "type" "callv")])
20837 (define_insn "*call_value_pop_1"
20838 [(set (match_operand 0 "" "")
20839 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20840 (match_operand:SI 2 "" "")))
20841 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20842 (match_operand:SI 3 "immediate_operand" "i")))]
20845 if (constant_call_address_operand (operands[1], Pmode))
20847 if (SIBLING_CALL_P (insn))
20850 return "call\t%P1";
20852 if (SIBLING_CALL_P (insn))
20855 return "call\t%A1";
20857 [(set_attr "type" "callv")])
20859 (define_insn "*call_value_0"
20860 [(set (match_operand 0 "" "")
20861 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20862 (match_operand:SI 2 "" "")))]
20865 if (SIBLING_CALL_P (insn))
20868 return "call\t%P1";
20870 [(set_attr "type" "callv")])
20872 (define_insn "*call_value_0_rex64"
20873 [(set (match_operand 0 "" "")
20874 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20875 (match_operand:DI 2 "const_int_operand" "")))]
20878 if (SIBLING_CALL_P (insn))
20881 return "call\t%P1";
20883 [(set_attr "type" "callv")])
20885 (define_insn "*call_value_1"
20886 [(set (match_operand 0 "" "")
20887 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20888 (match_operand:SI 2 "" "")))]
20889 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20891 if (constant_call_address_operand (operands[1], Pmode))
20892 return "call\t%P1";
20893 return "call\t%A1";
20895 [(set_attr "type" "callv")])
20897 (define_insn "*sibcall_value_1"
20898 [(set (match_operand 0 "" "")
20899 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20900 (match_operand:SI 2 "" "")))]
20901 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20903 if (constant_call_address_operand (operands[1], Pmode))
20907 [(set_attr "type" "callv")])
20909 (define_insn "*call_value_1_rex64"
20910 [(set (match_operand 0 "" "")
20911 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20912 (match_operand:DI 2 "" "")))]
20913 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20914 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20916 if (constant_call_address_operand (operands[1], Pmode))
20917 return "call\t%P1";
20918 return "call\t%A1";
20920 [(set_attr "type" "callv")])
20922 (define_insn "*call_value_1_rex64_large"
20923 [(set (match_operand 0 "" "")
20924 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20925 (match_operand:DI 2 "" "")))]
20926 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20928 [(set_attr "type" "callv")])
20930 (define_insn "*sibcall_value_1_rex64"
20931 [(set (match_operand 0 "" "")
20932 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20933 (match_operand:DI 2 "" "")))]
20934 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20936 [(set_attr "type" "callv")])
20938 (define_insn "*sibcall_value_1_rex64_v"
20939 [(set (match_operand 0 "" "")
20940 (call (mem:QI (reg:DI R11_REG))
20941 (match_operand:DI 1 "" "")))]
20942 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20944 [(set_attr "type" "callv")])
20946 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20947 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20948 ;; caught for use by garbage collectors and the like. Using an insn that
20949 ;; maps to SIGILL makes it more likely the program will rightfully die.
20950 ;; Keeping with tradition, "6" is in honor of #UD.
20951 (define_insn "trap"
20952 [(trap_if (const_int 1) (const_int 6))]
20954 { return ASM_SHORT "0x0b0f"; }
20955 [(set_attr "length" "2")])
20957 (define_expand "sse_prologue_save"
20958 [(parallel [(set (match_operand:BLK 0 "" "")
20959 (unspec:BLK [(reg:DI 21)
20966 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20967 (use (match_operand:DI 1 "register_operand" ""))
20968 (use (match_operand:DI 2 "immediate_operand" ""))
20969 (use (label_ref:DI (match_operand 3 "" "")))])]
20973 (define_insn "*sse_prologue_save_insn"
20974 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20975 (match_operand:DI 4 "const_int_operand" "n")))
20976 (unspec:BLK [(reg:DI 21)
20983 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20984 (use (match_operand:DI 1 "register_operand" "r"))
20985 (use (match_operand:DI 2 "const_int_operand" "i"))
20986 (use (label_ref:DI (match_operand 3 "" "X")))]
20988 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20989 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20993 operands[0] = gen_rtx_MEM (Pmode,
20994 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20995 output_asm_insn (\"jmp\\t%A1\", operands);
20996 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20998 operands[4] = adjust_address (operands[0], DImode, i*16);
20999 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21000 PUT_MODE (operands[4], TImode);
21001 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21002 output_asm_insn (\"rex\", operands);
21003 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21005 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21006 CODE_LABEL_NUMBER (operands[3]));
21010 [(set_attr "type" "other")
21011 (set_attr "length_immediate" "0")
21012 (set_attr "length_address" "0")
21013 (set_attr "length" "135")
21014 (set_attr "memory" "store")
21015 (set_attr "modrm" "0")
21016 (set_attr "mode" "DI")])
21018 (define_expand "prefetch"
21019 [(prefetch (match_operand 0 "address_operand" "")
21020 (match_operand:SI 1 "const_int_operand" "")
21021 (match_operand:SI 2 "const_int_operand" ""))]
21022 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21024 int rw = INTVAL (operands[1]);
21025 int locality = INTVAL (operands[2]);
21027 gcc_assert (rw == 0 || rw == 1);
21028 gcc_assert (locality >= 0 && locality <= 3);
21029 gcc_assert (GET_MODE (operands[0]) == Pmode
21030 || GET_MODE (operands[0]) == VOIDmode);
21032 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21033 supported by SSE counterpart or the SSE prefetch is not available
21034 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21036 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21037 operands[2] = GEN_INT (3);
21039 operands[1] = const0_rtx;
21042 (define_insn "*prefetch_sse"
21043 [(prefetch (match_operand:SI 0 "address_operand" "p")
21045 (match_operand:SI 1 "const_int_operand" ""))]
21046 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21048 static const char * const patterns[4] = {
21049 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21052 int locality = INTVAL (operands[1]);
21053 gcc_assert (locality >= 0 && locality <= 3);
21055 return patterns[locality];
21057 [(set_attr "type" "sse")
21058 (set_attr "memory" "none")])
21060 (define_insn "*prefetch_sse_rex"
21061 [(prefetch (match_operand:DI 0 "address_operand" "p")
21063 (match_operand:SI 1 "const_int_operand" ""))]
21064 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21066 static const char * const patterns[4] = {
21067 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21070 int locality = INTVAL (operands[1]);
21071 gcc_assert (locality >= 0 && locality <= 3);
21073 return patterns[locality];
21075 [(set_attr "type" "sse")
21076 (set_attr "memory" "none")])
21078 (define_insn "*prefetch_3dnow"
21079 [(prefetch (match_operand:SI 0 "address_operand" "p")
21080 (match_operand:SI 1 "const_int_operand" "n")
21082 "TARGET_3DNOW && !TARGET_64BIT"
21084 if (INTVAL (operands[1]) == 0)
21085 return "prefetch\t%a0";
21087 return "prefetchw\t%a0";
21089 [(set_attr "type" "mmx")
21090 (set_attr "memory" "none")])
21092 (define_insn "*prefetch_3dnow_rex"
21093 [(prefetch (match_operand:DI 0 "address_operand" "p")
21094 (match_operand:SI 1 "const_int_operand" "n")
21096 "TARGET_3DNOW && TARGET_64BIT"
21098 if (INTVAL (operands[1]) == 0)
21099 return "prefetch\t%a0";
21101 return "prefetchw\t%a0";
21103 [(set_attr "type" "mmx")
21104 (set_attr "memory" "none")])
21106 (define_expand "stack_protect_set"
21107 [(match_operand 0 "memory_operand" "")
21108 (match_operand 1 "memory_operand" "")]
21111 #ifdef TARGET_THREAD_SSP_OFFSET
21113 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21114 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21116 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21117 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21120 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21122 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21127 (define_insn "stack_protect_set_si"
21128 [(set (match_operand:SI 0 "memory_operand" "=m")
21129 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21130 (set (match_scratch:SI 2 "=&r") (const_int 0))
21131 (clobber (reg:CC FLAGS_REG))]
21133 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21134 [(set_attr "type" "multi")])
21136 (define_insn "stack_protect_set_di"
21137 [(set (match_operand:DI 0 "memory_operand" "=m")
21138 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21139 (set (match_scratch:DI 2 "=&r") (const_int 0))
21140 (clobber (reg:CC FLAGS_REG))]
21142 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21143 [(set_attr "type" "multi")])
21145 (define_insn "stack_tls_protect_set_si"
21146 [(set (match_operand:SI 0 "memory_operand" "=m")
21147 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21148 (set (match_scratch:SI 2 "=&r") (const_int 0))
21149 (clobber (reg:CC FLAGS_REG))]
21151 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21152 [(set_attr "type" "multi")])
21154 (define_insn "stack_tls_protect_set_di"
21155 [(set (match_operand:DI 0 "memory_operand" "=m")
21156 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21157 (set (match_scratch:DI 2 "=&r") (const_int 0))
21158 (clobber (reg:CC FLAGS_REG))]
21161 /* The kernel uses a different segment register for performance reasons; a
21162 system call would not have to trash the userspace segment register,
21163 which would be expensive */
21164 if (ix86_cmodel != CM_KERNEL)
21165 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21167 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21169 [(set_attr "type" "multi")])
21171 (define_expand "stack_protect_test"
21172 [(match_operand 0 "memory_operand" "")
21173 (match_operand 1 "memory_operand" "")
21174 (match_operand 2 "" "")]
21177 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21178 ix86_compare_op0 = operands[0];
21179 ix86_compare_op1 = operands[1];
21180 ix86_compare_emitted = flags;
21182 #ifdef TARGET_THREAD_SSP_OFFSET
21184 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21185 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21187 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21188 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21191 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21193 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21195 emit_jump_insn (gen_beq (operands[2]));
21199 (define_insn "stack_protect_test_si"
21200 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21201 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21202 (match_operand:SI 2 "memory_operand" "m")]
21204 (clobber (match_scratch:SI 3 "=&r"))]
21206 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21207 [(set_attr "type" "multi")])
21209 (define_insn "stack_protect_test_di"
21210 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21211 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21212 (match_operand:DI 2 "memory_operand" "m")]
21214 (clobber (match_scratch:DI 3 "=&r"))]
21216 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21217 [(set_attr "type" "multi")])
21219 (define_insn "stack_tls_protect_test_si"
21220 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21221 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21222 (match_operand:SI 2 "const_int_operand" "i")]
21223 UNSPEC_SP_TLS_TEST))
21224 (clobber (match_scratch:SI 3 "=r"))]
21226 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21227 [(set_attr "type" "multi")])
21229 (define_insn "stack_tls_protect_test_di"
21230 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21231 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21232 (match_operand:DI 2 "const_int_operand" "i")]
21233 UNSPEC_SP_TLS_TEST))
21234 (clobber (match_scratch:DI 3 "=r"))]
21237 /* The kernel uses a different segment register for performance reasons; a
21238 system call would not have to trash the userspace segment register,
21239 which would be expensive */
21240 if (ix86_cmodel != CM_KERNEL)
21241 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21243 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21245 [(set_attr "type" "multi")])
21247 (define_mode_iterator CRC32MODE [QI HI SI])
21248 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21249 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21251 (define_insn "sse4_2_crc32<mode>"
21252 [(set (match_operand:SI 0 "register_operand" "=r")
21254 [(match_operand:SI 1 "register_operand" "0")
21255 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21258 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21259 [(set_attr "type" "sselog1")
21260 (set_attr "prefix_rep" "1")
21261 (set_attr "prefix_extra" "1")
21262 (set_attr "mode" "SI")])
21264 (define_insn "sse4_2_crc32di"
21265 [(set (match_operand:DI 0 "register_operand" "=r")
21267 [(match_operand:DI 1 "register_operand" "0")
21268 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21270 "TARGET_SSE4_2 && TARGET_64BIT"
21271 "crc32q\t{%2, %0|%0, %2}"
21272 [(set_attr "type" "sselog1")
21273 (set_attr "prefix_rep" "1")
21274 (set_attr "prefix_extra" "1")
21275 (set_attr "mode" "DI")])
21279 (include "sync.md")