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 ;; All single word integer modes.
534 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
536 ;; Instruction suffix for integer modes.
537 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
539 ;; Register class for integer modes.
540 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
542 ;; Immediate operand constraint for integer modes.
543 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
545 ;; General operand predicate for integer modes.
546 (define_mode_attr general_operand
547 [(QI "general_operand")
548 (HI "general_operand")
549 (SI "general_operand")
550 (DI "x86_64_general_operand")])
552 ;; SSE and x87 SFmode and DFmode floating point modes
553 (define_mode_iterator MODEF [SF DF])
555 ;; All x87 floating point modes
556 (define_mode_iterator X87MODEF [SF DF XF])
558 ;; All integer modes handled by x87 fisttp operator.
559 (define_mode_iterator X87MODEI [HI SI DI])
561 ;; All integer modes handled by integer x87 operators.
562 (define_mode_iterator X87MODEI12 [HI SI])
564 ;; All integer modes handled by SSE cvtts?2si* operators.
565 (define_mode_iterator SSEMODEI24 [SI DI])
567 ;; SSE asm suffix for floating point modes
568 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
570 ;; SSE vector mode corresponding to a scalar mode
571 (define_mode_attr ssevecmode
572 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
574 ;; Scheduling descriptions
576 (include "pentium.md")
579 (include "athlon.md")
583 ;; Operand and operator predicates and constraints
585 (include "predicates.md")
586 (include "constraints.md")
589 ;; Compare instructions.
591 ;; All compare insns have expanders that save the operands away without
592 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
593 ;; after the cmp) will actually emit the cmpM.
595 (define_expand "cmpti"
596 [(set (reg:CC FLAGS_REG)
597 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
598 (match_operand:TI 1 "x86_64_general_operand" "")))]
601 if (MEM_P (operands[0]) && MEM_P (operands[1]))
602 operands[0] = force_reg (TImode, operands[0]);
603 ix86_compare_op0 = operands[0];
604 ix86_compare_op1 = operands[1];
608 (define_expand "cmpdi"
609 [(set (reg:CC FLAGS_REG)
610 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
611 (match_operand:DI 1 "x86_64_general_operand" "")))]
614 if (MEM_P (operands[0]) && MEM_P (operands[1]))
615 operands[0] = force_reg (DImode, operands[0]);
616 ix86_compare_op0 = operands[0];
617 ix86_compare_op1 = operands[1];
621 (define_expand "cmpsi"
622 [(set (reg:CC FLAGS_REG)
623 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
624 (match_operand:SI 1 "general_operand" "")))]
627 if (MEM_P (operands[0]) && MEM_P (operands[1]))
628 operands[0] = force_reg (SImode, operands[0]);
629 ix86_compare_op0 = operands[0];
630 ix86_compare_op1 = operands[1];
634 (define_expand "cmphi"
635 [(set (reg:CC FLAGS_REG)
636 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
637 (match_operand:HI 1 "general_operand" "")))]
640 if (MEM_P (operands[0]) && MEM_P (operands[1]))
641 operands[0] = force_reg (HImode, operands[0]);
642 ix86_compare_op0 = operands[0];
643 ix86_compare_op1 = operands[1];
647 (define_expand "cmpqi"
648 [(set (reg:CC FLAGS_REG)
649 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
650 (match_operand:QI 1 "general_operand" "")))]
653 if (MEM_P (operands[0]) && MEM_P (operands[1]))
654 operands[0] = force_reg (QImode, operands[0]);
655 ix86_compare_op0 = operands[0];
656 ix86_compare_op1 = operands[1];
660 (define_insn "cmpdi_ccno_1_rex64"
661 [(set (reg FLAGS_REG)
662 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
663 (match_operand:DI 1 "const0_operand" "n,n")))]
664 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
667 cmp{q}\t{%1, %0|%0, %1}"
668 [(set_attr "type" "test,icmp")
669 (set_attr "length_immediate" "0,1")
670 (set_attr "mode" "DI")])
672 (define_insn "*cmpdi_minus_1_rex64"
673 [(set (reg FLAGS_REG)
674 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
675 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
677 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
678 "cmp{q}\t{%1, %0|%0, %1}"
679 [(set_attr "type" "icmp")
680 (set_attr "mode" "DI")])
682 (define_expand "cmpdi_1_rex64"
683 [(set (reg:CC FLAGS_REG)
684 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
685 (match_operand:DI 1 "general_operand" "")))]
689 (define_insn "cmpdi_1_insn_rex64"
690 [(set (reg FLAGS_REG)
691 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
692 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
693 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
694 "cmp{q}\t{%1, %0|%0, %1}"
695 [(set_attr "type" "icmp")
696 (set_attr "mode" "DI")])
699 (define_insn "*cmpsi_ccno_1"
700 [(set (reg FLAGS_REG)
701 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
702 (match_operand:SI 1 "const0_operand" "n,n")))]
703 "ix86_match_ccmode (insn, CCNOmode)"
706 cmp{l}\t{%1, %0|%0, %1}"
707 [(set_attr "type" "test,icmp")
708 (set_attr "length_immediate" "0,1")
709 (set_attr "mode" "SI")])
711 (define_insn "*cmpsi_minus_1"
712 [(set (reg FLAGS_REG)
713 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
714 (match_operand:SI 1 "general_operand" "ri,mr"))
716 "ix86_match_ccmode (insn, CCGOCmode)"
717 "cmp{l}\t{%1, %0|%0, %1}"
718 [(set_attr "type" "icmp")
719 (set_attr "mode" "SI")])
721 (define_expand "cmpsi_1"
722 [(set (reg:CC FLAGS_REG)
723 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
724 (match_operand:SI 1 "general_operand" "")))]
728 (define_insn "*cmpsi_1_insn"
729 [(set (reg FLAGS_REG)
730 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
731 (match_operand:SI 1 "general_operand" "ri,mr")))]
732 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
733 && ix86_match_ccmode (insn, CCmode)"
734 "cmp{l}\t{%1, %0|%0, %1}"
735 [(set_attr "type" "icmp")
736 (set_attr "mode" "SI")])
738 (define_insn "*cmphi_ccno_1"
739 [(set (reg FLAGS_REG)
740 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
741 (match_operand:HI 1 "const0_operand" "n,n")))]
742 "ix86_match_ccmode (insn, CCNOmode)"
745 cmp{w}\t{%1, %0|%0, %1}"
746 [(set_attr "type" "test,icmp")
747 (set_attr "length_immediate" "0,1")
748 (set_attr "mode" "HI")])
750 (define_insn "*cmphi_minus_1"
751 [(set (reg FLAGS_REG)
752 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
753 (match_operand:HI 1 "general_operand" "ri,mr"))
755 "ix86_match_ccmode (insn, CCGOCmode)"
756 "cmp{w}\t{%1, %0|%0, %1}"
757 [(set_attr "type" "icmp")
758 (set_attr "mode" "HI")])
760 (define_insn "*cmphi_1"
761 [(set (reg FLAGS_REG)
762 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
763 (match_operand:HI 1 "general_operand" "ri,mr")))]
764 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
765 && ix86_match_ccmode (insn, CCmode)"
766 "cmp{w}\t{%1, %0|%0, %1}"
767 [(set_attr "type" "icmp")
768 (set_attr "mode" "HI")])
770 (define_insn "*cmpqi_ccno_1"
771 [(set (reg FLAGS_REG)
772 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
773 (match_operand:QI 1 "const0_operand" "n,n")))]
774 "ix86_match_ccmode (insn, CCNOmode)"
777 cmp{b}\t{$0, %0|%0, 0}"
778 [(set_attr "type" "test,icmp")
779 (set_attr "length_immediate" "0,1")
780 (set_attr "mode" "QI")])
782 (define_insn "*cmpqi_1"
783 [(set (reg FLAGS_REG)
784 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
785 (match_operand:QI 1 "general_operand" "qi,mq")))]
786 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
787 && ix86_match_ccmode (insn, CCmode)"
788 "cmp{b}\t{%1, %0|%0, %1}"
789 [(set_attr "type" "icmp")
790 (set_attr "mode" "QI")])
792 (define_insn "*cmpqi_minus_1"
793 [(set (reg FLAGS_REG)
794 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
795 (match_operand:QI 1 "general_operand" "qi,mq"))
797 "ix86_match_ccmode (insn, CCGOCmode)"
798 "cmp{b}\t{%1, %0|%0, %1}"
799 [(set_attr "type" "icmp")
800 (set_attr "mode" "QI")])
802 (define_insn "*cmpqi_ext_1"
803 [(set (reg FLAGS_REG)
805 (match_operand:QI 0 "general_operand" "Qm")
808 (match_operand 1 "ext_register_operand" "Q")
811 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
812 "cmp{b}\t{%h1, %0|%0, %h1}"
813 [(set_attr "type" "icmp")
814 (set_attr "mode" "QI")])
816 (define_insn "*cmpqi_ext_1_rex64"
817 [(set (reg FLAGS_REG)
819 (match_operand:QI 0 "register_operand" "Q")
822 (match_operand 1 "ext_register_operand" "Q")
825 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
826 "cmp{b}\t{%h1, %0|%0, %h1}"
827 [(set_attr "type" "icmp")
828 (set_attr "mode" "QI")])
830 (define_insn "*cmpqi_ext_2"
831 [(set (reg FLAGS_REG)
835 (match_operand 0 "ext_register_operand" "Q")
838 (match_operand:QI 1 "const0_operand" "n")))]
839 "ix86_match_ccmode (insn, CCNOmode)"
841 [(set_attr "type" "test")
842 (set_attr "length_immediate" "0")
843 (set_attr "mode" "QI")])
845 (define_expand "cmpqi_ext_3"
846 [(set (reg:CC FLAGS_REG)
850 (match_operand 0 "ext_register_operand" "")
853 (match_operand:QI 1 "general_operand" "")))]
857 (define_insn "cmpqi_ext_3_insn"
858 [(set (reg FLAGS_REG)
862 (match_operand 0 "ext_register_operand" "Q")
865 (match_operand:QI 1 "general_operand" "Qmn")))]
866 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
867 "cmp{b}\t{%1, %h0|%h0, %1}"
868 [(set_attr "type" "icmp")
869 (set_attr "mode" "QI")])
871 (define_insn "cmpqi_ext_3_insn_rex64"
872 [(set (reg FLAGS_REG)
876 (match_operand 0 "ext_register_operand" "Q")
879 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
880 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
881 "cmp{b}\t{%1, %h0|%h0, %1}"
882 [(set_attr "type" "icmp")
883 (set_attr "mode" "QI")])
885 (define_insn "*cmpqi_ext_4"
886 [(set (reg FLAGS_REG)
890 (match_operand 0 "ext_register_operand" "Q")
895 (match_operand 1 "ext_register_operand" "Q")
898 "ix86_match_ccmode (insn, CCmode)"
899 "cmp{b}\t{%h1, %h0|%h0, %h1}"
900 [(set_attr "type" "icmp")
901 (set_attr "mode" "QI")])
903 ;; These implement float point compares.
904 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
905 ;; which would allow mix and match FP modes on the compares. Which is what
906 ;; the old patterns did, but with many more of them.
908 (define_expand "cmpxf"
909 [(set (reg:CC FLAGS_REG)
910 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
911 (match_operand:XF 1 "nonmemory_operand" "")))]
914 ix86_compare_op0 = operands[0];
915 ix86_compare_op1 = operands[1];
919 (define_expand "cmp<mode>"
920 [(set (reg:CC FLAGS_REG)
921 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
922 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
923 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
925 ix86_compare_op0 = operands[0];
926 ix86_compare_op1 = operands[1];
930 ;; FP compares, step 1:
931 ;; Set the FP condition codes.
933 ;; CCFPmode compare with exceptions
934 ;; CCFPUmode compare with no exceptions
936 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
937 ;; used to manage the reg stack popping would not be preserved.
939 (define_insn "*cmpfp_0"
940 [(set (match_operand:HI 0 "register_operand" "=a")
943 (match_operand 1 "register_operand" "f")
944 (match_operand 2 "const0_operand" "X"))]
946 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
947 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
948 "* return output_fp_compare (insn, operands, 0, 0);"
949 [(set_attr "type" "multi")
950 (set_attr "unit" "i387")
952 (cond [(match_operand:SF 1 "" "")
954 (match_operand:DF 1 "" "")
957 (const_string "XF")))])
959 (define_insn_and_split "*cmpfp_0_cc"
960 [(set (reg:CCFP FLAGS_REG)
962 (match_operand 1 "register_operand" "f")
963 (match_operand 2 "const0_operand" "X")))
964 (clobber (match_operand:HI 0 "register_operand" "=a"))]
965 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
966 && TARGET_SAHF && !TARGET_CMOVE
967 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
969 "&& reload_completed"
972 [(compare:CCFP (match_dup 1)(match_dup 2))]
974 (set (reg:CC FLAGS_REG)
975 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
977 [(set_attr "type" "multi")
978 (set_attr "unit" "i387")
980 (cond [(match_operand:SF 1 "" "")
982 (match_operand:DF 1 "" "")
985 (const_string "XF")))])
987 (define_insn "*cmpfp_xf"
988 [(set (match_operand:HI 0 "register_operand" "=a")
991 (match_operand:XF 1 "register_operand" "f")
992 (match_operand:XF 2 "register_operand" "f"))]
995 "* return output_fp_compare (insn, operands, 0, 0);"
996 [(set_attr "type" "multi")
997 (set_attr "unit" "i387")
998 (set_attr "mode" "XF")])
1000 (define_insn_and_split "*cmpfp_xf_cc"
1001 [(set (reg:CCFP FLAGS_REG)
1003 (match_operand:XF 1 "register_operand" "f")
1004 (match_operand:XF 2 "register_operand" "f")))
1005 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1007 && TARGET_SAHF && !TARGET_CMOVE"
1009 "&& reload_completed"
1012 [(compare:CCFP (match_dup 1)(match_dup 2))]
1014 (set (reg:CC FLAGS_REG)
1015 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1017 [(set_attr "type" "multi")
1018 (set_attr "unit" "i387")
1019 (set_attr "mode" "XF")])
1021 (define_insn "*cmpfp_<mode>"
1022 [(set (match_operand:HI 0 "register_operand" "=a")
1025 (match_operand:MODEF 1 "register_operand" "f")
1026 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1029 "* return output_fp_compare (insn, operands, 0, 0);"
1030 [(set_attr "type" "multi")
1031 (set_attr "unit" "i387")
1032 (set_attr "mode" "<MODE>")])
1034 (define_insn_and_split "*cmpfp_<mode>_cc"
1035 [(set (reg:CCFP FLAGS_REG)
1037 (match_operand:MODEF 1 "register_operand" "f")
1038 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1039 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1041 && TARGET_SAHF && !TARGET_CMOVE"
1043 "&& reload_completed"
1046 [(compare:CCFP (match_dup 1)(match_dup 2))]
1048 (set (reg:CC FLAGS_REG)
1049 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1051 [(set_attr "type" "multi")
1052 (set_attr "unit" "i387")
1053 (set_attr "mode" "<MODE>")])
1055 (define_insn "*cmpfp_u"
1056 [(set (match_operand:HI 0 "register_operand" "=a")
1059 (match_operand 1 "register_operand" "f")
1060 (match_operand 2 "register_operand" "f"))]
1062 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1063 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1064 "* return output_fp_compare (insn, operands, 0, 1);"
1065 [(set_attr "type" "multi")
1066 (set_attr "unit" "i387")
1068 (cond [(match_operand:SF 1 "" "")
1070 (match_operand:DF 1 "" "")
1073 (const_string "XF")))])
1075 (define_insn_and_split "*cmpfp_u_cc"
1076 [(set (reg:CCFPU FLAGS_REG)
1078 (match_operand 1 "register_operand" "f")
1079 (match_operand 2 "register_operand" "f")))
1080 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1081 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1082 && TARGET_SAHF && !TARGET_CMOVE
1083 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1085 "&& reload_completed"
1088 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1090 (set (reg:CC FLAGS_REG)
1091 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1093 [(set_attr "type" "multi")
1094 (set_attr "unit" "i387")
1096 (cond [(match_operand:SF 1 "" "")
1098 (match_operand:DF 1 "" "")
1101 (const_string "XF")))])
1103 (define_insn "*cmpfp_<mode>"
1104 [(set (match_operand:HI 0 "register_operand" "=a")
1107 (match_operand 1 "register_operand" "f")
1108 (match_operator 3 "float_operator"
1109 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1111 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1112 && TARGET_USE_<MODE>MODE_FIOP
1113 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1114 "* return output_fp_compare (insn, operands, 0, 0);"
1115 [(set_attr "type" "multi")
1116 (set_attr "unit" "i387")
1117 (set_attr "fp_int_src" "true")
1118 (set_attr "mode" "<MODE>")])
1120 (define_insn_and_split "*cmpfp_<mode>_cc"
1121 [(set (reg:CCFP FLAGS_REG)
1123 (match_operand 1 "register_operand" "f")
1124 (match_operator 3 "float_operator"
1125 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1126 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1127 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1128 && TARGET_SAHF && !TARGET_CMOVE
1129 && TARGET_USE_<MODE>MODE_FIOP
1130 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1132 "&& reload_completed"
1137 (match_op_dup 3 [(match_dup 2)]))]
1139 (set (reg:CC FLAGS_REG)
1140 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1142 [(set_attr "type" "multi")
1143 (set_attr "unit" "i387")
1144 (set_attr "fp_int_src" "true")
1145 (set_attr "mode" "<MODE>")])
1147 ;; FP compares, step 2
1148 ;; Move the fpsw to ax.
1150 (define_insn "x86_fnstsw_1"
1151 [(set (match_operand:HI 0 "register_operand" "=a")
1152 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1155 [(set_attr "length" "2")
1156 (set_attr "mode" "SI")
1157 (set_attr "unit" "i387")])
1159 ;; FP compares, step 3
1160 ;; Get ax into flags, general case.
1162 (define_insn "x86_sahf_1"
1163 [(set (reg:CC FLAGS_REG)
1164 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1168 #ifdef HAVE_AS_IX86_SAHF
1171 return ".byte\t0x9e";
1174 [(set_attr "length" "1")
1175 (set_attr "athlon_decode" "vector")
1176 (set_attr "amdfam10_decode" "direct")
1177 (set_attr "mode" "SI")])
1179 ;; Pentium Pro can do steps 1 through 3 in one go.
1180 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1181 (define_insn "*cmpfp_i_mixed"
1182 [(set (reg:CCFP FLAGS_REG)
1183 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1184 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1185 "TARGET_MIX_SSE_I387
1186 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1187 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1188 "* return output_fp_compare (insn, operands, 1, 0);"
1189 [(set_attr "type" "fcmp,ssecomi")
1191 (if_then_else (match_operand:SF 1 "" "")
1193 (const_string "DF")))
1194 (set_attr "athlon_decode" "vector")
1195 (set_attr "amdfam10_decode" "direct")])
1197 (define_insn "*cmpfp_i_sse"
1198 [(set (reg:CCFP FLAGS_REG)
1199 (compare:CCFP (match_operand 0 "register_operand" "x")
1200 (match_operand 1 "nonimmediate_operand" "xm")))]
1202 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1203 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1204 "* return output_fp_compare (insn, operands, 1, 0);"
1205 [(set_attr "type" "ssecomi")
1207 (if_then_else (match_operand:SF 1 "" "")
1209 (const_string "DF")))
1210 (set_attr "athlon_decode" "vector")
1211 (set_attr "amdfam10_decode" "direct")])
1213 (define_insn "*cmpfp_i_i387"
1214 [(set (reg:CCFP FLAGS_REG)
1215 (compare:CCFP (match_operand 0 "register_operand" "f")
1216 (match_operand 1 "register_operand" "f")))]
1217 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1219 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1220 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1221 "* return output_fp_compare (insn, operands, 1, 0);"
1222 [(set_attr "type" "fcmp")
1224 (cond [(match_operand:SF 1 "" "")
1226 (match_operand:DF 1 "" "")
1229 (const_string "XF")))
1230 (set_attr "athlon_decode" "vector")
1231 (set_attr "amdfam10_decode" "direct")])
1233 (define_insn "*cmpfp_iu_mixed"
1234 [(set (reg:CCFPU FLAGS_REG)
1235 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1236 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1237 "TARGET_MIX_SSE_I387
1238 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1239 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1240 "* return output_fp_compare (insn, operands, 1, 1);"
1241 [(set_attr "type" "fcmp,ssecomi")
1243 (if_then_else (match_operand:SF 1 "" "")
1245 (const_string "DF")))
1246 (set_attr "athlon_decode" "vector")
1247 (set_attr "amdfam10_decode" "direct")])
1249 (define_insn "*cmpfp_iu_sse"
1250 [(set (reg:CCFPU FLAGS_REG)
1251 (compare:CCFPU (match_operand 0 "register_operand" "x")
1252 (match_operand 1 "nonimmediate_operand" "xm")))]
1254 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1255 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1256 "* return output_fp_compare (insn, operands, 1, 1);"
1257 [(set_attr "type" "ssecomi")
1259 (if_then_else (match_operand:SF 1 "" "")
1261 (const_string "DF")))
1262 (set_attr "athlon_decode" "vector")
1263 (set_attr "amdfam10_decode" "direct")])
1265 (define_insn "*cmpfp_iu_387"
1266 [(set (reg:CCFPU FLAGS_REG)
1267 (compare:CCFPU (match_operand 0 "register_operand" "f")
1268 (match_operand 1 "register_operand" "f")))]
1269 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1271 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1272 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1273 "* return output_fp_compare (insn, operands, 1, 1);"
1274 [(set_attr "type" "fcmp")
1276 (cond [(match_operand:SF 1 "" "")
1278 (match_operand:DF 1 "" "")
1281 (const_string "XF")))
1282 (set_attr "athlon_decode" "vector")
1283 (set_attr "amdfam10_decode" "direct")])
1285 ;; Move instructions.
1287 ;; General case of fullword move.
1289 (define_expand "movsi"
1290 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1291 (match_operand:SI 1 "general_operand" ""))]
1293 "ix86_expand_move (SImode, operands); DONE;")
1295 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1298 ;; %%% We don't use a post-inc memory reference because x86 is not a
1299 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1300 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1301 ;; targets without our curiosities, and it is just as easy to represent
1302 ;; this differently.
1304 (define_insn "*pushsi2"
1305 [(set (match_operand:SI 0 "push_operand" "=<")
1306 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1309 [(set_attr "type" "push")
1310 (set_attr "mode" "SI")])
1312 ;; For 64BIT abi we always round up to 8 bytes.
1313 (define_insn "*pushsi2_rex64"
1314 [(set (match_operand:SI 0 "push_operand" "=X")
1315 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1318 [(set_attr "type" "push")
1319 (set_attr "mode" "SI")])
1321 (define_insn "*pushsi2_prologue"
1322 [(set (match_operand:SI 0 "push_operand" "=<")
1323 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1324 (clobber (mem:BLK (scratch)))]
1327 [(set_attr "type" "push")
1328 (set_attr "mode" "SI")])
1330 (define_insn "*popsi1_epilogue"
1331 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1332 (mem:SI (reg:SI SP_REG)))
1333 (set (reg:SI SP_REG)
1334 (plus:SI (reg:SI SP_REG) (const_int 4)))
1335 (clobber (mem:BLK (scratch)))]
1338 [(set_attr "type" "pop")
1339 (set_attr "mode" "SI")])
1341 (define_insn "popsi1"
1342 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1343 (mem:SI (reg:SI SP_REG)))
1344 (set (reg:SI SP_REG)
1345 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1348 [(set_attr "type" "pop")
1349 (set_attr "mode" "SI")])
1351 (define_insn "*movsi_xor"
1352 [(set (match_operand:SI 0 "register_operand" "=r")
1353 (match_operand:SI 1 "const0_operand" "i"))
1354 (clobber (reg:CC FLAGS_REG))]
1355 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1357 [(set_attr "type" "alu1")
1358 (set_attr "mode" "SI")
1359 (set_attr "length_immediate" "0")])
1361 (define_insn "*movsi_or"
1362 [(set (match_operand:SI 0 "register_operand" "=r")
1363 (match_operand:SI 1 "immediate_operand" "i"))
1364 (clobber (reg:CC FLAGS_REG))]
1366 && operands[1] == constm1_rtx
1367 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1369 operands[1] = constm1_rtx;
1370 return "or{l}\t{%1, %0|%0, %1}";
1372 [(set_attr "type" "alu1")
1373 (set_attr "mode" "SI")
1374 (set_attr "length_immediate" "1")])
1376 (define_insn "*movsi_1"
1377 [(set (match_operand:SI 0 "nonimmediate_operand"
1378 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1379 (match_operand:SI 1 "general_operand"
1380 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1381 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1383 switch (get_attr_type (insn))
1386 if (get_attr_mode (insn) == MODE_TI)
1387 return "pxor\t%0, %0";
1388 return "xorps\t%0, %0";
1391 switch (get_attr_mode (insn))
1394 return "movdqa\t{%1, %0|%0, %1}";
1396 return "movaps\t{%1, %0|%0, %1}";
1398 return "movd\t{%1, %0|%0, %1}";
1400 return "movss\t{%1, %0|%0, %1}";
1406 return "pxor\t%0, %0";
1409 if (get_attr_mode (insn) == MODE_DI)
1410 return "movq\t{%1, %0|%0, %1}";
1411 return "movd\t{%1, %0|%0, %1}";
1414 return "lea{l}\t{%1, %0|%0, %1}";
1417 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1418 return "mov{l}\t{%1, %0|%0, %1}";
1422 (cond [(eq_attr "alternative" "2")
1423 (const_string "mmxadd")
1424 (eq_attr "alternative" "3,4,5")
1425 (const_string "mmxmov")
1426 (eq_attr "alternative" "6")
1427 (const_string "sselog1")
1428 (eq_attr "alternative" "7,8,9,10,11")
1429 (const_string "ssemov")
1430 (match_operand:DI 1 "pic_32bit_operand" "")
1431 (const_string "lea")
1433 (const_string "imov")))
1435 (cond [(eq_attr "alternative" "2,3")
1437 (eq_attr "alternative" "6,7")
1439 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1440 (const_string "V4SF")
1441 (const_string "TI"))
1442 (and (eq_attr "alternative" "8,9,10,11")
1443 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1446 (const_string "SI")))])
1448 ;; Stores and loads of ax to arbitrary constant address.
1449 ;; We fake an second form of instruction to force reload to load address
1450 ;; into register when rax is not available
1451 (define_insn "*movabssi_1_rex64"
1452 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1453 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1454 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1456 movabs{l}\t{%1, %P0|%P0, %1}
1457 mov{l}\t{%1, %a0|%a0, %1}"
1458 [(set_attr "type" "imov")
1459 (set_attr "modrm" "0,*")
1460 (set_attr "length_address" "8,0")
1461 (set_attr "length_immediate" "0,*")
1462 (set_attr "memory" "store")
1463 (set_attr "mode" "SI")])
1465 (define_insn "*movabssi_2_rex64"
1466 [(set (match_operand:SI 0 "register_operand" "=a,r")
1467 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1468 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1470 movabs{l}\t{%P1, %0|%0, %P1}
1471 mov{l}\t{%a1, %0|%0, %a1}"
1472 [(set_attr "type" "imov")
1473 (set_attr "modrm" "0,*")
1474 (set_attr "length_address" "8,0")
1475 (set_attr "length_immediate" "0")
1476 (set_attr "memory" "load")
1477 (set_attr "mode" "SI")])
1479 (define_insn "*swapsi"
1480 [(set (match_operand:SI 0 "register_operand" "+r")
1481 (match_operand:SI 1 "register_operand" "+r"))
1486 [(set_attr "type" "imov")
1487 (set_attr "mode" "SI")
1488 (set_attr "pent_pair" "np")
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "double")])
1492 (define_expand "movhi"
1493 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1494 (match_operand:HI 1 "general_operand" ""))]
1496 "ix86_expand_move (HImode, operands); DONE;")
1498 (define_insn "*pushhi2"
1499 [(set (match_operand:HI 0 "push_operand" "=X")
1500 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1503 [(set_attr "type" "push")
1504 (set_attr "mode" "SI")])
1506 ;; For 64BIT abi we always round up to 8 bytes.
1507 (define_insn "*pushhi2_rex64"
1508 [(set (match_operand:HI 0 "push_operand" "=X")
1509 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1512 [(set_attr "type" "push")
1513 (set_attr "mode" "DI")])
1515 (define_insn "*movhi_1"
1516 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1517 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1518 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1520 switch (get_attr_type (insn))
1523 /* movzwl is faster than movw on p2 due to partial word stalls,
1524 though not as fast as an aligned movl. */
1525 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1527 if (get_attr_mode (insn) == MODE_SI)
1528 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1530 return "mov{w}\t{%1, %0|%0, %1}";
1534 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1535 (const_string "imov")
1536 (and (eq_attr "alternative" "0")
1537 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1539 (eq (symbol_ref "TARGET_HIMODE_MATH")
1541 (const_string "imov")
1542 (and (eq_attr "alternative" "1,2")
1543 (match_operand:HI 1 "aligned_operand" ""))
1544 (const_string "imov")
1545 (and (ne (symbol_ref "TARGET_MOVX")
1547 (eq_attr "alternative" "0,2"))
1548 (const_string "imovx")
1550 (const_string "imov")))
1552 (cond [(eq_attr "type" "imovx")
1554 (and (eq_attr "alternative" "1,2")
1555 (match_operand:HI 1 "aligned_operand" ""))
1557 (and (eq_attr "alternative" "0")
1558 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1560 (eq (symbol_ref "TARGET_HIMODE_MATH")
1564 (const_string "HI")))])
1566 ;; Stores and loads of ax to arbitrary constant address.
1567 ;; We fake an second form of instruction to force reload to load address
1568 ;; into register when rax is not available
1569 (define_insn "*movabshi_1_rex64"
1570 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1571 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1572 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1574 movabs{w}\t{%1, %P0|%P0, %1}
1575 mov{w}\t{%1, %a0|%a0, %1}"
1576 [(set_attr "type" "imov")
1577 (set_attr "modrm" "0,*")
1578 (set_attr "length_address" "8,0")
1579 (set_attr "length_immediate" "0,*")
1580 (set_attr "memory" "store")
1581 (set_attr "mode" "HI")])
1583 (define_insn "*movabshi_2_rex64"
1584 [(set (match_operand:HI 0 "register_operand" "=a,r")
1585 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1586 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1588 movabs{w}\t{%P1, %0|%0, %P1}
1589 mov{w}\t{%a1, %0|%0, %a1}"
1590 [(set_attr "type" "imov")
1591 (set_attr "modrm" "0,*")
1592 (set_attr "length_address" "8,0")
1593 (set_attr "length_immediate" "0")
1594 (set_attr "memory" "load")
1595 (set_attr "mode" "HI")])
1597 (define_insn "*swaphi_1"
1598 [(set (match_operand:HI 0 "register_operand" "+r")
1599 (match_operand:HI 1 "register_operand" "+r"))
1602 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1604 [(set_attr "type" "imov")
1605 (set_attr "mode" "SI")
1606 (set_attr "pent_pair" "np")
1607 (set_attr "athlon_decode" "vector")
1608 (set_attr "amdfam10_decode" "double")])
1610 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1611 (define_insn "*swaphi_2"
1612 [(set (match_operand:HI 0 "register_operand" "+r")
1613 (match_operand:HI 1 "register_operand" "+r"))
1616 "TARGET_PARTIAL_REG_STALL"
1618 [(set_attr "type" "imov")
1619 (set_attr "mode" "HI")
1620 (set_attr "pent_pair" "np")
1621 (set_attr "athlon_decode" "vector")])
1623 (define_expand "movstricthi"
1624 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1625 (match_operand:HI 1 "general_operand" ""))]
1626 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1628 /* Don't generate memory->memory moves, go through a register */
1629 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1630 operands[1] = force_reg (HImode, operands[1]);
1633 (define_insn "*movstricthi_1"
1634 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1635 (match_operand:HI 1 "general_operand" "rn,m"))]
1636 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1637 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1638 "mov{w}\t{%1, %0|%0, %1}"
1639 [(set_attr "type" "imov")
1640 (set_attr "mode" "HI")])
1642 (define_insn "*movstricthi_xor"
1643 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1644 (match_operand:HI 1 "const0_operand" "i"))
1645 (clobber (reg:CC FLAGS_REG))]
1647 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1649 [(set_attr "type" "alu1")
1650 (set_attr "mode" "HI")
1651 (set_attr "length_immediate" "0")])
1653 (define_expand "movqi"
1654 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1655 (match_operand:QI 1 "general_operand" ""))]
1657 "ix86_expand_move (QImode, operands); DONE;")
1659 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1660 ;; "push a byte". But actually we use pushl, which has the effect
1661 ;; of rounding the amount pushed up to a word.
1663 (define_insn "*pushqi2"
1664 [(set (match_operand:QI 0 "push_operand" "=X")
1665 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1668 [(set_attr "type" "push")
1669 (set_attr "mode" "SI")])
1671 ;; For 64BIT abi we always round up to 8 bytes.
1672 (define_insn "*pushqi2_rex64"
1673 [(set (match_operand:QI 0 "push_operand" "=X")
1674 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1677 [(set_attr "type" "push")
1678 (set_attr "mode" "DI")])
1680 ;; Situation is quite tricky about when to choose full sized (SImode) move
1681 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1682 ;; partial register dependency machines (such as AMD Athlon), where QImode
1683 ;; moves issue extra dependency and for partial register stalls machines
1684 ;; that don't use QImode patterns (and QImode move cause stall on the next
1687 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1688 ;; register stall machines with, where we use QImode instructions, since
1689 ;; partial register stall can be caused there. Then we use movzx.
1690 (define_insn "*movqi_1"
1691 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1692 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1693 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1695 switch (get_attr_type (insn))
1698 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1699 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1701 if (get_attr_mode (insn) == MODE_SI)
1702 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1704 return "mov{b}\t{%1, %0|%0, %1}";
1708 (cond [(and (eq_attr "alternative" "5")
1709 (not (match_operand:QI 1 "aligned_operand" "")))
1710 (const_string "imovx")
1711 (ne (symbol_ref "optimize_size") (const_int 0))
1712 (const_string "imov")
1713 (and (eq_attr "alternative" "3")
1714 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1716 (eq (symbol_ref "TARGET_QIMODE_MATH")
1718 (const_string "imov")
1719 (eq_attr "alternative" "3,5")
1720 (const_string "imovx")
1721 (and (ne (symbol_ref "TARGET_MOVX")
1723 (eq_attr "alternative" "2"))
1724 (const_string "imovx")
1726 (const_string "imov")))
1728 (cond [(eq_attr "alternative" "3,4,5")
1730 (eq_attr "alternative" "6")
1732 (eq_attr "type" "imovx")
1734 (and (eq_attr "type" "imov")
1735 (and (eq_attr "alternative" "0,1")
1736 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1738 (and (eq (symbol_ref "optimize_size")
1740 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1743 ;; Avoid partial register stalls when not using QImode arithmetic
1744 (and (eq_attr "type" "imov")
1745 (and (eq_attr "alternative" "0,1")
1746 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1748 (eq (symbol_ref "TARGET_QIMODE_MATH")
1752 (const_string "QI")))])
1754 (define_expand "reload_outqi"
1755 [(parallel [(match_operand:QI 0 "" "=m")
1756 (match_operand:QI 1 "register_operand" "r")
1757 (match_operand:QI 2 "register_operand" "=&q")])]
1761 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1763 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1764 if (! q_regs_operand (op1, QImode))
1766 emit_insn (gen_movqi (op2, op1));
1769 emit_insn (gen_movqi (op0, op1));
1773 (define_insn "*swapqi_1"
1774 [(set (match_operand:QI 0 "register_operand" "+r")
1775 (match_operand:QI 1 "register_operand" "+r"))
1778 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1780 [(set_attr "type" "imov")
1781 (set_attr "mode" "SI")
1782 (set_attr "pent_pair" "np")
1783 (set_attr "athlon_decode" "vector")
1784 (set_attr "amdfam10_decode" "vector")])
1786 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1787 (define_insn "*swapqi_2"
1788 [(set (match_operand:QI 0 "register_operand" "+q")
1789 (match_operand:QI 1 "register_operand" "+q"))
1792 "TARGET_PARTIAL_REG_STALL"
1794 [(set_attr "type" "imov")
1795 (set_attr "mode" "QI")
1796 (set_attr "pent_pair" "np")
1797 (set_attr "athlon_decode" "vector")])
1799 (define_expand "movstrictqi"
1800 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1801 (match_operand:QI 1 "general_operand" ""))]
1802 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1804 /* Don't generate memory->memory moves, go through a register. */
1805 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1806 operands[1] = force_reg (QImode, operands[1]);
1809 (define_insn "*movstrictqi_1"
1810 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1811 (match_operand:QI 1 "general_operand" "*qn,m"))]
1812 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1813 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1814 "mov{b}\t{%1, %0|%0, %1}"
1815 [(set_attr "type" "imov")
1816 (set_attr "mode" "QI")])
1818 (define_insn "*movstrictqi_xor"
1819 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1820 (match_operand:QI 1 "const0_operand" "i"))
1821 (clobber (reg:CC FLAGS_REG))]
1822 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1824 [(set_attr "type" "alu1")
1825 (set_attr "mode" "QI")
1826 (set_attr "length_immediate" "0")])
1828 (define_insn "*movsi_extv_1"
1829 [(set (match_operand:SI 0 "register_operand" "=R")
1830 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1834 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1835 [(set_attr "type" "imovx")
1836 (set_attr "mode" "SI")])
1838 (define_insn "*movhi_extv_1"
1839 [(set (match_operand:HI 0 "register_operand" "=R")
1840 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1844 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1845 [(set_attr "type" "imovx")
1846 (set_attr "mode" "SI")])
1848 (define_insn "*movqi_extv_1"
1849 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1850 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1855 switch (get_attr_type (insn))
1858 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1860 return "mov{b}\t{%h1, %0|%0, %h1}";
1864 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1865 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1866 (ne (symbol_ref "TARGET_MOVX")
1868 (const_string "imovx")
1869 (const_string "imov")))
1871 (if_then_else (eq_attr "type" "imovx")
1873 (const_string "QI")))])
1875 (define_insn "*movqi_extv_1_rex64"
1876 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1877 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1882 switch (get_attr_type (insn))
1885 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1887 return "mov{b}\t{%h1, %0|%0, %h1}";
1891 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1892 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1893 (ne (symbol_ref "TARGET_MOVX")
1895 (const_string "imovx")
1896 (const_string "imov")))
1898 (if_then_else (eq_attr "type" "imovx")
1900 (const_string "QI")))])
1902 ;; Stores and loads of ax to arbitrary constant address.
1903 ;; We fake an second form of instruction to force reload to load address
1904 ;; into register when rax is not available
1905 (define_insn "*movabsqi_1_rex64"
1906 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1907 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1908 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1910 movabs{b}\t{%1, %P0|%P0, %1}
1911 mov{b}\t{%1, %a0|%a0, %1}"
1912 [(set_attr "type" "imov")
1913 (set_attr "modrm" "0,*")
1914 (set_attr "length_address" "8,0")
1915 (set_attr "length_immediate" "0,*")
1916 (set_attr "memory" "store")
1917 (set_attr "mode" "QI")])
1919 (define_insn "*movabsqi_2_rex64"
1920 [(set (match_operand:QI 0 "register_operand" "=a,r")
1921 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1922 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1924 movabs{b}\t{%P1, %0|%0, %P1}
1925 mov{b}\t{%a1, %0|%0, %a1}"
1926 [(set_attr "type" "imov")
1927 (set_attr "modrm" "0,*")
1928 (set_attr "length_address" "8,0")
1929 (set_attr "length_immediate" "0")
1930 (set_attr "memory" "load")
1931 (set_attr "mode" "QI")])
1933 (define_insn "*movdi_extzv_1"
1934 [(set (match_operand:DI 0 "register_operand" "=R")
1935 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1939 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1940 [(set_attr "type" "imovx")
1941 (set_attr "mode" "DI")])
1943 (define_insn "*movsi_extzv_1"
1944 [(set (match_operand:SI 0 "register_operand" "=R")
1945 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1949 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1950 [(set_attr "type" "imovx")
1951 (set_attr "mode" "SI")])
1953 (define_insn "*movqi_extzv_2"
1954 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1955 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1960 switch (get_attr_type (insn))
1963 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1965 return "mov{b}\t{%h1, %0|%0, %h1}";
1969 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1970 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1971 (ne (symbol_ref "TARGET_MOVX")
1973 (const_string "imovx")
1974 (const_string "imov")))
1976 (if_then_else (eq_attr "type" "imovx")
1978 (const_string "QI")))])
1980 (define_insn "*movqi_extzv_2_rex64"
1981 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1982 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1987 switch (get_attr_type (insn))
1990 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1992 return "mov{b}\t{%h1, %0|%0, %h1}";
1996 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1997 (ne (symbol_ref "TARGET_MOVX")
1999 (const_string "imovx")
2000 (const_string "imov")))
2002 (if_then_else (eq_attr "type" "imovx")
2004 (const_string "QI")))])
2006 (define_insn "movsi_insv_1"
2007 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2010 (match_operand:SI 1 "general_operand" "Qmn"))]
2012 "mov{b}\t{%b1, %h0|%h0, %b1}"
2013 [(set_attr "type" "imov")
2014 (set_attr "mode" "QI")])
2016 (define_insn "*movsi_insv_1_rex64"
2017 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2020 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2022 "mov{b}\t{%b1, %h0|%h0, %b1}"
2023 [(set_attr "type" "imov")
2024 (set_attr "mode" "QI")])
2026 (define_insn "movdi_insv_1_rex64"
2027 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2030 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2032 "mov{b}\t{%b1, %h0|%h0, %b1}"
2033 [(set_attr "type" "imov")
2034 (set_attr "mode" "QI")])
2036 (define_insn "*movqi_insv_2"
2037 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2040 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2043 "mov{b}\t{%h1, %h0|%h0, %h1}"
2044 [(set_attr "type" "imov")
2045 (set_attr "mode" "QI")])
2047 (define_expand "movdi"
2048 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2049 (match_operand:DI 1 "general_operand" ""))]
2051 "ix86_expand_move (DImode, operands); DONE;")
2053 (define_insn "*pushdi"
2054 [(set (match_operand:DI 0 "push_operand" "=<")
2055 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2059 (define_insn "*pushdi2_rex64"
2060 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2061 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2066 [(set_attr "type" "push,multi")
2067 (set_attr "mode" "DI")])
2069 ;; Convert impossible pushes of immediate to existing instructions.
2070 ;; First try to get scratch register and go through it. In case this
2071 ;; fails, push sign extended lower part first and then overwrite
2072 ;; upper part by 32bit move.
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "push_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))]
2083 ;; We need to define this as both peepholer and splitter for case
2084 ;; peephole2 pass is not run.
2085 ;; "&& 1" is needed to keep it from matching the previous pattern.
2087 [(set (match_operand:DI 0 "push_operand" "")
2088 (match_operand:DI 1 "immediate_operand" ""))]
2089 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2091 [(set (match_dup 0) (match_dup 1))
2092 (set (match_dup 2) (match_dup 3))]
2093 "split_di (operands + 1, 1, operands + 2, operands + 3);
2094 operands[1] = gen_lowpart (DImode, operands[2]);
2095 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2100 [(set (match_operand:DI 0 "push_operand" "")
2101 (match_operand:DI 1 "immediate_operand" ""))]
2102 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2103 ? epilogue_completed : reload_completed)
2104 && !symbolic_operand (operands[1], DImode)
2105 && !x86_64_immediate_operand (operands[1], DImode)"
2106 [(set (match_dup 0) (match_dup 1))
2107 (set (match_dup 2) (match_dup 3))]
2108 "split_di (operands + 1, 1, operands + 2, operands + 3);
2109 operands[1] = gen_lowpart (DImode, operands[2]);
2110 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2114 (define_insn "*pushdi2_prologue_rex64"
2115 [(set (match_operand:DI 0 "push_operand" "=<")
2116 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2117 (clobber (mem:BLK (scratch)))]
2120 [(set_attr "type" "push")
2121 (set_attr "mode" "DI")])
2123 (define_insn "*popdi1_epilogue_rex64"
2124 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2125 (mem:DI (reg:DI SP_REG)))
2126 (set (reg:DI SP_REG)
2127 (plus:DI (reg:DI SP_REG) (const_int 8)))
2128 (clobber (mem:BLK (scratch)))]
2131 [(set_attr "type" "pop")
2132 (set_attr "mode" "DI")])
2134 (define_insn "popdi1"
2135 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2136 (mem:DI (reg:DI SP_REG)))
2137 (set (reg:DI SP_REG)
2138 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2141 [(set_attr "type" "pop")
2142 (set_attr "mode" "DI")])
2144 (define_insn "*movdi_xor_rex64"
2145 [(set (match_operand:DI 0 "register_operand" "=r")
2146 (match_operand:DI 1 "const0_operand" "i"))
2147 (clobber (reg:CC FLAGS_REG))]
2148 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2149 && reload_completed"
2151 [(set_attr "type" "alu1")
2152 (set_attr "mode" "SI")
2153 (set_attr "length_immediate" "0")])
2155 (define_insn "*movdi_or_rex64"
2156 [(set (match_operand:DI 0 "register_operand" "=r")
2157 (match_operand:DI 1 "const_int_operand" "i"))
2158 (clobber (reg:CC FLAGS_REG))]
2159 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2161 && operands[1] == constm1_rtx"
2163 operands[1] = constm1_rtx;
2164 return "or{q}\t{%1, %0|%0, %1}";
2166 [(set_attr "type" "alu1")
2167 (set_attr "mode" "DI")
2168 (set_attr "length_immediate" "1")])
2170 (define_insn "*movdi_2"
2171 [(set (match_operand:DI 0 "nonimmediate_operand"
2172 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2173 (match_operand:DI 1 "general_operand"
2174 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2175 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2180 movq\t{%1, %0|%0, %1}
2181 movq\t{%1, %0|%0, %1}
2183 movq\t{%1, %0|%0, %1}
2184 movdqa\t{%1, %0|%0, %1}
2185 movq\t{%1, %0|%0, %1}
2187 movlps\t{%1, %0|%0, %1}
2188 movaps\t{%1, %0|%0, %1}
2189 movlps\t{%1, %0|%0, %1}"
2190 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2191 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2194 [(set (match_operand:DI 0 "push_operand" "")
2195 (match_operand:DI 1 "general_operand" ""))]
2196 "!TARGET_64BIT && reload_completed
2197 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2199 "ix86_split_long_move (operands); DONE;")
2201 ;; %%% This multiword shite has got to go.
2203 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2204 (match_operand:DI 1 "general_operand" ""))]
2205 "!TARGET_64BIT && reload_completed
2206 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2207 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2209 "ix86_split_long_move (operands); DONE;")
2211 (define_insn "*movdi_1_rex64"
2212 [(set (match_operand:DI 0 "nonimmediate_operand"
2213 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2214 (match_operand:DI 1 "general_operand"
2215 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2216 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2218 switch (get_attr_type (insn))
2221 if (SSE_REG_P (operands[0]))
2222 return "movq2dq\t{%1, %0|%0, %1}";
2224 return "movdq2q\t{%1, %0|%0, %1}";
2227 if (get_attr_mode (insn) == MODE_TI)
2228 return "movdqa\t{%1, %0|%0, %1}";
2232 /* Moves from and into integer register is done using movd
2233 opcode with REX prefix. */
2234 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2235 return "movd\t{%1, %0|%0, %1}";
2236 return "movq\t{%1, %0|%0, %1}";
2240 return "pxor\t%0, %0";
2246 return "lea{q}\t{%a1, %0|%0, %a1}";
2249 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2250 if (get_attr_mode (insn) == MODE_SI)
2251 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2252 else if (which_alternative == 2)
2253 return "movabs{q}\t{%1, %0|%0, %1}";
2255 return "mov{q}\t{%1, %0|%0, %1}";
2259 (cond [(eq_attr "alternative" "5")
2260 (const_string "mmxadd")
2261 (eq_attr "alternative" "6,7,8,9,10")
2262 (const_string "mmxmov")
2263 (eq_attr "alternative" "11")
2264 (const_string "sselog1")
2265 (eq_attr "alternative" "12,13,14,15,16")
2266 (const_string "ssemov")
2267 (eq_attr "alternative" "17,18")
2268 (const_string "ssecvt")
2269 (eq_attr "alternative" "4")
2270 (const_string "multi")
2271 (match_operand:DI 1 "pic_32bit_operand" "")
2272 (const_string "lea")
2274 (const_string "imov")))
2275 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2276 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2277 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2279 ;; Stores and loads of ax to arbitrary constant address.
2280 ;; We fake an second form of instruction to force reload to load address
2281 ;; into register when rax is not available
2282 (define_insn "*movabsdi_1_rex64"
2283 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2284 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2285 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2287 movabs{q}\t{%1, %P0|%P0, %1}
2288 mov{q}\t{%1, %a0|%a0, %1}"
2289 [(set_attr "type" "imov")
2290 (set_attr "modrm" "0,*")
2291 (set_attr "length_address" "8,0")
2292 (set_attr "length_immediate" "0,*")
2293 (set_attr "memory" "store")
2294 (set_attr "mode" "DI")])
2296 (define_insn "*movabsdi_2_rex64"
2297 [(set (match_operand:DI 0 "register_operand" "=a,r")
2298 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2299 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2301 movabs{q}\t{%P1, %0|%0, %P1}
2302 mov{q}\t{%a1, %0|%0, %a1}"
2303 [(set_attr "type" "imov")
2304 (set_attr "modrm" "0,*")
2305 (set_attr "length_address" "8,0")
2306 (set_attr "length_immediate" "0")
2307 (set_attr "memory" "load")
2308 (set_attr "mode" "DI")])
2310 ;; Convert impossible stores of immediate to existing instructions.
2311 ;; First try to get scratch register and go through it. In case this
2312 ;; fails, move by 32bit parts.
2314 [(match_scratch:DI 2 "r")
2315 (set (match_operand:DI 0 "memory_operand" "")
2316 (match_operand:DI 1 "immediate_operand" ""))]
2317 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2318 && !x86_64_immediate_operand (operands[1], DImode)"
2319 [(set (match_dup 2) (match_dup 1))
2320 (set (match_dup 0) (match_dup 2))]
2323 ;; We need to define this as both peepholer and splitter for case
2324 ;; peephole2 pass is not run.
2325 ;; "&& 1" is needed to keep it from matching the previous pattern.
2327 [(set (match_operand:DI 0 "memory_operand" "")
2328 (match_operand:DI 1 "immediate_operand" ""))]
2329 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2330 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2331 [(set (match_dup 2) (match_dup 3))
2332 (set (match_dup 4) (match_dup 5))]
2333 "split_di (operands, 2, operands + 2, operands + 4);")
2336 [(set (match_operand:DI 0 "memory_operand" "")
2337 (match_operand:DI 1 "immediate_operand" ""))]
2338 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2339 ? epilogue_completed : reload_completed)
2340 && !symbolic_operand (operands[1], DImode)
2341 && !x86_64_immediate_operand (operands[1], DImode)"
2342 [(set (match_dup 2) (match_dup 3))
2343 (set (match_dup 4) (match_dup 5))]
2344 "split_di (operands, 2, operands + 2, operands + 4);")
2346 (define_insn "*swapdi_rex64"
2347 [(set (match_operand:DI 0 "register_operand" "+r")
2348 (match_operand:DI 1 "register_operand" "+r"))
2353 [(set_attr "type" "imov")
2354 (set_attr "mode" "DI")
2355 (set_attr "pent_pair" "np")
2356 (set_attr "athlon_decode" "vector")
2357 (set_attr "amdfam10_decode" "double")])
2359 (define_expand "movti"
2360 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2361 (match_operand:TI 1 "nonimmediate_operand" ""))]
2362 "TARGET_SSE || TARGET_64BIT"
2365 ix86_expand_move (TImode, operands);
2366 else if (push_operand (operands[0], TImode))
2367 ix86_expand_push (TImode, operands[1]);
2369 ix86_expand_vector_move (TImode, operands);
2373 (define_insn "*movti_internal"
2374 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2375 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2376 "TARGET_SSE && !TARGET_64BIT
2377 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2379 switch (which_alternative)
2382 if (get_attr_mode (insn) == MODE_V4SF)
2383 return "xorps\t%0, %0";
2385 return "pxor\t%0, %0";
2388 if (get_attr_mode (insn) == MODE_V4SF)
2389 return "movaps\t{%1, %0|%0, %1}";
2391 return "movdqa\t{%1, %0|%0, %1}";
2396 [(set_attr "type" "sselog1,ssemov,ssemov")
2398 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2399 (ne (symbol_ref "optimize_size") (const_int 0)))
2400 (const_string "V4SF")
2401 (and (eq_attr "alternative" "2")
2402 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2404 (const_string "V4SF")]
2405 (const_string "TI")))])
2407 (define_insn "*movti_rex64"
2408 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2409 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2411 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2413 switch (which_alternative)
2419 if (get_attr_mode (insn) == MODE_V4SF)
2420 return "xorps\t%0, %0";
2422 return "pxor\t%0, %0";
2425 if (get_attr_mode (insn) == MODE_V4SF)
2426 return "movaps\t{%1, %0|%0, %1}";
2428 return "movdqa\t{%1, %0|%0, %1}";
2433 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2435 (cond [(eq_attr "alternative" "2,3")
2437 (ne (symbol_ref "optimize_size")
2439 (const_string "V4SF")
2440 (const_string "TI"))
2441 (eq_attr "alternative" "4")
2443 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2445 (ne (symbol_ref "optimize_size")
2447 (const_string "V4SF")
2448 (const_string "TI"))]
2449 (const_string "DI")))])
2452 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2453 (match_operand:TI 1 "general_operand" ""))]
2454 "reload_completed && !SSE_REG_P (operands[0])
2455 && !SSE_REG_P (operands[1])"
2457 "ix86_split_long_move (operands); DONE;")
2459 ;; This expands to what emit_move_complex would generate if we didn't
2460 ;; have a movti pattern. Having this avoids problems with reload on
2461 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2462 ;; to have around all the time.
2463 (define_expand "movcdi"
2464 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2465 (match_operand:CDI 1 "general_operand" ""))]
2468 if (push_operand (operands[0], CDImode))
2469 emit_move_complex_push (CDImode, operands[0], operands[1]);
2471 emit_move_complex_parts (operands[0], operands[1]);
2475 (define_expand "movsf"
2476 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2477 (match_operand:SF 1 "general_operand" ""))]
2479 "ix86_expand_move (SFmode, operands); DONE;")
2481 (define_insn "*pushsf"
2482 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2483 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2486 /* Anything else should be already split before reg-stack. */
2487 gcc_assert (which_alternative == 1);
2488 return "push{l}\t%1";
2490 [(set_attr "type" "multi,push,multi")
2491 (set_attr "unit" "i387,*,*")
2492 (set_attr "mode" "SF,SI,SF")])
2494 (define_insn "*pushsf_rex64"
2495 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2496 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2499 /* Anything else should be already split before reg-stack. */
2500 gcc_assert (which_alternative == 1);
2501 return "push{q}\t%q1";
2503 [(set_attr "type" "multi,push,multi")
2504 (set_attr "unit" "i387,*,*")
2505 (set_attr "mode" "SF,DI,SF")])
2508 [(set (match_operand:SF 0 "push_operand" "")
2509 (match_operand:SF 1 "memory_operand" ""))]
2511 && MEM_P (operands[1])
2512 && (operands[2] = find_constant_src (insn))"
2517 ;; %%% Kill this when call knows how to work this out.
2519 [(set (match_operand:SF 0 "push_operand" "")
2520 (match_operand:SF 1 "any_fp_register_operand" ""))]
2522 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2523 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2526 [(set (match_operand:SF 0 "push_operand" "")
2527 (match_operand:SF 1 "any_fp_register_operand" ""))]
2529 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2530 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2532 (define_insn "*movsf_1"
2533 [(set (match_operand:SF 0 "nonimmediate_operand"
2534 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2535 (match_operand:SF 1 "general_operand"
2536 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2537 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2538 && (reload_in_progress || reload_completed
2539 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2540 || (!TARGET_SSE_MATH && optimize_size
2541 && standard_80387_constant_p (operands[1]))
2542 || GET_CODE (operands[1]) != CONST_DOUBLE
2543 || memory_operand (operands[0], SFmode))"
2545 switch (which_alternative)
2549 return output_387_reg_move (insn, operands);
2552 return standard_80387_constant_opcode (operands[1]);
2556 return "mov{l}\t{%1, %0|%0, %1}";
2558 if (get_attr_mode (insn) == MODE_TI)
2559 return "pxor\t%0, %0";
2561 return "xorps\t%0, %0";
2563 if (get_attr_mode (insn) == MODE_V4SF)
2564 return "movaps\t{%1, %0|%0, %1}";
2566 return "movss\t{%1, %0|%0, %1}";
2568 return "movss\t{%1, %0|%0, %1}";
2571 case 12: case 13: case 14: case 15:
2572 return "movd\t{%1, %0|%0, %1}";
2575 return "movq\t{%1, %0|%0, %1}";
2581 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2583 (cond [(eq_attr "alternative" "3,4,9,10")
2585 (eq_attr "alternative" "5")
2587 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2589 (ne (symbol_ref "TARGET_SSE2")
2591 (eq (symbol_ref "optimize_size")
2594 (const_string "V4SF"))
2595 /* For architectures resolving dependencies on
2596 whole SSE registers use APS move to break dependency
2597 chains, otherwise use short move to avoid extra work.
2599 Do the same for architectures resolving dependencies on
2600 the parts. While in DF mode it is better to always handle
2601 just register parts, the SF mode is different due to lack
2602 of instructions to load just part of the register. It is
2603 better to maintain the whole registers in single format
2604 to avoid problems on using packed logical operations. */
2605 (eq_attr "alternative" "6")
2607 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2609 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2611 (const_string "V4SF")
2612 (const_string "SF"))
2613 (eq_attr "alternative" "11")
2614 (const_string "DI")]
2615 (const_string "SF")))])
2617 (define_insn "*swapsf"
2618 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2619 (match_operand:SF 1 "fp_register_operand" "+f"))
2622 "reload_completed || TARGET_80387"
2624 if (STACK_TOP_P (operands[0]))
2629 [(set_attr "type" "fxch")
2630 (set_attr "mode" "SF")])
2632 (define_expand "movdf"
2633 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2634 (match_operand:DF 1 "general_operand" ""))]
2636 "ix86_expand_move (DFmode, operands); DONE;")
2638 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2639 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2640 ;; On the average, pushdf using integers can be still shorter. Allow this
2641 ;; pattern for optimize_size too.
2643 (define_insn "*pushdf_nointeger"
2644 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2645 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2646 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2648 /* This insn should be already split before reg-stack. */
2651 [(set_attr "type" "multi")
2652 (set_attr "unit" "i387,*,*,*")
2653 (set_attr "mode" "DF,SI,SI,DF")])
2655 (define_insn "*pushdf_integer"
2656 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2657 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2658 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2660 /* This insn should be already split before reg-stack. */
2663 [(set_attr "type" "multi")
2664 (set_attr "unit" "i387,*,*")
2665 (set_attr "mode" "DF,SI,DF")])
2667 ;; %%% Kill this when call knows how to work this out.
2669 [(set (match_operand:DF 0 "push_operand" "")
2670 (match_operand:DF 1 "any_fp_register_operand" ""))]
2671 "!TARGET_64BIT && reload_completed"
2672 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2673 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2677 [(set (match_operand:DF 0 "push_operand" "")
2678 (match_operand:DF 1 "any_fp_register_operand" ""))]
2679 "TARGET_64BIT && reload_completed"
2680 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2681 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2685 [(set (match_operand:DF 0 "push_operand" "")
2686 (match_operand:DF 1 "general_operand" ""))]
2689 "ix86_split_long_move (operands); DONE;")
2691 ;; Moving is usually shorter when only FP registers are used. This separate
2692 ;; movdf pattern avoids the use of integer registers for FP operations
2693 ;; when optimizing for size.
2695 (define_insn "*movdf_nointeger"
2696 [(set (match_operand:DF 0 "nonimmediate_operand"
2697 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2698 (match_operand:DF 1 "general_operand"
2699 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2700 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2701 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2702 && (reload_in_progress || reload_completed
2703 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2704 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2705 && !memory_operand (operands[0], DFmode)
2706 && standard_80387_constant_p (operands[1]))
2707 || GET_CODE (operands[1]) != CONST_DOUBLE
2709 || !TARGET_MEMORY_MISMATCH_STALL
2710 || reload_in_progress || reload_completed)
2711 && memory_operand (operands[0], DFmode)))"
2713 switch (which_alternative)
2717 return output_387_reg_move (insn, operands);
2720 return standard_80387_constant_opcode (operands[1]);
2726 switch (get_attr_mode (insn))
2729 return "xorps\t%0, %0";
2731 return "xorpd\t%0, %0";
2733 return "pxor\t%0, %0";
2740 switch (get_attr_mode (insn))
2743 return "movaps\t{%1, %0|%0, %1}";
2745 return "movapd\t{%1, %0|%0, %1}";
2747 return "movdqa\t{%1, %0|%0, %1}";
2749 return "movq\t{%1, %0|%0, %1}";
2751 return "movsd\t{%1, %0|%0, %1}";
2753 return "movlpd\t{%1, %0|%0, %1}";
2755 return "movlps\t{%1, %0|%0, %1}";
2764 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2766 (cond [(eq_attr "alternative" "0,1,2")
2768 (eq_attr "alternative" "3,4")
2771 /* For SSE1, we have many fewer alternatives. */
2772 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2773 (cond [(eq_attr "alternative" "5,6")
2774 (const_string "V4SF")
2776 (const_string "V2SF"))
2778 /* xorps is one byte shorter. */
2779 (eq_attr "alternative" "5")
2780 (cond [(ne (symbol_ref "optimize_size")
2782 (const_string "V4SF")
2783 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2787 (const_string "V2DF"))
2789 /* For architectures resolving dependencies on
2790 whole SSE registers use APD move to break dependency
2791 chains, otherwise use short move to avoid extra work.
2793 movaps encodes one byte shorter. */
2794 (eq_attr "alternative" "6")
2796 [(ne (symbol_ref "optimize_size")
2798 (const_string "V4SF")
2799 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2801 (const_string "V2DF")
2803 (const_string "DF"))
2804 /* For architectures resolving dependencies on register
2805 parts we may avoid extra work to zero out upper part
2807 (eq_attr "alternative" "7")
2809 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2811 (const_string "V1DF")
2812 (const_string "DF"))
2814 (const_string "DF")))])
2816 (define_insn "*movdf_integer_rex64"
2817 [(set (match_operand:DF 0 "nonimmediate_operand"
2818 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2819 (match_operand:DF 1 "general_operand"
2820 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2821 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2822 && (reload_in_progress || reload_completed
2823 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2824 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2825 && standard_80387_constant_p (operands[1]))
2826 || GET_CODE (operands[1]) != CONST_DOUBLE
2827 || memory_operand (operands[0], DFmode))"
2829 switch (which_alternative)
2833 return output_387_reg_move (insn, operands);
2836 return standard_80387_constant_opcode (operands[1]);
2843 switch (get_attr_mode (insn))
2846 return "xorps\t%0, %0";
2848 return "xorpd\t%0, %0";
2850 return "pxor\t%0, %0";
2857 switch (get_attr_mode (insn))
2860 return "movaps\t{%1, %0|%0, %1}";
2862 return "movapd\t{%1, %0|%0, %1}";
2864 return "movdqa\t{%1, %0|%0, %1}";
2866 return "movq\t{%1, %0|%0, %1}";
2868 return "movsd\t{%1, %0|%0, %1}";
2870 return "movlpd\t{%1, %0|%0, %1}";
2872 return "movlps\t{%1, %0|%0, %1}";
2879 return "movd\t{%1, %0|%0, %1}";
2885 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2887 (cond [(eq_attr "alternative" "0,1,2")
2889 (eq_attr "alternative" "3,4,9,10")
2892 /* For SSE1, we have many fewer alternatives. */
2893 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2894 (cond [(eq_attr "alternative" "5,6")
2895 (const_string "V4SF")
2897 (const_string "V2SF"))
2899 /* xorps is one byte shorter. */
2900 (eq_attr "alternative" "5")
2901 (cond [(ne (symbol_ref "optimize_size")
2903 (const_string "V4SF")
2904 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2908 (const_string "V2DF"))
2910 /* For architectures resolving dependencies on
2911 whole SSE registers use APD move to break dependency
2912 chains, otherwise use short move to avoid extra work.
2914 movaps encodes one byte shorter. */
2915 (eq_attr "alternative" "6")
2917 [(ne (symbol_ref "optimize_size")
2919 (const_string "V4SF")
2920 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2922 (const_string "V2DF")
2924 (const_string "DF"))
2925 /* For architectures resolving dependencies on register
2926 parts we may avoid extra work to zero out upper part
2928 (eq_attr "alternative" "7")
2930 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2932 (const_string "V1DF")
2933 (const_string "DF"))
2935 (const_string "DF")))])
2937 (define_insn "*movdf_integer"
2938 [(set (match_operand:DF 0 "nonimmediate_operand"
2939 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2940 (match_operand:DF 1 "general_operand"
2941 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2942 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2943 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2944 && (reload_in_progress || reload_completed
2945 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2946 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2947 && standard_80387_constant_p (operands[1]))
2948 || GET_CODE (operands[1]) != CONST_DOUBLE
2949 || memory_operand (operands[0], DFmode))"
2951 switch (which_alternative)
2955 return output_387_reg_move (insn, operands);
2958 return standard_80387_constant_opcode (operands[1]);
2965 switch (get_attr_mode (insn))
2968 return "xorps\t%0, %0";
2970 return "xorpd\t%0, %0";
2972 return "pxor\t%0, %0";
2979 switch (get_attr_mode (insn))
2982 return "movaps\t{%1, %0|%0, %1}";
2984 return "movapd\t{%1, %0|%0, %1}";
2986 return "movdqa\t{%1, %0|%0, %1}";
2988 return "movq\t{%1, %0|%0, %1}";
2990 return "movsd\t{%1, %0|%0, %1}";
2992 return "movlpd\t{%1, %0|%0, %1}";
2994 return "movlps\t{%1, %0|%0, %1}";
3003 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3005 (cond [(eq_attr "alternative" "0,1,2")
3007 (eq_attr "alternative" "3,4")
3010 /* For SSE1, we have many fewer alternatives. */
3011 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3012 (cond [(eq_attr "alternative" "5,6")
3013 (const_string "V4SF")
3015 (const_string "V2SF"))
3017 /* xorps is one byte shorter. */
3018 (eq_attr "alternative" "5")
3019 (cond [(ne (symbol_ref "optimize_size")
3021 (const_string "V4SF")
3022 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3026 (const_string "V2DF"))
3028 /* For architectures resolving dependencies on
3029 whole SSE registers use APD move to break dependency
3030 chains, otherwise use short move to avoid extra work.
3032 movaps encodes one byte shorter. */
3033 (eq_attr "alternative" "6")
3035 [(ne (symbol_ref "optimize_size")
3037 (const_string "V4SF")
3038 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3040 (const_string "V2DF")
3042 (const_string "DF"))
3043 /* For architectures resolving dependencies on register
3044 parts we may avoid extra work to zero out upper part
3046 (eq_attr "alternative" "7")
3048 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3050 (const_string "V1DF")
3051 (const_string "DF"))
3053 (const_string "DF")))])
3056 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3057 (match_operand:DF 1 "general_operand" ""))]
3059 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3060 && ! (ANY_FP_REG_P (operands[0]) ||
3061 (GET_CODE (operands[0]) == SUBREG
3062 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3063 && ! (ANY_FP_REG_P (operands[1]) ||
3064 (GET_CODE (operands[1]) == SUBREG
3065 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3067 "ix86_split_long_move (operands); DONE;")
3069 (define_insn "*swapdf"
3070 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3071 (match_operand:DF 1 "fp_register_operand" "+f"))
3074 "reload_completed || TARGET_80387"
3076 if (STACK_TOP_P (operands[0]))
3081 [(set_attr "type" "fxch")
3082 (set_attr "mode" "DF")])
3084 (define_expand "movxf"
3085 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3086 (match_operand:XF 1 "general_operand" ""))]
3088 "ix86_expand_move (XFmode, operands); DONE;")
3090 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3091 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3092 ;; Pushing using integer instructions is longer except for constants
3093 ;; and direct memory references.
3094 ;; (assuming that any given constant is pushed only once, but this ought to be
3095 ;; handled elsewhere).
3097 (define_insn "*pushxf_nointeger"
3098 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3099 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3102 /* This insn should be already split before reg-stack. */
3105 [(set_attr "type" "multi")
3106 (set_attr "unit" "i387,*,*")
3107 (set_attr "mode" "XF,SI,SI")])
3109 (define_insn "*pushxf_integer"
3110 [(set (match_operand:XF 0 "push_operand" "=<,<")
3111 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3114 /* This insn should be already split before reg-stack. */
3117 [(set_attr "type" "multi")
3118 (set_attr "unit" "i387,*")
3119 (set_attr "mode" "XF,SI")])
3122 [(set (match_operand 0 "push_operand" "")
3123 (match_operand 1 "general_operand" ""))]
3125 && (GET_MODE (operands[0]) == XFmode
3126 || GET_MODE (operands[0]) == DFmode)
3127 && !ANY_FP_REG_P (operands[1])"
3129 "ix86_split_long_move (operands); DONE;")
3132 [(set (match_operand:XF 0 "push_operand" "")
3133 (match_operand:XF 1 "any_fp_register_operand" ""))]
3135 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3136 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3137 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3140 [(set (match_operand:XF 0 "push_operand" "")
3141 (match_operand:XF 1 "any_fp_register_operand" ""))]
3143 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3144 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3145 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3147 ;; Do not use integer registers when optimizing for size
3148 (define_insn "*movxf_nointeger"
3149 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3150 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3152 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3153 && (reload_in_progress || reload_completed
3154 || (optimize_size && standard_80387_constant_p (operands[1]))
3155 || GET_CODE (operands[1]) != CONST_DOUBLE
3156 || memory_operand (operands[0], XFmode))"
3158 switch (which_alternative)
3162 return output_387_reg_move (insn, operands);
3165 return standard_80387_constant_opcode (operands[1]);
3173 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3174 (set_attr "mode" "XF,XF,XF,SI,SI")])
3176 (define_insn "*movxf_integer"
3177 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3178 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3180 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3181 && (reload_in_progress || reload_completed
3182 || (optimize_size && standard_80387_constant_p (operands[1]))
3183 || GET_CODE (operands[1]) != CONST_DOUBLE
3184 || memory_operand (operands[0], XFmode))"
3186 switch (which_alternative)
3190 return output_387_reg_move (insn, operands);
3193 return standard_80387_constant_opcode (operands[1]);
3202 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3203 (set_attr "mode" "XF,XF,XF,SI,SI")])
3205 (define_expand "movtf"
3206 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3207 (match_operand:TF 1 "nonimmediate_operand" ""))]
3210 ix86_expand_move (TFmode, operands);
3214 (define_insn "*movtf_internal"
3215 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3216 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3218 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3220 switch (which_alternative)
3224 if (get_attr_mode (insn) == MODE_V4SF)
3225 return "movaps\t{%1, %0|%0, %1}";
3227 return "movdqa\t{%1, %0|%0, %1}";
3229 if (get_attr_mode (insn) == MODE_V4SF)
3230 return "xorps\t%0, %0";
3232 return "pxor\t%0, %0";
3240 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3242 (cond [(eq_attr "alternative" "0,2")
3244 (ne (symbol_ref "optimize_size")
3246 (const_string "V4SF")
3247 (const_string "TI"))
3248 (eq_attr "alternative" "1")
3250 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3252 (ne (symbol_ref "optimize_size")
3254 (const_string "V4SF")
3255 (const_string "TI"))]
3256 (const_string "DI")))])
3259 [(set (match_operand 0 "nonimmediate_operand" "")
3260 (match_operand 1 "general_operand" ""))]
3262 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3263 && GET_MODE (operands[0]) == XFmode
3264 && ! (ANY_FP_REG_P (operands[0]) ||
3265 (GET_CODE (operands[0]) == SUBREG
3266 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3267 && ! (ANY_FP_REG_P (operands[1]) ||
3268 (GET_CODE (operands[1]) == SUBREG
3269 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3271 "ix86_split_long_move (operands); DONE;")
3274 [(set (match_operand 0 "register_operand" "")
3275 (match_operand 1 "memory_operand" ""))]
3277 && MEM_P (operands[1])
3278 && (GET_MODE (operands[0]) == TFmode
3279 || GET_MODE (operands[0]) == XFmode
3280 || GET_MODE (operands[0]) == SFmode
3281 || GET_MODE (operands[0]) == DFmode)
3282 && (operands[2] = find_constant_src (insn))"
3283 [(set (match_dup 0) (match_dup 2))]
3285 rtx c = operands[2];
3286 rtx r = operands[0];
3288 if (GET_CODE (r) == SUBREG)
3293 if (!standard_sse_constant_p (c))
3296 else if (FP_REG_P (r))
3298 if (!standard_80387_constant_p (c))
3301 else if (MMX_REG_P (r))
3306 [(set (match_operand 0 "register_operand" "")
3307 (float_extend (match_operand 1 "memory_operand" "")))]
3309 && MEM_P (operands[1])
3310 && (GET_MODE (operands[0]) == TFmode
3311 || GET_MODE (operands[0]) == XFmode
3312 || GET_MODE (operands[0]) == SFmode
3313 || GET_MODE (operands[0]) == DFmode)
3314 && (operands[2] = find_constant_src (insn))"
3315 [(set (match_dup 0) (match_dup 2))]
3317 rtx c = operands[2];
3318 rtx r = operands[0];
3320 if (GET_CODE (r) == SUBREG)
3325 if (!standard_sse_constant_p (c))
3328 else if (FP_REG_P (r))
3330 if (!standard_80387_constant_p (c))
3333 else if (MMX_REG_P (r))
3337 (define_insn "swapxf"
3338 [(set (match_operand:XF 0 "register_operand" "+f")
3339 (match_operand:XF 1 "register_operand" "+f"))
3344 if (STACK_TOP_P (operands[0]))
3349 [(set_attr "type" "fxch")
3350 (set_attr "mode" "XF")])
3352 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3354 [(set (match_operand:X87MODEF 0 "register_operand" "")
3355 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3356 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3357 && (standard_80387_constant_p (operands[1]) == 8
3358 || standard_80387_constant_p (operands[1]) == 9)"
3359 [(set (match_dup 0)(match_dup 1))
3361 (neg:X87MODEF (match_dup 0)))]
3365 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3366 if (real_isnegzero (&r))
3367 operands[1] = CONST0_RTX (<MODE>mode);
3369 operands[1] = CONST1_RTX (<MODE>mode);
3373 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3374 (match_operand:TF 1 "general_operand" ""))]
3376 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3378 "ix86_split_long_move (operands); DONE;")
3380 ;; Zero extension instructions
3382 (define_expand "zero_extendhisi2"
3383 [(set (match_operand:SI 0 "register_operand" "")
3384 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3387 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3389 operands[1] = force_reg (HImode, operands[1]);
3390 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3395 (define_insn "zero_extendhisi2_and"
3396 [(set (match_operand:SI 0 "register_operand" "=r")
3397 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3398 (clobber (reg:CC FLAGS_REG))]
3399 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3401 [(set_attr "type" "alu1")
3402 (set_attr "mode" "SI")])
3405 [(set (match_operand:SI 0 "register_operand" "")
3406 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3407 (clobber (reg:CC FLAGS_REG))]
3408 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3409 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3410 (clobber (reg:CC FLAGS_REG))])]
3413 (define_insn "*zero_extendhisi2_movzwl"
3414 [(set (match_operand:SI 0 "register_operand" "=r")
3415 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3416 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3417 "movz{wl|x}\t{%1, %0|%0, %1}"
3418 [(set_attr "type" "imovx")
3419 (set_attr "mode" "SI")])
3421 (define_expand "zero_extendqihi2"
3423 [(set (match_operand:HI 0 "register_operand" "")
3424 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3425 (clobber (reg:CC FLAGS_REG))])]
3429 (define_insn "*zero_extendqihi2_and"
3430 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3431 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3432 (clobber (reg:CC FLAGS_REG))]
3433 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3435 [(set_attr "type" "alu1")
3436 (set_attr "mode" "HI")])
3438 (define_insn "*zero_extendqihi2_movzbw_and"
3439 [(set (match_operand:HI 0 "register_operand" "=r,r")
3440 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3441 (clobber (reg:CC FLAGS_REG))]
3442 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3444 [(set_attr "type" "imovx,alu1")
3445 (set_attr "mode" "HI")])
3447 ; zero extend to SImode here to avoid partial register stalls
3448 (define_insn "*zero_extendqihi2_movzbl"
3449 [(set (match_operand:HI 0 "register_operand" "=r")
3450 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3451 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3452 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3453 [(set_attr "type" "imovx")
3454 (set_attr "mode" "SI")])
3456 ;; For the movzbw case strip only the clobber
3458 [(set (match_operand:HI 0 "register_operand" "")
3459 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3460 (clobber (reg:CC FLAGS_REG))]
3462 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3463 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3464 [(set (match_operand:HI 0 "register_operand" "")
3465 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3467 ;; When source and destination does not overlap, clear destination
3468 ;; first and then do the movb
3470 [(set (match_operand:HI 0 "register_operand" "")
3471 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3472 (clobber (reg:CC FLAGS_REG))]
3474 && ANY_QI_REG_P (operands[0])
3475 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3476 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3477 [(set (match_dup 0) (const_int 0))
3478 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3479 "operands[2] = gen_lowpart (QImode, operands[0]);")
3481 ;; Rest is handled by single and.
3483 [(set (match_operand:HI 0 "register_operand" "")
3484 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3485 (clobber (reg:CC FLAGS_REG))]
3487 && true_regnum (operands[0]) == true_regnum (operands[1])"
3488 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3489 (clobber (reg:CC FLAGS_REG))])]
3492 (define_expand "zero_extendqisi2"
3494 [(set (match_operand:SI 0 "register_operand" "")
3495 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3496 (clobber (reg:CC FLAGS_REG))])]
3500 (define_insn "*zero_extendqisi2_and"
3501 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3502 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3503 (clobber (reg:CC FLAGS_REG))]
3504 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3506 [(set_attr "type" "alu1")
3507 (set_attr "mode" "SI")])
3509 (define_insn "*zero_extendqisi2_movzbw_and"
3510 [(set (match_operand:SI 0 "register_operand" "=r,r")
3511 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3512 (clobber (reg:CC FLAGS_REG))]
3513 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3515 [(set_attr "type" "imovx,alu1")
3516 (set_attr "mode" "SI")])
3518 (define_insn "*zero_extendqisi2_movzbw"
3519 [(set (match_operand:SI 0 "register_operand" "=r")
3520 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3521 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3522 "movz{bl|x}\t{%1, %0|%0, %1}"
3523 [(set_attr "type" "imovx")
3524 (set_attr "mode" "SI")])
3526 ;; For the movzbl case strip only the clobber
3528 [(set (match_operand:SI 0 "register_operand" "")
3529 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3530 (clobber (reg:CC FLAGS_REG))]
3532 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3533 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3535 (zero_extend:SI (match_dup 1)))])
3537 ;; When source and destination does not overlap, clear destination
3538 ;; first and then do the movb
3540 [(set (match_operand:SI 0 "register_operand" "")
3541 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3542 (clobber (reg:CC FLAGS_REG))]
3544 && ANY_QI_REG_P (operands[0])
3545 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3546 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3547 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3548 [(set (match_dup 0) (const_int 0))
3549 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3550 "operands[2] = gen_lowpart (QImode, operands[0]);")
3552 ;; Rest is handled by single and.
3554 [(set (match_operand:SI 0 "register_operand" "")
3555 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3556 (clobber (reg:CC FLAGS_REG))]
3558 && true_regnum (operands[0]) == true_regnum (operands[1])"
3559 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3560 (clobber (reg:CC FLAGS_REG))])]
3563 ;; %%% Kill me once multi-word ops are sane.
3564 (define_expand "zero_extendsidi2"
3565 [(set (match_operand:DI 0 "register_operand" "")
3566 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3571 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3576 (define_insn "zero_extendsidi2_32"
3577 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3579 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3580 (clobber (reg:CC FLAGS_REG))]
3586 movd\t{%1, %0|%0, %1}
3587 movd\t{%1, %0|%0, %1}
3588 movd\t{%1, %0|%0, %1}
3589 movd\t{%1, %0|%0, %1}"
3590 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3591 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3593 (define_insn "zero_extendsidi2_rex64"
3594 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3596 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3599 mov\t{%k1, %k0|%k0, %k1}
3601 movd\t{%1, %0|%0, %1}
3602 movd\t{%1, %0|%0, %1}
3603 movd\t{%1, %0|%0, %1}
3604 movd\t{%1, %0|%0, %1}"
3605 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3606 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3609 [(set (match_operand:DI 0 "memory_operand" "")
3610 (zero_extend:DI (match_dup 0)))]
3612 [(set (match_dup 4) (const_int 0))]
3613 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3616 [(set (match_operand:DI 0 "register_operand" "")
3617 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3618 (clobber (reg:CC FLAGS_REG))]
3619 "!TARGET_64BIT && reload_completed
3620 && true_regnum (operands[0]) == true_regnum (operands[1])"
3621 [(set (match_dup 4) (const_int 0))]
3622 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3625 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3626 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3627 (clobber (reg:CC FLAGS_REG))]
3628 "!TARGET_64BIT && reload_completed
3629 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3630 [(set (match_dup 3) (match_dup 1))
3631 (set (match_dup 4) (const_int 0))]
3632 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3634 (define_insn "zero_extendhidi2"
3635 [(set (match_operand:DI 0 "register_operand" "=r")
3636 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3638 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3639 [(set_attr "type" "imovx")
3640 (set_attr "mode" "DI")])
3642 (define_insn "zero_extendqidi2"
3643 [(set (match_operand:DI 0 "register_operand" "=r")
3644 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3646 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3647 [(set_attr "type" "imovx")
3648 (set_attr "mode" "DI")])
3650 ;; Sign extension instructions
3652 (define_expand "extendsidi2"
3653 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3654 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3655 (clobber (reg:CC FLAGS_REG))
3656 (clobber (match_scratch:SI 2 ""))])]
3661 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3666 (define_insn "*extendsidi2_1"
3667 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3668 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3669 (clobber (reg:CC FLAGS_REG))
3670 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3674 (define_insn "extendsidi2_rex64"
3675 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3676 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3680 movs{lq|x}\t{%1,%0|%0, %1}"
3681 [(set_attr "type" "imovx")
3682 (set_attr "mode" "DI")
3683 (set_attr "prefix_0f" "0")
3684 (set_attr "modrm" "0,1")])
3686 (define_insn "extendhidi2"
3687 [(set (match_operand:DI 0 "register_operand" "=r")
3688 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3690 "movs{wq|x}\t{%1,%0|%0, %1}"
3691 [(set_attr "type" "imovx")
3692 (set_attr "mode" "DI")])
3694 (define_insn "extendqidi2"
3695 [(set (match_operand:DI 0 "register_operand" "=r")
3696 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3698 "movs{bq|x}\t{%1,%0|%0, %1}"
3699 [(set_attr "type" "imovx")
3700 (set_attr "mode" "DI")])
3702 ;; Extend to memory case when source register does die.
3704 [(set (match_operand:DI 0 "memory_operand" "")
3705 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3706 (clobber (reg:CC FLAGS_REG))
3707 (clobber (match_operand:SI 2 "register_operand" ""))]
3709 && dead_or_set_p (insn, operands[1])
3710 && !reg_mentioned_p (operands[1], operands[0]))"
3711 [(set (match_dup 3) (match_dup 1))
3712 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3713 (clobber (reg:CC FLAGS_REG))])
3714 (set (match_dup 4) (match_dup 1))]
3715 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3717 ;; Extend to memory case when source register does not die.
3719 [(set (match_operand:DI 0 "memory_operand" "")
3720 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3721 (clobber (reg:CC FLAGS_REG))
3722 (clobber (match_operand:SI 2 "register_operand" ""))]
3726 split_di (&operands[0], 1, &operands[3], &operands[4]);
3728 emit_move_insn (operands[3], operands[1]);
3730 /* Generate a cltd if possible and doing so it profitable. */
3731 if ((optimize_size || TARGET_USE_CLTD)
3732 && true_regnum (operands[1]) == AX_REG
3733 && true_regnum (operands[2]) == DX_REG)
3735 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3739 emit_move_insn (operands[2], operands[1]);
3740 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3742 emit_move_insn (operands[4], operands[2]);
3746 ;; Extend to register case. Optimize case where source and destination
3747 ;; registers match and cases where we can use cltd.
3749 [(set (match_operand:DI 0 "register_operand" "")
3750 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3751 (clobber (reg:CC FLAGS_REG))
3752 (clobber (match_scratch:SI 2 ""))]
3756 split_di (&operands[0], 1, &operands[3], &operands[4]);
3758 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3759 emit_move_insn (operands[3], operands[1]);
3761 /* Generate a cltd if possible and doing so it profitable. */
3762 if ((optimize_size || TARGET_USE_CLTD)
3763 && true_regnum (operands[3]) == AX_REG)
3765 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3769 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3770 emit_move_insn (operands[4], operands[1]);
3772 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3776 (define_insn "extendhisi2"
3777 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3778 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3781 switch (get_attr_prefix_0f (insn))
3784 return "{cwtl|cwde}";
3786 return "movs{wl|x}\t{%1,%0|%0, %1}";
3789 [(set_attr "type" "imovx")
3790 (set_attr "mode" "SI")
3791 (set (attr "prefix_0f")
3792 ;; movsx is short decodable while cwtl is vector decoded.
3793 (if_then_else (and (eq_attr "cpu" "!k6")
3794 (eq_attr "alternative" "0"))
3796 (const_string "1")))
3798 (if_then_else (eq_attr "prefix_0f" "0")
3800 (const_string "1")))])
3802 (define_insn "*extendhisi2_zext"
3803 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3805 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3808 switch (get_attr_prefix_0f (insn))
3811 return "{cwtl|cwde}";
3813 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3816 [(set_attr "type" "imovx")
3817 (set_attr "mode" "SI")
3818 (set (attr "prefix_0f")
3819 ;; movsx is short decodable while cwtl is vector decoded.
3820 (if_then_else (and (eq_attr "cpu" "!k6")
3821 (eq_attr "alternative" "0"))
3823 (const_string "1")))
3825 (if_then_else (eq_attr "prefix_0f" "0")
3827 (const_string "1")))])
3829 (define_insn "extendqihi2"
3830 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3831 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3834 switch (get_attr_prefix_0f (insn))
3837 return "{cbtw|cbw}";
3839 return "movs{bw|x}\t{%1,%0|%0, %1}";
3842 [(set_attr "type" "imovx")
3843 (set_attr "mode" "HI")
3844 (set (attr "prefix_0f")
3845 ;; movsx is short decodable while cwtl is vector decoded.
3846 (if_then_else (and (eq_attr "cpu" "!k6")
3847 (eq_attr "alternative" "0"))
3849 (const_string "1")))
3851 (if_then_else (eq_attr "prefix_0f" "0")
3853 (const_string "1")))])
3855 (define_insn "extendqisi2"
3856 [(set (match_operand:SI 0 "register_operand" "=r")
3857 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3859 "movs{bl|x}\t{%1,%0|%0, %1}"
3860 [(set_attr "type" "imovx")
3861 (set_attr "mode" "SI")])
3863 (define_insn "*extendqisi2_zext"
3864 [(set (match_operand:DI 0 "register_operand" "=r")
3866 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3868 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3869 [(set_attr "type" "imovx")
3870 (set_attr "mode" "SI")])
3872 ;; Conversions between float and double.
3874 ;; These are all no-ops in the model used for the 80387. So just
3877 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3878 (define_insn "*dummy_extendsfdf2"
3879 [(set (match_operand:DF 0 "push_operand" "=<")
3880 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3885 [(set (match_operand:DF 0 "push_operand" "")
3886 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3888 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3889 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3892 [(set (match_operand:DF 0 "push_operand" "")
3893 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3895 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3896 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3898 (define_insn "*dummy_extendsfxf2"
3899 [(set (match_operand:XF 0 "push_operand" "=<")
3900 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3905 [(set (match_operand:XF 0 "push_operand" "")
3906 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3908 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3909 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3910 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3913 [(set (match_operand:XF 0 "push_operand" "")
3914 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3916 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3917 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3918 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3921 [(set (match_operand:XF 0 "push_operand" "")
3922 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3924 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3925 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3926 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3929 [(set (match_operand:XF 0 "push_operand" "")
3930 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3932 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3933 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3934 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3936 (define_expand "extendsfdf2"
3937 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3938 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3939 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3941 /* ??? Needed for compress_float_constant since all fp constants
3942 are LEGITIMATE_CONSTANT_P. */
3943 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3945 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3946 && standard_80387_constant_p (operands[1]) > 0)
3948 operands[1] = simplify_const_unary_operation
3949 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3950 emit_move_insn_1 (operands[0], operands[1]);
3953 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3957 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3959 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3961 We do the conversion post reload to avoid producing of 128bit spills
3962 that might lead to ICE on 32bit target. The sequence unlikely combine
3965 [(set (match_operand:DF 0 "register_operand" "")
3967 (match_operand:SF 1 "nonimmediate_operand" "")))]
3968 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3969 && reload_completed && SSE_REG_P (operands[0])"
3974 (parallel [(const_int 0) (const_int 1)]))))]
3976 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3977 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3978 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3979 Try to avoid move when unpacking can be done in source. */
3980 if (REG_P (operands[1]))
3982 /* If it is unsafe to overwrite upper half of source, we need
3983 to move to destination and unpack there. */
3984 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3985 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3986 && true_regnum (operands[0]) != true_regnum (operands[1]))
3988 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3989 emit_move_insn (tmp, operands[1]);
3992 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3993 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3996 emit_insn (gen_vec_setv4sf_0 (operands[3],
3997 CONST0_RTX (V4SFmode), operands[1]));
4000 (define_insn "*extendsfdf2_mixed"
4001 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4003 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4004 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4006 switch (which_alternative)
4010 return output_387_reg_move (insn, operands);
4013 return "cvtss2sd\t{%1, %0|%0, %1}";
4019 [(set_attr "type" "fmov,fmov,ssecvt")
4020 (set_attr "mode" "SF,XF,DF")])
4022 (define_insn "*extendsfdf2_sse"
4023 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4024 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4025 "TARGET_SSE2 && TARGET_SSE_MATH"
4026 "cvtss2sd\t{%1, %0|%0, %1}"
4027 [(set_attr "type" "ssecvt")
4028 (set_attr "mode" "DF")])
4030 (define_insn "*extendsfdf2_i387"
4031 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4032 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4034 "* return output_387_reg_move (insn, operands);"
4035 [(set_attr "type" "fmov")
4036 (set_attr "mode" "SF,XF")])
4038 (define_expand "extend<mode>xf2"
4039 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4040 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4043 /* ??? Needed for compress_float_constant since all fp constants
4044 are LEGITIMATE_CONSTANT_P. */
4045 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4047 if (standard_80387_constant_p (operands[1]) > 0)
4049 operands[1] = simplify_const_unary_operation
4050 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4051 emit_move_insn_1 (operands[0], operands[1]);
4054 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4058 (define_insn "*extend<mode>xf2_i387"
4059 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4061 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4063 "* return output_387_reg_move (insn, operands);"
4064 [(set_attr "type" "fmov")
4065 (set_attr "mode" "<MODE>,XF")])
4067 ;; %%% This seems bad bad news.
4068 ;; This cannot output into an f-reg because there is no way to be sure
4069 ;; of truncating in that case. Otherwise this is just like a simple move
4070 ;; insn. So we pretend we can output to a reg in order to get better
4071 ;; register preferencing, but we really use a stack slot.
4073 ;; Conversion from DFmode to SFmode.
4075 (define_expand "truncdfsf2"
4076 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4078 (match_operand:DF 1 "nonimmediate_operand" "")))]
4079 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4081 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4083 else if (flag_unsafe_math_optimizations)
4087 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4088 rtx temp = assign_386_stack_local (SFmode, slot);
4089 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4094 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4096 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4098 We do the conversion post reload to avoid producing of 128bit spills
4099 that might lead to ICE on 32bit target. The sequence unlikely combine
4102 [(set (match_operand:SF 0 "register_operand" "")
4104 (match_operand:DF 1 "nonimmediate_operand" "")))]
4105 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4106 && reload_completed && SSE_REG_P (operands[0])"
4109 (float_truncate:V2SF
4113 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4114 operands[3] = CONST0_RTX (V2SFmode);
4115 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4116 /* Use movsd for loading from memory, unpcklpd for registers.
4117 Try to avoid move when unpacking can be done in source, or SSE3
4118 movddup is available. */
4119 if (REG_P (operands[1]))
4122 && true_regnum (operands[0]) != true_regnum (operands[1])
4123 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4124 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4126 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4127 emit_move_insn (tmp, operands[1]);
4130 else if (!TARGET_SSE3)
4131 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4132 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4135 emit_insn (gen_sse2_loadlpd (operands[4],
4136 CONST0_RTX (V2DFmode), operands[1]));
4139 (define_expand "truncdfsf2_with_temp"
4140 [(parallel [(set (match_operand:SF 0 "" "")
4141 (float_truncate:SF (match_operand:DF 1 "" "")))
4142 (clobber (match_operand:SF 2 "" ""))])]
4145 (define_insn "*truncdfsf_fast_mixed"
4146 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4148 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4149 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4151 switch (which_alternative)
4155 return output_387_reg_move (insn, operands);
4157 return "cvtsd2ss\t{%1, %0|%0, %1}";
4162 [(set_attr "type" "fmov,fmov,ssecvt")
4163 (set_attr "mode" "SF")])
4165 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4166 ;; because nothing we do here is unsafe.
4167 (define_insn "*truncdfsf_fast_sse"
4168 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4170 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4171 "TARGET_SSE2 && TARGET_SSE_MATH"
4172 "cvtsd2ss\t{%1, %0|%0, %1}"
4173 [(set_attr "type" "ssecvt")
4174 (set_attr "mode" "SF")])
4176 (define_insn "*truncdfsf_fast_i387"
4177 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4179 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4180 "TARGET_80387 && flag_unsafe_math_optimizations"
4181 "* return output_387_reg_move (insn, operands);"
4182 [(set_attr "type" "fmov")
4183 (set_attr "mode" "SF")])
4185 (define_insn "*truncdfsf_mixed"
4186 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4188 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4189 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4190 "TARGET_MIX_SSE_I387"
4192 switch (which_alternative)
4195 return output_387_reg_move (insn, operands);
4200 return "cvtsd2ss\t{%1, %0|%0, %1}";
4205 [(set_attr "type" "fmov,multi,ssecvt")
4206 (set_attr "unit" "*,i387,*")
4207 (set_attr "mode" "SF")])
4209 (define_insn "*truncdfsf_i387"
4210 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4212 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4213 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4216 switch (which_alternative)
4219 return output_387_reg_move (insn, operands);
4227 [(set_attr "type" "fmov,multi")
4228 (set_attr "unit" "*,i387")
4229 (set_attr "mode" "SF")])
4231 (define_insn "*truncdfsf2_i387_1"
4232 [(set (match_operand:SF 0 "memory_operand" "=m")
4234 (match_operand:DF 1 "register_operand" "f")))]
4236 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4237 && !TARGET_MIX_SSE_I387"
4238 "* return output_387_reg_move (insn, operands);"
4239 [(set_attr "type" "fmov")
4240 (set_attr "mode" "SF")])
4243 [(set (match_operand:SF 0 "register_operand" "")
4245 (match_operand:DF 1 "fp_register_operand" "")))
4246 (clobber (match_operand 2 "" ""))]
4248 [(set (match_dup 2) (match_dup 1))
4249 (set (match_dup 0) (match_dup 2))]
4251 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4254 ;; Conversion from XFmode to {SF,DF}mode
4256 (define_expand "truncxf<mode>2"
4257 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4258 (float_truncate:MODEF
4259 (match_operand:XF 1 "register_operand" "")))
4260 (clobber (match_dup 2))])]
4263 if (flag_unsafe_math_optimizations)
4265 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4266 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4267 if (reg != operands[0])
4268 emit_move_insn (operands[0], reg);
4273 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4274 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4278 (define_insn "*truncxfsf2_mixed"
4279 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4281 (match_operand:XF 1 "register_operand" "f,f")))
4282 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4285 gcc_assert (!which_alternative);
4286 return output_387_reg_move (insn, operands);
4288 [(set_attr "type" "fmov,multi")
4289 (set_attr "unit" "*,i387")
4290 (set_attr "mode" "SF")])
4292 (define_insn "*truncxfdf2_mixed"
4293 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4295 (match_operand:XF 1 "register_operand" "f,f")))
4296 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4299 gcc_assert (!which_alternative);
4300 return output_387_reg_move (insn, operands);
4302 [(set_attr "type" "fmov,multi")
4303 (set_attr "unit" "*,i387")
4304 (set_attr "mode" "DF")])
4306 (define_insn "truncxf<mode>2_i387_noop"
4307 [(set (match_operand:MODEF 0 "register_operand" "=f")
4308 (float_truncate:MODEF
4309 (match_operand:XF 1 "register_operand" "f")))]
4310 "TARGET_80387 && flag_unsafe_math_optimizations"
4311 "* return output_387_reg_move (insn, operands);"
4312 [(set_attr "type" "fmov")
4313 (set_attr "mode" "<MODE>")])
4315 (define_insn "*truncxf<mode>2_i387"
4316 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4317 (float_truncate:MODEF
4318 (match_operand:XF 1 "register_operand" "f")))]
4320 "* return output_387_reg_move (insn, operands);"
4321 [(set_attr "type" "fmov")
4322 (set_attr "mode" "<MODE>")])
4325 [(set (match_operand:MODEF 0 "register_operand" "")
4326 (float_truncate:MODEF
4327 (match_operand:XF 1 "register_operand" "")))
4328 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4329 "TARGET_80387 && reload_completed"
4330 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4331 (set (match_dup 0) (match_dup 2))]
4335 [(set (match_operand:MODEF 0 "memory_operand" "")
4336 (float_truncate:MODEF
4337 (match_operand:XF 1 "register_operand" "")))
4338 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4340 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4343 ;; Signed conversion to DImode.
4345 (define_expand "fix_truncxfdi2"
4346 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4347 (fix:DI (match_operand:XF 1 "register_operand" "")))
4348 (clobber (reg:CC FLAGS_REG))])]
4353 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4358 (define_expand "fix_trunc<mode>di2"
4359 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4360 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4361 (clobber (reg:CC FLAGS_REG))])]
4362 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4365 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4367 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4370 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4372 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4373 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4374 if (out != operands[0])
4375 emit_move_insn (operands[0], out);
4380 ;; Signed conversion to SImode.
4382 (define_expand "fix_truncxfsi2"
4383 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4384 (fix:SI (match_operand:XF 1 "register_operand" "")))
4385 (clobber (reg:CC FLAGS_REG))])]
4390 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4395 (define_expand "fix_trunc<mode>si2"
4396 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4397 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4398 (clobber (reg:CC FLAGS_REG))])]
4399 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4402 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4404 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4407 if (SSE_FLOAT_MODE_P (<MODE>mode))
4409 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4410 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4411 if (out != operands[0])
4412 emit_move_insn (operands[0], out);
4417 ;; Signed conversion to HImode.
4419 (define_expand "fix_trunc<mode>hi2"
4420 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4421 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4422 (clobber (reg:CC FLAGS_REG))])]
4424 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4428 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4433 ;; Unsigned conversion to SImode.
4435 (define_expand "fixuns_trunc<mode>si2"
4437 [(set (match_operand:SI 0 "register_operand" "")
4439 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4441 (clobber (match_scratch:<ssevecmode> 3 ""))
4442 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4443 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4445 enum machine_mode mode = <MODE>mode;
4446 enum machine_mode vecmode = <ssevecmode>mode;
4447 REAL_VALUE_TYPE TWO31r;
4450 real_ldexp (&TWO31r, &dconst1, 31);
4451 two31 = const_double_from_real_value (TWO31r, mode);
4452 two31 = ix86_build_const_vector (mode, true, two31);
4453 operands[2] = force_reg (vecmode, two31);
4456 (define_insn_and_split "*fixuns_trunc<mode>_1"
4457 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4459 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4460 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4461 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4462 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4463 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4465 "&& reload_completed"
4468 ix86_split_convert_uns_si_sse (operands);
4472 ;; Unsigned conversion to HImode.
4473 ;; Without these patterns, we'll try the unsigned SI conversion which
4474 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4476 (define_expand "fixuns_trunc<mode>hi2"
4478 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4479 (set (match_operand:HI 0 "nonimmediate_operand" "")
4480 (subreg:HI (match_dup 2) 0))]
4481 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4482 "operands[2] = gen_reg_rtx (SImode);")
4484 ;; When SSE is available, it is always faster to use it!
4485 (define_insn "fix_trunc<mode>di_sse"
4486 [(set (match_operand:DI 0 "register_operand" "=r,r")
4487 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4488 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4489 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4490 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4491 [(set_attr "type" "sseicvt")
4492 (set_attr "mode" "<MODE>")
4493 (set_attr "athlon_decode" "double,vector")
4494 (set_attr "amdfam10_decode" "double,double")])
4496 (define_insn "fix_trunc<mode>si_sse"
4497 [(set (match_operand:SI 0 "register_operand" "=r,r")
4498 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4499 "SSE_FLOAT_MODE_P (<MODE>mode)
4500 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4501 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4502 [(set_attr "type" "sseicvt")
4503 (set_attr "mode" "<MODE>")
4504 (set_attr "athlon_decode" "double,vector")
4505 (set_attr "amdfam10_decode" "double,double")])
4507 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4509 [(set (match_operand:MODEF 0 "register_operand" "")
4510 (match_operand:MODEF 1 "memory_operand" ""))
4511 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4512 (fix:SSEMODEI24 (match_dup 0)))]
4513 "TARGET_SHORTEN_X87_SSE
4514 && peep2_reg_dead_p (2, operands[0])"
4515 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4518 ;; Avoid vector decoded forms of the instruction.
4520 [(match_scratch:DF 2 "Y2")
4521 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4522 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4523 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4524 [(set (match_dup 2) (match_dup 1))
4525 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4529 [(match_scratch:SF 2 "x")
4530 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4531 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4532 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4533 [(set (match_dup 2) (match_dup 1))
4534 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4537 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4538 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4539 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4540 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4542 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4543 && (TARGET_64BIT || <MODE>mode != DImode))
4545 && !(reload_completed || reload_in_progress)"
4550 if (memory_operand (operands[0], VOIDmode))
4551 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4554 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4555 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4561 [(set_attr "type" "fisttp")
4562 (set_attr "mode" "<MODE>")])
4564 (define_insn "fix_trunc<mode>_i387_fisttp"
4565 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4566 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4567 (clobber (match_scratch:XF 2 "=&1f"))]
4568 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4570 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4571 && (TARGET_64BIT || <MODE>mode != DImode))
4572 && TARGET_SSE_MATH)"
4573 "* return output_fix_trunc (insn, operands, 1);"
4574 [(set_attr "type" "fisttp")
4575 (set_attr "mode" "<MODE>")])
4577 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4578 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4579 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4580 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4581 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4582 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4585 && (TARGET_64BIT || <MODE>mode != DImode))
4586 && TARGET_SSE_MATH)"
4588 [(set_attr "type" "fisttp")
4589 (set_attr "mode" "<MODE>")])
4592 [(set (match_operand:X87MODEI 0 "register_operand" "")
4593 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4594 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4595 (clobber (match_scratch 3 ""))]
4597 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4598 (clobber (match_dup 3))])
4599 (set (match_dup 0) (match_dup 2))]
4603 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4604 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4605 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4606 (clobber (match_scratch 3 ""))]
4608 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4609 (clobber (match_dup 3))])]
4612 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4613 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4614 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4615 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4616 ;; function in i386.c.
4617 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4618 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4619 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4620 (clobber (reg:CC FLAGS_REG))]
4621 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4623 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4624 && (TARGET_64BIT || <MODE>mode != DImode))
4625 && !(reload_completed || reload_in_progress)"
4630 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4632 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4633 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4634 if (memory_operand (operands[0], VOIDmode))
4635 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4636 operands[2], operands[3]));
4639 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4640 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4641 operands[2], operands[3],
4646 [(set_attr "type" "fistp")
4647 (set_attr "i387_cw" "trunc")
4648 (set_attr "mode" "<MODE>")])
4650 (define_insn "fix_truncdi_i387"
4651 [(set (match_operand:DI 0 "memory_operand" "=m")
4652 (fix:DI (match_operand 1 "register_operand" "f")))
4653 (use (match_operand:HI 2 "memory_operand" "m"))
4654 (use (match_operand:HI 3 "memory_operand" "m"))
4655 (clobber (match_scratch:XF 4 "=&1f"))]
4656 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4658 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4659 "* return output_fix_trunc (insn, operands, 0);"
4660 [(set_attr "type" "fistp")
4661 (set_attr "i387_cw" "trunc")
4662 (set_attr "mode" "DI")])
4664 (define_insn "fix_truncdi_i387_with_temp"
4665 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4666 (fix:DI (match_operand 1 "register_operand" "f,f")))
4667 (use (match_operand:HI 2 "memory_operand" "m,m"))
4668 (use (match_operand:HI 3 "memory_operand" "m,m"))
4669 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4670 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4671 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4673 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4675 [(set_attr "type" "fistp")
4676 (set_attr "i387_cw" "trunc")
4677 (set_attr "mode" "DI")])
4680 [(set (match_operand:DI 0 "register_operand" "")
4681 (fix:DI (match_operand 1 "register_operand" "")))
4682 (use (match_operand:HI 2 "memory_operand" ""))
4683 (use (match_operand:HI 3 "memory_operand" ""))
4684 (clobber (match_operand:DI 4 "memory_operand" ""))
4685 (clobber (match_scratch 5 ""))]
4687 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4690 (clobber (match_dup 5))])
4691 (set (match_dup 0) (match_dup 4))]
4695 [(set (match_operand:DI 0 "memory_operand" "")
4696 (fix:DI (match_operand 1 "register_operand" "")))
4697 (use (match_operand:HI 2 "memory_operand" ""))
4698 (use (match_operand:HI 3 "memory_operand" ""))
4699 (clobber (match_operand:DI 4 "memory_operand" ""))
4700 (clobber (match_scratch 5 ""))]
4702 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4705 (clobber (match_dup 5))])]
4708 (define_insn "fix_trunc<mode>_i387"
4709 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4710 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4711 (use (match_operand:HI 2 "memory_operand" "m"))
4712 (use (match_operand:HI 3 "memory_operand" "m"))]
4713 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4715 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4716 "* return output_fix_trunc (insn, operands, 0);"
4717 [(set_attr "type" "fistp")
4718 (set_attr "i387_cw" "trunc")
4719 (set_attr "mode" "<MODE>")])
4721 (define_insn "fix_trunc<mode>_i387_with_temp"
4722 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4723 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4724 (use (match_operand:HI 2 "memory_operand" "m,m"))
4725 (use (match_operand:HI 3 "memory_operand" "m,m"))
4726 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4727 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4729 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4731 [(set_attr "type" "fistp")
4732 (set_attr "i387_cw" "trunc")
4733 (set_attr "mode" "<MODE>")])
4736 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4737 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4738 (use (match_operand:HI 2 "memory_operand" ""))
4739 (use (match_operand:HI 3 "memory_operand" ""))
4740 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4742 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4744 (use (match_dup 3))])
4745 (set (match_dup 0) (match_dup 4))]
4749 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4750 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4751 (use (match_operand:HI 2 "memory_operand" ""))
4752 (use (match_operand:HI 3 "memory_operand" ""))
4753 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4755 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4757 (use (match_dup 3))])]
4760 (define_insn "x86_fnstcw_1"
4761 [(set (match_operand:HI 0 "memory_operand" "=m")
4762 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4765 [(set_attr "length" "2")
4766 (set_attr "mode" "HI")
4767 (set_attr "unit" "i387")])
4769 (define_insn "x86_fldcw_1"
4770 [(set (reg:HI FPCR_REG)
4771 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4774 [(set_attr "length" "2")
4775 (set_attr "mode" "HI")
4776 (set_attr "unit" "i387")
4777 (set_attr "athlon_decode" "vector")
4778 (set_attr "amdfam10_decode" "vector")])
4780 ;; Conversion between fixed point and floating point.
4782 ;; Even though we only accept memory inputs, the backend _really_
4783 ;; wants to be able to do this between registers.
4785 (define_expand "floathi<mode>2"
4786 [(set (match_operand:MODEF 0 "register_operand" "")
4787 (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4788 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4790 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4793 (gen_floatsi<mode>2 (operands[0],
4794 convert_to_mode (SImode, operands[1], 0)));
4799 (define_insn "*floathi<mode>2_i387"
4800 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4802 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4805 || TARGET_MIX_SSE_I387)"
4809 [(set_attr "type" "fmov,multi")
4810 (set_attr "mode" "<MODE>")
4811 (set_attr "unit" "*,i387")
4812 (set_attr "fp_int_src" "true")])
4814 (define_expand "floatsi<mode>2"
4815 [(set (match_operand:MODEF 0 "register_operand" "")
4816 (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4817 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4819 /* When we use vector converts, we can't have input in memory. */
4820 if (GET_MODE (operands[0]) == DFmode
4821 && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4822 && SSE_FLOAT_MODE_P (DFmode))
4823 operands[1] = force_reg (SImode, operands[1]);
4824 else if (GET_MODE (operands[0]) == SFmode
4825 && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4826 && SSE_FLOAT_MODE_P (SFmode))
4828 /* When !flag_trapping_math, we handle SImode->SFmode vector
4829 conversions same way as SImode->DFmode.
4831 For flat_trapping_math we can't safely use vector conversion without
4832 clearing upper half, otherwise precision exception might occur.
4833 However we can still generate the common sequence converting value
4834 from general register to XMM register as:
4840 because we know that movd clears the upper half.
4842 Sadly in this case we can't rely on reload moving the value to XMM
4843 register, since we need to know if upper half is OK, so we need
4844 to do reloading by hand. We force operand to memory unless target
4845 supports inter unit moves. */
4846 if (!flag_trapping_math)
4847 operands[1] = force_reg (SImode, operands[1]);
4848 else if (!MEM_P (operands[1]))
4850 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4851 rtx tmp = assign_386_stack_local (SImode, slot);
4852 emit_move_insn (tmp, operands[1]);
4856 /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4857 !TARGET_INTER_UNIT_CONVERSIONS
4858 It is necessary for the patterns to not accept nonmemory operands
4859 as we would optimize out later. */
4860 else if (!TARGET_INTER_UNIT_CONVERSIONS
4861 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4863 && !MEM_P (operands[1]))
4865 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4866 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
4867 emit_move_insn (tmp, operands[1]);
4872 (define_insn "*floatsisf2_mixed_vector"
4873 [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4874 (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4875 "TARGET_MIX_SSE_I387 && !flag_trapping_math
4876 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4878 cvtdq2ps\t{%1, %0|%0, %1}
4881 [(set_attr "type" "sseicvt,fmov,multi")
4882 (set_attr "mode" "SF")
4883 (set_attr "unit" "*,i387,*")
4884 (set_attr "athlon_decode" "double,*,*")
4885 (set_attr "amdfam10_decode" "double,*,*")
4886 (set_attr "fp_int_src" "false,true,true")])
4888 (define_insn "*floatsisf2_mixed"
4889 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4890 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4891 "TARGET_MIX_SSE_I387
4892 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4897 cvtsi2ss\t{%1, %0|%0, %1}
4898 cvtsi2ss\t{%1, %0|%0, %1}"
4899 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4900 (set_attr "mode" "SF")
4901 (set_attr "unit" "*,i387,*,*")
4902 (set_attr "athlon_decode" "*,*,vector,double")
4903 (set_attr "amdfam10_decode" "*,*,vector,double")
4904 (set_attr "fp_int_src" "true")])
4906 (define_insn "*floatsisf2_mixed_memory"
4907 [(set (match_operand:SF 0 "register_operand" "=f,x")
4908 (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4909 "TARGET_MIX_SSE_I387
4910 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4913 cvtsi2ss\t{%1, %0|%0, %1}"
4914 [(set_attr "type" "fmov,sseicvt")
4915 (set_attr "mode" "SF")
4916 (set_attr "athlon_decode" "*,double")
4917 (set_attr "amdfam10_decode" "*,double")
4918 (set_attr "fp_int_src" "true")])
4920 (define_insn "*floatsisf2_sse_vector_nointernunit"
4921 [(set (match_operand:SF 0 "register_operand" "=x")
4922 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4923 "TARGET_SSE_MATH && flag_trapping_math
4924 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4925 && !TARGET_INTER_UNIT_MOVES"
4927 [(set_attr "type" "multi")])
4929 (define_insn "*floatsisf2_sse_vector_internunit"
4930 [(set (match_operand:SF 0 "register_operand" "=x,x")
4931 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4932 "TARGET_SSE_MATH && flag_trapping_math
4933 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4934 && TARGET_INTER_UNIT_MOVES"
4936 [(set_attr "type" "multi")])
4939 [(set (match_operand:SF 0 "register_operand" "")
4940 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4942 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4943 && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4944 && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4946 (float:V4SF (match_dup 2)))]
4948 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4949 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4950 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4954 [(set (match_operand:SF 0 "register_operand" "")
4955 (float:SF (match_operand:SI 1 "register_operand" "")))]
4957 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4958 && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4959 [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4961 (float:V4SF (match_dup 2)))]
4963 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4964 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4967 (define_insn "*floatsisf2_sse_vector"
4968 [(set (match_operand:SF 0 "register_operand" "=x")
4969 (float:SF (match_operand:SI 1 "register_operand" "x")))]
4970 "TARGET_SSE_MATH && !flag_trapping_math
4971 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4972 && !TARGET_INTER_UNIT_MOVES"
4973 "cvtdq2ps\t{%1, %0|%0, %1}"
4974 [(set_attr "type" "sseicvt")
4975 (set_attr "mode" "SF")
4976 (set_attr "athlon_decode" "double")
4977 (set_attr "amdfam10_decode" "double")
4978 (set_attr "fp_int_src" "true")])
4980 (define_insn "*floatsisf2_sse"
4981 [(set (match_operand:SF 0 "register_operand" "=x,x")
4982 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4984 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4986 "cvtsi2ss\t{%1, %0|%0, %1}"
4987 [(set_attr "type" "sseicvt")
4988 (set_attr "mode" "SF")
4989 (set_attr "athlon_decode" "vector,double")
4990 (set_attr "amdfam10_decode" "vector,double")
4991 (set_attr "fp_int_src" "true")])
4993 (define_insn "*floatsisf2_sse_memory"
4994 [(set (match_operand:SF 0 "register_operand" "=x")
4995 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4997 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4998 "cvtsi2ss\t{%1, %0|%0, %1}"
4999 [(set_attr "type" "sseicvt")
5000 (set_attr "mode" "SF")
5001 (set_attr "athlon_decode" "double")
5002 (set_attr "amdfam10_decode" "double")
5003 (set_attr "fp_int_src" "true")])
5005 (define_insn "*floatsidf2_mixed_vector"
5006 [(set (match_operand:DF 0 "register_operand" "=x,f,f")
5007 (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
5008 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5009 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5011 cvtdq2pd\t{%1, %0|%0, %1}
5014 [(set_attr "type" "sseicvt,fmov,multi")
5015 (set_attr "mode" "V2DF,DF,DF")
5016 (set_attr "unit" "*,*,i387")
5017 (set_attr "athlon_decode" "double,*,*")
5018 (set_attr "amdfam10_decode" "double,*,*")
5019 (set_attr "fp_int_src" "false,true,true")])
5021 (define_insn "*floatsidf2_mixed"
5022 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5023 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5024 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5025 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5030 cvtsi2sd\t{%1, %0|%0, %1}
5031 cvtsi2sd\t{%1, %0|%0, %1}
5032 cvtdq2pd\t{%1, %0|%0, %1}"
5033 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5034 (set_attr "mode" "DF,DF,DF,DF,V2DF")
5035 (set_attr "unit" "*,i387,*,*,*")
5036 (set_attr "athlon_decode" "*,*,double,direct,double")
5037 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5038 (set_attr "fp_int_src" "true,true,true,true,false")])
5040 (define_insn "*floatsidf2_mixed_memory"
5041 [(set (match_operand:DF 0 "register_operand" "=f,x")
5042 (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5043 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5044 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5047 cvtsi2sd\t{%1, %0|%0, %1}"
5048 [(set_attr "type" "fmov,sseicvt")
5049 (set_attr "mode" "DF")
5050 (set_attr "athlon_decode" "*,direct")
5051 (set_attr "amdfam10_decode" "*,double")
5052 (set_attr "fp_int_src" "true")])
5054 (define_insn "*floatsidf2_sse_vector"
5055 [(set (match_operand:DF 0 "register_operand" "=x")
5056 (float:DF (match_operand:SI 1 "register_operand" "x")))]
5057 "TARGET_SSE2 && TARGET_SSE_MATH
5058 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5059 "cvtdq2pd\t{%1, %0|%0, %1}"
5060 [(set_attr "type" "sseicvt")
5061 (set_attr "mode" "V2DF")
5062 (set_attr "athlon_decode" "double")
5063 (set_attr "amdfam10_decode" "double")
5064 (set_attr "fp_int_src" "true")])
5067 [(set (match_operand:DF 0 "register_operand" "")
5068 (float:DF (match_operand:SI 1 "memory_operand" "")))]
5069 "TARGET_USE_VECTOR_CONVERTS && reload_completed
5070 && SSE_REG_P (operands[0])"
5075 (parallel [(const_int 0) (const_int 1)]))))]
5077 operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5078 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5079 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5082 (define_insn "*floatsidf2_sse"
5083 [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5084 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5085 "TARGET_SSE2 && TARGET_SSE_MATH
5086 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5089 cvtsi2sd\t{%1, %0|%0, %1}
5090 cvtsi2sd\t{%1, %0|%0, %1}
5091 cvtdq2pd\t{%1, %0|%0, %1}"
5092 [(set_attr "type" "sseicvt")
5093 (set_attr "mode" "DF,DF,V2DF")
5094 (set_attr "athlon_decode" "double,direct,double")
5095 (set_attr "amdfam10_decode" "vector,double,double")
5096 (set_attr "fp_int_src" "true")])
5098 (define_insn "*floatsidf2_memory"
5099 [(set (match_operand:DF 0 "register_operand" "=x")
5100 (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5101 "TARGET_SSE2 && TARGET_SSE_MATH
5102 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5104 "cvtsi2sd\t{%1, %0|%0, %1}"
5105 [(set_attr "type" "sseicvt")
5106 (set_attr "mode" "DF")
5107 (set_attr "athlon_decode" "direct")
5108 (set_attr "amdfam10_decode" "double")
5109 (set_attr "fp_int_src" "true")])
5111 (define_insn "*floatsi<mode>2_i387"
5112 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5114 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5116 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5120 [(set_attr "type" "fmov,multi")
5121 (set_attr "mode" "<MODE>")
5122 (set_attr "unit" "*,i387")
5123 (set_attr "fp_int_src" "true")])
5125 (define_expand "floatdisf2"
5126 [(set (match_operand:SF 0 "register_operand" "")
5127 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5128 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5130 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5131 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5133 && !MEM_P (operands[1]))
5135 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5136 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5137 emit_move_insn (tmp, operands[1]);
5142 (define_insn "*floatdisf2_mixed"
5143 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5144 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5145 "TARGET_64BIT && TARGET_MIX_SSE_I387
5146 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5150 cvtsi2ss{q}\t{%1, %0|%0, %1}
5151 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5152 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5153 (set_attr "mode" "SF")
5154 (set_attr "unit" "*,i387,*,*")
5155 (set_attr "athlon_decode" "*,*,vector,double")
5156 (set_attr "amdfam10_decode" "*,*,vector,double")
5157 (set_attr "fp_int_src" "true")])
5159 (define_insn "*floatdisf2_mixed"
5160 [(set (match_operand:SF 0 "register_operand" "=f,x")
5161 (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5162 "TARGET_64BIT && TARGET_MIX_SSE_I387
5163 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5166 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5167 [(set_attr "type" "fmov,sseicvt")
5168 (set_attr "mode" "SF")
5169 (set_attr "athlon_decode" "*,double")
5170 (set_attr "amdfam10_decode" "*,double")
5171 (set_attr "fp_int_src" "true")])
5173 (define_insn "*floatdisf2_sse"
5174 [(set (match_operand:SF 0 "register_operand" "=x,x")
5175 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5176 "TARGET_64BIT && TARGET_SSE_MATH
5177 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5178 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5179 [(set_attr "type" "sseicvt")
5180 (set_attr "mode" "SF")
5181 (set_attr "athlon_decode" "vector,double")
5182 (set_attr "amdfam10_decode" "vector,double")
5183 (set_attr "fp_int_src" "true")])
5185 (define_insn "*floatdisf2_memory"
5186 [(set (match_operand:SF 0 "register_operand" "=x")
5187 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5188 "TARGET_64BIT && TARGET_SSE_MATH
5189 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5190 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5191 [(set_attr "type" "sseicvt")
5192 (set_attr "mode" "SF")
5193 (set_attr "athlon_decode" "double")
5194 (set_attr "amdfam10_decode" "double")
5195 (set_attr "fp_int_src" "true")])
5197 (define_expand "floatdidf2"
5198 [(set (match_operand:DF 0 "register_operand" "")
5199 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5200 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5202 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5204 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5207 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5208 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5210 && !MEM_P (operands[1]))
5212 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5213 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5214 emit_move_insn (tmp, operands[1]);
5219 (define_insn "*floatdidf2_mixed"
5220 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5221 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5222 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5223 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5227 cvtsi2sd{q}\t{%1, %0|%0, %1}
5228 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5229 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5230 (set_attr "mode" "DF")
5231 (set_attr "unit" "*,i387,*,*")
5232 (set_attr "athlon_decode" "*,*,double,direct")
5233 (set_attr "amdfam10_decode" "*,*,vector,double")
5234 (set_attr "fp_int_src" "true")])
5236 (define_insn "*floatdidf2_mixed_memory"
5237 [(set (match_operand:DF 0 "register_operand" "=f,x")
5238 (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5239 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5240 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5243 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5244 [(set_attr "type" "fmov,sseicvt")
5245 (set_attr "mode" "DF")
5246 (set_attr "athlon_decode" "*,direct")
5247 (set_attr "amdfam10_decode" "*,double")
5248 (set_attr "fp_int_src" "true")])
5250 (define_insn "*floatdidf2_sse"
5251 [(set (match_operand:DF 0 "register_operand" "=x,x")
5252 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5253 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5254 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5255 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5256 [(set_attr "type" "sseicvt")
5257 (set_attr "mode" "DF")
5258 (set_attr "athlon_decode" "double,direct")
5259 (set_attr "amdfam10_decode" "vector,double")
5260 (set_attr "fp_int_src" "true")])
5262 (define_insn "*floatdidf2_sse_memory"
5263 [(set (match_operand:DF 0 "register_operand" "=x")
5264 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5265 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5266 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5267 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5268 [(set_attr "type" "sseicvt")
5269 (set_attr "mode" "DF")
5270 (set_attr "athlon_decode" "direct")
5271 (set_attr "amdfam10_decode" "double")
5272 (set_attr "fp_int_src" "true")])
5274 (define_insn "*floatdi<mode>2_i387"
5275 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5277 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5279 && (!TARGET_SSE_MATH || !TARGET_64BIT
5280 || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5284 [(set_attr "type" "fmov,multi")
5285 (set_attr "mode" "<MODE>")
5286 (set_attr "unit" "*,i387")
5287 (set_attr "fp_int_src" "true")])
5289 (define_insn "float<mode>xf2"
5290 [(set (match_operand:XF 0 "register_operand" "=f,f")
5291 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5296 [(set_attr "type" "fmov,multi")
5297 (set_attr "mode" "XF")
5298 (set_attr "unit" "*,i387")
5299 (set_attr "fp_int_src" "true")])
5301 ;; %%% Kill these when reload knows how to do it.
5303 [(set (match_operand 0 "fp_register_operand" "")
5304 (float (match_operand 1 "register_operand" "")))]
5306 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5309 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5310 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5311 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5312 ix86_free_from_memory (GET_MODE (operands[1]));
5316 (define_expand "floatunssi<mode>2"
5317 [(use (match_operand:MODEF 0 "register_operand" ""))
5318 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5319 "!TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5321 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5325 (define_expand "floatunsdisf2"
5326 [(use (match_operand:SF 0 "register_operand" ""))
5327 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5328 "TARGET_64BIT && TARGET_SSE_MATH"
5329 "x86_emit_floatuns (operands); DONE;")
5331 (define_expand "floatunsdidf2"
5332 [(use (match_operand:DF 0 "register_operand" ""))
5333 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5334 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5335 && TARGET_SSE2 && TARGET_SSE_MATH"
5338 x86_emit_floatuns (operands);
5340 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5346 ;; %%% splits for addditi3
5348 (define_expand "addti3"
5349 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5350 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5351 (match_operand:TI 2 "x86_64_general_operand" "")))
5352 (clobber (reg:CC FLAGS_REG))]
5354 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5356 (define_insn "*addti3_1"
5357 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5358 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5359 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5360 (clobber (reg:CC FLAGS_REG))]
5361 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5365 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5366 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5367 (match_operand:TI 2 "x86_64_general_operand" "")))
5368 (clobber (reg:CC FLAGS_REG))]
5369 "TARGET_64BIT && reload_completed"
5370 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5372 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5373 (parallel [(set (match_dup 3)
5374 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5377 (clobber (reg:CC FLAGS_REG))])]
5378 "split_ti (operands+0, 1, operands+0, operands+3);
5379 split_ti (operands+1, 1, operands+1, operands+4);
5380 split_ti (operands+2, 1, operands+2, operands+5);")
5382 ;; %%% splits for addsidi3
5383 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5384 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5385 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5387 (define_expand "adddi3"
5388 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5389 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5390 (match_operand:DI 2 "x86_64_general_operand" "")))
5391 (clobber (reg:CC FLAGS_REG))]
5393 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5395 (define_insn "*adddi3_1"
5396 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5397 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5398 (match_operand:DI 2 "general_operand" "roiF,riF")))
5399 (clobber (reg:CC FLAGS_REG))]
5400 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5404 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5405 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5406 (match_operand:DI 2 "general_operand" "")))
5407 (clobber (reg:CC FLAGS_REG))]
5408 "!TARGET_64BIT && reload_completed"
5409 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5411 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5412 (parallel [(set (match_dup 3)
5413 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5416 (clobber (reg:CC FLAGS_REG))])]
5417 "split_di (operands+0, 1, operands+0, operands+3);
5418 split_di (operands+1, 1, operands+1, operands+4);
5419 split_di (operands+2, 1, operands+2, operands+5);")
5421 (define_insn "adddi3_carry_rex64"
5422 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5423 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5424 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5425 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5426 (clobber (reg:CC FLAGS_REG))]
5427 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5428 "adc{q}\t{%2, %0|%0, %2}"
5429 [(set_attr "type" "alu")
5430 (set_attr "pent_pair" "pu")
5431 (set_attr "mode" "DI")])
5433 (define_insn "*adddi3_cc_rex64"
5434 [(set (reg:CC FLAGS_REG)
5435 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5436 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5438 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5439 (plus:DI (match_dup 1) (match_dup 2)))]
5440 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5441 "add{q}\t{%2, %0|%0, %2}"
5442 [(set_attr "type" "alu")
5443 (set_attr "mode" "DI")])
5445 (define_insn "*<addsub><mode>3_cc_overflow"
5446 [(set (reg:CCC FLAGS_REG)
5449 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5450 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5452 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5453 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5454 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5455 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5456 [(set_attr "type" "alu")
5457 (set_attr "mode" "<MODE>")])
5459 (define_insn "*add<mode>3_cconly_overflow"
5460 [(set (reg:CCC FLAGS_REG)
5462 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5463 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5465 (clobber (match_scratch:SWI 0 "=<r>"))]
5466 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5467 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5468 [(set_attr "type" "alu")
5469 (set_attr "mode" "<MODE>")])
5471 (define_insn "*sub<mode>3_cconly_overflow"
5472 [(set (reg:CCC FLAGS_REG)
5474 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5475 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5478 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5479 [(set_attr "type" "icmp")
5480 (set_attr "mode" "<MODE>")])
5482 (define_insn "*<addsub>si3_zext_cc_overflow"
5483 [(set (reg:CCC FLAGS_REG)
5485 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5486 (match_operand:SI 2 "general_operand" "g"))
5488 (set (match_operand:DI 0 "register_operand" "=r")
5489 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5490 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5491 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5492 [(set_attr "type" "alu")
5493 (set_attr "mode" "SI")])
5495 (define_insn "addqi3_carry"
5496 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5497 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5498 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5499 (match_operand:QI 2 "general_operand" "qi,qm")))
5500 (clobber (reg:CC FLAGS_REG))]
5501 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5502 "adc{b}\t{%2, %0|%0, %2}"
5503 [(set_attr "type" "alu")
5504 (set_attr "pent_pair" "pu")
5505 (set_attr "mode" "QI")])
5507 (define_insn "addhi3_carry"
5508 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5509 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5510 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5511 (match_operand:HI 2 "general_operand" "ri,rm")))
5512 (clobber (reg:CC FLAGS_REG))]
5513 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5514 "adc{w}\t{%2, %0|%0, %2}"
5515 [(set_attr "type" "alu")
5516 (set_attr "pent_pair" "pu")
5517 (set_attr "mode" "HI")])
5519 (define_insn "addsi3_carry"
5520 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5521 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5522 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5523 (match_operand:SI 2 "general_operand" "ri,rm")))
5524 (clobber (reg:CC FLAGS_REG))]
5525 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5526 "adc{l}\t{%2, %0|%0, %2}"
5527 [(set_attr "type" "alu")
5528 (set_attr "pent_pair" "pu")
5529 (set_attr "mode" "SI")])
5531 (define_insn "*addsi3_carry_zext"
5532 [(set (match_operand:DI 0 "register_operand" "=r")
5534 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5535 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5536 (match_operand:SI 2 "general_operand" "g"))))
5537 (clobber (reg:CC FLAGS_REG))]
5538 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5539 "adc{l}\t{%2, %k0|%k0, %2}"
5540 [(set_attr "type" "alu")
5541 (set_attr "pent_pair" "pu")
5542 (set_attr "mode" "SI")])
5544 (define_insn "*addsi3_cc"
5545 [(set (reg:CC FLAGS_REG)
5546 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5547 (match_operand:SI 2 "general_operand" "ri,rm")]
5549 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5550 (plus:SI (match_dup 1) (match_dup 2)))]
5551 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5552 "add{l}\t{%2, %0|%0, %2}"
5553 [(set_attr "type" "alu")
5554 (set_attr "mode" "SI")])
5556 (define_insn "addqi3_cc"
5557 [(set (reg:CC FLAGS_REG)
5558 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5559 (match_operand:QI 2 "general_operand" "qi,qm")]
5561 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5562 (plus:QI (match_dup 1) (match_dup 2)))]
5563 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5564 "add{b}\t{%2, %0|%0, %2}"
5565 [(set_attr "type" "alu")
5566 (set_attr "mode" "QI")])
5568 (define_expand "addsi3"
5569 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5570 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5571 (match_operand:SI 2 "general_operand" "")))
5572 (clobber (reg:CC FLAGS_REG))])]
5574 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5576 (define_insn "*lea_1"
5577 [(set (match_operand:SI 0 "register_operand" "=r")
5578 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5580 "lea{l}\t{%a1, %0|%0, %a1}"
5581 [(set_attr "type" "lea")
5582 (set_attr "mode" "SI")])
5584 (define_insn "*lea_1_rex64"
5585 [(set (match_operand:SI 0 "register_operand" "=r")
5586 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5588 "lea{l}\t{%a1, %0|%0, %a1}"
5589 [(set_attr "type" "lea")
5590 (set_attr "mode" "SI")])
5592 (define_insn "*lea_1_zext"
5593 [(set (match_operand:DI 0 "register_operand" "=r")
5595 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5597 "lea{l}\t{%a1, %k0|%k0, %a1}"
5598 [(set_attr "type" "lea")
5599 (set_attr "mode" "SI")])
5601 (define_insn "*lea_2_rex64"
5602 [(set (match_operand:DI 0 "register_operand" "=r")
5603 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5605 "lea{q}\t{%a1, %0|%0, %a1}"
5606 [(set_attr "type" "lea")
5607 (set_attr "mode" "DI")])
5609 ;; The lea patterns for non-Pmodes needs to be matched by several
5610 ;; insns converted to real lea by splitters.
5612 (define_insn_and_split "*lea_general_1"
5613 [(set (match_operand 0 "register_operand" "=r")
5614 (plus (plus (match_operand 1 "index_register_operand" "l")
5615 (match_operand 2 "register_operand" "r"))
5616 (match_operand 3 "immediate_operand" "i")))]
5617 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5618 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5619 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5620 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5621 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5622 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5623 || GET_MODE (operands[3]) == VOIDmode)"
5625 "&& reload_completed"
5629 operands[0] = gen_lowpart (SImode, operands[0]);
5630 operands[1] = gen_lowpart (Pmode, operands[1]);
5631 operands[2] = gen_lowpart (Pmode, operands[2]);
5632 operands[3] = gen_lowpart (Pmode, operands[3]);
5633 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5635 if (Pmode != SImode)
5636 pat = gen_rtx_SUBREG (SImode, pat, 0);
5637 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5640 [(set_attr "type" "lea")
5641 (set_attr "mode" "SI")])
5643 (define_insn_and_split "*lea_general_1_zext"
5644 [(set (match_operand:DI 0 "register_operand" "=r")
5646 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5647 (match_operand:SI 2 "register_operand" "r"))
5648 (match_operand:SI 3 "immediate_operand" "i"))))]
5651 "&& reload_completed"
5653 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5655 (match_dup 3)) 0)))]
5657 operands[1] = gen_lowpart (Pmode, operands[1]);
5658 operands[2] = gen_lowpart (Pmode, operands[2]);
5659 operands[3] = gen_lowpart (Pmode, operands[3]);
5661 [(set_attr "type" "lea")
5662 (set_attr "mode" "SI")])
5664 (define_insn_and_split "*lea_general_2"
5665 [(set (match_operand 0 "register_operand" "=r")
5666 (plus (mult (match_operand 1 "index_register_operand" "l")
5667 (match_operand 2 "const248_operand" "i"))
5668 (match_operand 3 "nonmemory_operand" "ri")))]
5669 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5670 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5671 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5672 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5673 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5674 || GET_MODE (operands[3]) == VOIDmode)"
5676 "&& reload_completed"
5680 operands[0] = gen_lowpart (SImode, operands[0]);
5681 operands[1] = gen_lowpart (Pmode, operands[1]);
5682 operands[3] = gen_lowpart (Pmode, operands[3]);
5683 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5685 if (Pmode != SImode)
5686 pat = gen_rtx_SUBREG (SImode, pat, 0);
5687 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5690 [(set_attr "type" "lea")
5691 (set_attr "mode" "SI")])
5693 (define_insn_and_split "*lea_general_2_zext"
5694 [(set (match_operand:DI 0 "register_operand" "=r")
5696 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5697 (match_operand:SI 2 "const248_operand" "n"))
5698 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5701 "&& reload_completed"
5703 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5705 (match_dup 3)) 0)))]
5707 operands[1] = gen_lowpart (Pmode, operands[1]);
5708 operands[3] = gen_lowpart (Pmode, operands[3]);
5710 [(set_attr "type" "lea")
5711 (set_attr "mode" "SI")])
5713 (define_insn_and_split "*lea_general_3"
5714 [(set (match_operand 0 "register_operand" "=r")
5715 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5716 (match_operand 2 "const248_operand" "i"))
5717 (match_operand 3 "register_operand" "r"))
5718 (match_operand 4 "immediate_operand" "i")))]
5719 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5720 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5721 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5722 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5723 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5725 "&& reload_completed"
5729 operands[0] = gen_lowpart (SImode, operands[0]);
5730 operands[1] = gen_lowpart (Pmode, operands[1]);
5731 operands[3] = gen_lowpart (Pmode, operands[3]);
5732 operands[4] = gen_lowpart (Pmode, operands[4]);
5733 pat = gen_rtx_PLUS (Pmode,
5734 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5738 if (Pmode != SImode)
5739 pat = gen_rtx_SUBREG (SImode, pat, 0);
5740 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5743 [(set_attr "type" "lea")
5744 (set_attr "mode" "SI")])
5746 (define_insn_and_split "*lea_general_3_zext"
5747 [(set (match_operand:DI 0 "register_operand" "=r")
5749 (plus:SI (plus:SI (mult:SI
5750 (match_operand:SI 1 "index_register_operand" "l")
5751 (match_operand:SI 2 "const248_operand" "n"))
5752 (match_operand:SI 3 "register_operand" "r"))
5753 (match_operand:SI 4 "immediate_operand" "i"))))]
5756 "&& reload_completed"
5758 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5761 (match_dup 4)) 0)))]
5763 operands[1] = gen_lowpart (Pmode, operands[1]);
5764 operands[3] = gen_lowpart (Pmode, operands[3]);
5765 operands[4] = gen_lowpart (Pmode, operands[4]);
5767 [(set_attr "type" "lea")
5768 (set_attr "mode" "SI")])
5770 (define_insn "*adddi_1_rex64"
5771 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5772 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5773 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5774 (clobber (reg:CC FLAGS_REG))]
5775 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5777 switch (get_attr_type (insn))
5780 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5781 return "lea{q}\t{%a2, %0|%0, %a2}";
5784 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5785 if (operands[2] == const1_rtx)
5786 return "inc{q}\t%0";
5789 gcc_assert (operands[2] == constm1_rtx);
5790 return "dec{q}\t%0";
5794 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5796 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5797 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5798 if (CONST_INT_P (operands[2])
5799 /* Avoid overflows. */
5800 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5801 && (INTVAL (operands[2]) == 128
5802 || (INTVAL (operands[2]) < 0
5803 && INTVAL (operands[2]) != -128)))
5805 operands[2] = GEN_INT (-INTVAL (operands[2]));
5806 return "sub{q}\t{%2, %0|%0, %2}";
5808 return "add{q}\t{%2, %0|%0, %2}";
5812 (cond [(eq_attr "alternative" "2")
5813 (const_string "lea")
5814 ; Current assemblers are broken and do not allow @GOTOFF in
5815 ; ought but a memory context.
5816 (match_operand:DI 2 "pic_symbolic_operand" "")
5817 (const_string "lea")
5818 (match_operand:DI 2 "incdec_operand" "")
5819 (const_string "incdec")
5821 (const_string "alu")))
5822 (set_attr "mode" "DI")])
5824 ;; Convert lea to the lea pattern to avoid flags dependency.
5826 [(set (match_operand:DI 0 "register_operand" "")
5827 (plus:DI (match_operand:DI 1 "register_operand" "")
5828 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5829 (clobber (reg:CC FLAGS_REG))]
5830 "TARGET_64BIT && reload_completed
5831 && true_regnum (operands[0]) != true_regnum (operands[1])"
5833 (plus:DI (match_dup 1)
5837 (define_insn "*adddi_2_rex64"
5838 [(set (reg FLAGS_REG)
5840 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5841 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5843 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5844 (plus:DI (match_dup 1) (match_dup 2)))]
5845 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5846 && ix86_binary_operator_ok (PLUS, DImode, operands)
5847 /* Current assemblers are broken and do not allow @GOTOFF in
5848 ought but a memory context. */
5849 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5851 switch (get_attr_type (insn))
5854 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5855 if (operands[2] == const1_rtx)
5856 return "inc{q}\t%0";
5859 gcc_assert (operands[2] == constm1_rtx);
5860 return "dec{q}\t%0";
5864 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5865 /* ???? We ought to handle there the 32bit case too
5866 - do we need new constraint? */
5867 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5868 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5869 if (CONST_INT_P (operands[2])
5870 /* Avoid overflows. */
5871 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5872 && (INTVAL (operands[2]) == 128
5873 || (INTVAL (operands[2]) < 0
5874 && INTVAL (operands[2]) != -128)))
5876 operands[2] = GEN_INT (-INTVAL (operands[2]));
5877 return "sub{q}\t{%2, %0|%0, %2}";
5879 return "add{q}\t{%2, %0|%0, %2}";
5883 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5884 (const_string "incdec")
5885 (const_string "alu")))
5886 (set_attr "mode" "DI")])
5888 (define_insn "*adddi_3_rex64"
5889 [(set (reg FLAGS_REG)
5890 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5891 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5892 (clobber (match_scratch:DI 0 "=r"))]
5894 && ix86_match_ccmode (insn, CCZmode)
5895 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5896 /* Current assemblers are broken and do not allow @GOTOFF in
5897 ought but a memory context. */
5898 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5900 switch (get_attr_type (insn))
5903 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5904 if (operands[2] == const1_rtx)
5905 return "inc{q}\t%0";
5908 gcc_assert (operands[2] == constm1_rtx);
5909 return "dec{q}\t%0";
5913 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5914 /* ???? We ought to handle there the 32bit case too
5915 - do we need new constraint? */
5916 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5917 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5918 if (CONST_INT_P (operands[2])
5919 /* Avoid overflows. */
5920 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5921 && (INTVAL (operands[2]) == 128
5922 || (INTVAL (operands[2]) < 0
5923 && INTVAL (operands[2]) != -128)))
5925 operands[2] = GEN_INT (-INTVAL (operands[2]));
5926 return "sub{q}\t{%2, %0|%0, %2}";
5928 return "add{q}\t{%2, %0|%0, %2}";
5932 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5933 (const_string "incdec")
5934 (const_string "alu")))
5935 (set_attr "mode" "DI")])
5937 ; For comparisons against 1, -1 and 128, we may generate better code
5938 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5939 ; is matched then. We can't accept general immediate, because for
5940 ; case of overflows, the result is messed up.
5941 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5943 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5944 ; only for comparisons not depending on it.
5945 (define_insn "*adddi_4_rex64"
5946 [(set (reg FLAGS_REG)
5947 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5948 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5949 (clobber (match_scratch:DI 0 "=rm"))]
5951 && ix86_match_ccmode (insn, CCGCmode)"
5953 switch (get_attr_type (insn))
5956 if (operands[2] == constm1_rtx)
5957 return "inc{q}\t%0";
5960 gcc_assert (operands[2] == const1_rtx);
5961 return "dec{q}\t%0";
5965 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5966 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5968 if ((INTVAL (operands[2]) == -128
5969 || (INTVAL (operands[2]) > 0
5970 && INTVAL (operands[2]) != 128))
5971 /* Avoid overflows. */
5972 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5973 return "sub{q}\t{%2, %0|%0, %2}";
5974 operands[2] = GEN_INT (-INTVAL (operands[2]));
5975 return "add{q}\t{%2, %0|%0, %2}";
5979 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5980 (const_string "incdec")
5981 (const_string "alu")))
5982 (set_attr "mode" "DI")])
5984 (define_insn "*adddi_5_rex64"
5985 [(set (reg FLAGS_REG)
5987 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5988 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5990 (clobber (match_scratch:DI 0 "=r"))]
5992 && ix86_match_ccmode (insn, CCGOCmode)
5993 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5994 /* Current assemblers are broken and do not allow @GOTOFF in
5995 ought but a memory context. */
5996 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5998 switch (get_attr_type (insn))
6001 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6002 if (operands[2] == const1_rtx)
6003 return "inc{q}\t%0";
6006 gcc_assert (operands[2] == constm1_rtx);
6007 return "dec{q}\t%0";
6011 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6012 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6013 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6014 if (CONST_INT_P (operands[2])
6015 /* Avoid overflows. */
6016 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6017 && (INTVAL (operands[2]) == 128
6018 || (INTVAL (operands[2]) < 0
6019 && INTVAL (operands[2]) != -128)))
6021 operands[2] = GEN_INT (-INTVAL (operands[2]));
6022 return "sub{q}\t{%2, %0|%0, %2}";
6024 return "add{q}\t{%2, %0|%0, %2}";
6028 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6029 (const_string "incdec")
6030 (const_string "alu")))
6031 (set_attr "mode" "DI")])
6034 (define_insn "*addsi_1"
6035 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6036 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6037 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6038 (clobber (reg:CC FLAGS_REG))]
6039 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6041 switch (get_attr_type (insn))
6044 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6045 return "lea{l}\t{%a2, %0|%0, %a2}";
6048 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6049 if (operands[2] == const1_rtx)
6050 return "inc{l}\t%0";
6053 gcc_assert (operands[2] == constm1_rtx);
6054 return "dec{l}\t%0";
6058 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6060 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6061 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6062 if (CONST_INT_P (operands[2])
6063 && (INTVAL (operands[2]) == 128
6064 || (INTVAL (operands[2]) < 0
6065 && INTVAL (operands[2]) != -128)))
6067 operands[2] = GEN_INT (-INTVAL (operands[2]));
6068 return "sub{l}\t{%2, %0|%0, %2}";
6070 return "add{l}\t{%2, %0|%0, %2}";
6074 (cond [(eq_attr "alternative" "2")
6075 (const_string "lea")
6076 ; Current assemblers are broken and do not allow @GOTOFF in
6077 ; ought but a memory context.
6078 (match_operand:SI 2 "pic_symbolic_operand" "")
6079 (const_string "lea")
6080 (match_operand:SI 2 "incdec_operand" "")
6081 (const_string "incdec")
6083 (const_string "alu")))
6084 (set_attr "mode" "SI")])
6086 ;; Convert lea to the lea pattern to avoid flags dependency.
6088 [(set (match_operand 0 "register_operand" "")
6089 (plus (match_operand 1 "register_operand" "")
6090 (match_operand 2 "nonmemory_operand" "")))
6091 (clobber (reg:CC FLAGS_REG))]
6093 && true_regnum (operands[0]) != true_regnum (operands[1])"
6097 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6098 may confuse gen_lowpart. */
6099 if (GET_MODE (operands[0]) != Pmode)
6101 operands[1] = gen_lowpart (Pmode, operands[1]);
6102 operands[2] = gen_lowpart (Pmode, operands[2]);
6104 operands[0] = gen_lowpart (SImode, operands[0]);
6105 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6106 if (Pmode != SImode)
6107 pat = gen_rtx_SUBREG (SImode, pat, 0);
6108 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6112 ;; It may seem that nonimmediate operand is proper one for operand 1.
6113 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6114 ;; we take care in ix86_binary_operator_ok to not allow two memory
6115 ;; operands so proper swapping will be done in reload. This allow
6116 ;; patterns constructed from addsi_1 to match.
6117 (define_insn "addsi_1_zext"
6118 [(set (match_operand:DI 0 "register_operand" "=r,r")
6120 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6121 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6122 (clobber (reg:CC FLAGS_REG))]
6123 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6125 switch (get_attr_type (insn))
6128 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6129 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6132 if (operands[2] == const1_rtx)
6133 return "inc{l}\t%k0";
6136 gcc_assert (operands[2] == constm1_rtx);
6137 return "dec{l}\t%k0";
6141 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6143 if (CONST_INT_P (operands[2])
6144 && (INTVAL (operands[2]) == 128
6145 || (INTVAL (operands[2]) < 0
6146 && INTVAL (operands[2]) != -128)))
6148 operands[2] = GEN_INT (-INTVAL (operands[2]));
6149 return "sub{l}\t{%2, %k0|%k0, %2}";
6151 return "add{l}\t{%2, %k0|%k0, %2}";
6155 (cond [(eq_attr "alternative" "1")
6156 (const_string "lea")
6157 ; Current assemblers are broken and do not allow @GOTOFF in
6158 ; ought but a memory context.
6159 (match_operand:SI 2 "pic_symbolic_operand" "")
6160 (const_string "lea")
6161 (match_operand:SI 2 "incdec_operand" "")
6162 (const_string "incdec")
6164 (const_string "alu")))
6165 (set_attr "mode" "SI")])
6167 ;; Convert lea to the lea pattern to avoid flags dependency.
6169 [(set (match_operand:DI 0 "register_operand" "")
6171 (plus:SI (match_operand:SI 1 "register_operand" "")
6172 (match_operand:SI 2 "nonmemory_operand" ""))))
6173 (clobber (reg:CC FLAGS_REG))]
6174 "TARGET_64BIT && reload_completed
6175 && true_regnum (operands[0]) != true_regnum (operands[1])"
6177 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6179 operands[1] = gen_lowpart (Pmode, operands[1]);
6180 operands[2] = gen_lowpart (Pmode, operands[2]);
6183 (define_insn "*addsi_2"
6184 [(set (reg FLAGS_REG)
6186 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6187 (match_operand:SI 2 "general_operand" "rmni,rni"))
6189 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6190 (plus:SI (match_dup 1) (match_dup 2)))]
6191 "ix86_match_ccmode (insn, CCGOCmode)
6192 && ix86_binary_operator_ok (PLUS, SImode, operands)
6193 /* Current assemblers are broken and do not allow @GOTOFF in
6194 ought but a memory context. */
6195 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6197 switch (get_attr_type (insn))
6200 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6201 if (operands[2] == const1_rtx)
6202 return "inc{l}\t%0";
6205 gcc_assert (operands[2] == constm1_rtx);
6206 return "dec{l}\t%0";
6210 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6211 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6212 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6213 if (CONST_INT_P (operands[2])
6214 && (INTVAL (operands[2]) == 128
6215 || (INTVAL (operands[2]) < 0
6216 && INTVAL (operands[2]) != -128)))
6218 operands[2] = GEN_INT (-INTVAL (operands[2]));
6219 return "sub{l}\t{%2, %0|%0, %2}";
6221 return "add{l}\t{%2, %0|%0, %2}";
6225 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6226 (const_string "incdec")
6227 (const_string "alu")))
6228 (set_attr "mode" "SI")])
6230 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6231 (define_insn "*addsi_2_zext"
6232 [(set (reg FLAGS_REG)
6234 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6235 (match_operand:SI 2 "general_operand" "rmni"))
6237 (set (match_operand:DI 0 "register_operand" "=r")
6238 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6239 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6240 && ix86_binary_operator_ok (PLUS, SImode, operands)
6241 /* Current assemblers are broken and do not allow @GOTOFF in
6242 ought but a memory context. */
6243 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6245 switch (get_attr_type (insn))
6248 if (operands[2] == const1_rtx)
6249 return "inc{l}\t%k0";
6252 gcc_assert (operands[2] == constm1_rtx);
6253 return "dec{l}\t%k0";
6257 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6258 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6259 if (CONST_INT_P (operands[2])
6260 && (INTVAL (operands[2]) == 128
6261 || (INTVAL (operands[2]) < 0
6262 && INTVAL (operands[2]) != -128)))
6264 operands[2] = GEN_INT (-INTVAL (operands[2]));
6265 return "sub{l}\t{%2, %k0|%k0, %2}";
6267 return "add{l}\t{%2, %k0|%k0, %2}";
6271 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6272 (const_string "incdec")
6273 (const_string "alu")))
6274 (set_attr "mode" "SI")])
6276 (define_insn "*addsi_3"
6277 [(set (reg FLAGS_REG)
6278 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6279 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6280 (clobber (match_scratch:SI 0 "=r"))]
6281 "ix86_match_ccmode (insn, CCZmode)
6282 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6283 /* Current assemblers are broken and do not allow @GOTOFF in
6284 ought but a memory context. */
6285 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6287 switch (get_attr_type (insn))
6290 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6291 if (operands[2] == const1_rtx)
6292 return "inc{l}\t%0";
6295 gcc_assert (operands[2] == constm1_rtx);
6296 return "dec{l}\t%0";
6300 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6301 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6302 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6303 if (CONST_INT_P (operands[2])
6304 && (INTVAL (operands[2]) == 128
6305 || (INTVAL (operands[2]) < 0
6306 && INTVAL (operands[2]) != -128)))
6308 operands[2] = GEN_INT (-INTVAL (operands[2]));
6309 return "sub{l}\t{%2, %0|%0, %2}";
6311 return "add{l}\t{%2, %0|%0, %2}";
6315 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6316 (const_string "incdec")
6317 (const_string "alu")))
6318 (set_attr "mode" "SI")])
6320 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6321 (define_insn "*addsi_3_zext"
6322 [(set (reg FLAGS_REG)
6323 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6324 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6325 (set (match_operand:DI 0 "register_operand" "=r")
6326 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6327 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6328 && ix86_binary_operator_ok (PLUS, SImode, operands)
6329 /* Current assemblers are broken and do not allow @GOTOFF in
6330 ought but a memory context. */
6331 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6333 switch (get_attr_type (insn))
6336 if (operands[2] == const1_rtx)
6337 return "inc{l}\t%k0";
6340 gcc_assert (operands[2] == constm1_rtx);
6341 return "dec{l}\t%k0";
6345 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6346 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6347 if (CONST_INT_P (operands[2])
6348 && (INTVAL (operands[2]) == 128
6349 || (INTVAL (operands[2]) < 0
6350 && INTVAL (operands[2]) != -128)))
6352 operands[2] = GEN_INT (-INTVAL (operands[2]));
6353 return "sub{l}\t{%2, %k0|%k0, %2}";
6355 return "add{l}\t{%2, %k0|%k0, %2}";
6359 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6360 (const_string "incdec")
6361 (const_string "alu")))
6362 (set_attr "mode" "SI")])
6364 ; For comparisons against 1, -1 and 128, we may generate better code
6365 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6366 ; is matched then. We can't accept general immediate, because for
6367 ; case of overflows, the result is messed up.
6368 ; This pattern also don't hold of 0x80000000, since the value overflows
6370 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6371 ; only for comparisons not depending on it.
6372 (define_insn "*addsi_4"
6373 [(set (reg FLAGS_REG)
6374 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6375 (match_operand:SI 2 "const_int_operand" "n")))
6376 (clobber (match_scratch:SI 0 "=rm"))]
6377 "ix86_match_ccmode (insn, CCGCmode)
6378 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6380 switch (get_attr_type (insn))
6383 if (operands[2] == constm1_rtx)
6384 return "inc{l}\t%0";
6387 gcc_assert (operands[2] == const1_rtx);
6388 return "dec{l}\t%0";
6392 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6393 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6394 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6395 if ((INTVAL (operands[2]) == -128
6396 || (INTVAL (operands[2]) > 0
6397 && INTVAL (operands[2]) != 128)))
6398 return "sub{l}\t{%2, %0|%0, %2}";
6399 operands[2] = GEN_INT (-INTVAL (operands[2]));
6400 return "add{l}\t{%2, %0|%0, %2}";
6404 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6405 (const_string "incdec")
6406 (const_string "alu")))
6407 (set_attr "mode" "SI")])
6409 (define_insn "*addsi_5"
6410 [(set (reg FLAGS_REG)
6412 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6413 (match_operand:SI 2 "general_operand" "rmni"))
6415 (clobber (match_scratch:SI 0 "=r"))]
6416 "ix86_match_ccmode (insn, CCGOCmode)
6417 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6418 /* Current assemblers are broken and do not allow @GOTOFF in
6419 ought but a memory context. */
6420 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6422 switch (get_attr_type (insn))
6425 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6426 if (operands[2] == const1_rtx)
6427 return "inc{l}\t%0";
6430 gcc_assert (operands[2] == constm1_rtx);
6431 return "dec{l}\t%0";
6435 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6436 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6437 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6438 if (CONST_INT_P (operands[2])
6439 && (INTVAL (operands[2]) == 128
6440 || (INTVAL (operands[2]) < 0
6441 && INTVAL (operands[2]) != -128)))
6443 operands[2] = GEN_INT (-INTVAL (operands[2]));
6444 return "sub{l}\t{%2, %0|%0, %2}";
6446 return "add{l}\t{%2, %0|%0, %2}";
6450 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6451 (const_string "incdec")
6452 (const_string "alu")))
6453 (set_attr "mode" "SI")])
6455 (define_expand "addhi3"
6456 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6457 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6458 (match_operand:HI 2 "general_operand" "")))
6459 (clobber (reg:CC FLAGS_REG))])]
6460 "TARGET_HIMODE_MATH"
6461 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6463 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6464 ;; type optimizations enabled by define-splits. This is not important
6465 ;; for PII, and in fact harmful because of partial register stalls.
6467 (define_insn "*addhi_1_lea"
6468 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6469 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6470 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6471 (clobber (reg:CC FLAGS_REG))]
6472 "!TARGET_PARTIAL_REG_STALL
6473 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6475 switch (get_attr_type (insn))
6480 if (operands[2] == const1_rtx)
6481 return "inc{w}\t%0";
6484 gcc_assert (operands[2] == constm1_rtx);
6485 return "dec{w}\t%0";
6489 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6490 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6491 if (CONST_INT_P (operands[2])
6492 && (INTVAL (operands[2]) == 128
6493 || (INTVAL (operands[2]) < 0
6494 && INTVAL (operands[2]) != -128)))
6496 operands[2] = GEN_INT (-INTVAL (operands[2]));
6497 return "sub{w}\t{%2, %0|%0, %2}";
6499 return "add{w}\t{%2, %0|%0, %2}";
6503 (if_then_else (eq_attr "alternative" "2")
6504 (const_string "lea")
6505 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6506 (const_string "incdec")
6507 (const_string "alu"))))
6508 (set_attr "mode" "HI,HI,SI")])
6510 (define_insn "*addhi_1"
6511 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6512 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6513 (match_operand:HI 2 "general_operand" "ri,rm")))
6514 (clobber (reg:CC FLAGS_REG))]
6515 "TARGET_PARTIAL_REG_STALL
6516 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6518 switch (get_attr_type (insn))
6521 if (operands[2] == const1_rtx)
6522 return "inc{w}\t%0";
6525 gcc_assert (operands[2] == constm1_rtx);
6526 return "dec{w}\t%0";
6530 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6531 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6532 if (CONST_INT_P (operands[2])
6533 && (INTVAL (operands[2]) == 128
6534 || (INTVAL (operands[2]) < 0
6535 && INTVAL (operands[2]) != -128)))
6537 operands[2] = GEN_INT (-INTVAL (operands[2]));
6538 return "sub{w}\t{%2, %0|%0, %2}";
6540 return "add{w}\t{%2, %0|%0, %2}";
6544 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6545 (const_string "incdec")
6546 (const_string "alu")))
6547 (set_attr "mode" "HI")])
6549 (define_insn "*addhi_2"
6550 [(set (reg FLAGS_REG)
6552 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6553 (match_operand:HI 2 "general_operand" "rmni,rni"))
6555 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6556 (plus:HI (match_dup 1) (match_dup 2)))]
6557 "ix86_match_ccmode (insn, CCGOCmode)
6558 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6560 switch (get_attr_type (insn))
6563 if (operands[2] == const1_rtx)
6564 return "inc{w}\t%0";
6567 gcc_assert (operands[2] == constm1_rtx);
6568 return "dec{w}\t%0";
6572 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6573 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6574 if (CONST_INT_P (operands[2])
6575 && (INTVAL (operands[2]) == 128
6576 || (INTVAL (operands[2]) < 0
6577 && INTVAL (operands[2]) != -128)))
6579 operands[2] = GEN_INT (-INTVAL (operands[2]));
6580 return "sub{w}\t{%2, %0|%0, %2}";
6582 return "add{w}\t{%2, %0|%0, %2}";
6586 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6587 (const_string "incdec")
6588 (const_string "alu")))
6589 (set_attr "mode" "HI")])
6591 (define_insn "*addhi_3"
6592 [(set (reg FLAGS_REG)
6593 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6594 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6595 (clobber (match_scratch:HI 0 "=r"))]
6596 "ix86_match_ccmode (insn, CCZmode)
6597 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6599 switch (get_attr_type (insn))
6602 if (operands[2] == const1_rtx)
6603 return "inc{w}\t%0";
6606 gcc_assert (operands[2] == constm1_rtx);
6607 return "dec{w}\t%0";
6611 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6612 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6613 if (CONST_INT_P (operands[2])
6614 && (INTVAL (operands[2]) == 128
6615 || (INTVAL (operands[2]) < 0
6616 && INTVAL (operands[2]) != -128)))
6618 operands[2] = GEN_INT (-INTVAL (operands[2]));
6619 return "sub{w}\t{%2, %0|%0, %2}";
6621 return "add{w}\t{%2, %0|%0, %2}";
6625 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6626 (const_string "incdec")
6627 (const_string "alu")))
6628 (set_attr "mode" "HI")])
6630 ; See comments above addsi_4 for details.
6631 (define_insn "*addhi_4"
6632 [(set (reg FLAGS_REG)
6633 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6634 (match_operand:HI 2 "const_int_operand" "n")))
6635 (clobber (match_scratch:HI 0 "=rm"))]
6636 "ix86_match_ccmode (insn, CCGCmode)
6637 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6639 switch (get_attr_type (insn))
6642 if (operands[2] == constm1_rtx)
6643 return "inc{w}\t%0";
6646 gcc_assert (operands[2] == const1_rtx);
6647 return "dec{w}\t%0";
6651 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6652 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6653 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6654 if ((INTVAL (operands[2]) == -128
6655 || (INTVAL (operands[2]) > 0
6656 && INTVAL (operands[2]) != 128)))
6657 return "sub{w}\t{%2, %0|%0, %2}";
6658 operands[2] = GEN_INT (-INTVAL (operands[2]));
6659 return "add{w}\t{%2, %0|%0, %2}";
6663 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6664 (const_string "incdec")
6665 (const_string "alu")))
6666 (set_attr "mode" "SI")])
6669 (define_insn "*addhi_5"
6670 [(set (reg FLAGS_REG)
6672 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6673 (match_operand:HI 2 "general_operand" "rmni"))
6675 (clobber (match_scratch:HI 0 "=r"))]
6676 "ix86_match_ccmode (insn, CCGOCmode)
6677 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6679 switch (get_attr_type (insn))
6682 if (operands[2] == const1_rtx)
6683 return "inc{w}\t%0";
6686 gcc_assert (operands[2] == constm1_rtx);
6687 return "dec{w}\t%0";
6691 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6692 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6693 if (CONST_INT_P (operands[2])
6694 && (INTVAL (operands[2]) == 128
6695 || (INTVAL (operands[2]) < 0
6696 && INTVAL (operands[2]) != -128)))
6698 operands[2] = GEN_INT (-INTVAL (operands[2]));
6699 return "sub{w}\t{%2, %0|%0, %2}";
6701 return "add{w}\t{%2, %0|%0, %2}";
6705 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6706 (const_string "incdec")
6707 (const_string "alu")))
6708 (set_attr "mode" "HI")])
6710 (define_expand "addqi3"
6711 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6712 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6713 (match_operand:QI 2 "general_operand" "")))
6714 (clobber (reg:CC FLAGS_REG))])]
6715 "TARGET_QIMODE_MATH"
6716 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6718 ;; %%% Potential partial reg stall on alternative 2. What to do?
6719 (define_insn "*addqi_1_lea"
6720 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6721 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6722 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6723 (clobber (reg:CC FLAGS_REG))]
6724 "!TARGET_PARTIAL_REG_STALL
6725 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6727 int widen = (which_alternative == 2);
6728 switch (get_attr_type (insn))
6733 if (operands[2] == const1_rtx)
6734 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6737 gcc_assert (operands[2] == constm1_rtx);
6738 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6742 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6743 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6744 if (CONST_INT_P (operands[2])
6745 && (INTVAL (operands[2]) == 128
6746 || (INTVAL (operands[2]) < 0
6747 && INTVAL (operands[2]) != -128)))
6749 operands[2] = GEN_INT (-INTVAL (operands[2]));
6751 return "sub{l}\t{%2, %k0|%k0, %2}";
6753 return "sub{b}\t{%2, %0|%0, %2}";
6756 return "add{l}\t{%k2, %k0|%k0, %k2}";
6758 return "add{b}\t{%2, %0|%0, %2}";
6762 (if_then_else (eq_attr "alternative" "3")
6763 (const_string "lea")
6764 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6765 (const_string "incdec")
6766 (const_string "alu"))))
6767 (set_attr "mode" "QI,QI,SI,SI")])
6769 (define_insn "*addqi_1"
6770 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6771 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6772 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6773 (clobber (reg:CC FLAGS_REG))]
6774 "TARGET_PARTIAL_REG_STALL
6775 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6777 int widen = (which_alternative == 2);
6778 switch (get_attr_type (insn))
6781 if (operands[2] == const1_rtx)
6782 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6785 gcc_assert (operands[2] == constm1_rtx);
6786 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6790 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6791 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6792 if (CONST_INT_P (operands[2])
6793 && (INTVAL (operands[2]) == 128
6794 || (INTVAL (operands[2]) < 0
6795 && INTVAL (operands[2]) != -128)))
6797 operands[2] = GEN_INT (-INTVAL (operands[2]));
6799 return "sub{l}\t{%2, %k0|%k0, %2}";
6801 return "sub{b}\t{%2, %0|%0, %2}";
6804 return "add{l}\t{%k2, %k0|%k0, %k2}";
6806 return "add{b}\t{%2, %0|%0, %2}";
6810 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6811 (const_string "incdec")
6812 (const_string "alu")))
6813 (set_attr "mode" "QI,QI,SI")])
6815 (define_insn "*addqi_1_slp"
6816 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6817 (plus:QI (match_dup 0)
6818 (match_operand:QI 1 "general_operand" "qn,qnm")))
6819 (clobber (reg:CC FLAGS_REG))]
6820 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6821 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6823 switch (get_attr_type (insn))
6826 if (operands[1] == const1_rtx)
6827 return "inc{b}\t%0";
6830 gcc_assert (operands[1] == constm1_rtx);
6831 return "dec{b}\t%0";
6835 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6836 if (CONST_INT_P (operands[1])
6837 && INTVAL (operands[1]) < 0)
6839 operands[1] = GEN_INT (-INTVAL (operands[1]));
6840 return "sub{b}\t{%1, %0|%0, %1}";
6842 return "add{b}\t{%1, %0|%0, %1}";
6846 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6847 (const_string "incdec")
6848 (const_string "alu1")))
6849 (set (attr "memory")
6850 (if_then_else (match_operand 1 "memory_operand" "")
6851 (const_string "load")
6852 (const_string "none")))
6853 (set_attr "mode" "QI")])
6855 (define_insn "*addqi_2"
6856 [(set (reg FLAGS_REG)
6858 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6859 (match_operand:QI 2 "general_operand" "qmni,qni"))
6861 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6862 (plus:QI (match_dup 1) (match_dup 2)))]
6863 "ix86_match_ccmode (insn, CCGOCmode)
6864 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6866 switch (get_attr_type (insn))
6869 if (operands[2] == const1_rtx)
6870 return "inc{b}\t%0";
6873 gcc_assert (operands[2] == constm1_rtx
6874 || (CONST_INT_P (operands[2])
6875 && INTVAL (operands[2]) == 255));
6876 return "dec{b}\t%0";
6880 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6881 if (CONST_INT_P (operands[2])
6882 && INTVAL (operands[2]) < 0)
6884 operands[2] = GEN_INT (-INTVAL (operands[2]));
6885 return "sub{b}\t{%2, %0|%0, %2}";
6887 return "add{b}\t{%2, %0|%0, %2}";
6891 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6892 (const_string "incdec")
6893 (const_string "alu")))
6894 (set_attr "mode" "QI")])
6896 (define_insn "*addqi_3"
6897 [(set (reg FLAGS_REG)
6898 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6899 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6900 (clobber (match_scratch:QI 0 "=q"))]
6901 "ix86_match_ccmode (insn, CCZmode)
6902 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6904 switch (get_attr_type (insn))
6907 if (operands[2] == const1_rtx)
6908 return "inc{b}\t%0";
6911 gcc_assert (operands[2] == constm1_rtx
6912 || (CONST_INT_P (operands[2])
6913 && INTVAL (operands[2]) == 255));
6914 return "dec{b}\t%0";
6918 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6919 if (CONST_INT_P (operands[2])
6920 && INTVAL (operands[2]) < 0)
6922 operands[2] = GEN_INT (-INTVAL (operands[2]));
6923 return "sub{b}\t{%2, %0|%0, %2}";
6925 return "add{b}\t{%2, %0|%0, %2}";
6929 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6930 (const_string "incdec")
6931 (const_string "alu")))
6932 (set_attr "mode" "QI")])
6934 ; See comments above addsi_4 for details.
6935 (define_insn "*addqi_4"
6936 [(set (reg FLAGS_REG)
6937 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6938 (match_operand:QI 2 "const_int_operand" "n")))
6939 (clobber (match_scratch:QI 0 "=qm"))]
6940 "ix86_match_ccmode (insn, CCGCmode)
6941 && (INTVAL (operands[2]) & 0xff) != 0x80"
6943 switch (get_attr_type (insn))
6946 if (operands[2] == constm1_rtx
6947 || (CONST_INT_P (operands[2])
6948 && INTVAL (operands[2]) == 255))
6949 return "inc{b}\t%0";
6952 gcc_assert (operands[2] == const1_rtx);
6953 return "dec{b}\t%0";
6957 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6958 if (INTVAL (operands[2]) < 0)
6960 operands[2] = GEN_INT (-INTVAL (operands[2]));
6961 return "add{b}\t{%2, %0|%0, %2}";
6963 return "sub{b}\t{%2, %0|%0, %2}";
6967 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6968 (const_string "incdec")
6969 (const_string "alu")))
6970 (set_attr "mode" "QI")])
6973 (define_insn "*addqi_5"
6974 [(set (reg FLAGS_REG)
6976 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6977 (match_operand:QI 2 "general_operand" "qmni"))
6979 (clobber (match_scratch:QI 0 "=q"))]
6980 "ix86_match_ccmode (insn, CCGOCmode)
6981 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6983 switch (get_attr_type (insn))
6986 if (operands[2] == const1_rtx)
6987 return "inc{b}\t%0";
6990 gcc_assert (operands[2] == constm1_rtx
6991 || (CONST_INT_P (operands[2])
6992 && INTVAL (operands[2]) == 255));
6993 return "dec{b}\t%0";
6997 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6998 if (CONST_INT_P (operands[2])
6999 && INTVAL (operands[2]) < 0)
7001 operands[2] = GEN_INT (-INTVAL (operands[2]));
7002 return "sub{b}\t{%2, %0|%0, %2}";
7004 return "add{b}\t{%2, %0|%0, %2}";
7008 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7009 (const_string "incdec")
7010 (const_string "alu")))
7011 (set_attr "mode" "QI")])
7014 (define_insn "addqi_ext_1"
7015 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7020 (match_operand 1 "ext_register_operand" "0")
7023 (match_operand:QI 2 "general_operand" "Qmn")))
7024 (clobber (reg:CC FLAGS_REG))]
7027 switch (get_attr_type (insn))
7030 if (operands[2] == const1_rtx)
7031 return "inc{b}\t%h0";
7034 gcc_assert (operands[2] == constm1_rtx
7035 || (CONST_INT_P (operands[2])
7036 && INTVAL (operands[2]) == 255));
7037 return "dec{b}\t%h0";
7041 return "add{b}\t{%2, %h0|%h0, %2}";
7045 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7046 (const_string "incdec")
7047 (const_string "alu")))
7048 (set_attr "mode" "QI")])
7050 (define_insn "*addqi_ext_1_rex64"
7051 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7056 (match_operand 1 "ext_register_operand" "0")
7059 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7060 (clobber (reg:CC FLAGS_REG))]
7063 switch (get_attr_type (insn))
7066 if (operands[2] == const1_rtx)
7067 return "inc{b}\t%h0";
7070 gcc_assert (operands[2] == constm1_rtx
7071 || (CONST_INT_P (operands[2])
7072 && INTVAL (operands[2]) == 255));
7073 return "dec{b}\t%h0";
7077 return "add{b}\t{%2, %h0|%h0, %2}";
7081 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7082 (const_string "incdec")
7083 (const_string "alu")))
7084 (set_attr "mode" "QI")])
7086 (define_insn "*addqi_ext_2"
7087 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7092 (match_operand 1 "ext_register_operand" "%0")
7096 (match_operand 2 "ext_register_operand" "Q")
7099 (clobber (reg:CC FLAGS_REG))]
7101 "add{b}\t{%h2, %h0|%h0, %h2}"
7102 [(set_attr "type" "alu")
7103 (set_attr "mode" "QI")])
7105 ;; The patterns that match these are at the end of this file.
7107 (define_expand "addxf3"
7108 [(set (match_operand:XF 0 "register_operand" "")
7109 (plus:XF (match_operand:XF 1 "register_operand" "")
7110 (match_operand:XF 2 "register_operand" "")))]
7114 (define_expand "add<mode>3"
7115 [(set (match_operand:MODEF 0 "register_operand" "")
7116 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7117 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7118 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7121 ;; Subtract instructions
7123 ;; %%% splits for subditi3
7125 (define_expand "subti3"
7126 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7127 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7128 (match_operand:TI 2 "x86_64_general_operand" "")))
7129 (clobber (reg:CC FLAGS_REG))])]
7131 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7133 (define_insn "*subti3_1"
7134 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7135 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7136 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7137 (clobber (reg:CC FLAGS_REG))]
7138 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7142 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7143 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7144 (match_operand:TI 2 "x86_64_general_operand" "")))
7145 (clobber (reg:CC FLAGS_REG))]
7146 "TARGET_64BIT && reload_completed"
7147 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7148 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7149 (parallel [(set (match_dup 3)
7150 (minus:DI (match_dup 4)
7151 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7153 (clobber (reg:CC FLAGS_REG))])]
7154 "split_ti (operands+0, 1, operands+0, operands+3);
7155 split_ti (operands+1, 1, operands+1, operands+4);
7156 split_ti (operands+2, 1, operands+2, operands+5);")
7158 ;; %%% splits for subsidi3
7160 (define_expand "subdi3"
7161 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7162 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7163 (match_operand:DI 2 "x86_64_general_operand" "")))
7164 (clobber (reg:CC FLAGS_REG))])]
7166 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7168 (define_insn "*subdi3_1"
7169 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7170 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7171 (match_operand:DI 2 "general_operand" "roiF,riF")))
7172 (clobber (reg:CC FLAGS_REG))]
7173 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7177 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7178 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7179 (match_operand:DI 2 "general_operand" "")))
7180 (clobber (reg:CC FLAGS_REG))]
7181 "!TARGET_64BIT && reload_completed"
7182 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7183 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7184 (parallel [(set (match_dup 3)
7185 (minus:SI (match_dup 4)
7186 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7188 (clobber (reg:CC FLAGS_REG))])]
7189 "split_di (operands+0, 1, operands+0, operands+3);
7190 split_di (operands+1, 1, operands+1, operands+4);
7191 split_di (operands+2, 1, operands+2, operands+5);")
7193 (define_insn "subdi3_carry_rex64"
7194 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7195 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7196 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7197 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7198 (clobber (reg:CC FLAGS_REG))]
7199 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7200 "sbb{q}\t{%2, %0|%0, %2}"
7201 [(set_attr "type" "alu")
7202 (set_attr "pent_pair" "pu")
7203 (set_attr "mode" "DI")])
7205 (define_insn "*subdi_1_rex64"
7206 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7207 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7208 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7209 (clobber (reg:CC FLAGS_REG))]
7210 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7211 "sub{q}\t{%2, %0|%0, %2}"
7212 [(set_attr "type" "alu")
7213 (set_attr "mode" "DI")])
7215 (define_insn "*subdi_2_rex64"
7216 [(set (reg FLAGS_REG)
7218 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7219 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7221 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7222 (minus:DI (match_dup 1) (match_dup 2)))]
7223 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7224 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7225 "sub{q}\t{%2, %0|%0, %2}"
7226 [(set_attr "type" "alu")
7227 (set_attr "mode" "DI")])
7229 (define_insn "*subdi_3_rex63"
7230 [(set (reg FLAGS_REG)
7231 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7232 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7233 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7234 (minus:DI (match_dup 1) (match_dup 2)))]
7235 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7236 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7237 "sub{q}\t{%2, %0|%0, %2}"
7238 [(set_attr "type" "alu")
7239 (set_attr "mode" "DI")])
7241 (define_insn "subqi3_carry"
7242 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7243 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7244 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7245 (match_operand:QI 2 "general_operand" "qi,qm"))))
7246 (clobber (reg:CC FLAGS_REG))]
7247 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7248 "sbb{b}\t{%2, %0|%0, %2}"
7249 [(set_attr "type" "alu")
7250 (set_attr "pent_pair" "pu")
7251 (set_attr "mode" "QI")])
7253 (define_insn "subhi3_carry"
7254 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7255 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7256 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7257 (match_operand:HI 2 "general_operand" "ri,rm"))))
7258 (clobber (reg:CC FLAGS_REG))]
7259 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7260 "sbb{w}\t{%2, %0|%0, %2}"
7261 [(set_attr "type" "alu")
7262 (set_attr "pent_pair" "pu")
7263 (set_attr "mode" "HI")])
7265 (define_insn "subsi3_carry"
7266 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7267 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7268 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7269 (match_operand:SI 2 "general_operand" "ri,rm"))))
7270 (clobber (reg:CC FLAGS_REG))]
7271 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7272 "sbb{l}\t{%2, %0|%0, %2}"
7273 [(set_attr "type" "alu")
7274 (set_attr "pent_pair" "pu")
7275 (set_attr "mode" "SI")])
7277 (define_insn "subsi3_carry_zext"
7278 [(set (match_operand:DI 0 "register_operand" "=r")
7280 (minus:SI (match_operand:SI 1 "register_operand" "0")
7281 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7282 (match_operand:SI 2 "general_operand" "g")))))
7283 (clobber (reg:CC FLAGS_REG))]
7284 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7285 "sbb{l}\t{%2, %k0|%k0, %2}"
7286 [(set_attr "type" "alu")
7287 (set_attr "pent_pair" "pu")
7288 (set_attr "mode" "SI")])
7290 (define_expand "subsi3"
7291 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7292 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7293 (match_operand:SI 2 "general_operand" "")))
7294 (clobber (reg:CC FLAGS_REG))])]
7296 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7298 (define_insn "*subsi_1"
7299 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7300 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7301 (match_operand:SI 2 "general_operand" "ri,rm")))
7302 (clobber (reg:CC FLAGS_REG))]
7303 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7304 "sub{l}\t{%2, %0|%0, %2}"
7305 [(set_attr "type" "alu")
7306 (set_attr "mode" "SI")])
7308 (define_insn "*subsi_1_zext"
7309 [(set (match_operand:DI 0 "register_operand" "=r")
7311 (minus:SI (match_operand:SI 1 "register_operand" "0")
7312 (match_operand:SI 2 "general_operand" "g"))))
7313 (clobber (reg:CC FLAGS_REG))]
7314 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7315 "sub{l}\t{%2, %k0|%k0, %2}"
7316 [(set_attr "type" "alu")
7317 (set_attr "mode" "SI")])
7319 (define_insn "*subsi_2"
7320 [(set (reg FLAGS_REG)
7322 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7323 (match_operand:SI 2 "general_operand" "ri,rm"))
7325 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7326 (minus:SI (match_dup 1) (match_dup 2)))]
7327 "ix86_match_ccmode (insn, CCGOCmode)
7328 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7329 "sub{l}\t{%2, %0|%0, %2}"
7330 [(set_attr "type" "alu")
7331 (set_attr "mode" "SI")])
7333 (define_insn "*subsi_2_zext"
7334 [(set (reg FLAGS_REG)
7336 (minus:SI (match_operand:SI 1 "register_operand" "0")
7337 (match_operand:SI 2 "general_operand" "g"))
7339 (set (match_operand:DI 0 "register_operand" "=r")
7341 (minus:SI (match_dup 1)
7343 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7344 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7345 "sub{l}\t{%2, %k0|%k0, %2}"
7346 [(set_attr "type" "alu")
7347 (set_attr "mode" "SI")])
7349 (define_insn "*subsi_3"
7350 [(set (reg FLAGS_REG)
7351 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7352 (match_operand:SI 2 "general_operand" "ri,rm")))
7353 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7354 (minus:SI (match_dup 1) (match_dup 2)))]
7355 "ix86_match_ccmode (insn, CCmode)
7356 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7357 "sub{l}\t{%2, %0|%0, %2}"
7358 [(set_attr "type" "alu")
7359 (set_attr "mode" "SI")])
7361 (define_insn "*subsi_3_zext"
7362 [(set (reg FLAGS_REG)
7363 (compare (match_operand:SI 1 "register_operand" "0")
7364 (match_operand:SI 2 "general_operand" "g")))
7365 (set (match_operand:DI 0 "register_operand" "=r")
7367 (minus:SI (match_dup 1)
7369 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7370 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7371 "sub{l}\t{%2, %1|%1, %2}"
7372 [(set_attr "type" "alu")
7373 (set_attr "mode" "DI")])
7375 (define_expand "subhi3"
7376 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7377 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7378 (match_operand:HI 2 "general_operand" "")))
7379 (clobber (reg:CC FLAGS_REG))])]
7380 "TARGET_HIMODE_MATH"
7381 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7383 (define_insn "*subhi_1"
7384 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7385 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7386 (match_operand:HI 2 "general_operand" "ri,rm")))
7387 (clobber (reg:CC FLAGS_REG))]
7388 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7389 "sub{w}\t{%2, %0|%0, %2}"
7390 [(set_attr "type" "alu")
7391 (set_attr "mode" "HI")])
7393 (define_insn "*subhi_2"
7394 [(set (reg FLAGS_REG)
7396 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7397 (match_operand:HI 2 "general_operand" "ri,rm"))
7399 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7400 (minus:HI (match_dup 1) (match_dup 2)))]
7401 "ix86_match_ccmode (insn, CCGOCmode)
7402 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7403 "sub{w}\t{%2, %0|%0, %2}"
7404 [(set_attr "type" "alu")
7405 (set_attr "mode" "HI")])
7407 (define_insn "*subhi_3"
7408 [(set (reg FLAGS_REG)
7409 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7410 (match_operand:HI 2 "general_operand" "ri,rm")))
7411 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7412 (minus:HI (match_dup 1) (match_dup 2)))]
7413 "ix86_match_ccmode (insn, CCmode)
7414 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7415 "sub{w}\t{%2, %0|%0, %2}"
7416 [(set_attr "type" "alu")
7417 (set_attr "mode" "HI")])
7419 (define_expand "subqi3"
7420 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7421 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7422 (match_operand:QI 2 "general_operand" "")))
7423 (clobber (reg:CC FLAGS_REG))])]
7424 "TARGET_QIMODE_MATH"
7425 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7427 (define_insn "*subqi_1"
7428 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7429 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7430 (match_operand:QI 2 "general_operand" "qn,qmn")))
7431 (clobber (reg:CC FLAGS_REG))]
7432 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7433 "sub{b}\t{%2, %0|%0, %2}"
7434 [(set_attr "type" "alu")
7435 (set_attr "mode" "QI")])
7437 (define_insn "*subqi_1_slp"
7438 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7439 (minus:QI (match_dup 0)
7440 (match_operand:QI 1 "general_operand" "qn,qmn")))
7441 (clobber (reg:CC FLAGS_REG))]
7442 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7443 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7444 "sub{b}\t{%1, %0|%0, %1}"
7445 [(set_attr "type" "alu1")
7446 (set_attr "mode" "QI")])
7448 (define_insn "*subqi_2"
7449 [(set (reg FLAGS_REG)
7451 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7452 (match_operand:QI 2 "general_operand" "qi,qm"))
7454 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7455 (minus:HI (match_dup 1) (match_dup 2)))]
7456 "ix86_match_ccmode (insn, CCGOCmode)
7457 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7458 "sub{b}\t{%2, %0|%0, %2}"
7459 [(set_attr "type" "alu")
7460 (set_attr "mode" "QI")])
7462 (define_insn "*subqi_3"
7463 [(set (reg FLAGS_REG)
7464 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7465 (match_operand:QI 2 "general_operand" "qi,qm")))
7466 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7467 (minus:HI (match_dup 1) (match_dup 2)))]
7468 "ix86_match_ccmode (insn, CCmode)
7469 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7470 "sub{b}\t{%2, %0|%0, %2}"
7471 [(set_attr "type" "alu")
7472 (set_attr "mode" "QI")])
7474 ;; The patterns that match these are at the end of this file.
7476 (define_expand "subxf3"
7477 [(set (match_operand:XF 0 "register_operand" "")
7478 (minus:XF (match_operand:XF 1 "register_operand" "")
7479 (match_operand:XF 2 "register_operand" "")))]
7483 (define_expand "sub<mode>3"
7484 [(set (match_operand:MODEF 0 "register_operand" "")
7485 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7486 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7487 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7490 ;; Multiply instructions
7492 (define_expand "muldi3"
7493 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7494 (mult:DI (match_operand:DI 1 "register_operand" "")
7495 (match_operand:DI 2 "x86_64_general_operand" "")))
7496 (clobber (reg:CC FLAGS_REG))])]
7501 ;; IMUL reg64, reg64, imm8 Direct
7502 ;; IMUL reg64, mem64, imm8 VectorPath
7503 ;; IMUL reg64, reg64, imm32 Direct
7504 ;; IMUL reg64, mem64, imm32 VectorPath
7505 ;; IMUL reg64, reg64 Direct
7506 ;; IMUL reg64, mem64 Direct
7508 (define_insn "*muldi3_1_rex64"
7509 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7510 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7511 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7512 (clobber (reg:CC FLAGS_REG))]
7514 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7516 imul{q}\t{%2, %1, %0|%0, %1, %2}
7517 imul{q}\t{%2, %1, %0|%0, %1, %2}
7518 imul{q}\t{%2, %0|%0, %2}"
7519 [(set_attr "type" "imul")
7520 (set_attr "prefix_0f" "0,0,1")
7521 (set (attr "athlon_decode")
7522 (cond [(eq_attr "cpu" "athlon")
7523 (const_string "vector")
7524 (eq_attr "alternative" "1")
7525 (const_string "vector")
7526 (and (eq_attr "alternative" "2")
7527 (match_operand 1 "memory_operand" ""))
7528 (const_string "vector")]
7529 (const_string "direct")))
7530 (set (attr "amdfam10_decode")
7531 (cond [(and (eq_attr "alternative" "0,1")
7532 (match_operand 1 "memory_operand" ""))
7533 (const_string "vector")]
7534 (const_string "direct")))
7535 (set_attr "mode" "DI")])
7537 (define_expand "mulsi3"
7538 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7539 (mult:SI (match_operand:SI 1 "register_operand" "")
7540 (match_operand:SI 2 "general_operand" "")))
7541 (clobber (reg:CC FLAGS_REG))])]
7546 ;; IMUL reg32, reg32, imm8 Direct
7547 ;; IMUL reg32, mem32, imm8 VectorPath
7548 ;; IMUL reg32, reg32, imm32 Direct
7549 ;; IMUL reg32, mem32, imm32 VectorPath
7550 ;; IMUL reg32, reg32 Direct
7551 ;; IMUL reg32, mem32 Direct
7553 (define_insn "*mulsi3_1"
7554 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7555 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7556 (match_operand:SI 2 "general_operand" "K,i,mr")))
7557 (clobber (reg:CC FLAGS_REG))]
7558 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7560 imul{l}\t{%2, %1, %0|%0, %1, %2}
7561 imul{l}\t{%2, %1, %0|%0, %1, %2}
7562 imul{l}\t{%2, %0|%0, %2}"
7563 [(set_attr "type" "imul")
7564 (set_attr "prefix_0f" "0,0,1")
7565 (set (attr "athlon_decode")
7566 (cond [(eq_attr "cpu" "athlon")
7567 (const_string "vector")
7568 (eq_attr "alternative" "1")
7569 (const_string "vector")
7570 (and (eq_attr "alternative" "2")
7571 (match_operand 1 "memory_operand" ""))
7572 (const_string "vector")]
7573 (const_string "direct")))
7574 (set (attr "amdfam10_decode")
7575 (cond [(and (eq_attr "alternative" "0,1")
7576 (match_operand 1 "memory_operand" ""))
7577 (const_string "vector")]
7578 (const_string "direct")))
7579 (set_attr "mode" "SI")])
7581 (define_insn "*mulsi3_1_zext"
7582 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7584 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7585 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7586 (clobber (reg:CC FLAGS_REG))]
7588 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7590 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7591 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7592 imul{l}\t{%2, %k0|%k0, %2}"
7593 [(set_attr "type" "imul")
7594 (set_attr "prefix_0f" "0,0,1")
7595 (set (attr "athlon_decode")
7596 (cond [(eq_attr "cpu" "athlon")
7597 (const_string "vector")
7598 (eq_attr "alternative" "1")
7599 (const_string "vector")
7600 (and (eq_attr "alternative" "2")
7601 (match_operand 1 "memory_operand" ""))
7602 (const_string "vector")]
7603 (const_string "direct")))
7604 (set (attr "amdfam10_decode")
7605 (cond [(and (eq_attr "alternative" "0,1")
7606 (match_operand 1 "memory_operand" ""))
7607 (const_string "vector")]
7608 (const_string "direct")))
7609 (set_attr "mode" "SI")])
7611 (define_expand "mulhi3"
7612 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7613 (mult:HI (match_operand:HI 1 "register_operand" "")
7614 (match_operand:HI 2 "general_operand" "")))
7615 (clobber (reg:CC FLAGS_REG))])]
7616 "TARGET_HIMODE_MATH"
7620 ;; IMUL reg16, reg16, imm8 VectorPath
7621 ;; IMUL reg16, mem16, imm8 VectorPath
7622 ;; IMUL reg16, reg16, imm16 VectorPath
7623 ;; IMUL reg16, mem16, imm16 VectorPath
7624 ;; IMUL reg16, reg16 Direct
7625 ;; IMUL reg16, mem16 Direct
7626 (define_insn "*mulhi3_1"
7627 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7628 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7629 (match_operand:HI 2 "general_operand" "K,i,mr")))
7630 (clobber (reg:CC FLAGS_REG))]
7631 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7633 imul{w}\t{%2, %1, %0|%0, %1, %2}
7634 imul{w}\t{%2, %1, %0|%0, %1, %2}
7635 imul{w}\t{%2, %0|%0, %2}"
7636 [(set_attr "type" "imul")
7637 (set_attr "prefix_0f" "0,0,1")
7638 (set (attr "athlon_decode")
7639 (cond [(eq_attr "cpu" "athlon")
7640 (const_string "vector")
7641 (eq_attr "alternative" "1,2")
7642 (const_string "vector")]
7643 (const_string "direct")))
7644 (set (attr "amdfam10_decode")
7645 (cond [(eq_attr "alternative" "0,1")
7646 (const_string "vector")]
7647 (const_string "direct")))
7648 (set_attr "mode" "HI")])
7650 (define_expand "mulqi3"
7651 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7652 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7653 (match_operand:QI 2 "register_operand" "")))
7654 (clobber (reg:CC FLAGS_REG))])]
7655 "TARGET_QIMODE_MATH"
7662 (define_insn "*mulqi3_1"
7663 [(set (match_operand:QI 0 "register_operand" "=a")
7664 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7665 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7666 (clobber (reg:CC FLAGS_REG))]
7668 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7670 [(set_attr "type" "imul")
7671 (set_attr "length_immediate" "0")
7672 (set (attr "athlon_decode")
7673 (if_then_else (eq_attr "cpu" "athlon")
7674 (const_string "vector")
7675 (const_string "direct")))
7676 (set_attr "amdfam10_decode" "direct")
7677 (set_attr "mode" "QI")])
7679 (define_expand "umulqihi3"
7680 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7681 (mult:HI (zero_extend:HI
7682 (match_operand:QI 1 "nonimmediate_operand" ""))
7684 (match_operand:QI 2 "register_operand" ""))))
7685 (clobber (reg:CC FLAGS_REG))])]
7686 "TARGET_QIMODE_MATH"
7689 (define_insn "*umulqihi3_1"
7690 [(set (match_operand:HI 0 "register_operand" "=a")
7691 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7692 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7693 (clobber (reg:CC FLAGS_REG))]
7695 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7697 [(set_attr "type" "imul")
7698 (set_attr "length_immediate" "0")
7699 (set (attr "athlon_decode")
7700 (if_then_else (eq_attr "cpu" "athlon")
7701 (const_string "vector")
7702 (const_string "direct")))
7703 (set_attr "amdfam10_decode" "direct")
7704 (set_attr "mode" "QI")])
7706 (define_expand "mulqihi3"
7707 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7708 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7709 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7710 (clobber (reg:CC FLAGS_REG))])]
7711 "TARGET_QIMODE_MATH"
7714 (define_insn "*mulqihi3_insn"
7715 [(set (match_operand:HI 0 "register_operand" "=a")
7716 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7717 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7718 (clobber (reg:CC FLAGS_REG))]
7720 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7722 [(set_attr "type" "imul")
7723 (set_attr "length_immediate" "0")
7724 (set (attr "athlon_decode")
7725 (if_then_else (eq_attr "cpu" "athlon")
7726 (const_string "vector")
7727 (const_string "direct")))
7728 (set_attr "amdfam10_decode" "direct")
7729 (set_attr "mode" "QI")])
7731 (define_expand "umulditi3"
7732 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7733 (mult:TI (zero_extend:TI
7734 (match_operand:DI 1 "nonimmediate_operand" ""))
7736 (match_operand:DI 2 "register_operand" ""))))
7737 (clobber (reg:CC FLAGS_REG))])]
7741 (define_insn "*umulditi3_insn"
7742 [(set (match_operand:TI 0 "register_operand" "=A")
7743 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7744 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7745 (clobber (reg:CC FLAGS_REG))]
7747 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7749 [(set_attr "type" "imul")
7750 (set_attr "length_immediate" "0")
7751 (set (attr "athlon_decode")
7752 (if_then_else (eq_attr "cpu" "athlon")
7753 (const_string "vector")
7754 (const_string "double")))
7755 (set_attr "amdfam10_decode" "double")
7756 (set_attr "mode" "DI")])
7758 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7759 (define_expand "umulsidi3"
7760 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7761 (mult:DI (zero_extend:DI
7762 (match_operand:SI 1 "nonimmediate_operand" ""))
7764 (match_operand:SI 2 "register_operand" ""))))
7765 (clobber (reg:CC FLAGS_REG))])]
7769 (define_insn "*umulsidi3_insn"
7770 [(set (match_operand:DI 0 "register_operand" "=A")
7771 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7772 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7773 (clobber (reg:CC FLAGS_REG))]
7775 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7777 [(set_attr "type" "imul")
7778 (set_attr "length_immediate" "0")
7779 (set (attr "athlon_decode")
7780 (if_then_else (eq_attr "cpu" "athlon")
7781 (const_string "vector")
7782 (const_string "double")))
7783 (set_attr "amdfam10_decode" "double")
7784 (set_attr "mode" "SI")])
7786 (define_expand "mulditi3"
7787 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7788 (mult:TI (sign_extend:TI
7789 (match_operand:DI 1 "nonimmediate_operand" ""))
7791 (match_operand:DI 2 "register_operand" ""))))
7792 (clobber (reg:CC FLAGS_REG))])]
7796 (define_insn "*mulditi3_insn"
7797 [(set (match_operand:TI 0 "register_operand" "=A")
7798 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7799 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7800 (clobber (reg:CC FLAGS_REG))]
7802 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7804 [(set_attr "type" "imul")
7805 (set_attr "length_immediate" "0")
7806 (set (attr "athlon_decode")
7807 (if_then_else (eq_attr "cpu" "athlon")
7808 (const_string "vector")
7809 (const_string "double")))
7810 (set_attr "amdfam10_decode" "double")
7811 (set_attr "mode" "DI")])
7813 (define_expand "mulsidi3"
7814 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7815 (mult:DI (sign_extend:DI
7816 (match_operand:SI 1 "nonimmediate_operand" ""))
7818 (match_operand:SI 2 "register_operand" ""))))
7819 (clobber (reg:CC FLAGS_REG))])]
7823 (define_insn "*mulsidi3_insn"
7824 [(set (match_operand:DI 0 "register_operand" "=A")
7825 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7826 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7827 (clobber (reg:CC FLAGS_REG))]
7829 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7831 [(set_attr "type" "imul")
7832 (set_attr "length_immediate" "0")
7833 (set (attr "athlon_decode")
7834 (if_then_else (eq_attr "cpu" "athlon")
7835 (const_string "vector")
7836 (const_string "double")))
7837 (set_attr "amdfam10_decode" "double")
7838 (set_attr "mode" "SI")])
7840 (define_expand "umuldi3_highpart"
7841 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7844 (mult:TI (zero_extend:TI
7845 (match_operand:DI 1 "nonimmediate_operand" ""))
7847 (match_operand:DI 2 "register_operand" "")))
7849 (clobber (match_scratch:DI 3 ""))
7850 (clobber (reg:CC FLAGS_REG))])]
7854 (define_insn "*umuldi3_highpart_rex64"
7855 [(set (match_operand:DI 0 "register_operand" "=d")
7858 (mult:TI (zero_extend:TI
7859 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7861 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7863 (clobber (match_scratch:DI 3 "=1"))
7864 (clobber (reg:CC FLAGS_REG))]
7866 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7868 [(set_attr "type" "imul")
7869 (set_attr "length_immediate" "0")
7870 (set (attr "athlon_decode")
7871 (if_then_else (eq_attr "cpu" "athlon")
7872 (const_string "vector")
7873 (const_string "double")))
7874 (set_attr "amdfam10_decode" "double")
7875 (set_attr "mode" "DI")])
7877 (define_expand "umulsi3_highpart"
7878 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7881 (mult:DI (zero_extend:DI
7882 (match_operand:SI 1 "nonimmediate_operand" ""))
7884 (match_operand:SI 2 "register_operand" "")))
7886 (clobber (match_scratch:SI 3 ""))
7887 (clobber (reg:CC FLAGS_REG))])]
7891 (define_insn "*umulsi3_highpart_insn"
7892 [(set (match_operand:SI 0 "register_operand" "=d")
7895 (mult:DI (zero_extend:DI
7896 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7898 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7900 (clobber (match_scratch:SI 3 "=1"))
7901 (clobber (reg:CC FLAGS_REG))]
7902 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7904 [(set_attr "type" "imul")
7905 (set_attr "length_immediate" "0")
7906 (set (attr "athlon_decode")
7907 (if_then_else (eq_attr "cpu" "athlon")
7908 (const_string "vector")
7909 (const_string "double")))
7910 (set_attr "amdfam10_decode" "double")
7911 (set_attr "mode" "SI")])
7913 (define_insn "*umulsi3_highpart_zext"
7914 [(set (match_operand:DI 0 "register_operand" "=d")
7915 (zero_extend:DI (truncate:SI
7917 (mult:DI (zero_extend:DI
7918 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7920 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7922 (clobber (match_scratch:SI 3 "=1"))
7923 (clobber (reg:CC FLAGS_REG))]
7925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7927 [(set_attr "type" "imul")
7928 (set_attr "length_immediate" "0")
7929 (set (attr "athlon_decode")
7930 (if_then_else (eq_attr "cpu" "athlon")
7931 (const_string "vector")
7932 (const_string "double")))
7933 (set_attr "amdfam10_decode" "double")
7934 (set_attr "mode" "SI")])
7936 (define_expand "smuldi3_highpart"
7937 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7940 (mult:TI (sign_extend:TI
7941 (match_operand:DI 1 "nonimmediate_operand" ""))
7943 (match_operand:DI 2 "register_operand" "")))
7945 (clobber (match_scratch:DI 3 ""))
7946 (clobber (reg:CC FLAGS_REG))])]
7950 (define_insn "*smuldi3_highpart_rex64"
7951 [(set (match_operand:DI 0 "register_operand" "=d")
7954 (mult:TI (sign_extend:TI
7955 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7957 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7959 (clobber (match_scratch:DI 3 "=1"))
7960 (clobber (reg:CC FLAGS_REG))]
7962 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7964 [(set_attr "type" "imul")
7965 (set (attr "athlon_decode")
7966 (if_then_else (eq_attr "cpu" "athlon")
7967 (const_string "vector")
7968 (const_string "double")))
7969 (set_attr "amdfam10_decode" "double")
7970 (set_attr "mode" "DI")])
7972 (define_expand "smulsi3_highpart"
7973 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7976 (mult:DI (sign_extend:DI
7977 (match_operand:SI 1 "nonimmediate_operand" ""))
7979 (match_operand:SI 2 "register_operand" "")))
7981 (clobber (match_scratch:SI 3 ""))
7982 (clobber (reg:CC FLAGS_REG))])]
7986 (define_insn "*smulsi3_highpart_insn"
7987 [(set (match_operand:SI 0 "register_operand" "=d")
7990 (mult:DI (sign_extend:DI
7991 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7993 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7995 (clobber (match_scratch:SI 3 "=1"))
7996 (clobber (reg:CC FLAGS_REG))]
7997 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7999 [(set_attr "type" "imul")
8000 (set (attr "athlon_decode")
8001 (if_then_else (eq_attr "cpu" "athlon")
8002 (const_string "vector")
8003 (const_string "double")))
8004 (set_attr "amdfam10_decode" "double")
8005 (set_attr "mode" "SI")])
8007 (define_insn "*smulsi3_highpart_zext"
8008 [(set (match_operand:DI 0 "register_operand" "=d")
8009 (zero_extend:DI (truncate:SI
8011 (mult:DI (sign_extend:DI
8012 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8014 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8016 (clobber (match_scratch:SI 3 "=1"))
8017 (clobber (reg:CC FLAGS_REG))]
8019 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8021 [(set_attr "type" "imul")
8022 (set (attr "athlon_decode")
8023 (if_then_else (eq_attr "cpu" "athlon")
8024 (const_string "vector")
8025 (const_string "double")))
8026 (set_attr "amdfam10_decode" "double")
8027 (set_attr "mode" "SI")])
8029 ;; The patterns that match these are at the end of this file.
8031 (define_expand "mulxf3"
8032 [(set (match_operand:XF 0 "register_operand" "")
8033 (mult:XF (match_operand:XF 1 "register_operand" "")
8034 (match_operand:XF 2 "register_operand" "")))]
8038 (define_expand "mul<mode>3"
8039 [(set (match_operand:MODEF 0 "register_operand" "")
8040 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8041 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8042 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8045 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8048 ;; Divide instructions
8050 (define_insn "divqi3"
8051 [(set (match_operand:QI 0 "register_operand" "=a")
8052 (div:QI (match_operand:HI 1 "register_operand" "0")
8053 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8054 (clobber (reg:CC FLAGS_REG))]
8055 "TARGET_QIMODE_MATH"
8057 [(set_attr "type" "idiv")
8058 (set_attr "mode" "QI")])
8060 (define_insn "udivqi3"
8061 [(set (match_operand:QI 0 "register_operand" "=a")
8062 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8063 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8064 (clobber (reg:CC FLAGS_REG))]
8065 "TARGET_QIMODE_MATH"
8067 [(set_attr "type" "idiv")
8068 (set_attr "mode" "QI")])
8070 ;; The patterns that match these are at the end of this file.
8072 (define_expand "divxf3"
8073 [(set (match_operand:XF 0 "register_operand" "")
8074 (div:XF (match_operand:XF 1 "register_operand" "")
8075 (match_operand:XF 2 "register_operand" "")))]
8079 (define_expand "divdf3"
8080 [(set (match_operand:DF 0 "register_operand" "")
8081 (div:DF (match_operand:DF 1 "register_operand" "")
8082 (match_operand:DF 2 "nonimmediate_operand" "")))]
8083 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8086 (define_expand "divsf3"
8087 [(set (match_operand:SF 0 "register_operand" "")
8088 (div:SF (match_operand:SF 1 "register_operand" "")
8089 (match_operand:SF 2 "nonimmediate_operand" "")))]
8090 "TARGET_80387 || TARGET_SSE_MATH"
8092 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8093 && flag_finite_math_only && !flag_trapping_math
8094 && flag_unsafe_math_optimizations)
8096 ix86_emit_swdivsf (operands[0], operands[1],
8097 operands[2], SFmode);
8102 ;; Remainder instructions.
8104 (define_expand "divmoddi4"
8105 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8106 (div:DI (match_operand:DI 1 "register_operand" "")
8107 (match_operand:DI 2 "nonimmediate_operand" "")))
8108 (set (match_operand:DI 3 "register_operand" "")
8109 (mod:DI (match_dup 1) (match_dup 2)))
8110 (clobber (reg:CC FLAGS_REG))])]
8114 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8115 ;; Penalize eax case slightly because it results in worse scheduling
8117 (define_insn "*divmoddi4_nocltd_rex64"
8118 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8119 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8120 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8121 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8122 (mod:DI (match_dup 2) (match_dup 3)))
8123 (clobber (reg:CC FLAGS_REG))]
8124 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8126 [(set_attr "type" "multi")])
8128 (define_insn "*divmoddi4_cltd_rex64"
8129 [(set (match_operand:DI 0 "register_operand" "=a")
8130 (div:DI (match_operand:DI 2 "register_operand" "a")
8131 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8132 (set (match_operand:DI 1 "register_operand" "=&d")
8133 (mod:DI (match_dup 2) (match_dup 3)))
8134 (clobber (reg:CC FLAGS_REG))]
8135 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8137 [(set_attr "type" "multi")])
8139 (define_insn "*divmoddi_noext_rex64"
8140 [(set (match_operand:DI 0 "register_operand" "=a")
8141 (div:DI (match_operand:DI 1 "register_operand" "0")
8142 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8143 (set (match_operand:DI 3 "register_operand" "=d")
8144 (mod:DI (match_dup 1) (match_dup 2)))
8145 (use (match_operand:DI 4 "register_operand" "3"))
8146 (clobber (reg:CC FLAGS_REG))]
8149 [(set_attr "type" "idiv")
8150 (set_attr "mode" "DI")])
8153 [(set (match_operand:DI 0 "register_operand" "")
8154 (div:DI (match_operand:DI 1 "register_operand" "")
8155 (match_operand:DI 2 "nonimmediate_operand" "")))
8156 (set (match_operand:DI 3 "register_operand" "")
8157 (mod:DI (match_dup 1) (match_dup 2)))
8158 (clobber (reg:CC FLAGS_REG))]
8159 "TARGET_64BIT && reload_completed"
8160 [(parallel [(set (match_dup 3)
8161 (ashiftrt:DI (match_dup 4) (const_int 63)))
8162 (clobber (reg:CC FLAGS_REG))])
8163 (parallel [(set (match_dup 0)
8164 (div:DI (reg:DI 0) (match_dup 2)))
8166 (mod:DI (reg:DI 0) (match_dup 2)))
8168 (clobber (reg:CC FLAGS_REG))])]
8170 /* Avoid use of cltd in favor of a mov+shift. */
8171 if (!TARGET_USE_CLTD && !optimize_size)
8173 if (true_regnum (operands[1]))
8174 emit_move_insn (operands[0], operands[1]);
8176 emit_move_insn (operands[3], operands[1]);
8177 operands[4] = operands[3];
8181 gcc_assert (!true_regnum (operands[1]));
8182 operands[4] = operands[1];
8187 (define_expand "divmodsi4"
8188 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8189 (div:SI (match_operand:SI 1 "register_operand" "")
8190 (match_operand:SI 2 "nonimmediate_operand" "")))
8191 (set (match_operand:SI 3 "register_operand" "")
8192 (mod:SI (match_dup 1) (match_dup 2)))
8193 (clobber (reg:CC FLAGS_REG))])]
8197 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8198 ;; Penalize eax case slightly because it results in worse scheduling
8200 (define_insn "*divmodsi4_nocltd"
8201 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8202 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8203 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8204 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8205 (mod:SI (match_dup 2) (match_dup 3)))
8206 (clobber (reg:CC FLAGS_REG))]
8207 "!optimize_size && !TARGET_USE_CLTD"
8209 [(set_attr "type" "multi")])
8211 (define_insn "*divmodsi4_cltd"
8212 [(set (match_operand:SI 0 "register_operand" "=a")
8213 (div:SI (match_operand:SI 2 "register_operand" "a")
8214 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8215 (set (match_operand:SI 1 "register_operand" "=&d")
8216 (mod:SI (match_dup 2) (match_dup 3)))
8217 (clobber (reg:CC FLAGS_REG))]
8218 "optimize_size || TARGET_USE_CLTD"
8220 [(set_attr "type" "multi")])
8222 (define_insn "*divmodsi_noext"
8223 [(set (match_operand:SI 0 "register_operand" "=a")
8224 (div:SI (match_operand:SI 1 "register_operand" "0")
8225 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8226 (set (match_operand:SI 3 "register_operand" "=d")
8227 (mod:SI (match_dup 1) (match_dup 2)))
8228 (use (match_operand:SI 4 "register_operand" "3"))
8229 (clobber (reg:CC FLAGS_REG))]
8232 [(set_attr "type" "idiv")
8233 (set_attr "mode" "SI")])
8236 [(set (match_operand:SI 0 "register_operand" "")
8237 (div:SI (match_operand:SI 1 "register_operand" "")
8238 (match_operand:SI 2 "nonimmediate_operand" "")))
8239 (set (match_operand:SI 3 "register_operand" "")
8240 (mod:SI (match_dup 1) (match_dup 2)))
8241 (clobber (reg:CC FLAGS_REG))]
8243 [(parallel [(set (match_dup 3)
8244 (ashiftrt:SI (match_dup 4) (const_int 31)))
8245 (clobber (reg:CC FLAGS_REG))])
8246 (parallel [(set (match_dup 0)
8247 (div:SI (reg:SI 0) (match_dup 2)))
8249 (mod:SI (reg:SI 0) (match_dup 2)))
8251 (clobber (reg:CC FLAGS_REG))])]
8253 /* Avoid use of cltd in favor of a mov+shift. */
8254 if (!TARGET_USE_CLTD && !optimize_size)
8256 if (true_regnum (operands[1]))
8257 emit_move_insn (operands[0], operands[1]);
8259 emit_move_insn (operands[3], operands[1]);
8260 operands[4] = operands[3];
8264 gcc_assert (!true_regnum (operands[1]));
8265 operands[4] = operands[1];
8269 (define_insn "divmodhi4"
8270 [(set (match_operand:HI 0 "register_operand" "=a")
8271 (div:HI (match_operand:HI 1 "register_operand" "0")
8272 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8273 (set (match_operand:HI 3 "register_operand" "=&d")
8274 (mod:HI (match_dup 1) (match_dup 2)))
8275 (clobber (reg:CC FLAGS_REG))]
8276 "TARGET_HIMODE_MATH"
8278 [(set_attr "type" "multi")
8279 (set_attr "length_immediate" "0")
8280 (set_attr "mode" "SI")])
8282 (define_insn "udivmoddi4"
8283 [(set (match_operand:DI 0 "register_operand" "=a")
8284 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8285 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8286 (set (match_operand:DI 3 "register_operand" "=&d")
8287 (umod:DI (match_dup 1) (match_dup 2)))
8288 (clobber (reg:CC FLAGS_REG))]
8290 "xor{q}\t%3, %3\;div{q}\t%2"
8291 [(set_attr "type" "multi")
8292 (set_attr "length_immediate" "0")
8293 (set_attr "mode" "DI")])
8295 (define_insn "*udivmoddi4_noext"
8296 [(set (match_operand:DI 0 "register_operand" "=a")
8297 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8298 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8299 (set (match_operand:DI 3 "register_operand" "=d")
8300 (umod:DI (match_dup 1) (match_dup 2)))
8302 (clobber (reg:CC FLAGS_REG))]
8305 [(set_attr "type" "idiv")
8306 (set_attr "mode" "DI")])
8309 [(set (match_operand:DI 0 "register_operand" "")
8310 (udiv:DI (match_operand:DI 1 "register_operand" "")
8311 (match_operand:DI 2 "nonimmediate_operand" "")))
8312 (set (match_operand:DI 3 "register_operand" "")
8313 (umod:DI (match_dup 1) (match_dup 2)))
8314 (clobber (reg:CC FLAGS_REG))]
8315 "TARGET_64BIT && reload_completed"
8316 [(set (match_dup 3) (const_int 0))
8317 (parallel [(set (match_dup 0)
8318 (udiv:DI (match_dup 1) (match_dup 2)))
8320 (umod:DI (match_dup 1) (match_dup 2)))
8322 (clobber (reg:CC FLAGS_REG))])]
8325 (define_insn "udivmodsi4"
8326 [(set (match_operand:SI 0 "register_operand" "=a")
8327 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8328 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8329 (set (match_operand:SI 3 "register_operand" "=&d")
8330 (umod:SI (match_dup 1) (match_dup 2)))
8331 (clobber (reg:CC FLAGS_REG))]
8333 "xor{l}\t%3, %3\;div{l}\t%2"
8334 [(set_attr "type" "multi")
8335 (set_attr "length_immediate" "0")
8336 (set_attr "mode" "SI")])
8338 (define_insn "*udivmodsi4_noext"
8339 [(set (match_operand:SI 0 "register_operand" "=a")
8340 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8341 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8342 (set (match_operand:SI 3 "register_operand" "=d")
8343 (umod:SI (match_dup 1) (match_dup 2)))
8345 (clobber (reg:CC FLAGS_REG))]
8348 [(set_attr "type" "idiv")
8349 (set_attr "mode" "SI")])
8352 [(set (match_operand:SI 0 "register_operand" "")
8353 (udiv:SI (match_operand:SI 1 "register_operand" "")
8354 (match_operand:SI 2 "nonimmediate_operand" "")))
8355 (set (match_operand:SI 3 "register_operand" "")
8356 (umod:SI (match_dup 1) (match_dup 2)))
8357 (clobber (reg:CC FLAGS_REG))]
8359 [(set (match_dup 3) (const_int 0))
8360 (parallel [(set (match_dup 0)
8361 (udiv:SI (match_dup 1) (match_dup 2)))
8363 (umod:SI (match_dup 1) (match_dup 2)))
8365 (clobber (reg:CC FLAGS_REG))])]
8368 (define_expand "udivmodhi4"
8369 [(set (match_dup 4) (const_int 0))
8370 (parallel [(set (match_operand:HI 0 "register_operand" "")
8371 (udiv:HI (match_operand:HI 1 "register_operand" "")
8372 (match_operand:HI 2 "nonimmediate_operand" "")))
8373 (set (match_operand:HI 3 "register_operand" "")
8374 (umod:HI (match_dup 1) (match_dup 2)))
8376 (clobber (reg:CC FLAGS_REG))])]
8377 "TARGET_HIMODE_MATH"
8378 "operands[4] = gen_reg_rtx (HImode);")
8380 (define_insn "*udivmodhi_noext"
8381 [(set (match_operand:HI 0 "register_operand" "=a")
8382 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8383 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8384 (set (match_operand:HI 3 "register_operand" "=d")
8385 (umod:HI (match_dup 1) (match_dup 2)))
8386 (use (match_operand:HI 4 "register_operand" "3"))
8387 (clobber (reg:CC FLAGS_REG))]
8390 [(set_attr "type" "idiv")
8391 (set_attr "mode" "HI")])
8393 ;; We cannot use div/idiv for double division, because it causes
8394 ;; "division by zero" on the overflow and that's not what we expect
8395 ;; from truncate. Because true (non truncating) double division is
8396 ;; never generated, we can't create this insn anyway.
8399 ; [(set (match_operand:SI 0 "register_operand" "=a")
8401 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8403 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8404 ; (set (match_operand:SI 3 "register_operand" "=d")
8406 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8407 ; (clobber (reg:CC FLAGS_REG))]
8409 ; "div{l}\t{%2, %0|%0, %2}"
8410 ; [(set_attr "type" "idiv")])
8412 ;;- Logical AND instructions
8414 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8415 ;; Note that this excludes ah.
8417 (define_insn "*testdi_1_rex64"
8418 [(set (reg FLAGS_REG)
8420 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8421 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8423 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8424 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8426 test{l}\t{%k1, %k0|%k0, %k1}
8427 test{l}\t{%k1, %k0|%k0, %k1}
8428 test{q}\t{%1, %0|%0, %1}
8429 test{q}\t{%1, %0|%0, %1}
8430 test{q}\t{%1, %0|%0, %1}"
8431 [(set_attr "type" "test")
8432 (set_attr "modrm" "0,1,0,1,1")
8433 (set_attr "mode" "SI,SI,DI,DI,DI")
8434 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8436 (define_insn "testsi_1"
8437 [(set (reg FLAGS_REG)
8439 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8440 (match_operand:SI 1 "general_operand" "in,in,rin"))
8442 "ix86_match_ccmode (insn, CCNOmode)
8443 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8444 "test{l}\t{%1, %0|%0, %1}"
8445 [(set_attr "type" "test")
8446 (set_attr "modrm" "0,1,1")
8447 (set_attr "mode" "SI")
8448 (set_attr "pent_pair" "uv,np,uv")])
8450 (define_expand "testsi_ccno_1"
8451 [(set (reg:CCNO FLAGS_REG)
8453 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8454 (match_operand:SI 1 "nonmemory_operand" ""))
8459 (define_insn "*testhi_1"
8460 [(set (reg FLAGS_REG)
8461 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8462 (match_operand:HI 1 "general_operand" "n,n,rn"))
8464 "ix86_match_ccmode (insn, CCNOmode)
8465 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8466 "test{w}\t{%1, %0|%0, %1}"
8467 [(set_attr "type" "test")
8468 (set_attr "modrm" "0,1,1")
8469 (set_attr "mode" "HI")
8470 (set_attr "pent_pair" "uv,np,uv")])
8472 (define_expand "testqi_ccz_1"
8473 [(set (reg:CCZ FLAGS_REG)
8474 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8475 (match_operand:QI 1 "nonmemory_operand" ""))
8480 (define_insn "*testqi_1_maybe_si"
8481 [(set (reg FLAGS_REG)
8484 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8485 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8487 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8488 && ix86_match_ccmode (insn,
8489 CONST_INT_P (operands[1])
8490 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8492 if (which_alternative == 3)
8494 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8495 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8496 return "test{l}\t{%1, %k0|%k0, %1}";
8498 return "test{b}\t{%1, %0|%0, %1}";
8500 [(set_attr "type" "test")
8501 (set_attr "modrm" "0,1,1,1")
8502 (set_attr "mode" "QI,QI,QI,SI")
8503 (set_attr "pent_pair" "uv,np,uv,np")])
8505 (define_insn "*testqi_1"
8506 [(set (reg FLAGS_REG)
8509 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8510 (match_operand:QI 1 "general_operand" "n,n,qn"))
8512 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8513 && ix86_match_ccmode (insn, CCNOmode)"
8514 "test{b}\t{%1, %0|%0, %1}"
8515 [(set_attr "type" "test")
8516 (set_attr "modrm" "0,1,1")
8517 (set_attr "mode" "QI")
8518 (set_attr "pent_pair" "uv,np,uv")])
8520 (define_expand "testqi_ext_ccno_0"
8521 [(set (reg:CCNO FLAGS_REG)
8525 (match_operand 0 "ext_register_operand" "")
8528 (match_operand 1 "const_int_operand" ""))
8533 (define_insn "*testqi_ext_0"
8534 [(set (reg FLAGS_REG)
8538 (match_operand 0 "ext_register_operand" "Q")
8541 (match_operand 1 "const_int_operand" "n"))
8543 "ix86_match_ccmode (insn, CCNOmode)"
8544 "test{b}\t{%1, %h0|%h0, %1}"
8545 [(set_attr "type" "test")
8546 (set_attr "mode" "QI")
8547 (set_attr "length_immediate" "1")
8548 (set_attr "pent_pair" "np")])
8550 (define_insn "*testqi_ext_1"
8551 [(set (reg FLAGS_REG)
8555 (match_operand 0 "ext_register_operand" "Q")
8559 (match_operand:QI 1 "general_operand" "Qm")))
8561 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8562 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8563 "test{b}\t{%1, %h0|%h0, %1}"
8564 [(set_attr "type" "test")
8565 (set_attr "mode" "QI")])
8567 (define_insn "*testqi_ext_1_rex64"
8568 [(set (reg FLAGS_REG)
8572 (match_operand 0 "ext_register_operand" "Q")
8576 (match_operand:QI 1 "register_operand" "Q")))
8578 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8579 "test{b}\t{%1, %h0|%h0, %1}"
8580 [(set_attr "type" "test")
8581 (set_attr "mode" "QI")])
8583 (define_insn "*testqi_ext_2"
8584 [(set (reg FLAGS_REG)
8588 (match_operand 0 "ext_register_operand" "Q")
8592 (match_operand 1 "ext_register_operand" "Q")
8596 "ix86_match_ccmode (insn, CCNOmode)"
8597 "test{b}\t{%h1, %h0|%h0, %h1}"
8598 [(set_attr "type" "test")
8599 (set_attr "mode" "QI")])
8601 ;; Combine likes to form bit extractions for some tests. Humor it.
8602 (define_insn "*testqi_ext_3"
8603 [(set (reg FLAGS_REG)
8604 (compare (zero_extract:SI
8605 (match_operand 0 "nonimmediate_operand" "rm")
8606 (match_operand:SI 1 "const_int_operand" "")
8607 (match_operand:SI 2 "const_int_operand" ""))
8609 "ix86_match_ccmode (insn, CCNOmode)
8610 && INTVAL (operands[1]) > 0
8611 && INTVAL (operands[2]) >= 0
8612 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8613 && (GET_MODE (operands[0]) == SImode
8614 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8615 || GET_MODE (operands[0]) == HImode
8616 || GET_MODE (operands[0]) == QImode)"
8619 (define_insn "*testqi_ext_3_rex64"
8620 [(set (reg FLAGS_REG)
8621 (compare (zero_extract:DI
8622 (match_operand 0 "nonimmediate_operand" "rm")
8623 (match_operand:DI 1 "const_int_operand" "")
8624 (match_operand:DI 2 "const_int_operand" ""))
8627 && ix86_match_ccmode (insn, CCNOmode)
8628 && INTVAL (operands[1]) > 0
8629 && INTVAL (operands[2]) >= 0
8630 /* Ensure that resulting mask is zero or sign extended operand. */
8631 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8632 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8633 && INTVAL (operands[1]) > 32))
8634 && (GET_MODE (operands[0]) == SImode
8635 || GET_MODE (operands[0]) == DImode
8636 || GET_MODE (operands[0]) == HImode
8637 || GET_MODE (operands[0]) == QImode)"
8641 [(set (match_operand 0 "flags_reg_operand" "")
8642 (match_operator 1 "compare_operator"
8644 (match_operand 2 "nonimmediate_operand" "")
8645 (match_operand 3 "const_int_operand" "")
8646 (match_operand 4 "const_int_operand" ""))
8648 "ix86_match_ccmode (insn, CCNOmode)"
8649 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8651 rtx val = operands[2];
8652 HOST_WIDE_INT len = INTVAL (operands[3]);
8653 HOST_WIDE_INT pos = INTVAL (operands[4]);
8655 enum machine_mode mode, submode;
8657 mode = GET_MODE (val);
8660 /* ??? Combine likes to put non-volatile mem extractions in QImode
8661 no matter the size of the test. So find a mode that works. */
8662 if (! MEM_VOLATILE_P (val))
8664 mode = smallest_mode_for_size (pos + len, MODE_INT);
8665 val = adjust_address (val, mode, 0);
8668 else if (GET_CODE (val) == SUBREG
8669 && (submode = GET_MODE (SUBREG_REG (val)),
8670 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8671 && pos + len <= GET_MODE_BITSIZE (submode))
8673 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8675 val = SUBREG_REG (val);
8677 else if (mode == HImode && pos + len <= 8)
8679 /* Small HImode tests can be converted to QImode. */
8681 val = gen_lowpart (QImode, val);
8684 if (len == HOST_BITS_PER_WIDE_INT)
8687 mask = ((HOST_WIDE_INT)1 << len) - 1;
8690 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8693 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8694 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8695 ;; this is relatively important trick.
8696 ;; Do the conversion only post-reload to avoid limiting of the register class
8699 [(set (match_operand 0 "flags_reg_operand" "")
8700 (match_operator 1 "compare_operator"
8701 [(and (match_operand 2 "register_operand" "")
8702 (match_operand 3 "const_int_operand" ""))
8705 && QI_REG_P (operands[2])
8706 && GET_MODE (operands[2]) != QImode
8707 && ((ix86_match_ccmode (insn, CCZmode)
8708 && !(INTVAL (operands[3]) & ~(255 << 8)))
8709 || (ix86_match_ccmode (insn, CCNOmode)
8710 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8713 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8716 "operands[2] = gen_lowpart (SImode, operands[2]);
8717 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8720 [(set (match_operand 0 "flags_reg_operand" "")
8721 (match_operator 1 "compare_operator"
8722 [(and (match_operand 2 "nonimmediate_operand" "")
8723 (match_operand 3 "const_int_operand" ""))
8726 && GET_MODE (operands[2]) != QImode
8727 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8728 && ((ix86_match_ccmode (insn, CCZmode)
8729 && !(INTVAL (operands[3]) & ~255))
8730 || (ix86_match_ccmode (insn, CCNOmode)
8731 && !(INTVAL (operands[3]) & ~127)))"
8733 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8735 "operands[2] = gen_lowpart (QImode, operands[2]);
8736 operands[3] = gen_lowpart (QImode, operands[3]);")
8739 ;; %%% This used to optimize known byte-wide and operations to memory,
8740 ;; and sometimes to QImode registers. If this is considered useful,
8741 ;; it should be done with splitters.
8743 (define_expand "anddi3"
8744 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8745 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8746 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8747 (clobber (reg:CC FLAGS_REG))]
8749 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8751 (define_insn "*anddi_1_rex64"
8752 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8753 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8754 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8755 (clobber (reg:CC FLAGS_REG))]
8756 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8758 switch (get_attr_type (insn))
8762 enum machine_mode mode;
8764 gcc_assert (CONST_INT_P (operands[2]));
8765 if (INTVAL (operands[2]) == 0xff)
8769 gcc_assert (INTVAL (operands[2]) == 0xffff);
8773 operands[1] = gen_lowpart (mode, operands[1]);
8775 return "movz{bq|x}\t{%1,%0|%0, %1}";
8777 return "movz{wq|x}\t{%1,%0|%0, %1}";
8781 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8782 if (get_attr_mode (insn) == MODE_SI)
8783 return "and{l}\t{%k2, %k0|%k0, %k2}";
8785 return "and{q}\t{%2, %0|%0, %2}";
8788 [(set_attr "type" "alu,alu,alu,imovx")
8789 (set_attr "length_immediate" "*,*,*,0")
8790 (set_attr "mode" "SI,DI,DI,DI")])
8792 (define_insn "*anddi_2"
8793 [(set (reg FLAGS_REG)
8794 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8795 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8797 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8798 (and:DI (match_dup 1) (match_dup 2)))]
8799 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8800 && ix86_binary_operator_ok (AND, DImode, operands)"
8802 and{l}\t{%k2, %k0|%k0, %k2}
8803 and{q}\t{%2, %0|%0, %2}
8804 and{q}\t{%2, %0|%0, %2}"
8805 [(set_attr "type" "alu")
8806 (set_attr "mode" "SI,DI,DI")])
8808 (define_expand "andsi3"
8809 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8810 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8811 (match_operand:SI 2 "general_operand" "")))
8812 (clobber (reg:CC FLAGS_REG))]
8814 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8816 (define_insn "*andsi_1"
8817 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8818 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8819 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8820 (clobber (reg:CC FLAGS_REG))]
8821 "ix86_binary_operator_ok (AND, SImode, operands)"
8823 switch (get_attr_type (insn))
8827 enum machine_mode mode;
8829 gcc_assert (CONST_INT_P (operands[2]));
8830 if (INTVAL (operands[2]) == 0xff)
8834 gcc_assert (INTVAL (operands[2]) == 0xffff);
8838 operands[1] = gen_lowpart (mode, operands[1]);
8840 return "movz{bl|x}\t{%1,%0|%0, %1}";
8842 return "movz{wl|x}\t{%1,%0|%0, %1}";
8846 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8847 return "and{l}\t{%2, %0|%0, %2}";
8850 [(set_attr "type" "alu,alu,imovx")
8851 (set_attr "length_immediate" "*,*,0")
8852 (set_attr "mode" "SI")])
8855 [(set (match_operand 0 "register_operand" "")
8857 (const_int -65536)))
8858 (clobber (reg:CC FLAGS_REG))]
8859 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8860 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8861 "operands[1] = gen_lowpart (HImode, operands[0]);")
8864 [(set (match_operand 0 "ext_register_operand" "")
8867 (clobber (reg:CC FLAGS_REG))]
8868 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8869 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8870 "operands[1] = gen_lowpart (QImode, operands[0]);")
8873 [(set (match_operand 0 "ext_register_operand" "")
8875 (const_int -65281)))
8876 (clobber (reg:CC FLAGS_REG))]
8877 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8878 [(parallel [(set (zero_extract:SI (match_dup 0)
8882 (zero_extract:SI (match_dup 0)
8885 (zero_extract:SI (match_dup 0)
8888 (clobber (reg:CC FLAGS_REG))])]
8889 "operands[0] = gen_lowpart (SImode, operands[0]);")
8891 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8892 (define_insn "*andsi_1_zext"
8893 [(set (match_operand:DI 0 "register_operand" "=r")
8895 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8896 (match_operand:SI 2 "general_operand" "g"))))
8897 (clobber (reg:CC FLAGS_REG))]
8898 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8899 "and{l}\t{%2, %k0|%k0, %2}"
8900 [(set_attr "type" "alu")
8901 (set_attr "mode" "SI")])
8903 (define_insn "*andsi_2"
8904 [(set (reg FLAGS_REG)
8905 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8906 (match_operand:SI 2 "general_operand" "g,ri"))
8908 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8909 (and:SI (match_dup 1) (match_dup 2)))]
8910 "ix86_match_ccmode (insn, CCNOmode)
8911 && ix86_binary_operator_ok (AND, SImode, operands)"
8912 "and{l}\t{%2, %0|%0, %2}"
8913 [(set_attr "type" "alu")
8914 (set_attr "mode" "SI")])
8916 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8917 (define_insn "*andsi_2_zext"
8918 [(set (reg FLAGS_REG)
8919 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8920 (match_operand:SI 2 "general_operand" "g"))
8922 (set (match_operand:DI 0 "register_operand" "=r")
8923 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8924 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8925 && ix86_binary_operator_ok (AND, SImode, operands)"
8926 "and{l}\t{%2, %k0|%k0, %2}"
8927 [(set_attr "type" "alu")
8928 (set_attr "mode" "SI")])
8930 (define_expand "andhi3"
8931 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8932 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8933 (match_operand:HI 2 "general_operand" "")))
8934 (clobber (reg:CC FLAGS_REG))]
8935 "TARGET_HIMODE_MATH"
8936 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8938 (define_insn "*andhi_1"
8939 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8940 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8941 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8942 (clobber (reg:CC FLAGS_REG))]
8943 "ix86_binary_operator_ok (AND, HImode, operands)"
8945 switch (get_attr_type (insn))
8948 gcc_assert (CONST_INT_P (operands[2]));
8949 gcc_assert (INTVAL (operands[2]) == 0xff);
8950 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8953 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8955 return "and{w}\t{%2, %0|%0, %2}";
8958 [(set_attr "type" "alu,alu,imovx")
8959 (set_attr "length_immediate" "*,*,0")
8960 (set_attr "mode" "HI,HI,SI")])
8962 (define_insn "*andhi_2"
8963 [(set (reg FLAGS_REG)
8964 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8965 (match_operand:HI 2 "general_operand" "g,ri"))
8967 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8968 (and:HI (match_dup 1) (match_dup 2)))]
8969 "ix86_match_ccmode (insn, CCNOmode)
8970 && ix86_binary_operator_ok (AND, HImode, operands)"
8971 "and{w}\t{%2, %0|%0, %2}"
8972 [(set_attr "type" "alu")
8973 (set_attr "mode" "HI")])
8975 (define_expand "andqi3"
8976 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8977 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8978 (match_operand:QI 2 "general_operand" "")))
8979 (clobber (reg:CC FLAGS_REG))]
8980 "TARGET_QIMODE_MATH"
8981 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8983 ;; %%% Potential partial reg stall on alternative 2. What to do?
8984 (define_insn "*andqi_1"
8985 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8986 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8987 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8988 (clobber (reg:CC FLAGS_REG))]
8989 "ix86_binary_operator_ok (AND, QImode, operands)"
8991 and{b}\t{%2, %0|%0, %2}
8992 and{b}\t{%2, %0|%0, %2}
8993 and{l}\t{%k2, %k0|%k0, %k2}"
8994 [(set_attr "type" "alu")
8995 (set_attr "mode" "QI,QI,SI")])
8997 (define_insn "*andqi_1_slp"
8998 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8999 (and:QI (match_dup 0)
9000 (match_operand:QI 1 "general_operand" "qi,qmi")))
9001 (clobber (reg:CC FLAGS_REG))]
9002 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9003 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9004 "and{b}\t{%1, %0|%0, %1}"
9005 [(set_attr "type" "alu1")
9006 (set_attr "mode" "QI")])
9008 (define_insn "*andqi_2_maybe_si"
9009 [(set (reg FLAGS_REG)
9011 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9012 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9014 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9015 (and:QI (match_dup 1) (match_dup 2)))]
9016 "ix86_binary_operator_ok (AND, QImode, operands)
9017 && ix86_match_ccmode (insn,
9018 CONST_INT_P (operands[2])
9019 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9021 if (which_alternative == 2)
9023 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9024 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9025 return "and{l}\t{%2, %k0|%k0, %2}";
9027 return "and{b}\t{%2, %0|%0, %2}";
9029 [(set_attr "type" "alu")
9030 (set_attr "mode" "QI,QI,SI")])
9032 (define_insn "*andqi_2"
9033 [(set (reg FLAGS_REG)
9035 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9036 (match_operand:QI 2 "general_operand" "qim,qi"))
9038 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9039 (and:QI (match_dup 1) (match_dup 2)))]
9040 "ix86_match_ccmode (insn, CCNOmode)
9041 && ix86_binary_operator_ok (AND, QImode, operands)"
9042 "and{b}\t{%2, %0|%0, %2}"
9043 [(set_attr "type" "alu")
9044 (set_attr "mode" "QI")])
9046 (define_insn "*andqi_2_slp"
9047 [(set (reg FLAGS_REG)
9049 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9050 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9052 (set (strict_low_part (match_dup 0))
9053 (and:QI (match_dup 0) (match_dup 1)))]
9054 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9055 && ix86_match_ccmode (insn, CCNOmode)
9056 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9057 "and{b}\t{%1, %0|%0, %1}"
9058 [(set_attr "type" "alu1")
9059 (set_attr "mode" "QI")])
9061 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9062 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9063 ;; for a QImode operand, which of course failed.
9065 (define_insn "andqi_ext_0"
9066 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9071 (match_operand 1 "ext_register_operand" "0")
9074 (match_operand 2 "const_int_operand" "n")))
9075 (clobber (reg:CC FLAGS_REG))]
9077 "and{b}\t{%2, %h0|%h0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "length_immediate" "1")
9080 (set_attr "mode" "QI")])
9082 ;; Generated by peephole translating test to and. This shows up
9083 ;; often in fp comparisons.
9085 (define_insn "*andqi_ext_0_cc"
9086 [(set (reg FLAGS_REG)
9090 (match_operand 1 "ext_register_operand" "0")
9093 (match_operand 2 "const_int_operand" "n"))
9095 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9104 "ix86_match_ccmode (insn, CCNOmode)"
9105 "and{b}\t{%2, %h0|%h0, %2}"
9106 [(set_attr "type" "alu")
9107 (set_attr "length_immediate" "1")
9108 (set_attr "mode" "QI")])
9110 (define_insn "*andqi_ext_1"
9111 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9116 (match_operand 1 "ext_register_operand" "0")
9120 (match_operand:QI 2 "general_operand" "Qm"))))
9121 (clobber (reg:CC FLAGS_REG))]
9123 "and{b}\t{%2, %h0|%h0, %2}"
9124 [(set_attr "type" "alu")
9125 (set_attr "length_immediate" "0")
9126 (set_attr "mode" "QI")])
9128 (define_insn "*andqi_ext_1_rex64"
9129 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9134 (match_operand 1 "ext_register_operand" "0")
9138 (match_operand 2 "ext_register_operand" "Q"))))
9139 (clobber (reg:CC FLAGS_REG))]
9141 "and{b}\t{%2, %h0|%h0, %2}"
9142 [(set_attr "type" "alu")
9143 (set_attr "length_immediate" "0")
9144 (set_attr "mode" "QI")])
9146 (define_insn "*andqi_ext_2"
9147 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9152 (match_operand 1 "ext_register_operand" "%0")
9156 (match_operand 2 "ext_register_operand" "Q")
9159 (clobber (reg:CC FLAGS_REG))]
9161 "and{b}\t{%h2, %h0|%h0, %h2}"
9162 [(set_attr "type" "alu")
9163 (set_attr "length_immediate" "0")
9164 (set_attr "mode" "QI")])
9166 ;; Convert wide AND instructions with immediate operand to shorter QImode
9167 ;; equivalents when possible.
9168 ;; Don't do the splitting with memory operands, since it introduces risk
9169 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9170 ;; for size, but that can (should?) be handled by generic code instead.
9172 [(set (match_operand 0 "register_operand" "")
9173 (and (match_operand 1 "register_operand" "")
9174 (match_operand 2 "const_int_operand" "")))
9175 (clobber (reg:CC FLAGS_REG))]
9177 && QI_REG_P (operands[0])
9178 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9179 && !(~INTVAL (operands[2]) & ~(255 << 8))
9180 && GET_MODE (operands[0]) != QImode"
9181 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9182 (and:SI (zero_extract:SI (match_dup 1)
9183 (const_int 8) (const_int 8))
9185 (clobber (reg:CC FLAGS_REG))])]
9186 "operands[0] = gen_lowpart (SImode, operands[0]);
9187 operands[1] = gen_lowpart (SImode, operands[1]);
9188 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9190 ;; Since AND can be encoded with sign extended immediate, this is only
9191 ;; profitable when 7th bit is not set.
9193 [(set (match_operand 0 "register_operand" "")
9194 (and (match_operand 1 "general_operand" "")
9195 (match_operand 2 "const_int_operand" "")))
9196 (clobber (reg:CC FLAGS_REG))]
9198 && ANY_QI_REG_P (operands[0])
9199 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9200 && !(~INTVAL (operands[2]) & ~255)
9201 && !(INTVAL (operands[2]) & 128)
9202 && GET_MODE (operands[0]) != QImode"
9203 [(parallel [(set (strict_low_part (match_dup 0))
9204 (and:QI (match_dup 1)
9206 (clobber (reg:CC FLAGS_REG))])]
9207 "operands[0] = gen_lowpart (QImode, operands[0]);
9208 operands[1] = gen_lowpart (QImode, operands[1]);
9209 operands[2] = gen_lowpart (QImode, operands[2]);")
9211 ;; Logical inclusive OR instructions
9213 ;; %%% This used to optimize known byte-wide and operations to memory.
9214 ;; If this is considered useful, it should be done with splitters.
9216 (define_expand "iordi3"
9217 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9218 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9219 (match_operand:DI 2 "x86_64_general_operand" "")))
9220 (clobber (reg:CC FLAGS_REG))]
9222 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9224 (define_insn "*iordi_1_rex64"
9225 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9226 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9227 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9228 (clobber (reg:CC FLAGS_REG))]
9230 && ix86_binary_operator_ok (IOR, DImode, operands)"
9231 "or{q}\t{%2, %0|%0, %2}"
9232 [(set_attr "type" "alu")
9233 (set_attr "mode" "DI")])
9235 (define_insn "*iordi_2_rex64"
9236 [(set (reg FLAGS_REG)
9237 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9238 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9240 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9241 (ior:DI (match_dup 1) (match_dup 2)))]
9243 && ix86_match_ccmode (insn, CCNOmode)
9244 && ix86_binary_operator_ok (IOR, DImode, operands)"
9245 "or{q}\t{%2, %0|%0, %2}"
9246 [(set_attr "type" "alu")
9247 (set_attr "mode" "DI")])
9249 (define_insn "*iordi_3_rex64"
9250 [(set (reg FLAGS_REG)
9251 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9252 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9254 (clobber (match_scratch:DI 0 "=r"))]
9256 && ix86_match_ccmode (insn, CCNOmode)
9257 && ix86_binary_operator_ok (IOR, DImode, operands)"
9258 "or{q}\t{%2, %0|%0, %2}"
9259 [(set_attr "type" "alu")
9260 (set_attr "mode" "DI")])
9263 (define_expand "iorsi3"
9264 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9265 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9266 (match_operand:SI 2 "general_operand" "")))
9267 (clobber (reg:CC FLAGS_REG))]
9269 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9271 (define_insn "*iorsi_1"
9272 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9273 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9274 (match_operand:SI 2 "general_operand" "ri,g")))
9275 (clobber (reg:CC FLAGS_REG))]
9276 "ix86_binary_operator_ok (IOR, SImode, operands)"
9277 "or{l}\t{%2, %0|%0, %2}"
9278 [(set_attr "type" "alu")
9279 (set_attr "mode" "SI")])
9281 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9282 (define_insn "*iorsi_1_zext"
9283 [(set (match_operand:DI 0 "register_operand" "=r")
9285 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9286 (match_operand:SI 2 "general_operand" "g"))))
9287 (clobber (reg:CC FLAGS_REG))]
9288 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9289 "or{l}\t{%2, %k0|%k0, %2}"
9290 [(set_attr "type" "alu")
9291 (set_attr "mode" "SI")])
9293 (define_insn "*iorsi_1_zext_imm"
9294 [(set (match_operand:DI 0 "register_operand" "=r")
9295 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9296 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9297 (clobber (reg:CC FLAGS_REG))]
9299 "or{l}\t{%2, %k0|%k0, %2}"
9300 [(set_attr "type" "alu")
9301 (set_attr "mode" "SI")])
9303 (define_insn "*iorsi_2"
9304 [(set (reg FLAGS_REG)
9305 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9306 (match_operand:SI 2 "general_operand" "g,ri"))
9308 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9309 (ior:SI (match_dup 1) (match_dup 2)))]
9310 "ix86_match_ccmode (insn, CCNOmode)
9311 && ix86_binary_operator_ok (IOR, SImode, operands)"
9312 "or{l}\t{%2, %0|%0, %2}"
9313 [(set_attr "type" "alu")
9314 (set_attr "mode" "SI")])
9316 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9317 ;; ??? Special case for immediate operand is missing - it is tricky.
9318 (define_insn "*iorsi_2_zext"
9319 [(set (reg FLAGS_REG)
9320 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9321 (match_operand:SI 2 "general_operand" "g"))
9323 (set (match_operand:DI 0 "register_operand" "=r")
9324 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9325 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9326 && ix86_binary_operator_ok (IOR, SImode, operands)"
9327 "or{l}\t{%2, %k0|%k0, %2}"
9328 [(set_attr "type" "alu")
9329 (set_attr "mode" "SI")])
9331 (define_insn "*iorsi_2_zext_imm"
9332 [(set (reg FLAGS_REG)
9333 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9334 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9336 (set (match_operand:DI 0 "register_operand" "=r")
9337 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9338 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9339 && ix86_binary_operator_ok (IOR, SImode, operands)"
9340 "or{l}\t{%2, %k0|%k0, %2}"
9341 [(set_attr "type" "alu")
9342 (set_attr "mode" "SI")])
9344 (define_insn "*iorsi_3"
9345 [(set (reg FLAGS_REG)
9346 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9347 (match_operand:SI 2 "general_operand" "g"))
9349 (clobber (match_scratch:SI 0 "=r"))]
9350 "ix86_match_ccmode (insn, CCNOmode)
9351 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9352 "or{l}\t{%2, %0|%0, %2}"
9353 [(set_attr "type" "alu")
9354 (set_attr "mode" "SI")])
9356 (define_expand "iorhi3"
9357 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9358 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9359 (match_operand:HI 2 "general_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))]
9361 "TARGET_HIMODE_MATH"
9362 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9364 (define_insn "*iorhi_1"
9365 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9366 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9367 (match_operand:HI 2 "general_operand" "g,ri")))
9368 (clobber (reg:CC FLAGS_REG))]
9369 "ix86_binary_operator_ok (IOR, HImode, operands)"
9370 "or{w}\t{%2, %0|%0, %2}"
9371 [(set_attr "type" "alu")
9372 (set_attr "mode" "HI")])
9374 (define_insn "*iorhi_2"
9375 [(set (reg FLAGS_REG)
9376 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9377 (match_operand:HI 2 "general_operand" "g,ri"))
9379 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9380 (ior:HI (match_dup 1) (match_dup 2)))]
9381 "ix86_match_ccmode (insn, CCNOmode)
9382 && ix86_binary_operator_ok (IOR, HImode, operands)"
9383 "or{w}\t{%2, %0|%0, %2}"
9384 [(set_attr "type" "alu")
9385 (set_attr "mode" "HI")])
9387 (define_insn "*iorhi_3"
9388 [(set (reg FLAGS_REG)
9389 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9390 (match_operand:HI 2 "general_operand" "g"))
9392 (clobber (match_scratch:HI 0 "=r"))]
9393 "ix86_match_ccmode (insn, CCNOmode)
9394 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9395 "or{w}\t{%2, %0|%0, %2}"
9396 [(set_attr "type" "alu")
9397 (set_attr "mode" "HI")])
9399 (define_expand "iorqi3"
9400 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9401 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9402 (match_operand:QI 2 "general_operand" "")))
9403 (clobber (reg:CC FLAGS_REG))]
9404 "TARGET_QIMODE_MATH"
9405 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9407 ;; %%% Potential partial reg stall on alternative 2. What to do?
9408 (define_insn "*iorqi_1"
9409 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9410 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9411 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9412 (clobber (reg:CC FLAGS_REG))]
9413 "ix86_binary_operator_ok (IOR, QImode, operands)"
9415 or{b}\t{%2, %0|%0, %2}
9416 or{b}\t{%2, %0|%0, %2}
9417 or{l}\t{%k2, %k0|%k0, %k2}"
9418 [(set_attr "type" "alu")
9419 (set_attr "mode" "QI,QI,SI")])
9421 (define_insn "*iorqi_1_slp"
9422 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9423 (ior:QI (match_dup 0)
9424 (match_operand:QI 1 "general_operand" "qmi,qi")))
9425 (clobber (reg:CC FLAGS_REG))]
9426 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9427 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9428 "or{b}\t{%1, %0|%0, %1}"
9429 [(set_attr "type" "alu1")
9430 (set_attr "mode" "QI")])
9432 (define_insn "*iorqi_2"
9433 [(set (reg FLAGS_REG)
9434 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9435 (match_operand:QI 2 "general_operand" "qim,qi"))
9437 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9438 (ior:QI (match_dup 1) (match_dup 2)))]
9439 "ix86_match_ccmode (insn, CCNOmode)
9440 && ix86_binary_operator_ok (IOR, QImode, operands)"
9441 "or{b}\t{%2, %0|%0, %2}"
9442 [(set_attr "type" "alu")
9443 (set_attr "mode" "QI")])
9445 (define_insn "*iorqi_2_slp"
9446 [(set (reg FLAGS_REG)
9447 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9448 (match_operand:QI 1 "general_operand" "qim,qi"))
9450 (set (strict_low_part (match_dup 0))
9451 (ior:QI (match_dup 0) (match_dup 1)))]
9452 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9453 && ix86_match_ccmode (insn, CCNOmode)
9454 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9455 "or{b}\t{%1, %0|%0, %1}"
9456 [(set_attr "type" "alu1")
9457 (set_attr "mode" "QI")])
9459 (define_insn "*iorqi_3"
9460 [(set (reg FLAGS_REG)
9461 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9462 (match_operand:QI 2 "general_operand" "qim"))
9464 (clobber (match_scratch:QI 0 "=q"))]
9465 "ix86_match_ccmode (insn, CCNOmode)
9466 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9467 "or{b}\t{%2, %0|%0, %2}"
9468 [(set_attr "type" "alu")
9469 (set_attr "mode" "QI")])
9471 (define_insn "iorqi_ext_0"
9472 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9477 (match_operand 1 "ext_register_operand" "0")
9480 (match_operand 2 "const_int_operand" "n")))
9481 (clobber (reg:CC FLAGS_REG))]
9482 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9483 "or{b}\t{%2, %h0|%h0, %2}"
9484 [(set_attr "type" "alu")
9485 (set_attr "length_immediate" "1")
9486 (set_attr "mode" "QI")])
9488 (define_insn "*iorqi_ext_1"
9489 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9494 (match_operand 1 "ext_register_operand" "0")
9498 (match_operand:QI 2 "general_operand" "Qm"))))
9499 (clobber (reg:CC FLAGS_REG))]
9501 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9502 "or{b}\t{%2, %h0|%h0, %2}"
9503 [(set_attr "type" "alu")
9504 (set_attr "length_immediate" "0")
9505 (set_attr "mode" "QI")])
9507 (define_insn "*iorqi_ext_1_rex64"
9508 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9513 (match_operand 1 "ext_register_operand" "0")
9517 (match_operand 2 "ext_register_operand" "Q"))))
9518 (clobber (reg:CC FLAGS_REG))]
9520 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9521 "or{b}\t{%2, %h0|%h0, %2}"
9522 [(set_attr "type" "alu")
9523 (set_attr "length_immediate" "0")
9524 (set_attr "mode" "QI")])
9526 (define_insn "*iorqi_ext_2"
9527 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9531 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9534 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9537 (clobber (reg:CC FLAGS_REG))]
9538 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9539 "ior{b}\t{%h2, %h0|%h0, %h2}"
9540 [(set_attr "type" "alu")
9541 (set_attr "length_immediate" "0")
9542 (set_attr "mode" "QI")])
9545 [(set (match_operand 0 "register_operand" "")
9546 (ior (match_operand 1 "register_operand" "")
9547 (match_operand 2 "const_int_operand" "")))
9548 (clobber (reg:CC FLAGS_REG))]
9550 && QI_REG_P (operands[0])
9551 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9552 && !(INTVAL (operands[2]) & ~(255 << 8))
9553 && GET_MODE (operands[0]) != QImode"
9554 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9555 (ior:SI (zero_extract:SI (match_dup 1)
9556 (const_int 8) (const_int 8))
9558 (clobber (reg:CC FLAGS_REG))])]
9559 "operands[0] = gen_lowpart (SImode, operands[0]);
9560 operands[1] = gen_lowpart (SImode, operands[1]);
9561 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9563 ;; Since OR can be encoded with sign extended immediate, this is only
9564 ;; profitable when 7th bit is set.
9566 [(set (match_operand 0 "register_operand" "")
9567 (ior (match_operand 1 "general_operand" "")
9568 (match_operand 2 "const_int_operand" "")))
9569 (clobber (reg:CC FLAGS_REG))]
9571 && ANY_QI_REG_P (operands[0])
9572 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9573 && !(INTVAL (operands[2]) & ~255)
9574 && (INTVAL (operands[2]) & 128)
9575 && GET_MODE (operands[0]) != QImode"
9576 [(parallel [(set (strict_low_part (match_dup 0))
9577 (ior:QI (match_dup 1)
9579 (clobber (reg:CC FLAGS_REG))])]
9580 "operands[0] = gen_lowpart (QImode, operands[0]);
9581 operands[1] = gen_lowpart (QImode, operands[1]);
9582 operands[2] = gen_lowpart (QImode, operands[2]);")
9584 ;; Logical XOR instructions
9586 ;; %%% This used to optimize known byte-wide and operations to memory.
9587 ;; If this is considered useful, it should be done with splitters.
9589 (define_expand "xordi3"
9590 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9591 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9592 (match_operand:DI 2 "x86_64_general_operand" "")))
9593 (clobber (reg:CC FLAGS_REG))]
9595 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9597 (define_insn "*xordi_1_rex64"
9598 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9599 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9600 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9601 (clobber (reg:CC FLAGS_REG))]
9603 && ix86_binary_operator_ok (XOR, DImode, operands)"
9605 xor{q}\t{%2, %0|%0, %2}
9606 xor{q}\t{%2, %0|%0, %2}"
9607 [(set_attr "type" "alu")
9608 (set_attr "mode" "DI,DI")])
9610 (define_insn "*xordi_2_rex64"
9611 [(set (reg FLAGS_REG)
9612 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9613 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9615 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9616 (xor:DI (match_dup 1) (match_dup 2)))]
9618 && ix86_match_ccmode (insn, CCNOmode)
9619 && ix86_binary_operator_ok (XOR, DImode, operands)"
9621 xor{q}\t{%2, %0|%0, %2}
9622 xor{q}\t{%2, %0|%0, %2}"
9623 [(set_attr "type" "alu")
9624 (set_attr "mode" "DI,DI")])
9626 (define_insn "*xordi_3_rex64"
9627 [(set (reg FLAGS_REG)
9628 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9629 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9631 (clobber (match_scratch:DI 0 "=r"))]
9633 && ix86_match_ccmode (insn, CCNOmode)
9634 && ix86_binary_operator_ok (XOR, DImode, operands)"
9635 "xor{q}\t{%2, %0|%0, %2}"
9636 [(set_attr "type" "alu")
9637 (set_attr "mode" "DI")])
9639 (define_expand "xorsi3"
9640 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9641 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9642 (match_operand:SI 2 "general_operand" "")))
9643 (clobber (reg:CC FLAGS_REG))]
9645 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9647 (define_insn "*xorsi_1"
9648 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9649 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9650 (match_operand:SI 2 "general_operand" "ri,rm")))
9651 (clobber (reg:CC FLAGS_REG))]
9652 "ix86_binary_operator_ok (XOR, SImode, operands)"
9653 "xor{l}\t{%2, %0|%0, %2}"
9654 [(set_attr "type" "alu")
9655 (set_attr "mode" "SI")])
9657 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9658 ;; Add speccase for immediates
9659 (define_insn "*xorsi_1_zext"
9660 [(set (match_operand:DI 0 "register_operand" "=r")
9662 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9663 (match_operand:SI 2 "general_operand" "g"))))
9664 (clobber (reg:CC FLAGS_REG))]
9665 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9666 "xor{l}\t{%2, %k0|%k0, %2}"
9667 [(set_attr "type" "alu")
9668 (set_attr "mode" "SI")])
9670 (define_insn "*xorsi_1_zext_imm"
9671 [(set (match_operand:DI 0 "register_operand" "=r")
9672 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9673 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9674 (clobber (reg:CC FLAGS_REG))]
9675 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9676 "xor{l}\t{%2, %k0|%k0, %2}"
9677 [(set_attr "type" "alu")
9678 (set_attr "mode" "SI")])
9680 (define_insn "*xorsi_2"
9681 [(set (reg FLAGS_REG)
9682 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9683 (match_operand:SI 2 "general_operand" "g,ri"))
9685 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9686 (xor:SI (match_dup 1) (match_dup 2)))]
9687 "ix86_match_ccmode (insn, CCNOmode)
9688 && ix86_binary_operator_ok (XOR, SImode, operands)"
9689 "xor{l}\t{%2, %0|%0, %2}"
9690 [(set_attr "type" "alu")
9691 (set_attr "mode" "SI")])
9693 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9694 ;; ??? Special case for immediate operand is missing - it is tricky.
9695 (define_insn "*xorsi_2_zext"
9696 [(set (reg FLAGS_REG)
9697 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9698 (match_operand:SI 2 "general_operand" "g"))
9700 (set (match_operand:DI 0 "register_operand" "=r")
9701 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9702 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9703 && ix86_binary_operator_ok (XOR, SImode, operands)"
9704 "xor{l}\t{%2, %k0|%k0, %2}"
9705 [(set_attr "type" "alu")
9706 (set_attr "mode" "SI")])
9708 (define_insn "*xorsi_2_zext_imm"
9709 [(set (reg FLAGS_REG)
9710 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9711 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9713 (set (match_operand:DI 0 "register_operand" "=r")
9714 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9715 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9716 && ix86_binary_operator_ok (XOR, SImode, operands)"
9717 "xor{l}\t{%2, %k0|%k0, %2}"
9718 [(set_attr "type" "alu")
9719 (set_attr "mode" "SI")])
9721 (define_insn "*xorsi_3"
9722 [(set (reg FLAGS_REG)
9723 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9724 (match_operand:SI 2 "general_operand" "g"))
9726 (clobber (match_scratch:SI 0 "=r"))]
9727 "ix86_match_ccmode (insn, CCNOmode)
9728 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9729 "xor{l}\t{%2, %0|%0, %2}"
9730 [(set_attr "type" "alu")
9731 (set_attr "mode" "SI")])
9733 (define_expand "xorhi3"
9734 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9735 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9736 (match_operand:HI 2 "general_operand" "")))
9737 (clobber (reg:CC FLAGS_REG))]
9738 "TARGET_HIMODE_MATH"
9739 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9741 (define_insn "*xorhi_1"
9742 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9743 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9744 (match_operand:HI 2 "general_operand" "g,ri")))
9745 (clobber (reg:CC FLAGS_REG))]
9746 "ix86_binary_operator_ok (XOR, HImode, operands)"
9747 "xor{w}\t{%2, %0|%0, %2}"
9748 [(set_attr "type" "alu")
9749 (set_attr "mode" "HI")])
9751 (define_insn "*xorhi_2"
9752 [(set (reg FLAGS_REG)
9753 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9754 (match_operand:HI 2 "general_operand" "g,ri"))
9756 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9757 (xor:HI (match_dup 1) (match_dup 2)))]
9758 "ix86_match_ccmode (insn, CCNOmode)
9759 && ix86_binary_operator_ok (XOR, HImode, operands)"
9760 "xor{w}\t{%2, %0|%0, %2}"
9761 [(set_attr "type" "alu")
9762 (set_attr "mode" "HI")])
9764 (define_insn "*xorhi_3"
9765 [(set (reg FLAGS_REG)
9766 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9767 (match_operand:HI 2 "general_operand" "g"))
9769 (clobber (match_scratch:HI 0 "=r"))]
9770 "ix86_match_ccmode (insn, CCNOmode)
9771 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9772 "xor{w}\t{%2, %0|%0, %2}"
9773 [(set_attr "type" "alu")
9774 (set_attr "mode" "HI")])
9776 (define_expand "xorqi3"
9777 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9778 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9779 (match_operand:QI 2 "general_operand" "")))
9780 (clobber (reg:CC FLAGS_REG))]
9781 "TARGET_QIMODE_MATH"
9782 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9784 ;; %%% Potential partial reg stall on alternative 2. What to do?
9785 (define_insn "*xorqi_1"
9786 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9787 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9788 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9789 (clobber (reg:CC FLAGS_REG))]
9790 "ix86_binary_operator_ok (XOR, QImode, operands)"
9792 xor{b}\t{%2, %0|%0, %2}
9793 xor{b}\t{%2, %0|%0, %2}
9794 xor{l}\t{%k2, %k0|%k0, %k2}"
9795 [(set_attr "type" "alu")
9796 (set_attr "mode" "QI,QI,SI")])
9798 (define_insn "*xorqi_1_slp"
9799 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9800 (xor:QI (match_dup 0)
9801 (match_operand:QI 1 "general_operand" "qi,qmi")))
9802 (clobber (reg:CC FLAGS_REG))]
9803 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9804 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9805 "xor{b}\t{%1, %0|%0, %1}"
9806 [(set_attr "type" "alu1")
9807 (set_attr "mode" "QI")])
9809 (define_insn "xorqi_ext_0"
9810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9815 (match_operand 1 "ext_register_operand" "0")
9818 (match_operand 2 "const_int_operand" "n")))
9819 (clobber (reg:CC FLAGS_REG))]
9820 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9821 "xor{b}\t{%2, %h0|%h0, %2}"
9822 [(set_attr "type" "alu")
9823 (set_attr "length_immediate" "1")
9824 (set_attr "mode" "QI")])
9826 (define_insn "*xorqi_ext_1"
9827 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9832 (match_operand 1 "ext_register_operand" "0")
9836 (match_operand:QI 2 "general_operand" "Qm"))))
9837 (clobber (reg:CC FLAGS_REG))]
9839 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9840 "xor{b}\t{%2, %h0|%h0, %2}"
9841 [(set_attr "type" "alu")
9842 (set_attr "length_immediate" "0")
9843 (set_attr "mode" "QI")])
9845 (define_insn "*xorqi_ext_1_rex64"
9846 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9851 (match_operand 1 "ext_register_operand" "0")
9855 (match_operand 2 "ext_register_operand" "Q"))))
9856 (clobber (reg:CC FLAGS_REG))]
9858 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9859 "xor{b}\t{%2, %h0|%h0, %2}"
9860 [(set_attr "type" "alu")
9861 (set_attr "length_immediate" "0")
9862 (set_attr "mode" "QI")])
9864 (define_insn "*xorqi_ext_2"
9865 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9869 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9872 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9875 (clobber (reg:CC FLAGS_REG))]
9876 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9877 "xor{b}\t{%h2, %h0|%h0, %h2}"
9878 [(set_attr "type" "alu")
9879 (set_attr "length_immediate" "0")
9880 (set_attr "mode" "QI")])
9882 (define_insn "*xorqi_cc_1"
9883 [(set (reg FLAGS_REG)
9885 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9886 (match_operand:QI 2 "general_operand" "qim,qi"))
9888 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9889 (xor:QI (match_dup 1) (match_dup 2)))]
9890 "ix86_match_ccmode (insn, CCNOmode)
9891 && ix86_binary_operator_ok (XOR, QImode, operands)"
9892 "xor{b}\t{%2, %0|%0, %2}"
9893 [(set_attr "type" "alu")
9894 (set_attr "mode" "QI")])
9896 (define_insn "*xorqi_2_slp"
9897 [(set (reg FLAGS_REG)
9898 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9899 (match_operand:QI 1 "general_operand" "qim,qi"))
9901 (set (strict_low_part (match_dup 0))
9902 (xor:QI (match_dup 0) (match_dup 1)))]
9903 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9904 && ix86_match_ccmode (insn, CCNOmode)
9905 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9906 "xor{b}\t{%1, %0|%0, %1}"
9907 [(set_attr "type" "alu1")
9908 (set_attr "mode" "QI")])
9910 (define_insn "*xorqi_cc_2"
9911 [(set (reg FLAGS_REG)
9913 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9914 (match_operand:QI 2 "general_operand" "qim"))
9916 (clobber (match_scratch:QI 0 "=q"))]
9917 "ix86_match_ccmode (insn, CCNOmode)
9918 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9919 "xor{b}\t{%2, %0|%0, %2}"
9920 [(set_attr "type" "alu")
9921 (set_attr "mode" "QI")])
9923 (define_insn "*xorqi_cc_ext_1"
9924 [(set (reg FLAGS_REG)
9928 (match_operand 1 "ext_register_operand" "0")
9931 (match_operand:QI 2 "general_operand" "qmn"))
9933 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9937 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9939 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9940 "xor{b}\t{%2, %h0|%h0, %2}"
9941 [(set_attr "type" "alu")
9942 (set_attr "mode" "QI")])
9944 (define_insn "*xorqi_cc_ext_1_rex64"
9945 [(set (reg FLAGS_REG)
9949 (match_operand 1 "ext_register_operand" "0")
9952 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9954 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9958 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9960 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9961 "xor{b}\t{%2, %h0|%h0, %2}"
9962 [(set_attr "type" "alu")
9963 (set_attr "mode" "QI")])
9965 (define_expand "xorqi_cc_ext_1"
9967 (set (reg:CCNO FLAGS_REG)
9971 (match_operand 1 "ext_register_operand" "")
9974 (match_operand:QI 2 "general_operand" ""))
9976 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9980 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9986 [(set (match_operand 0 "register_operand" "")
9987 (xor (match_operand 1 "register_operand" "")
9988 (match_operand 2 "const_int_operand" "")))
9989 (clobber (reg:CC FLAGS_REG))]
9991 && QI_REG_P (operands[0])
9992 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9993 && !(INTVAL (operands[2]) & ~(255 << 8))
9994 && GET_MODE (operands[0]) != QImode"
9995 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9996 (xor:SI (zero_extract:SI (match_dup 1)
9997 (const_int 8) (const_int 8))
9999 (clobber (reg:CC FLAGS_REG))])]
10000 "operands[0] = gen_lowpart (SImode, operands[0]);
10001 operands[1] = gen_lowpart (SImode, operands[1]);
10002 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10004 ;; Since XOR can be encoded with sign extended immediate, this is only
10005 ;; profitable when 7th bit is set.
10007 [(set (match_operand 0 "register_operand" "")
10008 (xor (match_operand 1 "general_operand" "")
10009 (match_operand 2 "const_int_operand" "")))
10010 (clobber (reg:CC FLAGS_REG))]
10012 && ANY_QI_REG_P (operands[0])
10013 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10014 && !(INTVAL (operands[2]) & ~255)
10015 && (INTVAL (operands[2]) & 128)
10016 && GET_MODE (operands[0]) != QImode"
10017 [(parallel [(set (strict_low_part (match_dup 0))
10018 (xor:QI (match_dup 1)
10020 (clobber (reg:CC FLAGS_REG))])]
10021 "operands[0] = gen_lowpart (QImode, operands[0]);
10022 operands[1] = gen_lowpart (QImode, operands[1]);
10023 operands[2] = gen_lowpart (QImode, operands[2]);")
10025 ;; Negation instructions
10027 (define_expand "negti2"
10028 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10029 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10030 (clobber (reg:CC FLAGS_REG))])]
10032 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10034 (define_insn "*negti2_1"
10035 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10036 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10037 (clobber (reg:CC FLAGS_REG))]
10039 && ix86_unary_operator_ok (NEG, TImode, operands)"
10043 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10044 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10045 (clobber (reg:CC FLAGS_REG))]
10046 "TARGET_64BIT && reload_completed"
10048 [(set (reg:CCZ FLAGS_REG)
10049 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10050 (set (match_dup 0) (neg:DI (match_dup 2)))])
10052 [(set (match_dup 1)
10053 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10056 (clobber (reg:CC FLAGS_REG))])
10058 [(set (match_dup 1)
10059 (neg:DI (match_dup 1)))
10060 (clobber (reg:CC FLAGS_REG))])]
10061 "split_ti (operands+1, 1, operands+2, operands+3);
10062 split_ti (operands+0, 1, operands+0, operands+1);")
10064 (define_expand "negdi2"
10065 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10066 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10067 (clobber (reg:CC FLAGS_REG))])]
10069 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10071 (define_insn "*negdi2_1"
10072 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10073 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10074 (clobber (reg:CC FLAGS_REG))]
10076 && ix86_unary_operator_ok (NEG, DImode, operands)"
10080 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10081 (neg:DI (match_operand:DI 1 "general_operand" "")))
10082 (clobber (reg:CC FLAGS_REG))]
10083 "!TARGET_64BIT && reload_completed"
10085 [(set (reg:CCZ FLAGS_REG)
10086 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10087 (set (match_dup 0) (neg:SI (match_dup 2)))])
10089 [(set (match_dup 1)
10090 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10093 (clobber (reg:CC FLAGS_REG))])
10095 [(set (match_dup 1)
10096 (neg:SI (match_dup 1)))
10097 (clobber (reg:CC FLAGS_REG))])]
10098 "split_di (operands+1, 1, operands+2, operands+3);
10099 split_di (operands+0, 1, operands+0, operands+1);")
10101 (define_insn "*negdi2_1_rex64"
10102 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10103 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10104 (clobber (reg:CC FLAGS_REG))]
10105 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10107 [(set_attr "type" "negnot")
10108 (set_attr "mode" "DI")])
10110 ;; The problem with neg is that it does not perform (compare x 0),
10111 ;; it really performs (compare 0 x), which leaves us with the zero
10112 ;; flag being the only useful item.
10114 (define_insn "*negdi2_cmpz_rex64"
10115 [(set (reg:CCZ FLAGS_REG)
10116 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10118 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10119 (neg:DI (match_dup 1)))]
10120 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10122 [(set_attr "type" "negnot")
10123 (set_attr "mode" "DI")])
10126 (define_expand "negsi2"
10127 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10128 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10129 (clobber (reg:CC FLAGS_REG))])]
10131 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10133 (define_insn "*negsi2_1"
10134 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10135 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10136 (clobber (reg:CC FLAGS_REG))]
10137 "ix86_unary_operator_ok (NEG, SImode, operands)"
10139 [(set_attr "type" "negnot")
10140 (set_attr "mode" "SI")])
10142 ;; Combine is quite creative about this pattern.
10143 (define_insn "*negsi2_1_zext"
10144 [(set (match_operand:DI 0 "register_operand" "=r")
10145 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10148 (clobber (reg:CC FLAGS_REG))]
10149 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10151 [(set_attr "type" "negnot")
10152 (set_attr "mode" "SI")])
10154 ;; The problem with neg is that it does not perform (compare x 0),
10155 ;; it really performs (compare 0 x), which leaves us with the zero
10156 ;; flag being the only useful item.
10158 (define_insn "*negsi2_cmpz"
10159 [(set (reg:CCZ FLAGS_REG)
10160 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10162 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10163 (neg:SI (match_dup 1)))]
10164 "ix86_unary_operator_ok (NEG, SImode, operands)"
10166 [(set_attr "type" "negnot")
10167 (set_attr "mode" "SI")])
10169 (define_insn "*negsi2_cmpz_zext"
10170 [(set (reg:CCZ FLAGS_REG)
10171 (compare:CCZ (lshiftrt:DI
10173 (match_operand:DI 1 "register_operand" "0")
10177 (set (match_operand:DI 0 "register_operand" "=r")
10178 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10181 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10183 [(set_attr "type" "negnot")
10184 (set_attr "mode" "SI")])
10186 (define_expand "neghi2"
10187 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10188 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10189 (clobber (reg:CC FLAGS_REG))])]
10190 "TARGET_HIMODE_MATH"
10191 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10193 (define_insn "*neghi2_1"
10194 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10195 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10196 (clobber (reg:CC FLAGS_REG))]
10197 "ix86_unary_operator_ok (NEG, HImode, operands)"
10199 [(set_attr "type" "negnot")
10200 (set_attr "mode" "HI")])
10202 (define_insn "*neghi2_cmpz"
10203 [(set (reg:CCZ FLAGS_REG)
10204 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10206 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10207 (neg:HI (match_dup 1)))]
10208 "ix86_unary_operator_ok (NEG, HImode, operands)"
10210 [(set_attr "type" "negnot")
10211 (set_attr "mode" "HI")])
10213 (define_expand "negqi2"
10214 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10215 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10216 (clobber (reg:CC FLAGS_REG))])]
10217 "TARGET_QIMODE_MATH"
10218 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10220 (define_insn "*negqi2_1"
10221 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10222 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "ix86_unary_operator_ok (NEG, QImode, operands)"
10226 [(set_attr "type" "negnot")
10227 (set_attr "mode" "QI")])
10229 (define_insn "*negqi2_cmpz"
10230 [(set (reg:CCZ FLAGS_REG)
10231 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10233 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10234 (neg:QI (match_dup 1)))]
10235 "ix86_unary_operator_ok (NEG, QImode, operands)"
10237 [(set_attr "type" "negnot")
10238 (set_attr "mode" "QI")])
10240 ;; Changing of sign for FP values is doable using integer unit too.
10242 (define_expand "neg<mode>2"
10243 [(set (match_operand:X87MODEF 0 "register_operand" "")
10244 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10245 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10246 "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10248 (define_expand "abs<mode>2"
10249 [(set (match_operand:X87MODEF 0 "register_operand" "")
10250 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10251 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10252 "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10254 (define_insn "*absneg<mode>2_mixed"
10255 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10256 (match_operator:MODEF 3 "absneg_operator"
10257 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10258 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10259 (clobber (reg:CC FLAGS_REG))]
10260 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10263 (define_insn "*absneg<mode>2_sse"
10264 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10265 (match_operator:MODEF 3 "absneg_operator"
10266 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10267 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10268 (clobber (reg:CC FLAGS_REG))]
10269 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10272 (define_insn "*absneg<mode>2_i387"
10273 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10274 (match_operator:X87MODEF 3 "absneg_operator"
10275 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10276 (use (match_operand 2 "" ""))
10277 (clobber (reg:CC FLAGS_REG))]
10278 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10281 (define_expand "negtf2"
10282 [(set (match_operand:TF 0 "register_operand" "")
10283 (neg:TF (match_operand:TF 1 "register_operand" "")))]
10285 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10287 (define_expand "abstf2"
10288 [(set (match_operand:TF 0 "register_operand" "")
10289 (abs:TF (match_operand:TF 1 "register_operand" "")))]
10291 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10293 (define_insn "*absnegtf2_sse"
10294 [(set (match_operand:TF 0 "register_operand" "=x,x")
10295 (match_operator:TF 3 "absneg_operator"
10296 [(match_operand:TF 1 "register_operand" "0,x")]))
10297 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10298 (clobber (reg:CC FLAGS_REG))]
10302 ;; Splitters for fp abs and neg.
10305 [(set (match_operand 0 "fp_register_operand" "")
10306 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10307 (use (match_operand 2 "" ""))
10308 (clobber (reg:CC FLAGS_REG))]
10310 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10313 [(set (match_operand 0 "register_operand" "")
10314 (match_operator 3 "absneg_operator"
10315 [(match_operand 1 "register_operand" "")]))
10316 (use (match_operand 2 "nonimmediate_operand" ""))
10317 (clobber (reg:CC FLAGS_REG))]
10318 "reload_completed && SSE_REG_P (operands[0])"
10319 [(set (match_dup 0) (match_dup 3))]
10321 enum machine_mode mode = GET_MODE (operands[0]);
10322 enum machine_mode vmode = GET_MODE (operands[2]);
10325 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10326 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10327 if (operands_match_p (operands[0], operands[2]))
10330 operands[1] = operands[2];
10333 if (GET_CODE (operands[3]) == ABS)
10334 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10336 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10341 [(set (match_operand:SF 0 "register_operand" "")
10342 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10343 (use (match_operand:V4SF 2 "" ""))
10344 (clobber (reg:CC FLAGS_REG))]
10346 [(parallel [(set (match_dup 0) (match_dup 1))
10347 (clobber (reg:CC FLAGS_REG))])]
10350 operands[0] = gen_lowpart (SImode, operands[0]);
10351 if (GET_CODE (operands[1]) == ABS)
10353 tmp = gen_int_mode (0x7fffffff, SImode);
10354 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10358 tmp = gen_int_mode (0x80000000, SImode);
10359 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10365 [(set (match_operand:DF 0 "register_operand" "")
10366 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10367 (use (match_operand 2 "" ""))
10368 (clobber (reg:CC FLAGS_REG))]
10370 [(parallel [(set (match_dup 0) (match_dup 1))
10371 (clobber (reg:CC FLAGS_REG))])]
10376 tmp = gen_lowpart (DImode, operands[0]);
10377 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10380 if (GET_CODE (operands[1]) == ABS)
10383 tmp = gen_rtx_NOT (DImode, tmp);
10387 operands[0] = gen_highpart (SImode, operands[0]);
10388 if (GET_CODE (operands[1]) == ABS)
10390 tmp = gen_int_mode (0x7fffffff, SImode);
10391 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10395 tmp = gen_int_mode (0x80000000, SImode);
10396 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10403 [(set (match_operand:XF 0 "register_operand" "")
10404 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10405 (use (match_operand 2 "" ""))
10406 (clobber (reg:CC FLAGS_REG))]
10408 [(parallel [(set (match_dup 0) (match_dup 1))
10409 (clobber (reg:CC FLAGS_REG))])]
10412 operands[0] = gen_rtx_REG (SImode,
10413 true_regnum (operands[0])
10414 + (TARGET_64BIT ? 1 : 2));
10415 if (GET_CODE (operands[1]) == ABS)
10417 tmp = GEN_INT (0x7fff);
10418 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10422 tmp = GEN_INT (0x8000);
10423 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10428 ;; Conditionalize these after reload. If they match before reload, we
10429 ;; lose the clobber and ability to use integer instructions.
10431 (define_insn "*neg<mode>2_1"
10432 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10433 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10435 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10437 [(set_attr "type" "fsgn")
10438 (set_attr "mode" "<MODE>")])
10440 (define_insn "*abs<mode>2_1"
10441 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10442 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10444 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10446 [(set_attr "type" "fsgn")
10447 (set_attr "mode" "<MODE>")])
10449 (define_insn "*negextendsfdf2"
10450 [(set (match_operand:DF 0 "register_operand" "=f")
10451 (neg:DF (float_extend:DF
10452 (match_operand:SF 1 "register_operand" "0"))))]
10453 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10455 [(set_attr "type" "fsgn")
10456 (set_attr "mode" "DF")])
10458 (define_insn "*negextenddfxf2"
10459 [(set (match_operand:XF 0 "register_operand" "=f")
10460 (neg:XF (float_extend:XF
10461 (match_operand:DF 1 "register_operand" "0"))))]
10464 [(set_attr "type" "fsgn")
10465 (set_attr "mode" "XF")])
10467 (define_insn "*negextendsfxf2"
10468 [(set (match_operand:XF 0 "register_operand" "=f")
10469 (neg:XF (float_extend:XF
10470 (match_operand:SF 1 "register_operand" "0"))))]
10473 [(set_attr "type" "fsgn")
10474 (set_attr "mode" "XF")])
10476 (define_insn "*absextendsfdf2"
10477 [(set (match_operand:DF 0 "register_operand" "=f")
10478 (abs:DF (float_extend:DF
10479 (match_operand:SF 1 "register_operand" "0"))))]
10480 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10482 [(set_attr "type" "fsgn")
10483 (set_attr "mode" "DF")])
10485 (define_insn "*absextenddfxf2"
10486 [(set (match_operand:XF 0 "register_operand" "=f")
10487 (abs:XF (float_extend:XF
10488 (match_operand:DF 1 "register_operand" "0"))))]
10491 [(set_attr "type" "fsgn")
10492 (set_attr "mode" "XF")])
10494 (define_insn "*absextendsfxf2"
10495 [(set (match_operand:XF 0 "register_operand" "=f")
10496 (abs:XF (float_extend:XF
10497 (match_operand:SF 1 "register_operand" "0"))))]
10500 [(set_attr "type" "fsgn")
10501 (set_attr "mode" "XF")])
10503 ;; Copysign instructions
10505 (define_mode_iterator CSGNMODE [SF DF TF])
10506 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10508 (define_expand "copysign<mode>3"
10509 [(match_operand:CSGNMODE 0 "register_operand" "")
10510 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10511 (match_operand:CSGNMODE 2 "register_operand" "")]
10512 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10513 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10515 ix86_expand_copysign (operands);
10519 (define_insn_and_split "copysign<mode>3_const"
10520 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10522 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10523 (match_operand:CSGNMODE 2 "register_operand" "0")
10524 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10526 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10527 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10529 "&& reload_completed"
10532 ix86_split_copysign_const (operands);
10536 (define_insn "copysign<mode>3_var"
10537 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10539 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10540 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10541 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10542 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10544 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10545 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10546 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10550 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10552 [(match_operand:CSGNMODE 2 "register_operand" "")
10553 (match_operand:CSGNMODE 3 "register_operand" "")
10554 (match_operand:<CSGNVMODE> 4 "" "")
10555 (match_operand:<CSGNVMODE> 5 "" "")]
10557 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10558 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10559 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10560 && reload_completed"
10563 ix86_split_copysign_var (operands);
10567 ;; One complement instructions
10569 (define_expand "one_cmpldi2"
10570 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10571 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10573 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10575 (define_insn "*one_cmpldi2_1_rex64"
10576 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10577 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10578 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10580 [(set_attr "type" "negnot")
10581 (set_attr "mode" "DI")])
10583 (define_insn "*one_cmpldi2_2_rex64"
10584 [(set (reg FLAGS_REG)
10585 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10587 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10588 (not:DI (match_dup 1)))]
10589 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10590 && ix86_unary_operator_ok (NOT, DImode, operands)"
10592 [(set_attr "type" "alu1")
10593 (set_attr "mode" "DI")])
10596 [(set (match_operand 0 "flags_reg_operand" "")
10597 (match_operator 2 "compare_operator"
10598 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10600 (set (match_operand:DI 1 "nonimmediate_operand" "")
10601 (not:DI (match_dup 3)))]
10602 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10603 [(parallel [(set (match_dup 0)
10605 [(xor:DI (match_dup 3) (const_int -1))
10608 (xor:DI (match_dup 3) (const_int -1)))])]
10611 (define_expand "one_cmplsi2"
10612 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10613 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10615 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10617 (define_insn "*one_cmplsi2_1"
10618 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10619 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10620 "ix86_unary_operator_ok (NOT, SImode, operands)"
10622 [(set_attr "type" "negnot")
10623 (set_attr "mode" "SI")])
10625 ;; ??? Currently never generated - xor is used instead.
10626 (define_insn "*one_cmplsi2_1_zext"
10627 [(set (match_operand:DI 0 "register_operand" "=r")
10628 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10629 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10631 [(set_attr "type" "negnot")
10632 (set_attr "mode" "SI")])
10634 (define_insn "*one_cmplsi2_2"
10635 [(set (reg FLAGS_REG)
10636 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10638 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10639 (not:SI (match_dup 1)))]
10640 "ix86_match_ccmode (insn, CCNOmode)
10641 && ix86_unary_operator_ok (NOT, SImode, operands)"
10643 [(set_attr "type" "alu1")
10644 (set_attr "mode" "SI")])
10647 [(set (match_operand 0 "flags_reg_operand" "")
10648 (match_operator 2 "compare_operator"
10649 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10651 (set (match_operand:SI 1 "nonimmediate_operand" "")
10652 (not:SI (match_dup 3)))]
10653 "ix86_match_ccmode (insn, CCNOmode)"
10654 [(parallel [(set (match_dup 0)
10655 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10658 (xor:SI (match_dup 3) (const_int -1)))])]
10661 ;; ??? Currently never generated - xor is used instead.
10662 (define_insn "*one_cmplsi2_2_zext"
10663 [(set (reg FLAGS_REG)
10664 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10666 (set (match_operand:DI 0 "register_operand" "=r")
10667 (zero_extend:DI (not:SI (match_dup 1))))]
10668 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10669 && ix86_unary_operator_ok (NOT, SImode, operands)"
10671 [(set_attr "type" "alu1")
10672 (set_attr "mode" "SI")])
10675 [(set (match_operand 0 "flags_reg_operand" "")
10676 (match_operator 2 "compare_operator"
10677 [(not:SI (match_operand:SI 3 "register_operand" ""))
10679 (set (match_operand:DI 1 "register_operand" "")
10680 (zero_extend:DI (not:SI (match_dup 3))))]
10681 "ix86_match_ccmode (insn, CCNOmode)"
10682 [(parallel [(set (match_dup 0)
10683 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10686 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10689 (define_expand "one_cmplhi2"
10690 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10691 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10692 "TARGET_HIMODE_MATH"
10693 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10695 (define_insn "*one_cmplhi2_1"
10696 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10697 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10698 "ix86_unary_operator_ok (NOT, HImode, operands)"
10700 [(set_attr "type" "negnot")
10701 (set_attr "mode" "HI")])
10703 (define_insn "*one_cmplhi2_2"
10704 [(set (reg FLAGS_REG)
10705 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10707 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10708 (not:HI (match_dup 1)))]
10709 "ix86_match_ccmode (insn, CCNOmode)
10710 && ix86_unary_operator_ok (NEG, HImode, operands)"
10712 [(set_attr "type" "alu1")
10713 (set_attr "mode" "HI")])
10716 [(set (match_operand 0 "flags_reg_operand" "")
10717 (match_operator 2 "compare_operator"
10718 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10720 (set (match_operand:HI 1 "nonimmediate_operand" "")
10721 (not:HI (match_dup 3)))]
10722 "ix86_match_ccmode (insn, CCNOmode)"
10723 [(parallel [(set (match_dup 0)
10724 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10727 (xor:HI (match_dup 3) (const_int -1)))])]
10730 ;; %%% Potential partial reg stall on alternative 1. What to do?
10731 (define_expand "one_cmplqi2"
10732 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10733 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10734 "TARGET_QIMODE_MATH"
10735 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10737 (define_insn "*one_cmplqi2_1"
10738 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10739 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10740 "ix86_unary_operator_ok (NOT, QImode, operands)"
10744 [(set_attr "type" "negnot")
10745 (set_attr "mode" "QI,SI")])
10747 (define_insn "*one_cmplqi2_2"
10748 [(set (reg FLAGS_REG)
10749 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10751 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10752 (not:QI (match_dup 1)))]
10753 "ix86_match_ccmode (insn, CCNOmode)
10754 && ix86_unary_operator_ok (NOT, QImode, operands)"
10756 [(set_attr "type" "alu1")
10757 (set_attr "mode" "QI")])
10760 [(set (match_operand 0 "flags_reg_operand" "")
10761 (match_operator 2 "compare_operator"
10762 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10764 (set (match_operand:QI 1 "nonimmediate_operand" "")
10765 (not:QI (match_dup 3)))]
10766 "ix86_match_ccmode (insn, CCNOmode)"
10767 [(parallel [(set (match_dup 0)
10768 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10771 (xor:QI (match_dup 3) (const_int -1)))])]
10774 ;; Arithmetic shift instructions
10776 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10777 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10778 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10779 ;; from the assembler input.
10781 ;; This instruction shifts the target reg/mem as usual, but instead of
10782 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10783 ;; is a left shift double, bits are taken from the high order bits of
10784 ;; reg, else if the insn is a shift right double, bits are taken from the
10785 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10786 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10788 ;; Since sh[lr]d does not change the `reg' operand, that is done
10789 ;; separately, making all shifts emit pairs of shift double and normal
10790 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10791 ;; support a 63 bit shift, each shift where the count is in a reg expands
10792 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10794 ;; If the shift count is a constant, we need never emit more than one
10795 ;; shift pair, instead using moves and sign extension for counts greater
10798 (define_expand "ashlti3"
10799 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10800 (ashift:TI (match_operand:TI 1 "register_operand" "")
10801 (match_operand:QI 2 "nonmemory_operand" "")))
10802 (clobber (reg:CC FLAGS_REG))])]
10805 if (! immediate_operand (operands[2], QImode))
10807 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10810 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10814 (define_insn "ashlti3_1"
10815 [(set (match_operand:TI 0 "register_operand" "=r")
10816 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10817 (match_operand:QI 2 "register_operand" "c")))
10818 (clobber (match_scratch:DI 3 "=&r"))
10819 (clobber (reg:CC FLAGS_REG))]
10822 [(set_attr "type" "multi")])
10824 ;; This pattern must be defined before *ashlti3_2 to prevent
10825 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10827 (define_insn "sse2_ashlti3"
10828 [(set (match_operand:TI 0 "register_operand" "=x")
10829 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10830 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10833 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10834 return "pslldq\t{%2, %0|%0, %2}";
10836 [(set_attr "type" "sseishft")
10837 (set_attr "prefix_data16" "1")
10838 (set_attr "mode" "TI")])
10840 (define_insn "*ashlti3_2"
10841 [(set (match_operand:TI 0 "register_operand" "=r")
10842 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10843 (match_operand:QI 2 "immediate_operand" "O")))
10844 (clobber (reg:CC FLAGS_REG))]
10847 [(set_attr "type" "multi")])
10850 [(set (match_operand:TI 0 "register_operand" "")
10851 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10852 (match_operand:QI 2 "register_operand" "")))
10853 (clobber (match_scratch:DI 3 ""))
10854 (clobber (reg:CC FLAGS_REG))]
10855 "TARGET_64BIT && reload_completed"
10857 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10860 [(set (match_operand:TI 0 "register_operand" "")
10861 (ashift:TI (match_operand:TI 1 "register_operand" "")
10862 (match_operand:QI 2 "immediate_operand" "")))
10863 (clobber (reg:CC FLAGS_REG))]
10864 "TARGET_64BIT && reload_completed"
10866 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10868 (define_insn "x86_64_shld"
10869 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10870 (ior:DI (ashift:DI (match_dup 0)
10871 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10872 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10873 (minus:QI (const_int 64) (match_dup 2)))))
10874 (clobber (reg:CC FLAGS_REG))]
10877 shld{q}\t{%2, %1, %0|%0, %1, %2}
10878 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10879 [(set_attr "type" "ishift")
10880 (set_attr "prefix_0f" "1")
10881 (set_attr "mode" "DI")
10882 (set_attr "athlon_decode" "vector")
10883 (set_attr "amdfam10_decode" "vector")])
10885 (define_expand "x86_64_shift_adj"
10886 [(set (reg:CCZ FLAGS_REG)
10887 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10890 (set (match_operand:DI 0 "register_operand" "")
10891 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10892 (match_operand:DI 1 "register_operand" "")
10895 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10896 (match_operand:DI 3 "register_operand" "r")
10901 (define_expand "ashldi3"
10902 [(set (match_operand:DI 0 "shiftdi_operand" "")
10903 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10904 (match_operand:QI 2 "nonmemory_operand" "")))]
10906 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10908 (define_insn "*ashldi3_1_rex64"
10909 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10910 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10911 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10912 (clobber (reg:CC FLAGS_REG))]
10913 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10915 switch (get_attr_type (insn))
10918 gcc_assert (operands[2] == const1_rtx);
10919 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10920 return "add{q}\t%0, %0";
10923 gcc_assert (CONST_INT_P (operands[2]));
10924 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10925 operands[1] = gen_rtx_MULT (DImode, operands[1],
10926 GEN_INT (1 << INTVAL (operands[2])));
10927 return "lea{q}\t{%a1, %0|%0, %a1}";
10930 if (REG_P (operands[2]))
10931 return "sal{q}\t{%b2, %0|%0, %b2}";
10932 else if (operands[2] == const1_rtx
10933 && (TARGET_SHIFT1 || optimize_size))
10934 return "sal{q}\t%0";
10936 return "sal{q}\t{%2, %0|%0, %2}";
10939 [(set (attr "type")
10940 (cond [(eq_attr "alternative" "1")
10941 (const_string "lea")
10942 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10944 (match_operand 0 "register_operand" ""))
10945 (match_operand 2 "const1_operand" ""))
10946 (const_string "alu")
10948 (const_string "ishift")))
10949 (set_attr "mode" "DI")])
10951 ;; Convert lea to the lea pattern to avoid flags dependency.
10953 [(set (match_operand:DI 0 "register_operand" "")
10954 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10955 (match_operand:QI 2 "immediate_operand" "")))
10956 (clobber (reg:CC FLAGS_REG))]
10957 "TARGET_64BIT && reload_completed
10958 && true_regnum (operands[0]) != true_regnum (operands[1])"
10959 [(set (match_dup 0)
10960 (mult:DI (match_dup 1)
10962 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10964 ;; This pattern can't accept a variable shift count, since shifts by
10965 ;; zero don't affect the flags. We assume that shifts by constant
10966 ;; zero are optimized away.
10967 (define_insn "*ashldi3_cmp_rex64"
10968 [(set (reg FLAGS_REG)
10970 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10971 (match_operand:QI 2 "immediate_operand" "e"))
10973 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10974 (ashift:DI (match_dup 1) (match_dup 2)))]
10977 || !TARGET_PARTIAL_FLAG_REG_STALL
10978 || (operands[2] == const1_rtx
10980 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10981 && ix86_match_ccmode (insn, CCGOCmode)
10982 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10984 switch (get_attr_type (insn))
10987 gcc_assert (operands[2] == const1_rtx);
10988 return "add{q}\t%0, %0";
10991 if (REG_P (operands[2]))
10992 return "sal{q}\t{%b2, %0|%0, %b2}";
10993 else if (operands[2] == const1_rtx
10994 && (TARGET_SHIFT1 || optimize_size))
10995 return "sal{q}\t%0";
10997 return "sal{q}\t{%2, %0|%0, %2}";
11000 [(set (attr "type")
11001 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11003 (match_operand 0 "register_operand" ""))
11004 (match_operand 2 "const1_operand" ""))
11005 (const_string "alu")
11007 (const_string "ishift")))
11008 (set_attr "mode" "DI")])
11010 (define_insn "*ashldi3_cconly_rex64"
11011 [(set (reg FLAGS_REG)
11013 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11014 (match_operand:QI 2 "immediate_operand" "e"))
11016 (clobber (match_scratch:DI 0 "=r"))]
11019 || !TARGET_PARTIAL_FLAG_REG_STALL
11020 || (operands[2] == const1_rtx
11022 || TARGET_DOUBLE_WITH_ADD)))
11023 && ix86_match_ccmode (insn, CCGOCmode)
11024 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11026 switch (get_attr_type (insn))
11029 gcc_assert (operands[2] == const1_rtx);
11030 return "add{q}\t%0, %0";
11033 if (REG_P (operands[2]))
11034 return "sal{q}\t{%b2, %0|%0, %b2}";
11035 else if (operands[2] == const1_rtx
11036 && (TARGET_SHIFT1 || optimize_size))
11037 return "sal{q}\t%0";
11039 return "sal{q}\t{%2, %0|%0, %2}";
11042 [(set (attr "type")
11043 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11045 (match_operand 0 "register_operand" ""))
11046 (match_operand 2 "const1_operand" ""))
11047 (const_string "alu")
11049 (const_string "ishift")))
11050 (set_attr "mode" "DI")])
11052 (define_insn "*ashldi3_1"
11053 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11054 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11055 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11056 (clobber (reg:CC FLAGS_REG))]
11059 [(set_attr "type" "multi")])
11061 ;; By default we don't ask for a scratch register, because when DImode
11062 ;; values are manipulated, registers are already at a premium. But if
11063 ;; we have one handy, we won't turn it away.
11065 [(match_scratch:SI 3 "r")
11066 (parallel [(set (match_operand:DI 0 "register_operand" "")
11067 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11068 (match_operand:QI 2 "nonmemory_operand" "")))
11069 (clobber (reg:CC FLAGS_REG))])
11071 "!TARGET_64BIT && TARGET_CMOVE"
11073 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11076 [(set (match_operand:DI 0 "register_operand" "")
11077 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11078 (match_operand:QI 2 "nonmemory_operand" "")))
11079 (clobber (reg:CC FLAGS_REG))]
11080 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11081 ? epilogue_completed : reload_completed)"
11083 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11085 (define_insn "x86_shld_1"
11086 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11087 (ior:SI (ashift:SI (match_dup 0)
11088 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11089 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11090 (minus:QI (const_int 32) (match_dup 2)))))
11091 (clobber (reg:CC FLAGS_REG))]
11094 shld{l}\t{%2, %1, %0|%0, %1, %2}
11095 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11096 [(set_attr "type" "ishift")
11097 (set_attr "prefix_0f" "1")
11098 (set_attr "mode" "SI")
11099 (set_attr "pent_pair" "np")
11100 (set_attr "athlon_decode" "vector")
11101 (set_attr "amdfam10_decode" "vector")])
11103 (define_expand "x86_shift_adj_1"
11104 [(set (reg:CCZ FLAGS_REG)
11105 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11108 (set (match_operand:SI 0 "register_operand" "")
11109 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11110 (match_operand:SI 1 "register_operand" "")
11113 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11114 (match_operand:SI 3 "register_operand" "r")
11119 (define_expand "x86_shift_adj_2"
11120 [(use (match_operand:SI 0 "register_operand" ""))
11121 (use (match_operand:SI 1 "register_operand" ""))
11122 (use (match_operand:QI 2 "register_operand" ""))]
11125 rtx label = gen_label_rtx ();
11128 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11130 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11131 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11132 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11133 gen_rtx_LABEL_REF (VOIDmode, label),
11135 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11136 JUMP_LABEL (tmp) = label;
11138 emit_move_insn (operands[0], operands[1]);
11139 ix86_expand_clear (operands[1]);
11141 emit_label (label);
11142 LABEL_NUSES (label) = 1;
11147 (define_expand "ashlsi3"
11148 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11149 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11150 (match_operand:QI 2 "nonmemory_operand" "")))
11151 (clobber (reg:CC FLAGS_REG))]
11153 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11155 (define_insn "*ashlsi3_1"
11156 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11157 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11158 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11159 (clobber (reg:CC FLAGS_REG))]
11160 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11162 switch (get_attr_type (insn))
11165 gcc_assert (operands[2] == const1_rtx);
11166 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11167 return "add{l}\t%0, %0";
11173 if (REG_P (operands[2]))
11174 return "sal{l}\t{%b2, %0|%0, %b2}";
11175 else if (operands[2] == const1_rtx
11176 && (TARGET_SHIFT1 || optimize_size))
11177 return "sal{l}\t%0";
11179 return "sal{l}\t{%2, %0|%0, %2}";
11182 [(set (attr "type")
11183 (cond [(eq_attr "alternative" "1")
11184 (const_string "lea")
11185 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11187 (match_operand 0 "register_operand" ""))
11188 (match_operand 2 "const1_operand" ""))
11189 (const_string "alu")
11191 (const_string "ishift")))
11192 (set_attr "mode" "SI")])
11194 ;; Convert lea to the lea pattern to avoid flags dependency.
11196 [(set (match_operand 0 "register_operand" "")
11197 (ashift (match_operand 1 "index_register_operand" "")
11198 (match_operand:QI 2 "const_int_operand" "")))
11199 (clobber (reg:CC FLAGS_REG))]
11201 && true_regnum (operands[0]) != true_regnum (operands[1])
11202 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11206 enum machine_mode mode = GET_MODE (operands[0]);
11208 if (GET_MODE_SIZE (mode) < 4)
11209 operands[0] = gen_lowpart (SImode, operands[0]);
11211 operands[1] = gen_lowpart (Pmode, operands[1]);
11212 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11214 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11215 if (Pmode != SImode)
11216 pat = gen_rtx_SUBREG (SImode, pat, 0);
11217 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11221 ;; Rare case of shifting RSP is handled by generating move and shift
11223 [(set (match_operand 0 "register_operand" "")
11224 (ashift (match_operand 1 "register_operand" "")
11225 (match_operand:QI 2 "const_int_operand" "")))
11226 (clobber (reg:CC FLAGS_REG))]
11228 && true_regnum (operands[0]) != true_regnum (operands[1])"
11232 emit_move_insn (operands[0], operands[1]);
11233 pat = gen_rtx_SET (VOIDmode, operands[0],
11234 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11235 operands[0], operands[2]));
11236 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11237 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11241 (define_insn "*ashlsi3_1_zext"
11242 [(set (match_operand:DI 0 "register_operand" "=r,r")
11243 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11244 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11245 (clobber (reg:CC FLAGS_REG))]
11246 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11248 switch (get_attr_type (insn))
11251 gcc_assert (operands[2] == const1_rtx);
11252 return "add{l}\t%k0, %k0";
11258 if (REG_P (operands[2]))
11259 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11260 else if (operands[2] == const1_rtx
11261 && (TARGET_SHIFT1 || optimize_size))
11262 return "sal{l}\t%k0";
11264 return "sal{l}\t{%2, %k0|%k0, %2}";
11267 [(set (attr "type")
11268 (cond [(eq_attr "alternative" "1")
11269 (const_string "lea")
11270 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11272 (match_operand 2 "const1_operand" ""))
11273 (const_string "alu")
11275 (const_string "ishift")))
11276 (set_attr "mode" "SI")])
11278 ;; Convert lea to the lea pattern to avoid flags dependency.
11280 [(set (match_operand:DI 0 "register_operand" "")
11281 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11282 (match_operand:QI 2 "const_int_operand" ""))))
11283 (clobber (reg:CC FLAGS_REG))]
11284 "TARGET_64BIT && reload_completed
11285 && true_regnum (operands[0]) != true_regnum (operands[1])"
11286 [(set (match_dup 0) (zero_extend:DI
11287 (subreg:SI (mult:SI (match_dup 1)
11288 (match_dup 2)) 0)))]
11290 operands[1] = gen_lowpart (Pmode, operands[1]);
11291 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11294 ;; This pattern can't accept a variable shift count, since shifts by
11295 ;; zero don't affect the flags. We assume that shifts by constant
11296 ;; zero are optimized away.
11297 (define_insn "*ashlsi3_cmp"
11298 [(set (reg FLAGS_REG)
11300 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11301 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11303 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11304 (ashift:SI (match_dup 1) (match_dup 2)))]
11306 || !TARGET_PARTIAL_FLAG_REG_STALL
11307 || (operands[2] == const1_rtx
11309 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11310 && ix86_match_ccmode (insn, CCGOCmode)
11311 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11313 switch (get_attr_type (insn))
11316 gcc_assert (operands[2] == const1_rtx);
11317 return "add{l}\t%0, %0";
11320 if (REG_P (operands[2]))
11321 return "sal{l}\t{%b2, %0|%0, %b2}";
11322 else if (operands[2] == const1_rtx
11323 && (TARGET_SHIFT1 || optimize_size))
11324 return "sal{l}\t%0";
11326 return "sal{l}\t{%2, %0|%0, %2}";
11329 [(set (attr "type")
11330 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11332 (match_operand 0 "register_operand" ""))
11333 (match_operand 2 "const1_operand" ""))
11334 (const_string "alu")
11336 (const_string "ishift")))
11337 (set_attr "mode" "SI")])
11339 (define_insn "*ashlsi3_cconly"
11340 [(set (reg FLAGS_REG)
11342 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11343 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11345 (clobber (match_scratch:SI 0 "=r"))]
11347 || !TARGET_PARTIAL_FLAG_REG_STALL
11348 || (operands[2] == const1_rtx
11350 || TARGET_DOUBLE_WITH_ADD)))
11351 && ix86_match_ccmode (insn, CCGOCmode)
11352 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11354 switch (get_attr_type (insn))
11357 gcc_assert (operands[2] == const1_rtx);
11358 return "add{l}\t%0, %0";
11361 if (REG_P (operands[2]))
11362 return "sal{l}\t{%b2, %0|%0, %b2}";
11363 else if (operands[2] == const1_rtx
11364 && (TARGET_SHIFT1 || optimize_size))
11365 return "sal{l}\t%0";
11367 return "sal{l}\t{%2, %0|%0, %2}";
11370 [(set (attr "type")
11371 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11373 (match_operand 0 "register_operand" ""))
11374 (match_operand 2 "const1_operand" ""))
11375 (const_string "alu")
11377 (const_string "ishift")))
11378 (set_attr "mode" "SI")])
11380 (define_insn "*ashlsi3_cmp_zext"
11381 [(set (reg FLAGS_REG)
11383 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11384 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11386 (set (match_operand:DI 0 "register_operand" "=r")
11387 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11390 || !TARGET_PARTIAL_FLAG_REG_STALL
11391 || (operands[2] == const1_rtx
11393 || TARGET_DOUBLE_WITH_ADD)))
11394 && ix86_match_ccmode (insn, CCGOCmode)
11395 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11397 switch (get_attr_type (insn))
11400 gcc_assert (operands[2] == const1_rtx);
11401 return "add{l}\t%k0, %k0";
11404 if (REG_P (operands[2]))
11405 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11406 else if (operands[2] == const1_rtx
11407 && (TARGET_SHIFT1 || optimize_size))
11408 return "sal{l}\t%k0";
11410 return "sal{l}\t{%2, %k0|%k0, %2}";
11413 [(set (attr "type")
11414 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11416 (match_operand 2 "const1_operand" ""))
11417 (const_string "alu")
11419 (const_string "ishift")))
11420 (set_attr "mode" "SI")])
11422 (define_expand "ashlhi3"
11423 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11424 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11425 (match_operand:QI 2 "nonmemory_operand" "")))
11426 (clobber (reg:CC FLAGS_REG))]
11427 "TARGET_HIMODE_MATH"
11428 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11430 (define_insn "*ashlhi3_1_lea"
11431 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11432 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11433 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11434 (clobber (reg:CC FLAGS_REG))]
11435 "!TARGET_PARTIAL_REG_STALL
11436 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11438 switch (get_attr_type (insn))
11443 gcc_assert (operands[2] == const1_rtx);
11444 return "add{w}\t%0, %0";
11447 if (REG_P (operands[2]))
11448 return "sal{w}\t{%b2, %0|%0, %b2}";
11449 else if (operands[2] == const1_rtx
11450 && (TARGET_SHIFT1 || optimize_size))
11451 return "sal{w}\t%0";
11453 return "sal{w}\t{%2, %0|%0, %2}";
11456 [(set (attr "type")
11457 (cond [(eq_attr "alternative" "1")
11458 (const_string "lea")
11459 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11461 (match_operand 0 "register_operand" ""))
11462 (match_operand 2 "const1_operand" ""))
11463 (const_string "alu")
11465 (const_string "ishift")))
11466 (set_attr "mode" "HI,SI")])
11468 (define_insn "*ashlhi3_1"
11469 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11470 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11471 (match_operand:QI 2 "nonmemory_operand" "cI")))
11472 (clobber (reg:CC FLAGS_REG))]
11473 "TARGET_PARTIAL_REG_STALL
11474 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11476 switch (get_attr_type (insn))
11479 gcc_assert (operands[2] == const1_rtx);
11480 return "add{w}\t%0, %0";
11483 if (REG_P (operands[2]))
11484 return "sal{w}\t{%b2, %0|%0, %b2}";
11485 else if (operands[2] == const1_rtx
11486 && (TARGET_SHIFT1 || optimize_size))
11487 return "sal{w}\t%0";
11489 return "sal{w}\t{%2, %0|%0, %2}";
11492 [(set (attr "type")
11493 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11495 (match_operand 0 "register_operand" ""))
11496 (match_operand 2 "const1_operand" ""))
11497 (const_string "alu")
11499 (const_string "ishift")))
11500 (set_attr "mode" "HI")])
11502 ;; This pattern can't accept a variable shift count, since shifts by
11503 ;; zero don't affect the flags. We assume that shifts by constant
11504 ;; zero are optimized away.
11505 (define_insn "*ashlhi3_cmp"
11506 [(set (reg FLAGS_REG)
11508 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11509 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11511 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11512 (ashift:HI (match_dup 1) (match_dup 2)))]
11514 || !TARGET_PARTIAL_FLAG_REG_STALL
11515 || (operands[2] == const1_rtx
11517 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11518 && ix86_match_ccmode (insn, CCGOCmode)
11519 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11521 switch (get_attr_type (insn))
11524 gcc_assert (operands[2] == const1_rtx);
11525 return "add{w}\t%0, %0";
11528 if (REG_P (operands[2]))
11529 return "sal{w}\t{%b2, %0|%0, %b2}";
11530 else if (operands[2] == const1_rtx
11531 && (TARGET_SHIFT1 || optimize_size))
11532 return "sal{w}\t%0";
11534 return "sal{w}\t{%2, %0|%0, %2}";
11537 [(set (attr "type")
11538 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11540 (match_operand 0 "register_operand" ""))
11541 (match_operand 2 "const1_operand" ""))
11542 (const_string "alu")
11544 (const_string "ishift")))
11545 (set_attr "mode" "HI")])
11547 (define_insn "*ashlhi3_cconly"
11548 [(set (reg FLAGS_REG)
11550 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11551 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11553 (clobber (match_scratch:HI 0 "=r"))]
11555 || !TARGET_PARTIAL_FLAG_REG_STALL
11556 || (operands[2] == const1_rtx
11558 || TARGET_DOUBLE_WITH_ADD)))
11559 && ix86_match_ccmode (insn, CCGOCmode)
11560 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11562 switch (get_attr_type (insn))
11565 gcc_assert (operands[2] == const1_rtx);
11566 return "add{w}\t%0, %0";
11569 if (REG_P (operands[2]))
11570 return "sal{w}\t{%b2, %0|%0, %b2}";
11571 else if (operands[2] == const1_rtx
11572 && (TARGET_SHIFT1 || optimize_size))
11573 return "sal{w}\t%0";
11575 return "sal{w}\t{%2, %0|%0, %2}";
11578 [(set (attr "type")
11579 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11581 (match_operand 0 "register_operand" ""))
11582 (match_operand 2 "const1_operand" ""))
11583 (const_string "alu")
11585 (const_string "ishift")))
11586 (set_attr "mode" "HI")])
11588 (define_expand "ashlqi3"
11589 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11590 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11591 (match_operand:QI 2 "nonmemory_operand" "")))
11592 (clobber (reg:CC FLAGS_REG))]
11593 "TARGET_QIMODE_MATH"
11594 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11596 ;; %%% Potential partial reg stall on alternative 2. What to do?
11598 (define_insn "*ashlqi3_1_lea"
11599 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11600 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11601 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11602 (clobber (reg:CC FLAGS_REG))]
11603 "!TARGET_PARTIAL_REG_STALL
11604 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11606 switch (get_attr_type (insn))
11611 gcc_assert (operands[2] == const1_rtx);
11612 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11613 return "add{l}\t%k0, %k0";
11615 return "add{b}\t%0, %0";
11618 if (REG_P (operands[2]))
11620 if (get_attr_mode (insn) == MODE_SI)
11621 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11623 return "sal{b}\t{%b2, %0|%0, %b2}";
11625 else if (operands[2] == const1_rtx
11626 && (TARGET_SHIFT1 || optimize_size))
11628 if (get_attr_mode (insn) == MODE_SI)
11629 return "sal{l}\t%0";
11631 return "sal{b}\t%0";
11635 if (get_attr_mode (insn) == MODE_SI)
11636 return "sal{l}\t{%2, %k0|%k0, %2}";
11638 return "sal{b}\t{%2, %0|%0, %2}";
11642 [(set (attr "type")
11643 (cond [(eq_attr "alternative" "2")
11644 (const_string "lea")
11645 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11647 (match_operand 0 "register_operand" ""))
11648 (match_operand 2 "const1_operand" ""))
11649 (const_string "alu")
11651 (const_string "ishift")))
11652 (set_attr "mode" "QI,SI,SI")])
11654 (define_insn "*ashlqi3_1"
11655 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11656 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11657 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11658 (clobber (reg:CC FLAGS_REG))]
11659 "TARGET_PARTIAL_REG_STALL
11660 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11662 switch (get_attr_type (insn))
11665 gcc_assert (operands[2] == const1_rtx);
11666 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11667 return "add{l}\t%k0, %k0";
11669 return "add{b}\t%0, %0";
11672 if (REG_P (operands[2]))
11674 if (get_attr_mode (insn) == MODE_SI)
11675 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11677 return "sal{b}\t{%b2, %0|%0, %b2}";
11679 else if (operands[2] == const1_rtx
11680 && (TARGET_SHIFT1 || optimize_size))
11682 if (get_attr_mode (insn) == MODE_SI)
11683 return "sal{l}\t%0";
11685 return "sal{b}\t%0";
11689 if (get_attr_mode (insn) == MODE_SI)
11690 return "sal{l}\t{%2, %k0|%k0, %2}";
11692 return "sal{b}\t{%2, %0|%0, %2}";
11696 [(set (attr "type")
11697 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11699 (match_operand 0 "register_operand" ""))
11700 (match_operand 2 "const1_operand" ""))
11701 (const_string "alu")
11703 (const_string "ishift")))
11704 (set_attr "mode" "QI,SI")])
11706 ;; This pattern can't accept a variable shift count, since shifts by
11707 ;; zero don't affect the flags. We assume that shifts by constant
11708 ;; zero are optimized away.
11709 (define_insn "*ashlqi3_cmp"
11710 [(set (reg FLAGS_REG)
11712 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11713 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11715 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11716 (ashift:QI (match_dup 1) (match_dup 2)))]
11718 || !TARGET_PARTIAL_FLAG_REG_STALL
11719 || (operands[2] == const1_rtx
11721 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11722 && ix86_match_ccmode (insn, CCGOCmode)
11723 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11725 switch (get_attr_type (insn))
11728 gcc_assert (operands[2] == const1_rtx);
11729 return "add{b}\t%0, %0";
11732 if (REG_P (operands[2]))
11733 return "sal{b}\t{%b2, %0|%0, %b2}";
11734 else if (operands[2] == const1_rtx
11735 && (TARGET_SHIFT1 || optimize_size))
11736 return "sal{b}\t%0";
11738 return "sal{b}\t{%2, %0|%0, %2}";
11741 [(set (attr "type")
11742 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11744 (match_operand 0 "register_operand" ""))
11745 (match_operand 2 "const1_operand" ""))
11746 (const_string "alu")
11748 (const_string "ishift")))
11749 (set_attr "mode" "QI")])
11751 (define_insn "*ashlqi3_cconly"
11752 [(set (reg FLAGS_REG)
11754 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11755 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11757 (clobber (match_scratch:QI 0 "=q"))]
11759 || !TARGET_PARTIAL_FLAG_REG_STALL
11760 || (operands[2] == const1_rtx
11762 || TARGET_DOUBLE_WITH_ADD)))
11763 && ix86_match_ccmode (insn, CCGOCmode)
11764 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11766 switch (get_attr_type (insn))
11769 gcc_assert (operands[2] == const1_rtx);
11770 return "add{b}\t%0, %0";
11773 if (REG_P (operands[2]))
11774 return "sal{b}\t{%b2, %0|%0, %b2}";
11775 else if (operands[2] == const1_rtx
11776 && (TARGET_SHIFT1 || optimize_size))
11777 return "sal{b}\t%0";
11779 return "sal{b}\t{%2, %0|%0, %2}";
11782 [(set (attr "type")
11783 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11785 (match_operand 0 "register_operand" ""))
11786 (match_operand 2 "const1_operand" ""))
11787 (const_string "alu")
11789 (const_string "ishift")))
11790 (set_attr "mode" "QI")])
11792 ;; See comment above `ashldi3' about how this works.
11794 (define_expand "ashrti3"
11795 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11796 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11797 (match_operand:QI 2 "nonmemory_operand" "")))
11798 (clobber (reg:CC FLAGS_REG))])]
11801 if (! immediate_operand (operands[2], QImode))
11803 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11806 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11810 (define_insn "ashrti3_1"
11811 [(set (match_operand:TI 0 "register_operand" "=r")
11812 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11813 (match_operand:QI 2 "register_operand" "c")))
11814 (clobber (match_scratch:DI 3 "=&r"))
11815 (clobber (reg:CC FLAGS_REG))]
11818 [(set_attr "type" "multi")])
11820 (define_insn "*ashrti3_2"
11821 [(set (match_operand:TI 0 "register_operand" "=r")
11822 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11823 (match_operand:QI 2 "immediate_operand" "O")))
11824 (clobber (reg:CC FLAGS_REG))]
11827 [(set_attr "type" "multi")])
11830 [(set (match_operand:TI 0 "register_operand" "")
11831 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11832 (match_operand:QI 2 "register_operand" "")))
11833 (clobber (match_scratch:DI 3 ""))
11834 (clobber (reg:CC FLAGS_REG))]
11835 "TARGET_64BIT && reload_completed"
11837 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11840 [(set (match_operand:TI 0 "register_operand" "")
11841 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11842 (match_operand:QI 2 "immediate_operand" "")))
11843 (clobber (reg:CC FLAGS_REG))]
11844 "TARGET_64BIT && reload_completed"
11846 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11848 (define_insn "x86_64_shrd"
11849 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11850 (ior:DI (ashiftrt:DI (match_dup 0)
11851 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11852 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11853 (minus:QI (const_int 64) (match_dup 2)))))
11854 (clobber (reg:CC FLAGS_REG))]
11857 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11858 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11859 [(set_attr "type" "ishift")
11860 (set_attr "prefix_0f" "1")
11861 (set_attr "mode" "DI")
11862 (set_attr "athlon_decode" "vector")
11863 (set_attr "amdfam10_decode" "vector")])
11865 (define_expand "ashrdi3"
11866 [(set (match_operand:DI 0 "shiftdi_operand" "")
11867 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11868 (match_operand:QI 2 "nonmemory_operand" "")))]
11870 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11872 (define_insn "*ashrdi3_63_rex64"
11873 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11874 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11875 (match_operand:DI 2 "const_int_operand" "i,i")))
11876 (clobber (reg:CC FLAGS_REG))]
11877 "TARGET_64BIT && INTVAL (operands[2]) == 63
11878 && (TARGET_USE_CLTD || optimize_size)
11879 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11882 sar{q}\t{%2, %0|%0, %2}"
11883 [(set_attr "type" "imovx,ishift")
11884 (set_attr "prefix_0f" "0,*")
11885 (set_attr "length_immediate" "0,*")
11886 (set_attr "modrm" "0,1")
11887 (set_attr "mode" "DI")])
11889 (define_insn "*ashrdi3_1_one_bit_rex64"
11890 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11891 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11892 (match_operand:QI 2 "const1_operand" "")))
11893 (clobber (reg:CC FLAGS_REG))]
11895 && (TARGET_SHIFT1 || optimize_size)
11896 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11898 [(set_attr "type" "ishift")
11899 (set (attr "length")
11900 (if_then_else (match_operand:DI 0 "register_operand" "")
11902 (const_string "*")))])
11904 (define_insn "*ashrdi3_1_rex64"
11905 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11906 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11907 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11908 (clobber (reg:CC FLAGS_REG))]
11909 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11911 sar{q}\t{%2, %0|%0, %2}
11912 sar{q}\t{%b2, %0|%0, %b2}"
11913 [(set_attr "type" "ishift")
11914 (set_attr "mode" "DI")])
11916 ;; This pattern can't accept a variable shift count, since shifts by
11917 ;; zero don't affect the flags. We assume that shifts by constant
11918 ;; zero are optimized away.
11919 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11920 [(set (reg FLAGS_REG)
11922 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11923 (match_operand:QI 2 "const1_operand" ""))
11925 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11926 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11928 && (TARGET_SHIFT1 || optimize_size)
11929 && ix86_match_ccmode (insn, CCGOCmode)
11930 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11932 [(set_attr "type" "ishift")
11933 (set (attr "length")
11934 (if_then_else (match_operand:DI 0 "register_operand" "")
11936 (const_string "*")))])
11938 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11939 [(set (reg FLAGS_REG)
11941 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11942 (match_operand:QI 2 "const1_operand" ""))
11944 (clobber (match_scratch:DI 0 "=r"))]
11946 && (TARGET_SHIFT1 || optimize_size)
11947 && ix86_match_ccmode (insn, CCGOCmode)
11948 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11950 [(set_attr "type" "ishift")
11951 (set_attr "length" "2")])
11953 ;; This pattern can't accept a variable shift count, since shifts by
11954 ;; zero don't affect the flags. We assume that shifts by constant
11955 ;; zero are optimized away.
11956 (define_insn "*ashrdi3_cmp_rex64"
11957 [(set (reg FLAGS_REG)
11959 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11960 (match_operand:QI 2 "const_int_operand" "n"))
11962 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11963 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11965 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11966 && ix86_match_ccmode (insn, CCGOCmode)
11967 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11968 "sar{q}\t{%2, %0|%0, %2}"
11969 [(set_attr "type" "ishift")
11970 (set_attr "mode" "DI")])
11972 (define_insn "*ashrdi3_cconly_rex64"
11973 [(set (reg FLAGS_REG)
11975 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11976 (match_operand:QI 2 "const_int_operand" "n"))
11978 (clobber (match_scratch:DI 0 "=r"))]
11980 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11981 && ix86_match_ccmode (insn, CCGOCmode)
11982 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11983 "sar{q}\t{%2, %0|%0, %2}"
11984 [(set_attr "type" "ishift")
11985 (set_attr "mode" "DI")])
11987 (define_insn "*ashrdi3_1"
11988 [(set (match_operand:DI 0 "register_operand" "=r")
11989 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11990 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11991 (clobber (reg:CC FLAGS_REG))]
11994 [(set_attr "type" "multi")])
11996 ;; By default we don't ask for a scratch register, because when DImode
11997 ;; values are manipulated, registers are already at a premium. But if
11998 ;; we have one handy, we won't turn it away.
12000 [(match_scratch:SI 3 "r")
12001 (parallel [(set (match_operand:DI 0 "register_operand" "")
12002 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12003 (match_operand:QI 2 "nonmemory_operand" "")))
12004 (clobber (reg:CC FLAGS_REG))])
12006 "!TARGET_64BIT && TARGET_CMOVE"
12008 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12011 [(set (match_operand:DI 0 "register_operand" "")
12012 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12013 (match_operand:QI 2 "nonmemory_operand" "")))
12014 (clobber (reg:CC FLAGS_REG))]
12015 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12016 ? epilogue_completed : reload_completed)"
12018 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12020 (define_insn "x86_shrd_1"
12021 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12022 (ior:SI (ashiftrt:SI (match_dup 0)
12023 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12024 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12025 (minus:QI (const_int 32) (match_dup 2)))))
12026 (clobber (reg:CC FLAGS_REG))]
12029 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12030 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12031 [(set_attr "type" "ishift")
12032 (set_attr "prefix_0f" "1")
12033 (set_attr "pent_pair" "np")
12034 (set_attr "mode" "SI")])
12036 (define_expand "x86_shift_adj_3"
12037 [(use (match_operand:SI 0 "register_operand" ""))
12038 (use (match_operand:SI 1 "register_operand" ""))
12039 (use (match_operand:QI 2 "register_operand" ""))]
12042 rtx label = gen_label_rtx ();
12045 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12047 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12048 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12049 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12050 gen_rtx_LABEL_REF (VOIDmode, label),
12052 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12053 JUMP_LABEL (tmp) = label;
12055 emit_move_insn (operands[0], operands[1]);
12056 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12058 emit_label (label);
12059 LABEL_NUSES (label) = 1;
12064 (define_insn "ashrsi3_31"
12065 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12066 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12067 (match_operand:SI 2 "const_int_operand" "i,i")))
12068 (clobber (reg:CC FLAGS_REG))]
12069 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12070 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12073 sar{l}\t{%2, %0|%0, %2}"
12074 [(set_attr "type" "imovx,ishift")
12075 (set_attr "prefix_0f" "0,*")
12076 (set_attr "length_immediate" "0,*")
12077 (set_attr "modrm" "0,1")
12078 (set_attr "mode" "SI")])
12080 (define_insn "*ashrsi3_31_zext"
12081 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12082 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12083 (match_operand:SI 2 "const_int_operand" "i,i"))))
12084 (clobber (reg:CC FLAGS_REG))]
12085 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12086 && INTVAL (operands[2]) == 31
12087 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12090 sar{l}\t{%2, %k0|%k0, %2}"
12091 [(set_attr "type" "imovx,ishift")
12092 (set_attr "prefix_0f" "0,*")
12093 (set_attr "length_immediate" "0,*")
12094 (set_attr "modrm" "0,1")
12095 (set_attr "mode" "SI")])
12097 (define_expand "ashrsi3"
12098 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12099 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12100 (match_operand:QI 2 "nonmemory_operand" "")))
12101 (clobber (reg:CC FLAGS_REG))]
12103 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12105 (define_insn "*ashrsi3_1_one_bit"
12106 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12107 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12108 (match_operand:QI 2 "const1_operand" "")))
12109 (clobber (reg:CC FLAGS_REG))]
12110 "(TARGET_SHIFT1 || optimize_size)
12111 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12113 [(set_attr "type" "ishift")
12114 (set (attr "length")
12115 (if_then_else (match_operand:SI 0 "register_operand" "")
12117 (const_string "*")))])
12119 (define_insn "*ashrsi3_1_one_bit_zext"
12120 [(set (match_operand:DI 0 "register_operand" "=r")
12121 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12122 (match_operand:QI 2 "const1_operand" ""))))
12123 (clobber (reg:CC FLAGS_REG))]
12125 && (TARGET_SHIFT1 || optimize_size)
12126 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12128 [(set_attr "type" "ishift")
12129 (set_attr "length" "2")])
12131 (define_insn "*ashrsi3_1"
12132 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12133 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12134 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12135 (clobber (reg:CC FLAGS_REG))]
12136 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12138 sar{l}\t{%2, %0|%0, %2}
12139 sar{l}\t{%b2, %0|%0, %b2}"
12140 [(set_attr "type" "ishift")
12141 (set_attr "mode" "SI")])
12143 (define_insn "*ashrsi3_1_zext"
12144 [(set (match_operand:DI 0 "register_operand" "=r,r")
12145 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12146 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12147 (clobber (reg:CC FLAGS_REG))]
12148 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12150 sar{l}\t{%2, %k0|%k0, %2}
12151 sar{l}\t{%b2, %k0|%k0, %b2}"
12152 [(set_attr "type" "ishift")
12153 (set_attr "mode" "SI")])
12155 ;; This pattern can't accept a variable shift count, since shifts by
12156 ;; zero don't affect the flags. We assume that shifts by constant
12157 ;; zero are optimized away.
12158 (define_insn "*ashrsi3_one_bit_cmp"
12159 [(set (reg FLAGS_REG)
12161 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12162 (match_operand:QI 2 "const1_operand" ""))
12164 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12165 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12166 "(TARGET_SHIFT1 || optimize_size)
12167 && ix86_match_ccmode (insn, CCGOCmode)
12168 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12170 [(set_attr "type" "ishift")
12171 (set (attr "length")
12172 (if_then_else (match_operand:SI 0 "register_operand" "")
12174 (const_string "*")))])
12176 (define_insn "*ashrsi3_one_bit_cconly"
12177 [(set (reg FLAGS_REG)
12179 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12180 (match_operand:QI 2 "const1_operand" ""))
12182 (clobber (match_scratch:SI 0 "=r"))]
12183 "(TARGET_SHIFT1 || optimize_size)
12184 && ix86_match_ccmode (insn, CCGOCmode)
12185 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12187 [(set_attr "type" "ishift")
12188 (set_attr "length" "2")])
12190 (define_insn "*ashrsi3_one_bit_cmp_zext"
12191 [(set (reg FLAGS_REG)
12193 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12194 (match_operand:QI 2 "const1_operand" ""))
12196 (set (match_operand:DI 0 "register_operand" "=r")
12197 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12199 && (TARGET_SHIFT1 || optimize_size)
12200 && ix86_match_ccmode (insn, CCmode)
12201 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12203 [(set_attr "type" "ishift")
12204 (set_attr "length" "2")])
12206 ;; This pattern can't accept a variable shift count, since shifts by
12207 ;; zero don't affect the flags. We assume that shifts by constant
12208 ;; zero are optimized away.
12209 (define_insn "*ashrsi3_cmp"
12210 [(set (reg FLAGS_REG)
12212 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12213 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12215 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12216 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12217 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12218 && ix86_match_ccmode (insn, CCGOCmode)
12219 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12220 "sar{l}\t{%2, %0|%0, %2}"
12221 [(set_attr "type" "ishift")
12222 (set_attr "mode" "SI")])
12224 (define_insn "*ashrsi3_cconly"
12225 [(set (reg FLAGS_REG)
12227 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12228 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12230 (clobber (match_scratch:SI 0 "=r"))]
12231 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12232 && ix86_match_ccmode (insn, CCGOCmode)
12233 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12234 "sar{l}\t{%2, %0|%0, %2}"
12235 [(set_attr "type" "ishift")
12236 (set_attr "mode" "SI")])
12238 (define_insn "*ashrsi3_cmp_zext"
12239 [(set (reg FLAGS_REG)
12241 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12242 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12244 (set (match_operand:DI 0 "register_operand" "=r")
12245 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12247 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12248 && ix86_match_ccmode (insn, CCGOCmode)
12249 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12250 "sar{l}\t{%2, %k0|%k0, %2}"
12251 [(set_attr "type" "ishift")
12252 (set_attr "mode" "SI")])
12254 (define_expand "ashrhi3"
12255 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12256 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12257 (match_operand:QI 2 "nonmemory_operand" "")))
12258 (clobber (reg:CC FLAGS_REG))]
12259 "TARGET_HIMODE_MATH"
12260 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12262 (define_insn "*ashrhi3_1_one_bit"
12263 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12264 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12265 (match_operand:QI 2 "const1_operand" "")))
12266 (clobber (reg:CC FLAGS_REG))]
12267 "(TARGET_SHIFT1 || optimize_size)
12268 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12270 [(set_attr "type" "ishift")
12271 (set (attr "length")
12272 (if_then_else (match_operand 0 "register_operand" "")
12274 (const_string "*")))])
12276 (define_insn "*ashrhi3_1"
12277 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12278 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12279 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12280 (clobber (reg:CC FLAGS_REG))]
12281 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12283 sar{w}\t{%2, %0|%0, %2}
12284 sar{w}\t{%b2, %0|%0, %b2}"
12285 [(set_attr "type" "ishift")
12286 (set_attr "mode" "HI")])
12288 ;; This pattern can't accept a variable shift count, since shifts by
12289 ;; zero don't affect the flags. We assume that shifts by constant
12290 ;; zero are optimized away.
12291 (define_insn "*ashrhi3_one_bit_cmp"
12292 [(set (reg FLAGS_REG)
12294 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12295 (match_operand:QI 2 "const1_operand" ""))
12297 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12298 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12299 "(TARGET_SHIFT1 || optimize_size)
12300 && ix86_match_ccmode (insn, CCGOCmode)
12301 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12303 [(set_attr "type" "ishift")
12304 (set (attr "length")
12305 (if_then_else (match_operand 0 "register_operand" "")
12307 (const_string "*")))])
12309 (define_insn "*ashrhi3_one_bit_cconly"
12310 [(set (reg FLAGS_REG)
12312 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12313 (match_operand:QI 2 "const1_operand" ""))
12315 (clobber (match_scratch:HI 0 "=r"))]
12316 "(TARGET_SHIFT1 || optimize_size)
12317 && ix86_match_ccmode (insn, CCGOCmode)
12318 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12320 [(set_attr "type" "ishift")
12321 (set_attr "length" "2")])
12323 ;; This pattern can't accept a variable shift count, since shifts by
12324 ;; zero don't affect the flags. We assume that shifts by constant
12325 ;; zero are optimized away.
12326 (define_insn "*ashrhi3_cmp"
12327 [(set (reg FLAGS_REG)
12329 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12330 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12332 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12333 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12334 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12335 && ix86_match_ccmode (insn, CCGOCmode)
12336 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12337 "sar{w}\t{%2, %0|%0, %2}"
12338 [(set_attr "type" "ishift")
12339 (set_attr "mode" "HI")])
12341 (define_insn "*ashrhi3_cconly"
12342 [(set (reg FLAGS_REG)
12344 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12345 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12347 (clobber (match_scratch:HI 0 "=r"))]
12348 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12349 && ix86_match_ccmode (insn, CCGOCmode)
12350 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12351 "sar{w}\t{%2, %0|%0, %2}"
12352 [(set_attr "type" "ishift")
12353 (set_attr "mode" "HI")])
12355 (define_expand "ashrqi3"
12356 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12357 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12358 (match_operand:QI 2 "nonmemory_operand" "")))
12359 (clobber (reg:CC FLAGS_REG))]
12360 "TARGET_QIMODE_MATH"
12361 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12363 (define_insn "*ashrqi3_1_one_bit"
12364 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12365 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12366 (match_operand:QI 2 "const1_operand" "")))
12367 (clobber (reg:CC FLAGS_REG))]
12368 "(TARGET_SHIFT1 || optimize_size)
12369 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12371 [(set_attr "type" "ishift")
12372 (set (attr "length")
12373 (if_then_else (match_operand 0 "register_operand" "")
12375 (const_string "*")))])
12377 (define_insn "*ashrqi3_1_one_bit_slp"
12378 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12379 (ashiftrt:QI (match_dup 0)
12380 (match_operand:QI 1 "const1_operand" "")))
12381 (clobber (reg:CC FLAGS_REG))]
12382 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12383 && (TARGET_SHIFT1 || optimize_size)
12384 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12386 [(set_attr "type" "ishift1")
12387 (set (attr "length")
12388 (if_then_else (match_operand 0 "register_operand" "")
12390 (const_string "*")))])
12392 (define_insn "*ashrqi3_1"
12393 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12394 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12395 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12396 (clobber (reg:CC FLAGS_REG))]
12397 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12399 sar{b}\t{%2, %0|%0, %2}
12400 sar{b}\t{%b2, %0|%0, %b2}"
12401 [(set_attr "type" "ishift")
12402 (set_attr "mode" "QI")])
12404 (define_insn "*ashrqi3_1_slp"
12405 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12406 (ashiftrt:QI (match_dup 0)
12407 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12408 (clobber (reg:CC FLAGS_REG))]
12409 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12410 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12412 sar{b}\t{%1, %0|%0, %1}
12413 sar{b}\t{%b1, %0|%0, %b1}"
12414 [(set_attr "type" "ishift1")
12415 (set_attr "mode" "QI")])
12417 ;; This pattern can't accept a variable shift count, since shifts by
12418 ;; zero don't affect the flags. We assume that shifts by constant
12419 ;; zero are optimized away.
12420 (define_insn "*ashrqi3_one_bit_cmp"
12421 [(set (reg FLAGS_REG)
12423 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12424 (match_operand:QI 2 "const1_operand" "I"))
12426 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12427 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12428 "(TARGET_SHIFT1 || optimize_size)
12429 && ix86_match_ccmode (insn, CCGOCmode)
12430 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12432 [(set_attr "type" "ishift")
12433 (set (attr "length")
12434 (if_then_else (match_operand 0 "register_operand" "")
12436 (const_string "*")))])
12438 (define_insn "*ashrqi3_one_bit_cconly"
12439 [(set (reg FLAGS_REG)
12441 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12442 (match_operand:QI 2 "const1_operand" "I"))
12444 (clobber (match_scratch:QI 0 "=q"))]
12445 "(TARGET_SHIFT1 || optimize_size)
12446 && ix86_match_ccmode (insn, CCGOCmode)
12447 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12449 [(set_attr "type" "ishift")
12450 (set_attr "length" "2")])
12452 ;; This pattern can't accept a variable shift count, since shifts by
12453 ;; zero don't affect the flags. We assume that shifts by constant
12454 ;; zero are optimized away.
12455 (define_insn "*ashrqi3_cmp"
12456 [(set (reg FLAGS_REG)
12458 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12459 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12461 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12462 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12463 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12464 && ix86_match_ccmode (insn, CCGOCmode)
12465 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12466 "sar{b}\t{%2, %0|%0, %2}"
12467 [(set_attr "type" "ishift")
12468 (set_attr "mode" "QI")])
12470 (define_insn "*ashrqi3_cconly"
12471 [(set (reg FLAGS_REG)
12473 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12474 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12476 (clobber (match_scratch:QI 0 "=q"))]
12477 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12478 && ix86_match_ccmode (insn, CCGOCmode)
12479 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12480 "sar{b}\t{%2, %0|%0, %2}"
12481 [(set_attr "type" "ishift")
12482 (set_attr "mode" "QI")])
12485 ;; Logical shift instructions
12487 ;; See comment above `ashldi3' about how this works.
12489 (define_expand "lshrti3"
12490 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12491 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12492 (match_operand:QI 2 "nonmemory_operand" "")))
12493 (clobber (reg:CC FLAGS_REG))])]
12496 if (! immediate_operand (operands[2], QImode))
12498 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12501 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12505 (define_insn "lshrti3_1"
12506 [(set (match_operand:TI 0 "register_operand" "=r")
12507 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12508 (match_operand:QI 2 "register_operand" "c")))
12509 (clobber (match_scratch:DI 3 "=&r"))
12510 (clobber (reg:CC FLAGS_REG))]
12513 [(set_attr "type" "multi")])
12515 ;; This pattern must be defined before *lshrti3_2 to prevent
12516 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12518 (define_insn "sse2_lshrti3"
12519 [(set (match_operand:TI 0 "register_operand" "=x")
12520 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12521 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12524 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12525 return "psrldq\t{%2, %0|%0, %2}";
12527 [(set_attr "type" "sseishft")
12528 (set_attr "prefix_data16" "1")
12529 (set_attr "mode" "TI")])
12531 (define_insn "*lshrti3_2"
12532 [(set (match_operand:TI 0 "register_operand" "=r")
12533 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12534 (match_operand:QI 2 "immediate_operand" "O")))
12535 (clobber (reg:CC FLAGS_REG))]
12538 [(set_attr "type" "multi")])
12541 [(set (match_operand:TI 0 "register_operand" "")
12542 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12543 (match_operand:QI 2 "register_operand" "")))
12544 (clobber (match_scratch:DI 3 ""))
12545 (clobber (reg:CC FLAGS_REG))]
12546 "TARGET_64BIT && reload_completed"
12548 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12551 [(set (match_operand:TI 0 "register_operand" "")
12552 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12553 (match_operand:QI 2 "immediate_operand" "")))
12554 (clobber (reg:CC FLAGS_REG))]
12555 "TARGET_64BIT && reload_completed"
12557 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12559 (define_expand "lshrdi3"
12560 [(set (match_operand:DI 0 "shiftdi_operand" "")
12561 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12562 (match_operand:QI 2 "nonmemory_operand" "")))]
12564 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12566 (define_insn "*lshrdi3_1_one_bit_rex64"
12567 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12568 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12569 (match_operand:QI 2 "const1_operand" "")))
12570 (clobber (reg:CC FLAGS_REG))]
12572 && (TARGET_SHIFT1 || optimize_size)
12573 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12575 [(set_attr "type" "ishift")
12576 (set (attr "length")
12577 (if_then_else (match_operand:DI 0 "register_operand" "")
12579 (const_string "*")))])
12581 (define_insn "*lshrdi3_1_rex64"
12582 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12583 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12584 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12585 (clobber (reg:CC FLAGS_REG))]
12586 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12588 shr{q}\t{%2, %0|%0, %2}
12589 shr{q}\t{%b2, %0|%0, %b2}"
12590 [(set_attr "type" "ishift")
12591 (set_attr "mode" "DI")])
12593 ;; This pattern can't accept a variable shift count, since shifts by
12594 ;; zero don't affect the flags. We assume that shifts by constant
12595 ;; zero are optimized away.
12596 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12597 [(set (reg FLAGS_REG)
12599 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12600 (match_operand:QI 2 "const1_operand" ""))
12602 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12603 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12605 && (TARGET_SHIFT1 || optimize_size)
12606 && ix86_match_ccmode (insn, CCGOCmode)
12607 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12609 [(set_attr "type" "ishift")
12610 (set (attr "length")
12611 (if_then_else (match_operand:DI 0 "register_operand" "")
12613 (const_string "*")))])
12615 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12616 [(set (reg FLAGS_REG)
12618 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12619 (match_operand:QI 2 "const1_operand" ""))
12621 (clobber (match_scratch:DI 0 "=r"))]
12623 && (TARGET_SHIFT1 || optimize_size)
12624 && ix86_match_ccmode (insn, CCGOCmode)
12625 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12627 [(set_attr "type" "ishift")
12628 (set_attr "length" "2")])
12630 ;; This pattern can't accept a variable shift count, since shifts by
12631 ;; zero don't affect the flags. We assume that shifts by constant
12632 ;; zero are optimized away.
12633 (define_insn "*lshrdi3_cmp_rex64"
12634 [(set (reg FLAGS_REG)
12636 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12637 (match_operand:QI 2 "const_int_operand" "e"))
12639 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12640 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12642 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12643 && ix86_match_ccmode (insn, CCGOCmode)
12644 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12645 "shr{q}\t{%2, %0|%0, %2}"
12646 [(set_attr "type" "ishift")
12647 (set_attr "mode" "DI")])
12649 (define_insn "*lshrdi3_cconly_rex64"
12650 [(set (reg FLAGS_REG)
12652 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12653 (match_operand:QI 2 "const_int_operand" "e"))
12655 (clobber (match_scratch:DI 0 "=r"))]
12657 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12658 && ix86_match_ccmode (insn, CCGOCmode)
12659 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12660 "shr{q}\t{%2, %0|%0, %2}"
12661 [(set_attr "type" "ishift")
12662 (set_attr "mode" "DI")])
12664 (define_insn "*lshrdi3_1"
12665 [(set (match_operand:DI 0 "register_operand" "=r")
12666 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12667 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12668 (clobber (reg:CC FLAGS_REG))]
12671 [(set_attr "type" "multi")])
12673 ;; By default we don't ask for a scratch register, because when DImode
12674 ;; values are manipulated, registers are already at a premium. But if
12675 ;; we have one handy, we won't turn it away.
12677 [(match_scratch:SI 3 "r")
12678 (parallel [(set (match_operand:DI 0 "register_operand" "")
12679 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12680 (match_operand:QI 2 "nonmemory_operand" "")))
12681 (clobber (reg:CC FLAGS_REG))])
12683 "!TARGET_64BIT && TARGET_CMOVE"
12685 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12688 [(set (match_operand:DI 0 "register_operand" "")
12689 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12690 (match_operand:QI 2 "nonmemory_operand" "")))
12691 (clobber (reg:CC FLAGS_REG))]
12692 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12693 ? epilogue_completed : reload_completed)"
12695 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12697 (define_expand "lshrsi3"
12698 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12699 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12700 (match_operand:QI 2 "nonmemory_operand" "")))
12701 (clobber (reg:CC FLAGS_REG))]
12703 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12705 (define_insn "*lshrsi3_1_one_bit"
12706 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12707 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12708 (match_operand:QI 2 "const1_operand" "")))
12709 (clobber (reg:CC FLAGS_REG))]
12710 "(TARGET_SHIFT1 || optimize_size)
12711 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12713 [(set_attr "type" "ishift")
12714 (set (attr "length")
12715 (if_then_else (match_operand:SI 0 "register_operand" "")
12717 (const_string "*")))])
12719 (define_insn "*lshrsi3_1_one_bit_zext"
12720 [(set (match_operand:DI 0 "register_operand" "=r")
12721 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12722 (match_operand:QI 2 "const1_operand" "")))
12723 (clobber (reg:CC FLAGS_REG))]
12725 && (TARGET_SHIFT1 || optimize_size)
12726 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12728 [(set_attr "type" "ishift")
12729 (set_attr "length" "2")])
12731 (define_insn "*lshrsi3_1"
12732 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12733 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12734 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12735 (clobber (reg:CC FLAGS_REG))]
12736 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12738 shr{l}\t{%2, %0|%0, %2}
12739 shr{l}\t{%b2, %0|%0, %b2}"
12740 [(set_attr "type" "ishift")
12741 (set_attr "mode" "SI")])
12743 (define_insn "*lshrsi3_1_zext"
12744 [(set (match_operand:DI 0 "register_operand" "=r,r")
12746 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12747 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12748 (clobber (reg:CC FLAGS_REG))]
12749 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12751 shr{l}\t{%2, %k0|%k0, %2}
12752 shr{l}\t{%b2, %k0|%k0, %b2}"
12753 [(set_attr "type" "ishift")
12754 (set_attr "mode" "SI")])
12756 ;; This pattern can't accept a variable shift count, since shifts by
12757 ;; zero don't affect the flags. We assume that shifts by constant
12758 ;; zero are optimized away.
12759 (define_insn "*lshrsi3_one_bit_cmp"
12760 [(set (reg FLAGS_REG)
12762 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12763 (match_operand:QI 2 "const1_operand" ""))
12765 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12766 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12767 "(TARGET_SHIFT1 || optimize_size)
12768 && ix86_match_ccmode (insn, CCGOCmode)
12769 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12771 [(set_attr "type" "ishift")
12772 (set (attr "length")
12773 (if_then_else (match_operand:SI 0 "register_operand" "")
12775 (const_string "*")))])
12777 (define_insn "*lshrsi3_one_bit_cconly"
12778 [(set (reg FLAGS_REG)
12780 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12781 (match_operand:QI 2 "const1_operand" ""))
12783 (clobber (match_scratch:SI 0 "=r"))]
12784 "(TARGET_SHIFT1 || optimize_size)
12785 && ix86_match_ccmode (insn, CCGOCmode)
12786 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12788 [(set_attr "type" "ishift")
12789 (set_attr "length" "2")])
12791 (define_insn "*lshrsi3_cmp_one_bit_zext"
12792 [(set (reg FLAGS_REG)
12794 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12795 (match_operand:QI 2 "const1_operand" ""))
12797 (set (match_operand:DI 0 "register_operand" "=r")
12798 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12800 && (TARGET_SHIFT1 || optimize_size)
12801 && ix86_match_ccmode (insn, CCGOCmode)
12802 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12804 [(set_attr "type" "ishift")
12805 (set_attr "length" "2")])
12807 ;; This pattern can't accept a variable shift count, since shifts by
12808 ;; zero don't affect the flags. We assume that shifts by constant
12809 ;; zero are optimized away.
12810 (define_insn "*lshrsi3_cmp"
12811 [(set (reg FLAGS_REG)
12813 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12814 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12816 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12817 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12818 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12819 && ix86_match_ccmode (insn, CCGOCmode)
12820 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12821 "shr{l}\t{%2, %0|%0, %2}"
12822 [(set_attr "type" "ishift")
12823 (set_attr "mode" "SI")])
12825 (define_insn "*lshrsi3_cconly"
12826 [(set (reg FLAGS_REG)
12828 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12829 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12831 (clobber (match_scratch:SI 0 "=r"))]
12832 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12833 && ix86_match_ccmode (insn, CCGOCmode)
12834 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12835 "shr{l}\t{%2, %0|%0, %2}"
12836 [(set_attr "type" "ishift")
12837 (set_attr "mode" "SI")])
12839 (define_insn "*lshrsi3_cmp_zext"
12840 [(set (reg FLAGS_REG)
12842 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12843 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12845 (set (match_operand:DI 0 "register_operand" "=r")
12846 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12848 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12849 && ix86_match_ccmode (insn, CCGOCmode)
12850 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12851 "shr{l}\t{%2, %k0|%k0, %2}"
12852 [(set_attr "type" "ishift")
12853 (set_attr "mode" "SI")])
12855 (define_expand "lshrhi3"
12856 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12857 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12858 (match_operand:QI 2 "nonmemory_operand" "")))
12859 (clobber (reg:CC FLAGS_REG))]
12860 "TARGET_HIMODE_MATH"
12861 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12863 (define_insn "*lshrhi3_1_one_bit"
12864 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12865 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12866 (match_operand:QI 2 "const1_operand" "")))
12867 (clobber (reg:CC FLAGS_REG))]
12868 "(TARGET_SHIFT1 || optimize_size)
12869 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12871 [(set_attr "type" "ishift")
12872 (set (attr "length")
12873 (if_then_else (match_operand 0 "register_operand" "")
12875 (const_string "*")))])
12877 (define_insn "*lshrhi3_1"
12878 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12879 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12880 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12881 (clobber (reg:CC FLAGS_REG))]
12882 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12884 shr{w}\t{%2, %0|%0, %2}
12885 shr{w}\t{%b2, %0|%0, %b2}"
12886 [(set_attr "type" "ishift")
12887 (set_attr "mode" "HI")])
12889 ;; This pattern can't accept a variable shift count, since shifts by
12890 ;; zero don't affect the flags. We assume that shifts by constant
12891 ;; zero are optimized away.
12892 (define_insn "*lshrhi3_one_bit_cmp"
12893 [(set (reg FLAGS_REG)
12895 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12896 (match_operand:QI 2 "const1_operand" ""))
12898 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12899 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12900 "(TARGET_SHIFT1 || optimize_size)
12901 && ix86_match_ccmode (insn, CCGOCmode)
12902 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12904 [(set_attr "type" "ishift")
12905 (set (attr "length")
12906 (if_then_else (match_operand:SI 0 "register_operand" "")
12908 (const_string "*")))])
12910 (define_insn "*lshrhi3_one_bit_cconly"
12911 [(set (reg FLAGS_REG)
12913 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12914 (match_operand:QI 2 "const1_operand" ""))
12916 (clobber (match_scratch:HI 0 "=r"))]
12917 "(TARGET_SHIFT1 || optimize_size)
12918 && ix86_match_ccmode (insn, CCGOCmode)
12919 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12921 [(set_attr "type" "ishift")
12922 (set_attr "length" "2")])
12924 ;; This pattern can't accept a variable shift count, since shifts by
12925 ;; zero don't affect the flags. We assume that shifts by constant
12926 ;; zero are optimized away.
12927 (define_insn "*lshrhi3_cmp"
12928 [(set (reg FLAGS_REG)
12930 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12931 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12933 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12934 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12935 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12936 && ix86_match_ccmode (insn, CCGOCmode)
12937 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12938 "shr{w}\t{%2, %0|%0, %2}"
12939 [(set_attr "type" "ishift")
12940 (set_attr "mode" "HI")])
12942 (define_insn "*lshrhi3_cconly"
12943 [(set (reg FLAGS_REG)
12945 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12946 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12948 (clobber (match_scratch:HI 0 "=r"))]
12949 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12950 && ix86_match_ccmode (insn, CCGOCmode)
12951 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12952 "shr{w}\t{%2, %0|%0, %2}"
12953 [(set_attr "type" "ishift")
12954 (set_attr "mode" "HI")])
12956 (define_expand "lshrqi3"
12957 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12958 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12959 (match_operand:QI 2 "nonmemory_operand" "")))
12960 (clobber (reg:CC FLAGS_REG))]
12961 "TARGET_QIMODE_MATH"
12962 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12964 (define_insn "*lshrqi3_1_one_bit"
12965 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12966 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12967 (match_operand:QI 2 "const1_operand" "")))
12968 (clobber (reg:CC FLAGS_REG))]
12969 "(TARGET_SHIFT1 || optimize_size)
12970 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12972 [(set_attr "type" "ishift")
12973 (set (attr "length")
12974 (if_then_else (match_operand 0 "register_operand" "")
12976 (const_string "*")))])
12978 (define_insn "*lshrqi3_1_one_bit_slp"
12979 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12980 (lshiftrt:QI (match_dup 0)
12981 (match_operand:QI 1 "const1_operand" "")))
12982 (clobber (reg:CC FLAGS_REG))]
12983 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12984 && (TARGET_SHIFT1 || optimize_size)"
12986 [(set_attr "type" "ishift1")
12987 (set (attr "length")
12988 (if_then_else (match_operand 0 "register_operand" "")
12990 (const_string "*")))])
12992 (define_insn "*lshrqi3_1"
12993 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12994 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12995 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12996 (clobber (reg:CC FLAGS_REG))]
12997 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12999 shr{b}\t{%2, %0|%0, %2}
13000 shr{b}\t{%b2, %0|%0, %b2}"
13001 [(set_attr "type" "ishift")
13002 (set_attr "mode" "QI")])
13004 (define_insn "*lshrqi3_1_slp"
13005 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13006 (lshiftrt:QI (match_dup 0)
13007 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13008 (clobber (reg:CC FLAGS_REG))]
13009 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13010 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13012 shr{b}\t{%1, %0|%0, %1}
13013 shr{b}\t{%b1, %0|%0, %b1}"
13014 [(set_attr "type" "ishift1")
13015 (set_attr "mode" "QI")])
13017 ;; This pattern can't accept a variable shift count, since shifts by
13018 ;; zero don't affect the flags. We assume that shifts by constant
13019 ;; zero are optimized away.
13020 (define_insn "*lshrqi2_one_bit_cmp"
13021 [(set (reg FLAGS_REG)
13023 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13024 (match_operand:QI 2 "const1_operand" ""))
13026 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13027 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13028 "(TARGET_SHIFT1 || optimize_size)
13029 && ix86_match_ccmode (insn, CCGOCmode)
13030 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13032 [(set_attr "type" "ishift")
13033 (set (attr "length")
13034 (if_then_else (match_operand:SI 0 "register_operand" "")
13036 (const_string "*")))])
13038 (define_insn "*lshrqi2_one_bit_cconly"
13039 [(set (reg FLAGS_REG)
13041 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13042 (match_operand:QI 2 "const1_operand" ""))
13044 (clobber (match_scratch:QI 0 "=q"))]
13045 "(TARGET_SHIFT1 || optimize_size)
13046 && ix86_match_ccmode (insn, CCGOCmode)
13047 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13049 [(set_attr "type" "ishift")
13050 (set_attr "length" "2")])
13052 ;; This pattern can't accept a variable shift count, since shifts by
13053 ;; zero don't affect the flags. We assume that shifts by constant
13054 ;; zero are optimized away.
13055 (define_insn "*lshrqi2_cmp"
13056 [(set (reg FLAGS_REG)
13058 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13059 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13061 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13062 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13063 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13064 && ix86_match_ccmode (insn, CCGOCmode)
13065 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13066 "shr{b}\t{%2, %0|%0, %2}"
13067 [(set_attr "type" "ishift")
13068 (set_attr "mode" "QI")])
13070 (define_insn "*lshrqi2_cconly"
13071 [(set (reg FLAGS_REG)
13073 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13074 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13076 (clobber (match_scratch:QI 0 "=q"))]
13077 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13078 && ix86_match_ccmode (insn, CCGOCmode)
13079 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13080 "shr{b}\t{%2, %0|%0, %2}"
13081 [(set_attr "type" "ishift")
13082 (set_attr "mode" "QI")])
13084 ;; Rotate instructions
13086 (define_expand "rotldi3"
13087 [(set (match_operand:DI 0 "shiftdi_operand" "")
13088 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13089 (match_operand:QI 2 "nonmemory_operand" "")))
13090 (clobber (reg:CC FLAGS_REG))]
13095 ix86_expand_binary_operator (ROTATE, DImode, operands);
13098 if (!const_1_to_31_operand (operands[2], VOIDmode))
13100 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13104 ;; Implement rotation using two double-precision shift instructions
13105 ;; and a scratch register.
13106 (define_insn_and_split "ix86_rotldi3"
13107 [(set (match_operand:DI 0 "register_operand" "=r")
13108 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13109 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13110 (clobber (reg:CC FLAGS_REG))
13111 (clobber (match_scratch:SI 3 "=&r"))]
13114 "&& reload_completed"
13115 [(set (match_dup 3) (match_dup 4))
13117 [(set (match_dup 4)
13118 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13119 (lshiftrt:SI (match_dup 5)
13120 (minus:QI (const_int 32) (match_dup 2)))))
13121 (clobber (reg:CC FLAGS_REG))])
13123 [(set (match_dup 5)
13124 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13125 (lshiftrt:SI (match_dup 3)
13126 (minus:QI (const_int 32) (match_dup 2)))))
13127 (clobber (reg:CC FLAGS_REG))])]
13128 "split_di (operands, 1, operands + 4, operands + 5);")
13130 (define_insn "*rotlsi3_1_one_bit_rex64"
13131 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13132 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13133 (match_operand:QI 2 "const1_operand" "")))
13134 (clobber (reg:CC FLAGS_REG))]
13136 && (TARGET_SHIFT1 || optimize_size)
13137 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13139 [(set_attr "type" "rotate")
13140 (set (attr "length")
13141 (if_then_else (match_operand:DI 0 "register_operand" "")
13143 (const_string "*")))])
13145 (define_insn "*rotldi3_1_rex64"
13146 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13147 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13148 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13149 (clobber (reg:CC FLAGS_REG))]
13150 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13152 rol{q}\t{%2, %0|%0, %2}
13153 rol{q}\t{%b2, %0|%0, %b2}"
13154 [(set_attr "type" "rotate")
13155 (set_attr "mode" "DI")])
13157 (define_expand "rotlsi3"
13158 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13159 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13160 (match_operand:QI 2 "nonmemory_operand" "")))
13161 (clobber (reg:CC FLAGS_REG))]
13163 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13165 (define_insn "*rotlsi3_1_one_bit"
13166 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13167 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13168 (match_operand:QI 2 "const1_operand" "")))
13169 (clobber (reg:CC FLAGS_REG))]
13170 "(TARGET_SHIFT1 || optimize_size)
13171 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13173 [(set_attr "type" "rotate")
13174 (set (attr "length")
13175 (if_then_else (match_operand:SI 0 "register_operand" "")
13177 (const_string "*")))])
13179 (define_insn "*rotlsi3_1_one_bit_zext"
13180 [(set (match_operand:DI 0 "register_operand" "=r")
13182 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13183 (match_operand:QI 2 "const1_operand" ""))))
13184 (clobber (reg:CC FLAGS_REG))]
13186 && (TARGET_SHIFT1 || optimize_size)
13187 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13189 [(set_attr "type" "rotate")
13190 (set_attr "length" "2")])
13192 (define_insn "*rotlsi3_1"
13193 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13194 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13195 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13196 (clobber (reg:CC FLAGS_REG))]
13197 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13199 rol{l}\t{%2, %0|%0, %2}
13200 rol{l}\t{%b2, %0|%0, %b2}"
13201 [(set_attr "type" "rotate")
13202 (set_attr "mode" "SI")])
13204 (define_insn "*rotlsi3_1_zext"
13205 [(set (match_operand:DI 0 "register_operand" "=r,r")
13207 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13208 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13209 (clobber (reg:CC FLAGS_REG))]
13210 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13212 rol{l}\t{%2, %k0|%k0, %2}
13213 rol{l}\t{%b2, %k0|%k0, %b2}"
13214 [(set_attr "type" "rotate")
13215 (set_attr "mode" "SI")])
13217 (define_expand "rotlhi3"
13218 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13219 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13220 (match_operand:QI 2 "nonmemory_operand" "")))
13221 (clobber (reg:CC FLAGS_REG))]
13222 "TARGET_HIMODE_MATH"
13223 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13225 (define_insn "*rotlhi3_1_one_bit"
13226 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13227 (rotate:HI (match_operand:HI 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, HImode, operands)"
13233 [(set_attr "type" "rotate")
13234 (set (attr "length")
13235 (if_then_else (match_operand 0 "register_operand" "")
13237 (const_string "*")))])
13239 (define_insn "*rotlhi3_1"
13240 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13241 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13242 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13243 (clobber (reg:CC FLAGS_REG))]
13244 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13246 rol{w}\t{%2, %0|%0, %2}
13247 rol{w}\t{%b2, %0|%0, %b2}"
13248 [(set_attr "type" "rotate")
13249 (set_attr "mode" "HI")])
13252 [(set (match_operand:HI 0 "register_operand" "")
13253 (rotate:HI (match_dup 0) (const_int 8)))
13254 (clobber (reg:CC FLAGS_REG))]
13256 [(parallel [(set (strict_low_part (match_dup 0))
13257 (bswap:HI (match_dup 0)))
13258 (clobber (reg:CC FLAGS_REG))])]
13261 (define_expand "rotlqi3"
13262 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13263 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13264 (match_operand:QI 2 "nonmemory_operand" "")))
13265 (clobber (reg:CC FLAGS_REG))]
13266 "TARGET_QIMODE_MATH"
13267 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13269 (define_insn "*rotlqi3_1_one_bit_slp"
13270 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13271 (rotate:QI (match_dup 0)
13272 (match_operand:QI 1 "const1_operand" "")))
13273 (clobber (reg:CC FLAGS_REG))]
13274 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13275 && (TARGET_SHIFT1 || optimize_size)"
13277 [(set_attr "type" "rotate1")
13278 (set (attr "length")
13279 (if_then_else (match_operand 0 "register_operand" "")
13281 (const_string "*")))])
13283 (define_insn "*rotlqi3_1_one_bit"
13284 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13285 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13286 (match_operand:QI 2 "const1_operand" "")))
13287 (clobber (reg:CC FLAGS_REG))]
13288 "(TARGET_SHIFT1 || optimize_size)
13289 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13291 [(set_attr "type" "rotate")
13292 (set (attr "length")
13293 (if_then_else (match_operand 0 "register_operand" "")
13295 (const_string "*")))])
13297 (define_insn "*rotlqi3_1_slp"
13298 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13299 (rotate:QI (match_dup 0)
13300 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13301 (clobber (reg:CC FLAGS_REG))]
13302 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13303 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13305 rol{b}\t{%1, %0|%0, %1}
13306 rol{b}\t{%b1, %0|%0, %b1}"
13307 [(set_attr "type" "rotate1")
13308 (set_attr "mode" "QI")])
13310 (define_insn "*rotlqi3_1"
13311 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13312 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13313 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13314 (clobber (reg:CC FLAGS_REG))]
13315 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13317 rol{b}\t{%2, %0|%0, %2}
13318 rol{b}\t{%b2, %0|%0, %b2}"
13319 [(set_attr "type" "rotate")
13320 (set_attr "mode" "QI")])
13322 (define_expand "rotrdi3"
13323 [(set (match_operand:DI 0 "shiftdi_operand" "")
13324 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13325 (match_operand:QI 2 "nonmemory_operand" "")))
13326 (clobber (reg:CC FLAGS_REG))]
13331 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13334 if (!const_1_to_31_operand (operands[2], VOIDmode))
13336 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13340 ;; Implement rotation using two double-precision shift instructions
13341 ;; and a scratch register.
13342 (define_insn_and_split "ix86_rotrdi3"
13343 [(set (match_operand:DI 0 "register_operand" "=r")
13344 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13345 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13346 (clobber (reg:CC FLAGS_REG))
13347 (clobber (match_scratch:SI 3 "=&r"))]
13350 "&& reload_completed"
13351 [(set (match_dup 3) (match_dup 4))
13353 [(set (match_dup 4)
13354 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13355 (ashift:SI (match_dup 5)
13356 (minus:QI (const_int 32) (match_dup 2)))))
13357 (clobber (reg:CC FLAGS_REG))])
13359 [(set (match_dup 5)
13360 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13361 (ashift:SI (match_dup 3)
13362 (minus:QI (const_int 32) (match_dup 2)))))
13363 (clobber (reg:CC FLAGS_REG))])]
13364 "split_di (operands, 1, operands + 4, operands + 5);")
13366 (define_insn "*rotrdi3_1_one_bit_rex64"
13367 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13368 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13369 (match_operand:QI 2 "const1_operand" "")))
13370 (clobber (reg:CC FLAGS_REG))]
13372 && (TARGET_SHIFT1 || optimize_size)
13373 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13375 [(set_attr "type" "rotate")
13376 (set (attr "length")
13377 (if_then_else (match_operand:DI 0 "register_operand" "")
13379 (const_string "*")))])
13381 (define_insn "*rotrdi3_1_rex64"
13382 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13383 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13384 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13385 (clobber (reg:CC FLAGS_REG))]
13386 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13388 ror{q}\t{%2, %0|%0, %2}
13389 ror{q}\t{%b2, %0|%0, %b2}"
13390 [(set_attr "type" "rotate")
13391 (set_attr "mode" "DI")])
13393 (define_expand "rotrsi3"
13394 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13395 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13396 (match_operand:QI 2 "nonmemory_operand" "")))
13397 (clobber (reg:CC FLAGS_REG))]
13399 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13401 (define_insn "*rotrsi3_1_one_bit"
13402 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13403 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13404 (match_operand:QI 2 "const1_operand" "")))
13405 (clobber (reg:CC FLAGS_REG))]
13406 "(TARGET_SHIFT1 || optimize_size)
13407 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13409 [(set_attr "type" "rotate")
13410 (set (attr "length")
13411 (if_then_else (match_operand:SI 0 "register_operand" "")
13413 (const_string "*")))])
13415 (define_insn "*rotrsi3_1_one_bit_zext"
13416 [(set (match_operand:DI 0 "register_operand" "=r")
13418 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13419 (match_operand:QI 2 "const1_operand" ""))))
13420 (clobber (reg:CC FLAGS_REG))]
13422 && (TARGET_SHIFT1 || optimize_size)
13423 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13425 [(set_attr "type" "rotate")
13426 (set (attr "length")
13427 (if_then_else (match_operand:SI 0 "register_operand" "")
13429 (const_string "*")))])
13431 (define_insn "*rotrsi3_1"
13432 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13433 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13434 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13435 (clobber (reg:CC FLAGS_REG))]
13436 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13438 ror{l}\t{%2, %0|%0, %2}
13439 ror{l}\t{%b2, %0|%0, %b2}"
13440 [(set_attr "type" "rotate")
13441 (set_attr "mode" "SI")])
13443 (define_insn "*rotrsi3_1_zext"
13444 [(set (match_operand:DI 0 "register_operand" "=r,r")
13446 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13447 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13448 (clobber (reg:CC FLAGS_REG))]
13449 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13451 ror{l}\t{%2, %k0|%k0, %2}
13452 ror{l}\t{%b2, %k0|%k0, %b2}"
13453 [(set_attr "type" "rotate")
13454 (set_attr "mode" "SI")])
13456 (define_expand "rotrhi3"
13457 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13458 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13459 (match_operand:QI 2 "nonmemory_operand" "")))
13460 (clobber (reg:CC FLAGS_REG))]
13461 "TARGET_HIMODE_MATH"
13462 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13464 (define_insn "*rotrhi3_one_bit"
13465 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13466 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13467 (match_operand:QI 2 "const1_operand" "")))
13468 (clobber (reg:CC FLAGS_REG))]
13469 "(TARGET_SHIFT1 || optimize_size)
13470 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13472 [(set_attr "type" "rotate")
13473 (set (attr "length")
13474 (if_then_else (match_operand 0 "register_operand" "")
13476 (const_string "*")))])
13478 (define_insn "*rotrhi3_1"
13479 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13480 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13481 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13482 (clobber (reg:CC FLAGS_REG))]
13483 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13485 ror{w}\t{%2, %0|%0, %2}
13486 ror{w}\t{%b2, %0|%0, %b2}"
13487 [(set_attr "type" "rotate")
13488 (set_attr "mode" "HI")])
13491 [(set (match_operand:HI 0 "register_operand" "")
13492 (rotatert:HI (match_dup 0) (const_int 8)))
13493 (clobber (reg:CC FLAGS_REG))]
13495 [(parallel [(set (strict_low_part (match_dup 0))
13496 (bswap:HI (match_dup 0)))
13497 (clobber (reg:CC FLAGS_REG))])]
13500 (define_expand "rotrqi3"
13501 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13502 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13503 (match_operand:QI 2 "nonmemory_operand" "")))
13504 (clobber (reg:CC FLAGS_REG))]
13505 "TARGET_QIMODE_MATH"
13506 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13508 (define_insn "*rotrqi3_1_one_bit"
13509 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13510 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13511 (match_operand:QI 2 "const1_operand" "")))
13512 (clobber (reg:CC FLAGS_REG))]
13513 "(TARGET_SHIFT1 || optimize_size)
13514 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13516 [(set_attr "type" "rotate")
13517 (set (attr "length")
13518 (if_then_else (match_operand 0 "register_operand" "")
13520 (const_string "*")))])
13522 (define_insn "*rotrqi3_1_one_bit_slp"
13523 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13524 (rotatert:QI (match_dup 0)
13525 (match_operand:QI 1 "const1_operand" "")))
13526 (clobber (reg:CC FLAGS_REG))]
13527 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13528 && (TARGET_SHIFT1 || optimize_size)"
13530 [(set_attr "type" "rotate1")
13531 (set (attr "length")
13532 (if_then_else (match_operand 0 "register_operand" "")
13534 (const_string "*")))])
13536 (define_insn "*rotrqi3_1"
13537 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13538 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13539 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13540 (clobber (reg:CC FLAGS_REG))]
13541 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13543 ror{b}\t{%2, %0|%0, %2}
13544 ror{b}\t{%b2, %0|%0, %b2}"
13545 [(set_attr "type" "rotate")
13546 (set_attr "mode" "QI")])
13548 (define_insn "*rotrqi3_1_slp"
13549 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13550 (rotatert:QI (match_dup 0)
13551 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13552 (clobber (reg:CC FLAGS_REG))]
13553 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13554 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13556 ror{b}\t{%1, %0|%0, %1}
13557 ror{b}\t{%b1, %0|%0, %b1}"
13558 [(set_attr "type" "rotate1")
13559 (set_attr "mode" "QI")])
13561 ;; Bit set / bit test instructions
13563 (define_expand "extv"
13564 [(set (match_operand:SI 0 "register_operand" "")
13565 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13566 (match_operand:SI 2 "const8_operand" "")
13567 (match_operand:SI 3 "const8_operand" "")))]
13570 /* Handle extractions from %ah et al. */
13571 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13574 /* From mips.md: extract_bit_field doesn't verify that our source
13575 matches the predicate, so check it again here. */
13576 if (! ext_register_operand (operands[1], VOIDmode))
13580 (define_expand "extzv"
13581 [(set (match_operand:SI 0 "register_operand" "")
13582 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13583 (match_operand:SI 2 "const8_operand" "")
13584 (match_operand:SI 3 "const8_operand" "")))]
13587 /* Handle extractions from %ah et al. */
13588 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13591 /* From mips.md: extract_bit_field doesn't verify that our source
13592 matches the predicate, so check it again here. */
13593 if (! ext_register_operand (operands[1], VOIDmode))
13597 (define_expand "insv"
13598 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13599 (match_operand 1 "const8_operand" "")
13600 (match_operand 2 "const8_operand" ""))
13601 (match_operand 3 "register_operand" ""))]
13604 /* Handle insertions to %ah et al. */
13605 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13608 /* From mips.md: insert_bit_field doesn't verify that our source
13609 matches the predicate, so check it again here. */
13610 if (! ext_register_operand (operands[0], VOIDmode))
13614 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13616 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13621 ;; %%% bts, btr, btc, bt.
13622 ;; In general these instructions are *slow* when applied to memory,
13623 ;; since they enforce atomic operation. When applied to registers,
13624 ;; it depends on the cpu implementation. They're never faster than
13625 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13626 ;; no point. But in 64-bit, we can't hold the relevant immediates
13627 ;; within the instruction itself, so operating on bits in the high
13628 ;; 32-bits of a register becomes easier.
13630 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13631 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13632 ;; negdf respectively, so they can never be disabled entirely.
13634 (define_insn "*btsq"
13635 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13637 (match_operand:DI 1 "const_0_to_63_operand" ""))
13639 (clobber (reg:CC FLAGS_REG))]
13640 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13642 [(set_attr "type" "alu1")])
13644 (define_insn "*btrq"
13645 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13647 (match_operand:DI 1 "const_0_to_63_operand" ""))
13649 (clobber (reg:CC FLAGS_REG))]
13650 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13652 [(set_attr "type" "alu1")])
13654 (define_insn "*btcq"
13655 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13657 (match_operand:DI 1 "const_0_to_63_operand" ""))
13658 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13659 (clobber (reg:CC FLAGS_REG))]
13660 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13662 [(set_attr "type" "alu1")])
13664 ;; Allow Nocona to avoid these instructions if a register is available.
13667 [(match_scratch:DI 2 "r")
13668 (parallel [(set (zero_extract:DI
13669 (match_operand:DI 0 "register_operand" "")
13671 (match_operand:DI 1 "const_0_to_63_operand" ""))
13673 (clobber (reg:CC FLAGS_REG))])]
13674 "TARGET_64BIT && !TARGET_USE_BT"
13677 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13680 if (HOST_BITS_PER_WIDE_INT >= 64)
13681 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13682 else if (i < HOST_BITS_PER_WIDE_INT)
13683 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13685 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13687 op1 = immed_double_const (lo, hi, DImode);
13690 emit_move_insn (operands[2], op1);
13694 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13699 [(match_scratch:DI 2 "r")
13700 (parallel [(set (zero_extract:DI
13701 (match_operand:DI 0 "register_operand" "")
13703 (match_operand:DI 1 "const_0_to_63_operand" ""))
13705 (clobber (reg:CC FLAGS_REG))])]
13706 "TARGET_64BIT && !TARGET_USE_BT"
13709 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13712 if (HOST_BITS_PER_WIDE_INT >= 64)
13713 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13714 else if (i < HOST_BITS_PER_WIDE_INT)
13715 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13717 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13719 op1 = immed_double_const (~lo, ~hi, DImode);
13722 emit_move_insn (operands[2], op1);
13726 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13731 [(match_scratch:DI 2 "r")
13732 (parallel [(set (zero_extract:DI
13733 (match_operand:DI 0 "register_operand" "")
13735 (match_operand:DI 1 "const_0_to_63_operand" ""))
13736 (not:DI (zero_extract:DI
13737 (match_dup 0) (const_int 1) (match_dup 1))))
13738 (clobber (reg:CC FLAGS_REG))])]
13739 "TARGET_64BIT && !TARGET_USE_BT"
13742 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13745 if (HOST_BITS_PER_WIDE_INT >= 64)
13746 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13747 else if (i < HOST_BITS_PER_WIDE_INT)
13748 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13750 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13752 op1 = immed_double_const (lo, hi, DImode);
13755 emit_move_insn (operands[2], op1);
13759 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13763 ;; Store-flag instructions.
13765 ;; For all sCOND expanders, also expand the compare or test insn that
13766 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13768 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13769 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13770 ;; way, which can later delete the movzx if only QImode is needed.
13772 (define_expand "s<code>"
13773 [(set (match_operand:QI 0 "register_operand" "")
13774 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13776 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13778 (define_expand "s<code>"
13779 [(set (match_operand:QI 0 "register_operand" "")
13780 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13781 "TARGET_80387 || TARGET_SSE"
13782 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13784 (define_insn "*setcc_1"
13785 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13786 (match_operator:QI 1 "ix86_comparison_operator"
13787 [(reg FLAGS_REG) (const_int 0)]))]
13790 [(set_attr "type" "setcc")
13791 (set_attr "mode" "QI")])
13793 (define_insn "*setcc_2"
13794 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13795 (match_operator:QI 1 "ix86_comparison_operator"
13796 [(reg FLAGS_REG) (const_int 0)]))]
13799 [(set_attr "type" "setcc")
13800 (set_attr "mode" "QI")])
13802 ;; In general it is not safe to assume too much about CCmode registers,
13803 ;; so simplify-rtx stops when it sees a second one. Under certain
13804 ;; conditions this is safe on x86, so help combine not create
13811 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13812 (ne:QI (match_operator 1 "ix86_comparison_operator"
13813 [(reg FLAGS_REG) (const_int 0)])
13816 [(set (match_dup 0) (match_dup 1))]
13818 PUT_MODE (operands[1], QImode);
13822 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13823 (ne:QI (match_operator 1 "ix86_comparison_operator"
13824 [(reg FLAGS_REG) (const_int 0)])
13827 [(set (match_dup 0) (match_dup 1))]
13829 PUT_MODE (operands[1], QImode);
13833 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13834 (eq:QI (match_operator 1 "ix86_comparison_operator"
13835 [(reg FLAGS_REG) (const_int 0)])
13838 [(set (match_dup 0) (match_dup 1))]
13840 rtx new_op1 = copy_rtx (operands[1]);
13841 operands[1] = new_op1;
13842 PUT_MODE (new_op1, QImode);
13843 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13844 GET_MODE (XEXP (new_op1, 0))));
13846 /* Make sure that (a) the CCmode we have for the flags is strong
13847 enough for the reversed compare or (b) we have a valid FP compare. */
13848 if (! ix86_comparison_operator (new_op1, VOIDmode))
13853 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13854 (eq:QI (match_operator 1 "ix86_comparison_operator"
13855 [(reg FLAGS_REG) (const_int 0)])
13858 [(set (match_dup 0) (match_dup 1))]
13860 rtx new_op1 = copy_rtx (operands[1]);
13861 operands[1] = new_op1;
13862 PUT_MODE (new_op1, QImode);
13863 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13864 GET_MODE (XEXP (new_op1, 0))));
13866 /* Make sure that (a) the CCmode we have for the flags is strong
13867 enough for the reversed compare or (b) we have a valid FP compare. */
13868 if (! ix86_comparison_operator (new_op1, VOIDmode))
13872 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13873 ;; subsequent logical operations are used to imitate conditional moves.
13874 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13877 (define_insn "*sse_setcc<mode>"
13878 [(set (match_operand:MODEF 0 "register_operand" "=x")
13879 (match_operator:MODEF 1 "sse_comparison_operator"
13880 [(match_operand:MODEF 2 "register_operand" "0")
13881 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13882 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13883 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13884 [(set_attr "type" "ssecmp")
13885 (set_attr "mode" "<MODE>")])
13887 (define_insn "*sse5_setcc<mode>"
13888 [(set (match_operand:MODEF 0 "register_operand" "=x")
13889 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13890 [(match_operand:MODEF 2 "register_operand" "x")
13891 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13893 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13894 [(set_attr "type" "sse4arg")
13895 (set_attr "mode" "<MODE>")])
13898 ;; Basic conditional jump instructions.
13899 ;; We ignore the overflow flag for signed branch instructions.
13901 ;; For all bCOND expanders, also expand the compare or test insn that
13902 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13904 (define_expand "b<code>"
13906 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13908 (label_ref (match_operand 0 ""))
13911 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13913 (define_expand "b<code>"
13915 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13917 (label_ref (match_operand 0 ""))
13919 "TARGET_80387 || TARGET_SSE_MATH"
13920 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13922 (define_insn "*jcc_1"
13924 (if_then_else (match_operator 1 "ix86_comparison_operator"
13925 [(reg FLAGS_REG) (const_int 0)])
13926 (label_ref (match_operand 0 "" ""))
13930 [(set_attr "type" "ibr")
13931 (set_attr "modrm" "0")
13932 (set (attr "length")
13933 (if_then_else (and (ge (minus (match_dup 0) (pc))
13935 (lt (minus (match_dup 0) (pc))
13940 (define_insn "*jcc_2"
13942 (if_then_else (match_operator 1 "ix86_comparison_operator"
13943 [(reg FLAGS_REG) (const_int 0)])
13945 (label_ref (match_operand 0 "" ""))))]
13948 [(set_attr "type" "ibr")
13949 (set_attr "modrm" "0")
13950 (set (attr "length")
13951 (if_then_else (and (ge (minus (match_dup 0) (pc))
13953 (lt (minus (match_dup 0) (pc))
13958 ;; In general it is not safe to assume too much about CCmode registers,
13959 ;; so simplify-rtx stops when it sees a second one. Under certain
13960 ;; conditions this is safe on x86, so help combine not create
13968 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13969 [(reg FLAGS_REG) (const_int 0)])
13971 (label_ref (match_operand 1 "" ""))
13975 (if_then_else (match_dup 0)
13976 (label_ref (match_dup 1))
13979 PUT_MODE (operands[0], VOIDmode);
13984 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13985 [(reg FLAGS_REG) (const_int 0)])
13987 (label_ref (match_operand 1 "" ""))
13991 (if_then_else (match_dup 0)
13992 (label_ref (match_dup 1))
13995 rtx new_op0 = copy_rtx (operands[0]);
13996 operands[0] = new_op0;
13997 PUT_MODE (new_op0, VOIDmode);
13998 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13999 GET_MODE (XEXP (new_op0, 0))));
14001 /* Make sure that (a) the CCmode we have for the flags is strong
14002 enough for the reversed compare or (b) we have a valid FP compare. */
14003 if (! ix86_comparison_operator (new_op0, VOIDmode))
14007 ;; Define combination compare-and-branch fp compare instructions to use
14008 ;; during early optimization. Splitting the operation apart early makes
14009 ;; for bad code when we want to reverse the operation.
14011 (define_insn "*fp_jcc_1_mixed"
14013 (if_then_else (match_operator 0 "comparison_operator"
14014 [(match_operand 1 "register_operand" "f,x")
14015 (match_operand 2 "nonimmediate_operand" "f,xm")])
14016 (label_ref (match_operand 3 "" ""))
14018 (clobber (reg:CCFP FPSR_REG))
14019 (clobber (reg:CCFP FLAGS_REG))]
14020 "TARGET_MIX_SSE_I387
14021 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14022 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14023 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14026 (define_insn "*fp_jcc_1_sse"
14028 (if_then_else (match_operator 0 "comparison_operator"
14029 [(match_operand 1 "register_operand" "x")
14030 (match_operand 2 "nonimmediate_operand" "xm")])
14031 (label_ref (match_operand 3 "" ""))
14033 (clobber (reg:CCFP FPSR_REG))
14034 (clobber (reg:CCFP FLAGS_REG))]
14036 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14037 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14038 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14041 (define_insn "*fp_jcc_1_387"
14043 (if_then_else (match_operator 0 "comparison_operator"
14044 [(match_operand 1 "register_operand" "f")
14045 (match_operand 2 "register_operand" "f")])
14046 (label_ref (match_operand 3 "" ""))
14048 (clobber (reg:CCFP FPSR_REG))
14049 (clobber (reg:CCFP FLAGS_REG))]
14050 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14052 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14053 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14056 (define_insn "*fp_jcc_2_mixed"
14058 (if_then_else (match_operator 0 "comparison_operator"
14059 [(match_operand 1 "register_operand" "f,x")
14060 (match_operand 2 "nonimmediate_operand" "f,xm")])
14062 (label_ref (match_operand 3 "" ""))))
14063 (clobber (reg:CCFP FPSR_REG))
14064 (clobber (reg:CCFP FLAGS_REG))]
14065 "TARGET_MIX_SSE_I387
14066 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14067 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14068 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14071 (define_insn "*fp_jcc_2_sse"
14073 (if_then_else (match_operator 0 "comparison_operator"
14074 [(match_operand 1 "register_operand" "x")
14075 (match_operand 2 "nonimmediate_operand" "xm")])
14077 (label_ref (match_operand 3 "" ""))))
14078 (clobber (reg:CCFP FPSR_REG))
14079 (clobber (reg:CCFP FLAGS_REG))]
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_2_387"
14088 (if_then_else (match_operator 0 "comparison_operator"
14089 [(match_operand 1 "register_operand" "f")
14090 (match_operand 2 "register_operand" "f")])
14092 (label_ref (match_operand 3 "" ""))))
14093 (clobber (reg:CCFP FPSR_REG))
14094 (clobber (reg:CCFP FLAGS_REG))]
14095 "X87_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_3_387"
14103 (if_then_else (match_operator 0 "comparison_operator"
14104 [(match_operand 1 "register_operand" "f")
14105 (match_operand 2 "nonimmediate_operand" "fm")])
14106 (label_ref (match_operand 3 "" ""))
14108 (clobber (reg:CCFP FPSR_REG))
14109 (clobber (reg:CCFP FLAGS_REG))
14110 (clobber (match_scratch:HI 4 "=a"))]
14112 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14113 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14114 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14115 && SELECT_CC_MODE (GET_CODE (operands[0]),
14116 operands[1], operands[2]) == CCFPmode
14117 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14120 (define_insn "*fp_jcc_4_387"
14122 (if_then_else (match_operator 0 "comparison_operator"
14123 [(match_operand 1 "register_operand" "f")
14124 (match_operand 2 "nonimmediate_operand" "fm")])
14126 (label_ref (match_operand 3 "" ""))))
14127 (clobber (reg:CCFP FPSR_REG))
14128 (clobber (reg:CCFP FLAGS_REG))
14129 (clobber (match_scratch:HI 4 "=a"))]
14131 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14132 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14133 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14134 && SELECT_CC_MODE (GET_CODE (operands[0]),
14135 operands[1], operands[2]) == CCFPmode
14136 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14139 (define_insn "*fp_jcc_5_387"
14141 (if_then_else (match_operator 0 "comparison_operator"
14142 [(match_operand 1 "register_operand" "f")
14143 (match_operand 2 "register_operand" "f")])
14144 (label_ref (match_operand 3 "" ""))
14146 (clobber (reg:CCFP FPSR_REG))
14147 (clobber (reg:CCFP FLAGS_REG))
14148 (clobber (match_scratch:HI 4 "=a"))]
14149 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14150 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14151 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14154 (define_insn "*fp_jcc_6_387"
14156 (if_then_else (match_operator 0 "comparison_operator"
14157 [(match_operand 1 "register_operand" "f")
14158 (match_operand 2 "register_operand" "f")])
14160 (label_ref (match_operand 3 "" ""))))
14161 (clobber (reg:CCFP FPSR_REG))
14162 (clobber (reg:CCFP FLAGS_REG))
14163 (clobber (match_scratch:HI 4 "=a"))]
14164 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14165 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14166 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14169 (define_insn "*fp_jcc_7_387"
14171 (if_then_else (match_operator 0 "comparison_operator"
14172 [(match_operand 1 "register_operand" "f")
14173 (match_operand 2 "const0_operand" "X")])
14174 (label_ref (match_operand 3 "" ""))
14176 (clobber (reg:CCFP FPSR_REG))
14177 (clobber (reg:CCFP FLAGS_REG))
14178 (clobber (match_scratch:HI 4 "=a"))]
14179 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14180 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14181 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14182 && SELECT_CC_MODE (GET_CODE (operands[0]),
14183 operands[1], operands[2]) == CCFPmode
14184 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14187 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14188 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14189 ;; with a precedence over other operators and is always put in the first
14190 ;; place. Swap condition and operands to match ficom instruction.
14192 (define_insn "*fp_jcc_8<mode>_387"
14194 (if_then_else (match_operator 0 "comparison_operator"
14195 [(match_operator 1 "float_operator"
14196 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14197 (match_operand 3 "register_operand" "f,f")])
14198 (label_ref (match_operand 4 "" ""))
14200 (clobber (reg:CCFP FPSR_REG))
14201 (clobber (reg:CCFP FLAGS_REG))
14202 (clobber (match_scratch:HI 5 "=a,a"))]
14203 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14204 && TARGET_USE_<MODE>MODE_FIOP
14205 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14206 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14207 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14208 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14213 (if_then_else (match_operator 0 "comparison_operator"
14214 [(match_operand 1 "register_operand" "")
14215 (match_operand 2 "nonimmediate_operand" "")])
14216 (match_operand 3 "" "")
14217 (match_operand 4 "" "")))
14218 (clobber (reg:CCFP FPSR_REG))
14219 (clobber (reg:CCFP FLAGS_REG))]
14223 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14224 operands[3], operands[4], NULL_RTX, NULL_RTX);
14230 (if_then_else (match_operator 0 "comparison_operator"
14231 [(match_operand 1 "register_operand" "")
14232 (match_operand 2 "general_operand" "")])
14233 (match_operand 3 "" "")
14234 (match_operand 4 "" "")))
14235 (clobber (reg:CCFP FPSR_REG))
14236 (clobber (reg:CCFP FLAGS_REG))
14237 (clobber (match_scratch:HI 5 "=a"))]
14241 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14242 operands[3], operands[4], operands[5], NULL_RTX);
14248 (if_then_else (match_operator 0 "comparison_operator"
14249 [(match_operator 1 "float_operator"
14250 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14251 (match_operand 3 "register_operand" "")])
14252 (match_operand 4 "" "")
14253 (match_operand 5 "" "")))
14254 (clobber (reg:CCFP FPSR_REG))
14255 (clobber (reg:CCFP FLAGS_REG))
14256 (clobber (match_scratch:HI 6 "=a"))]
14260 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14261 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14262 operands[3], operands[7],
14263 operands[4], operands[5], operands[6], NULL_RTX);
14267 ;; %%% Kill this when reload knows how to do it.
14270 (if_then_else (match_operator 0 "comparison_operator"
14271 [(match_operator 1 "float_operator"
14272 [(match_operand:X87MODEI12 2 "register_operand" "")])
14273 (match_operand 3 "register_operand" "")])
14274 (match_operand 4 "" "")
14275 (match_operand 5 "" "")))
14276 (clobber (reg:CCFP FPSR_REG))
14277 (clobber (reg:CCFP FLAGS_REG))
14278 (clobber (match_scratch:HI 6 "=a"))]
14282 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14283 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14284 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14285 operands[3], operands[7],
14286 operands[4], operands[5], operands[6], operands[2]);
14290 ;; Unconditional and other jump instructions
14292 (define_insn "jump"
14294 (label_ref (match_operand 0 "" "")))]
14297 [(set_attr "type" "ibr")
14298 (set (attr "length")
14299 (if_then_else (and (ge (minus (match_dup 0) (pc))
14301 (lt (minus (match_dup 0) (pc))
14305 (set_attr "modrm" "0")])
14307 (define_expand "indirect_jump"
14308 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14312 (define_insn "*indirect_jump"
14313 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14316 [(set_attr "type" "ibr")
14317 (set_attr "length_immediate" "0")])
14319 (define_insn "*indirect_jump_rtx64"
14320 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14323 [(set_attr "type" "ibr")
14324 (set_attr "length_immediate" "0")])
14326 (define_expand "tablejump"
14327 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14328 (use (label_ref (match_operand 1 "" "")))])]
14331 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14332 relative. Convert the relative address to an absolute address. */
14336 enum rtx_code code;
14338 /* We can't use @GOTOFF for text labels on VxWorks;
14339 see gotoff_operand. */
14340 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14344 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14346 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14350 op1 = pic_offset_table_rtx;
14355 op0 = pic_offset_table_rtx;
14359 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14364 (define_insn "*tablejump_1"
14365 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14366 (use (label_ref (match_operand 1 "" "")))]
14369 [(set_attr "type" "ibr")
14370 (set_attr "length_immediate" "0")])
14372 (define_insn "*tablejump_1_rtx64"
14373 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14374 (use (label_ref (match_operand 1 "" "")))]
14377 [(set_attr "type" "ibr")
14378 (set_attr "length_immediate" "0")])
14380 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14383 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14384 (set (match_operand:QI 1 "register_operand" "")
14385 (match_operator:QI 2 "ix86_comparison_operator"
14386 [(reg FLAGS_REG) (const_int 0)]))
14387 (set (match_operand 3 "q_regs_operand" "")
14388 (zero_extend (match_dup 1)))]
14389 "(peep2_reg_dead_p (3, operands[1])
14390 || operands_match_p (operands[1], operands[3]))
14391 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14392 [(set (match_dup 4) (match_dup 0))
14393 (set (strict_low_part (match_dup 5))
14396 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14397 operands[5] = gen_lowpart (QImode, operands[3]);
14398 ix86_expand_clear (operands[3]);
14401 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14404 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14405 (set (match_operand:QI 1 "register_operand" "")
14406 (match_operator:QI 2 "ix86_comparison_operator"
14407 [(reg FLAGS_REG) (const_int 0)]))
14408 (parallel [(set (match_operand 3 "q_regs_operand" "")
14409 (zero_extend (match_dup 1)))
14410 (clobber (reg:CC FLAGS_REG))])]
14411 "(peep2_reg_dead_p (3, operands[1])
14412 || operands_match_p (operands[1], operands[3]))
14413 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14414 [(set (match_dup 4) (match_dup 0))
14415 (set (strict_low_part (match_dup 5))
14418 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14419 operands[5] = gen_lowpart (QImode, operands[3]);
14420 ix86_expand_clear (operands[3]);
14423 ;; Call instructions.
14425 ;; The predicates normally associated with named expanders are not properly
14426 ;; checked for calls. This is a bug in the generic code, but it isn't that
14427 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14429 ;; Call subroutine returning no value.
14431 (define_expand "call_pop"
14432 [(parallel [(call (match_operand:QI 0 "" "")
14433 (match_operand:SI 1 "" ""))
14434 (set (reg:SI SP_REG)
14435 (plus:SI (reg:SI SP_REG)
14436 (match_operand:SI 3 "" "")))])]
14439 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14443 (define_insn "*call_pop_0"
14444 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14445 (match_operand:SI 1 "" ""))
14446 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14447 (match_operand:SI 2 "immediate_operand" "")))]
14450 if (SIBLING_CALL_P (insn))
14453 return "call\t%P0";
14455 [(set_attr "type" "call")])
14457 (define_insn "*call_pop_1"
14458 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14459 (match_operand:SI 1 "" ""))
14460 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14461 (match_operand:SI 2 "immediate_operand" "i")))]
14464 if (constant_call_address_operand (operands[0], Pmode))
14466 if (SIBLING_CALL_P (insn))
14469 return "call\t%P0";
14471 if (SIBLING_CALL_P (insn))
14474 return "call\t%A0";
14476 [(set_attr "type" "call")])
14478 (define_expand "call"
14479 [(call (match_operand:QI 0 "" "")
14480 (match_operand 1 "" ""))
14481 (use (match_operand 2 "" ""))]
14484 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14488 (define_expand "sibcall"
14489 [(call (match_operand:QI 0 "" "")
14490 (match_operand 1 "" ""))
14491 (use (match_operand 2 "" ""))]
14494 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14498 (define_insn "*call_0"
14499 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14500 (match_operand 1 "" ""))]
14503 if (SIBLING_CALL_P (insn))
14506 return "call\t%P0";
14508 [(set_attr "type" "call")])
14510 (define_insn "*call_1"
14511 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14512 (match_operand 1 "" ""))]
14513 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14515 if (constant_call_address_operand (operands[0], Pmode))
14516 return "call\t%P0";
14517 return "call\t%A0";
14519 [(set_attr "type" "call")])
14521 (define_insn "*sibcall_1"
14522 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14523 (match_operand 1 "" ""))]
14524 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14526 if (constant_call_address_operand (operands[0], Pmode))
14530 [(set_attr "type" "call")])
14532 (define_insn "*call_1_rex64"
14533 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14534 (match_operand 1 "" ""))]
14535 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14536 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14538 if (constant_call_address_operand (operands[0], Pmode))
14539 return "call\t%P0";
14540 return "call\t%A0";
14542 [(set_attr "type" "call")])
14544 (define_insn "*call_1_rex64_large"
14545 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14546 (match_operand 1 "" ""))]
14547 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14549 [(set_attr "type" "call")])
14551 (define_insn "*sibcall_1_rex64"
14552 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14553 (match_operand 1 "" ""))]
14554 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14556 [(set_attr "type" "call")])
14558 (define_insn "*sibcall_1_rex64_v"
14559 [(call (mem:QI (reg:DI R11_REG))
14560 (match_operand 0 "" ""))]
14561 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14563 [(set_attr "type" "call")])
14566 ;; Call subroutine, returning value in operand 0
14568 (define_expand "call_value_pop"
14569 [(parallel [(set (match_operand 0 "" "")
14570 (call (match_operand:QI 1 "" "")
14571 (match_operand:SI 2 "" "")))
14572 (set (reg:SI SP_REG)
14573 (plus:SI (reg:SI SP_REG)
14574 (match_operand:SI 4 "" "")))])]
14577 ix86_expand_call (operands[0], operands[1], operands[2],
14578 operands[3], operands[4], 0);
14582 (define_expand "call_value"
14583 [(set (match_operand 0 "" "")
14584 (call (match_operand:QI 1 "" "")
14585 (match_operand:SI 2 "" "")))
14586 (use (match_operand:SI 3 "" ""))]
14587 ;; Operand 2 not used on the i386.
14590 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14594 (define_expand "sibcall_value"
14595 [(set (match_operand 0 "" "")
14596 (call (match_operand:QI 1 "" "")
14597 (match_operand:SI 2 "" "")))
14598 (use (match_operand:SI 3 "" ""))]
14599 ;; Operand 2 not used on the i386.
14602 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14606 ;; Call subroutine returning any type.
14608 (define_expand "untyped_call"
14609 [(parallel [(call (match_operand 0 "" "")
14611 (match_operand 1 "" "")
14612 (match_operand 2 "" "")])]
14617 /* In order to give reg-stack an easier job in validating two
14618 coprocessor registers as containing a possible return value,
14619 simply pretend the untyped call returns a complex long double
14622 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14623 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14624 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14627 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14629 rtx set = XVECEXP (operands[2], 0, i);
14630 emit_move_insn (SET_DEST (set), SET_SRC (set));
14633 /* The optimizer does not know that the call sets the function value
14634 registers we stored in the result block. We avoid problems by
14635 claiming that all hard registers are used and clobbered at this
14637 emit_insn (gen_blockage ());
14642 ;; Prologue and epilogue instructions
14644 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14645 ;; all of memory. This blocks insns from being moved across this point.
14647 (define_insn "blockage"
14648 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14651 [(set_attr "length" "0")])
14653 ;; As USE insns aren't meaningful after reload, this is used instead
14654 ;; to prevent deleting instructions setting registers for PIC code
14655 (define_insn "prologue_use"
14656 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14659 [(set_attr "length" "0")])
14661 ;; Insn emitted into the body of a function to return from a function.
14662 ;; This is only done if the function's epilogue is known to be simple.
14663 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14665 (define_expand "return"
14667 "ix86_can_use_return_insn_p ()"
14669 if (current_function_pops_args)
14671 rtx popc = GEN_INT (current_function_pops_args);
14672 emit_jump_insn (gen_return_pop_internal (popc));
14677 (define_insn "return_internal"
14681 [(set_attr "length" "1")
14682 (set_attr "length_immediate" "0")
14683 (set_attr "modrm" "0")])
14685 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14686 ;; instruction Athlon and K8 have.
14688 (define_insn "return_internal_long"
14690 (unspec [(const_int 0)] UNSPEC_REP)]
14693 [(set_attr "length" "1")
14694 (set_attr "length_immediate" "0")
14695 (set_attr "prefix_rep" "1")
14696 (set_attr "modrm" "0")])
14698 (define_insn "return_pop_internal"
14700 (use (match_operand:SI 0 "const_int_operand" ""))]
14703 [(set_attr "length" "3")
14704 (set_attr "length_immediate" "2")
14705 (set_attr "modrm" "0")])
14707 (define_insn "return_indirect_internal"
14709 (use (match_operand:SI 0 "register_operand" "r"))]
14712 [(set_attr "type" "ibr")
14713 (set_attr "length_immediate" "0")])
14719 [(set_attr "length" "1")
14720 (set_attr "length_immediate" "0")
14721 (set_attr "modrm" "0")])
14723 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14724 ;; branch prediction penalty for the third jump in a 16-byte
14727 (define_insn "align"
14728 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14731 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14732 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14734 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14735 The align insn is used to avoid 3 jump instructions in the row to improve
14736 branch prediction and the benefits hardly outweigh the cost of extra 8
14737 nops on the average inserted by full alignment pseudo operation. */
14741 [(set_attr "length" "16")])
14743 (define_expand "prologue"
14746 "ix86_expand_prologue (); DONE;")
14748 (define_insn "set_got"
14749 [(set (match_operand:SI 0 "register_operand" "=r")
14750 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14751 (clobber (reg:CC FLAGS_REG))]
14753 { return output_set_got (operands[0], NULL_RTX); }
14754 [(set_attr "type" "multi")
14755 (set_attr "length" "12")])
14757 (define_insn "set_got_labelled"
14758 [(set (match_operand:SI 0 "register_operand" "=r")
14759 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14761 (clobber (reg:CC FLAGS_REG))]
14763 { return output_set_got (operands[0], operands[1]); }
14764 [(set_attr "type" "multi")
14765 (set_attr "length" "12")])
14767 (define_insn "set_got_rex64"
14768 [(set (match_operand:DI 0 "register_operand" "=r")
14769 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14771 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14772 [(set_attr "type" "lea")
14773 (set_attr "length" "6")])
14775 (define_insn "set_rip_rex64"
14776 [(set (match_operand:DI 0 "register_operand" "=r")
14777 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14779 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14780 [(set_attr "type" "lea")
14781 (set_attr "length" "6")])
14783 (define_insn "set_got_offset_rex64"
14784 [(set (match_operand:DI 0 "register_operand" "=r")
14785 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14787 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14788 [(set_attr "type" "imov")
14789 (set_attr "length" "11")])
14791 (define_expand "epilogue"
14794 "ix86_expand_epilogue (1); DONE;")
14796 (define_expand "sibcall_epilogue"
14799 "ix86_expand_epilogue (0); DONE;")
14801 (define_expand "eh_return"
14802 [(use (match_operand 0 "register_operand" ""))]
14805 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14807 /* Tricky bit: we write the address of the handler to which we will
14808 be returning into someone else's stack frame, one word below the
14809 stack address we wish to restore. */
14810 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14811 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14812 tmp = gen_rtx_MEM (Pmode, tmp);
14813 emit_move_insn (tmp, ra);
14815 if (Pmode == SImode)
14816 emit_jump_insn (gen_eh_return_si (sa));
14818 emit_jump_insn (gen_eh_return_di (sa));
14823 (define_insn_and_split "eh_return_si"
14825 (unspec [(match_operand:SI 0 "register_operand" "c")]
14826 UNSPEC_EH_RETURN))]
14831 "ix86_expand_epilogue (2); DONE;")
14833 (define_insn_and_split "eh_return_di"
14835 (unspec [(match_operand:DI 0 "register_operand" "c")]
14836 UNSPEC_EH_RETURN))]
14841 "ix86_expand_epilogue (2); DONE;")
14843 (define_insn "leave"
14844 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14845 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14846 (clobber (mem:BLK (scratch)))]
14849 [(set_attr "type" "leave")])
14851 (define_insn "leave_rex64"
14852 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14853 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14854 (clobber (mem:BLK (scratch)))]
14857 [(set_attr "type" "leave")])
14859 (define_expand "ffssi2"
14861 [(set (match_operand:SI 0 "register_operand" "")
14862 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14863 (clobber (match_scratch:SI 2 ""))
14864 (clobber (reg:CC FLAGS_REG))])]
14869 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14874 (define_expand "ffs_cmove"
14875 [(set (match_dup 2) (const_int -1))
14876 (parallel [(set (reg:CCZ FLAGS_REG)
14877 (compare:CCZ (match_operand:SI 1 "register_operand" "")
14879 (set (match_operand:SI 0 "nonimmediate_operand" "")
14880 (ctz:SI (match_dup 1)))])
14881 (set (match_dup 0) (if_then_else:SI
14882 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14885 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14886 (clobber (reg:CC FLAGS_REG))])]
14888 "operands[2] = gen_reg_rtx (SImode);")
14890 (define_insn_and_split "*ffs_no_cmove"
14891 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14892 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14893 (clobber (match_scratch:SI 2 "=&q"))
14894 (clobber (reg:CC FLAGS_REG))]
14897 "&& reload_completed"
14898 [(parallel [(set (reg:CCZ FLAGS_REG)
14899 (compare:CCZ (match_dup 1) (const_int 0)))
14900 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14901 (set (strict_low_part (match_dup 3))
14902 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14903 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14904 (clobber (reg:CC FLAGS_REG))])
14905 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14906 (clobber (reg:CC FLAGS_REG))])
14907 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14908 (clobber (reg:CC FLAGS_REG))])]
14910 operands[3] = gen_lowpart (QImode, operands[2]);
14911 ix86_expand_clear (operands[2]);
14914 (define_insn "*ffssi_1"
14915 [(set (reg:CCZ FLAGS_REG)
14916 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14918 (set (match_operand:SI 0 "register_operand" "=r")
14919 (ctz:SI (match_dup 1)))]
14921 "bsf{l}\t{%1, %0|%0, %1}"
14922 [(set_attr "prefix_0f" "1")])
14924 (define_expand "ffsdi2"
14925 [(set (match_dup 2) (const_int -1))
14926 (parallel [(set (reg:CCZ FLAGS_REG)
14927 (compare:CCZ (match_operand:DI 1 "register_operand" "")
14929 (set (match_operand:DI 0 "nonimmediate_operand" "")
14930 (ctz:DI (match_dup 1)))])
14931 (set (match_dup 0) (if_then_else:DI
14932 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14935 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14936 (clobber (reg:CC FLAGS_REG))])]
14938 "operands[2] = gen_reg_rtx (DImode);")
14940 (define_insn "*ffsdi_1"
14941 [(set (reg:CCZ FLAGS_REG)
14942 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14944 (set (match_operand:DI 0 "register_operand" "=r")
14945 (ctz:DI (match_dup 1)))]
14947 "bsf{q}\t{%1, %0|%0, %1}"
14948 [(set_attr "prefix_0f" "1")])
14950 (define_insn "ctzsi2"
14951 [(set (match_operand:SI 0 "register_operand" "=r")
14952 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14953 (clobber (reg:CC FLAGS_REG))]
14955 "bsf{l}\t{%1, %0|%0, %1}"
14956 [(set_attr "prefix_0f" "1")])
14958 (define_insn "ctzdi2"
14959 [(set (match_operand:DI 0 "register_operand" "=r")
14960 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14961 (clobber (reg:CC FLAGS_REG))]
14963 "bsf{q}\t{%1, %0|%0, %1}"
14964 [(set_attr "prefix_0f" "1")])
14966 (define_expand "clzsi2"
14968 [(set (match_operand:SI 0 "register_operand" "")
14969 (minus:SI (const_int 31)
14970 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14971 (clobber (reg:CC FLAGS_REG))])
14973 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14974 (clobber (reg:CC FLAGS_REG))])]
14979 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14984 (define_insn "clzsi2_abm"
14985 [(set (match_operand:SI 0 "register_operand" "=r")
14986 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14987 (clobber (reg:CC FLAGS_REG))]
14989 "lzcnt{l}\t{%1, %0|%0, %1}"
14990 [(set_attr "prefix_rep" "1")
14991 (set_attr "type" "bitmanip")
14992 (set_attr "mode" "SI")])
14994 (define_insn "*bsr"
14995 [(set (match_operand:SI 0 "register_operand" "=r")
14996 (minus:SI (const_int 31)
14997 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14998 (clobber (reg:CC FLAGS_REG))]
15000 "bsr{l}\t{%1, %0|%0, %1}"
15001 [(set_attr "prefix_0f" "1")
15002 (set_attr "mode" "SI")])
15004 (define_insn "popcountsi2"
15005 [(set (match_operand:SI 0 "register_operand" "=r")
15006 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15007 (clobber (reg:CC FLAGS_REG))]
15009 "popcnt{l}\t{%1, %0|%0, %1}"
15010 [(set_attr "prefix_rep" "1")
15011 (set_attr "type" "bitmanip")
15012 (set_attr "mode" "SI")])
15014 (define_insn "*popcountsi2_cmp"
15015 [(set (reg FLAGS_REG)
15017 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15019 (set (match_operand:SI 0 "register_operand" "=r")
15020 (popcount:SI (match_dup 1)))]
15021 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15022 "popcnt{l}\t{%1, %0|%0, %1}"
15023 [(set_attr "prefix_rep" "1")
15024 (set_attr "type" "bitmanip")
15025 (set_attr "mode" "SI")])
15027 (define_insn "*popcountsi2_cmp_zext"
15028 [(set (reg FLAGS_REG)
15030 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15032 (set (match_operand:DI 0 "register_operand" "=r")
15033 (zero_extend:DI(popcount:SI (match_dup 1))))]
15034 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15035 "popcnt{l}\t{%1, %0|%0, %1}"
15036 [(set_attr "prefix_rep" "1")
15037 (set_attr "type" "bitmanip")
15038 (set_attr "mode" "SI")])
15040 (define_expand "bswapsi2"
15041 [(set (match_operand:SI 0 "register_operand" "")
15042 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15047 rtx x = operands[0];
15049 emit_move_insn (x, operands[1]);
15050 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15051 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15052 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15057 (define_insn "*bswapsi_1"
15058 [(set (match_operand:SI 0 "register_operand" "=r")
15059 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15062 [(set_attr "prefix_0f" "1")
15063 (set_attr "length" "2")])
15065 (define_insn "*bswaphi_lowpart_1"
15066 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15067 (bswap:HI (match_dup 0)))
15068 (clobber (reg:CC FLAGS_REG))]
15069 "TARGET_USE_XCHGB || optimize_size"
15071 xchg{b}\t{%h0, %b0|%b0, %h0}
15072 rol{w}\t{$8, %0|%0, 8}"
15073 [(set_attr "length" "2,4")
15074 (set_attr "mode" "QI,HI")])
15076 (define_insn "bswaphi_lowpart"
15077 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15078 (bswap:HI (match_dup 0)))
15079 (clobber (reg:CC FLAGS_REG))]
15081 "rol{w}\t{$8, %0|%0, 8}"
15082 [(set_attr "length" "4")
15083 (set_attr "mode" "HI")])
15085 (define_insn "bswapdi2"
15086 [(set (match_operand:DI 0 "register_operand" "=r")
15087 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15090 [(set_attr "prefix_0f" "1")
15091 (set_attr "length" "3")])
15093 (define_expand "clzdi2"
15095 [(set (match_operand:DI 0 "register_operand" "")
15096 (minus:DI (const_int 63)
15097 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15098 (clobber (reg:CC FLAGS_REG))])
15100 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15101 (clobber (reg:CC FLAGS_REG))])]
15106 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15111 (define_insn "clzdi2_abm"
15112 [(set (match_operand:DI 0 "register_operand" "=r")
15113 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15114 (clobber (reg:CC FLAGS_REG))]
15115 "TARGET_64BIT && TARGET_ABM"
15116 "lzcnt{q}\t{%1, %0|%0, %1}"
15117 [(set_attr "prefix_rep" "1")
15118 (set_attr "type" "bitmanip")
15119 (set_attr "mode" "DI")])
15121 (define_insn "*bsr_rex64"
15122 [(set (match_operand:DI 0 "register_operand" "=r")
15123 (minus:DI (const_int 63)
15124 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15125 (clobber (reg:CC FLAGS_REG))]
15127 "bsr{q}\t{%1, %0|%0, %1}"
15128 [(set_attr "prefix_0f" "1")
15129 (set_attr "mode" "DI")])
15131 (define_insn "popcountdi2"
15132 [(set (match_operand:DI 0 "register_operand" "=r")
15133 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15134 (clobber (reg:CC FLAGS_REG))]
15135 "TARGET_64BIT && TARGET_POPCNT"
15136 "popcnt{q}\t{%1, %0|%0, %1}"
15137 [(set_attr "prefix_rep" "1")
15138 (set_attr "type" "bitmanip")
15139 (set_attr "mode" "DI")])
15141 (define_insn "*popcountdi2_cmp"
15142 [(set (reg FLAGS_REG)
15144 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15146 (set (match_operand:DI 0 "register_operand" "=r")
15147 (popcount:DI (match_dup 1)))]
15148 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15149 "popcnt{q}\t{%1, %0|%0, %1}"
15150 [(set_attr "prefix_rep" "1")
15151 (set_attr "type" "bitmanip")
15152 (set_attr "mode" "DI")])
15154 (define_expand "clzhi2"
15156 [(set (match_operand:HI 0 "register_operand" "")
15157 (minus:HI (const_int 15)
15158 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15159 (clobber (reg:CC FLAGS_REG))])
15161 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15162 (clobber (reg:CC FLAGS_REG))])]
15167 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15172 (define_insn "clzhi2_abm"
15173 [(set (match_operand:HI 0 "register_operand" "=r")
15174 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15175 (clobber (reg:CC FLAGS_REG))]
15177 "lzcnt{w}\t{%1, %0|%0, %1}"
15178 [(set_attr "prefix_rep" "1")
15179 (set_attr "type" "bitmanip")
15180 (set_attr "mode" "HI")])
15182 (define_insn "*bsrhi"
15183 [(set (match_operand:HI 0 "register_operand" "=r")
15184 (minus:HI (const_int 15)
15185 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15186 (clobber (reg:CC FLAGS_REG))]
15188 "bsr{w}\t{%1, %0|%0, %1}"
15189 [(set_attr "prefix_0f" "1")
15190 (set_attr "mode" "HI")])
15192 (define_insn "popcounthi2"
15193 [(set (match_operand:HI 0 "register_operand" "=r")
15194 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15195 (clobber (reg:CC FLAGS_REG))]
15197 "popcnt{w}\t{%1, %0|%0, %1}"
15198 [(set_attr "prefix_rep" "1")
15199 (set_attr "type" "bitmanip")
15200 (set_attr "mode" "HI")])
15202 (define_insn "*popcounthi2_cmp"
15203 [(set (reg FLAGS_REG)
15205 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15207 (set (match_operand:HI 0 "register_operand" "=r")
15208 (popcount:HI (match_dup 1)))]
15209 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15210 "popcnt{w}\t{%1, %0|%0, %1}"
15211 [(set_attr "prefix_rep" "1")
15212 (set_attr "type" "bitmanip")
15213 (set_attr "mode" "HI")])
15215 (define_expand "paritydi2"
15216 [(set (match_operand:DI 0 "register_operand" "")
15217 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15220 rtx scratch = gen_reg_rtx (QImode);
15223 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15224 NULL_RTX, operands[1]));
15226 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15227 gen_rtx_REG (CCmode, FLAGS_REG),
15229 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15232 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15235 rtx tmp = gen_reg_rtx (SImode);
15237 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15238 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15243 (define_insn_and_split "paritydi2_cmp"
15244 [(set (reg:CC FLAGS_REG)
15245 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15246 (clobber (match_scratch:DI 0 "=r"))
15247 (clobber (match_scratch:SI 1 "=&r"))
15248 (clobber (match_scratch:HI 2 "=Q"))]
15251 "&& reload_completed"
15253 [(set (match_dup 1)
15254 (xor:SI (match_dup 1) (match_dup 4)))
15255 (clobber (reg:CC FLAGS_REG))])
15257 [(set (reg:CC FLAGS_REG)
15258 (parity:CC (match_dup 1)))
15259 (clobber (match_dup 1))
15260 (clobber (match_dup 2))])]
15262 operands[4] = gen_lowpart (SImode, operands[3]);
15266 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15267 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15270 operands[1] = gen_highpart (SImode, operands[3]);
15273 (define_expand "paritysi2"
15274 [(set (match_operand:SI 0 "register_operand" "")
15275 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15278 rtx scratch = gen_reg_rtx (QImode);
15281 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15283 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15284 gen_rtx_REG (CCmode, FLAGS_REG),
15286 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15288 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15292 (define_insn_and_split "paritysi2_cmp"
15293 [(set (reg:CC FLAGS_REG)
15294 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15295 (clobber (match_scratch:SI 0 "=r"))
15296 (clobber (match_scratch:HI 1 "=&Q"))]
15299 "&& reload_completed"
15301 [(set (match_dup 1)
15302 (xor:HI (match_dup 1) (match_dup 3)))
15303 (clobber (reg:CC FLAGS_REG))])
15305 [(set (reg:CC FLAGS_REG)
15306 (parity:CC (match_dup 1)))
15307 (clobber (match_dup 1))])]
15309 operands[3] = gen_lowpart (HImode, operands[2]);
15311 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15312 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15315 (define_insn "*parityhi2_cmp"
15316 [(set (reg:CC FLAGS_REG)
15317 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15318 (clobber (match_scratch:HI 0 "=Q"))]
15320 "xor{b}\t{%h0, %b0|%b0, %h0}"
15321 [(set_attr "length" "2")
15322 (set_attr "mode" "HI")])
15324 (define_insn "*parityqi2_cmp"
15325 [(set (reg:CC FLAGS_REG)
15326 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15329 [(set_attr "length" "2")
15330 (set_attr "mode" "QI")])
15332 ;; Thread-local storage patterns for ELF.
15334 ;; Note that these code sequences must appear exactly as shown
15335 ;; in order to allow linker relaxation.
15337 (define_insn "*tls_global_dynamic_32_gnu"
15338 [(set (match_operand:SI 0 "register_operand" "=a")
15339 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15340 (match_operand:SI 2 "tls_symbolic_operand" "")
15341 (match_operand:SI 3 "call_insn_operand" "")]
15343 (clobber (match_scratch:SI 4 "=d"))
15344 (clobber (match_scratch:SI 5 "=c"))
15345 (clobber (reg:CC FLAGS_REG))]
15346 "!TARGET_64BIT && TARGET_GNU_TLS"
15347 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15348 [(set_attr "type" "multi")
15349 (set_attr "length" "12")])
15351 (define_insn "*tls_global_dynamic_32_sun"
15352 [(set (match_operand:SI 0 "register_operand" "=a")
15353 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15354 (match_operand:SI 2 "tls_symbolic_operand" "")
15355 (match_operand:SI 3 "call_insn_operand" "")]
15357 (clobber (match_scratch:SI 4 "=d"))
15358 (clobber (match_scratch:SI 5 "=c"))
15359 (clobber (reg:CC FLAGS_REG))]
15360 "!TARGET_64BIT && TARGET_SUN_TLS"
15361 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15362 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15363 [(set_attr "type" "multi")
15364 (set_attr "length" "14")])
15366 (define_expand "tls_global_dynamic_32"
15367 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15370 (match_operand:SI 1 "tls_symbolic_operand" "")
15373 (clobber (match_scratch:SI 4 ""))
15374 (clobber (match_scratch:SI 5 ""))
15375 (clobber (reg:CC FLAGS_REG))])]
15379 operands[2] = pic_offset_table_rtx;
15382 operands[2] = gen_reg_rtx (Pmode);
15383 emit_insn (gen_set_got (operands[2]));
15385 if (TARGET_GNU2_TLS)
15387 emit_insn (gen_tls_dynamic_gnu2_32
15388 (operands[0], operands[1], operands[2]));
15391 operands[3] = ix86_tls_get_addr ();
15394 (define_insn "*tls_global_dynamic_64"
15395 [(set (match_operand:DI 0 "register_operand" "=a")
15396 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15397 (match_operand:DI 3 "" "")))
15398 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15401 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15402 [(set_attr "type" "multi")
15403 (set_attr "length" "16")])
15405 (define_expand "tls_global_dynamic_64"
15406 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15407 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15408 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15412 if (TARGET_GNU2_TLS)
15414 emit_insn (gen_tls_dynamic_gnu2_64
15415 (operands[0], operands[1]));
15418 operands[2] = ix86_tls_get_addr ();
15421 (define_insn "*tls_local_dynamic_base_32_gnu"
15422 [(set (match_operand:SI 0 "register_operand" "=a")
15423 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15424 (match_operand:SI 2 "call_insn_operand" "")]
15425 UNSPEC_TLS_LD_BASE))
15426 (clobber (match_scratch:SI 3 "=d"))
15427 (clobber (match_scratch:SI 4 "=c"))
15428 (clobber (reg:CC FLAGS_REG))]
15429 "!TARGET_64BIT && TARGET_GNU_TLS"
15430 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15431 [(set_attr "type" "multi")
15432 (set_attr "length" "11")])
15434 (define_insn "*tls_local_dynamic_base_32_sun"
15435 [(set (match_operand:SI 0 "register_operand" "=a")
15436 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15437 (match_operand:SI 2 "call_insn_operand" "")]
15438 UNSPEC_TLS_LD_BASE))
15439 (clobber (match_scratch:SI 3 "=d"))
15440 (clobber (match_scratch:SI 4 "=c"))
15441 (clobber (reg:CC FLAGS_REG))]
15442 "!TARGET_64BIT && TARGET_SUN_TLS"
15443 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15444 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15445 [(set_attr "type" "multi")
15446 (set_attr "length" "13")])
15448 (define_expand "tls_local_dynamic_base_32"
15449 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15450 (unspec:SI [(match_dup 1) (match_dup 2)]
15451 UNSPEC_TLS_LD_BASE))
15452 (clobber (match_scratch:SI 3 ""))
15453 (clobber (match_scratch:SI 4 ""))
15454 (clobber (reg:CC FLAGS_REG))])]
15458 operands[1] = pic_offset_table_rtx;
15461 operands[1] = gen_reg_rtx (Pmode);
15462 emit_insn (gen_set_got (operands[1]));
15464 if (TARGET_GNU2_TLS)
15466 emit_insn (gen_tls_dynamic_gnu2_32
15467 (operands[0], ix86_tls_module_base (), operands[1]));
15470 operands[2] = ix86_tls_get_addr ();
15473 (define_insn "*tls_local_dynamic_base_64"
15474 [(set (match_operand:DI 0 "register_operand" "=a")
15475 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15476 (match_operand:DI 2 "" "")))
15477 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15479 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15480 [(set_attr "type" "multi")
15481 (set_attr "length" "12")])
15483 (define_expand "tls_local_dynamic_base_64"
15484 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15485 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15486 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15489 if (TARGET_GNU2_TLS)
15491 emit_insn (gen_tls_dynamic_gnu2_64
15492 (operands[0], ix86_tls_module_base ()));
15495 operands[1] = ix86_tls_get_addr ();
15498 ;; Local dynamic of a single variable is a lose. Show combine how
15499 ;; to convert that back to global dynamic.
15501 (define_insn_and_split "*tls_local_dynamic_32_once"
15502 [(set (match_operand:SI 0 "register_operand" "=a")
15503 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15504 (match_operand:SI 2 "call_insn_operand" "")]
15505 UNSPEC_TLS_LD_BASE)
15506 (const:SI (unspec:SI
15507 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15509 (clobber (match_scratch:SI 4 "=d"))
15510 (clobber (match_scratch:SI 5 "=c"))
15511 (clobber (reg:CC FLAGS_REG))]
15515 [(parallel [(set (match_dup 0)
15516 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15518 (clobber (match_dup 4))
15519 (clobber (match_dup 5))
15520 (clobber (reg:CC FLAGS_REG))])]
15523 ;; Load and add the thread base pointer from %gs:0.
15525 (define_insn "*load_tp_si"
15526 [(set (match_operand:SI 0 "register_operand" "=r")
15527 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15529 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15530 [(set_attr "type" "imov")
15531 (set_attr "modrm" "0")
15532 (set_attr "length" "7")
15533 (set_attr "memory" "load")
15534 (set_attr "imm_disp" "false")])
15536 (define_insn "*add_tp_si"
15537 [(set (match_operand:SI 0 "register_operand" "=r")
15538 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15539 (match_operand:SI 1 "register_operand" "0")))
15540 (clobber (reg:CC FLAGS_REG))]
15542 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15543 [(set_attr "type" "alu")
15544 (set_attr "modrm" "0")
15545 (set_attr "length" "7")
15546 (set_attr "memory" "load")
15547 (set_attr "imm_disp" "false")])
15549 (define_insn "*load_tp_di"
15550 [(set (match_operand:DI 0 "register_operand" "=r")
15551 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15553 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15554 [(set_attr "type" "imov")
15555 (set_attr "modrm" "0")
15556 (set_attr "length" "7")
15557 (set_attr "memory" "load")
15558 (set_attr "imm_disp" "false")])
15560 (define_insn "*add_tp_di"
15561 [(set (match_operand:DI 0 "register_operand" "=r")
15562 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15563 (match_operand:DI 1 "register_operand" "0")))
15564 (clobber (reg:CC FLAGS_REG))]
15566 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15567 [(set_attr "type" "alu")
15568 (set_attr "modrm" "0")
15569 (set_attr "length" "7")
15570 (set_attr "memory" "load")
15571 (set_attr "imm_disp" "false")])
15573 ;; GNU2 TLS patterns can be split.
15575 (define_expand "tls_dynamic_gnu2_32"
15576 [(set (match_dup 3)
15577 (plus:SI (match_operand:SI 2 "register_operand" "")
15579 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15582 [(set (match_operand:SI 0 "register_operand" "")
15583 (unspec:SI [(match_dup 1) (match_dup 3)
15584 (match_dup 2) (reg:SI SP_REG)]
15586 (clobber (reg:CC FLAGS_REG))])]
15587 "!TARGET_64BIT && TARGET_GNU2_TLS"
15589 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15590 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15593 (define_insn "*tls_dynamic_lea_32"
15594 [(set (match_operand:SI 0 "register_operand" "=r")
15595 (plus:SI (match_operand:SI 1 "register_operand" "b")
15597 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15598 UNSPEC_TLSDESC))))]
15599 "!TARGET_64BIT && TARGET_GNU2_TLS"
15600 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15601 [(set_attr "type" "lea")
15602 (set_attr "mode" "SI")
15603 (set_attr "length" "6")
15604 (set_attr "length_address" "4")])
15606 (define_insn "*tls_dynamic_call_32"
15607 [(set (match_operand:SI 0 "register_operand" "=a")
15608 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15609 (match_operand:SI 2 "register_operand" "0")
15610 ;; we have to make sure %ebx still points to the GOT
15611 (match_operand:SI 3 "register_operand" "b")
15614 (clobber (reg:CC FLAGS_REG))]
15615 "!TARGET_64BIT && TARGET_GNU2_TLS"
15616 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15617 [(set_attr "type" "call")
15618 (set_attr "length" "2")
15619 (set_attr "length_address" "0")])
15621 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15622 [(set (match_operand:SI 0 "register_operand" "=&a")
15624 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15625 (match_operand:SI 4 "" "")
15626 (match_operand:SI 2 "register_operand" "b")
15629 (const:SI (unspec:SI
15630 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15632 (clobber (reg:CC FLAGS_REG))]
15633 "!TARGET_64BIT && TARGET_GNU2_TLS"
15636 [(set (match_dup 0) (match_dup 5))]
15638 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15639 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15642 (define_expand "tls_dynamic_gnu2_64"
15643 [(set (match_dup 2)
15644 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15647 [(set (match_operand:DI 0 "register_operand" "")
15648 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15650 (clobber (reg:CC FLAGS_REG))])]
15651 "TARGET_64BIT && TARGET_GNU2_TLS"
15653 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15654 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15657 (define_insn "*tls_dynamic_lea_64"
15658 [(set (match_operand:DI 0 "register_operand" "=r")
15659 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15661 "TARGET_64BIT && TARGET_GNU2_TLS"
15662 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15663 [(set_attr "type" "lea")
15664 (set_attr "mode" "DI")
15665 (set_attr "length" "7")
15666 (set_attr "length_address" "4")])
15668 (define_insn "*tls_dynamic_call_64"
15669 [(set (match_operand:DI 0 "register_operand" "=a")
15670 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15671 (match_operand:DI 2 "register_operand" "0")
15674 (clobber (reg:CC FLAGS_REG))]
15675 "TARGET_64BIT && TARGET_GNU2_TLS"
15676 "call\t{*%a1@TLSCALL(%2)|[QWORD 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_64"
15682 [(set (match_operand:DI 0 "register_operand" "=&a")
15684 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15685 (match_operand:DI 3 "" "")
15688 (const:DI (unspec:DI
15689 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15691 (clobber (reg:CC FLAGS_REG))]
15692 "TARGET_64BIT && TARGET_GNU2_TLS"
15695 [(set (match_dup 0) (match_dup 4))]
15697 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15698 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15703 ;; These patterns match the binary 387 instructions for addM3, subM3,
15704 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15705 ;; SFmode. The first is the normal insn, the second the same insn but
15706 ;; with one operand a conversion, and the third the same insn but with
15707 ;; the other operand a conversion. The conversion may be SFmode or
15708 ;; SImode if the target mode DFmode, but only SImode if the target mode
15711 ;; Gcc is slightly more smart about handling normal two address instructions
15712 ;; so use special patterns for add and mull.
15714 (define_insn "*fop_sf_comm_mixed"
15715 [(set (match_operand:SF 0 "register_operand" "=f,x")
15716 (match_operator:SF 3 "binary_fp_operator"
15717 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15718 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15719 "TARGET_MIX_SSE_I387
15720 && COMMUTATIVE_ARITH_P (operands[3])
15721 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15722 "* return output_387_binary_op (insn, operands);"
15723 [(set (attr "type")
15724 (if_then_else (eq_attr "alternative" "1")
15725 (if_then_else (match_operand:SF 3 "mult_operator" "")
15726 (const_string "ssemul")
15727 (const_string "sseadd"))
15728 (if_then_else (match_operand:SF 3 "mult_operator" "")
15729 (const_string "fmul")
15730 (const_string "fop"))))
15731 (set_attr "mode" "SF")])
15733 (define_insn "*fop_sf_comm_sse"
15734 [(set (match_operand:SF 0 "register_operand" "=x")
15735 (match_operator:SF 3 "binary_fp_operator"
15736 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15737 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15739 && COMMUTATIVE_ARITH_P (operands[3])
15740 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15741 "* return output_387_binary_op (insn, operands);"
15742 [(set (attr "type")
15743 (if_then_else (match_operand:SF 3 "mult_operator" "")
15744 (const_string "ssemul")
15745 (const_string "sseadd")))
15746 (set_attr "mode" "SF")])
15748 (define_insn "*fop_sf_comm_i387"
15749 [(set (match_operand:SF 0 "register_operand" "=f")
15750 (match_operator:SF 3 "binary_fp_operator"
15751 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15752 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15754 && COMMUTATIVE_ARITH_P (operands[3])
15755 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15756 "* return output_387_binary_op (insn, operands);"
15757 [(set (attr "type")
15758 (if_then_else (match_operand:SF 3 "mult_operator" "")
15759 (const_string "fmul")
15760 (const_string "fop")))
15761 (set_attr "mode" "SF")])
15763 (define_insn "*fop_sf_1_mixed"
15764 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15765 (match_operator:SF 3 "binary_fp_operator"
15766 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15767 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15768 "TARGET_MIX_SSE_I387
15769 && !COMMUTATIVE_ARITH_P (operands[3])
15770 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15771 "* return output_387_binary_op (insn, operands);"
15772 [(set (attr "type")
15773 (cond [(and (eq_attr "alternative" "2")
15774 (match_operand:SF 3 "mult_operator" ""))
15775 (const_string "ssemul")
15776 (and (eq_attr "alternative" "2")
15777 (match_operand:SF 3 "div_operator" ""))
15778 (const_string "ssediv")
15779 (eq_attr "alternative" "2")
15780 (const_string "sseadd")
15781 (match_operand:SF 3 "mult_operator" "")
15782 (const_string "fmul")
15783 (match_operand:SF 3 "div_operator" "")
15784 (const_string "fdiv")
15786 (const_string "fop")))
15787 (set_attr "mode" "SF")])
15789 (define_insn "*rcpsf2_sse"
15790 [(set (match_operand:SF 0 "register_operand" "=x")
15791 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15794 "rcpss\t{%1, %0|%0, %1}"
15795 [(set_attr "type" "sse")
15796 (set_attr "mode" "SF")])
15798 (define_insn "*fop_sf_1_sse"
15799 [(set (match_operand:SF 0 "register_operand" "=x")
15800 (match_operator:SF 3 "binary_fp_operator"
15801 [(match_operand:SF 1 "register_operand" "0")
15802 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15804 && !COMMUTATIVE_ARITH_P (operands[3])"
15805 "* return output_387_binary_op (insn, operands);"
15806 [(set (attr "type")
15807 (cond [(match_operand:SF 3 "mult_operator" "")
15808 (const_string "ssemul")
15809 (match_operand:SF 3 "div_operator" "")
15810 (const_string "ssediv")
15812 (const_string "sseadd")))
15813 (set_attr "mode" "SF")])
15815 ;; This pattern is not fully shadowed by the pattern above.
15816 (define_insn "*fop_sf_1_i387"
15817 [(set (match_operand:SF 0 "register_operand" "=f,f")
15818 (match_operator:SF 3 "binary_fp_operator"
15819 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15820 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15821 "TARGET_80387 && !TARGET_SSE_MATH
15822 && !COMMUTATIVE_ARITH_P (operands[3])
15823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15824 "* return output_387_binary_op (insn, operands);"
15825 [(set (attr "type")
15826 (cond [(match_operand:SF 3 "mult_operator" "")
15827 (const_string "fmul")
15828 (match_operand:SF 3 "div_operator" "")
15829 (const_string "fdiv")
15831 (const_string "fop")))
15832 (set_attr "mode" "SF")])
15834 ;; ??? Add SSE splitters for these!
15835 (define_insn "*fop_sf_2<mode>_i387"
15836 [(set (match_operand:SF 0 "register_operand" "=f,f")
15837 (match_operator:SF 3 "binary_fp_operator"
15838 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15839 (match_operand:SF 2 "register_operand" "0,0")]))]
15840 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15841 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15842 [(set (attr "type")
15843 (cond [(match_operand:SF 3 "mult_operator" "")
15844 (const_string "fmul")
15845 (match_operand:SF 3 "div_operator" "")
15846 (const_string "fdiv")
15848 (const_string "fop")))
15849 (set_attr "fp_int_src" "true")
15850 (set_attr "mode" "<MODE>")])
15852 (define_insn "*fop_sf_3<mode>_i387"
15853 [(set (match_operand:SF 0 "register_operand" "=f,f")
15854 (match_operator:SF 3 "binary_fp_operator"
15855 [(match_operand:SF 1 "register_operand" "0,0")
15856 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15857 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15858 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15859 [(set (attr "type")
15860 (cond [(match_operand:SF 3 "mult_operator" "")
15861 (const_string "fmul")
15862 (match_operand:SF 3 "div_operator" "")
15863 (const_string "fdiv")
15865 (const_string "fop")))
15866 (set_attr "fp_int_src" "true")
15867 (set_attr "mode" "<MODE>")])
15869 (define_insn "*fop_df_comm_mixed"
15870 [(set (match_operand:DF 0 "register_operand" "=f,x")
15871 (match_operator:DF 3 "binary_fp_operator"
15872 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15873 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15874 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15875 && COMMUTATIVE_ARITH_P (operands[3])
15876 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15877 "* return output_387_binary_op (insn, operands);"
15878 [(set (attr "type")
15879 (if_then_else (eq_attr "alternative" "1")
15880 (if_then_else (match_operand:DF 3 "mult_operator" "")
15881 (const_string "ssemul")
15882 (const_string "sseadd"))
15883 (if_then_else (match_operand:DF 3 "mult_operator" "")
15884 (const_string "fmul")
15885 (const_string "fop"))))
15886 (set_attr "mode" "DF")])
15888 (define_insn "*fop_df_comm_sse"
15889 [(set (match_operand:DF 0 "register_operand" "=x")
15890 (match_operator:DF 3 "binary_fp_operator"
15891 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15892 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15893 "TARGET_SSE2 && TARGET_SSE_MATH
15894 && COMMUTATIVE_ARITH_P (operands[3])
15895 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15896 "* return output_387_binary_op (insn, operands);"
15897 [(set (attr "type")
15898 (if_then_else (match_operand:DF 3 "mult_operator" "")
15899 (const_string "ssemul")
15900 (const_string "sseadd")))
15901 (set_attr "mode" "DF")])
15903 (define_insn "*fop_df_comm_i387"
15904 [(set (match_operand:DF 0 "register_operand" "=f")
15905 (match_operator:DF 3 "binary_fp_operator"
15906 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15907 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15909 && COMMUTATIVE_ARITH_P (operands[3])
15910 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15911 "* return output_387_binary_op (insn, operands);"
15912 [(set (attr "type")
15913 (if_then_else (match_operand:DF 3 "mult_operator" "")
15914 (const_string "fmul")
15915 (const_string "fop")))
15916 (set_attr "mode" "DF")])
15918 (define_insn "*fop_df_1_mixed"
15919 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15920 (match_operator:DF 3 "binary_fp_operator"
15921 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15922 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15923 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15924 && !COMMUTATIVE_ARITH_P (operands[3])
15925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15926 "* return output_387_binary_op (insn, operands);"
15927 [(set (attr "type")
15928 (cond [(and (eq_attr "alternative" "2")
15929 (match_operand:DF 3 "mult_operator" ""))
15930 (const_string "ssemul")
15931 (and (eq_attr "alternative" "2")
15932 (match_operand:DF 3 "div_operator" ""))
15933 (const_string "ssediv")
15934 (eq_attr "alternative" "2")
15935 (const_string "sseadd")
15936 (match_operand:DF 3 "mult_operator" "")
15937 (const_string "fmul")
15938 (match_operand:DF 3 "div_operator" "")
15939 (const_string "fdiv")
15941 (const_string "fop")))
15942 (set_attr "mode" "DF")])
15944 (define_insn "*fop_df_1_sse"
15945 [(set (match_operand:DF 0 "register_operand" "=x")
15946 (match_operator:DF 3 "binary_fp_operator"
15947 [(match_operand:DF 1 "register_operand" "0")
15948 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15949 "TARGET_SSE2 && TARGET_SSE_MATH
15950 && !COMMUTATIVE_ARITH_P (operands[3])"
15951 "* return output_387_binary_op (insn, operands);"
15952 [(set_attr "mode" "DF")
15954 (cond [(match_operand:DF 3 "mult_operator" "")
15955 (const_string "ssemul")
15956 (match_operand:DF 3 "div_operator" "")
15957 (const_string "ssediv")
15959 (const_string "sseadd")))])
15961 ;; This pattern is not fully shadowed by the pattern above.
15962 (define_insn "*fop_df_1_i387"
15963 [(set (match_operand:DF 0 "register_operand" "=f,f")
15964 (match_operator:DF 3 "binary_fp_operator"
15965 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15966 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15967 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15968 && !COMMUTATIVE_ARITH_P (operands[3])
15969 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15970 "* return output_387_binary_op (insn, operands);"
15971 [(set (attr "type")
15972 (cond [(match_operand:DF 3 "mult_operator" "")
15973 (const_string "fmul")
15974 (match_operand:DF 3 "div_operator" "")
15975 (const_string "fdiv")
15977 (const_string "fop")))
15978 (set_attr "mode" "DF")])
15980 ;; ??? Add SSE splitters for these!
15981 (define_insn "*fop_df_2<mode>_i387"
15982 [(set (match_operand:DF 0 "register_operand" "=f,f")
15983 (match_operator:DF 3 "binary_fp_operator"
15984 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15985 (match_operand:DF 2 "register_operand" "0,0")]))]
15986 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15987 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15988 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15989 [(set (attr "type")
15990 (cond [(match_operand:DF 3 "mult_operator" "")
15991 (const_string "fmul")
15992 (match_operand:DF 3 "div_operator" "")
15993 (const_string "fdiv")
15995 (const_string "fop")))
15996 (set_attr "fp_int_src" "true")
15997 (set_attr "mode" "<MODE>")])
15999 (define_insn "*fop_df_3<mode>_i387"
16000 [(set (match_operand:DF 0 "register_operand" "=f,f")
16001 (match_operator:DF 3 "binary_fp_operator"
16002 [(match_operand:DF 1 "register_operand" "0,0")
16003 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16004 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16005 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16006 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16007 [(set (attr "type")
16008 (cond [(match_operand:DF 3 "mult_operator" "")
16009 (const_string "fmul")
16010 (match_operand:DF 3 "div_operator" "")
16011 (const_string "fdiv")
16013 (const_string "fop")))
16014 (set_attr "fp_int_src" "true")
16015 (set_attr "mode" "<MODE>")])
16017 (define_insn "*fop_df_4_i387"
16018 [(set (match_operand:DF 0 "register_operand" "=f,f")
16019 (match_operator:DF 3 "binary_fp_operator"
16020 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16021 (match_operand:DF 2 "register_operand" "0,f")]))]
16022 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16023 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16024 "* return output_387_binary_op (insn, operands);"
16025 [(set (attr "type")
16026 (cond [(match_operand:DF 3 "mult_operator" "")
16027 (const_string "fmul")
16028 (match_operand:DF 3 "div_operator" "")
16029 (const_string "fdiv")
16031 (const_string "fop")))
16032 (set_attr "mode" "SF")])
16034 (define_insn "*fop_df_5_i387"
16035 [(set (match_operand:DF 0 "register_operand" "=f,f")
16036 (match_operator:DF 3 "binary_fp_operator"
16037 [(match_operand:DF 1 "register_operand" "0,f")
16039 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16040 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16041 "* return output_387_binary_op (insn, operands);"
16042 [(set (attr "type")
16043 (cond [(match_operand:DF 3 "mult_operator" "")
16044 (const_string "fmul")
16045 (match_operand:DF 3 "div_operator" "")
16046 (const_string "fdiv")
16048 (const_string "fop")))
16049 (set_attr "mode" "SF")])
16051 (define_insn "*fop_df_6_i387"
16052 [(set (match_operand:DF 0 "register_operand" "=f,f")
16053 (match_operator:DF 3 "binary_fp_operator"
16055 (match_operand:SF 1 "register_operand" "0,f"))
16057 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16058 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16059 "* return output_387_binary_op (insn, operands);"
16060 [(set (attr "type")
16061 (cond [(match_operand:DF 3 "mult_operator" "")
16062 (const_string "fmul")
16063 (match_operand:DF 3 "div_operator" "")
16064 (const_string "fdiv")
16066 (const_string "fop")))
16067 (set_attr "mode" "SF")])
16069 (define_insn "*fop_xf_comm_i387"
16070 [(set (match_operand:XF 0 "register_operand" "=f")
16071 (match_operator:XF 3 "binary_fp_operator"
16072 [(match_operand:XF 1 "register_operand" "%0")
16073 (match_operand:XF 2 "register_operand" "f")]))]
16075 && COMMUTATIVE_ARITH_P (operands[3])"
16076 "* return output_387_binary_op (insn, operands);"
16077 [(set (attr "type")
16078 (if_then_else (match_operand:XF 3 "mult_operator" "")
16079 (const_string "fmul")
16080 (const_string "fop")))
16081 (set_attr "mode" "XF")])
16083 (define_insn "*fop_xf_1_i387"
16084 [(set (match_operand:XF 0 "register_operand" "=f,f")
16085 (match_operator:XF 3 "binary_fp_operator"
16086 [(match_operand:XF 1 "register_operand" "0,f")
16087 (match_operand:XF 2 "register_operand" "f,0")]))]
16089 && !COMMUTATIVE_ARITH_P (operands[3])"
16090 "* return output_387_binary_op (insn, operands);"
16091 [(set (attr "type")
16092 (cond [(match_operand:XF 3 "mult_operator" "")
16093 (const_string "fmul")
16094 (match_operand:XF 3 "div_operator" "")
16095 (const_string "fdiv")
16097 (const_string "fop")))
16098 (set_attr "mode" "XF")])
16100 (define_insn "*fop_xf_2<mode>_i387"
16101 [(set (match_operand:XF 0 "register_operand" "=f,f")
16102 (match_operator:XF 3 "binary_fp_operator"
16103 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16104 (match_operand:XF 2 "register_operand" "0,0")]))]
16105 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16106 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16107 [(set (attr "type")
16108 (cond [(match_operand:XF 3 "mult_operator" "")
16109 (const_string "fmul")
16110 (match_operand:XF 3 "div_operator" "")
16111 (const_string "fdiv")
16113 (const_string "fop")))
16114 (set_attr "fp_int_src" "true")
16115 (set_attr "mode" "<MODE>")])
16117 (define_insn "*fop_xf_3<mode>_i387"
16118 [(set (match_operand:XF 0 "register_operand" "=f,f")
16119 (match_operator:XF 3 "binary_fp_operator"
16120 [(match_operand:XF 1 "register_operand" "0,0")
16121 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16122 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16123 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16124 [(set (attr "type")
16125 (cond [(match_operand:XF 3 "mult_operator" "")
16126 (const_string "fmul")
16127 (match_operand:XF 3 "div_operator" "")
16128 (const_string "fdiv")
16130 (const_string "fop")))
16131 (set_attr "fp_int_src" "true")
16132 (set_attr "mode" "<MODE>")])
16134 (define_insn "*fop_xf_4_i387"
16135 [(set (match_operand:XF 0 "register_operand" "=f,f")
16136 (match_operator:XF 3 "binary_fp_operator"
16138 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16139 (match_operand:XF 2 "register_operand" "0,f")]))]
16141 "* return output_387_binary_op (insn, operands);"
16142 [(set (attr "type")
16143 (cond [(match_operand:XF 3 "mult_operator" "")
16144 (const_string "fmul")
16145 (match_operand:XF 3 "div_operator" "")
16146 (const_string "fdiv")
16148 (const_string "fop")))
16149 (set_attr "mode" "SF")])
16151 (define_insn "*fop_xf_5_i387"
16152 [(set (match_operand:XF 0 "register_operand" "=f,f")
16153 (match_operator:XF 3 "binary_fp_operator"
16154 [(match_operand:XF 1 "register_operand" "0,f")
16156 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16158 "* return output_387_binary_op (insn, operands);"
16159 [(set (attr "type")
16160 (cond [(match_operand:XF 3 "mult_operator" "")
16161 (const_string "fmul")
16162 (match_operand:XF 3 "div_operator" "")
16163 (const_string "fdiv")
16165 (const_string "fop")))
16166 (set_attr "mode" "SF")])
16168 (define_insn "*fop_xf_6_i387"
16169 [(set (match_operand:XF 0 "register_operand" "=f,f")
16170 (match_operator:XF 3 "binary_fp_operator"
16172 (match_operand:MODEF 1 "register_operand" "0,f"))
16174 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16176 "* return output_387_binary_op (insn, operands);"
16177 [(set (attr "type")
16178 (cond [(match_operand:XF 3 "mult_operator" "")
16179 (const_string "fmul")
16180 (match_operand:XF 3 "div_operator" "")
16181 (const_string "fdiv")
16183 (const_string "fop")))
16184 (set_attr "mode" "SF")])
16187 [(set (match_operand 0 "register_operand" "")
16188 (match_operator 3 "binary_fp_operator"
16189 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16190 (match_operand 2 "register_operand" "")]))]
16192 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16195 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16196 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16197 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16198 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16199 GET_MODE (operands[3]),
16202 ix86_free_from_memory (GET_MODE (operands[1]));
16207 [(set (match_operand 0 "register_operand" "")
16208 (match_operator 3 "binary_fp_operator"
16209 [(match_operand 1 "register_operand" "")
16210 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16212 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16215 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16216 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16217 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16218 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16219 GET_MODE (operands[3]),
16222 ix86_free_from_memory (GET_MODE (operands[2]));
16226 ;; FPU special functions.
16228 ;; This pattern implements a no-op XFmode truncation for
16229 ;; all fancy i386 XFmode math functions.
16231 (define_insn "truncxf<mode>2_i387_noop_unspec"
16232 [(set (match_operand:MODEF 0 "register_operand" "=f")
16233 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16234 UNSPEC_TRUNC_NOOP))]
16235 "TARGET_USE_FANCY_MATH_387"
16236 "* return output_387_reg_move (insn, operands);"
16237 [(set_attr "type" "fmov")
16238 (set_attr "mode" "<MODE>")])
16240 (define_insn "sqrtxf2"
16241 [(set (match_operand:XF 0 "register_operand" "=f")
16242 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16243 "TARGET_USE_FANCY_MATH_387"
16245 [(set_attr "type" "fpspc")
16246 (set_attr "mode" "XF")
16247 (set_attr "athlon_decode" "direct")
16248 (set_attr "amdfam10_decode" "direct")])
16250 (define_insn "sqrt_extend<mode>xf2_i387"
16251 [(set (match_operand:XF 0 "register_operand" "=f")
16254 (match_operand:MODEF 1 "register_operand" "0"))))]
16255 "TARGET_USE_FANCY_MATH_387"
16257 [(set_attr "type" "fpspc")
16258 (set_attr "mode" "XF")
16259 (set_attr "athlon_decode" "direct")
16260 (set_attr "amdfam10_decode" "direct")])
16262 (define_insn "*rsqrtsf2_sse"
16263 [(set (match_operand:SF 0 "register_operand" "=x")
16264 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16267 "rsqrtss\t{%1, %0|%0, %1}"
16268 [(set_attr "type" "sse")
16269 (set_attr "mode" "SF")])
16271 (define_expand "rsqrtsf2"
16272 [(set (match_operand:SF 0 "register_operand" "")
16273 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16277 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16281 (define_insn "*sqrt<mode>2_sse"
16282 [(set (match_operand:MODEF 0 "register_operand" "=x")
16284 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16285 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16286 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16287 [(set_attr "type" "sse")
16288 (set_attr "mode" "<MODE>")
16289 (set_attr "athlon_decode" "*")
16290 (set_attr "amdfam10_decode" "*")])
16292 (define_expand "sqrt<mode>2"
16293 [(set (match_operand:MODEF 0 "register_operand" "")
16295 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16296 "TARGET_USE_FANCY_MATH_387
16297 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16299 if (<MODE>mode == SFmode
16300 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16301 && flag_finite_math_only && !flag_trapping_math
16302 && flag_unsafe_math_optimizations)
16304 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16308 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16310 rtx op0 = gen_reg_rtx (XFmode);
16311 rtx op1 = force_reg (<MODE>mode, operands[1]);
16313 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16314 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16319 (define_insn "fpremxf4_i387"
16320 [(set (match_operand:XF 0 "register_operand" "=f")
16321 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16322 (match_operand:XF 3 "register_operand" "1")]
16324 (set (match_operand:XF 1 "register_operand" "=u")
16325 (unspec:XF [(match_dup 2) (match_dup 3)]
16327 (set (reg:CCFP FPSR_REG)
16328 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16330 "TARGET_USE_FANCY_MATH_387"
16332 [(set_attr "type" "fpspc")
16333 (set_attr "mode" "XF")])
16335 (define_expand "fmodxf3"
16336 [(use (match_operand:XF 0 "register_operand" ""))
16337 (use (match_operand:XF 1 "register_operand" ""))
16338 (use (match_operand:XF 2 "register_operand" ""))]
16339 "TARGET_USE_FANCY_MATH_387"
16341 rtx label = gen_label_rtx ();
16345 if (rtx_equal_p (operands[1], operands[2]))
16347 op2 = gen_reg_rtx (XFmode);
16348 emit_move_insn (op2, operands[2]);
16353 emit_label (label);
16354 emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16355 ix86_emit_fp_unordered_jump (label);
16356 LABEL_NUSES (label) = 1;
16358 emit_move_insn (operands[0], operands[1]);
16362 (define_expand "fmod<mode>3"
16363 [(use (match_operand:MODEF 0 "register_operand" ""))
16364 (use (match_operand:MODEF 1 "general_operand" ""))
16365 (use (match_operand:MODEF 2 "general_operand" ""))]
16366 "TARGET_USE_FANCY_MATH_387"
16368 rtx label = gen_label_rtx ();
16370 rtx op1 = gen_reg_rtx (XFmode);
16371 rtx op2 = gen_reg_rtx (XFmode);
16373 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16374 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16376 emit_label (label);
16377 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16378 ix86_emit_fp_unordered_jump (label);
16379 LABEL_NUSES (label) = 1;
16381 /* Truncate the result properly for strict SSE math. */
16382 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16383 && !TARGET_MIX_SSE_I387)
16384 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16386 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16391 (define_insn "fprem1xf4_i387"
16392 [(set (match_operand:XF 0 "register_operand" "=f")
16393 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16394 (match_operand:XF 3 "register_operand" "1")]
16396 (set (match_operand:XF 1 "register_operand" "=u")
16397 (unspec:XF [(match_dup 2) (match_dup 3)]
16399 (set (reg:CCFP FPSR_REG)
16400 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16402 "TARGET_USE_FANCY_MATH_387"
16404 [(set_attr "type" "fpspc")
16405 (set_attr "mode" "XF")])
16407 (define_expand "remainderxf3"
16408 [(use (match_operand:XF 0 "register_operand" ""))
16409 (use (match_operand:XF 1 "register_operand" ""))
16410 (use (match_operand:XF 2 "register_operand" ""))]
16411 "TARGET_USE_FANCY_MATH_387"
16413 rtx label = gen_label_rtx ();
16417 if (rtx_equal_p (operands[1], operands[2]))
16419 op2 = gen_reg_rtx (XFmode);
16420 emit_move_insn (op2, operands[2]);
16425 emit_label (label);
16426 emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16427 ix86_emit_fp_unordered_jump (label);
16428 LABEL_NUSES (label) = 1;
16430 emit_move_insn (operands[0], operands[1]);
16434 (define_expand "remainder<mode>3"
16435 [(use (match_operand:MODEF 0 "register_operand" ""))
16436 (use (match_operand:MODEF 1 "general_operand" ""))
16437 (use (match_operand:MODEF 2 "general_operand" ""))]
16438 "TARGET_USE_FANCY_MATH_387"
16440 rtx label = gen_label_rtx ();
16442 rtx op1 = gen_reg_rtx (XFmode);
16443 rtx op2 = gen_reg_rtx (XFmode);
16445 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16446 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16448 emit_label (label);
16450 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16451 ix86_emit_fp_unordered_jump (label);
16452 LABEL_NUSES (label) = 1;
16454 /* Truncate the result properly for strict SSE math. */
16455 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16456 && !TARGET_MIX_SSE_I387)
16457 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16459 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16464 (define_insn "*sinxf2_i387"
16465 [(set (match_operand:XF 0 "register_operand" "=f")
16466 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16467 "TARGET_USE_FANCY_MATH_387
16468 && flag_unsafe_math_optimizations"
16470 [(set_attr "type" "fpspc")
16471 (set_attr "mode" "XF")])
16473 (define_insn "*sin_extend<mode>xf2_i387"
16474 [(set (match_operand:XF 0 "register_operand" "=f")
16475 (unspec:XF [(float_extend:XF
16476 (match_operand:MODEF 1 "register_operand" "0"))]
16478 "TARGET_USE_FANCY_MATH_387
16479 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16480 || TARGET_MIX_SSE_I387)
16481 && flag_unsafe_math_optimizations"
16483 [(set_attr "type" "fpspc")
16484 (set_attr "mode" "XF")])
16486 (define_insn "*cosxf2_i387"
16487 [(set (match_operand:XF 0 "register_operand" "=f")
16488 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16489 "TARGET_USE_FANCY_MATH_387
16490 && flag_unsafe_math_optimizations"
16492 [(set_attr "type" "fpspc")
16493 (set_attr "mode" "XF")])
16495 (define_insn "*cos_extend<mode>xf2_i387"
16496 [(set (match_operand:XF 0 "register_operand" "=f")
16497 (unspec:XF [(float_extend:XF
16498 (match_operand:MODEF 1 "register_operand" "0"))]
16500 "TARGET_USE_FANCY_MATH_387
16501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16502 || TARGET_MIX_SSE_I387)
16503 && flag_unsafe_math_optimizations"
16505 [(set_attr "type" "fpspc")
16506 (set_attr "mode" "XF")])
16508 ;; When sincos pattern is defined, sin and cos builtin functions will be
16509 ;; expanded to sincos pattern with one of its outputs left unused.
16510 ;; CSE pass will figure out if two sincos patterns can be combined,
16511 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16512 ;; depending on the unused output.
16514 (define_insn "sincosxf3"
16515 [(set (match_operand:XF 0 "register_operand" "=f")
16516 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16517 UNSPEC_SINCOS_COS))
16518 (set (match_operand:XF 1 "register_operand" "=u")
16519 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16520 "TARGET_USE_FANCY_MATH_387
16521 && flag_unsafe_math_optimizations"
16523 [(set_attr "type" "fpspc")
16524 (set_attr "mode" "XF")])
16527 [(set (match_operand:XF 0 "register_operand" "")
16528 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16529 UNSPEC_SINCOS_COS))
16530 (set (match_operand:XF 1 "register_operand" "")
16531 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16532 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16533 && !(reload_completed || reload_in_progress)"
16534 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16538 [(set (match_operand:XF 0 "register_operand" "")
16539 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16540 UNSPEC_SINCOS_COS))
16541 (set (match_operand:XF 1 "register_operand" "")
16542 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16543 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16544 && !(reload_completed || reload_in_progress)"
16545 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16548 (define_insn "sincos_extend<mode>xf3_i387"
16549 [(set (match_operand:XF 0 "register_operand" "=f")
16550 (unspec:XF [(float_extend:XF
16551 (match_operand:MODEF 2 "register_operand" "0"))]
16552 UNSPEC_SINCOS_COS))
16553 (set (match_operand:XF 1 "register_operand" "=u")
16554 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16555 "TARGET_USE_FANCY_MATH_387
16556 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16557 || TARGET_MIX_SSE_I387)
16558 && flag_unsafe_math_optimizations"
16560 [(set_attr "type" "fpspc")
16561 (set_attr "mode" "XF")])
16564 [(set (match_operand:XF 0 "register_operand" "")
16565 (unspec:XF [(float_extend:XF
16566 (match_operand:MODEF 2 "register_operand" ""))]
16567 UNSPEC_SINCOS_COS))
16568 (set (match_operand:XF 1 "register_operand" "")
16569 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16570 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16571 && !(reload_completed || reload_in_progress)"
16572 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16576 [(set (match_operand:XF 0 "register_operand" "")
16577 (unspec:XF [(float_extend:XF
16578 (match_operand:MODEF 2 "register_operand" ""))]
16579 UNSPEC_SINCOS_COS))
16580 (set (match_operand:XF 1 "register_operand" "")
16581 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16582 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16583 && !(reload_completed || reload_in_progress)"
16584 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16587 (define_expand "sincos<mode>3"
16588 [(use (match_operand:MODEF 0 "register_operand" ""))
16589 (use (match_operand:MODEF 1 "register_operand" ""))
16590 (use (match_operand:MODEF 2 "register_operand" ""))]
16591 "TARGET_USE_FANCY_MATH_387
16592 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16593 || TARGET_MIX_SSE_I387)
16594 && flag_unsafe_math_optimizations"
16596 rtx op0 = gen_reg_rtx (XFmode);
16597 rtx op1 = gen_reg_rtx (XFmode);
16599 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16600 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16601 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16605 (define_insn "fptanxf4_i387"
16606 [(set (match_operand:XF 0 "register_operand" "=f")
16607 (match_operand:XF 3 "const_double_operand" "F"))
16608 (set (match_operand:XF 1 "register_operand" "=u")
16609 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16611 "TARGET_USE_FANCY_MATH_387
16612 && flag_unsafe_math_optimizations
16613 && standard_80387_constant_p (operands[3]) == 2"
16615 [(set_attr "type" "fpspc")
16616 (set_attr "mode" "XF")])
16618 (define_insn "fptan_extend<mode>xf4_i387"
16619 [(set (match_operand:MODEF 0 "register_operand" "=f")
16620 (match_operand:MODEF 3 "const_double_operand" "F"))
16621 (set (match_operand:XF 1 "register_operand" "=u")
16622 (unspec:XF [(float_extend:XF
16623 (match_operand:MODEF 2 "register_operand" "0"))]
16625 "TARGET_USE_FANCY_MATH_387
16626 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16627 || TARGET_MIX_SSE_I387)
16628 && flag_unsafe_math_optimizations
16629 && standard_80387_constant_p (operands[3]) == 2"
16631 [(set_attr "type" "fpspc")
16632 (set_attr "mode" "XF")])
16634 (define_expand "tanxf2"
16635 [(use (match_operand:XF 0 "register_operand" ""))
16636 (use (match_operand:XF 1 "register_operand" ""))]
16637 "TARGET_USE_FANCY_MATH_387
16638 && flag_unsafe_math_optimizations"
16640 rtx one = gen_reg_rtx (XFmode);
16641 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16643 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16647 (define_expand "tan<mode>2"
16648 [(use (match_operand:MODEF 0 "register_operand" ""))
16649 (use (match_operand:MODEF 1 "register_operand" ""))]
16650 "TARGET_USE_FANCY_MATH_387
16651 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16652 || TARGET_MIX_SSE_I387)
16653 && flag_unsafe_math_optimizations"
16655 rtx op0 = gen_reg_rtx (XFmode);
16657 rtx one = gen_reg_rtx (<MODE>mode);
16658 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16660 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16661 operands[1], op2));
16662 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16666 (define_insn "*fpatanxf3_i387"
16667 [(set (match_operand:XF 0 "register_operand" "=f")
16668 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16669 (match_operand:XF 2 "register_operand" "u")]
16671 (clobber (match_scratch:XF 3 "=2"))]
16672 "TARGET_USE_FANCY_MATH_387
16673 && flag_unsafe_math_optimizations"
16675 [(set_attr "type" "fpspc")
16676 (set_attr "mode" "XF")])
16678 (define_insn "fpatan_extend<mode>xf3_i387"
16679 [(set (match_operand:XF 0 "register_operand" "=f")
16680 (unspec:XF [(float_extend:XF
16681 (match_operand:MODEF 1 "register_operand" "0"))
16683 (match_operand:MODEF 2 "register_operand" "u"))]
16685 (clobber (match_scratch:XF 3 "=2"))]
16686 "TARGET_USE_FANCY_MATH_387
16687 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16688 || TARGET_MIX_SSE_I387)
16689 && flag_unsafe_math_optimizations"
16691 [(set_attr "type" "fpspc")
16692 (set_attr "mode" "XF")])
16694 (define_expand "atan2xf3"
16695 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16696 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16697 (match_operand:XF 1 "register_operand" "")]
16699 (clobber (match_scratch:XF 3 ""))])]
16700 "TARGET_USE_FANCY_MATH_387
16701 && flag_unsafe_math_optimizations"
16704 (define_expand "atan2<mode>3"
16705 [(use (match_operand:MODEF 0 "register_operand" ""))
16706 (use (match_operand:MODEF 1 "register_operand" ""))
16707 (use (match_operand:MODEF 2 "register_operand" ""))]
16708 "TARGET_USE_FANCY_MATH_387
16709 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16710 || TARGET_MIX_SSE_I387)
16711 && flag_unsafe_math_optimizations"
16713 rtx op0 = gen_reg_rtx (XFmode);
16715 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16716 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16720 (define_expand "atanxf2"
16721 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16722 (unspec:XF [(match_dup 2)
16723 (match_operand:XF 1 "register_operand" "")]
16725 (clobber (match_scratch:XF 3 ""))])]
16726 "TARGET_USE_FANCY_MATH_387
16727 && flag_unsafe_math_optimizations"
16729 operands[2] = gen_reg_rtx (XFmode);
16730 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16733 (define_expand "atan<mode>2"
16734 [(use (match_operand:MODEF 0 "register_operand" ""))
16735 (use (match_operand:MODEF 1 "register_operand" ""))]
16736 "TARGET_USE_FANCY_MATH_387
16737 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16738 || TARGET_MIX_SSE_I387)
16739 && flag_unsafe_math_optimizations"
16741 rtx op0 = gen_reg_rtx (XFmode);
16743 rtx op2 = gen_reg_rtx (<MODE>mode);
16744 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16746 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16747 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16751 (define_expand "asinxf2"
16752 [(set (match_dup 2)
16753 (mult:XF (match_operand:XF 1 "register_operand" "")
16755 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16756 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16757 (parallel [(set (match_operand:XF 0 "register_operand" "")
16758 (unspec:XF [(match_dup 5) (match_dup 1)]
16760 (clobber (match_scratch:XF 6 ""))])]
16761 "TARGET_USE_FANCY_MATH_387
16762 && flag_unsafe_math_optimizations && !optimize_size"
16766 for (i = 2; i < 6; i++)
16767 operands[i] = gen_reg_rtx (XFmode);
16769 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16772 (define_expand "asin<mode>2"
16773 [(use (match_operand:MODEF 0 "register_operand" ""))
16774 (use (match_operand:MODEF 1 "general_operand" ""))]
16775 "TARGET_USE_FANCY_MATH_387
16776 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16777 || TARGET_MIX_SSE_I387)
16778 && flag_unsafe_math_optimizations && !optimize_size"
16780 rtx op0 = gen_reg_rtx (XFmode);
16781 rtx op1 = gen_reg_rtx (XFmode);
16783 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16784 emit_insn (gen_asinxf2 (op0, op1));
16785 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16789 (define_expand "acosxf2"
16790 [(set (match_dup 2)
16791 (mult:XF (match_operand:XF 1 "register_operand" "")
16793 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16794 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16795 (parallel [(set (match_operand:XF 0 "register_operand" "")
16796 (unspec:XF [(match_dup 1) (match_dup 5)]
16798 (clobber (match_scratch:XF 6 ""))])]
16799 "TARGET_USE_FANCY_MATH_387
16800 && flag_unsafe_math_optimizations && !optimize_size"
16804 for (i = 2; i < 6; i++)
16805 operands[i] = gen_reg_rtx (XFmode);
16807 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16810 (define_expand "acos<mode>2"
16811 [(use (match_operand:MODEF 0 "register_operand" ""))
16812 (use (match_operand:MODEF 1 "general_operand" ""))]
16813 "TARGET_USE_FANCY_MATH_387
16814 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16815 || TARGET_MIX_SSE_I387)
16816 && flag_unsafe_math_optimizations && !optimize_size"
16818 rtx op0 = gen_reg_rtx (XFmode);
16819 rtx op1 = gen_reg_rtx (XFmode);
16821 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16822 emit_insn (gen_acosxf2 (op0, op1));
16823 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16827 (define_insn "fyl2xxf3_i387"
16828 [(set (match_operand:XF 0 "register_operand" "=f")
16829 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16830 (match_operand:XF 2 "register_operand" "u")]
16832 (clobber (match_scratch:XF 3 "=2"))]
16833 "TARGET_USE_FANCY_MATH_387
16834 && flag_unsafe_math_optimizations"
16836 [(set_attr "type" "fpspc")
16837 (set_attr "mode" "XF")])
16839 (define_insn "fyl2x_extend<mode>xf3_i387"
16840 [(set (match_operand:XF 0 "register_operand" "=f")
16841 (unspec:XF [(float_extend:XF
16842 (match_operand:MODEF 1 "register_operand" "0"))
16843 (match_operand:XF 2 "register_operand" "u")]
16845 (clobber (match_scratch:XF 3 "=2"))]
16846 "TARGET_USE_FANCY_MATH_387
16847 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16848 || TARGET_MIX_SSE_I387)
16849 && flag_unsafe_math_optimizations"
16851 [(set_attr "type" "fpspc")
16852 (set_attr "mode" "XF")])
16854 (define_expand "logxf2"
16855 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16856 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16857 (match_dup 2)] UNSPEC_FYL2X))
16858 (clobber (match_scratch:XF 3 ""))])]
16859 "TARGET_USE_FANCY_MATH_387
16860 && flag_unsafe_math_optimizations"
16862 operands[2] = gen_reg_rtx (XFmode);
16863 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16866 (define_expand "log<mode>2"
16867 [(use (match_operand:MODEF 0 "register_operand" ""))
16868 (use (match_operand:MODEF 1 "register_operand" ""))]
16869 "TARGET_USE_FANCY_MATH_387
16870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16871 || TARGET_MIX_SSE_I387)
16872 && flag_unsafe_math_optimizations"
16874 rtx op0 = gen_reg_rtx (XFmode);
16876 rtx op2 = gen_reg_rtx (XFmode);
16877 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16879 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16880 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16884 (define_expand "log10xf2"
16885 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16886 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16887 (match_dup 2)] UNSPEC_FYL2X))
16888 (clobber (match_scratch:XF 3 ""))])]
16889 "TARGET_USE_FANCY_MATH_387
16890 && flag_unsafe_math_optimizations"
16892 operands[2] = gen_reg_rtx (XFmode);
16893 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16896 (define_expand "log10<mode>2"
16897 [(use (match_operand:MODEF 0 "register_operand" ""))
16898 (use (match_operand:MODEF 1 "register_operand" ""))]
16899 "TARGET_USE_FANCY_MATH_387
16900 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16901 || TARGET_MIX_SSE_I387)
16902 && flag_unsafe_math_optimizations"
16904 rtx op0 = gen_reg_rtx (XFmode);
16906 rtx op2 = gen_reg_rtx (XFmode);
16907 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16909 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16910 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16914 (define_expand "log2xf2"
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], CONST1_RTX (XFmode)); /* fld1 */
16926 (define_expand "log2<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, CONST1_RTX (XFmode)); /* fld1 */
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_insn "fyl2xp1xf3_i387"
16945 [(set (match_operand:XF 0 "register_operand" "=f")
16946 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16947 (match_operand:XF 2 "register_operand" "u")]
16949 (clobber (match_scratch:XF 3 "=2"))]
16950 "TARGET_USE_FANCY_MATH_387
16951 && flag_unsafe_math_optimizations"
16953 [(set_attr "type" "fpspc")
16954 (set_attr "mode" "XF")])
16956 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16957 [(set (match_operand:XF 0 "register_operand" "=f")
16958 (unspec:XF [(float_extend:XF
16959 (match_operand:MODEF 1 "register_operand" "0"))
16960 (match_operand:XF 2 "register_operand" "u")]
16962 (clobber (match_scratch:XF 3 "=2"))]
16963 "TARGET_USE_FANCY_MATH_387
16964 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16965 || TARGET_MIX_SSE_I387)
16966 && flag_unsafe_math_optimizations"
16968 [(set_attr "type" "fpspc")
16969 (set_attr "mode" "XF")])
16971 (define_expand "log1pxf2"
16972 [(use (match_operand:XF 0 "register_operand" ""))
16973 (use (match_operand:XF 1 "register_operand" ""))]
16974 "TARGET_USE_FANCY_MATH_387
16975 && flag_unsafe_math_optimizations && !optimize_size"
16977 ix86_emit_i387_log1p (operands[0], operands[1]);
16981 (define_expand "log1p<mode>2"
16982 [(use (match_operand:MODEF 0 "register_operand" ""))
16983 (use (match_operand:MODEF 1 "register_operand" ""))]
16984 "TARGET_USE_FANCY_MATH_387
16985 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16986 || TARGET_MIX_SSE_I387)
16987 && flag_unsafe_math_optimizations && !optimize_size"
16989 rtx op0 = gen_reg_rtx (XFmode);
16991 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16993 ix86_emit_i387_log1p (op0, operands[1]);
16994 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16998 (define_insn "fxtractxf3_i387"
16999 [(set (match_operand:XF 0 "register_operand" "=f")
17000 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17001 UNSPEC_XTRACT_FRACT))
17002 (set (match_operand:XF 1 "register_operand" "=u")
17003 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17004 "TARGET_USE_FANCY_MATH_387
17005 && flag_unsafe_math_optimizations"
17007 [(set_attr "type" "fpspc")
17008 (set_attr "mode" "XF")])
17010 (define_insn "fxtract_extend<mode>xf3_i387"
17011 [(set (match_operand:XF 0 "register_operand" "=f")
17012 (unspec:XF [(float_extend:XF
17013 (match_operand:MODEF 2 "register_operand" "0"))]
17014 UNSPEC_XTRACT_FRACT))
17015 (set (match_operand:XF 1 "register_operand" "=u")
17016 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17017 "TARGET_USE_FANCY_MATH_387
17018 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17019 || TARGET_MIX_SSE_I387)
17020 && flag_unsafe_math_optimizations"
17022 [(set_attr "type" "fpspc")
17023 (set_attr "mode" "XF")])
17025 (define_expand "logbxf2"
17026 [(parallel [(set (match_dup 2)
17027 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17028 UNSPEC_XTRACT_FRACT))
17029 (set (match_operand:XF 0 "register_operand" "")
17030 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17031 "TARGET_USE_FANCY_MATH_387
17032 && flag_unsafe_math_optimizations"
17034 operands[2] = gen_reg_rtx (XFmode);
17037 (define_expand "logb<mode>2"
17038 [(use (match_operand:MODEF 0 "register_operand" ""))
17039 (use (match_operand:MODEF 1 "register_operand" ""))]
17040 "TARGET_USE_FANCY_MATH_387
17041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17042 || TARGET_MIX_SSE_I387)
17043 && flag_unsafe_math_optimizations"
17045 rtx op0 = gen_reg_rtx (XFmode);
17046 rtx op1 = gen_reg_rtx (XFmode);
17048 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17049 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17053 (define_expand "ilogbxf2"
17054 [(use (match_operand:SI 0 "register_operand" ""))
17055 (use (match_operand:XF 1 "register_operand" ""))]
17056 "TARGET_USE_FANCY_MATH_387
17057 && flag_unsafe_math_optimizations && !optimize_size"
17059 rtx op0 = gen_reg_rtx (XFmode);
17060 rtx op1 = gen_reg_rtx (XFmode);
17062 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17063 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17067 (define_expand "ilogb<mode>2"
17068 [(use (match_operand:SI 0 "register_operand" ""))
17069 (use (match_operand:MODEF 1 "register_operand" ""))]
17070 "TARGET_USE_FANCY_MATH_387
17071 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17072 || TARGET_MIX_SSE_I387)
17073 && flag_unsafe_math_optimizations && !optimize_size"
17075 rtx op0 = gen_reg_rtx (XFmode);
17076 rtx op1 = gen_reg_rtx (XFmode);
17078 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17079 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17083 (define_insn "*f2xm1xf2_i387"
17084 [(set (match_operand:XF 0 "register_operand" "=f")
17085 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17087 "TARGET_USE_FANCY_MATH_387
17088 && flag_unsafe_math_optimizations"
17090 [(set_attr "type" "fpspc")
17091 (set_attr "mode" "XF")])
17093 (define_insn "*fscalexf4_i387"
17094 [(set (match_operand:XF 0 "register_operand" "=f")
17095 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17096 (match_operand:XF 3 "register_operand" "1")]
17097 UNSPEC_FSCALE_FRACT))
17098 (set (match_operand:XF 1 "register_operand" "=u")
17099 (unspec:XF [(match_dup 2) (match_dup 3)]
17100 UNSPEC_FSCALE_EXP))]
17101 "TARGET_USE_FANCY_MATH_387
17102 && flag_unsafe_math_optimizations"
17104 [(set_attr "type" "fpspc")
17105 (set_attr "mode" "XF")])
17107 (define_expand "expNcorexf3"
17108 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17109 (match_operand:XF 2 "register_operand" "")))
17110 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17111 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17112 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17113 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17114 (parallel [(set (match_operand:XF 0 "register_operand" "")
17115 (unspec:XF [(match_dup 8) (match_dup 4)]
17116 UNSPEC_FSCALE_FRACT))
17118 (unspec:XF [(match_dup 8) (match_dup 4)]
17119 UNSPEC_FSCALE_EXP))])]
17120 "TARGET_USE_FANCY_MATH_387
17121 && flag_unsafe_math_optimizations && !optimize_size"
17125 for (i = 3; i < 10; i++)
17126 operands[i] = gen_reg_rtx (XFmode);
17128 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17131 (define_expand "expxf2"
17132 [(use (match_operand:XF 0 "register_operand" ""))
17133 (use (match_operand:XF 1 "register_operand" ""))]
17134 "TARGET_USE_FANCY_MATH_387
17135 && flag_unsafe_math_optimizations && !optimize_size"
17137 rtx op2 = gen_reg_rtx (XFmode);
17138 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17140 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17144 (define_expand "exp<mode>2"
17145 [(use (match_operand:MODEF 0 "register_operand" ""))
17146 (use (match_operand:MODEF 1 "general_operand" ""))]
17147 "TARGET_USE_FANCY_MATH_387
17148 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17149 || TARGET_MIX_SSE_I387)
17150 && flag_unsafe_math_optimizations && !optimize_size"
17152 rtx op0 = gen_reg_rtx (XFmode);
17153 rtx op1 = gen_reg_rtx (XFmode);
17155 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17156 emit_insn (gen_expxf2 (op0, op1));
17157 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17161 (define_expand "exp10xf2"
17162 [(use (match_operand:XF 0 "register_operand" ""))
17163 (use (match_operand:XF 1 "register_operand" ""))]
17164 "TARGET_USE_FANCY_MATH_387
17165 && flag_unsafe_math_optimizations && !optimize_size"
17167 rtx op2 = gen_reg_rtx (XFmode);
17168 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17170 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17174 (define_expand "exp10<mode>2"
17175 [(use (match_operand:MODEF 0 "register_operand" ""))
17176 (use (match_operand:MODEF 1 "general_operand" ""))]
17177 "TARGET_USE_FANCY_MATH_387
17178 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17179 || TARGET_MIX_SSE_I387)
17180 && flag_unsafe_math_optimizations && !optimize_size"
17182 rtx op0 = gen_reg_rtx (XFmode);
17183 rtx op1 = gen_reg_rtx (XFmode);
17185 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17186 emit_insn (gen_exp10xf2 (op0, op1));
17187 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17191 (define_expand "exp2xf2"
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, CONST1_RTX (XFmode)); /* fld1 */
17200 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17204 (define_expand "exp2<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_exp2xf2 (op0, op1));
17217 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17221 (define_expand "expm1xf2"
17222 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17224 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17225 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17226 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17227 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17228 (parallel [(set (match_dup 7)
17229 (unspec:XF [(match_dup 6) (match_dup 4)]
17230 UNSPEC_FSCALE_FRACT))
17232 (unspec:XF [(match_dup 6) (match_dup 4)]
17233 UNSPEC_FSCALE_EXP))])
17234 (parallel [(set (match_dup 10)
17235 (unspec:XF [(match_dup 9) (match_dup 8)]
17236 UNSPEC_FSCALE_FRACT))
17237 (set (match_dup 11)
17238 (unspec:XF [(match_dup 9) (match_dup 8)]
17239 UNSPEC_FSCALE_EXP))])
17240 (set (match_dup 12) (minus:XF (match_dup 10)
17241 (float_extend:XF (match_dup 13))))
17242 (set (match_operand:XF 0 "register_operand" "")
17243 (plus:XF (match_dup 12) (match_dup 7)))]
17244 "TARGET_USE_FANCY_MATH_387
17245 && flag_unsafe_math_optimizations && !optimize_size"
17249 for (i = 2; i < 13; i++)
17250 operands[i] = gen_reg_rtx (XFmode);
17253 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17255 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17258 (define_expand "expm1<mode>2"
17259 [(use (match_operand:MODEF 0 "register_operand" ""))
17260 (use (match_operand:MODEF 1 "general_operand" ""))]
17261 "TARGET_USE_FANCY_MATH_387
17262 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17263 || TARGET_MIX_SSE_I387)
17264 && flag_unsafe_math_optimizations && !optimize_size"
17266 rtx op0 = gen_reg_rtx (XFmode);
17267 rtx op1 = gen_reg_rtx (XFmode);
17269 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17270 emit_insn (gen_expm1xf2 (op0, op1));
17271 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17275 (define_expand "ldexpxf3"
17276 [(set (match_dup 3)
17277 (float:XF (match_operand:SI 2 "register_operand" "")))
17278 (parallel [(set (match_operand:XF 0 " register_operand" "")
17279 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17281 UNSPEC_FSCALE_FRACT))
17283 (unspec:XF [(match_dup 1) (match_dup 3)]
17284 UNSPEC_FSCALE_EXP))])]
17285 "TARGET_USE_FANCY_MATH_387
17286 && flag_unsafe_math_optimizations && !optimize_size"
17288 operands[3] = gen_reg_rtx (XFmode);
17289 operands[4] = gen_reg_rtx (XFmode);
17292 (define_expand "ldexp<mode>3"
17293 [(use (match_operand:MODEF 0 "register_operand" ""))
17294 (use (match_operand:MODEF 1 "general_operand" ""))
17295 (use (match_operand:SI 2 "register_operand" ""))]
17296 "TARGET_USE_FANCY_MATH_387
17297 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17298 || TARGET_MIX_SSE_I387)
17299 && flag_unsafe_math_optimizations && !optimize_size"
17301 rtx op0 = gen_reg_rtx (XFmode);
17302 rtx op1 = gen_reg_rtx (XFmode);
17304 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17305 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17306 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17310 (define_expand "scalbxf3"
17311 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17312 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17313 (match_operand:XF 2 "register_operand" "")]
17314 UNSPEC_FSCALE_FRACT))
17316 (unspec:XF [(match_dup 1) (match_dup 2)]
17317 UNSPEC_FSCALE_EXP))])]
17318 "TARGET_USE_FANCY_MATH_387
17319 && flag_unsafe_math_optimizations && !optimize_size"
17321 operands[3] = gen_reg_rtx (XFmode);
17324 (define_expand "scalb<mode>3"
17325 [(use (match_operand:MODEF 0 "register_operand" ""))
17326 (use (match_operand:MODEF 1 "general_operand" ""))
17327 (use (match_operand:MODEF 2 "register_operand" ""))]
17328 "TARGET_USE_FANCY_MATH_387
17329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17330 || TARGET_MIX_SSE_I387)
17331 && flag_unsafe_math_optimizations && !optimize_size"
17333 rtx op0 = gen_reg_rtx (XFmode);
17334 rtx op1 = gen_reg_rtx (XFmode);
17335 rtx op2 = gen_reg_rtx (XFmode);
17337 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17338 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17339 emit_insn (gen_scalbxf3 (op0, op1, op2));
17340 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17345 (define_insn "sse4_1_round<mode>2"
17346 [(set (match_operand:MODEF 0 "register_operand" "=x")
17347 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17348 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17351 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17352 [(set_attr "type" "ssecvt")
17353 (set_attr "prefix_extra" "1")
17354 (set_attr "mode" "<MODE>")])
17356 (define_insn "rintxf2"
17357 [(set (match_operand:XF 0 "register_operand" "=f")
17358 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17360 "TARGET_USE_FANCY_MATH_387
17361 && flag_unsafe_math_optimizations"
17363 [(set_attr "type" "fpspc")
17364 (set_attr "mode" "XF")])
17366 (define_expand "rint<mode>2"
17367 [(use (match_operand:MODEF 0 "register_operand" ""))
17368 (use (match_operand:MODEF 1 "register_operand" ""))]
17369 "(TARGET_USE_FANCY_MATH_387
17370 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17371 || TARGET_MIX_SSE_I387)
17372 && flag_unsafe_math_optimizations)
17373 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17374 && !flag_trapping_math
17375 && (TARGET_ROUND || !optimize_size))"
17377 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17378 && !flag_trapping_math
17379 && (TARGET_ROUND || !optimize_size))
17382 emit_insn (gen_sse4_1_round<mode>2
17383 (operands[0], operands[1], GEN_INT (0x04)));
17385 ix86_expand_rint (operand0, operand1);
17389 rtx op0 = gen_reg_rtx (XFmode);
17390 rtx op1 = gen_reg_rtx (XFmode);
17392 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17393 emit_insn (gen_rintxf2 (op0, op1));
17395 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17400 (define_expand "round<mode>2"
17401 [(match_operand:MODEF 0 "register_operand" "")
17402 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17403 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17404 && !flag_trapping_math && !flag_rounding_math
17407 if (TARGET_64BIT || (<MODE>mode != DFmode))
17408 ix86_expand_round (operand0, operand1);
17410 ix86_expand_rounddf_32 (operand0, operand1);
17414 (define_insn_and_split "*fistdi2_1"
17415 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17416 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17418 "TARGET_USE_FANCY_MATH_387
17419 && !(reload_completed || reload_in_progress)"
17424 if (memory_operand (operands[0], VOIDmode))
17425 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17428 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17429 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17434 [(set_attr "type" "fpspc")
17435 (set_attr "mode" "DI")])
17437 (define_insn "fistdi2"
17438 [(set (match_operand:DI 0 "memory_operand" "=m")
17439 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17441 (clobber (match_scratch:XF 2 "=&1f"))]
17442 "TARGET_USE_FANCY_MATH_387"
17443 "* return output_fix_trunc (insn, operands, 0);"
17444 [(set_attr "type" "fpspc")
17445 (set_attr "mode" "DI")])
17447 (define_insn "fistdi2_with_temp"
17448 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17449 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17451 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17452 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17453 "TARGET_USE_FANCY_MATH_387"
17455 [(set_attr "type" "fpspc")
17456 (set_attr "mode" "DI")])
17459 [(set (match_operand:DI 0 "register_operand" "")
17460 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17462 (clobber (match_operand:DI 2 "memory_operand" ""))
17463 (clobber (match_scratch 3 ""))]
17465 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17466 (clobber (match_dup 3))])
17467 (set (match_dup 0) (match_dup 2))]
17471 [(set (match_operand:DI 0 "memory_operand" "")
17472 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17474 (clobber (match_operand:DI 2 "memory_operand" ""))
17475 (clobber (match_scratch 3 ""))]
17477 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17478 (clobber (match_dup 3))])]
17481 (define_insn_and_split "*fist<mode>2_1"
17482 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17483 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17485 "TARGET_USE_FANCY_MATH_387
17486 && !(reload_completed || reload_in_progress)"
17491 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17492 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17496 [(set_attr "type" "fpspc")
17497 (set_attr "mode" "<MODE>")])
17499 (define_insn "fist<mode>2"
17500 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17501 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17503 "TARGET_USE_FANCY_MATH_387"
17504 "* return output_fix_trunc (insn, operands, 0);"
17505 [(set_attr "type" "fpspc")
17506 (set_attr "mode" "<MODE>")])
17508 (define_insn "fist<mode>2_with_temp"
17509 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17510 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17512 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17513 "TARGET_USE_FANCY_MATH_387"
17515 [(set_attr "type" "fpspc")
17516 (set_attr "mode" "<MODE>")])
17519 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17520 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17522 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17524 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17525 (set (match_dup 0) (match_dup 2))]
17529 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17530 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17532 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17534 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17537 (define_expand "lrintxf<mode>2"
17538 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17539 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17541 "TARGET_USE_FANCY_MATH_387"
17544 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17545 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17546 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17547 UNSPEC_FIX_NOTRUNC))]
17548 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17549 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17552 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17553 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17554 (match_operand:MODEF 1 "register_operand" "")]
17555 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17556 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17557 && !flag_trapping_math && !flag_rounding_math
17560 ix86_expand_lround (operand0, operand1);
17564 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17565 (define_insn_and_split "frndintxf2_floor"
17566 [(set (match_operand:XF 0 "register_operand" "")
17567 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17568 UNSPEC_FRNDINT_FLOOR))
17569 (clobber (reg:CC FLAGS_REG))]
17570 "TARGET_USE_FANCY_MATH_387
17571 && flag_unsafe_math_optimizations
17572 && !(reload_completed || reload_in_progress)"
17577 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17579 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17580 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17582 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17583 operands[2], operands[3]));
17586 [(set_attr "type" "frndint")
17587 (set_attr "i387_cw" "floor")
17588 (set_attr "mode" "XF")])
17590 (define_insn "frndintxf2_floor_i387"
17591 [(set (match_operand:XF 0 "register_operand" "=f")
17592 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17593 UNSPEC_FRNDINT_FLOOR))
17594 (use (match_operand:HI 2 "memory_operand" "m"))
17595 (use (match_operand:HI 3 "memory_operand" "m"))]
17596 "TARGET_USE_FANCY_MATH_387
17597 && flag_unsafe_math_optimizations"
17598 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17599 [(set_attr "type" "frndint")
17600 (set_attr "i387_cw" "floor")
17601 (set_attr "mode" "XF")])
17603 (define_expand "floorxf2"
17604 [(use (match_operand:XF 0 "register_operand" ""))
17605 (use (match_operand:XF 1 "register_operand" ""))]
17606 "TARGET_USE_FANCY_MATH_387
17607 && flag_unsafe_math_optimizations && !optimize_size"
17609 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17613 (define_expand "floor<mode>2"
17614 [(use (match_operand:MODEF 0 "register_operand" ""))
17615 (use (match_operand:MODEF 1 "register_operand" ""))]
17616 "(TARGET_USE_FANCY_MATH_387
17617 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17618 || TARGET_MIX_SSE_I387)
17619 && flag_unsafe_math_optimizations && !optimize_size)
17620 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17621 && !flag_trapping_math
17622 && (TARGET_ROUND || !optimize_size))"
17624 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17625 && !flag_trapping_math
17626 && (TARGET_ROUND || !optimize_size))
17629 emit_insn (gen_sse4_1_round<mode>2
17630 (operands[0], operands[1], GEN_INT (0x01)));
17631 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17632 ix86_expand_floorceil (operand0, operand1, true);
17634 ix86_expand_floorceildf_32 (operand0, operand1, true);
17638 rtx op0 = gen_reg_rtx (XFmode);
17639 rtx op1 = gen_reg_rtx (XFmode);
17641 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17642 emit_insn (gen_frndintxf2_floor (op0, op1));
17644 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17649 (define_insn_and_split "*fist<mode>2_floor_1"
17650 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17651 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17652 UNSPEC_FIST_FLOOR))
17653 (clobber (reg:CC FLAGS_REG))]
17654 "TARGET_USE_FANCY_MATH_387
17655 && flag_unsafe_math_optimizations
17656 && !(reload_completed || reload_in_progress)"
17661 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17663 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17664 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17665 if (memory_operand (operands[0], VOIDmode))
17666 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17667 operands[2], operands[3]));
17670 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17671 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17672 operands[2], operands[3],
17677 [(set_attr "type" "fistp")
17678 (set_attr "i387_cw" "floor")
17679 (set_attr "mode" "<MODE>")])
17681 (define_insn "fistdi2_floor"
17682 [(set (match_operand:DI 0 "memory_operand" "=m")
17683 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17684 UNSPEC_FIST_FLOOR))
17685 (use (match_operand:HI 2 "memory_operand" "m"))
17686 (use (match_operand:HI 3 "memory_operand" "m"))
17687 (clobber (match_scratch:XF 4 "=&1f"))]
17688 "TARGET_USE_FANCY_MATH_387
17689 && flag_unsafe_math_optimizations"
17690 "* return output_fix_trunc (insn, operands, 0);"
17691 [(set_attr "type" "fistp")
17692 (set_attr "i387_cw" "floor")
17693 (set_attr "mode" "DI")])
17695 (define_insn "fistdi2_floor_with_temp"
17696 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17697 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17698 UNSPEC_FIST_FLOOR))
17699 (use (match_operand:HI 2 "memory_operand" "m,m"))
17700 (use (match_operand:HI 3 "memory_operand" "m,m"))
17701 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17702 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17703 "TARGET_USE_FANCY_MATH_387
17704 && flag_unsafe_math_optimizations"
17706 [(set_attr "type" "fistp")
17707 (set_attr "i387_cw" "floor")
17708 (set_attr "mode" "DI")])
17711 [(set (match_operand:DI 0 "register_operand" "")
17712 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17713 UNSPEC_FIST_FLOOR))
17714 (use (match_operand:HI 2 "memory_operand" ""))
17715 (use (match_operand:HI 3 "memory_operand" ""))
17716 (clobber (match_operand:DI 4 "memory_operand" ""))
17717 (clobber (match_scratch 5 ""))]
17719 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17720 (use (match_dup 2))
17721 (use (match_dup 3))
17722 (clobber (match_dup 5))])
17723 (set (match_dup 0) (match_dup 4))]
17727 [(set (match_operand:DI 0 "memory_operand" "")
17728 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17729 UNSPEC_FIST_FLOOR))
17730 (use (match_operand:HI 2 "memory_operand" ""))
17731 (use (match_operand:HI 3 "memory_operand" ""))
17732 (clobber (match_operand:DI 4 "memory_operand" ""))
17733 (clobber (match_scratch 5 ""))]
17735 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17736 (use (match_dup 2))
17737 (use (match_dup 3))
17738 (clobber (match_dup 5))])]
17741 (define_insn "fist<mode>2_floor"
17742 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17743 (unspec:X87MODEI12 [(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 "TARGET_USE_FANCY_MATH_387
17748 && flag_unsafe_math_optimizations"
17749 "* return output_fix_trunc (insn, operands, 0);"
17750 [(set_attr "type" "fistp")
17751 (set_attr "i387_cw" "floor")
17752 (set_attr "mode" "<MODE>")])
17754 (define_insn "fist<mode>2_floor_with_temp"
17755 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17756 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17757 UNSPEC_FIST_FLOOR))
17758 (use (match_operand:HI 2 "memory_operand" "m,m"))
17759 (use (match_operand:HI 3 "memory_operand" "m,m"))
17760 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17761 "TARGET_USE_FANCY_MATH_387
17762 && flag_unsafe_math_optimizations"
17764 [(set_attr "type" "fistp")
17765 (set_attr "i387_cw" "floor")
17766 (set_attr "mode" "<MODE>")])
17769 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17770 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17771 UNSPEC_FIST_FLOOR))
17772 (use (match_operand:HI 2 "memory_operand" ""))
17773 (use (match_operand:HI 3 "memory_operand" ""))
17774 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17776 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17777 UNSPEC_FIST_FLOOR))
17778 (use (match_dup 2))
17779 (use (match_dup 3))])
17780 (set (match_dup 0) (match_dup 4))]
17784 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17785 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17786 UNSPEC_FIST_FLOOR))
17787 (use (match_operand:HI 2 "memory_operand" ""))
17788 (use (match_operand:HI 3 "memory_operand" ""))
17789 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17791 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17792 UNSPEC_FIST_FLOOR))
17793 (use (match_dup 2))
17794 (use (match_dup 3))])]
17797 (define_expand "lfloorxf<mode>2"
17798 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17799 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17800 UNSPEC_FIST_FLOOR))
17801 (clobber (reg:CC FLAGS_REG))])]
17802 "TARGET_USE_FANCY_MATH_387
17803 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17804 && flag_unsafe_math_optimizations"
17807 (define_expand "lfloor<mode>di2"
17808 [(match_operand:DI 0 "nonimmediate_operand" "")
17809 (match_operand:MODEF 1 "register_operand" "")]
17810 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17811 && !flag_trapping_math
17814 ix86_expand_lfloorceil (operand0, operand1, true);
17818 (define_expand "lfloor<mode>si2"
17819 [(match_operand:SI 0 "nonimmediate_operand" "")
17820 (match_operand:MODEF 1 "register_operand" "")]
17821 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17822 && !flag_trapping_math
17823 && (!optimize_size || !TARGET_64BIT)"
17825 ix86_expand_lfloorceil (operand0, operand1, true);
17829 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17830 (define_insn_and_split "frndintxf2_ceil"
17831 [(set (match_operand:XF 0 "register_operand" "")
17832 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17833 UNSPEC_FRNDINT_CEIL))
17834 (clobber (reg:CC FLAGS_REG))]
17835 "TARGET_USE_FANCY_MATH_387
17836 && flag_unsafe_math_optimizations
17837 && !(reload_completed || reload_in_progress)"
17842 ix86_optimize_mode_switching[I387_CEIL] = 1;
17844 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17845 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17847 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17848 operands[2], operands[3]));
17851 [(set_attr "type" "frndint")
17852 (set_attr "i387_cw" "ceil")
17853 (set_attr "mode" "XF")])
17855 (define_insn "frndintxf2_ceil_i387"
17856 [(set (match_operand:XF 0 "register_operand" "=f")
17857 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17858 UNSPEC_FRNDINT_CEIL))
17859 (use (match_operand:HI 2 "memory_operand" "m"))
17860 (use (match_operand:HI 3 "memory_operand" "m"))]
17861 "TARGET_USE_FANCY_MATH_387
17862 && flag_unsafe_math_optimizations"
17863 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17864 [(set_attr "type" "frndint")
17865 (set_attr "i387_cw" "ceil")
17866 (set_attr "mode" "XF")])
17868 (define_expand "ceilxf2"
17869 [(use (match_operand:XF 0 "register_operand" ""))
17870 (use (match_operand:XF 1 "register_operand" ""))]
17871 "TARGET_USE_FANCY_MATH_387
17872 && flag_unsafe_math_optimizations && !optimize_size"
17874 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17878 (define_expand "ceil<mode>2"
17879 [(use (match_operand:MODEF 0 "register_operand" ""))
17880 (use (match_operand:MODEF 1 "register_operand" ""))]
17881 "(TARGET_USE_FANCY_MATH_387
17882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17883 || TARGET_MIX_SSE_I387)
17884 && flag_unsafe_math_optimizations && !optimize_size)
17885 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17886 && !flag_trapping_math
17887 && (TARGET_ROUND || !optimize_size))"
17889 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17890 && !flag_trapping_math
17891 && (TARGET_ROUND || !optimize_size))
17894 emit_insn (gen_sse4_1_round<mode>2
17895 (operands[0], operands[1], GEN_INT (0x02)));
17896 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17897 ix86_expand_floorceil (operand0, operand1, false);
17899 ix86_expand_floorceildf_32 (operand0, operand1, false);
17903 rtx op0 = gen_reg_rtx (XFmode);
17904 rtx op1 = gen_reg_rtx (XFmode);
17906 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17907 emit_insn (gen_frndintxf2_ceil (op0, op1));
17909 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17914 (define_insn_and_split "*fist<mode>2_ceil_1"
17915 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17916 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17918 (clobber (reg:CC FLAGS_REG))]
17919 "TARGET_USE_FANCY_MATH_387
17920 && flag_unsafe_math_optimizations
17921 && !(reload_completed || reload_in_progress)"
17926 ix86_optimize_mode_switching[I387_CEIL] = 1;
17928 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17929 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17930 if (memory_operand (operands[0], VOIDmode))
17931 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17932 operands[2], operands[3]));
17935 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17936 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17937 operands[2], operands[3],
17942 [(set_attr "type" "fistp")
17943 (set_attr "i387_cw" "ceil")
17944 (set_attr "mode" "<MODE>")])
17946 (define_insn "fistdi2_ceil"
17947 [(set (match_operand:DI 0 "memory_operand" "=m")
17948 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17950 (use (match_operand:HI 2 "memory_operand" "m"))
17951 (use (match_operand:HI 3 "memory_operand" "m"))
17952 (clobber (match_scratch:XF 4 "=&1f"))]
17953 "TARGET_USE_FANCY_MATH_387
17954 && flag_unsafe_math_optimizations"
17955 "* return output_fix_trunc (insn, operands, 0);"
17956 [(set_attr "type" "fistp")
17957 (set_attr "i387_cw" "ceil")
17958 (set_attr "mode" "DI")])
17960 (define_insn "fistdi2_ceil_with_temp"
17961 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17962 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17964 (use (match_operand:HI 2 "memory_operand" "m,m"))
17965 (use (match_operand:HI 3 "memory_operand" "m,m"))
17966 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17967 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17968 "TARGET_USE_FANCY_MATH_387
17969 && flag_unsafe_math_optimizations"
17971 [(set_attr "type" "fistp")
17972 (set_attr "i387_cw" "ceil")
17973 (set_attr "mode" "DI")])
17976 [(set (match_operand:DI 0 "register_operand" "")
17977 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17979 (use (match_operand:HI 2 "memory_operand" ""))
17980 (use (match_operand:HI 3 "memory_operand" ""))
17981 (clobber (match_operand:DI 4 "memory_operand" ""))
17982 (clobber (match_scratch 5 ""))]
17984 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17985 (use (match_dup 2))
17986 (use (match_dup 3))
17987 (clobber (match_dup 5))])
17988 (set (match_dup 0) (match_dup 4))]
17992 [(set (match_operand:DI 0 "memory_operand" "")
17993 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17995 (use (match_operand:HI 2 "memory_operand" ""))
17996 (use (match_operand:HI 3 "memory_operand" ""))
17997 (clobber (match_operand:DI 4 "memory_operand" ""))
17998 (clobber (match_scratch 5 ""))]
18000 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18001 (use (match_dup 2))
18002 (use (match_dup 3))
18003 (clobber (match_dup 5))])]
18006 (define_insn "fist<mode>2_ceil"
18007 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18008 (unspec:X87MODEI12 [(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 "TARGET_USE_FANCY_MATH_387
18013 && flag_unsafe_math_optimizations"
18014 "* return output_fix_trunc (insn, operands, 0);"
18015 [(set_attr "type" "fistp")
18016 (set_attr "i387_cw" "ceil")
18017 (set_attr "mode" "<MODE>")])
18019 (define_insn "fist<mode>2_ceil_with_temp"
18020 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18021 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18023 (use (match_operand:HI 2 "memory_operand" "m,m"))
18024 (use (match_operand:HI 3 "memory_operand" "m,m"))
18025 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18026 "TARGET_USE_FANCY_MATH_387
18027 && flag_unsafe_math_optimizations"
18029 [(set_attr "type" "fistp")
18030 (set_attr "i387_cw" "ceil")
18031 (set_attr "mode" "<MODE>")])
18034 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18035 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18037 (use (match_operand:HI 2 "memory_operand" ""))
18038 (use (match_operand:HI 3 "memory_operand" ""))
18039 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18041 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18043 (use (match_dup 2))
18044 (use (match_dup 3))])
18045 (set (match_dup 0) (match_dup 4))]
18049 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18050 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18052 (use (match_operand:HI 2 "memory_operand" ""))
18053 (use (match_operand:HI 3 "memory_operand" ""))
18054 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18056 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18058 (use (match_dup 2))
18059 (use (match_dup 3))])]
18062 (define_expand "lceilxf<mode>2"
18063 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18064 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18066 (clobber (reg:CC FLAGS_REG))])]
18067 "TARGET_USE_FANCY_MATH_387
18068 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18069 && flag_unsafe_math_optimizations"
18072 (define_expand "lceil<mode>di2"
18073 [(match_operand:DI 0 "nonimmediate_operand" "")
18074 (match_operand:MODEF 1 "register_operand" "")]
18075 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18076 && !flag_trapping_math"
18078 ix86_expand_lfloorceil (operand0, operand1, false);
18082 (define_expand "lceil<mode>si2"
18083 [(match_operand:SI 0 "nonimmediate_operand" "")
18084 (match_operand:MODEF 1 "register_operand" "")]
18085 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18086 && !flag_trapping_math"
18088 ix86_expand_lfloorceil (operand0, operand1, false);
18092 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18093 (define_insn_and_split "frndintxf2_trunc"
18094 [(set (match_operand:XF 0 "register_operand" "")
18095 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18096 UNSPEC_FRNDINT_TRUNC))
18097 (clobber (reg:CC FLAGS_REG))]
18098 "TARGET_USE_FANCY_MATH_387
18099 && flag_unsafe_math_optimizations
18100 && !(reload_completed || reload_in_progress)"
18105 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18107 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18108 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18110 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18111 operands[2], operands[3]));
18114 [(set_attr "type" "frndint")
18115 (set_attr "i387_cw" "trunc")
18116 (set_attr "mode" "XF")])
18118 (define_insn "frndintxf2_trunc_i387"
18119 [(set (match_operand:XF 0 "register_operand" "=f")
18120 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18121 UNSPEC_FRNDINT_TRUNC))
18122 (use (match_operand:HI 2 "memory_operand" "m"))
18123 (use (match_operand:HI 3 "memory_operand" "m"))]
18124 "TARGET_USE_FANCY_MATH_387
18125 && flag_unsafe_math_optimizations"
18126 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18127 [(set_attr "type" "frndint")
18128 (set_attr "i387_cw" "trunc")
18129 (set_attr "mode" "XF")])
18131 (define_expand "btruncxf2"
18132 [(use (match_operand:XF 0 "register_operand" ""))
18133 (use (match_operand:XF 1 "register_operand" ""))]
18134 "TARGET_USE_FANCY_MATH_387
18135 && flag_unsafe_math_optimizations && !optimize_size"
18137 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18141 (define_expand "btrunc<mode>2"
18142 [(use (match_operand:MODEF 0 "register_operand" ""))
18143 (use (match_operand:MODEF 1 "register_operand" ""))]
18144 "(TARGET_USE_FANCY_MATH_387
18145 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18146 || TARGET_MIX_SSE_I387)
18147 && flag_unsafe_math_optimizations && !optimize_size)
18148 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18149 && !flag_trapping_math
18150 && (TARGET_ROUND || !optimize_size))"
18152 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18153 && !flag_trapping_math
18154 && (TARGET_ROUND || !optimize_size))
18157 emit_insn (gen_sse4_1_round<mode>2
18158 (operands[0], operands[1], GEN_INT (0x03)));
18159 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18160 ix86_expand_trunc (operand0, operand1);
18162 ix86_expand_truncdf_32 (operand0, operand1);
18166 rtx op0 = gen_reg_rtx (XFmode);
18167 rtx op1 = gen_reg_rtx (XFmode);
18169 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18170 emit_insn (gen_frndintxf2_trunc (op0, op1));
18172 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18177 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18178 (define_insn_and_split "frndintxf2_mask_pm"
18179 [(set (match_operand:XF 0 "register_operand" "")
18180 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18181 UNSPEC_FRNDINT_MASK_PM))
18182 (clobber (reg:CC FLAGS_REG))]
18183 "TARGET_USE_FANCY_MATH_387
18184 && flag_unsafe_math_optimizations
18185 && !(reload_completed || reload_in_progress)"
18190 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18192 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18193 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18195 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18196 operands[2], operands[3]));
18199 [(set_attr "type" "frndint")
18200 (set_attr "i387_cw" "mask_pm")
18201 (set_attr "mode" "XF")])
18203 (define_insn "frndintxf2_mask_pm_i387"
18204 [(set (match_operand:XF 0 "register_operand" "=f")
18205 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18206 UNSPEC_FRNDINT_MASK_PM))
18207 (use (match_operand:HI 2 "memory_operand" "m"))
18208 (use (match_operand:HI 3 "memory_operand" "m"))]
18209 "TARGET_USE_FANCY_MATH_387
18210 && flag_unsafe_math_optimizations"
18211 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18212 [(set_attr "type" "frndint")
18213 (set_attr "i387_cw" "mask_pm")
18214 (set_attr "mode" "XF")])
18216 (define_expand "nearbyintxf2"
18217 [(use (match_operand:XF 0 "register_operand" ""))
18218 (use (match_operand:XF 1 "register_operand" ""))]
18219 "TARGET_USE_FANCY_MATH_387
18220 && flag_unsafe_math_optimizations"
18222 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18227 (define_expand "nearbyint<mode>2"
18228 [(use (match_operand:MODEF 0 "register_operand" ""))
18229 (use (match_operand:MODEF 1 "register_operand" ""))]
18230 "TARGET_USE_FANCY_MATH_387
18231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18232 || TARGET_MIX_SSE_I387)
18233 && flag_unsafe_math_optimizations"
18235 rtx op0 = gen_reg_rtx (XFmode);
18236 rtx op1 = gen_reg_rtx (XFmode);
18238 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18239 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18241 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18245 (define_insn "fxam<mode>2_i387"
18246 [(set (match_operand:HI 0 "register_operand" "=a")
18248 [(match_operand:X87MODEF 1 "register_operand" "f")]
18250 "TARGET_USE_FANCY_MATH_387"
18251 "fxam\n\tfnstsw\t%0"
18252 [(set_attr "type" "multi")
18253 (set_attr "unit" "i387")
18254 (set_attr "mode" "<MODE>")])
18256 (define_expand "isinf<mode>2"
18257 [(use (match_operand:SI 0 "register_operand" ""))
18258 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18259 "TARGET_USE_FANCY_MATH_387
18260 && TARGET_C99_FUNCTIONS
18261 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18263 rtx mask = GEN_INT (0x45);
18264 rtx val = GEN_INT (0x05);
18268 rtx scratch = gen_reg_rtx (HImode);
18269 rtx res = gen_reg_rtx (QImode);
18271 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18272 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18273 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18274 cond = gen_rtx_fmt_ee (EQ, QImode,
18275 gen_rtx_REG (CCmode, FLAGS_REG),
18277 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18278 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18282 (define_expand "signbit<mode>2"
18283 [(use (match_operand:SI 0 "register_operand" ""))
18284 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18285 "TARGET_USE_FANCY_MATH_387
18286 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18288 rtx mask = GEN_INT (0x0200);
18290 rtx scratch = gen_reg_rtx (HImode);
18292 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18293 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18297 ;; Block operation instructions
18299 (define_expand "movmemsi"
18300 [(use (match_operand:BLK 0 "memory_operand" ""))
18301 (use (match_operand:BLK 1 "memory_operand" ""))
18302 (use (match_operand:SI 2 "nonmemory_operand" ""))
18303 (use (match_operand:SI 3 "const_int_operand" ""))
18304 (use (match_operand:SI 4 "const_int_operand" ""))
18305 (use (match_operand:SI 5 "const_int_operand" ""))]
18308 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18309 operands[4], operands[5]))
18315 (define_expand "movmemdi"
18316 [(use (match_operand:BLK 0 "memory_operand" ""))
18317 (use (match_operand:BLK 1 "memory_operand" ""))
18318 (use (match_operand:DI 2 "nonmemory_operand" ""))
18319 (use (match_operand:DI 3 "const_int_operand" ""))
18320 (use (match_operand:SI 4 "const_int_operand" ""))
18321 (use (match_operand:SI 5 "const_int_operand" ""))]
18324 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18325 operands[4], operands[5]))
18331 ;; Most CPUs don't like single string operations
18332 ;; Handle this case here to simplify previous expander.
18334 (define_expand "strmov"
18335 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18336 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18337 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18338 (clobber (reg:CC FLAGS_REG))])
18339 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18340 (clobber (reg:CC FLAGS_REG))])]
18343 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18345 /* If .md ever supports :P for Pmode, these can be directly
18346 in the pattern above. */
18347 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18348 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18350 /* Can't use this if the user has appropriated esi or edi. */
18351 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18352 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18354 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18355 operands[2], operands[3],
18356 operands[5], operands[6]));
18360 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18363 (define_expand "strmov_singleop"
18364 [(parallel [(set (match_operand 1 "memory_operand" "")
18365 (match_operand 3 "memory_operand" ""))
18366 (set (match_operand 0 "register_operand" "")
18367 (match_operand 4 "" ""))
18368 (set (match_operand 2 "register_operand" "")
18369 (match_operand 5 "" ""))])]
18370 "TARGET_SINGLE_STRINGOP || optimize_size"
18373 (define_insn "*strmovdi_rex_1"
18374 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18375 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18376 (set (match_operand:DI 0 "register_operand" "=D")
18377 (plus:DI (match_dup 2)
18379 (set (match_operand:DI 1 "register_operand" "=S")
18380 (plus:DI (match_dup 3)
18382 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18384 [(set_attr "type" "str")
18385 (set_attr "mode" "DI")
18386 (set_attr "memory" "both")])
18388 (define_insn "*strmovsi_1"
18389 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18390 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18391 (set (match_operand:SI 0 "register_operand" "=D")
18392 (plus:SI (match_dup 2)
18394 (set (match_operand:SI 1 "register_operand" "=S")
18395 (plus:SI (match_dup 3)
18397 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18399 [(set_attr "type" "str")
18400 (set_attr "mode" "SI")
18401 (set_attr "memory" "both")])
18403 (define_insn "*strmovsi_rex_1"
18404 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18405 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18406 (set (match_operand:DI 0 "register_operand" "=D")
18407 (plus:DI (match_dup 2)
18409 (set (match_operand:DI 1 "register_operand" "=S")
18410 (plus:DI (match_dup 3)
18412 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18414 [(set_attr "type" "str")
18415 (set_attr "mode" "SI")
18416 (set_attr "memory" "both")])
18418 (define_insn "*strmovhi_1"
18419 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18420 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18421 (set (match_operand:SI 0 "register_operand" "=D")
18422 (plus:SI (match_dup 2)
18424 (set (match_operand:SI 1 "register_operand" "=S")
18425 (plus:SI (match_dup 3)
18427 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18429 [(set_attr "type" "str")
18430 (set_attr "memory" "both")
18431 (set_attr "mode" "HI")])
18433 (define_insn "*strmovhi_rex_1"
18434 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18435 (mem:HI (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 "memory" "both")
18446 (set_attr "mode" "HI")])
18448 (define_insn "*strmovqi_1"
18449 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18450 (mem:QI (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 "memory" "both")
18461 (set_attr "mode" "QI")])
18463 (define_insn "*strmovqi_rex_1"
18464 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18465 (mem:QI (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 "memory" "both")
18476 (set_attr "mode" "QI")])
18478 (define_expand "rep_mov"
18479 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18480 (set (match_operand 0 "register_operand" "")
18481 (match_operand 5 "" ""))
18482 (set (match_operand 2 "register_operand" "")
18483 (match_operand 6 "" ""))
18484 (set (match_operand 1 "memory_operand" "")
18485 (match_operand 3 "memory_operand" ""))
18486 (use (match_dup 4))])]
18490 (define_insn "*rep_movdi_rex64"
18491 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18492 (set (match_operand:DI 0 "register_operand" "=D")
18493 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18495 (match_operand:DI 3 "register_operand" "0")))
18496 (set (match_operand:DI 1 "register_operand" "=S")
18497 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18498 (match_operand:DI 4 "register_operand" "1")))
18499 (set (mem:BLK (match_dup 3))
18500 (mem:BLK (match_dup 4)))
18501 (use (match_dup 5))]
18504 [(set_attr "type" "str")
18505 (set_attr "prefix_rep" "1")
18506 (set_attr "memory" "both")
18507 (set_attr "mode" "DI")])
18509 (define_insn "*rep_movsi"
18510 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18511 (set (match_operand:SI 0 "register_operand" "=D")
18512 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18514 (match_operand:SI 3 "register_operand" "0")))
18515 (set (match_operand:SI 1 "register_operand" "=S")
18516 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18517 (match_operand:SI 4 "register_operand" "1")))
18518 (set (mem:BLK (match_dup 3))
18519 (mem:BLK (match_dup 4)))
18520 (use (match_dup 5))]
18523 [(set_attr "type" "str")
18524 (set_attr "prefix_rep" "1")
18525 (set_attr "memory" "both")
18526 (set_attr "mode" "SI")])
18528 (define_insn "*rep_movsi_rex64"
18529 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18530 (set (match_operand:DI 0 "register_operand" "=D")
18531 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18533 (match_operand:DI 3 "register_operand" "0")))
18534 (set (match_operand:DI 1 "register_operand" "=S")
18535 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18536 (match_operand:DI 4 "register_operand" "1")))
18537 (set (mem:BLK (match_dup 3))
18538 (mem:BLK (match_dup 4)))
18539 (use (match_dup 5))]
18542 [(set_attr "type" "str")
18543 (set_attr "prefix_rep" "1")
18544 (set_attr "memory" "both")
18545 (set_attr "mode" "SI")])
18547 (define_insn "*rep_movqi"
18548 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18549 (set (match_operand:SI 0 "register_operand" "=D")
18550 (plus:SI (match_operand:SI 3 "register_operand" "0")
18551 (match_operand:SI 5 "register_operand" "2")))
18552 (set (match_operand:SI 1 "register_operand" "=S")
18553 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18554 (set (mem:BLK (match_dup 3))
18555 (mem:BLK (match_dup 4)))
18556 (use (match_dup 5))]
18559 [(set_attr "type" "str")
18560 (set_attr "prefix_rep" "1")
18561 (set_attr "memory" "both")
18562 (set_attr "mode" "SI")])
18564 (define_insn "*rep_movqi_rex64"
18565 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18566 (set (match_operand:DI 0 "register_operand" "=D")
18567 (plus:DI (match_operand:DI 3 "register_operand" "0")
18568 (match_operand:DI 5 "register_operand" "2")))
18569 (set (match_operand:DI 1 "register_operand" "=S")
18570 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18571 (set (mem:BLK (match_dup 3))
18572 (mem:BLK (match_dup 4)))
18573 (use (match_dup 5))]
18576 [(set_attr "type" "str")
18577 (set_attr "prefix_rep" "1")
18578 (set_attr "memory" "both")
18579 (set_attr "mode" "SI")])
18581 (define_expand "setmemsi"
18582 [(use (match_operand:BLK 0 "memory_operand" ""))
18583 (use (match_operand:SI 1 "nonmemory_operand" ""))
18584 (use (match_operand 2 "const_int_operand" ""))
18585 (use (match_operand 3 "const_int_operand" ""))
18586 (use (match_operand:SI 4 "const_int_operand" ""))
18587 (use (match_operand:SI 5 "const_int_operand" ""))]
18590 if (ix86_expand_setmem (operands[0], operands[1],
18591 operands[2], operands[3],
18592 operands[4], operands[5]))
18598 (define_expand "setmemdi"
18599 [(use (match_operand:BLK 0 "memory_operand" ""))
18600 (use (match_operand:DI 1 "nonmemory_operand" ""))
18601 (use (match_operand 2 "const_int_operand" ""))
18602 (use (match_operand 3 "const_int_operand" ""))
18603 (use (match_operand 4 "const_int_operand" ""))
18604 (use (match_operand 5 "const_int_operand" ""))]
18607 if (ix86_expand_setmem (operands[0], operands[1],
18608 operands[2], operands[3],
18609 operands[4], operands[5]))
18615 ;; Most CPUs don't like single string operations
18616 ;; Handle this case here to simplify previous expander.
18618 (define_expand "strset"
18619 [(set (match_operand 1 "memory_operand" "")
18620 (match_operand 2 "register_operand" ""))
18621 (parallel [(set (match_operand 0 "register_operand" "")
18623 (clobber (reg:CC FLAGS_REG))])]
18626 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18627 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18629 /* If .md ever supports :P for Pmode, this can be directly
18630 in the pattern above. */
18631 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18632 GEN_INT (GET_MODE_SIZE (GET_MODE
18634 if (TARGET_SINGLE_STRINGOP || optimize_size)
18636 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18642 (define_expand "strset_singleop"
18643 [(parallel [(set (match_operand 1 "memory_operand" "")
18644 (match_operand 2 "register_operand" ""))
18645 (set (match_operand 0 "register_operand" "")
18646 (match_operand 3 "" ""))])]
18647 "TARGET_SINGLE_STRINGOP || optimize_size"
18650 (define_insn "*strsetdi_rex_1"
18651 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18652 (match_operand:DI 2 "register_operand" "a"))
18653 (set (match_operand:DI 0 "register_operand" "=D")
18654 (plus:DI (match_dup 1)
18656 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18658 [(set_attr "type" "str")
18659 (set_attr "memory" "store")
18660 (set_attr "mode" "DI")])
18662 (define_insn "*strsetsi_1"
18663 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18664 (match_operand:SI 2 "register_operand" "a"))
18665 (set (match_operand:SI 0 "register_operand" "=D")
18666 (plus:SI (match_dup 1)
18668 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18670 [(set_attr "type" "str")
18671 (set_attr "memory" "store")
18672 (set_attr "mode" "SI")])
18674 (define_insn "*strsetsi_rex_1"
18675 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18676 (match_operand:SI 2 "register_operand" "a"))
18677 (set (match_operand:DI 0 "register_operand" "=D")
18678 (plus:DI (match_dup 1)
18680 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18682 [(set_attr "type" "str")
18683 (set_attr "memory" "store")
18684 (set_attr "mode" "SI")])
18686 (define_insn "*strsethi_1"
18687 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18688 (match_operand:HI 2 "register_operand" "a"))
18689 (set (match_operand:SI 0 "register_operand" "=D")
18690 (plus:SI (match_dup 1)
18692 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18694 [(set_attr "type" "str")
18695 (set_attr "memory" "store")
18696 (set_attr "mode" "HI")])
18698 (define_insn "*strsethi_rex_1"
18699 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18700 (match_operand:HI 2 "register_operand" "a"))
18701 (set (match_operand:DI 0 "register_operand" "=D")
18702 (plus:DI (match_dup 1)
18704 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18706 [(set_attr "type" "str")
18707 (set_attr "memory" "store")
18708 (set_attr "mode" "HI")])
18710 (define_insn "*strsetqi_1"
18711 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18712 (match_operand:QI 2 "register_operand" "a"))
18713 (set (match_operand:SI 0 "register_operand" "=D")
18714 (plus:SI (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" "QI")])
18722 (define_insn "*strsetqi_rex_1"
18723 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18724 (match_operand:QI 2 "register_operand" "a"))
18725 (set (match_operand:DI 0 "register_operand" "=D")
18726 (plus:DI (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" "QI")])
18734 (define_expand "rep_stos"
18735 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18736 (set (match_operand 0 "register_operand" "")
18737 (match_operand 4 "" ""))
18738 (set (match_operand 2 "memory_operand" "") (const_int 0))
18739 (use (match_operand 3 "register_operand" ""))
18740 (use (match_dup 1))])]
18744 (define_insn "*rep_stosdi_rex64"
18745 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18746 (set (match_operand:DI 0 "register_operand" "=D")
18747 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18749 (match_operand:DI 3 "register_operand" "0")))
18750 (set (mem:BLK (match_dup 3))
18752 (use (match_operand:DI 2 "register_operand" "a"))
18753 (use (match_dup 4))]
18756 [(set_attr "type" "str")
18757 (set_attr "prefix_rep" "1")
18758 (set_attr "memory" "store")
18759 (set_attr "mode" "DI")])
18761 (define_insn "*rep_stossi"
18762 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18763 (set (match_operand:SI 0 "register_operand" "=D")
18764 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18766 (match_operand:SI 3 "register_operand" "0")))
18767 (set (mem:BLK (match_dup 3))
18769 (use (match_operand:SI 2 "register_operand" "a"))
18770 (use (match_dup 4))]
18773 [(set_attr "type" "str")
18774 (set_attr "prefix_rep" "1")
18775 (set_attr "memory" "store")
18776 (set_attr "mode" "SI")])
18778 (define_insn "*rep_stossi_rex64"
18779 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18780 (set (match_operand:DI 0 "register_operand" "=D")
18781 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18783 (match_operand:DI 3 "register_operand" "0")))
18784 (set (mem:BLK (match_dup 3))
18786 (use (match_operand:SI 2 "register_operand" "a"))
18787 (use (match_dup 4))]
18790 [(set_attr "type" "str")
18791 (set_attr "prefix_rep" "1")
18792 (set_attr "memory" "store")
18793 (set_attr "mode" "SI")])
18795 (define_insn "*rep_stosqi"
18796 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18797 (set (match_operand:SI 0 "register_operand" "=D")
18798 (plus:SI (match_operand:SI 3 "register_operand" "0")
18799 (match_operand:SI 4 "register_operand" "1")))
18800 (set (mem:BLK (match_dup 3))
18802 (use (match_operand:QI 2 "register_operand" "a"))
18803 (use (match_dup 4))]
18806 [(set_attr "type" "str")
18807 (set_attr "prefix_rep" "1")
18808 (set_attr "memory" "store")
18809 (set_attr "mode" "QI")])
18811 (define_insn "*rep_stosqi_rex64"
18812 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18813 (set (match_operand:DI 0 "register_operand" "=D")
18814 (plus:DI (match_operand:DI 3 "register_operand" "0")
18815 (match_operand:DI 4 "register_operand" "1")))
18816 (set (mem:BLK (match_dup 3))
18818 (use (match_operand:QI 2 "register_operand" "a"))
18819 (use (match_dup 4))]
18822 [(set_attr "type" "str")
18823 (set_attr "prefix_rep" "1")
18824 (set_attr "memory" "store")
18825 (set_attr "mode" "QI")])
18827 (define_expand "cmpstrnsi"
18828 [(set (match_operand:SI 0 "register_operand" "")
18829 (compare:SI (match_operand:BLK 1 "general_operand" "")
18830 (match_operand:BLK 2 "general_operand" "")))
18831 (use (match_operand 3 "general_operand" ""))
18832 (use (match_operand 4 "immediate_operand" ""))]
18833 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18835 rtx addr1, addr2, out, outlow, count, countreg, align;
18837 /* Can't use this if the user has appropriated esi or edi. */
18838 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18843 out = gen_reg_rtx (SImode);
18845 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18846 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18847 if (addr1 != XEXP (operands[1], 0))
18848 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18849 if (addr2 != XEXP (operands[2], 0))
18850 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18852 count = operands[3];
18853 countreg = ix86_zero_extend_to_Pmode (count);
18855 /* %%% Iff we are testing strict equality, we can use known alignment
18856 to good advantage. This may be possible with combine, particularly
18857 once cc0 is dead. */
18858 align = operands[4];
18860 if (CONST_INT_P (count))
18862 if (INTVAL (count) == 0)
18864 emit_move_insn (operands[0], const0_rtx);
18867 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18868 operands[1], operands[2]));
18873 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18875 emit_insn (gen_cmpsi_1 (countreg, countreg));
18876 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18877 operands[1], operands[2]));
18880 outlow = gen_lowpart (QImode, out);
18881 emit_insn (gen_cmpintqi (outlow));
18882 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18884 if (operands[0] != out)
18885 emit_move_insn (operands[0], out);
18890 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18892 (define_expand "cmpintqi"
18893 [(set (match_dup 1)
18894 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18896 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18897 (parallel [(set (match_operand:QI 0 "register_operand" "")
18898 (minus:QI (match_dup 1)
18900 (clobber (reg:CC FLAGS_REG))])]
18902 "operands[1] = gen_reg_rtx (QImode);
18903 operands[2] = gen_reg_rtx (QImode);")
18905 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18906 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18908 (define_expand "cmpstrnqi_nz_1"
18909 [(parallel [(set (reg:CC FLAGS_REG)
18910 (compare:CC (match_operand 4 "memory_operand" "")
18911 (match_operand 5 "memory_operand" "")))
18912 (use (match_operand 2 "register_operand" ""))
18913 (use (match_operand:SI 3 "immediate_operand" ""))
18914 (clobber (match_operand 0 "register_operand" ""))
18915 (clobber (match_operand 1 "register_operand" ""))
18916 (clobber (match_dup 2))])]
18920 (define_insn "*cmpstrnqi_nz_1"
18921 [(set (reg:CC FLAGS_REG)
18922 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18923 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18924 (use (match_operand:SI 6 "register_operand" "2"))
18925 (use (match_operand:SI 3 "immediate_operand" "i"))
18926 (clobber (match_operand:SI 0 "register_operand" "=S"))
18927 (clobber (match_operand:SI 1 "register_operand" "=D"))
18928 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18931 [(set_attr "type" "str")
18932 (set_attr "mode" "QI")
18933 (set_attr "prefix_rep" "1")])
18935 (define_insn "*cmpstrnqi_nz_rex_1"
18936 [(set (reg:CC FLAGS_REG)
18937 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18938 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18939 (use (match_operand:DI 6 "register_operand" "2"))
18940 (use (match_operand:SI 3 "immediate_operand" "i"))
18941 (clobber (match_operand:DI 0 "register_operand" "=S"))
18942 (clobber (match_operand:DI 1 "register_operand" "=D"))
18943 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18946 [(set_attr "type" "str")
18947 (set_attr "mode" "QI")
18948 (set_attr "prefix_rep" "1")])
18950 ;; The same, but the count is not known to not be zero.
18952 (define_expand "cmpstrnqi_1"
18953 [(parallel [(set (reg:CC FLAGS_REG)
18954 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18956 (compare:CC (match_operand 4 "memory_operand" "")
18957 (match_operand 5 "memory_operand" ""))
18959 (use (match_operand:SI 3 "immediate_operand" ""))
18960 (use (reg:CC FLAGS_REG))
18961 (clobber (match_operand 0 "register_operand" ""))
18962 (clobber (match_operand 1 "register_operand" ""))
18963 (clobber (match_dup 2))])]
18967 (define_insn "*cmpstrnqi_1"
18968 [(set (reg:CC FLAGS_REG)
18969 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18971 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18972 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18974 (use (match_operand:SI 3 "immediate_operand" "i"))
18975 (use (reg:CC FLAGS_REG))
18976 (clobber (match_operand:SI 0 "register_operand" "=S"))
18977 (clobber (match_operand:SI 1 "register_operand" "=D"))
18978 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18981 [(set_attr "type" "str")
18982 (set_attr "mode" "QI")
18983 (set_attr "prefix_rep" "1")])
18985 (define_insn "*cmpstrnqi_rex_1"
18986 [(set (reg:CC FLAGS_REG)
18987 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18989 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18990 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18992 (use (match_operand:SI 3 "immediate_operand" "i"))
18993 (use (reg:CC FLAGS_REG))
18994 (clobber (match_operand:DI 0 "register_operand" "=S"))
18995 (clobber (match_operand:DI 1 "register_operand" "=D"))
18996 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18999 [(set_attr "type" "str")
19000 (set_attr "mode" "QI")
19001 (set_attr "prefix_rep" "1")])
19003 (define_expand "strlensi"
19004 [(set (match_operand:SI 0 "register_operand" "")
19005 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19006 (match_operand:QI 2 "immediate_operand" "")
19007 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19010 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19016 (define_expand "strlendi"
19017 [(set (match_operand:DI 0 "register_operand" "")
19018 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19019 (match_operand:QI 2 "immediate_operand" "")
19020 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19023 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19029 (define_expand "strlenqi_1"
19030 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19031 (clobber (match_operand 1 "register_operand" ""))
19032 (clobber (reg:CC FLAGS_REG))])]
19036 (define_insn "*strlenqi_1"
19037 [(set (match_operand:SI 0 "register_operand" "=&c")
19038 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19039 (match_operand:QI 2 "register_operand" "a")
19040 (match_operand:SI 3 "immediate_operand" "i")
19041 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19042 (clobber (match_operand:SI 1 "register_operand" "=D"))
19043 (clobber (reg:CC FLAGS_REG))]
19046 [(set_attr "type" "str")
19047 (set_attr "mode" "QI")
19048 (set_attr "prefix_rep" "1")])
19050 (define_insn "*strlenqi_rex_1"
19051 [(set (match_operand:DI 0 "register_operand" "=&c")
19052 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19053 (match_operand:QI 2 "register_operand" "a")
19054 (match_operand:DI 3 "immediate_operand" "i")
19055 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19056 (clobber (match_operand:DI 1 "register_operand" "=D"))
19057 (clobber (reg:CC FLAGS_REG))]
19060 [(set_attr "type" "str")
19061 (set_attr "mode" "QI")
19062 (set_attr "prefix_rep" "1")])
19064 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19065 ;; handled in combine, but it is not currently up to the task.
19066 ;; When used for their truth value, the cmpstrn* expanders generate
19075 ;; The intermediate three instructions are unnecessary.
19077 ;; This one handles cmpstrn*_nz_1...
19080 (set (reg:CC FLAGS_REG)
19081 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19082 (mem:BLK (match_operand 5 "register_operand" ""))))
19083 (use (match_operand 6 "register_operand" ""))
19084 (use (match_operand:SI 3 "immediate_operand" ""))
19085 (clobber (match_operand 0 "register_operand" ""))
19086 (clobber (match_operand 1 "register_operand" ""))
19087 (clobber (match_operand 2 "register_operand" ""))])
19088 (set (match_operand:QI 7 "register_operand" "")
19089 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19090 (set (match_operand:QI 8 "register_operand" "")
19091 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19092 (set (reg FLAGS_REG)
19093 (compare (match_dup 7) (match_dup 8)))
19095 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19097 (set (reg:CC FLAGS_REG)
19098 (compare:CC (mem:BLK (match_dup 4))
19099 (mem:BLK (match_dup 5))))
19100 (use (match_dup 6))
19101 (use (match_dup 3))
19102 (clobber (match_dup 0))
19103 (clobber (match_dup 1))
19104 (clobber (match_dup 2))])]
19107 ;; ...and this one handles cmpstrn*_1.
19110 (set (reg:CC FLAGS_REG)
19111 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19113 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19114 (mem:BLK (match_operand 5 "register_operand" "")))
19116 (use (match_operand:SI 3 "immediate_operand" ""))
19117 (use (reg:CC FLAGS_REG))
19118 (clobber (match_operand 0 "register_operand" ""))
19119 (clobber (match_operand 1 "register_operand" ""))
19120 (clobber (match_operand 2 "register_operand" ""))])
19121 (set (match_operand:QI 7 "register_operand" "")
19122 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19123 (set (match_operand:QI 8 "register_operand" "")
19124 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19125 (set (reg FLAGS_REG)
19126 (compare (match_dup 7) (match_dup 8)))
19128 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19130 (set (reg:CC FLAGS_REG)
19131 (if_then_else:CC (ne (match_dup 6)
19133 (compare:CC (mem:BLK (match_dup 4))
19134 (mem:BLK (match_dup 5)))
19136 (use (match_dup 3))
19137 (use (reg:CC FLAGS_REG))
19138 (clobber (match_dup 0))
19139 (clobber (match_dup 1))
19140 (clobber (match_dup 2))])]
19145 ;; Conditional move instructions.
19147 (define_expand "movdicc"
19148 [(set (match_operand:DI 0 "register_operand" "")
19149 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19150 (match_operand:DI 2 "general_operand" "")
19151 (match_operand:DI 3 "general_operand" "")))]
19153 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19155 (define_insn "x86_movdicc_0_m1_rex64"
19156 [(set (match_operand:DI 0 "register_operand" "=r")
19157 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19160 (clobber (reg:CC FLAGS_REG))]
19163 ; Since we don't have the proper number of operands for an alu insn,
19164 ; fill in all the blanks.
19165 [(set_attr "type" "alu")
19166 (set_attr "pent_pair" "pu")
19167 (set_attr "memory" "none")
19168 (set_attr "imm_disp" "false")
19169 (set_attr "mode" "DI")
19170 (set_attr "length_immediate" "0")])
19172 (define_insn "*x86_movdicc_0_m1_se"
19173 [(set (match_operand:DI 0 "register_operand" "=r")
19174 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19177 (clobber (reg:CC FLAGS_REG))]
19180 [(set_attr "type" "alu")
19181 (set_attr "pent_pair" "pu")
19182 (set_attr "memory" "none")
19183 (set_attr "imm_disp" "false")
19184 (set_attr "mode" "DI")
19185 (set_attr "length_immediate" "0")])
19187 (define_insn "*movdicc_c_rex64"
19188 [(set (match_operand:DI 0 "register_operand" "=r,r")
19189 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19190 [(reg FLAGS_REG) (const_int 0)])
19191 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19192 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19193 "TARGET_64BIT && TARGET_CMOVE
19194 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19196 cmov%O2%C1\t{%2, %0|%0, %2}
19197 cmov%O2%c1\t{%3, %0|%0, %3}"
19198 [(set_attr "type" "icmov")
19199 (set_attr "mode" "DI")])
19201 (define_expand "movsicc"
19202 [(set (match_operand:SI 0 "register_operand" "")
19203 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19204 (match_operand:SI 2 "general_operand" "")
19205 (match_operand:SI 3 "general_operand" "")))]
19207 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19209 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19210 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19211 ;; So just document what we're doing explicitly.
19213 (define_insn "x86_movsicc_0_m1"
19214 [(set (match_operand:SI 0 "register_operand" "=r")
19215 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19218 (clobber (reg:CC FLAGS_REG))]
19221 ; Since we don't have the proper number of operands for an alu insn,
19222 ; fill in all the blanks.
19223 [(set_attr "type" "alu")
19224 (set_attr "pent_pair" "pu")
19225 (set_attr "memory" "none")
19226 (set_attr "imm_disp" "false")
19227 (set_attr "mode" "SI")
19228 (set_attr "length_immediate" "0")])
19230 (define_insn "*x86_movsicc_0_m1_se"
19231 [(set (match_operand:SI 0 "register_operand" "=r")
19232 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19235 (clobber (reg:CC FLAGS_REG))]
19238 [(set_attr "type" "alu")
19239 (set_attr "pent_pair" "pu")
19240 (set_attr "memory" "none")
19241 (set_attr "imm_disp" "false")
19242 (set_attr "mode" "SI")
19243 (set_attr "length_immediate" "0")])
19245 (define_insn "*movsicc_noc"
19246 [(set (match_operand:SI 0 "register_operand" "=r,r")
19247 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19248 [(reg FLAGS_REG) (const_int 0)])
19249 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19250 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19252 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19254 cmov%O2%C1\t{%2, %0|%0, %2}
19255 cmov%O2%c1\t{%3, %0|%0, %3}"
19256 [(set_attr "type" "icmov")
19257 (set_attr "mode" "SI")])
19259 (define_expand "movhicc"
19260 [(set (match_operand:HI 0 "register_operand" "")
19261 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19262 (match_operand:HI 2 "general_operand" "")
19263 (match_operand:HI 3 "general_operand" "")))]
19264 "TARGET_HIMODE_MATH"
19265 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19267 (define_insn "*movhicc_noc"
19268 [(set (match_operand:HI 0 "register_operand" "=r,r")
19269 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19270 [(reg FLAGS_REG) (const_int 0)])
19271 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19272 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19274 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19276 cmov%O2%C1\t{%2, %0|%0, %2}
19277 cmov%O2%c1\t{%3, %0|%0, %3}"
19278 [(set_attr "type" "icmov")
19279 (set_attr "mode" "HI")])
19281 (define_expand "movqicc"
19282 [(set (match_operand:QI 0 "register_operand" "")
19283 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19284 (match_operand:QI 2 "general_operand" "")
19285 (match_operand:QI 3 "general_operand" "")))]
19286 "TARGET_QIMODE_MATH"
19287 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19289 (define_insn_and_split "*movqicc_noc"
19290 [(set (match_operand:QI 0 "register_operand" "=r,r")
19291 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19292 [(match_operand 4 "flags_reg_operand" "")
19294 (match_operand:QI 2 "register_operand" "r,0")
19295 (match_operand:QI 3 "register_operand" "0,r")))]
19296 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19298 "&& reload_completed"
19299 [(set (match_dup 0)
19300 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19303 "operands[0] = gen_lowpart (SImode, operands[0]);
19304 operands[2] = gen_lowpart (SImode, operands[2]);
19305 operands[3] = gen_lowpart (SImode, operands[3]);"
19306 [(set_attr "type" "icmov")
19307 (set_attr "mode" "SI")])
19309 (define_expand "mov<mode>cc"
19310 [(set (match_operand:X87MODEF 0 "register_operand" "")
19311 (if_then_else:X87MODEF
19312 (match_operand 1 "comparison_operator" "")
19313 (match_operand:X87MODEF 2 "register_operand" "")
19314 (match_operand:X87MODEF 3 "register_operand" "")))]
19315 "(TARGET_80387 && TARGET_CMOVE)
19316 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19317 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19319 (define_insn "*movsfcc_1_387"
19320 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19321 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19322 [(reg FLAGS_REG) (const_int 0)])
19323 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19324 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19325 "TARGET_80387 && TARGET_CMOVE
19326 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19328 fcmov%F1\t{%2, %0|%0, %2}
19329 fcmov%f1\t{%3, %0|%0, %3}
19330 cmov%O2%C1\t{%2, %0|%0, %2}
19331 cmov%O2%c1\t{%3, %0|%0, %3}"
19332 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19333 (set_attr "mode" "SF,SF,SI,SI")])
19335 (define_insn "*movdfcc_1"
19336 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19337 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19338 [(reg FLAGS_REG) (const_int 0)])
19339 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19340 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19341 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19342 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19344 fcmov%F1\t{%2, %0|%0, %2}
19345 fcmov%f1\t{%3, %0|%0, %3}
19348 [(set_attr "type" "fcmov,fcmov,multi,multi")
19349 (set_attr "mode" "DF")])
19351 (define_insn "*movdfcc_1_rex64"
19352 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19353 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19354 [(reg FLAGS_REG) (const_int 0)])
19355 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19356 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19357 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19358 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19360 fcmov%F1\t{%2, %0|%0, %2}
19361 fcmov%f1\t{%3, %0|%0, %3}
19362 cmov%O2%C1\t{%2, %0|%0, %2}
19363 cmov%O2%c1\t{%3, %0|%0, %3}"
19364 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19365 (set_attr "mode" "DF")])
19368 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19369 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19370 [(match_operand 4 "flags_reg_operand" "")
19372 (match_operand:DF 2 "nonimmediate_operand" "")
19373 (match_operand:DF 3 "nonimmediate_operand" "")))]
19374 "!TARGET_64BIT && reload_completed"
19375 [(set (match_dup 2)
19376 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19380 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19383 "split_di (operands+2, 1, operands+5, operands+6);
19384 split_di (operands+3, 1, operands+7, operands+8);
19385 split_di (operands, 1, operands+2, operands+3);")
19387 (define_insn "*movxfcc_1"
19388 [(set (match_operand:XF 0 "register_operand" "=f,f")
19389 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19390 [(reg FLAGS_REG) (const_int 0)])
19391 (match_operand:XF 2 "register_operand" "f,0")
19392 (match_operand:XF 3 "register_operand" "0,f")))]
19393 "TARGET_80387 && TARGET_CMOVE"
19395 fcmov%F1\t{%2, %0|%0, %2}
19396 fcmov%f1\t{%3, %0|%0, %3}"
19397 [(set_attr "type" "fcmov")
19398 (set_attr "mode" "XF")])
19400 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19401 ;; the scalar versions to have only XMM registers as operands.
19403 ;; SSE5 conditional move
19404 (define_insn "*sse5_pcmov_<mode>"
19405 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19406 (if_then_else:MODEF
19407 (match_operand:MODEF 1 "register_operand" "x,0")
19408 (match_operand:MODEF 2 "register_operand" "0,x")
19409 (match_operand:MODEF 3 "register_operand" "x,x")))]
19410 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19411 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19412 [(set_attr "type" "sse4arg")])
19414 ;; These versions of the min/max patterns are intentionally ignorant of
19415 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19416 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19417 ;; are undefined in this condition, we're certain this is correct.
19419 (define_insn "smin<mode>3"
19420 [(set (match_operand:MODEF 0 "register_operand" "=x")
19422 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19423 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19424 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19425 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19426 [(set_attr "type" "sseadd")
19427 (set_attr "mode" "<MODE>")])
19429 (define_insn "smax<mode>3"
19430 [(set (match_operand:MODEF 0 "register_operand" "=x")
19432 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19433 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19434 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19435 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19436 [(set_attr "type" "sseadd")
19437 (set_attr "mode" "<MODE>")])
19439 ;; These versions of the min/max patterns implement exactly the operations
19440 ;; min = (op1 < op2 ? op1 : op2)
19441 ;; max = (!(op1 < op2) ? op1 : op2)
19442 ;; Their operands are not commutative, and thus they may be used in the
19443 ;; presence of -0.0 and NaN.
19445 (define_insn "*ieee_smin<mode>3"
19446 [(set (match_operand:MODEF 0 "register_operand" "=x")
19448 [(match_operand:MODEF 1 "register_operand" "0")
19449 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19451 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19452 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19453 [(set_attr "type" "sseadd")
19454 (set_attr "mode" "<MODE>")])
19456 (define_insn "*ieee_smax<mode>3"
19457 [(set (match_operand:MODEF 0 "register_operand" "=x")
19459 [(match_operand:MODEF 1 "register_operand" "0")
19460 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19462 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19463 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19464 [(set_attr "type" "sseadd")
19465 (set_attr "mode" "<MODE>")])
19467 ;; Make two stack loads independent:
19469 ;; fld %st(0) -> fld bb
19470 ;; fmul bb fmul %st(1), %st
19472 ;; Actually we only match the last two instructions for simplicity.
19474 [(set (match_operand 0 "fp_register_operand" "")
19475 (match_operand 1 "fp_register_operand" ""))
19477 (match_operator 2 "binary_fp_operator"
19479 (match_operand 3 "memory_operand" "")]))]
19480 "REGNO (operands[0]) != REGNO (operands[1])"
19481 [(set (match_dup 0) (match_dup 3))
19482 (set (match_dup 0) (match_dup 4))]
19484 ;; The % modifier is not operational anymore in peephole2's, so we have to
19485 ;; swap the operands manually in the case of addition and multiplication.
19486 "if (COMMUTATIVE_ARITH_P (operands[2]))
19487 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19488 operands[0], operands[1]);
19490 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19491 operands[1], operands[0]);")
19493 ;; Conditional addition patterns
19494 (define_expand "addqicc"
19495 [(match_operand:QI 0 "register_operand" "")
19496 (match_operand 1 "comparison_operator" "")
19497 (match_operand:QI 2 "register_operand" "")
19498 (match_operand:QI 3 "const_int_operand" "")]
19500 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19502 (define_expand "addhicc"
19503 [(match_operand:HI 0 "register_operand" "")
19504 (match_operand 1 "comparison_operator" "")
19505 (match_operand:HI 2 "register_operand" "")
19506 (match_operand:HI 3 "const_int_operand" "")]
19508 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19510 (define_expand "addsicc"
19511 [(match_operand:SI 0 "register_operand" "")
19512 (match_operand 1 "comparison_operator" "")
19513 (match_operand:SI 2 "register_operand" "")
19514 (match_operand:SI 3 "const_int_operand" "")]
19516 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19518 (define_expand "adddicc"
19519 [(match_operand:DI 0 "register_operand" "")
19520 (match_operand 1 "comparison_operator" "")
19521 (match_operand:DI 2 "register_operand" "")
19522 (match_operand:DI 3 "const_int_operand" "")]
19524 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19527 ;; Misc patterns (?)
19529 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19530 ;; Otherwise there will be nothing to keep
19532 ;; [(set (reg ebp) (reg esp))]
19533 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19534 ;; (clobber (eflags)]
19535 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19537 ;; in proper program order.
19538 (define_insn "pro_epilogue_adjust_stack_1"
19539 [(set (match_operand:SI 0 "register_operand" "=r,r")
19540 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19541 (match_operand:SI 2 "immediate_operand" "i,i")))
19542 (clobber (reg:CC FLAGS_REG))
19543 (clobber (mem:BLK (scratch)))]
19546 switch (get_attr_type (insn))
19549 return "mov{l}\t{%1, %0|%0, %1}";
19552 if (CONST_INT_P (operands[2])
19553 && (INTVAL (operands[2]) == 128
19554 || (INTVAL (operands[2]) < 0
19555 && INTVAL (operands[2]) != -128)))
19557 operands[2] = GEN_INT (-INTVAL (operands[2]));
19558 return "sub{l}\t{%2, %0|%0, %2}";
19560 return "add{l}\t{%2, %0|%0, %2}";
19563 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19564 return "lea{l}\t{%a2, %0|%0, %a2}";
19567 gcc_unreachable ();
19570 [(set (attr "type")
19571 (cond [(eq_attr "alternative" "0")
19572 (const_string "alu")
19573 (match_operand:SI 2 "const0_operand" "")
19574 (const_string "imov")
19576 (const_string "lea")))
19577 (set_attr "mode" "SI")])
19579 (define_insn "pro_epilogue_adjust_stack_rex64"
19580 [(set (match_operand:DI 0 "register_operand" "=r,r")
19581 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19582 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19583 (clobber (reg:CC FLAGS_REG))
19584 (clobber (mem:BLK (scratch)))]
19587 switch (get_attr_type (insn))
19590 return "mov{q}\t{%1, %0|%0, %1}";
19593 if (CONST_INT_P (operands[2])
19594 /* Avoid overflows. */
19595 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19596 && (INTVAL (operands[2]) == 128
19597 || (INTVAL (operands[2]) < 0
19598 && INTVAL (operands[2]) != -128)))
19600 operands[2] = GEN_INT (-INTVAL (operands[2]));
19601 return "sub{q}\t{%2, %0|%0, %2}";
19603 return "add{q}\t{%2, %0|%0, %2}";
19606 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19607 return "lea{q}\t{%a2, %0|%0, %a2}";
19610 gcc_unreachable ();
19613 [(set (attr "type")
19614 (cond [(eq_attr "alternative" "0")
19615 (const_string "alu")
19616 (match_operand:DI 2 "const0_operand" "")
19617 (const_string "imov")
19619 (const_string "lea")))
19620 (set_attr "mode" "DI")])
19622 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19623 [(set (match_operand:DI 0 "register_operand" "=r,r")
19624 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19625 (match_operand:DI 3 "immediate_operand" "i,i")))
19626 (use (match_operand:DI 2 "register_operand" "r,r"))
19627 (clobber (reg:CC FLAGS_REG))
19628 (clobber (mem:BLK (scratch)))]
19631 switch (get_attr_type (insn))
19634 return "add{q}\t{%2, %0|%0, %2}";
19637 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19638 return "lea{q}\t{%a2, %0|%0, %a2}";
19641 gcc_unreachable ();
19644 [(set_attr "type" "alu,lea")
19645 (set_attr "mode" "DI")])
19647 (define_insn "allocate_stack_worker_32"
19648 [(set (match_operand:SI 0 "register_operand" "+a")
19649 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19650 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19651 (clobber (reg:CC FLAGS_REG))]
19652 "!TARGET_64BIT && TARGET_STACK_PROBE"
19654 [(set_attr "type" "multi")
19655 (set_attr "length" "5")])
19657 (define_insn "allocate_stack_worker_64"
19658 [(set (match_operand:DI 0 "register_operand" "=a")
19659 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19660 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19661 (clobber (reg:DI R10_REG))
19662 (clobber (reg:DI R11_REG))
19663 (clobber (reg:CC FLAGS_REG))]
19664 "TARGET_64BIT && TARGET_STACK_PROBE"
19666 [(set_attr "type" "multi")
19667 (set_attr "length" "5")])
19669 (define_expand "allocate_stack"
19670 [(match_operand 0 "register_operand" "")
19671 (match_operand 1 "general_operand" "")]
19672 "TARGET_STACK_PROBE"
19676 #ifndef CHECK_STACK_LIMIT
19677 #define CHECK_STACK_LIMIT 0
19680 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19681 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19683 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19684 stack_pointer_rtx, 0, OPTAB_DIRECT);
19685 if (x != stack_pointer_rtx)
19686 emit_move_insn (stack_pointer_rtx, x);
19690 x = copy_to_mode_reg (Pmode, operands[1]);
19692 x = gen_allocate_stack_worker_64 (x);
19694 x = gen_allocate_stack_worker_32 (x);
19698 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19702 (define_expand "builtin_setjmp_receiver"
19703 [(label_ref (match_operand 0 "" ""))]
19704 "!TARGET_64BIT && flag_pic"
19709 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19710 rtx label_rtx = gen_label_rtx ();
19711 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19712 xops[0] = xops[1] = picreg;
19713 xops[2] = gen_rtx_CONST (SImode,
19714 gen_rtx_MINUS (SImode,
19715 gen_rtx_LABEL_REF (SImode, label_rtx),
19716 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19717 ix86_expand_binary_operator (MINUS, SImode, xops);
19720 emit_insn (gen_set_got (pic_offset_table_rtx));
19724 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19727 [(set (match_operand 0 "register_operand" "")
19728 (match_operator 3 "promotable_binary_operator"
19729 [(match_operand 1 "register_operand" "")
19730 (match_operand 2 "aligned_operand" "")]))
19731 (clobber (reg:CC FLAGS_REG))]
19732 "! TARGET_PARTIAL_REG_STALL && reload_completed
19733 && ((GET_MODE (operands[0]) == HImode
19734 && ((!optimize_size && !TARGET_FAST_PREFIX)
19735 /* ??? next two lines just !satisfies_constraint_K (...) */
19736 || !CONST_INT_P (operands[2])
19737 || satisfies_constraint_K (operands[2])))
19738 || (GET_MODE (operands[0]) == QImode
19739 && (TARGET_PROMOTE_QImode || optimize_size)))"
19740 [(parallel [(set (match_dup 0)
19741 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19742 (clobber (reg:CC FLAGS_REG))])]
19743 "operands[0] = gen_lowpart (SImode, operands[0]);
19744 operands[1] = gen_lowpart (SImode, operands[1]);
19745 if (GET_CODE (operands[3]) != ASHIFT)
19746 operands[2] = gen_lowpart (SImode, operands[2]);
19747 PUT_MODE (operands[3], SImode);")
19749 ; Promote the QImode tests, as i386 has encoding of the AND
19750 ; instruction with 32-bit sign-extended immediate and thus the
19751 ; instruction size is unchanged, except in the %eax case for
19752 ; which it is increased by one byte, hence the ! optimize_size.
19754 [(set (match_operand 0 "flags_reg_operand" "")
19755 (match_operator 2 "compare_operator"
19756 [(and (match_operand 3 "aligned_operand" "")
19757 (match_operand 4 "const_int_operand" ""))
19759 (set (match_operand 1 "register_operand" "")
19760 (and (match_dup 3) (match_dup 4)))]
19761 "! TARGET_PARTIAL_REG_STALL && reload_completed
19763 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19764 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19765 /* Ensure that the operand will remain sign-extended immediate. */
19766 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19767 [(parallel [(set (match_dup 0)
19768 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19771 (and:SI (match_dup 3) (match_dup 4)))])]
19774 = gen_int_mode (INTVAL (operands[4])
19775 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19776 operands[1] = gen_lowpart (SImode, operands[1]);
19777 operands[3] = gen_lowpart (SImode, operands[3]);
19780 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19781 ; the TEST instruction with 32-bit sign-extended immediate and thus
19782 ; the instruction size would at least double, which is not what we
19783 ; want even with ! optimize_size.
19785 [(set (match_operand 0 "flags_reg_operand" "")
19786 (match_operator 1 "compare_operator"
19787 [(and (match_operand:HI 2 "aligned_operand" "")
19788 (match_operand:HI 3 "const_int_operand" ""))
19790 "! TARGET_PARTIAL_REG_STALL && reload_completed
19791 && ! TARGET_FAST_PREFIX
19793 /* Ensure that the operand will remain sign-extended immediate. */
19794 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19795 [(set (match_dup 0)
19796 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19800 = gen_int_mode (INTVAL (operands[3])
19801 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19802 operands[2] = gen_lowpart (SImode, operands[2]);
19806 [(set (match_operand 0 "register_operand" "")
19807 (neg (match_operand 1 "register_operand" "")))
19808 (clobber (reg:CC FLAGS_REG))]
19809 "! TARGET_PARTIAL_REG_STALL && reload_completed
19810 && (GET_MODE (operands[0]) == HImode
19811 || (GET_MODE (operands[0]) == QImode
19812 && (TARGET_PROMOTE_QImode || optimize_size)))"
19813 [(parallel [(set (match_dup 0)
19814 (neg:SI (match_dup 1)))
19815 (clobber (reg:CC FLAGS_REG))])]
19816 "operands[0] = gen_lowpart (SImode, operands[0]);
19817 operands[1] = gen_lowpart (SImode, operands[1]);")
19820 [(set (match_operand 0 "register_operand" "")
19821 (not (match_operand 1 "register_operand" "")))]
19822 "! TARGET_PARTIAL_REG_STALL && reload_completed
19823 && (GET_MODE (operands[0]) == HImode
19824 || (GET_MODE (operands[0]) == QImode
19825 && (TARGET_PROMOTE_QImode || optimize_size)))"
19826 [(set (match_dup 0)
19827 (not:SI (match_dup 1)))]
19828 "operands[0] = gen_lowpart (SImode, operands[0]);
19829 operands[1] = gen_lowpart (SImode, operands[1]);")
19832 [(set (match_operand 0 "register_operand" "")
19833 (if_then_else (match_operator 1 "comparison_operator"
19834 [(reg FLAGS_REG) (const_int 0)])
19835 (match_operand 2 "register_operand" "")
19836 (match_operand 3 "register_operand" "")))]
19837 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19838 && (GET_MODE (operands[0]) == HImode
19839 || (GET_MODE (operands[0]) == QImode
19840 && (TARGET_PROMOTE_QImode || optimize_size)))"
19841 [(set (match_dup 0)
19842 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19843 "operands[0] = gen_lowpart (SImode, operands[0]);
19844 operands[2] = gen_lowpart (SImode, operands[2]);
19845 operands[3] = gen_lowpart (SImode, operands[3]);")
19848 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19849 ;; transform a complex memory operation into two memory to register operations.
19851 ;; Don't push memory operands
19853 [(set (match_operand:SI 0 "push_operand" "")
19854 (match_operand:SI 1 "memory_operand" ""))
19855 (match_scratch:SI 2 "r")]
19856 "!optimize_size && !TARGET_PUSH_MEMORY
19857 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19858 [(set (match_dup 2) (match_dup 1))
19859 (set (match_dup 0) (match_dup 2))]
19863 [(set (match_operand:DI 0 "push_operand" "")
19864 (match_operand:DI 1 "memory_operand" ""))
19865 (match_scratch:DI 2 "r")]
19866 "!optimize_size && !TARGET_PUSH_MEMORY
19867 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19868 [(set (match_dup 2) (match_dup 1))
19869 (set (match_dup 0) (match_dup 2))]
19872 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19875 [(set (match_operand:SF 0 "push_operand" "")
19876 (match_operand:SF 1 "memory_operand" ""))
19877 (match_scratch:SF 2 "r")]
19878 "!optimize_size && !TARGET_PUSH_MEMORY
19879 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19880 [(set (match_dup 2) (match_dup 1))
19881 (set (match_dup 0) (match_dup 2))]
19885 [(set (match_operand:HI 0 "push_operand" "")
19886 (match_operand:HI 1 "memory_operand" ""))
19887 (match_scratch:HI 2 "r")]
19888 "!optimize_size && !TARGET_PUSH_MEMORY
19889 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19890 [(set (match_dup 2) (match_dup 1))
19891 (set (match_dup 0) (match_dup 2))]
19895 [(set (match_operand:QI 0 "push_operand" "")
19896 (match_operand:QI 1 "memory_operand" ""))
19897 (match_scratch:QI 2 "q")]
19898 "!optimize_size && !TARGET_PUSH_MEMORY
19899 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19900 [(set (match_dup 2) (match_dup 1))
19901 (set (match_dup 0) (match_dup 2))]
19904 ;; Don't move an immediate directly to memory when the instruction
19907 [(match_scratch:SI 1 "r")
19908 (set (match_operand:SI 0 "memory_operand" "")
19911 && ! TARGET_USE_MOV0
19912 && TARGET_SPLIT_LONG_MOVES
19913 && get_attr_length (insn) >= ix86_cost->large_insn
19914 && peep2_regno_dead_p (0, FLAGS_REG)"
19915 [(parallel [(set (match_dup 1) (const_int 0))
19916 (clobber (reg:CC FLAGS_REG))])
19917 (set (match_dup 0) (match_dup 1))]
19921 [(match_scratch:HI 1 "r")
19922 (set (match_operand:HI 0 "memory_operand" "")
19925 && ! TARGET_USE_MOV0
19926 && TARGET_SPLIT_LONG_MOVES
19927 && get_attr_length (insn) >= ix86_cost->large_insn
19928 && peep2_regno_dead_p (0, FLAGS_REG)"
19929 [(parallel [(set (match_dup 2) (const_int 0))
19930 (clobber (reg:CC FLAGS_REG))])
19931 (set (match_dup 0) (match_dup 1))]
19932 "operands[2] = gen_lowpart (SImode, operands[1]);")
19935 [(match_scratch:QI 1 "q")
19936 (set (match_operand:QI 0 "memory_operand" "")
19939 && ! TARGET_USE_MOV0
19940 && TARGET_SPLIT_LONG_MOVES
19941 && get_attr_length (insn) >= ix86_cost->large_insn
19942 && peep2_regno_dead_p (0, FLAGS_REG)"
19943 [(parallel [(set (match_dup 2) (const_int 0))
19944 (clobber (reg:CC FLAGS_REG))])
19945 (set (match_dup 0) (match_dup 1))]
19946 "operands[2] = gen_lowpart (SImode, operands[1]);")
19949 [(match_scratch:SI 2 "r")
19950 (set (match_operand:SI 0 "memory_operand" "")
19951 (match_operand:SI 1 "immediate_operand" ""))]
19953 && TARGET_SPLIT_LONG_MOVES
19954 && get_attr_length (insn) >= ix86_cost->large_insn"
19955 [(set (match_dup 2) (match_dup 1))
19956 (set (match_dup 0) (match_dup 2))]
19960 [(match_scratch:HI 2 "r")
19961 (set (match_operand:HI 0 "memory_operand" "")
19962 (match_operand:HI 1 "immediate_operand" ""))]
19964 && TARGET_SPLIT_LONG_MOVES
19965 && get_attr_length (insn) >= ix86_cost->large_insn"
19966 [(set (match_dup 2) (match_dup 1))
19967 (set (match_dup 0) (match_dup 2))]
19971 [(match_scratch:QI 2 "q")
19972 (set (match_operand:QI 0 "memory_operand" "")
19973 (match_operand:QI 1 "immediate_operand" ""))]
19975 && TARGET_SPLIT_LONG_MOVES
19976 && get_attr_length (insn) >= ix86_cost->large_insn"
19977 [(set (match_dup 2) (match_dup 1))
19978 (set (match_dup 0) (match_dup 2))]
19981 ;; Don't compare memory with zero, load and use a test instead.
19983 [(set (match_operand 0 "flags_reg_operand" "")
19984 (match_operator 1 "compare_operator"
19985 [(match_operand:SI 2 "memory_operand" "")
19987 (match_scratch:SI 3 "r")]
19988 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
19989 [(set (match_dup 3) (match_dup 2))
19990 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19993 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19994 ;; Don't split NOTs with a displacement operand, because resulting XOR
19995 ;; will not be pairable anyway.
19997 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19998 ;; represented using a modRM byte. The XOR replacement is long decoded,
19999 ;; so this split helps here as well.
20001 ;; Note: Can't do this as a regular split because we can't get proper
20002 ;; lifetime information then.
20005 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20006 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20008 && ((TARGET_NOT_UNPAIRABLE
20009 && (!MEM_P (operands[0])
20010 || !memory_displacement_operand (operands[0], SImode)))
20011 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20012 && peep2_regno_dead_p (0, FLAGS_REG)"
20013 [(parallel [(set (match_dup 0)
20014 (xor:SI (match_dup 1) (const_int -1)))
20015 (clobber (reg:CC FLAGS_REG))])]
20019 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20020 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20022 && ((TARGET_NOT_UNPAIRABLE
20023 && (!MEM_P (operands[0])
20024 || !memory_displacement_operand (operands[0], HImode)))
20025 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20026 && peep2_regno_dead_p (0, FLAGS_REG)"
20027 [(parallel [(set (match_dup 0)
20028 (xor:HI (match_dup 1) (const_int -1)))
20029 (clobber (reg:CC FLAGS_REG))])]
20033 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20034 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20036 && ((TARGET_NOT_UNPAIRABLE
20037 && (!MEM_P (operands[0])
20038 || !memory_displacement_operand (operands[0], QImode)))
20039 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20040 && peep2_regno_dead_p (0, FLAGS_REG)"
20041 [(parallel [(set (match_dup 0)
20042 (xor:QI (match_dup 1) (const_int -1)))
20043 (clobber (reg:CC FLAGS_REG))])]
20046 ;; Non pairable "test imm, reg" instructions can be translated to
20047 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20048 ;; byte opcode instead of two, have a short form for byte operands),
20049 ;; so do it for other CPUs as well. Given that the value was dead,
20050 ;; this should not create any new dependencies. Pass on the sub-word
20051 ;; versions if we're concerned about partial register stalls.
20054 [(set (match_operand 0 "flags_reg_operand" "")
20055 (match_operator 1 "compare_operator"
20056 [(and:SI (match_operand:SI 2 "register_operand" "")
20057 (match_operand:SI 3 "immediate_operand" ""))
20059 "ix86_match_ccmode (insn, CCNOmode)
20060 && (true_regnum (operands[2]) != AX_REG
20061 || satisfies_constraint_K (operands[3]))
20062 && peep2_reg_dead_p (1, operands[2])"
20064 [(set (match_dup 0)
20065 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20068 (and:SI (match_dup 2) (match_dup 3)))])]
20071 ;; We don't need to handle HImode case, because it will be promoted to SImode
20072 ;; on ! TARGET_PARTIAL_REG_STALL
20075 [(set (match_operand 0 "flags_reg_operand" "")
20076 (match_operator 1 "compare_operator"
20077 [(and:QI (match_operand:QI 2 "register_operand" "")
20078 (match_operand:QI 3 "immediate_operand" ""))
20080 "! TARGET_PARTIAL_REG_STALL
20081 && ix86_match_ccmode (insn, CCNOmode)
20082 && true_regnum (operands[2]) != AX_REG
20083 && peep2_reg_dead_p (1, operands[2])"
20085 [(set (match_dup 0)
20086 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20089 (and:QI (match_dup 2) (match_dup 3)))])]
20093 [(set (match_operand 0 "flags_reg_operand" "")
20094 (match_operator 1 "compare_operator"
20097 (match_operand 2 "ext_register_operand" "")
20100 (match_operand 3 "const_int_operand" ""))
20102 "! TARGET_PARTIAL_REG_STALL
20103 && ix86_match_ccmode (insn, CCNOmode)
20104 && true_regnum (operands[2]) != AX_REG
20105 && peep2_reg_dead_p (1, operands[2])"
20106 [(parallel [(set (match_dup 0)
20115 (set (zero_extract:SI (match_dup 2)
20126 ;; Don't do logical operations with memory inputs.
20128 [(match_scratch:SI 2 "r")
20129 (parallel [(set (match_operand:SI 0 "register_operand" "")
20130 (match_operator:SI 3 "arith_or_logical_operator"
20132 (match_operand:SI 1 "memory_operand" "")]))
20133 (clobber (reg:CC FLAGS_REG))])]
20134 "! optimize_size && ! TARGET_READ_MODIFY"
20135 [(set (match_dup 2) (match_dup 1))
20136 (parallel [(set (match_dup 0)
20137 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20138 (clobber (reg:CC FLAGS_REG))])]
20142 [(match_scratch:SI 2 "r")
20143 (parallel [(set (match_operand:SI 0 "register_operand" "")
20144 (match_operator:SI 3 "arith_or_logical_operator"
20145 [(match_operand:SI 1 "memory_operand" "")
20147 (clobber (reg:CC FLAGS_REG))])]
20148 "! optimize_size && ! TARGET_READ_MODIFY"
20149 [(set (match_dup 2) (match_dup 1))
20150 (parallel [(set (match_dup 0)
20151 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20152 (clobber (reg:CC FLAGS_REG))])]
20155 ; Don't do logical operations with memory outputs
20157 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20158 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20159 ; the same decoder scheduling characteristics as the original.
20162 [(match_scratch:SI 2 "r")
20163 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20164 (match_operator:SI 3 "arith_or_logical_operator"
20166 (match_operand:SI 1 "nonmemory_operand" "")]))
20167 (clobber (reg:CC FLAGS_REG))])]
20168 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20169 [(set (match_dup 2) (match_dup 0))
20170 (parallel [(set (match_dup 2)
20171 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20172 (clobber (reg:CC FLAGS_REG))])
20173 (set (match_dup 0) (match_dup 2))]
20177 [(match_scratch:SI 2 "r")
20178 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20179 (match_operator:SI 3 "arith_or_logical_operator"
20180 [(match_operand:SI 1 "nonmemory_operand" "")
20182 (clobber (reg:CC FLAGS_REG))])]
20183 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20184 [(set (match_dup 2) (match_dup 0))
20185 (parallel [(set (match_dup 2)
20186 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20187 (clobber (reg:CC FLAGS_REG))])
20188 (set (match_dup 0) (match_dup 2))]
20191 ;; Attempt to always use XOR for zeroing registers.
20193 [(set (match_operand 0 "register_operand" "")
20194 (match_operand 1 "const0_operand" ""))]
20195 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20196 && (! TARGET_USE_MOV0 || optimize_size)
20197 && GENERAL_REG_P (operands[0])
20198 && peep2_regno_dead_p (0, FLAGS_REG)"
20199 [(parallel [(set (match_dup 0) (const_int 0))
20200 (clobber (reg:CC FLAGS_REG))])]
20202 operands[0] = gen_lowpart (word_mode, operands[0]);
20206 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20208 "(GET_MODE (operands[0]) == QImode
20209 || GET_MODE (operands[0]) == HImode)
20210 && (! TARGET_USE_MOV0 || optimize_size)
20211 && peep2_regno_dead_p (0, FLAGS_REG)"
20212 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20213 (clobber (reg:CC FLAGS_REG))])])
20215 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20217 [(set (match_operand 0 "register_operand" "")
20219 "(GET_MODE (operands[0]) == HImode
20220 || GET_MODE (operands[0]) == SImode
20221 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20222 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20223 && peep2_regno_dead_p (0, FLAGS_REG)"
20224 [(parallel [(set (match_dup 0) (const_int -1))
20225 (clobber (reg:CC FLAGS_REG))])]
20226 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20229 ;; Attempt to convert simple leas to adds. These can be created by
20232 [(set (match_operand:SI 0 "register_operand" "")
20233 (plus:SI (match_dup 0)
20234 (match_operand:SI 1 "nonmemory_operand" "")))]
20235 "peep2_regno_dead_p (0, FLAGS_REG)"
20236 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20237 (clobber (reg:CC FLAGS_REG))])]
20241 [(set (match_operand:SI 0 "register_operand" "")
20242 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20243 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20244 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20245 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20246 (clobber (reg:CC FLAGS_REG))])]
20247 "operands[2] = gen_lowpart (SImode, operands[2]);")
20250 [(set (match_operand:DI 0 "register_operand" "")
20251 (plus:DI (match_dup 0)
20252 (match_operand:DI 1 "x86_64_general_operand" "")))]
20253 "peep2_regno_dead_p (0, FLAGS_REG)"
20254 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20255 (clobber (reg:CC FLAGS_REG))])]
20259 [(set (match_operand:SI 0 "register_operand" "")
20260 (mult:SI (match_dup 0)
20261 (match_operand:SI 1 "const_int_operand" "")))]
20262 "exact_log2 (INTVAL (operands[1])) >= 0
20263 && peep2_regno_dead_p (0, FLAGS_REG)"
20264 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20265 (clobber (reg:CC FLAGS_REG))])]
20266 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20269 [(set (match_operand:DI 0 "register_operand" "")
20270 (mult:DI (match_dup 0)
20271 (match_operand:DI 1 "const_int_operand" "")))]
20272 "exact_log2 (INTVAL (operands[1])) >= 0
20273 && peep2_regno_dead_p (0, FLAGS_REG)"
20274 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20275 (clobber (reg:CC FLAGS_REG))])]
20276 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20279 [(set (match_operand:SI 0 "register_operand" "")
20280 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20281 (match_operand:DI 2 "const_int_operand" "")) 0))]
20282 "exact_log2 (INTVAL (operands[2])) >= 0
20283 && REGNO (operands[0]) == REGNO (operands[1])
20284 && peep2_regno_dead_p (0, FLAGS_REG)"
20285 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20286 (clobber (reg:CC FLAGS_REG))])]
20287 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20289 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20290 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20291 ;; many CPUs it is also faster, since special hardware to avoid esp
20292 ;; dependencies is present.
20294 ;; While some of these conversions may be done using splitters, we use peepholes
20295 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20297 ;; Convert prologue esp subtractions to push.
20298 ;; We need register to push. In order to keep verify_flow_info happy we have
20300 ;; - use scratch and clobber it in order to avoid dependencies
20301 ;; - use already live register
20302 ;; We can't use the second way right now, since there is no reliable way how to
20303 ;; verify that given register is live. First choice will also most likely in
20304 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20305 ;; call clobbered registers are dead. We may want to use base pointer as an
20306 ;; alternative when no register is available later.
20309 [(match_scratch:SI 0 "r")
20310 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20311 (clobber (reg:CC FLAGS_REG))
20312 (clobber (mem:BLK (scratch)))])]
20313 "optimize_size || !TARGET_SUB_ESP_4"
20314 [(clobber (match_dup 0))
20315 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20316 (clobber (mem:BLK (scratch)))])])
20319 [(match_scratch:SI 0 "r")
20320 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20321 (clobber (reg:CC FLAGS_REG))
20322 (clobber (mem:BLK (scratch)))])]
20323 "optimize_size || !TARGET_SUB_ESP_8"
20324 [(clobber (match_dup 0))
20325 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20326 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20327 (clobber (mem:BLK (scratch)))])])
20329 ;; Convert esp subtractions to push.
20331 [(match_scratch:SI 0 "r")
20332 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20333 (clobber (reg:CC FLAGS_REG))])]
20334 "optimize_size || !TARGET_SUB_ESP_4"
20335 [(clobber (match_dup 0))
20336 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20339 [(match_scratch:SI 0 "r")
20340 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20341 (clobber (reg:CC FLAGS_REG))])]
20342 "optimize_size || !TARGET_SUB_ESP_8"
20343 [(clobber (match_dup 0))
20344 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20345 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20347 ;; Convert epilogue deallocator to pop.
20349 [(match_scratch:SI 0 "r")
20350 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20351 (clobber (reg:CC FLAGS_REG))
20352 (clobber (mem:BLK (scratch)))])]
20353 "optimize_size || !TARGET_ADD_ESP_4"
20354 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20355 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20356 (clobber (mem:BLK (scratch)))])]
20359 ;; Two pops case is tricky, since pop causes dependency on destination register.
20360 ;; We use two registers if available.
20362 [(match_scratch:SI 0 "r")
20363 (match_scratch:SI 1 "r")
20364 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20365 (clobber (reg:CC FLAGS_REG))
20366 (clobber (mem:BLK (scratch)))])]
20367 "optimize_size || !TARGET_ADD_ESP_8"
20368 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20369 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20370 (clobber (mem:BLK (scratch)))])
20371 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20372 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20376 [(match_scratch:SI 0 "r")
20377 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20378 (clobber (reg:CC FLAGS_REG))
20379 (clobber (mem:BLK (scratch)))])]
20381 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20382 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20383 (clobber (mem:BLK (scratch)))])
20384 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20385 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20388 ;; Convert esp additions to pop.
20390 [(match_scratch:SI 0 "r")
20391 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20392 (clobber (reg:CC FLAGS_REG))])]
20394 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20395 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20398 ;; Two pops case is tricky, since pop causes dependency on destination register.
20399 ;; We use two registers if available.
20401 [(match_scratch:SI 0 "r")
20402 (match_scratch:SI 1 "r")
20403 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20404 (clobber (reg:CC FLAGS_REG))])]
20406 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20407 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20408 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20409 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20413 [(match_scratch:SI 0 "r")
20414 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20415 (clobber (reg:CC FLAGS_REG))])]
20417 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20418 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20419 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20420 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20423 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20424 ;; required and register dies. Similarly for 128 to plus -128.
20426 [(set (match_operand 0 "flags_reg_operand" "")
20427 (match_operator 1 "compare_operator"
20428 [(match_operand 2 "register_operand" "")
20429 (match_operand 3 "const_int_operand" "")]))]
20430 "(INTVAL (operands[3]) == -1
20431 || INTVAL (operands[3]) == 1
20432 || INTVAL (operands[3]) == 128)
20433 && ix86_match_ccmode (insn, CCGCmode)
20434 && peep2_reg_dead_p (1, operands[2])"
20435 [(parallel [(set (match_dup 0)
20436 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20437 (clobber (match_dup 2))])]
20441 [(match_scratch:DI 0 "r")
20442 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20443 (clobber (reg:CC FLAGS_REG))
20444 (clobber (mem:BLK (scratch)))])]
20445 "optimize_size || !TARGET_SUB_ESP_4"
20446 [(clobber (match_dup 0))
20447 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20448 (clobber (mem:BLK (scratch)))])])
20451 [(match_scratch:DI 0 "r")
20452 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20453 (clobber (reg:CC FLAGS_REG))
20454 (clobber (mem:BLK (scratch)))])]
20455 "optimize_size || !TARGET_SUB_ESP_8"
20456 [(clobber (match_dup 0))
20457 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20458 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20459 (clobber (mem:BLK (scratch)))])])
20461 ;; Convert esp subtractions to push.
20463 [(match_scratch:DI 0 "r")
20464 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20465 (clobber (reg:CC FLAGS_REG))])]
20466 "optimize_size || !TARGET_SUB_ESP_4"
20467 [(clobber (match_dup 0))
20468 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20471 [(match_scratch:DI 0 "r")
20472 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20473 (clobber (reg:CC FLAGS_REG))])]
20474 "optimize_size || !TARGET_SUB_ESP_8"
20475 [(clobber (match_dup 0))
20476 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20477 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20479 ;; Convert epilogue deallocator to pop.
20481 [(match_scratch:DI 0 "r")
20482 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20483 (clobber (reg:CC FLAGS_REG))
20484 (clobber (mem:BLK (scratch)))])]
20485 "optimize_size || !TARGET_ADD_ESP_4"
20486 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20487 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20488 (clobber (mem:BLK (scratch)))])]
20491 ;; Two pops case is tricky, since pop causes dependency on destination register.
20492 ;; We use two registers if available.
20494 [(match_scratch:DI 0 "r")
20495 (match_scratch:DI 1 "r")
20496 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20497 (clobber (reg:CC FLAGS_REG))
20498 (clobber (mem:BLK (scratch)))])]
20499 "optimize_size || !TARGET_ADD_ESP_8"
20500 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20501 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20502 (clobber (mem:BLK (scratch)))])
20503 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20504 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20508 [(match_scratch:DI 0 "r")
20509 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20510 (clobber (reg:CC FLAGS_REG))
20511 (clobber (mem:BLK (scratch)))])]
20513 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20514 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20515 (clobber (mem:BLK (scratch)))])
20516 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20517 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20520 ;; Convert esp additions to pop.
20522 [(match_scratch:DI 0 "r")
20523 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20524 (clobber (reg:CC FLAGS_REG))])]
20526 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20527 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20530 ;; Two pops case is tricky, since pop causes dependency on destination register.
20531 ;; We use two registers if available.
20533 [(match_scratch:DI 0 "r")
20534 (match_scratch:DI 1 "r")
20535 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20536 (clobber (reg:CC FLAGS_REG))])]
20538 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20539 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20540 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20541 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20545 [(match_scratch:DI 0 "r")
20546 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20547 (clobber (reg:CC FLAGS_REG))])]
20549 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20550 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20551 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20552 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20555 ;; Convert imul by three, five and nine into lea
20558 [(set (match_operand:SI 0 "register_operand" "")
20559 (mult:SI (match_operand:SI 1 "register_operand" "")
20560 (match_operand:SI 2 "const_int_operand" "")))
20561 (clobber (reg:CC FLAGS_REG))])]
20562 "INTVAL (operands[2]) == 3
20563 || INTVAL (operands[2]) == 5
20564 || INTVAL (operands[2]) == 9"
20565 [(set (match_dup 0)
20566 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20568 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20572 [(set (match_operand:SI 0 "register_operand" "")
20573 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20574 (match_operand:SI 2 "const_int_operand" "")))
20575 (clobber (reg:CC FLAGS_REG))])]
20577 && (INTVAL (operands[2]) == 3
20578 || INTVAL (operands[2]) == 5
20579 || INTVAL (operands[2]) == 9)"
20580 [(set (match_dup 0) (match_dup 1))
20582 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20584 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20588 [(set (match_operand:DI 0 "register_operand" "")
20589 (mult:DI (match_operand:DI 1 "register_operand" "")
20590 (match_operand:DI 2 "const_int_operand" "")))
20591 (clobber (reg:CC FLAGS_REG))])]
20593 && (INTVAL (operands[2]) == 3
20594 || INTVAL (operands[2]) == 5
20595 || INTVAL (operands[2]) == 9)"
20596 [(set (match_dup 0)
20597 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20599 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20603 [(set (match_operand:DI 0 "register_operand" "")
20604 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20605 (match_operand:DI 2 "const_int_operand" "")))
20606 (clobber (reg:CC FLAGS_REG))])]
20609 && (INTVAL (operands[2]) == 3
20610 || INTVAL (operands[2]) == 5
20611 || INTVAL (operands[2]) == 9)"
20612 [(set (match_dup 0) (match_dup 1))
20614 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20616 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20618 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20619 ;; imul $32bit_imm, reg, reg is direct decoded.
20621 [(match_scratch:DI 3 "r")
20622 (parallel [(set (match_operand:DI 0 "register_operand" "")
20623 (mult:DI (match_operand:DI 1 "memory_operand" "")
20624 (match_operand:DI 2 "immediate_operand" "")))
20625 (clobber (reg:CC FLAGS_REG))])]
20626 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20627 && !satisfies_constraint_K (operands[2])"
20628 [(set (match_dup 3) (match_dup 1))
20629 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20630 (clobber (reg:CC FLAGS_REG))])]
20634 [(match_scratch:SI 3 "r")
20635 (parallel [(set (match_operand:SI 0 "register_operand" "")
20636 (mult:SI (match_operand:SI 1 "memory_operand" "")
20637 (match_operand:SI 2 "immediate_operand" "")))
20638 (clobber (reg:CC FLAGS_REG))])]
20639 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20640 && !satisfies_constraint_K (operands[2])"
20641 [(set (match_dup 3) (match_dup 1))
20642 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20643 (clobber (reg:CC FLAGS_REG))])]
20647 [(match_scratch:SI 3 "r")
20648 (parallel [(set (match_operand:DI 0 "register_operand" "")
20650 (mult:SI (match_operand:SI 1 "memory_operand" "")
20651 (match_operand:SI 2 "immediate_operand" ""))))
20652 (clobber (reg:CC FLAGS_REG))])]
20653 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20654 && !satisfies_constraint_K (operands[2])"
20655 [(set (match_dup 3) (match_dup 1))
20656 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20657 (clobber (reg:CC FLAGS_REG))])]
20660 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20661 ;; Convert it into imul reg, reg
20662 ;; It would be better to force assembler to encode instruction using long
20663 ;; immediate, but there is apparently no way to do so.
20665 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20666 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20667 (match_operand:DI 2 "const_int_operand" "")))
20668 (clobber (reg:CC FLAGS_REG))])
20669 (match_scratch:DI 3 "r")]
20670 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20671 && satisfies_constraint_K (operands[2])"
20672 [(set (match_dup 3) (match_dup 2))
20673 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20674 (clobber (reg:CC FLAGS_REG))])]
20676 if (!rtx_equal_p (operands[0], operands[1]))
20677 emit_move_insn (operands[0], operands[1]);
20681 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20682 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20683 (match_operand:SI 2 "const_int_operand" "")))
20684 (clobber (reg:CC FLAGS_REG))])
20685 (match_scratch:SI 3 "r")]
20686 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20687 && satisfies_constraint_K (operands[2])"
20688 [(set (match_dup 3) (match_dup 2))
20689 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20690 (clobber (reg:CC FLAGS_REG))])]
20692 if (!rtx_equal_p (operands[0], operands[1]))
20693 emit_move_insn (operands[0], operands[1]);
20697 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20698 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20699 (match_operand:HI 2 "immediate_operand" "")))
20700 (clobber (reg:CC FLAGS_REG))])
20701 (match_scratch:HI 3 "r")]
20702 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20703 [(set (match_dup 3) (match_dup 2))
20704 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20705 (clobber (reg:CC FLAGS_REG))])]
20707 if (!rtx_equal_p (operands[0], operands[1]))
20708 emit_move_insn (operands[0], operands[1]);
20711 ;; After splitting up read-modify operations, array accesses with memory
20712 ;; operands might end up in form:
20714 ;; movl 4(%esp), %edx
20716 ;; instead of pre-splitting:
20718 ;; addl 4(%esp), %eax
20720 ;; movl 4(%esp), %edx
20721 ;; leal (%edx,%eax,4), %eax
20724 [(parallel [(set (match_operand 0 "register_operand" "")
20725 (ashift (match_operand 1 "register_operand" "")
20726 (match_operand 2 "const_int_operand" "")))
20727 (clobber (reg:CC FLAGS_REG))])
20728 (set (match_operand 3 "register_operand")
20729 (match_operand 4 "x86_64_general_operand" ""))
20730 (parallel [(set (match_operand 5 "register_operand" "")
20731 (plus (match_operand 6 "register_operand" "")
20732 (match_operand 7 "register_operand" "")))
20733 (clobber (reg:CC FLAGS_REG))])]
20734 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20735 /* Validate MODE for lea. */
20736 && ((!TARGET_PARTIAL_REG_STALL
20737 && (GET_MODE (operands[0]) == QImode
20738 || GET_MODE (operands[0]) == HImode))
20739 || GET_MODE (operands[0]) == SImode
20740 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20741 /* We reorder load and the shift. */
20742 && !rtx_equal_p (operands[1], operands[3])
20743 && !reg_overlap_mentioned_p (operands[0], operands[4])
20744 /* Last PLUS must consist of operand 0 and 3. */
20745 && !rtx_equal_p (operands[0], operands[3])
20746 && (rtx_equal_p (operands[3], operands[6])
20747 || rtx_equal_p (operands[3], operands[7]))
20748 && (rtx_equal_p (operands[0], operands[6])
20749 || rtx_equal_p (operands[0], operands[7]))
20750 /* The intermediate operand 0 must die or be same as output. */
20751 && (rtx_equal_p (operands[0], operands[5])
20752 || peep2_reg_dead_p (3, operands[0]))"
20753 [(set (match_dup 3) (match_dup 4))
20754 (set (match_dup 0) (match_dup 1))]
20756 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20757 int scale = 1 << INTVAL (operands[2]);
20758 rtx index = gen_lowpart (Pmode, operands[1]);
20759 rtx base = gen_lowpart (Pmode, operands[3]);
20760 rtx dest = gen_lowpart (mode, operands[5]);
20762 operands[1] = gen_rtx_PLUS (Pmode, base,
20763 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20765 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20766 operands[0] = dest;
20769 ;; Call-value patterns last so that the wildcard operand does not
20770 ;; disrupt insn-recog's switch tables.
20772 (define_insn "*call_value_pop_0"
20773 [(set (match_operand 0 "" "")
20774 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20775 (match_operand:SI 2 "" "")))
20776 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20777 (match_operand:SI 3 "immediate_operand" "")))]
20780 if (SIBLING_CALL_P (insn))
20783 return "call\t%P1";
20785 [(set_attr "type" "callv")])
20787 (define_insn "*call_value_pop_1"
20788 [(set (match_operand 0 "" "")
20789 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20790 (match_operand:SI 2 "" "")))
20791 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20792 (match_operand:SI 3 "immediate_operand" "i")))]
20795 if (constant_call_address_operand (operands[1], Pmode))
20797 if (SIBLING_CALL_P (insn))
20800 return "call\t%P1";
20802 if (SIBLING_CALL_P (insn))
20805 return "call\t%A1";
20807 [(set_attr "type" "callv")])
20809 (define_insn "*call_value_0"
20810 [(set (match_operand 0 "" "")
20811 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20812 (match_operand:SI 2 "" "")))]
20815 if (SIBLING_CALL_P (insn))
20818 return "call\t%P1";
20820 [(set_attr "type" "callv")])
20822 (define_insn "*call_value_0_rex64"
20823 [(set (match_operand 0 "" "")
20824 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20825 (match_operand:DI 2 "const_int_operand" "")))]
20828 if (SIBLING_CALL_P (insn))
20831 return "call\t%P1";
20833 [(set_attr "type" "callv")])
20835 (define_insn "*call_value_1"
20836 [(set (match_operand 0 "" "")
20837 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20838 (match_operand:SI 2 "" "")))]
20839 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20841 if (constant_call_address_operand (operands[1], Pmode))
20842 return "call\t%P1";
20843 return "call\t%A1";
20845 [(set_attr "type" "callv")])
20847 (define_insn "*sibcall_value_1"
20848 [(set (match_operand 0 "" "")
20849 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20850 (match_operand:SI 2 "" "")))]
20851 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20853 if (constant_call_address_operand (operands[1], Pmode))
20857 [(set_attr "type" "callv")])
20859 (define_insn "*call_value_1_rex64"
20860 [(set (match_operand 0 "" "")
20861 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20862 (match_operand:DI 2 "" "")))]
20863 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20864 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20866 if (constant_call_address_operand (operands[1], Pmode))
20867 return "call\t%P1";
20868 return "call\t%A1";
20870 [(set_attr "type" "callv")])
20872 (define_insn "*call_value_1_rex64_large"
20873 [(set (match_operand 0 "" "")
20874 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20875 (match_operand:DI 2 "" "")))]
20876 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20878 [(set_attr "type" "callv")])
20880 (define_insn "*sibcall_value_1_rex64"
20881 [(set (match_operand 0 "" "")
20882 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20883 (match_operand:DI 2 "" "")))]
20884 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20886 [(set_attr "type" "callv")])
20888 (define_insn "*sibcall_value_1_rex64_v"
20889 [(set (match_operand 0 "" "")
20890 (call (mem:QI (reg:DI R11_REG))
20891 (match_operand:DI 1 "" "")))]
20892 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20894 [(set_attr "type" "callv")])
20896 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20897 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20898 ;; caught for use by garbage collectors and the like. Using an insn that
20899 ;; maps to SIGILL makes it more likely the program will rightfully die.
20900 ;; Keeping with tradition, "6" is in honor of #UD.
20901 (define_insn "trap"
20902 [(trap_if (const_int 1) (const_int 6))]
20904 { return ASM_SHORT "0x0b0f"; }
20905 [(set_attr "length" "2")])
20907 (define_expand "sse_prologue_save"
20908 [(parallel [(set (match_operand:BLK 0 "" "")
20909 (unspec:BLK [(reg:DI 21)
20916 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20917 (use (match_operand:DI 1 "register_operand" ""))
20918 (use (match_operand:DI 2 "immediate_operand" ""))
20919 (use (label_ref:DI (match_operand 3 "" "")))])]
20923 (define_insn "*sse_prologue_save_insn"
20924 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20925 (match_operand:DI 4 "const_int_operand" "n")))
20926 (unspec:BLK [(reg:DI 21)
20933 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20934 (use (match_operand:DI 1 "register_operand" "r"))
20935 (use (match_operand:DI 2 "const_int_operand" "i"))
20936 (use (label_ref:DI (match_operand 3 "" "X")))]
20938 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20939 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20943 operands[0] = gen_rtx_MEM (Pmode,
20944 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20945 output_asm_insn (\"jmp\\t%A1\", operands);
20946 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20948 operands[4] = adjust_address (operands[0], DImode, i*16);
20949 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20950 PUT_MODE (operands[4], TImode);
20951 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20952 output_asm_insn (\"rex\", operands);
20953 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20955 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20956 CODE_LABEL_NUMBER (operands[3]));
20960 [(set_attr "type" "other")
20961 (set_attr "length_immediate" "0")
20962 (set_attr "length_address" "0")
20963 (set_attr "length" "135")
20964 (set_attr "memory" "store")
20965 (set_attr "modrm" "0")
20966 (set_attr "mode" "DI")])
20968 (define_expand "prefetch"
20969 [(prefetch (match_operand 0 "address_operand" "")
20970 (match_operand:SI 1 "const_int_operand" "")
20971 (match_operand:SI 2 "const_int_operand" ""))]
20972 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20974 int rw = INTVAL (operands[1]);
20975 int locality = INTVAL (operands[2]);
20977 gcc_assert (rw == 0 || rw == 1);
20978 gcc_assert (locality >= 0 && locality <= 3);
20979 gcc_assert (GET_MODE (operands[0]) == Pmode
20980 || GET_MODE (operands[0]) == VOIDmode);
20982 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20983 supported by SSE counterpart or the SSE prefetch is not available
20984 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20986 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20987 operands[2] = GEN_INT (3);
20989 operands[1] = const0_rtx;
20992 (define_insn "*prefetch_sse"
20993 [(prefetch (match_operand:SI 0 "address_operand" "p")
20995 (match_operand:SI 1 "const_int_operand" ""))]
20996 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20998 static const char * const patterns[4] = {
20999 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21002 int locality = INTVAL (operands[1]);
21003 gcc_assert (locality >= 0 && locality <= 3);
21005 return patterns[locality];
21007 [(set_attr "type" "sse")
21008 (set_attr "memory" "none")])
21010 (define_insn "*prefetch_sse_rex"
21011 [(prefetch (match_operand:DI 0 "address_operand" "p")
21013 (match_operand:SI 1 "const_int_operand" ""))]
21014 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21016 static const char * const patterns[4] = {
21017 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21020 int locality = INTVAL (operands[1]);
21021 gcc_assert (locality >= 0 && locality <= 3);
21023 return patterns[locality];
21025 [(set_attr "type" "sse")
21026 (set_attr "memory" "none")])
21028 (define_insn "*prefetch_3dnow"
21029 [(prefetch (match_operand:SI 0 "address_operand" "p")
21030 (match_operand:SI 1 "const_int_operand" "n")
21032 "TARGET_3DNOW && !TARGET_64BIT"
21034 if (INTVAL (operands[1]) == 0)
21035 return "prefetch\t%a0";
21037 return "prefetchw\t%a0";
21039 [(set_attr "type" "mmx")
21040 (set_attr "memory" "none")])
21042 (define_insn "*prefetch_3dnow_rex"
21043 [(prefetch (match_operand:DI 0 "address_operand" "p")
21044 (match_operand:SI 1 "const_int_operand" "n")
21046 "TARGET_3DNOW && TARGET_64BIT"
21048 if (INTVAL (operands[1]) == 0)
21049 return "prefetch\t%a0";
21051 return "prefetchw\t%a0";
21053 [(set_attr "type" "mmx")
21054 (set_attr "memory" "none")])
21056 (define_expand "stack_protect_set"
21057 [(match_operand 0 "memory_operand" "")
21058 (match_operand 1 "memory_operand" "")]
21061 #ifdef TARGET_THREAD_SSP_OFFSET
21063 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21064 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21066 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21067 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21070 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21072 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21077 (define_insn "stack_protect_set_si"
21078 [(set (match_operand:SI 0 "memory_operand" "=m")
21079 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21080 (set (match_scratch:SI 2 "=&r") (const_int 0))
21081 (clobber (reg:CC FLAGS_REG))]
21083 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21084 [(set_attr "type" "multi")])
21086 (define_insn "stack_protect_set_di"
21087 [(set (match_operand:DI 0 "memory_operand" "=m")
21088 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21089 (set (match_scratch:DI 2 "=&r") (const_int 0))
21090 (clobber (reg:CC FLAGS_REG))]
21092 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21093 [(set_attr "type" "multi")])
21095 (define_insn "stack_tls_protect_set_si"
21096 [(set (match_operand:SI 0 "memory_operand" "=m")
21097 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21098 (set (match_scratch:SI 2 "=&r") (const_int 0))
21099 (clobber (reg:CC FLAGS_REG))]
21101 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21102 [(set_attr "type" "multi")])
21104 (define_insn "stack_tls_protect_set_di"
21105 [(set (match_operand:DI 0 "memory_operand" "=m")
21106 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21107 (set (match_scratch:DI 2 "=&r") (const_int 0))
21108 (clobber (reg:CC FLAGS_REG))]
21111 /* The kernel uses a different segment register for performance reasons; a
21112 system call would not have to trash the userspace segment register,
21113 which would be expensive */
21114 if (ix86_cmodel != CM_KERNEL)
21115 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21117 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21119 [(set_attr "type" "multi")])
21121 (define_expand "stack_protect_test"
21122 [(match_operand 0 "memory_operand" "")
21123 (match_operand 1 "memory_operand" "")
21124 (match_operand 2 "" "")]
21127 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21128 ix86_compare_op0 = operands[0];
21129 ix86_compare_op1 = operands[1];
21130 ix86_compare_emitted = flags;
21132 #ifdef TARGET_THREAD_SSP_OFFSET
21134 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21135 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21137 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21138 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21141 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21143 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21145 emit_jump_insn (gen_beq (operands[2]));
21149 (define_insn "stack_protect_test_si"
21150 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21151 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21152 (match_operand:SI 2 "memory_operand" "m")]
21154 (clobber (match_scratch:SI 3 "=&r"))]
21156 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21157 [(set_attr "type" "multi")])
21159 (define_insn "stack_protect_test_di"
21160 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21161 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21162 (match_operand:DI 2 "memory_operand" "m")]
21164 (clobber (match_scratch:DI 3 "=&r"))]
21166 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21167 [(set_attr "type" "multi")])
21169 (define_insn "stack_tls_protect_test_si"
21170 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21171 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21172 (match_operand:SI 2 "const_int_operand" "i")]
21173 UNSPEC_SP_TLS_TEST))
21174 (clobber (match_scratch:SI 3 "=r"))]
21176 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21177 [(set_attr "type" "multi")])
21179 (define_insn "stack_tls_protect_test_di"
21180 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21181 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21182 (match_operand:DI 2 "const_int_operand" "i")]
21183 UNSPEC_SP_TLS_TEST))
21184 (clobber (match_scratch:DI 3 "=r"))]
21187 /* The kernel uses a different segment register for performance reasons; a
21188 system call would not have to trash the userspace segment register,
21189 which would be expensive */
21190 if (ix86_cmodel != CM_KERNEL)
21191 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21193 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21195 [(set_attr "type" "multi")])
21197 (define_mode_iterator CRC32MODE [QI HI SI])
21198 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21199 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21201 (define_insn "sse4_2_crc32<mode>"
21202 [(set (match_operand:SI 0 "register_operand" "=r")
21204 [(match_operand:SI 1 "register_operand" "0")
21205 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21208 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21209 [(set_attr "type" "sselog1")
21210 (set_attr "prefix_rep" "1")
21211 (set_attr "prefix_extra" "1")
21212 (set_attr "mode" "SI")])
21214 (define_insn "sse4_2_crc32di"
21215 [(set (match_operand:DI 0 "register_operand" "=r")
21217 [(match_operand:DI 1 "register_operand" "0")
21218 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21220 "TARGET_SSE4_2 && TARGET_64BIT"
21221 "crc32q\t{%2, %0|%0, %2}"
21222 [(set_attr "type" "sselog1")
21223 (set_attr "prefix_rep" "1")
21224 (set_attr "prefix_extra" "1")
21225 (set_attr "mode" "DI")])
21229 (include "sync.md")