1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 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)
98 (UNSPEC_NOP 48) ; prevents combiner cleverness
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
127 (UNSPEC_FRNDINT_FLOOR 70)
128 (UNSPEC_FRNDINT_CEIL 71)
129 (UNSPEC_FRNDINT_TRUNC 72)
130 (UNSPEC_FRNDINT_MASK_PM 73)
131 (UNSPEC_FIST_FLOOR 74)
132 (UNSPEC_FIST_CEIL 75)
134 ; x87 Double output FP
135 (UNSPEC_SINCOS_COS 80)
136 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
151 (UNSPEC_SP_TLS_SET 102)
152 (UNSPEC_SP_TLS_TEST 103)
162 (UNSPEC_INSERTQI 132)
167 (UNSPEC_INSERTPS 135)
169 (UNSPEC_MOVNTDQA 137)
171 (UNSPEC_PHMINPOSUW 139)
177 (UNSPEC_PCMPESTR 144)
178 (UNSPEC_PCMPISTR 145)
181 (UNSPEC_SSE5_INTRINSIC 150)
182 (UNSPEC_SSE5_UNSIGNED_CMP 151)
183 (UNSPEC_SSE5_TRUEFALSE 152)
184 (UNSPEC_SSE5_PERMUTE 153)
185 (UNSPEC_SSE5_ASHIFT 154)
186 (UNSPEC_SSE5_LSHIFT 155)
188 (UNSPEC_CVTPH2PS 157)
189 (UNSPEC_CVTPS2PH 158)
193 [(UNSPECV_BLOCKAGE 0)
194 (UNSPECV_STACK_PROBE 1)
203 (UNSPECV_CMPXCHG_1 10)
204 (UNSPECV_CMPXCHG_2 11)
207 (UNSPECV_PROLOGUE_USE 14)
210 ;; Constants to represent pcomtrue/pcomfalse varients
220 ;; Registers by name.
231 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
234 ;; In C guard expressions, put expressions which may be compile-time
235 ;; constants first. This allows for better optimization. For
236 ;; example, write "TARGET_64BIT && reload_completed", not
237 ;; "reload_completed && TARGET_64BIT".
240 ;; Processor type. This attribute must exactly match the processor_type
241 ;; enumeration in i386.h.
242 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
243 nocona,core2,generic32,generic64,amdfam10"
244 (const (symbol_ref "ix86_tune")))
246 ;; A basic instruction type. Refinements due to arguments to be
247 ;; provided in other attributes.
250 alu,alu1,negnot,imov,imovx,lea,
251 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
252 icmp,test,ibr,setcc,icmov,
253 push,pop,call,callv,leave,
255 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
256 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
257 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
259 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
260 (const_string "other"))
262 ;; Main data type used by the insn
264 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
265 (const_string "unknown"))
267 ;; The CPU unit operations uses.
268 (define_attr "unit" "integer,i387,sse,mmx,unknown"
269 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
270 (const_string "i387")
271 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
272 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
273 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
275 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
277 (eq_attr "type" "other")
278 (const_string "unknown")]
279 (const_string "integer")))
281 ;; The (bounding maximum) length of an instruction immediate.
282 (define_attr "length_immediate" ""
283 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
286 (eq_attr "unit" "i387,sse,mmx")
288 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
290 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
291 (eq_attr "type" "imov,test")
292 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
293 (eq_attr "type" "call")
294 (if_then_else (match_operand 0 "constant_call_address_operand" "")
297 (eq_attr "type" "callv")
298 (if_then_else (match_operand 1 "constant_call_address_operand" "")
301 ;; We don't know the size before shorten_branches. Expect
302 ;; the instruction to fit for better scheduling.
303 (eq_attr "type" "ibr")
306 (symbol_ref "/* Update immediate_length and other attributes! */
307 gcc_unreachable (),1")))
309 ;; The (bounding maximum) length of an instruction address.
310 (define_attr "length_address" ""
311 (cond [(eq_attr "type" "str,other,multi,fxch")
313 (and (eq_attr "type" "call")
314 (match_operand 0 "constant_call_address_operand" ""))
316 (and (eq_attr "type" "callv")
317 (match_operand 1 "constant_call_address_operand" ""))
320 (symbol_ref "ix86_attr_length_address_default (insn)")))
322 ;; Set when length prefix is used.
323 (define_attr "prefix_data16" ""
324 (if_then_else (ior (eq_attr "mode" "HI")
325 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
329 ;; Set when string REP prefix is used.
330 (define_attr "prefix_rep" ""
331 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
335 ;; Set when 0f opcode prefix is used.
336 (define_attr "prefix_0f" ""
338 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
339 (eq_attr "unit" "sse,mmx"))
343 ;; Set when REX opcode prefix is used.
344 (define_attr "prefix_rex" ""
345 (cond [(and (eq_attr "mode" "DI")
346 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
348 (and (eq_attr "mode" "QI")
349 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
352 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
358 ;; There are also additional prefixes in SSSE3.
359 (define_attr "prefix_extra" "" (const_int 0))
361 ;; Set when modrm byte is used.
362 (define_attr "modrm" ""
363 (cond [(eq_attr "type" "str,leave")
365 (eq_attr "unit" "i387")
367 (and (eq_attr "type" "incdec")
368 (ior (match_operand:SI 1 "register_operand" "")
369 (match_operand:HI 1 "register_operand" "")))
371 (and (eq_attr "type" "push")
372 (not (match_operand 1 "memory_operand" "")))
374 (and (eq_attr "type" "pop")
375 (not (match_operand 0 "memory_operand" "")))
377 (and (eq_attr "type" "imov")
378 (ior (and (match_operand 0 "register_operand" "")
379 (match_operand 1 "immediate_operand" ""))
380 (ior (and (match_operand 0 "ax_reg_operand" "")
381 (match_operand 1 "memory_displacement_only_operand" ""))
382 (and (match_operand 0 "memory_displacement_only_operand" "")
383 (match_operand 1 "ax_reg_operand" "")))))
385 (and (eq_attr "type" "call")
386 (match_operand 0 "constant_call_address_operand" ""))
388 (and (eq_attr "type" "callv")
389 (match_operand 1 "constant_call_address_operand" ""))
394 ;; The (bounding maximum) length of an instruction in bytes.
395 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
396 ;; Later we may want to split them and compute proper length as for
398 (define_attr "length" ""
399 (cond [(eq_attr "type" "other,multi,fistp,frndint")
401 (eq_attr "type" "fcmp")
403 (eq_attr "unit" "i387")
405 (plus (attr "prefix_data16")
406 (attr "length_address")))]
407 (plus (plus (attr "modrm")
408 (plus (attr "prefix_0f")
409 (plus (attr "prefix_rex")
410 (plus (attr "prefix_extra")
412 (plus (attr "prefix_rep")
413 (plus (attr "prefix_data16")
414 (plus (attr "length_immediate")
415 (attr "length_address")))))))
417 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
418 ;; `store' if there is a simple memory reference therein, or `unknown'
419 ;; if the instruction is complex.
421 (define_attr "memory" "none,load,store,both,unknown"
422 (cond [(eq_attr "type" "other,multi,str")
423 (const_string "unknown")
424 (eq_attr "type" "lea,fcmov,fpspc")
425 (const_string "none")
426 (eq_attr "type" "fistp,leave")
427 (const_string "both")
428 (eq_attr "type" "frndint")
429 (const_string "load")
430 (eq_attr "type" "push")
431 (if_then_else (match_operand 1 "memory_operand" "")
432 (const_string "both")
433 (const_string "store"))
434 (eq_attr "type" "pop")
435 (if_then_else (match_operand 0 "memory_operand" "")
436 (const_string "both")
437 (const_string "load"))
438 (eq_attr "type" "setcc")
439 (if_then_else (match_operand 0 "memory_operand" "")
440 (const_string "store")
441 (const_string "none"))
442 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
443 (if_then_else (ior (match_operand 0 "memory_operand" "")
444 (match_operand 1 "memory_operand" ""))
445 (const_string "load")
446 (const_string "none"))
447 (eq_attr "type" "ibr")
448 (if_then_else (match_operand 0 "memory_operand" "")
449 (const_string "load")
450 (const_string "none"))
451 (eq_attr "type" "call")
452 (if_then_else (match_operand 0 "constant_call_address_operand" "")
453 (const_string "none")
454 (const_string "load"))
455 (eq_attr "type" "callv")
456 (if_then_else (match_operand 1 "constant_call_address_operand" "")
457 (const_string "none")
458 (const_string "load"))
459 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
460 (match_operand 1 "memory_operand" ""))
461 (const_string "both")
462 (and (match_operand 0 "memory_operand" "")
463 (match_operand 1 "memory_operand" ""))
464 (const_string "both")
465 (match_operand 0 "memory_operand" "")
466 (const_string "store")
467 (match_operand 1 "memory_operand" "")
468 (const_string "load")
470 "!alu1,negnot,ishift1,
471 imov,imovx,icmp,test,bitmanip,
473 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
474 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
475 (match_operand 2 "memory_operand" ""))
476 (const_string "load")
477 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
478 (match_operand 3 "memory_operand" ""))
479 (const_string "load")
481 (const_string "none")))
483 ;; Indicates if an instruction has both an immediate and a displacement.
485 (define_attr "imm_disp" "false,true,unknown"
486 (cond [(eq_attr "type" "other,multi")
487 (const_string "unknown")
488 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
489 (and (match_operand 0 "memory_displacement_operand" "")
490 (match_operand 1 "immediate_operand" "")))
491 (const_string "true")
492 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
493 (and (match_operand 0 "memory_displacement_operand" "")
494 (match_operand 2 "immediate_operand" "")))
495 (const_string "true")
497 (const_string "false")))
499 ;; Indicates if an FP operation has an integer source.
501 (define_attr "fp_int_src" "false,true"
502 (const_string "false"))
504 ;; Defines rounding mode of an FP operation.
506 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
507 (const_string "any"))
509 ;; Describe a user's asm statement.
510 (define_asm_attributes
511 [(set_attr "length" "128")
512 (set_attr "type" "multi")])
514 (define_code_iterator plusminus [plus minus])
516 ;; Base name for define_insn and insn mnemonic.
517 (define_code_attr addsub [(plus "add") (minus "sub")])
519 ;; Mark commutative operators as such in constraints.
520 (define_code_attr comm [(plus "%") (minus "")])
522 ;; All single word integer modes.
523 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
525 ;; Instruction suffix for integer modes.
526 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
528 ;; Register class for integer modes.
529 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
531 ;; Immediate operand constraint for integer modes.
532 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
534 ;; General operand predicate for integer modes.
535 (define_mode_attr general_operand
536 [(QI "general_operand")
537 (HI "general_operand")
538 (SI "general_operand")
539 (DI "x86_64_general_operand")])
541 ;; SSE and x87 SFmode and DFmode floating point modes
542 (define_mode_iterator MODEF [SF DF])
544 ;; All x87 floating point modes
545 (define_mode_iterator X87MODEF [SF DF XF])
547 ;; All integer modes handled by x87 fisttp operator.
548 (define_mode_iterator X87MODEI [HI SI DI])
550 ;; All integer modes handled by integer x87 operators.
551 (define_mode_iterator X87MODEI12 [HI SI])
553 ;; All integer modes handled by SSE cvtts?2si* operators.
554 (define_mode_iterator SSEMODEI24 [SI DI])
556 ;; SSE asm suffix for floating point modes
557 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
559 ;; SSE vector mode corresponding to a scalar mode
560 (define_mode_attr ssevecmode
561 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
563 ;; Scheduling descriptions
565 (include "pentium.md")
568 (include "athlon.md")
572 ;; Operand and operator predicates and constraints
574 (include "predicates.md")
575 (include "constraints.md")
578 ;; Compare instructions.
580 ;; All compare insns have expanders that save the operands away without
581 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
582 ;; after the cmp) will actually emit the cmpM.
584 (define_expand "cmpti"
585 [(set (reg:CC FLAGS_REG)
586 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
587 (match_operand:TI 1 "x86_64_general_operand" "")))]
590 if (MEM_P (operands[0]) && MEM_P (operands[1]))
591 operands[0] = force_reg (TImode, operands[0]);
592 ix86_compare_op0 = operands[0];
593 ix86_compare_op1 = operands[1];
597 (define_expand "cmpdi"
598 [(set (reg:CC FLAGS_REG)
599 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
600 (match_operand:DI 1 "x86_64_general_operand" "")))]
603 if (MEM_P (operands[0]) && MEM_P (operands[1]))
604 operands[0] = force_reg (DImode, operands[0]);
605 ix86_compare_op0 = operands[0];
606 ix86_compare_op1 = operands[1];
610 (define_expand "cmpsi"
611 [(set (reg:CC FLAGS_REG)
612 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
613 (match_operand:SI 1 "general_operand" "")))]
616 if (MEM_P (operands[0]) && MEM_P (operands[1]))
617 operands[0] = force_reg (SImode, operands[0]);
618 ix86_compare_op0 = operands[0];
619 ix86_compare_op1 = operands[1];
623 (define_expand "cmphi"
624 [(set (reg:CC FLAGS_REG)
625 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
626 (match_operand:HI 1 "general_operand" "")))]
629 if (MEM_P (operands[0]) && MEM_P (operands[1]))
630 operands[0] = force_reg (HImode, operands[0]);
631 ix86_compare_op0 = operands[0];
632 ix86_compare_op1 = operands[1];
636 (define_expand "cmpqi"
637 [(set (reg:CC FLAGS_REG)
638 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
639 (match_operand:QI 1 "general_operand" "")))]
642 if (MEM_P (operands[0]) && MEM_P (operands[1]))
643 operands[0] = force_reg (QImode, operands[0]);
644 ix86_compare_op0 = operands[0];
645 ix86_compare_op1 = operands[1];
649 (define_insn "cmpdi_ccno_1_rex64"
650 [(set (reg FLAGS_REG)
651 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
652 (match_operand:DI 1 "const0_operand" "n,n")))]
653 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
656 cmp{q}\t{%1, %0|%0, %1}"
657 [(set_attr "type" "test,icmp")
658 (set_attr "length_immediate" "0,1")
659 (set_attr "mode" "DI")])
661 (define_insn "*cmpdi_minus_1_rex64"
662 [(set (reg FLAGS_REG)
663 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
664 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
666 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
667 "cmp{q}\t{%1, %0|%0, %1}"
668 [(set_attr "type" "icmp")
669 (set_attr "mode" "DI")])
671 (define_expand "cmpdi_1_rex64"
672 [(set (reg:CC FLAGS_REG)
673 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
674 (match_operand:DI 1 "general_operand" "")))]
678 (define_insn "cmpdi_1_insn_rex64"
679 [(set (reg FLAGS_REG)
680 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
681 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
682 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
683 "cmp{q}\t{%1, %0|%0, %1}"
684 [(set_attr "type" "icmp")
685 (set_attr "mode" "DI")])
688 (define_insn "*cmpsi_ccno_1"
689 [(set (reg FLAGS_REG)
690 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
691 (match_operand:SI 1 "const0_operand" "n,n")))]
692 "ix86_match_ccmode (insn, CCNOmode)"
695 cmp{l}\t{%1, %0|%0, %1}"
696 [(set_attr "type" "test,icmp")
697 (set_attr "length_immediate" "0,1")
698 (set_attr "mode" "SI")])
700 (define_insn "*cmpsi_minus_1"
701 [(set (reg FLAGS_REG)
702 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
703 (match_operand:SI 1 "general_operand" "ri,mr"))
705 "ix86_match_ccmode (insn, CCGOCmode)"
706 "cmp{l}\t{%1, %0|%0, %1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "SI")])
710 (define_expand "cmpsi_1"
711 [(set (reg:CC FLAGS_REG)
712 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
713 (match_operand:SI 1 "general_operand" "")))]
717 (define_insn "*cmpsi_1_insn"
718 [(set (reg FLAGS_REG)
719 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
720 (match_operand:SI 1 "general_operand" "ri,mr")))]
721 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
722 && ix86_match_ccmode (insn, CCmode)"
723 "cmp{l}\t{%1, %0|%0, %1}"
724 [(set_attr "type" "icmp")
725 (set_attr "mode" "SI")])
727 (define_insn "*cmphi_ccno_1"
728 [(set (reg FLAGS_REG)
729 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
730 (match_operand:HI 1 "const0_operand" "n,n")))]
731 "ix86_match_ccmode (insn, CCNOmode)"
734 cmp{w}\t{%1, %0|%0, %1}"
735 [(set_attr "type" "test,icmp")
736 (set_attr "length_immediate" "0,1")
737 (set_attr "mode" "HI")])
739 (define_insn "*cmphi_minus_1"
740 [(set (reg FLAGS_REG)
741 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
742 (match_operand:HI 1 "general_operand" "ri,mr"))
744 "ix86_match_ccmode (insn, CCGOCmode)"
745 "cmp{w}\t{%1, %0|%0, %1}"
746 [(set_attr "type" "icmp")
747 (set_attr "mode" "HI")])
749 (define_insn "*cmphi_1"
750 [(set (reg FLAGS_REG)
751 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
752 (match_operand:HI 1 "general_operand" "ri,mr")))]
753 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
754 && ix86_match_ccmode (insn, CCmode)"
755 "cmp{w}\t{%1, %0|%0, %1}"
756 [(set_attr "type" "icmp")
757 (set_attr "mode" "HI")])
759 (define_insn "*cmpqi_ccno_1"
760 [(set (reg FLAGS_REG)
761 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
762 (match_operand:QI 1 "const0_operand" "n,n")))]
763 "ix86_match_ccmode (insn, CCNOmode)"
766 cmp{b}\t{$0, %0|%0, 0}"
767 [(set_attr "type" "test,icmp")
768 (set_attr "length_immediate" "0,1")
769 (set_attr "mode" "QI")])
771 (define_insn "*cmpqi_1"
772 [(set (reg FLAGS_REG)
773 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
774 (match_operand:QI 1 "general_operand" "qi,mq")))]
775 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
776 && ix86_match_ccmode (insn, CCmode)"
777 "cmp{b}\t{%1, %0|%0, %1}"
778 [(set_attr "type" "icmp")
779 (set_attr "mode" "QI")])
781 (define_insn "*cmpqi_minus_1"
782 [(set (reg FLAGS_REG)
783 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
784 (match_operand:QI 1 "general_operand" "qi,mq"))
786 "ix86_match_ccmode (insn, CCGOCmode)"
787 "cmp{b}\t{%1, %0|%0, %1}"
788 [(set_attr "type" "icmp")
789 (set_attr "mode" "QI")])
791 (define_insn "*cmpqi_ext_1"
792 [(set (reg FLAGS_REG)
794 (match_operand:QI 0 "general_operand" "Qm")
797 (match_operand 1 "ext_register_operand" "Q")
800 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
801 "cmp{b}\t{%h1, %0|%0, %h1}"
802 [(set_attr "type" "icmp")
803 (set_attr "mode" "QI")])
805 (define_insn "*cmpqi_ext_1_rex64"
806 [(set (reg FLAGS_REG)
808 (match_operand:QI 0 "register_operand" "Q")
811 (match_operand 1 "ext_register_operand" "Q")
814 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
815 "cmp{b}\t{%h1, %0|%0, %h1}"
816 [(set_attr "type" "icmp")
817 (set_attr "mode" "QI")])
819 (define_insn "*cmpqi_ext_2"
820 [(set (reg FLAGS_REG)
824 (match_operand 0 "ext_register_operand" "Q")
827 (match_operand:QI 1 "const0_operand" "n")))]
828 "ix86_match_ccmode (insn, CCNOmode)"
830 [(set_attr "type" "test")
831 (set_attr "length_immediate" "0")
832 (set_attr "mode" "QI")])
834 (define_expand "cmpqi_ext_3"
835 [(set (reg:CC FLAGS_REG)
839 (match_operand 0 "ext_register_operand" "")
842 (match_operand:QI 1 "general_operand" "")))]
846 (define_insn "cmpqi_ext_3_insn"
847 [(set (reg FLAGS_REG)
851 (match_operand 0 "ext_register_operand" "Q")
854 (match_operand:QI 1 "general_operand" "Qmn")))]
855 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
856 "cmp{b}\t{%1, %h0|%h0, %1}"
857 [(set_attr "type" "icmp")
858 (set_attr "mode" "QI")])
860 (define_insn "cmpqi_ext_3_insn_rex64"
861 [(set (reg FLAGS_REG)
865 (match_operand 0 "ext_register_operand" "Q")
868 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
869 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
870 "cmp{b}\t{%1, %h0|%h0, %1}"
871 [(set_attr "type" "icmp")
872 (set_attr "mode" "QI")])
874 (define_insn "*cmpqi_ext_4"
875 [(set (reg FLAGS_REG)
879 (match_operand 0 "ext_register_operand" "Q")
884 (match_operand 1 "ext_register_operand" "Q")
887 "ix86_match_ccmode (insn, CCmode)"
888 "cmp{b}\t{%h1, %h0|%h0, %h1}"
889 [(set_attr "type" "icmp")
890 (set_attr "mode" "QI")])
892 ;; These implement float point compares.
893 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
894 ;; which would allow mix and match FP modes on the compares. Which is what
895 ;; the old patterns did, but with many more of them.
897 (define_expand "cmpxf"
898 [(set (reg:CC FLAGS_REG)
899 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
900 (match_operand:XF 1 "nonmemory_operand" "")))]
903 ix86_compare_op0 = operands[0];
904 ix86_compare_op1 = operands[1];
908 (define_expand "cmp<mode>"
909 [(set (reg:CC FLAGS_REG)
910 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
911 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
912 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
914 ix86_compare_op0 = operands[0];
915 ix86_compare_op1 = operands[1];
919 ;; FP compares, step 1:
920 ;; Set the FP condition codes.
922 ;; CCFPmode compare with exceptions
923 ;; CCFPUmode compare with no exceptions
925 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
926 ;; used to manage the reg stack popping would not be preserved.
928 (define_insn "*cmpfp_0"
929 [(set (match_operand:HI 0 "register_operand" "=a")
932 (match_operand 1 "register_operand" "f")
933 (match_operand 2 "const0_operand" "X"))]
935 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
936 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
937 "* return output_fp_compare (insn, operands, 0, 0);"
938 [(set_attr "type" "multi")
939 (set_attr "unit" "i387")
941 (cond [(match_operand:SF 1 "" "")
943 (match_operand:DF 1 "" "")
946 (const_string "XF")))])
948 (define_insn_and_split "*cmpfp_0_cc"
949 [(set (reg:CCFP FLAGS_REG)
951 (match_operand 1 "register_operand" "f")
952 (match_operand 2 "const0_operand" "X")))
953 (clobber (match_operand:HI 0 "register_operand" "=a"))]
954 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
955 && TARGET_SAHF && !TARGET_CMOVE
956 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
958 "&& reload_completed"
961 [(compare:CCFP (match_dup 1)(match_dup 2))]
963 (set (reg:CC FLAGS_REG)
964 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
966 [(set_attr "type" "multi")
967 (set_attr "unit" "i387")
969 (cond [(match_operand:SF 1 "" "")
971 (match_operand:DF 1 "" "")
974 (const_string "XF")))])
976 (define_insn "*cmpfp_xf"
977 [(set (match_operand:HI 0 "register_operand" "=a")
980 (match_operand:XF 1 "register_operand" "f")
981 (match_operand:XF 2 "register_operand" "f"))]
984 "* return output_fp_compare (insn, operands, 0, 0);"
985 [(set_attr "type" "multi")
986 (set_attr "unit" "i387")
987 (set_attr "mode" "XF")])
989 (define_insn_and_split "*cmpfp_xf_cc"
990 [(set (reg:CCFP FLAGS_REG)
992 (match_operand:XF 1 "register_operand" "f")
993 (match_operand:XF 2 "register_operand" "f")))
994 (clobber (match_operand:HI 0 "register_operand" "=a"))]
996 && TARGET_SAHF && !TARGET_CMOVE"
998 "&& reload_completed"
1001 [(compare:CCFP (match_dup 1)(match_dup 2))]
1003 (set (reg:CC FLAGS_REG)
1004 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1006 [(set_attr "type" "multi")
1007 (set_attr "unit" "i387")
1008 (set_attr "mode" "XF")])
1010 (define_insn "*cmpfp_<mode>"
1011 [(set (match_operand:HI 0 "register_operand" "=a")
1014 (match_operand:MODEF 1 "register_operand" "f")
1015 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1018 "* return output_fp_compare (insn, operands, 0, 0);"
1019 [(set_attr "type" "multi")
1020 (set_attr "unit" "i387")
1021 (set_attr "mode" "<MODE>")])
1023 (define_insn_and_split "*cmpfp_<mode>_cc"
1024 [(set (reg:CCFP FLAGS_REG)
1026 (match_operand:MODEF 1 "register_operand" "f")
1027 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1028 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1030 && TARGET_SAHF && !TARGET_CMOVE"
1032 "&& reload_completed"
1035 [(compare:CCFP (match_dup 1)(match_dup 2))]
1037 (set (reg:CC FLAGS_REG)
1038 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1040 [(set_attr "type" "multi")
1041 (set_attr "unit" "i387")
1042 (set_attr "mode" "<MODE>")])
1044 (define_insn "*cmpfp_u"
1045 [(set (match_operand:HI 0 "register_operand" "=a")
1048 (match_operand 1 "register_operand" "f")
1049 (match_operand 2 "register_operand" "f"))]
1051 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1052 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1053 "* return output_fp_compare (insn, operands, 0, 1);"
1054 [(set_attr "type" "multi")
1055 (set_attr "unit" "i387")
1057 (cond [(match_operand:SF 1 "" "")
1059 (match_operand:DF 1 "" "")
1062 (const_string "XF")))])
1064 (define_insn_and_split "*cmpfp_u_cc"
1065 [(set (reg:CCFPU FLAGS_REG)
1067 (match_operand 1 "register_operand" "f")
1068 (match_operand 2 "register_operand" "f")))
1069 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1070 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1071 && TARGET_SAHF && !TARGET_CMOVE
1072 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1074 "&& reload_completed"
1077 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1079 (set (reg:CC FLAGS_REG)
1080 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1082 [(set_attr "type" "multi")
1083 (set_attr "unit" "i387")
1085 (cond [(match_operand:SF 1 "" "")
1087 (match_operand:DF 1 "" "")
1090 (const_string "XF")))])
1092 (define_insn "*cmpfp_<mode>"
1093 [(set (match_operand:HI 0 "register_operand" "=a")
1096 (match_operand 1 "register_operand" "f")
1097 (match_operator 3 "float_operator"
1098 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1100 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1101 && TARGET_USE_<MODE>MODE_FIOP
1102 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1103 "* return output_fp_compare (insn, operands, 0, 0);"
1104 [(set_attr "type" "multi")
1105 (set_attr "unit" "i387")
1106 (set_attr "fp_int_src" "true")
1107 (set_attr "mode" "<MODE>")])
1109 (define_insn_and_split "*cmpfp_<mode>_cc"
1110 [(set (reg:CCFP FLAGS_REG)
1112 (match_operand 1 "register_operand" "f")
1113 (match_operator 3 "float_operator"
1114 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1115 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1116 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1117 && TARGET_SAHF && !TARGET_CMOVE
1118 && TARGET_USE_<MODE>MODE_FIOP
1119 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1121 "&& reload_completed"
1126 (match_op_dup 3 [(match_dup 2)]))]
1128 (set (reg:CC FLAGS_REG)
1129 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1131 [(set_attr "type" "multi")
1132 (set_attr "unit" "i387")
1133 (set_attr "fp_int_src" "true")
1134 (set_attr "mode" "<MODE>")])
1136 ;; FP compares, step 2
1137 ;; Move the fpsw to ax.
1139 (define_insn "x86_fnstsw_1"
1140 [(set (match_operand:HI 0 "register_operand" "=a")
1141 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1144 [(set_attr "length" "2")
1145 (set_attr "mode" "SI")
1146 (set_attr "unit" "i387")])
1148 ;; FP compares, step 3
1149 ;; Get ax into flags, general case.
1151 (define_insn "x86_sahf_1"
1152 [(set (reg:CC FLAGS_REG)
1153 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1157 #ifdef HAVE_AS_IX86_SAHF
1160 return ".byte\t0x9e";
1163 [(set_attr "length" "1")
1164 (set_attr "athlon_decode" "vector")
1165 (set_attr "amdfam10_decode" "direct")
1166 (set_attr "mode" "SI")])
1168 ;; Pentium Pro can do steps 1 through 3 in one go.
1169 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1170 (define_insn "*cmpfp_i_mixed"
1171 [(set (reg:CCFP FLAGS_REG)
1172 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1173 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1174 "TARGET_MIX_SSE_I387
1175 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1176 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1177 "* return output_fp_compare (insn, operands, 1, 0);"
1178 [(set_attr "type" "fcmp,ssecomi")
1180 (if_then_else (match_operand:SF 1 "" "")
1182 (const_string "DF")))
1183 (set_attr "athlon_decode" "vector")
1184 (set_attr "amdfam10_decode" "direct")])
1186 (define_insn "*cmpfp_i_sse"
1187 [(set (reg:CCFP FLAGS_REG)
1188 (compare:CCFP (match_operand 0 "register_operand" "x")
1189 (match_operand 1 "nonimmediate_operand" "xm")))]
1191 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1192 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1193 "* return output_fp_compare (insn, operands, 1, 0);"
1194 [(set_attr "type" "ssecomi")
1196 (if_then_else (match_operand:SF 1 "" "")
1198 (const_string "DF")))
1199 (set_attr "athlon_decode" "vector")
1200 (set_attr "amdfam10_decode" "direct")])
1202 (define_insn "*cmpfp_i_i387"
1203 [(set (reg:CCFP FLAGS_REG)
1204 (compare:CCFP (match_operand 0 "register_operand" "f")
1205 (match_operand 1 "register_operand" "f")))]
1206 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1208 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1209 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1210 "* return output_fp_compare (insn, operands, 1, 0);"
1211 [(set_attr "type" "fcmp")
1213 (cond [(match_operand:SF 1 "" "")
1215 (match_operand:DF 1 "" "")
1218 (const_string "XF")))
1219 (set_attr "athlon_decode" "vector")
1220 (set_attr "amdfam10_decode" "direct")])
1222 (define_insn "*cmpfp_iu_mixed"
1223 [(set (reg:CCFPU FLAGS_REG)
1224 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1225 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1226 "TARGET_MIX_SSE_I387
1227 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1228 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1229 "* return output_fp_compare (insn, operands, 1, 1);"
1230 [(set_attr "type" "fcmp,ssecomi")
1232 (if_then_else (match_operand:SF 1 "" "")
1234 (const_string "DF")))
1235 (set_attr "athlon_decode" "vector")
1236 (set_attr "amdfam10_decode" "direct")])
1238 (define_insn "*cmpfp_iu_sse"
1239 [(set (reg:CCFPU FLAGS_REG)
1240 (compare:CCFPU (match_operand 0 "register_operand" "x")
1241 (match_operand 1 "nonimmediate_operand" "xm")))]
1243 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1244 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1245 "* return output_fp_compare (insn, operands, 1, 1);"
1246 [(set_attr "type" "ssecomi")
1248 (if_then_else (match_operand:SF 1 "" "")
1250 (const_string "DF")))
1251 (set_attr "athlon_decode" "vector")
1252 (set_attr "amdfam10_decode" "direct")])
1254 (define_insn "*cmpfp_iu_387"
1255 [(set (reg:CCFPU FLAGS_REG)
1256 (compare:CCFPU (match_operand 0 "register_operand" "f")
1257 (match_operand 1 "register_operand" "f")))]
1258 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1260 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1261 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1262 "* return output_fp_compare (insn, operands, 1, 1);"
1263 [(set_attr "type" "fcmp")
1265 (cond [(match_operand:SF 1 "" "")
1267 (match_operand:DF 1 "" "")
1270 (const_string "XF")))
1271 (set_attr "athlon_decode" "vector")
1272 (set_attr "amdfam10_decode" "direct")])
1274 ;; Move instructions.
1276 ;; General case of fullword move.
1278 (define_expand "movsi"
1279 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1280 (match_operand:SI 1 "general_operand" ""))]
1282 "ix86_expand_move (SImode, operands); DONE;")
1284 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1287 ;; %%% We don't use a post-inc memory reference because x86 is not a
1288 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1289 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1290 ;; targets without our curiosities, and it is just as easy to represent
1291 ;; this differently.
1293 (define_insn "*pushsi2"
1294 [(set (match_operand:SI 0 "push_operand" "=<")
1295 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1298 [(set_attr "type" "push")
1299 (set_attr "mode" "SI")])
1301 ;; For 64BIT abi we always round up to 8 bytes.
1302 (define_insn "*pushsi2_rex64"
1303 [(set (match_operand:SI 0 "push_operand" "=X")
1304 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1307 [(set_attr "type" "push")
1308 (set_attr "mode" "SI")])
1310 (define_insn "*pushsi2_prologue"
1311 [(set (match_operand:SI 0 "push_operand" "=<")
1312 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1313 (clobber (mem:BLK (scratch)))]
1316 [(set_attr "type" "push")
1317 (set_attr "mode" "SI")])
1319 (define_insn "*popsi1_epilogue"
1320 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1321 (mem:SI (reg:SI SP_REG)))
1322 (set (reg:SI SP_REG)
1323 (plus:SI (reg:SI SP_REG) (const_int 4)))
1324 (clobber (mem:BLK (scratch)))]
1327 [(set_attr "type" "pop")
1328 (set_attr "mode" "SI")])
1330 (define_insn "popsi1"
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)))]
1337 [(set_attr "type" "pop")
1338 (set_attr "mode" "SI")])
1340 (define_insn "*movsi_xor"
1341 [(set (match_operand:SI 0 "register_operand" "=r")
1342 (match_operand:SI 1 "const0_operand" "i"))
1343 (clobber (reg:CC FLAGS_REG))]
1344 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1346 [(set_attr "type" "alu1")
1347 (set_attr "mode" "SI")
1348 (set_attr "length_immediate" "0")])
1350 (define_insn "*movsi_or"
1351 [(set (match_operand:SI 0 "register_operand" "=r")
1352 (match_operand:SI 1 "immediate_operand" "i"))
1353 (clobber (reg:CC FLAGS_REG))]
1355 && operands[1] == constm1_rtx
1356 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1358 operands[1] = constm1_rtx;
1359 return "or{l}\t{%1, %0|%0, %1}";
1361 [(set_attr "type" "alu1")
1362 (set_attr "mode" "SI")
1363 (set_attr "length_immediate" "1")])
1365 (define_insn "*movsi_1"
1366 [(set (match_operand:SI 0 "nonimmediate_operand"
1367 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1368 (match_operand:SI 1 "general_operand"
1369 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1370 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1372 switch (get_attr_type (insn))
1375 if (get_attr_mode (insn) == MODE_TI)
1376 return "pxor\t%0, %0";
1377 return "xorps\t%0, %0";
1380 switch (get_attr_mode (insn))
1383 return "movdqa\t{%1, %0|%0, %1}";
1385 return "movaps\t{%1, %0|%0, %1}";
1387 return "movd\t{%1, %0|%0, %1}";
1389 return "movss\t{%1, %0|%0, %1}";
1395 return "pxor\t%0, %0";
1398 if (get_attr_mode (insn) == MODE_DI)
1399 return "movq\t{%1, %0|%0, %1}";
1400 return "movd\t{%1, %0|%0, %1}";
1403 return "lea{l}\t{%1, %0|%0, %1}";
1406 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1407 return "mov{l}\t{%1, %0|%0, %1}";
1411 (cond [(eq_attr "alternative" "2")
1412 (const_string "mmxadd")
1413 (eq_attr "alternative" "3,4,5")
1414 (const_string "mmxmov")
1415 (eq_attr "alternative" "6")
1416 (const_string "sselog1")
1417 (eq_attr "alternative" "7,8,9,10,11")
1418 (const_string "ssemov")
1419 (match_operand:DI 1 "pic_32bit_operand" "")
1420 (const_string "lea")
1422 (const_string "imov")))
1424 (cond [(eq_attr "alternative" "2,3")
1426 (eq_attr "alternative" "6,7")
1428 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1429 (const_string "V4SF")
1430 (const_string "TI"))
1431 (and (eq_attr "alternative" "8,9,10,11")
1432 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1435 (const_string "SI")))])
1437 ;; Stores and loads of ax to arbitrary constant address.
1438 ;; We fake an second form of instruction to force reload to load address
1439 ;; into register when rax is not available
1440 (define_insn "*movabssi_1_rex64"
1441 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1442 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1443 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1445 movabs{l}\t{%1, %P0|%P0, %1}
1446 mov{l}\t{%1, %a0|%a0, %1}"
1447 [(set_attr "type" "imov")
1448 (set_attr "modrm" "0,*")
1449 (set_attr "length_address" "8,0")
1450 (set_attr "length_immediate" "0,*")
1451 (set_attr "memory" "store")
1452 (set_attr "mode" "SI")])
1454 (define_insn "*movabssi_2_rex64"
1455 [(set (match_operand:SI 0 "register_operand" "=a,r")
1456 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1457 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1459 movabs{l}\t{%P1, %0|%0, %P1}
1460 mov{l}\t{%a1, %0|%0, %a1}"
1461 [(set_attr "type" "imov")
1462 (set_attr "modrm" "0,*")
1463 (set_attr "length_address" "8,0")
1464 (set_attr "length_immediate" "0")
1465 (set_attr "memory" "load")
1466 (set_attr "mode" "SI")])
1468 (define_insn "*swapsi"
1469 [(set (match_operand:SI 0 "register_operand" "+r")
1470 (match_operand:SI 1 "register_operand" "+r"))
1475 [(set_attr "type" "imov")
1476 (set_attr "mode" "SI")
1477 (set_attr "pent_pair" "np")
1478 (set_attr "athlon_decode" "vector")
1479 (set_attr "amdfam10_decode" "double")])
1481 (define_expand "movhi"
1482 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1483 (match_operand:HI 1 "general_operand" ""))]
1485 "ix86_expand_move (HImode, operands); DONE;")
1487 (define_insn "*pushhi2"
1488 [(set (match_operand:HI 0 "push_operand" "=X")
1489 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1492 [(set_attr "type" "push")
1493 (set_attr "mode" "SI")])
1495 ;; For 64BIT abi we always round up to 8 bytes.
1496 (define_insn "*pushhi2_rex64"
1497 [(set (match_operand:HI 0 "push_operand" "=X")
1498 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1501 [(set_attr "type" "push")
1502 (set_attr "mode" "DI")])
1504 (define_insn "*movhi_1"
1505 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1506 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1507 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1509 switch (get_attr_type (insn))
1512 /* movzwl is faster than movw on p2 due to partial word stalls,
1513 though not as fast as an aligned movl. */
1514 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1516 if (get_attr_mode (insn) == MODE_SI)
1517 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1519 return "mov{w}\t{%1, %0|%0, %1}";
1523 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1524 (const_string "imov")
1525 (and (eq_attr "alternative" "0")
1526 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1528 (eq (symbol_ref "TARGET_HIMODE_MATH")
1530 (const_string "imov")
1531 (and (eq_attr "alternative" "1,2")
1532 (match_operand:HI 1 "aligned_operand" ""))
1533 (const_string "imov")
1534 (and (ne (symbol_ref "TARGET_MOVX")
1536 (eq_attr "alternative" "0,2"))
1537 (const_string "imovx")
1539 (const_string "imov")))
1541 (cond [(eq_attr "type" "imovx")
1543 (and (eq_attr "alternative" "1,2")
1544 (match_operand:HI 1 "aligned_operand" ""))
1546 (and (eq_attr "alternative" "0")
1547 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1549 (eq (symbol_ref "TARGET_HIMODE_MATH")
1553 (const_string "HI")))])
1555 ;; Stores and loads of ax to arbitrary constant address.
1556 ;; We fake an second form of instruction to force reload to load address
1557 ;; into register when rax is not available
1558 (define_insn "*movabshi_1_rex64"
1559 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1560 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1561 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1563 movabs{w}\t{%1, %P0|%P0, %1}
1564 mov{w}\t{%1, %a0|%a0, %1}"
1565 [(set_attr "type" "imov")
1566 (set_attr "modrm" "0,*")
1567 (set_attr "length_address" "8,0")
1568 (set_attr "length_immediate" "0,*")
1569 (set_attr "memory" "store")
1570 (set_attr "mode" "HI")])
1572 (define_insn "*movabshi_2_rex64"
1573 [(set (match_operand:HI 0 "register_operand" "=a,r")
1574 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1575 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1577 movabs{w}\t{%P1, %0|%0, %P1}
1578 mov{w}\t{%a1, %0|%0, %a1}"
1579 [(set_attr "type" "imov")
1580 (set_attr "modrm" "0,*")
1581 (set_attr "length_address" "8,0")
1582 (set_attr "length_immediate" "0")
1583 (set_attr "memory" "load")
1584 (set_attr "mode" "HI")])
1586 (define_insn "*swaphi_1"
1587 [(set (match_operand:HI 0 "register_operand" "+r")
1588 (match_operand:HI 1 "register_operand" "+r"))
1591 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1593 [(set_attr "type" "imov")
1594 (set_attr "mode" "SI")
1595 (set_attr "pent_pair" "np")
1596 (set_attr "athlon_decode" "vector")
1597 (set_attr "amdfam10_decode" "double")])
1599 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1600 (define_insn "*swaphi_2"
1601 [(set (match_operand:HI 0 "register_operand" "+r")
1602 (match_operand:HI 1 "register_operand" "+r"))
1605 "TARGET_PARTIAL_REG_STALL"
1607 [(set_attr "type" "imov")
1608 (set_attr "mode" "HI")
1609 (set_attr "pent_pair" "np")
1610 (set_attr "athlon_decode" "vector")])
1612 (define_expand "movstricthi"
1613 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1614 (match_operand:HI 1 "general_operand" ""))]
1615 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1617 /* Don't generate memory->memory moves, go through a register */
1618 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1619 operands[1] = force_reg (HImode, operands[1]);
1622 (define_insn "*movstricthi_1"
1623 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1624 (match_operand:HI 1 "general_operand" "rn,m"))]
1625 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1626 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1627 "mov{w}\t{%1, %0|%0, %1}"
1628 [(set_attr "type" "imov")
1629 (set_attr "mode" "HI")])
1631 (define_insn "*movstricthi_xor"
1632 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1633 (match_operand:HI 1 "const0_operand" "i"))
1634 (clobber (reg:CC FLAGS_REG))]
1636 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1638 [(set_attr "type" "alu1")
1639 (set_attr "mode" "HI")
1640 (set_attr "length_immediate" "0")])
1642 (define_expand "movqi"
1643 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1644 (match_operand:QI 1 "general_operand" ""))]
1646 "ix86_expand_move (QImode, operands); DONE;")
1648 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1649 ;; "push a byte". But actually we use pushl, which has the effect
1650 ;; of rounding the amount pushed up to a word.
1652 (define_insn "*pushqi2"
1653 [(set (match_operand:QI 0 "push_operand" "=X")
1654 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1657 [(set_attr "type" "push")
1658 (set_attr "mode" "SI")])
1660 ;; For 64BIT abi we always round up to 8 bytes.
1661 (define_insn "*pushqi2_rex64"
1662 [(set (match_operand:QI 0 "push_operand" "=X")
1663 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1666 [(set_attr "type" "push")
1667 (set_attr "mode" "DI")])
1669 ;; Situation is quite tricky about when to choose full sized (SImode) move
1670 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1671 ;; partial register dependency machines (such as AMD Athlon), where QImode
1672 ;; moves issue extra dependency and for partial register stalls machines
1673 ;; that don't use QImode patterns (and QImode move cause stall on the next
1676 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1677 ;; register stall machines with, where we use QImode instructions, since
1678 ;; partial register stall can be caused there. Then we use movzx.
1679 (define_insn "*movqi_1"
1680 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1681 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1682 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1684 switch (get_attr_type (insn))
1687 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1688 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1690 if (get_attr_mode (insn) == MODE_SI)
1691 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1693 return "mov{b}\t{%1, %0|%0, %1}";
1697 (cond [(and (eq_attr "alternative" "5")
1698 (not (match_operand:QI 1 "aligned_operand" "")))
1699 (const_string "imovx")
1700 (ne (symbol_ref "optimize_size") (const_int 0))
1701 (const_string "imov")
1702 (and (eq_attr "alternative" "3")
1703 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1705 (eq (symbol_ref "TARGET_QIMODE_MATH")
1707 (const_string "imov")
1708 (eq_attr "alternative" "3,5")
1709 (const_string "imovx")
1710 (and (ne (symbol_ref "TARGET_MOVX")
1712 (eq_attr "alternative" "2"))
1713 (const_string "imovx")
1715 (const_string "imov")))
1717 (cond [(eq_attr "alternative" "3,4,5")
1719 (eq_attr "alternative" "6")
1721 (eq_attr "type" "imovx")
1723 (and (eq_attr "type" "imov")
1724 (and (eq_attr "alternative" "0,1")
1725 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1727 (and (eq (symbol_ref "optimize_size")
1729 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1732 ;; Avoid partial register stalls when not using QImode arithmetic
1733 (and (eq_attr "type" "imov")
1734 (and (eq_attr "alternative" "0,1")
1735 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1737 (eq (symbol_ref "TARGET_QIMODE_MATH")
1741 (const_string "QI")))])
1743 (define_expand "reload_outqi"
1744 [(parallel [(match_operand:QI 0 "" "=m")
1745 (match_operand:QI 1 "register_operand" "r")
1746 (match_operand:QI 2 "register_operand" "=&q")])]
1750 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1752 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1753 if (! q_regs_operand (op1, QImode))
1755 emit_insn (gen_movqi (op2, op1));
1758 emit_insn (gen_movqi (op0, op1));
1762 (define_insn "*swapqi_1"
1763 [(set (match_operand:QI 0 "register_operand" "+r")
1764 (match_operand:QI 1 "register_operand" "+r"))
1767 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1769 [(set_attr "type" "imov")
1770 (set_attr "mode" "SI")
1771 (set_attr "pent_pair" "np")
1772 (set_attr "athlon_decode" "vector")
1773 (set_attr "amdfam10_decode" "vector")])
1775 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1776 (define_insn "*swapqi_2"
1777 [(set (match_operand:QI 0 "register_operand" "+q")
1778 (match_operand:QI 1 "register_operand" "+q"))
1781 "TARGET_PARTIAL_REG_STALL"
1783 [(set_attr "type" "imov")
1784 (set_attr "mode" "QI")
1785 (set_attr "pent_pair" "np")
1786 (set_attr "athlon_decode" "vector")])
1788 (define_expand "movstrictqi"
1789 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1790 (match_operand:QI 1 "general_operand" ""))]
1791 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1793 /* Don't generate memory->memory moves, go through a register. */
1794 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1795 operands[1] = force_reg (QImode, operands[1]);
1798 (define_insn "*movstrictqi_1"
1799 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1800 (match_operand:QI 1 "general_operand" "*qn,m"))]
1801 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1802 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1803 "mov{b}\t{%1, %0|%0, %1}"
1804 [(set_attr "type" "imov")
1805 (set_attr "mode" "QI")])
1807 (define_insn "*movstrictqi_xor"
1808 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1809 (match_operand:QI 1 "const0_operand" "i"))
1810 (clobber (reg:CC FLAGS_REG))]
1811 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1813 [(set_attr "type" "alu1")
1814 (set_attr "mode" "QI")
1815 (set_attr "length_immediate" "0")])
1817 (define_insn "*movsi_extv_1"
1818 [(set (match_operand:SI 0 "register_operand" "=R")
1819 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1823 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1824 [(set_attr "type" "imovx")
1825 (set_attr "mode" "SI")])
1827 (define_insn "*movhi_extv_1"
1828 [(set (match_operand:HI 0 "register_operand" "=R")
1829 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1833 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1834 [(set_attr "type" "imovx")
1835 (set_attr "mode" "SI")])
1837 (define_insn "*movqi_extv_1"
1838 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1839 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1844 switch (get_attr_type (insn))
1847 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1849 return "mov{b}\t{%h1, %0|%0, %h1}";
1853 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1854 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1855 (ne (symbol_ref "TARGET_MOVX")
1857 (const_string "imovx")
1858 (const_string "imov")))
1860 (if_then_else (eq_attr "type" "imovx")
1862 (const_string "QI")))])
1864 (define_insn "*movqi_extv_1_rex64"
1865 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1866 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1871 switch (get_attr_type (insn))
1874 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1876 return "mov{b}\t{%h1, %0|%0, %h1}";
1880 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1881 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1882 (ne (symbol_ref "TARGET_MOVX")
1884 (const_string "imovx")
1885 (const_string "imov")))
1887 (if_then_else (eq_attr "type" "imovx")
1889 (const_string "QI")))])
1891 ;; Stores and loads of ax to arbitrary constant address.
1892 ;; We fake an second form of instruction to force reload to load address
1893 ;; into register when rax is not available
1894 (define_insn "*movabsqi_1_rex64"
1895 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1896 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1897 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1899 movabs{b}\t{%1, %P0|%P0, %1}
1900 mov{b}\t{%1, %a0|%a0, %1}"
1901 [(set_attr "type" "imov")
1902 (set_attr "modrm" "0,*")
1903 (set_attr "length_address" "8,0")
1904 (set_attr "length_immediate" "0,*")
1905 (set_attr "memory" "store")
1906 (set_attr "mode" "QI")])
1908 (define_insn "*movabsqi_2_rex64"
1909 [(set (match_operand:QI 0 "register_operand" "=a,r")
1910 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1911 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1913 movabs{b}\t{%P1, %0|%0, %P1}
1914 mov{b}\t{%a1, %0|%0, %a1}"
1915 [(set_attr "type" "imov")
1916 (set_attr "modrm" "0,*")
1917 (set_attr "length_address" "8,0")
1918 (set_attr "length_immediate" "0")
1919 (set_attr "memory" "load")
1920 (set_attr "mode" "QI")])
1922 (define_insn "*movdi_extzv_1"
1923 [(set (match_operand:DI 0 "register_operand" "=R")
1924 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1928 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1929 [(set_attr "type" "imovx")
1930 (set_attr "mode" "DI")])
1932 (define_insn "*movsi_extzv_1"
1933 [(set (match_operand:SI 0 "register_operand" "=R")
1934 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1938 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1939 [(set_attr "type" "imovx")
1940 (set_attr "mode" "SI")])
1942 (define_insn "*movqi_extzv_2"
1943 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1944 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1949 switch (get_attr_type (insn))
1952 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1954 return "mov{b}\t{%h1, %0|%0, %h1}";
1958 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1959 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1960 (ne (symbol_ref "TARGET_MOVX")
1962 (const_string "imovx")
1963 (const_string "imov")))
1965 (if_then_else (eq_attr "type" "imovx")
1967 (const_string "QI")))])
1969 (define_insn "*movqi_extzv_2_rex64"
1970 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1971 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1976 switch (get_attr_type (insn))
1979 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1981 return "mov{b}\t{%h1, %0|%0, %h1}";
1985 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1986 (ne (symbol_ref "TARGET_MOVX")
1988 (const_string "imovx")
1989 (const_string "imov")))
1991 (if_then_else (eq_attr "type" "imovx")
1993 (const_string "QI")))])
1995 (define_insn "movsi_insv_1"
1996 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1999 (match_operand:SI 1 "general_operand" "Qmn"))]
2001 "mov{b}\t{%b1, %h0|%h0, %b1}"
2002 [(set_attr "type" "imov")
2003 (set_attr "mode" "QI")])
2005 (define_insn "*movsi_insv_1_rex64"
2006 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2009 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2011 "mov{b}\t{%b1, %h0|%h0, %b1}"
2012 [(set_attr "type" "imov")
2013 (set_attr "mode" "QI")])
2015 (define_insn "movdi_insv_1_rex64"
2016 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2019 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2021 "mov{b}\t{%b1, %h0|%h0, %b1}"
2022 [(set_attr "type" "imov")
2023 (set_attr "mode" "QI")])
2025 (define_insn "*movqi_insv_2"
2026 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2029 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2032 "mov{b}\t{%h1, %h0|%h0, %h1}"
2033 [(set_attr "type" "imov")
2034 (set_attr "mode" "QI")])
2036 (define_expand "movdi"
2037 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2038 (match_operand:DI 1 "general_operand" ""))]
2040 "ix86_expand_move (DImode, operands); DONE;")
2042 (define_insn "*pushdi"
2043 [(set (match_operand:DI 0 "push_operand" "=<")
2044 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2048 (define_insn "*pushdi2_rex64"
2049 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2050 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2055 [(set_attr "type" "push,multi")
2056 (set_attr "mode" "DI")])
2058 ;; Convert impossible pushes of immediate to existing instructions.
2059 ;; First try to get scratch register and go through it. In case this
2060 ;; fails, push sign extended lower part first and then overwrite
2061 ;; upper part by 32bit move.
2063 [(match_scratch:DI 2 "r")
2064 (set (match_operand:DI 0 "push_operand" "")
2065 (match_operand:DI 1 "immediate_operand" ""))]
2066 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2067 && !x86_64_immediate_operand (operands[1], DImode)"
2068 [(set (match_dup 2) (match_dup 1))
2069 (set (match_dup 0) (match_dup 2))]
2072 ;; We need to define this as both peepholer and splitter for case
2073 ;; peephole2 pass is not run.
2074 ;; "&& 1" is needed to keep it from matching the previous pattern.
2076 [(set (match_operand:DI 0 "push_operand" "")
2077 (match_operand:DI 1 "immediate_operand" ""))]
2078 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2080 [(set (match_dup 0) (match_dup 1))
2081 (set (match_dup 2) (match_dup 3))]
2082 "split_di (operands + 1, 1, operands + 2, operands + 3);
2083 operands[1] = gen_lowpart (DImode, operands[2]);
2084 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2089 [(set (match_operand:DI 0 "push_operand" "")
2090 (match_operand:DI 1 "immediate_operand" ""))]
2091 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2092 ? epilogue_completed : reload_completed)
2093 && !symbolic_operand (operands[1], DImode)
2094 && !x86_64_immediate_operand (operands[1], DImode)"
2095 [(set (match_dup 0) (match_dup 1))
2096 (set (match_dup 2) (match_dup 3))]
2097 "split_di (operands + 1, 1, operands + 2, operands + 3);
2098 operands[1] = gen_lowpart (DImode, operands[2]);
2099 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2103 (define_insn "*pushdi2_prologue_rex64"
2104 [(set (match_operand:DI 0 "push_operand" "=<")
2105 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2106 (clobber (mem:BLK (scratch)))]
2109 [(set_attr "type" "push")
2110 (set_attr "mode" "DI")])
2112 (define_insn "*popdi1_epilogue_rex64"
2113 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2114 (mem:DI (reg:DI SP_REG)))
2115 (set (reg:DI SP_REG)
2116 (plus:DI (reg:DI SP_REG) (const_int 8)))
2117 (clobber (mem:BLK (scratch)))]
2120 [(set_attr "type" "pop")
2121 (set_attr "mode" "DI")])
2123 (define_insn "popdi1"
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)))]
2130 [(set_attr "type" "pop")
2131 (set_attr "mode" "DI")])
2133 (define_insn "*movdi_xor_rex64"
2134 [(set (match_operand:DI 0 "register_operand" "=r")
2135 (match_operand:DI 1 "const0_operand" "i"))
2136 (clobber (reg:CC FLAGS_REG))]
2137 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2138 && reload_completed"
2140 [(set_attr "type" "alu1")
2141 (set_attr "mode" "SI")
2142 (set_attr "length_immediate" "0")])
2144 (define_insn "*movdi_or_rex64"
2145 [(set (match_operand:DI 0 "register_operand" "=r")
2146 (match_operand:DI 1 "const_int_operand" "i"))
2147 (clobber (reg:CC FLAGS_REG))]
2148 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2150 && operands[1] == constm1_rtx"
2152 operands[1] = constm1_rtx;
2153 return "or{q}\t{%1, %0|%0, %1}";
2155 [(set_attr "type" "alu1")
2156 (set_attr "mode" "DI")
2157 (set_attr "length_immediate" "1")])
2159 (define_insn "*movdi_2"
2160 [(set (match_operand:DI 0 "nonimmediate_operand"
2161 "=r ,o ,*y,m*y,*y,*Yt,m ,*Yt,*Yt,*x,m ,*x,*x")
2162 (match_operand:DI 1 "general_operand"
2163 "riFo,riF,C ,*y ,m ,C ,*Yt,*Yt,m ,C ,*x,*x,m "))]
2164 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2169 movq\t{%1, %0|%0, %1}
2170 movq\t{%1, %0|%0, %1}
2172 movq\t{%1, %0|%0, %1}
2173 movdqa\t{%1, %0|%0, %1}
2174 movq\t{%1, %0|%0, %1}
2176 movlps\t{%1, %0|%0, %1}
2177 movaps\t{%1, %0|%0, %1}
2178 movlps\t{%1, %0|%0, %1}"
2179 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2180 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2183 [(set (match_operand:DI 0 "push_operand" "")
2184 (match_operand:DI 1 "general_operand" ""))]
2185 "!TARGET_64BIT && reload_completed
2186 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2188 "ix86_split_long_move (operands); DONE;")
2190 ;; %%% This multiword shite has got to go.
2192 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2193 (match_operand:DI 1 "general_operand" ""))]
2194 "!TARGET_64BIT && reload_completed
2195 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2196 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2198 "ix86_split_long_move (operands); DONE;")
2200 (define_insn "*movdi_1_rex64"
2201 [(set (match_operand:DI 0 "nonimmediate_operand"
2202 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2203 (match_operand:DI 1 "general_operand"
2204 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2205 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2207 switch (get_attr_type (insn))
2210 if (SSE_REG_P (operands[0]))
2211 return "movq2dq\t{%1, %0|%0, %1}";
2213 return "movdq2q\t{%1, %0|%0, %1}";
2216 if (get_attr_mode (insn) == MODE_TI)
2217 return "movdqa\t{%1, %0|%0, %1}";
2221 /* Moves from and into integer register is done using movd
2222 opcode with REX prefix. */
2223 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2224 return "movd\t{%1, %0|%0, %1}";
2225 return "movq\t{%1, %0|%0, %1}";
2229 return "pxor\t%0, %0";
2235 return "lea{q}\t{%a1, %0|%0, %a1}";
2238 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2239 if (get_attr_mode (insn) == MODE_SI)
2240 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2241 else if (which_alternative == 2)
2242 return "movabs{q}\t{%1, %0|%0, %1}";
2244 return "mov{q}\t{%1, %0|%0, %1}";
2248 (cond [(eq_attr "alternative" "5")
2249 (const_string "mmxadd")
2250 (eq_attr "alternative" "6,7,8,9,10")
2251 (const_string "mmxmov")
2252 (eq_attr "alternative" "11")
2253 (const_string "sselog1")
2254 (eq_attr "alternative" "12,13,14,15,16")
2255 (const_string "ssemov")
2256 (eq_attr "alternative" "17,18")
2257 (const_string "ssecvt")
2258 (eq_attr "alternative" "4")
2259 (const_string "multi")
2260 (match_operand:DI 1 "pic_32bit_operand" "")
2261 (const_string "lea")
2263 (const_string "imov")))
2264 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2265 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2266 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2268 ;; Stores and loads of ax to arbitrary constant address.
2269 ;; We fake an second form of instruction to force reload to load address
2270 ;; into register when rax is not available
2271 (define_insn "*movabsdi_1_rex64"
2272 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2273 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2274 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2276 movabs{q}\t{%1, %P0|%P0, %1}
2277 mov{q}\t{%1, %a0|%a0, %1}"
2278 [(set_attr "type" "imov")
2279 (set_attr "modrm" "0,*")
2280 (set_attr "length_address" "8,0")
2281 (set_attr "length_immediate" "0,*")
2282 (set_attr "memory" "store")
2283 (set_attr "mode" "DI")])
2285 (define_insn "*movabsdi_2_rex64"
2286 [(set (match_operand:DI 0 "register_operand" "=a,r")
2287 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2288 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2290 movabs{q}\t{%P1, %0|%0, %P1}
2291 mov{q}\t{%a1, %0|%0, %a1}"
2292 [(set_attr "type" "imov")
2293 (set_attr "modrm" "0,*")
2294 (set_attr "length_address" "8,0")
2295 (set_attr "length_immediate" "0")
2296 (set_attr "memory" "load")
2297 (set_attr "mode" "DI")])
2299 ;; Convert impossible stores of immediate to existing instructions.
2300 ;; First try to get scratch register and go through it. In case this
2301 ;; fails, move by 32bit parts.
2303 [(match_scratch:DI 2 "r")
2304 (set (match_operand:DI 0 "memory_operand" "")
2305 (match_operand:DI 1 "immediate_operand" ""))]
2306 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2307 && !x86_64_immediate_operand (operands[1], DImode)"
2308 [(set (match_dup 2) (match_dup 1))
2309 (set (match_dup 0) (match_dup 2))]
2312 ;; We need to define this as both peepholer and splitter for case
2313 ;; peephole2 pass is not run.
2314 ;; "&& 1" is needed to keep it from matching the previous pattern.
2316 [(set (match_operand:DI 0 "memory_operand" "")
2317 (match_operand:DI 1 "immediate_operand" ""))]
2318 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2319 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2320 [(set (match_dup 2) (match_dup 3))
2321 (set (match_dup 4) (match_dup 5))]
2322 "split_di (operands, 2, operands + 2, operands + 4);")
2325 [(set (match_operand:DI 0 "memory_operand" "")
2326 (match_operand:DI 1 "immediate_operand" ""))]
2327 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2328 ? epilogue_completed : reload_completed)
2329 && !symbolic_operand (operands[1], DImode)
2330 && !x86_64_immediate_operand (operands[1], DImode)"
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);")
2335 (define_insn "*swapdi_rex64"
2336 [(set (match_operand:DI 0 "register_operand" "+r")
2337 (match_operand:DI 1 "register_operand" "+r"))
2342 [(set_attr "type" "imov")
2343 (set_attr "mode" "DI")
2344 (set_attr "pent_pair" "np")
2345 (set_attr "athlon_decode" "vector")
2346 (set_attr "amdfam10_decode" "double")])
2348 (define_expand "movti"
2349 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2350 (match_operand:TI 1 "nonimmediate_operand" ""))]
2351 "TARGET_SSE || TARGET_64BIT"
2354 ix86_expand_move (TImode, operands);
2355 else if (push_operand (operands[0], TImode))
2356 ix86_expand_push (TImode, operands[1]);
2358 ix86_expand_vector_move (TImode, operands);
2362 (define_insn "*movti_internal"
2363 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2364 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2365 "TARGET_SSE && !TARGET_64BIT
2366 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2368 switch (which_alternative)
2371 if (get_attr_mode (insn) == MODE_V4SF)
2372 return "xorps\t%0, %0";
2374 return "pxor\t%0, %0";
2377 if (get_attr_mode (insn) == MODE_V4SF)
2378 return "movaps\t{%1, %0|%0, %1}";
2380 return "movdqa\t{%1, %0|%0, %1}";
2385 [(set_attr "type" "sselog1,ssemov,ssemov")
2387 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2388 (ne (symbol_ref "optimize_size") (const_int 0)))
2389 (const_string "V4SF")
2390 (and (eq_attr "alternative" "2")
2391 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2393 (const_string "V4SF")]
2394 (const_string "TI")))])
2396 (define_insn "*movti_rex64"
2397 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2398 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2400 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2402 switch (which_alternative)
2408 if (get_attr_mode (insn) == MODE_V4SF)
2409 return "xorps\t%0, %0";
2411 return "pxor\t%0, %0";
2414 if (get_attr_mode (insn) == MODE_V4SF)
2415 return "movaps\t{%1, %0|%0, %1}";
2417 return "movdqa\t{%1, %0|%0, %1}";
2422 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2424 (cond [(eq_attr "alternative" "2,3")
2426 (ne (symbol_ref "optimize_size")
2428 (const_string "V4SF")
2429 (const_string "TI"))
2430 (eq_attr "alternative" "4")
2432 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2434 (ne (symbol_ref "optimize_size")
2436 (const_string "V4SF")
2437 (const_string "TI"))]
2438 (const_string "DI")))])
2441 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2442 (match_operand:TI 1 "general_operand" ""))]
2443 "reload_completed && !SSE_REG_P (operands[0])
2444 && !SSE_REG_P (operands[1])"
2446 "ix86_split_long_move (operands); DONE;")
2448 ;; This expands to what emit_move_complex would generate if we didn't
2449 ;; have a movti pattern. Having this avoids problems with reload on
2450 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2451 ;; to have around all the time.
2452 (define_expand "movcdi"
2453 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2454 (match_operand:CDI 1 "general_operand" ""))]
2457 if (push_operand (operands[0], CDImode))
2458 emit_move_complex_push (CDImode, operands[0], operands[1]);
2460 emit_move_complex_parts (operands[0], operands[1]);
2464 (define_expand "movsf"
2465 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2466 (match_operand:SF 1 "general_operand" ""))]
2468 "ix86_expand_move (SFmode, operands); DONE;")
2470 (define_insn "*pushsf"
2471 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2472 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2475 /* Anything else should be already split before reg-stack. */
2476 gcc_assert (which_alternative == 1);
2477 return "push{l}\t%1";
2479 [(set_attr "type" "multi,push,multi")
2480 (set_attr "unit" "i387,*,*")
2481 (set_attr "mode" "SF,SI,SF")])
2483 (define_insn "*pushsf_rex64"
2484 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2485 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2488 /* Anything else should be already split before reg-stack. */
2489 gcc_assert (which_alternative == 1);
2490 return "push{q}\t%q1";
2492 [(set_attr "type" "multi,push,multi")
2493 (set_attr "unit" "i387,*,*")
2494 (set_attr "mode" "SF,DI,SF")])
2497 [(set (match_operand:SF 0 "push_operand" "")
2498 (match_operand:SF 1 "memory_operand" ""))]
2500 && MEM_P (operands[1])
2501 && (operands[2] = find_constant_src (insn))"
2506 ;; %%% Kill this when call knows how to work this out.
2508 [(set (match_operand:SF 0 "push_operand" "")
2509 (match_operand:SF 1 "any_fp_register_operand" ""))]
2511 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2512 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2515 [(set (match_operand:SF 0 "push_operand" "")
2516 (match_operand:SF 1 "any_fp_register_operand" ""))]
2518 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2519 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2521 (define_insn "*movsf_1"
2522 [(set (match_operand:SF 0 "nonimmediate_operand"
2523 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2524 (match_operand:SF 1 "general_operand"
2525 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2526 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2527 && (reload_in_progress || reload_completed
2528 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2529 || (!TARGET_SSE_MATH && optimize_size
2530 && standard_80387_constant_p (operands[1]))
2531 || GET_CODE (operands[1]) != CONST_DOUBLE
2532 || memory_operand (operands[0], SFmode))"
2534 switch (which_alternative)
2538 return output_387_reg_move (insn, operands);
2541 return standard_80387_constant_opcode (operands[1]);
2545 return "mov{l}\t{%1, %0|%0, %1}";
2547 if (get_attr_mode (insn) == MODE_TI)
2548 return "pxor\t%0, %0";
2550 return "xorps\t%0, %0";
2552 if (get_attr_mode (insn) == MODE_V4SF)
2553 return "movaps\t{%1, %0|%0, %1}";
2555 return "movss\t{%1, %0|%0, %1}";
2557 return "movss\t{%1, %0|%0, %1}";
2560 case 12: case 13: case 14: case 15:
2561 return "movd\t{%1, %0|%0, %1}";
2564 return "movq\t{%1, %0|%0, %1}";
2570 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2572 (cond [(eq_attr "alternative" "3,4,9,10")
2574 (eq_attr "alternative" "5")
2576 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2578 (ne (symbol_ref "TARGET_SSE2")
2580 (eq (symbol_ref "optimize_size")
2583 (const_string "V4SF"))
2584 /* For architectures resolving dependencies on
2585 whole SSE registers use APS move to break dependency
2586 chains, otherwise use short move to avoid extra work.
2588 Do the same for architectures resolving dependencies on
2589 the parts. While in DF mode it is better to always handle
2590 just register parts, the SF mode is different due to lack
2591 of instructions to load just part of the register. It is
2592 better to maintain the whole registers in single format
2593 to avoid problems on using packed logical operations. */
2594 (eq_attr "alternative" "6")
2596 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2598 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2600 (const_string "V4SF")
2601 (const_string "SF"))
2602 (eq_attr "alternative" "11")
2603 (const_string "DI")]
2604 (const_string "SF")))])
2606 (define_insn "*swapsf"
2607 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2608 (match_operand:SF 1 "fp_register_operand" "+f"))
2611 "reload_completed || TARGET_80387"
2613 if (STACK_TOP_P (operands[0]))
2618 [(set_attr "type" "fxch")
2619 (set_attr "mode" "SF")])
2621 (define_expand "movdf"
2622 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2623 (match_operand:DF 1 "general_operand" ""))]
2625 "ix86_expand_move (DFmode, operands); DONE;")
2627 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2628 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2629 ;; On the average, pushdf using integers can be still shorter. Allow this
2630 ;; pattern for optimize_size too.
2632 (define_insn "*pushdf_nointeger"
2633 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2634 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Yt"))]
2635 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2637 /* This insn should be already split before reg-stack. */
2640 [(set_attr "type" "multi")
2641 (set_attr "unit" "i387,*,*,*")
2642 (set_attr "mode" "DF,SI,SI,DF")])
2644 (define_insn "*pushdf_integer"
2645 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2646 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Yt"))]
2647 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2649 /* This insn should be already split before reg-stack. */
2652 [(set_attr "type" "multi")
2653 (set_attr "unit" "i387,*,*")
2654 (set_attr "mode" "DF,SI,DF")])
2656 ;; %%% Kill this when call knows how to work this out.
2658 [(set (match_operand:DF 0 "push_operand" "")
2659 (match_operand:DF 1 "any_fp_register_operand" ""))]
2660 "!TARGET_64BIT && reload_completed"
2661 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2662 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2666 [(set (match_operand:DF 0 "push_operand" "")
2667 (match_operand:DF 1 "any_fp_register_operand" ""))]
2668 "TARGET_64BIT && reload_completed"
2669 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2670 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2674 [(set (match_operand:DF 0 "push_operand" "")
2675 (match_operand:DF 1 "general_operand" ""))]
2678 "ix86_split_long_move (operands); DONE;")
2680 ;; Moving is usually shorter when only FP registers are used. This separate
2681 ;; movdf pattern avoids the use of integer registers for FP operations
2682 ;; when optimizing for size.
2684 (define_insn "*movdf_nointeger"
2685 [(set (match_operand:DF 0 "nonimmediate_operand"
2686 "=f,m,f,*r ,o ,Yt*x,Yt*x,Yt*x ,m ")
2687 (match_operand:DF 1 "general_operand"
2688 "fm,f,G,*roF,F*r,C ,Yt*x,mYt*x,Yt*x"))]
2689 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2690 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2691 && (reload_in_progress || reload_completed
2692 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2693 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2694 && standard_80387_constant_p (operands[1]))
2695 || GET_CODE (operands[1]) != CONST_DOUBLE
2696 || memory_operand (operands[0], DFmode))"
2698 switch (which_alternative)
2702 return output_387_reg_move (insn, operands);
2705 return standard_80387_constant_opcode (operands[1]);
2711 switch (get_attr_mode (insn))
2714 return "xorps\t%0, %0";
2716 return "xorpd\t%0, %0";
2718 return "pxor\t%0, %0";
2725 switch (get_attr_mode (insn))
2728 return "movaps\t{%1, %0|%0, %1}";
2730 return "movapd\t{%1, %0|%0, %1}";
2732 return "movdqa\t{%1, %0|%0, %1}";
2734 return "movq\t{%1, %0|%0, %1}";
2736 return "movsd\t{%1, %0|%0, %1}";
2738 return "movlpd\t{%1, %0|%0, %1}";
2740 return "movlps\t{%1, %0|%0, %1}";
2749 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2751 (cond [(eq_attr "alternative" "0,1,2")
2753 (eq_attr "alternative" "3,4")
2756 /* For SSE1, we have many fewer alternatives. */
2757 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2758 (cond [(eq_attr "alternative" "5,6")
2759 (const_string "V4SF")
2761 (const_string "V2SF"))
2763 /* xorps is one byte shorter. */
2764 (eq_attr "alternative" "5")
2765 (cond [(ne (symbol_ref "optimize_size")
2767 (const_string "V4SF")
2768 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2772 (const_string "V2DF"))
2774 /* For architectures resolving dependencies on
2775 whole SSE registers use APD move to break dependency
2776 chains, otherwise use short move to avoid extra work.
2778 movaps encodes one byte shorter. */
2779 (eq_attr "alternative" "6")
2781 [(ne (symbol_ref "optimize_size")
2783 (const_string "V4SF")
2784 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2786 (const_string "V2DF")
2788 (const_string "DF"))
2789 /* For architectures resolving dependencies on register
2790 parts we may avoid extra work to zero out upper part
2792 (eq_attr "alternative" "7")
2794 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2796 (const_string "V1DF")
2797 (const_string "DF"))
2799 (const_string "DF")))])
2801 (define_insn "*movdf_integer_rex64"
2802 [(set (match_operand:DF 0 "nonimmediate_operand"
2803 "=f,m,f,r ,m ,Yt*x,Yt*x,Yt*x,m ,Yi,r ")
2804 (match_operand:DF 1 "general_operand"
2805 "fm,f,G,rmF,Fr,C ,Yt*x,m ,Yt*x,r ,Yi"))]
2806 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2807 && (reload_in_progress || reload_completed
2808 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2809 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2810 && standard_80387_constant_p (operands[1]))
2811 || GET_CODE (operands[1]) != CONST_DOUBLE
2812 || memory_operand (operands[0], DFmode))"
2814 switch (which_alternative)
2818 return output_387_reg_move (insn, operands);
2821 return standard_80387_constant_opcode (operands[1]);
2828 switch (get_attr_mode (insn))
2831 return "xorps\t%0, %0";
2833 return "xorpd\t%0, %0";
2835 return "pxor\t%0, %0";
2842 switch (get_attr_mode (insn))
2845 return "movaps\t{%1, %0|%0, %1}";
2847 return "movapd\t{%1, %0|%0, %1}";
2849 return "movdqa\t{%1, %0|%0, %1}";
2851 return "movq\t{%1, %0|%0, %1}";
2853 return "movsd\t{%1, %0|%0, %1}";
2855 return "movlpd\t{%1, %0|%0, %1}";
2857 return "movlps\t{%1, %0|%0, %1}";
2864 return "movd\t{%1, %0|%0, %1}";
2870 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2872 (cond [(eq_attr "alternative" "0,1,2")
2874 (eq_attr "alternative" "3,4,9,10")
2877 /* For SSE1, we have many fewer alternatives. */
2878 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2879 (cond [(eq_attr "alternative" "5,6")
2880 (const_string "V4SF")
2882 (const_string "V2SF"))
2884 /* xorps is one byte shorter. */
2885 (eq_attr "alternative" "5")
2886 (cond [(ne (symbol_ref "optimize_size")
2888 (const_string "V4SF")
2889 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2893 (const_string "V2DF"))
2895 /* For architectures resolving dependencies on
2896 whole SSE registers use APD move to break dependency
2897 chains, otherwise use short move to avoid extra work.
2899 movaps encodes one byte shorter. */
2900 (eq_attr "alternative" "6")
2902 [(ne (symbol_ref "optimize_size")
2904 (const_string "V4SF")
2905 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2907 (const_string "V2DF")
2909 (const_string "DF"))
2910 /* For architectures resolving dependencies on register
2911 parts we may avoid extra work to zero out upper part
2913 (eq_attr "alternative" "7")
2915 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2917 (const_string "V1DF")
2918 (const_string "DF"))
2920 (const_string "DF")))])
2922 (define_insn "*movdf_integer"
2923 [(set (match_operand:DF 0 "nonimmediate_operand"
2924 "=f,m,f,r ,o ,Yt*x,Yt*x,Yt*x,m ")
2925 (match_operand:DF 1 "general_operand"
2926 "fm,f,G,roF,Fr,C ,Yt*x,m ,Yt*x"))]
2927 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2928 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2929 && (reload_in_progress || reload_completed
2930 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2931 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2932 && standard_80387_constant_p (operands[1]))
2933 || GET_CODE (operands[1]) != CONST_DOUBLE
2934 || memory_operand (operands[0], DFmode))"
2936 switch (which_alternative)
2940 return output_387_reg_move (insn, operands);
2943 return standard_80387_constant_opcode (operands[1]);
2950 switch (get_attr_mode (insn))
2953 return "xorps\t%0, %0";
2955 return "xorpd\t%0, %0";
2957 return "pxor\t%0, %0";
2964 switch (get_attr_mode (insn))
2967 return "movaps\t{%1, %0|%0, %1}";
2969 return "movapd\t{%1, %0|%0, %1}";
2971 return "movdqa\t{%1, %0|%0, %1}";
2973 return "movq\t{%1, %0|%0, %1}";
2975 return "movsd\t{%1, %0|%0, %1}";
2977 return "movlpd\t{%1, %0|%0, %1}";
2979 return "movlps\t{%1, %0|%0, %1}";
2988 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2990 (cond [(eq_attr "alternative" "0,1,2")
2992 (eq_attr "alternative" "3,4")
2995 /* For SSE1, we have many fewer alternatives. */
2996 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2997 (cond [(eq_attr "alternative" "5,6")
2998 (const_string "V4SF")
3000 (const_string "V2SF"))
3002 /* xorps is one byte shorter. */
3003 (eq_attr "alternative" "5")
3004 (cond [(ne (symbol_ref "optimize_size")
3006 (const_string "V4SF")
3007 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3011 (const_string "V2DF"))
3013 /* For architectures resolving dependencies on
3014 whole SSE registers use APD move to break dependency
3015 chains, otherwise use short move to avoid extra work.
3017 movaps encodes one byte shorter. */
3018 (eq_attr "alternative" "6")
3020 [(ne (symbol_ref "optimize_size")
3022 (const_string "V4SF")
3023 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3025 (const_string "V2DF")
3027 (const_string "DF"))
3028 /* For architectures resolving dependencies on register
3029 parts we may avoid extra work to zero out upper part
3031 (eq_attr "alternative" "7")
3033 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3035 (const_string "V1DF")
3036 (const_string "DF"))
3038 (const_string "DF")))])
3041 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3042 (match_operand:DF 1 "general_operand" ""))]
3044 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3045 && ! (ANY_FP_REG_P (operands[0]) ||
3046 (GET_CODE (operands[0]) == SUBREG
3047 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3048 && ! (ANY_FP_REG_P (operands[1]) ||
3049 (GET_CODE (operands[1]) == SUBREG
3050 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3052 "ix86_split_long_move (operands); DONE;")
3054 (define_insn "*swapdf"
3055 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3056 (match_operand:DF 1 "fp_register_operand" "+f"))
3059 "reload_completed || TARGET_80387"
3061 if (STACK_TOP_P (operands[0]))
3066 [(set_attr "type" "fxch")
3067 (set_attr "mode" "DF")])
3069 (define_expand "movxf"
3070 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3071 (match_operand:XF 1 "general_operand" ""))]
3073 "ix86_expand_move (XFmode, operands); DONE;")
3075 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3076 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3077 ;; Pushing using integer instructions is longer except for constants
3078 ;; and direct memory references.
3079 ;; (assuming that any given constant is pushed only once, but this ought to be
3080 ;; handled elsewhere).
3082 (define_insn "*pushxf_nointeger"
3083 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3084 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3087 /* This insn should be already split before reg-stack. */
3090 [(set_attr "type" "multi")
3091 (set_attr "unit" "i387,*,*")
3092 (set_attr "mode" "XF,SI,SI")])
3094 (define_insn "*pushxf_integer"
3095 [(set (match_operand:XF 0 "push_operand" "=<,<")
3096 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3099 /* This insn should be already split before reg-stack. */
3102 [(set_attr "type" "multi")
3103 (set_attr "unit" "i387,*")
3104 (set_attr "mode" "XF,SI")])
3107 [(set (match_operand 0 "push_operand" "")
3108 (match_operand 1 "general_operand" ""))]
3110 && (GET_MODE (operands[0]) == XFmode
3111 || GET_MODE (operands[0]) == DFmode)
3112 && !ANY_FP_REG_P (operands[1])"
3114 "ix86_split_long_move (operands); DONE;")
3117 [(set (match_operand:XF 0 "push_operand" "")
3118 (match_operand:XF 1 "any_fp_register_operand" ""))]
3120 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3121 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3122 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3125 [(set (match_operand:XF 0 "push_operand" "")
3126 (match_operand:XF 1 "any_fp_register_operand" ""))]
3128 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3129 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3130 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3132 ;; Do not use integer registers when optimizing for size
3133 (define_insn "*movxf_nointeger"
3134 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3135 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3137 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3138 && (reload_in_progress || reload_completed
3139 || (optimize_size && standard_80387_constant_p (operands[1]))
3140 || GET_CODE (operands[1]) != CONST_DOUBLE
3141 || memory_operand (operands[0], XFmode))"
3143 switch (which_alternative)
3147 return output_387_reg_move (insn, operands);
3150 return standard_80387_constant_opcode (operands[1]);
3158 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3159 (set_attr "mode" "XF,XF,XF,SI,SI")])
3161 (define_insn "*movxf_integer"
3162 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3163 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3165 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3166 && (reload_in_progress || reload_completed
3167 || (optimize_size && standard_80387_constant_p (operands[1]))
3168 || GET_CODE (operands[1]) != CONST_DOUBLE
3169 || memory_operand (operands[0], XFmode))"
3171 switch (which_alternative)
3175 return output_387_reg_move (insn, operands);
3178 return standard_80387_constant_opcode (operands[1]);
3187 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3188 (set_attr "mode" "XF,XF,XF,SI,SI")])
3190 (define_expand "movtf"
3191 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3192 (match_operand:TF 1 "nonimmediate_operand" ""))]
3195 ix86_expand_move (TFmode, operands);
3199 (define_insn "*movtf_internal"
3200 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3201 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3203 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3205 switch (which_alternative)
3209 if (get_attr_mode (insn) == MODE_V4SF)
3210 return "movaps\t{%1, %0|%0, %1}";
3212 return "movdqa\t{%1, %0|%0, %1}";
3214 if (get_attr_mode (insn) == MODE_V4SF)
3215 return "xorps\t%0, %0";
3217 return "pxor\t%0, %0";
3225 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3227 (cond [(eq_attr "alternative" "0,2")
3229 (ne (symbol_ref "optimize_size")
3231 (const_string "V4SF")
3232 (const_string "TI"))
3233 (eq_attr "alternative" "1")
3235 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3237 (ne (symbol_ref "optimize_size")
3239 (const_string "V4SF")
3240 (const_string "TI"))]
3241 (const_string "DI")))])
3244 [(set (match_operand 0 "nonimmediate_operand" "")
3245 (match_operand 1 "general_operand" ""))]
3247 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3248 && GET_MODE (operands[0]) == XFmode
3249 && ! (ANY_FP_REG_P (operands[0]) ||
3250 (GET_CODE (operands[0]) == SUBREG
3251 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3252 && ! (ANY_FP_REG_P (operands[1]) ||
3253 (GET_CODE (operands[1]) == SUBREG
3254 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3256 "ix86_split_long_move (operands); DONE;")
3259 [(set (match_operand 0 "register_operand" "")
3260 (match_operand 1 "memory_operand" ""))]
3262 && MEM_P (operands[1])
3263 && (GET_MODE (operands[0]) == TFmode
3264 || GET_MODE (operands[0]) == XFmode
3265 || GET_MODE (operands[0]) == SFmode
3266 || GET_MODE (operands[0]) == DFmode)
3267 && (operands[2] = find_constant_src (insn))"
3268 [(set (match_dup 0) (match_dup 2))]
3270 rtx c = operands[2];
3271 rtx r = operands[0];
3273 if (GET_CODE (r) == SUBREG)
3278 if (!standard_sse_constant_p (c))
3281 else if (FP_REG_P (r))
3283 if (!standard_80387_constant_p (c))
3286 else if (MMX_REG_P (r))
3291 [(set (match_operand 0 "register_operand" "")
3292 (float_extend (match_operand 1 "memory_operand" "")))]
3294 && MEM_P (operands[1])
3295 && (GET_MODE (operands[0]) == TFmode
3296 || GET_MODE (operands[0]) == XFmode
3297 || GET_MODE (operands[0]) == SFmode
3298 || GET_MODE (operands[0]) == DFmode)
3299 && (operands[2] = find_constant_src (insn))"
3300 [(set (match_dup 0) (match_dup 2))]
3302 rtx c = operands[2];
3303 rtx r = operands[0];
3305 if (GET_CODE (r) == SUBREG)
3310 if (!standard_sse_constant_p (c))
3313 else if (FP_REG_P (r))
3315 if (!standard_80387_constant_p (c))
3318 else if (MMX_REG_P (r))
3322 (define_insn "swapxf"
3323 [(set (match_operand:XF 0 "register_operand" "+f")
3324 (match_operand:XF 1 "register_operand" "+f"))
3329 if (STACK_TOP_P (operands[0]))
3334 [(set_attr "type" "fxch")
3335 (set_attr "mode" "XF")])
3337 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3339 [(set (match_operand:X87MODEF 0 "register_operand" "")
3340 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3341 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3342 && (standard_80387_constant_p (operands[1]) == 8
3343 || standard_80387_constant_p (operands[1]) == 9)"
3344 [(set (match_dup 0)(match_dup 1))
3346 (neg:X87MODEF (match_dup 0)))]
3350 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3351 if (real_isnegzero (&r))
3352 operands[1] = CONST0_RTX (<MODE>mode);
3354 operands[1] = CONST1_RTX (<MODE>mode);
3358 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3359 (match_operand:TF 1 "general_operand" ""))]
3361 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3363 "ix86_split_long_move (operands); DONE;")
3365 ;; Zero extension instructions
3367 (define_expand "zero_extendhisi2"
3368 [(set (match_operand:SI 0 "register_operand" "")
3369 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3372 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3374 operands[1] = force_reg (HImode, operands[1]);
3375 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3380 (define_insn "zero_extendhisi2_and"
3381 [(set (match_operand:SI 0 "register_operand" "=r")
3382 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3383 (clobber (reg:CC FLAGS_REG))]
3384 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3386 [(set_attr "type" "alu1")
3387 (set_attr "mode" "SI")])
3390 [(set (match_operand:SI 0 "register_operand" "")
3391 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3392 (clobber (reg:CC FLAGS_REG))]
3393 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3394 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3395 (clobber (reg:CC FLAGS_REG))])]
3398 (define_insn "*zero_extendhisi2_movzwl"
3399 [(set (match_operand:SI 0 "register_operand" "=r")
3400 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3401 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3402 "movz{wl|x}\t{%1, %0|%0, %1}"
3403 [(set_attr "type" "imovx")
3404 (set_attr "mode" "SI")])
3406 (define_expand "zero_extendqihi2"
3408 [(set (match_operand:HI 0 "register_operand" "")
3409 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3410 (clobber (reg:CC FLAGS_REG))])]
3414 (define_insn "*zero_extendqihi2_and"
3415 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3416 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3417 (clobber (reg:CC FLAGS_REG))]
3418 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3420 [(set_attr "type" "alu1")
3421 (set_attr "mode" "HI")])
3423 (define_insn "*zero_extendqihi2_movzbw_and"
3424 [(set (match_operand:HI 0 "register_operand" "=r,r")
3425 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3426 (clobber (reg:CC FLAGS_REG))]
3427 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3429 [(set_attr "type" "imovx,alu1")
3430 (set_attr "mode" "HI")])
3432 ; zero extend to SImode here to avoid partial register stalls
3433 (define_insn "*zero_extendqihi2_movzbl"
3434 [(set (match_operand:HI 0 "register_operand" "=r")
3435 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3436 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3437 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3438 [(set_attr "type" "imovx")
3439 (set_attr "mode" "SI")])
3441 ;; For the movzbw case strip only the clobber
3443 [(set (match_operand:HI 0 "register_operand" "")
3444 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3445 (clobber (reg:CC FLAGS_REG))]
3447 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3448 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3449 [(set (match_operand:HI 0 "register_operand" "")
3450 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3452 ;; When source and destination does not overlap, clear destination
3453 ;; first and then do the movb
3455 [(set (match_operand:HI 0 "register_operand" "")
3456 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3457 (clobber (reg:CC FLAGS_REG))]
3459 && ANY_QI_REG_P (operands[0])
3460 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3461 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3462 [(set (match_dup 0) (const_int 0))
3463 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3464 "operands[2] = gen_lowpart (QImode, operands[0]);")
3466 ;; Rest is handled by single and.
3468 [(set (match_operand:HI 0 "register_operand" "")
3469 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3470 (clobber (reg:CC FLAGS_REG))]
3472 && true_regnum (operands[0]) == true_regnum (operands[1])"
3473 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3474 (clobber (reg:CC FLAGS_REG))])]
3477 (define_expand "zero_extendqisi2"
3479 [(set (match_operand:SI 0 "register_operand" "")
3480 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3481 (clobber (reg:CC FLAGS_REG))])]
3485 (define_insn "*zero_extendqisi2_and"
3486 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3487 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3488 (clobber (reg:CC FLAGS_REG))]
3489 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3491 [(set_attr "type" "alu1")
3492 (set_attr "mode" "SI")])
3494 (define_insn "*zero_extendqisi2_movzbw_and"
3495 [(set (match_operand:SI 0 "register_operand" "=r,r")
3496 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3497 (clobber (reg:CC FLAGS_REG))]
3498 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3500 [(set_attr "type" "imovx,alu1")
3501 (set_attr "mode" "SI")])
3503 (define_insn "*zero_extendqisi2_movzbw"
3504 [(set (match_operand:SI 0 "register_operand" "=r")
3505 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3506 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3507 "movz{bl|x}\t{%1, %0|%0, %1}"
3508 [(set_attr "type" "imovx")
3509 (set_attr "mode" "SI")])
3511 ;; For the movzbl case strip only the clobber
3513 [(set (match_operand:SI 0 "register_operand" "")
3514 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3515 (clobber (reg:CC FLAGS_REG))]
3517 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3518 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3520 (zero_extend:SI (match_dup 1)))])
3522 ;; When source and destination does not overlap, clear destination
3523 ;; first and then do the movb
3525 [(set (match_operand:SI 0 "register_operand" "")
3526 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3527 (clobber (reg:CC FLAGS_REG))]
3529 && ANY_QI_REG_P (operands[0])
3530 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3531 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3532 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3533 [(set (match_dup 0) (const_int 0))
3534 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3535 "operands[2] = gen_lowpart (QImode, operands[0]);")
3537 ;; Rest is handled by single and.
3539 [(set (match_operand:SI 0 "register_operand" "")
3540 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3541 (clobber (reg:CC FLAGS_REG))]
3543 && true_regnum (operands[0]) == true_regnum (operands[1])"
3544 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3545 (clobber (reg:CC FLAGS_REG))])]
3548 ;; %%% Kill me once multi-word ops are sane.
3549 (define_expand "zero_extendsidi2"
3550 [(set (match_operand:DI 0 "register_operand" "")
3551 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3556 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3561 (define_insn "zero_extendsidi2_32"
3562 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Yt")
3564 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3565 (clobber (reg:CC FLAGS_REG))]
3571 movd\t{%1, %0|%0, %1}
3572 movd\t{%1, %0|%0, %1}
3573 movd\t{%1, %0|%0, %1}
3574 movd\t{%1, %0|%0, %1}"
3575 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3576 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3578 (define_insn "zero_extendsidi2_rex64"
3579 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Yt")
3581 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3584 mov\t{%k1, %k0|%k0, %k1}
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 "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3591 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3594 [(set (match_operand:DI 0 "memory_operand" "")
3595 (zero_extend:DI (match_dup 0)))]
3597 [(set (match_dup 4) (const_int 0))]
3598 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3601 [(set (match_operand:DI 0 "register_operand" "")
3602 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3603 (clobber (reg:CC FLAGS_REG))]
3604 "!TARGET_64BIT && reload_completed
3605 && true_regnum (operands[0]) == true_regnum (operands[1])"
3606 [(set (match_dup 4) (const_int 0))]
3607 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3610 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3611 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3612 (clobber (reg:CC FLAGS_REG))]
3613 "!TARGET_64BIT && reload_completed
3614 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3615 [(set (match_dup 3) (match_dup 1))
3616 (set (match_dup 4) (const_int 0))]
3617 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3619 (define_insn "zero_extendhidi2"
3620 [(set (match_operand:DI 0 "register_operand" "=r")
3621 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3623 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3624 [(set_attr "type" "imovx")
3625 (set_attr "mode" "DI")])
3627 (define_insn "zero_extendqidi2"
3628 [(set (match_operand:DI 0 "register_operand" "=r")
3629 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3631 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3632 [(set_attr "type" "imovx")
3633 (set_attr "mode" "DI")])
3635 ;; Sign extension instructions
3637 (define_expand "extendsidi2"
3638 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3639 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3640 (clobber (reg:CC FLAGS_REG))
3641 (clobber (match_scratch:SI 2 ""))])]
3646 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3651 (define_insn "*extendsidi2_1"
3652 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3653 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3654 (clobber (reg:CC FLAGS_REG))
3655 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3659 (define_insn "extendsidi2_rex64"
3660 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3661 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3665 movs{lq|x}\t{%1,%0|%0, %1}"
3666 [(set_attr "type" "imovx")
3667 (set_attr "mode" "DI")
3668 (set_attr "prefix_0f" "0")
3669 (set_attr "modrm" "0,1")])
3671 (define_insn "extendhidi2"
3672 [(set (match_operand:DI 0 "register_operand" "=r")
3673 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3675 "movs{wq|x}\t{%1,%0|%0, %1}"
3676 [(set_attr "type" "imovx")
3677 (set_attr "mode" "DI")])
3679 (define_insn "extendqidi2"
3680 [(set (match_operand:DI 0 "register_operand" "=r")
3681 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3683 "movs{bq|x}\t{%1,%0|%0, %1}"
3684 [(set_attr "type" "imovx")
3685 (set_attr "mode" "DI")])
3687 ;; Extend to memory case when source register does die.
3689 [(set (match_operand:DI 0 "memory_operand" "")
3690 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3691 (clobber (reg:CC FLAGS_REG))
3692 (clobber (match_operand:SI 2 "register_operand" ""))]
3694 && dead_or_set_p (insn, operands[1])
3695 && !reg_mentioned_p (operands[1], operands[0]))"
3696 [(set (match_dup 3) (match_dup 1))
3697 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3698 (clobber (reg:CC FLAGS_REG))])
3699 (set (match_dup 4) (match_dup 1))]
3700 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3702 ;; Extend to memory case when source register does not 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" ""))]
3711 split_di (&operands[0], 1, &operands[3], &operands[4]);
3713 emit_move_insn (operands[3], operands[1]);
3715 /* Generate a cltd if possible and doing so it profitable. */
3716 if ((optimize_size || TARGET_USE_CLTD)
3717 && true_regnum (operands[1]) == 0
3718 && true_regnum (operands[2]) == 1)
3720 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3724 emit_move_insn (operands[2], operands[1]);
3725 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3727 emit_move_insn (operands[4], operands[2]);
3731 ;; Extend to register case. Optimize case where source and destination
3732 ;; registers match and cases where we can use cltd.
3734 [(set (match_operand:DI 0 "register_operand" "")
3735 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3736 (clobber (reg:CC FLAGS_REG))
3737 (clobber (match_scratch:SI 2 ""))]
3741 split_di (&operands[0], 1, &operands[3], &operands[4]);
3743 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3744 emit_move_insn (operands[3], operands[1]);
3746 /* Generate a cltd if possible and doing so it profitable. */
3747 if ((optimize_size || TARGET_USE_CLTD)
3748 && true_regnum (operands[3]) == 0)
3750 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3754 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3755 emit_move_insn (operands[4], operands[1]);
3757 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3761 (define_insn "extendhisi2"
3762 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3763 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3766 switch (get_attr_prefix_0f (insn))
3769 return "{cwtl|cwde}";
3771 return "movs{wl|x}\t{%1,%0|%0, %1}";
3774 [(set_attr "type" "imovx")
3775 (set_attr "mode" "SI")
3776 (set (attr "prefix_0f")
3777 ;; movsx is short decodable while cwtl is vector decoded.
3778 (if_then_else (and (eq_attr "cpu" "!k6")
3779 (eq_attr "alternative" "0"))
3781 (const_string "1")))
3783 (if_then_else (eq_attr "prefix_0f" "0")
3785 (const_string "1")))])
3787 (define_insn "*extendhisi2_zext"
3788 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3790 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3793 switch (get_attr_prefix_0f (insn))
3796 return "{cwtl|cwde}";
3798 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3801 [(set_attr "type" "imovx")
3802 (set_attr "mode" "SI")
3803 (set (attr "prefix_0f")
3804 ;; movsx is short decodable while cwtl is vector decoded.
3805 (if_then_else (and (eq_attr "cpu" "!k6")
3806 (eq_attr "alternative" "0"))
3808 (const_string "1")))
3810 (if_then_else (eq_attr "prefix_0f" "0")
3812 (const_string "1")))])
3814 (define_insn "extendqihi2"
3815 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3816 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3819 switch (get_attr_prefix_0f (insn))
3822 return "{cbtw|cbw}";
3824 return "movs{bw|x}\t{%1,%0|%0, %1}";
3827 [(set_attr "type" "imovx")
3828 (set_attr "mode" "HI")
3829 (set (attr "prefix_0f")
3830 ;; movsx is short decodable while cwtl is vector decoded.
3831 (if_then_else (and (eq_attr "cpu" "!k6")
3832 (eq_attr "alternative" "0"))
3834 (const_string "1")))
3836 (if_then_else (eq_attr "prefix_0f" "0")
3838 (const_string "1")))])
3840 (define_insn "extendqisi2"
3841 [(set (match_operand:SI 0 "register_operand" "=r")
3842 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3844 "movs{bl|x}\t{%1,%0|%0, %1}"
3845 [(set_attr "type" "imovx")
3846 (set_attr "mode" "SI")])
3848 (define_insn "*extendqisi2_zext"
3849 [(set (match_operand:DI 0 "register_operand" "=r")
3851 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3853 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3854 [(set_attr "type" "imovx")
3855 (set_attr "mode" "SI")])
3857 ;; Conversions between float and double.
3859 ;; These are all no-ops in the model used for the 80387. So just
3862 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3863 (define_insn "*dummy_extendsfdf2"
3864 [(set (match_operand:DF 0 "push_operand" "=<")
3865 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3870 [(set (match_operand:DF 0 "push_operand" "")
3871 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3873 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3874 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3877 [(set (match_operand:DF 0 "push_operand" "")
3878 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3880 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3881 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3883 (define_insn "*dummy_extendsfxf2"
3884 [(set (match_operand:XF 0 "push_operand" "=<")
3885 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3890 [(set (match_operand:XF 0 "push_operand" "")
3891 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3893 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3894 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3895 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3898 [(set (match_operand:XF 0 "push_operand" "")
3899 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3901 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3902 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3903 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3906 [(set (match_operand:XF 0 "push_operand" "")
3907 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3909 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3910 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3911 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3914 [(set (match_operand:XF 0 "push_operand" "")
3915 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3917 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3918 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3919 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3921 (define_expand "extendsfdf2"
3922 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3923 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3924 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3926 /* ??? Needed for compress_float_constant since all fp constants
3927 are LEGITIMATE_CONSTANT_P. */
3928 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3930 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3931 && standard_80387_constant_p (operands[1]) > 0)
3933 operands[1] = simplify_const_unary_operation
3934 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3935 emit_move_insn_1 (operands[0], operands[1]);
3938 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3942 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3944 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3946 We do the conversion post reload to avoid producing of 128bit spills
3947 that might lead to ICE on 32bit target. The sequence unlikely combine
3950 [(set (match_operand:DF 0 "register_operand" "")
3952 (match_operand:SF 1 "nonimmediate_operand" "")))]
3953 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3954 && reload_completed && SSE_REG_P (operands[0])"
3959 (parallel [(const_int 0) (const_int 1)]))))]
3961 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3962 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3963 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3964 Try to avoid move when unpacking can be done in source. */
3965 if (REG_P (operands[1]))
3967 /* If it is unsafe to overwrite upper half of source, we need
3968 to move to destination and unpack there. */
3969 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3970 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3971 && true_regnum (operands[0]) != true_regnum (operands[1]))
3973 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3974 emit_move_insn (tmp, operands[1]);
3977 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3978 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3981 emit_insn (gen_vec_setv4sf_0 (operands[3],
3982 CONST0_RTX (V4SFmode), operands[1]));
3985 (define_insn "*extendsfdf2_mixed"
3986 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3988 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3989 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3991 switch (which_alternative)
3995 return output_387_reg_move (insn, operands);
3998 return "cvtss2sd\t{%1, %0|%0, %1}";
4004 [(set_attr "type" "fmov,fmov,ssecvt")
4005 (set_attr "mode" "SF,XF,DF")])
4007 (define_insn "*extendsfdf2_sse"
4008 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4009 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4010 "TARGET_SSE2 && TARGET_SSE_MATH"
4011 "cvtss2sd\t{%1, %0|%0, %1}"
4012 [(set_attr "type" "ssecvt")
4013 (set_attr "mode" "DF")])
4015 (define_insn "*extendsfdf2_i387"
4016 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4017 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4019 "* return output_387_reg_move (insn, operands);"
4020 [(set_attr "type" "fmov")
4021 (set_attr "mode" "SF,XF")])
4023 (define_expand "extend<mode>xf2"
4024 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4025 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4028 /* ??? Needed for compress_float_constant since all fp constants
4029 are LEGITIMATE_CONSTANT_P. */
4030 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4032 if (standard_80387_constant_p (operands[1]) > 0)
4034 operands[1] = simplify_const_unary_operation
4035 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4036 emit_move_insn_1 (operands[0], operands[1]);
4039 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4043 (define_insn "*extend<mode>xf2_i387"
4044 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4046 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4048 "* return output_387_reg_move (insn, operands);"
4049 [(set_attr "type" "fmov")
4050 (set_attr "mode" "<MODE>,XF")])
4052 ;; %%% This seems bad bad news.
4053 ;; This cannot output into an f-reg because there is no way to be sure
4054 ;; of truncating in that case. Otherwise this is just like a simple move
4055 ;; insn. So we pretend we can output to a reg in order to get better
4056 ;; register preferencing, but we really use a stack slot.
4058 ;; Conversion from DFmode to SFmode.
4060 (define_expand "truncdfsf2"
4061 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4063 (match_operand:DF 1 "nonimmediate_operand" "")))]
4064 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4066 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4068 else if (flag_unsafe_math_optimizations)
4072 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
4073 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4078 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4080 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4082 We do the conversion post reload to avoid producing of 128bit spills
4083 that might lead to ICE on 32bit target. The sequence unlikely combine
4086 [(set (match_operand:SF 0 "register_operand" "")
4088 (match_operand:DF 1 "nonimmediate_operand" "")))]
4089 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4090 && reload_completed && SSE_REG_P (operands[0])"
4093 (float_truncate:V2SF
4097 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4098 operands[3] = CONST0_RTX (V2SFmode);
4099 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4100 /* Use movsd for loading from memory, unpcklpd for registers.
4101 Try to avoid move when unpacking can be done in source, or SSE3
4102 movddup is available. */
4103 if (REG_P (operands[1]))
4106 && true_regnum (operands[0]) != true_regnum (operands[1])
4107 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4108 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4110 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4111 emit_move_insn (tmp, operands[1]);
4114 else if (!TARGET_SSE3)
4115 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4116 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4119 emit_insn (gen_sse2_loadlpd (operands[4],
4120 CONST0_RTX (V2DFmode), operands[1]));
4123 (define_expand "truncdfsf2_with_temp"
4124 [(parallel [(set (match_operand:SF 0 "" "")
4125 (float_truncate:SF (match_operand:DF 1 "" "")))
4126 (clobber (match_operand:SF 2 "" ""))])]
4129 (define_insn "*truncdfsf_fast_mixed"
4130 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4132 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4133 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4135 switch (which_alternative)
4139 return output_387_reg_move (insn, operands);
4141 return "cvtsd2ss\t{%1, %0|%0, %1}";
4146 [(set_attr "type" "fmov,fmov,ssecvt")
4147 (set_attr "mode" "SF")])
4149 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4150 ;; because nothing we do here is unsafe.
4151 (define_insn "*truncdfsf_fast_sse"
4152 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4154 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4155 "TARGET_SSE2 && TARGET_SSE_MATH"
4156 "cvtsd2ss\t{%1, %0|%0, %1}"
4157 [(set_attr "type" "ssecvt")
4158 (set_attr "mode" "SF")])
4160 (define_insn "*truncdfsf_fast_i387"
4161 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4163 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4164 "TARGET_80387 && flag_unsafe_math_optimizations"
4165 "* return output_387_reg_move (insn, operands);"
4166 [(set_attr "type" "fmov")
4167 (set_attr "mode" "SF")])
4169 (define_insn "*truncdfsf_mixed"
4170 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Yt")
4172 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ytm")))
4173 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4174 "TARGET_MIX_SSE_I387"
4176 switch (which_alternative)
4179 return output_387_reg_move (insn, operands);
4184 return "cvtsd2ss\t{%1, %0|%0, %1}";
4189 [(set_attr "type" "fmov,multi,ssecvt")
4190 (set_attr "unit" "*,i387,*")
4191 (set_attr "mode" "SF")])
4193 (define_insn "*truncdfsf_i387"
4194 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4196 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4197 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4200 switch (which_alternative)
4203 return output_387_reg_move (insn, operands);
4211 [(set_attr "type" "fmov,multi")
4212 (set_attr "unit" "*,i387")
4213 (set_attr "mode" "SF")])
4215 (define_insn "*truncdfsf2_i387_1"
4216 [(set (match_operand:SF 0 "memory_operand" "=m")
4218 (match_operand:DF 1 "register_operand" "f")))]
4220 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4221 && !TARGET_MIX_SSE_I387"
4222 "* return output_387_reg_move (insn, operands);"
4223 [(set_attr "type" "fmov")
4224 (set_attr "mode" "SF")])
4227 [(set (match_operand:SF 0 "register_operand" "")
4229 (match_operand:DF 1 "fp_register_operand" "")))
4230 (clobber (match_operand 2 "" ""))]
4232 [(set (match_dup 2) (match_dup 1))
4233 (set (match_dup 0) (match_dup 2))]
4235 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4238 ;; Conversion from XFmode to {SF,DF}mode
4240 (define_expand "truncxf<mode>2"
4241 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4242 (float_truncate:MODEF
4243 (match_operand:XF 1 "register_operand" "")))
4244 (clobber (match_dup 2))])]
4247 if (flag_unsafe_math_optimizations)
4249 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4250 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4251 if (reg != operands[0])
4252 emit_move_insn (operands[0], reg);
4256 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_VIRTUAL);
4259 (define_insn "*truncxfsf2_mixed"
4260 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4262 (match_operand:XF 1 "register_operand" "f,f")))
4263 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4266 gcc_assert (!which_alternative);
4267 return output_387_reg_move (insn, operands);
4269 [(set_attr "type" "fmov,multi")
4270 (set_attr "unit" "*,i387")
4271 (set_attr "mode" "SF")])
4273 (define_insn "*truncxfdf2_mixed"
4274 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fYt*r")
4276 (match_operand:XF 1 "register_operand" "f,f")))
4277 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4280 gcc_assert (!which_alternative);
4281 return output_387_reg_move (insn, operands);
4283 [(set_attr "type" "fmov,multi")
4284 (set_attr "unit" "*,i387")
4285 (set_attr "mode" "DF")])
4287 (define_insn "truncxf<mode>2_i387_noop"
4288 [(set (match_operand:MODEF 0 "register_operand" "=f")
4289 (float_truncate:MODEF
4290 (match_operand:XF 1 "register_operand" "f")))]
4291 "TARGET_80387 && flag_unsafe_math_optimizations"
4292 "* return output_387_reg_move (insn, operands);"
4293 [(set_attr "type" "fmov")
4294 (set_attr "mode" "<MODE>")])
4296 (define_insn "*truncxf<mode>2_i387"
4297 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4298 (float_truncate:MODEF
4299 (match_operand:XF 1 "register_operand" "f")))]
4301 "* return output_387_reg_move (insn, operands);"
4302 [(set_attr "type" "fmov")
4303 (set_attr "mode" "<MODE>")])
4306 [(set (match_operand:MODEF 0 "register_operand" "")
4307 (float_truncate:MODEF
4308 (match_operand:XF 1 "register_operand" "")))
4309 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4310 "TARGET_80387 && reload_completed"
4311 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4312 (set (match_dup 0) (match_dup 2))]
4316 [(set (match_operand:MODEF 0 "memory_operand" "")
4317 (float_truncate:MODEF
4318 (match_operand:XF 1 "register_operand" "")))
4319 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4321 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4324 ;; Signed conversion to DImode.
4326 (define_expand "fix_truncxfdi2"
4327 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4328 (fix:DI (match_operand:XF 1 "register_operand" "")))
4329 (clobber (reg:CC FLAGS_REG))])]
4334 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4339 (define_expand "fix_trunc<mode>di2"
4340 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4341 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4342 (clobber (reg:CC FLAGS_REG))])]
4343 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4346 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4348 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4351 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4353 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4354 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4355 if (out != operands[0])
4356 emit_move_insn (operands[0], out);
4361 ;; Signed conversion to SImode.
4363 (define_expand "fix_truncxfsi2"
4364 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4365 (fix:SI (match_operand:XF 1 "register_operand" "")))
4366 (clobber (reg:CC FLAGS_REG))])]
4371 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4376 (define_expand "fix_trunc<mode>si2"
4377 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4378 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4379 (clobber (reg:CC FLAGS_REG))])]
4380 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4383 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4385 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4388 if (SSE_FLOAT_MODE_P (<MODE>mode))
4390 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4391 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4392 if (out != operands[0])
4393 emit_move_insn (operands[0], out);
4398 ;; Signed conversion to HImode.
4400 (define_expand "fix_trunc<mode>hi2"
4401 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4402 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4403 (clobber (reg:CC FLAGS_REG))])]
4405 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4409 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4414 ;; Unsigned conversion to SImode.
4416 (define_expand "fixuns_trunc<mode>si2"
4418 [(set (match_operand:SI 0 "register_operand" "")
4420 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4422 (clobber (match_scratch:<ssevecmode> 3 ""))
4423 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4424 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4426 enum machine_mode mode = <MODE>mode;
4427 enum machine_mode vecmode = <ssevecmode>mode;
4428 REAL_VALUE_TYPE TWO31r;
4431 real_ldexp (&TWO31r, &dconst1, 31);
4432 two31 = const_double_from_real_value (TWO31r, mode);
4433 two31 = ix86_build_const_vector (mode, true, two31);
4434 operands[2] = force_reg (vecmode, two31);
4437 (define_insn_and_split "*fixuns_trunc<mode>_1"
4438 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4440 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4441 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4442 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4443 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4444 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4446 "&& reload_completed"
4449 ix86_split_convert_uns_si_sse (operands);
4453 ;; Unsigned conversion to HImode.
4454 ;; Without these patterns, we'll try the unsigned SI conversion which
4455 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4457 (define_expand "fixuns_trunc<mode>hi2"
4459 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4460 (set (match_operand:HI 0 "nonimmediate_operand" "")
4461 (subreg:HI (match_dup 2) 0))]
4462 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4463 "operands[2] = gen_reg_rtx (SImode);")
4465 ;; When SSE is available, it is always faster to use it!
4466 (define_insn "fix_trunc<mode>di_sse"
4467 [(set (match_operand:DI 0 "register_operand" "=r,r")
4468 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4469 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4470 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4471 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4472 [(set_attr "type" "sseicvt")
4473 (set_attr "mode" "<MODE>")
4474 (set_attr "athlon_decode" "double,vector")
4475 (set_attr "amdfam10_decode" "double,double")])
4477 (define_insn "fix_trunc<mode>si_sse"
4478 [(set (match_operand:SI 0 "register_operand" "=r,r")
4479 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4480 "SSE_FLOAT_MODE_P (<MODE>mode)
4481 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4482 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4483 [(set_attr "type" "sseicvt")
4484 (set_attr "mode" "<MODE>")
4485 (set_attr "athlon_decode" "double,vector")
4486 (set_attr "amdfam10_decode" "double,double")])
4488 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4490 [(set (match_operand:MODEF 0 "register_operand" "")
4491 (match_operand:MODEF 1 "memory_operand" ""))
4492 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4493 (fix:SSEMODEI24 (match_dup 0)))]
4494 "TARGET_SHORTEN_X87_SSE
4495 && peep2_reg_dead_p (2, operands[0])"
4496 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4499 ;; Avoid vector decoded forms of the instruction.
4501 [(match_scratch:DF 2 "Yt")
4502 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4503 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4504 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4505 [(set (match_dup 2) (match_dup 1))
4506 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4510 [(match_scratch:SF 2 "x")
4511 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4512 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4513 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4514 [(set (match_dup 2) (match_dup 1))
4515 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4518 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4519 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4520 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4521 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4523 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4524 && (TARGET_64BIT || <MODE>mode != DImode))
4526 && !(reload_completed || reload_in_progress)"
4531 if (memory_operand (operands[0], VOIDmode))
4532 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4535 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4536 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4542 [(set_attr "type" "fisttp")
4543 (set_attr "mode" "<MODE>")])
4545 (define_insn "fix_trunc<mode>_i387_fisttp"
4546 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4547 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4548 (clobber (match_scratch:XF 2 "=&1f"))]
4549 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4551 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4552 && (TARGET_64BIT || <MODE>mode != DImode))
4553 && TARGET_SSE_MATH)"
4554 "* return output_fix_trunc (insn, operands, 1);"
4555 [(set_attr "type" "fisttp")
4556 (set_attr "mode" "<MODE>")])
4558 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4559 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4560 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4561 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4562 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4563 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4565 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4566 && (TARGET_64BIT || <MODE>mode != DImode))
4567 && TARGET_SSE_MATH)"
4569 [(set_attr "type" "fisttp")
4570 (set_attr "mode" "<MODE>")])
4573 [(set (match_operand:X87MODEI 0 "register_operand" "")
4574 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4575 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4576 (clobber (match_scratch 3 ""))]
4578 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4579 (clobber (match_dup 3))])
4580 (set (match_dup 0) (match_dup 2))]
4584 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4585 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4586 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4587 (clobber (match_scratch 3 ""))]
4589 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4590 (clobber (match_dup 3))])]
4593 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4594 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4595 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4596 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4597 ;; function in i386.c.
4598 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4599 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4600 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4601 (clobber (reg:CC FLAGS_REG))]
4602 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4604 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4605 && (TARGET_64BIT || <MODE>mode != DImode))
4606 && !(reload_completed || reload_in_progress)"
4611 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4613 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4614 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4615 if (memory_operand (operands[0], VOIDmode))
4616 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4617 operands[2], operands[3]));
4620 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4621 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4622 operands[2], operands[3],
4627 [(set_attr "type" "fistp")
4628 (set_attr "i387_cw" "trunc")
4629 (set_attr "mode" "<MODE>")])
4631 (define_insn "fix_truncdi_i387"
4632 [(set (match_operand:DI 0 "memory_operand" "=m")
4633 (fix:DI (match_operand 1 "register_operand" "f")))
4634 (use (match_operand:HI 2 "memory_operand" "m"))
4635 (use (match_operand:HI 3 "memory_operand" "m"))
4636 (clobber (match_scratch:XF 4 "=&1f"))]
4637 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4639 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4640 "* return output_fix_trunc (insn, operands, 0);"
4641 [(set_attr "type" "fistp")
4642 (set_attr "i387_cw" "trunc")
4643 (set_attr "mode" "DI")])
4645 (define_insn "fix_truncdi_i387_with_temp"
4646 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4647 (fix:DI (match_operand 1 "register_operand" "f,f")))
4648 (use (match_operand:HI 2 "memory_operand" "m,m"))
4649 (use (match_operand:HI 3 "memory_operand" "m,m"))
4650 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4651 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4652 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4654 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4656 [(set_attr "type" "fistp")
4657 (set_attr "i387_cw" "trunc")
4658 (set_attr "mode" "DI")])
4661 [(set (match_operand:DI 0 "register_operand" "")
4662 (fix:DI (match_operand 1 "register_operand" "")))
4663 (use (match_operand:HI 2 "memory_operand" ""))
4664 (use (match_operand:HI 3 "memory_operand" ""))
4665 (clobber (match_operand:DI 4 "memory_operand" ""))
4666 (clobber (match_scratch 5 ""))]
4668 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4671 (clobber (match_dup 5))])
4672 (set (match_dup 0) (match_dup 4))]
4676 [(set (match_operand:DI 0 "memory_operand" "")
4677 (fix:DI (match_operand 1 "register_operand" "")))
4678 (use (match_operand:HI 2 "memory_operand" ""))
4679 (use (match_operand:HI 3 "memory_operand" ""))
4680 (clobber (match_operand:DI 4 "memory_operand" ""))
4681 (clobber (match_scratch 5 ""))]
4683 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4686 (clobber (match_dup 5))])]
4689 (define_insn "fix_trunc<mode>_i387"
4690 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4691 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4692 (use (match_operand:HI 2 "memory_operand" "m"))
4693 (use (match_operand:HI 3 "memory_operand" "m"))]
4694 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4696 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4697 "* return output_fix_trunc (insn, operands, 0);"
4698 [(set_attr "type" "fistp")
4699 (set_attr "i387_cw" "trunc")
4700 (set_attr "mode" "<MODE>")])
4702 (define_insn "fix_trunc<mode>_i387_with_temp"
4703 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4704 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4705 (use (match_operand:HI 2 "memory_operand" "m,m"))
4706 (use (match_operand:HI 3 "memory_operand" "m,m"))
4707 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4708 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4710 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4712 [(set_attr "type" "fistp")
4713 (set_attr "i387_cw" "trunc")
4714 (set_attr "mode" "<MODE>")])
4717 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4718 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4719 (use (match_operand:HI 2 "memory_operand" ""))
4720 (use (match_operand:HI 3 "memory_operand" ""))
4721 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4723 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4725 (use (match_dup 3))])
4726 (set (match_dup 0) (match_dup 4))]
4730 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4731 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4732 (use (match_operand:HI 2 "memory_operand" ""))
4733 (use (match_operand:HI 3 "memory_operand" ""))
4734 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4736 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4738 (use (match_dup 3))])]
4741 (define_insn "x86_fnstcw_1"
4742 [(set (match_operand:HI 0 "memory_operand" "=m")
4743 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4746 [(set_attr "length" "2")
4747 (set_attr "mode" "HI")
4748 (set_attr "unit" "i387")])
4750 (define_insn "x86_fldcw_1"
4751 [(set (reg:HI FPCR_REG)
4752 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4755 [(set_attr "length" "2")
4756 (set_attr "mode" "HI")
4757 (set_attr "unit" "i387")
4758 (set_attr "athlon_decode" "vector")
4759 (set_attr "amdfam10_decode" "vector")])
4761 ;; Conversion between fixed point and floating point.
4763 ;; Even though we only accept memory inputs, the backend _really_
4764 ;; wants to be able to do this between registers.
4766 (define_expand "floathi<mode>2"
4767 [(set (match_operand:MODEF 0 "register_operand" "")
4768 (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4769 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4771 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4774 (gen_floatsi<mode>2 (operands[0],
4775 convert_to_mode (SImode, operands[1], 0)));
4780 (define_insn "*floathi<mode>2_i387"
4781 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4783 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4785 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4786 || TARGET_MIX_SSE_I387)"
4790 [(set_attr "type" "fmov,multi")
4791 (set_attr "mode" "<MODE>")
4792 (set_attr "unit" "*,i387")
4793 (set_attr "fp_int_src" "true")])
4795 (define_expand "floatsi<mode>2"
4796 [(set (match_operand:MODEF 0 "register_operand" "")
4797 (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4798 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4800 /* When we use vector converts, we can't have input in memory. */
4801 if (GET_MODE (operands[0]) == DFmode
4802 && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4803 && SSE_FLOAT_MODE_P (DFmode))
4804 operands[1] = force_reg (SImode, operands[1]);
4805 else if (GET_MODE (operands[0]) == SFmode
4806 && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4807 && SSE_FLOAT_MODE_P (SFmode))
4809 /* When !flag_trapping_math, we handle SImode->SFmode vector
4810 conversions same way as SImode->DFmode.
4812 For flat_trapping_math we can't safely use vector conversion without
4813 clearing upper half, otherwise precision exception might occur.
4814 However we can still generate the common sequence converting value
4815 from general register to XMM register as:
4821 because we know that movd clears the upper half.
4823 Sadly in this case we can't rely on reload moving the value to XMM
4824 register, since we need to know if upper half is OK, so we need
4825 to do reloading by hand. We force operand to memory unless target
4826 supports inter unit moves. */
4827 if (!flag_trapping_math)
4828 operands[1] = force_reg (SImode, operands[1]);
4829 else if (!MEM_P (operands[1]))
4831 rtx tmp = assign_386_stack_local (SImode, SLOT_VIRTUAL);
4832 emit_move_insn (tmp, operands[1]);
4836 /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4837 !TARGET_INTER_UNIT_CONVERSIONS
4838 It is neccesary for the patterns to not accept nonemmory operands
4839 as we would optimize out later. */
4840 else if (!TARGET_INTER_UNIT_CONVERSIONS
4841 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4843 && !MEM_P (operands[1]))
4845 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
4846 emit_move_insn (tmp, operands[1]);
4851 (define_insn "*floatsisf2_mixed_vector"
4852 [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4853 (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4854 "TARGET_MIX_SSE_I387 && !flag_trapping_math
4855 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4857 cvtdq2ps\t{%1, %0|%0, %1}
4860 [(set_attr "type" "sseicvt,fmov,multi")
4861 (set_attr "mode" "SF")
4862 (set_attr "unit" "*,i387,*")
4863 (set_attr "athlon_decode" "double,*,*")
4864 (set_attr "amdfam10_decode" "double,*,*")
4865 (set_attr "fp_int_src" "false,true,true")])
4867 (define_insn "*floatsisf2_mixed"
4868 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4869 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4870 "TARGET_MIX_SSE_I387
4871 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4876 cvtsi2ss\t{%1, %0|%0, %1}
4877 cvtsi2ss\t{%1, %0|%0, %1}"
4878 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4879 (set_attr "mode" "SF")
4880 (set_attr "unit" "*,i387,*,*")
4881 (set_attr "athlon_decode" "*,*,vector,double")
4882 (set_attr "amdfam10_decode" "*,*,vector,double")
4883 (set_attr "fp_int_src" "true")])
4885 (define_insn "*floatsisf2_mixed_memory"
4886 [(set (match_operand:SF 0 "register_operand" "=f,x")
4887 (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4888 "TARGET_MIX_SSE_I387
4889 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4892 cvtsi2ss\t{%1, %0|%0, %1}"
4893 [(set_attr "type" "fmov,sseicvt")
4894 (set_attr "mode" "SF")
4895 (set_attr "athlon_decode" "*,double")
4896 (set_attr "amdfam10_decode" "*,double")
4897 (set_attr "fp_int_src" "true")])
4899 (define_insn "*floatsisf2_sse_vector_nointernunit"
4900 [(set (match_operand:SF 0 "register_operand" "=x")
4901 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4902 "TARGET_SSE_MATH && flag_trapping_math
4903 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4904 && !TARGET_INTER_UNIT_MOVES"
4906 [(set_attr "type" "multi")])
4908 (define_insn "*floatsisf2_sse_vector_internunit"
4909 [(set (match_operand:SF 0 "register_operand" "=x,x")
4910 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4911 "TARGET_SSE_MATH && flag_trapping_math
4912 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4913 && TARGET_INTER_UNIT_MOVES"
4915 [(set_attr "type" "multi")])
4918 [(set (match_operand:SF 0 "register_operand" "")
4919 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4921 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4922 && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4923 && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4925 (float:V4SF (match_dup 2)))]
4927 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4928 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4929 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4933 [(set (match_operand:SF 0 "register_operand" "")
4934 (float:SF (match_operand:SI 1 "register_operand" "")))]
4936 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4937 && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4938 [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4940 (float:V4SF (match_dup 2)))]
4942 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4943 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4946 (define_insn "*floatsisf2_sse_vector"
4947 [(set (match_operand:SF 0 "register_operand" "=x")
4948 (float:SF (match_operand:SI 1 "register_operand" "x")))]
4949 "TARGET_SSE_MATH && !flag_trapping_math
4950 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4951 && !TARGET_INTER_UNIT_MOVES"
4952 "cvtdq2ps\t{%1, %0|%0, %1}"
4953 [(set_attr "type" "sseicvt")
4954 (set_attr "mode" "SF")
4955 (set_attr "athlon_decode" "double")
4956 (set_attr "amdfam10_decode" "double")
4957 (set_attr "fp_int_src" "true")])
4959 (define_insn "*floatsisf2_sse"
4960 [(set (match_operand:SF 0 "register_operand" "=x,x")
4961 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4963 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4965 "cvtsi2ss\t{%1, %0|%0, %1}"
4966 [(set_attr "type" "sseicvt")
4967 (set_attr "mode" "SF")
4968 (set_attr "athlon_decode" "vector,double")
4969 (set_attr "amdfam10_decode" "vector,double")
4970 (set_attr "fp_int_src" "true")])
4972 (define_insn "*floatsisf2_sse_memory"
4973 [(set (match_operand:SF 0 "register_operand" "=x")
4974 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4976 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4977 "cvtsi2ss\t{%1, %0|%0, %1}"
4978 [(set_attr "type" "sseicvt")
4979 (set_attr "mode" "SF")
4980 (set_attr "athlon_decode" "double")
4981 (set_attr "amdfam10_decode" "double")
4982 (set_attr "fp_int_src" "true")])
4984 (define_insn "*floatsidf2_mixed_vector"
4985 [(set (match_operand:DF 0 "register_operand" "=x,f,f")
4986 (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4987 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4988 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4990 cvtdq2pd\t{%1, %0|%0, %1}
4993 [(set_attr "type" "sseicvt,fmov,multi")
4994 (set_attr "mode" "V2DF,DF,DF")
4995 (set_attr "unit" "*,*,i387")
4996 (set_attr "athlon_decode" "double,*,*")
4997 (set_attr "amdfam10_decode" "double,*,*")
4998 (set_attr "fp_int_src" "false,true,true")])
5000 (define_insn "*floatsidf2_mixed"
5001 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5002 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5003 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5004 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5009 cvtsi2sd\t{%1, %0|%0, %1}
5010 cvtsi2sd\t{%1, %0|%0, %1}
5011 cvtdq2pd\t{%1, %0|%0, %1}"
5012 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5013 (set_attr "mode" "DF,DF,DF,DF,V2DF")
5014 (set_attr "unit" "*,i387,*,*,*")
5015 (set_attr "athlon_decode" "*,*,double,direct,double")
5016 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5017 (set_attr "fp_int_src" "true,true,true,true,false")])
5019 (define_insn "*floatsidf2_mixed_memory"
5020 [(set (match_operand:DF 0 "register_operand" "=f,x")
5021 (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5022 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5023 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5026 cvtsi2sd\t{%1, %0|%0, %1}"
5027 [(set_attr "type" "fmov,sseicvt")
5028 (set_attr "mode" "DF")
5029 (set_attr "athlon_decode" "*,direct")
5030 (set_attr "amdfam10_decode" "*,double")
5031 (set_attr "fp_int_src" "true")])
5033 (define_insn "*floatsidf2_sse_vector"
5034 [(set (match_operand:DF 0 "register_operand" "=x")
5035 (float:DF (match_operand:SI 1 "register_operand" "x")))]
5036 "TARGET_SSE2 && TARGET_SSE_MATH
5037 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5038 "cvtdq2pd\t{%1, %0|%0, %1}"
5039 [(set_attr "type" "sseicvt")
5040 (set_attr "mode" "V2DF")
5041 (set_attr "athlon_decode" "double")
5042 (set_attr "amdfam10_decode" "double")
5043 (set_attr "fp_int_src" "true")])
5046 [(set (match_operand:DF 0 "register_operand" "")
5047 (float:DF (match_operand:SI 1 "memory_operand" "")))]
5048 "TARGET_USE_VECTOR_CONVERTS && reload_completed
5049 && SSE_REG_P (operands[0])"
5054 (parallel [(const_int 0) (const_int 1)]))))]
5056 operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5057 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5058 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5061 (define_insn "*floatsidf2_sse"
5062 [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5063 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5064 "TARGET_SSE2 && TARGET_SSE_MATH
5065 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5068 cvtsi2sd\t{%1, %0|%0, %1}
5069 cvtsi2sd\t{%1, %0|%0, %1}
5070 cvtdq2pd\t{%1, %0|%0, %1}"
5071 [(set_attr "type" "sseicvt")
5072 (set_attr "mode" "DF,DF,V2DF")
5073 (set_attr "athlon_decode" "double,direct,double")
5074 (set_attr "amdfam10_decode" "vector,double,double")
5075 (set_attr "fp_int_src" "true")])
5077 (define_insn "*floatsidf2_memory"
5078 [(set (match_operand:DF 0 "register_operand" "=x")
5079 (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5080 "TARGET_SSE2 && TARGET_SSE_MATH
5081 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5083 "cvtsi2sd\t{%1, %0|%0, %1}"
5084 [(set_attr "type" "sseicvt")
5085 (set_attr "mode" "DF")
5086 (set_attr "athlon_decode" "direct")
5087 (set_attr "amdfam10_decode" "double")
5088 (set_attr "fp_int_src" "true")])
5090 (define_insn "*floatsi<mode>2_i387"
5091 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5093 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5095 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5099 [(set_attr "type" "fmov,multi")
5100 (set_attr "mode" "<MODE>")
5101 (set_attr "unit" "*,i387")
5102 (set_attr "fp_int_src" "true")])
5104 (define_expand "floatdisf2"
5105 [(set (match_operand:SF 0 "register_operand" "")
5106 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5107 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5109 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5110 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5112 && !MEM_P (operands[1]))
5114 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
5115 emit_move_insn (tmp, operands[1]);
5120 (define_insn "*floatdisf2_mixed"
5121 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5122 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5123 "TARGET_64BIT && TARGET_MIX_SSE_I387
5124 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5128 cvtsi2ss{q}\t{%1, %0|%0, %1}
5129 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5130 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5131 (set_attr "mode" "SF")
5132 (set_attr "unit" "*,i387,*,*")
5133 (set_attr "athlon_decode" "*,*,vector,double")
5134 (set_attr "amdfam10_decode" "*,*,vector,double")
5135 (set_attr "fp_int_src" "true")])
5137 (define_insn "*floatdisf2_mixed"
5138 [(set (match_operand:SF 0 "register_operand" "=f,x")
5139 (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5140 "TARGET_64BIT && TARGET_MIX_SSE_I387
5141 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5144 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5145 [(set_attr "type" "fmov,sseicvt")
5146 (set_attr "mode" "SF")
5147 (set_attr "athlon_decode" "*,double")
5148 (set_attr "amdfam10_decode" "*,double")
5149 (set_attr "fp_int_src" "true")])
5151 (define_insn "*floatdisf2_sse"
5152 [(set (match_operand:SF 0 "register_operand" "=x,x")
5153 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5154 "TARGET_64BIT && TARGET_SSE_MATH
5155 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5156 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5157 [(set_attr "type" "sseicvt")
5158 (set_attr "mode" "SF")
5159 (set_attr "athlon_decode" "vector,double")
5160 (set_attr "amdfam10_decode" "vector,double")
5161 (set_attr "fp_int_src" "true")])
5163 (define_insn "*floatdisf2_memory"
5164 [(set (match_operand:SF 0 "register_operand" "=x")
5165 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5166 "TARGET_64BIT && TARGET_SSE_MATH
5167 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5168 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5169 [(set_attr "type" "sseicvt")
5170 (set_attr "mode" "SF")
5171 (set_attr "athlon_decode" "double")
5172 (set_attr "amdfam10_decode" "double")
5173 (set_attr "fp_int_src" "true")])
5175 (define_expand "floatdidf2"
5176 [(set (match_operand:DF 0 "register_operand" "")
5177 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5178 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5180 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5182 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5185 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5186 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5188 && !MEM_P (operands[1]))
5190 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
5191 emit_move_insn (tmp, operands[1]);
5196 (define_insn "*floatdidf2_mixed"
5197 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5198 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5199 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5200 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5204 cvtsi2sd{q}\t{%1, %0|%0, %1}
5205 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5206 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5207 (set_attr "mode" "DF")
5208 (set_attr "unit" "*,i387,*,*")
5209 (set_attr "athlon_decode" "*,*,double,direct")
5210 (set_attr "amdfam10_decode" "*,*,vector,double")
5211 (set_attr "fp_int_src" "true")])
5213 (define_insn "*floatdidf2_mixed_memory"
5214 [(set (match_operand:DF 0 "register_operand" "=f,x")
5215 (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5216 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5217 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5220 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5221 [(set_attr "type" "fmov,sseicvt")
5222 (set_attr "mode" "DF")
5223 (set_attr "athlon_decode" "*,direct")
5224 (set_attr "amdfam10_decode" "*,double")
5225 (set_attr "fp_int_src" "true")])
5227 (define_insn "*floatdidf2_sse"
5228 [(set (match_operand:DF 0 "register_operand" "=x,x")
5229 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5230 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5231 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5232 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5233 [(set_attr "type" "sseicvt")
5234 (set_attr "mode" "DF")
5235 (set_attr "athlon_decode" "double,direct")
5236 (set_attr "amdfam10_decode" "vector,double")
5237 (set_attr "fp_int_src" "true")])
5239 (define_insn "*floatdidf2_sse_memory"
5240 [(set (match_operand:DF 0 "register_operand" "=x")
5241 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5242 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5243 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5244 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5245 [(set_attr "type" "sseicvt")
5246 (set_attr "mode" "DF")
5247 (set_attr "athlon_decode" "direct")
5248 (set_attr "amdfam10_decode" "double")
5249 (set_attr "fp_int_src" "true")])
5251 (define_insn "*floatdi<mode>2_i387"
5252 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5254 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5256 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5260 [(set_attr "type" "fmov,multi")
5261 (set_attr "mode" "<MODE>")
5262 (set_attr "unit" "*,i387")
5263 (set_attr "fp_int_src" "true")])
5265 (define_insn "float<mode>xf2"
5266 [(set (match_operand:XF 0 "register_operand" "=f,f")
5267 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5272 [(set_attr "type" "fmov,multi")
5273 (set_attr "mode" "XF")
5274 (set_attr "unit" "*,i387")
5275 (set_attr "fp_int_src" "true")])
5277 ;; %%% Kill these when reload knows how to do it.
5279 [(set (match_operand 0 "fp_register_operand" "")
5280 (float (match_operand 1 "register_operand" "")))]
5282 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5285 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5286 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5287 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5288 ix86_free_from_memory (GET_MODE (operands[1]));
5292 (define_expand "floatunssisf2"
5293 [(use (match_operand:SF 0 "register_operand" ""))
5294 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5297 if (TARGET_SSE_MATH && TARGET_SSE2)
5298 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5300 x86_emit_floatuns (operands);
5304 (define_expand "floatunssidf2"
5305 [(use (match_operand:DF 0 "register_operand" ""))
5306 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5307 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5308 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5310 (define_expand "floatunsdisf2"
5311 [(use (match_operand:SF 0 "register_operand" ""))
5312 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5313 "TARGET_64BIT && TARGET_SSE_MATH"
5314 "x86_emit_floatuns (operands); DONE;")
5316 (define_expand "floatunsdidf2"
5317 [(use (match_operand:DF 0 "register_operand" ""))
5318 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5319 "TARGET_SSE_MATH && TARGET_SSE2
5320 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5323 x86_emit_floatuns (operands);
5325 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5331 ;; %%% splits for addditi3
5333 (define_expand "addti3"
5334 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5335 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5336 (match_operand:TI 2 "x86_64_general_operand" "")))
5337 (clobber (reg:CC FLAGS_REG))]
5339 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5341 (define_insn "*addti3_1"
5342 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5343 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5344 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5345 (clobber (reg:CC FLAGS_REG))]
5346 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5350 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5351 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5352 (match_operand:TI 2 "x86_64_general_operand" "")))
5353 (clobber (reg:CC FLAGS_REG))]
5354 "TARGET_64BIT && reload_completed"
5355 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5357 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5358 (parallel [(set (match_dup 3)
5359 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5362 (clobber (reg:CC FLAGS_REG))])]
5363 "split_ti (operands+0, 1, operands+0, operands+3);
5364 split_ti (operands+1, 1, operands+1, operands+4);
5365 split_ti (operands+2, 1, operands+2, operands+5);")
5367 ;; %%% splits for addsidi3
5368 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5369 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5370 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5372 (define_expand "adddi3"
5373 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5374 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5375 (match_operand:DI 2 "x86_64_general_operand" "")))
5376 (clobber (reg:CC FLAGS_REG))]
5378 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5380 (define_insn "*adddi3_1"
5381 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5382 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5383 (match_operand:DI 2 "general_operand" "roiF,riF")))
5384 (clobber (reg:CC FLAGS_REG))]
5385 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5389 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5390 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5391 (match_operand:DI 2 "general_operand" "")))
5392 (clobber (reg:CC FLAGS_REG))]
5393 "!TARGET_64BIT && reload_completed"
5394 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5396 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5397 (parallel [(set (match_dup 3)
5398 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5401 (clobber (reg:CC FLAGS_REG))])]
5402 "split_di (operands+0, 1, operands+0, operands+3);
5403 split_di (operands+1, 1, operands+1, operands+4);
5404 split_di (operands+2, 1, operands+2, operands+5);")
5406 (define_insn "adddi3_carry_rex64"
5407 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5408 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5409 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5410 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5411 (clobber (reg:CC FLAGS_REG))]
5412 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5413 "adc{q}\t{%2, %0|%0, %2}"
5414 [(set_attr "type" "alu")
5415 (set_attr "pent_pair" "pu")
5416 (set_attr "mode" "DI")])
5418 (define_insn "*adddi3_cc_rex64"
5419 [(set (reg:CC FLAGS_REG)
5420 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5421 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5423 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5424 (plus:DI (match_dup 1) (match_dup 2)))]
5425 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5426 "add{q}\t{%2, %0|%0, %2}"
5427 [(set_attr "type" "alu")
5428 (set_attr "mode" "DI")])
5430 (define_insn "*<addsub><mode>3_cc_overflow"
5431 [(set (reg:CCC FLAGS_REG)
5434 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5435 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5437 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5438 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5439 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5440 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5441 [(set_attr "type" "alu")
5442 (set_attr "mode" "<MODE>")])
5444 (define_insn "*add<mode>3_cconly_overflow"
5445 [(set (reg:CCC FLAGS_REG)
5447 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5448 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5450 (clobber (match_scratch:SWI 0 "=<r>"))]
5451 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5452 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5453 [(set_attr "type" "alu")
5454 (set_attr "mode" "<MODE>")])
5456 (define_insn "*sub<mode>3_cconly_overflow"
5457 [(set (reg:CCC FLAGS_REG)
5459 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5460 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5463 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5464 [(set_attr "type" "icmp")
5465 (set_attr "mode" "<MODE>")])
5467 (define_insn "*<addsub>si3_zext_cc_overflow"
5468 [(set (reg:CCC FLAGS_REG)
5470 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5471 (match_operand:SI 2 "general_operand" "g"))
5473 (set (match_operand:DI 0 "register_operand" "=r")
5474 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5475 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5476 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5477 [(set_attr "type" "alu")
5478 (set_attr "mode" "SI")])
5480 (define_insn "addqi3_carry"
5481 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5482 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5483 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5484 (match_operand:QI 2 "general_operand" "qi,qm")))
5485 (clobber (reg:CC FLAGS_REG))]
5486 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5487 "adc{b}\t{%2, %0|%0, %2}"
5488 [(set_attr "type" "alu")
5489 (set_attr "pent_pair" "pu")
5490 (set_attr "mode" "QI")])
5492 (define_insn "addhi3_carry"
5493 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5494 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5495 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5496 (match_operand:HI 2 "general_operand" "ri,rm")))
5497 (clobber (reg:CC FLAGS_REG))]
5498 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5499 "adc{w}\t{%2, %0|%0, %2}"
5500 [(set_attr "type" "alu")
5501 (set_attr "pent_pair" "pu")
5502 (set_attr "mode" "HI")])
5504 (define_insn "addsi3_carry"
5505 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5506 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5507 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5508 (match_operand:SI 2 "general_operand" "ri,rm")))
5509 (clobber (reg:CC FLAGS_REG))]
5510 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5511 "adc{l}\t{%2, %0|%0, %2}"
5512 [(set_attr "type" "alu")
5513 (set_attr "pent_pair" "pu")
5514 (set_attr "mode" "SI")])
5516 (define_insn "*addsi3_carry_zext"
5517 [(set (match_operand:DI 0 "register_operand" "=r")
5519 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5520 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5521 (match_operand:SI 2 "general_operand" "g"))))
5522 (clobber (reg:CC FLAGS_REG))]
5523 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5524 "adc{l}\t{%2, %k0|%k0, %2}"
5525 [(set_attr "type" "alu")
5526 (set_attr "pent_pair" "pu")
5527 (set_attr "mode" "SI")])
5529 (define_insn "*addsi3_cc"
5530 [(set (reg:CC FLAGS_REG)
5531 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5532 (match_operand:SI 2 "general_operand" "ri,rm")]
5534 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5535 (plus:SI (match_dup 1) (match_dup 2)))]
5536 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5537 "add{l}\t{%2, %0|%0, %2}"
5538 [(set_attr "type" "alu")
5539 (set_attr "mode" "SI")])
5541 (define_insn "addqi3_cc"
5542 [(set (reg:CC FLAGS_REG)
5543 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5544 (match_operand:QI 2 "general_operand" "qi,qm")]
5546 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5547 (plus:QI (match_dup 1) (match_dup 2)))]
5548 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5549 "add{b}\t{%2, %0|%0, %2}"
5550 [(set_attr "type" "alu")
5551 (set_attr "mode" "QI")])
5553 (define_expand "addsi3"
5554 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5555 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5556 (match_operand:SI 2 "general_operand" "")))
5557 (clobber (reg:CC FLAGS_REG))])]
5559 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5561 (define_insn "*lea_1"
5562 [(set (match_operand:SI 0 "register_operand" "=r")
5563 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5565 "lea{l}\t{%a1, %0|%0, %a1}"
5566 [(set_attr "type" "lea")
5567 (set_attr "mode" "SI")])
5569 (define_insn "*lea_1_rex64"
5570 [(set (match_operand:SI 0 "register_operand" "=r")
5571 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5573 "lea{l}\t{%a1, %0|%0, %a1}"
5574 [(set_attr "type" "lea")
5575 (set_attr "mode" "SI")])
5577 (define_insn "*lea_1_zext"
5578 [(set (match_operand:DI 0 "register_operand" "=r")
5580 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5582 "lea{l}\t{%a1, %k0|%k0, %a1}"
5583 [(set_attr "type" "lea")
5584 (set_attr "mode" "SI")])
5586 (define_insn "*lea_2_rex64"
5587 [(set (match_operand:DI 0 "register_operand" "=r")
5588 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5590 "lea{q}\t{%a1, %0|%0, %a1}"
5591 [(set_attr "type" "lea")
5592 (set_attr "mode" "DI")])
5594 ;; The lea patterns for non-Pmodes needs to be matched by several
5595 ;; insns converted to real lea by splitters.
5597 (define_insn_and_split "*lea_general_1"
5598 [(set (match_operand 0 "register_operand" "=r")
5599 (plus (plus (match_operand 1 "index_register_operand" "l")
5600 (match_operand 2 "register_operand" "r"))
5601 (match_operand 3 "immediate_operand" "i")))]
5602 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5603 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5604 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5605 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5606 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5607 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5608 || GET_MODE (operands[3]) == VOIDmode)"
5610 "&& reload_completed"
5614 operands[0] = gen_lowpart (SImode, operands[0]);
5615 operands[1] = gen_lowpart (Pmode, operands[1]);
5616 operands[2] = gen_lowpart (Pmode, operands[2]);
5617 operands[3] = gen_lowpart (Pmode, operands[3]);
5618 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5620 if (Pmode != SImode)
5621 pat = gen_rtx_SUBREG (SImode, pat, 0);
5622 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5625 [(set_attr "type" "lea")
5626 (set_attr "mode" "SI")])
5628 (define_insn_and_split "*lea_general_1_zext"
5629 [(set (match_operand:DI 0 "register_operand" "=r")
5631 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5632 (match_operand:SI 2 "register_operand" "r"))
5633 (match_operand:SI 3 "immediate_operand" "i"))))]
5636 "&& reload_completed"
5638 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5640 (match_dup 3)) 0)))]
5642 operands[1] = gen_lowpart (Pmode, operands[1]);
5643 operands[2] = gen_lowpart (Pmode, operands[2]);
5644 operands[3] = gen_lowpart (Pmode, operands[3]);
5646 [(set_attr "type" "lea")
5647 (set_attr "mode" "SI")])
5649 (define_insn_and_split "*lea_general_2"
5650 [(set (match_operand 0 "register_operand" "=r")
5651 (plus (mult (match_operand 1 "index_register_operand" "l")
5652 (match_operand 2 "const248_operand" "i"))
5653 (match_operand 3 "nonmemory_operand" "ri")))]
5654 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5655 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5656 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5657 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5658 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5659 || GET_MODE (operands[3]) == VOIDmode)"
5661 "&& reload_completed"
5665 operands[0] = gen_lowpart (SImode, operands[0]);
5666 operands[1] = gen_lowpart (Pmode, operands[1]);
5667 operands[3] = gen_lowpart (Pmode, operands[3]);
5668 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5670 if (Pmode != SImode)
5671 pat = gen_rtx_SUBREG (SImode, pat, 0);
5672 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5675 [(set_attr "type" "lea")
5676 (set_attr "mode" "SI")])
5678 (define_insn_and_split "*lea_general_2_zext"
5679 [(set (match_operand:DI 0 "register_operand" "=r")
5681 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5682 (match_operand:SI 2 "const248_operand" "n"))
5683 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5686 "&& reload_completed"
5688 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5690 (match_dup 3)) 0)))]
5692 operands[1] = gen_lowpart (Pmode, operands[1]);
5693 operands[3] = gen_lowpart (Pmode, operands[3]);
5695 [(set_attr "type" "lea")
5696 (set_attr "mode" "SI")])
5698 (define_insn_and_split "*lea_general_3"
5699 [(set (match_operand 0 "register_operand" "=r")
5700 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5701 (match_operand 2 "const248_operand" "i"))
5702 (match_operand 3 "register_operand" "r"))
5703 (match_operand 4 "immediate_operand" "i")))]
5704 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5705 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5706 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5707 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5708 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5710 "&& reload_completed"
5714 operands[0] = gen_lowpart (SImode, operands[0]);
5715 operands[1] = gen_lowpart (Pmode, operands[1]);
5716 operands[3] = gen_lowpart (Pmode, operands[3]);
5717 operands[4] = gen_lowpart (Pmode, operands[4]);
5718 pat = gen_rtx_PLUS (Pmode,
5719 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5723 if (Pmode != SImode)
5724 pat = gen_rtx_SUBREG (SImode, pat, 0);
5725 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5728 [(set_attr "type" "lea")
5729 (set_attr "mode" "SI")])
5731 (define_insn_and_split "*lea_general_3_zext"
5732 [(set (match_operand:DI 0 "register_operand" "=r")
5734 (plus:SI (plus:SI (mult:SI
5735 (match_operand:SI 1 "index_register_operand" "l")
5736 (match_operand:SI 2 "const248_operand" "n"))
5737 (match_operand:SI 3 "register_operand" "r"))
5738 (match_operand:SI 4 "immediate_operand" "i"))))]
5741 "&& reload_completed"
5743 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5746 (match_dup 4)) 0)))]
5748 operands[1] = gen_lowpart (Pmode, operands[1]);
5749 operands[3] = gen_lowpart (Pmode, operands[3]);
5750 operands[4] = gen_lowpart (Pmode, operands[4]);
5752 [(set_attr "type" "lea")
5753 (set_attr "mode" "SI")])
5755 (define_insn "*adddi_1_rex64"
5756 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5757 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5758 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5759 (clobber (reg:CC FLAGS_REG))]
5760 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5762 switch (get_attr_type (insn))
5765 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5766 return "lea{q}\t{%a2, %0|%0, %a2}";
5769 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5770 if (operands[2] == const1_rtx)
5771 return "inc{q}\t%0";
5774 gcc_assert (operands[2] == constm1_rtx);
5775 return "dec{q}\t%0";
5779 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5781 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5782 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5783 if (CONST_INT_P (operands[2])
5784 /* Avoid overflows. */
5785 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5786 && (INTVAL (operands[2]) == 128
5787 || (INTVAL (operands[2]) < 0
5788 && INTVAL (operands[2]) != -128)))
5790 operands[2] = GEN_INT (-INTVAL (operands[2]));
5791 return "sub{q}\t{%2, %0|%0, %2}";
5793 return "add{q}\t{%2, %0|%0, %2}";
5797 (cond [(eq_attr "alternative" "2")
5798 (const_string "lea")
5799 ; Current assemblers are broken and do not allow @GOTOFF in
5800 ; ought but a memory context.
5801 (match_operand:DI 2 "pic_symbolic_operand" "")
5802 (const_string "lea")
5803 (match_operand:DI 2 "incdec_operand" "")
5804 (const_string "incdec")
5806 (const_string "alu")))
5807 (set_attr "mode" "DI")])
5809 ;; Convert lea to the lea pattern to avoid flags dependency.
5811 [(set (match_operand:DI 0 "register_operand" "")
5812 (plus:DI (match_operand:DI 1 "register_operand" "")
5813 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5814 (clobber (reg:CC FLAGS_REG))]
5815 "TARGET_64BIT && reload_completed
5816 && true_regnum (operands[0]) != true_regnum (operands[1])"
5818 (plus:DI (match_dup 1)
5822 (define_insn "*adddi_2_rex64"
5823 [(set (reg FLAGS_REG)
5825 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5826 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5828 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5829 (plus:DI (match_dup 1) (match_dup 2)))]
5830 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5831 && ix86_binary_operator_ok (PLUS, DImode, operands)
5832 /* Current assemblers are broken and do not allow @GOTOFF in
5833 ought but a memory context. */
5834 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5836 switch (get_attr_type (insn))
5839 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5840 if (operands[2] == const1_rtx)
5841 return "inc{q}\t%0";
5844 gcc_assert (operands[2] == constm1_rtx);
5845 return "dec{q}\t%0";
5849 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5850 /* ???? We ought to handle there the 32bit case too
5851 - do we need new constraint? */
5852 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5853 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5854 if (CONST_INT_P (operands[2])
5855 /* Avoid overflows. */
5856 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5857 && (INTVAL (operands[2]) == 128
5858 || (INTVAL (operands[2]) < 0
5859 && INTVAL (operands[2]) != -128)))
5861 operands[2] = GEN_INT (-INTVAL (operands[2]));
5862 return "sub{q}\t{%2, %0|%0, %2}";
5864 return "add{q}\t{%2, %0|%0, %2}";
5868 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5869 (const_string "incdec")
5870 (const_string "alu")))
5871 (set_attr "mode" "DI")])
5873 (define_insn "*adddi_3_rex64"
5874 [(set (reg FLAGS_REG)
5875 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5876 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5877 (clobber (match_scratch:DI 0 "=r"))]
5879 && ix86_match_ccmode (insn, CCZmode)
5880 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5881 /* Current assemblers are broken and do not allow @GOTOFF in
5882 ought but a memory context. */
5883 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5885 switch (get_attr_type (insn))
5888 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5889 if (operands[2] == const1_rtx)
5890 return "inc{q}\t%0";
5893 gcc_assert (operands[2] == constm1_rtx);
5894 return "dec{q}\t%0";
5898 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5899 /* ???? We ought to handle there the 32bit case too
5900 - do we need new constraint? */
5901 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5902 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5903 if (CONST_INT_P (operands[2])
5904 /* Avoid overflows. */
5905 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5906 && (INTVAL (operands[2]) == 128
5907 || (INTVAL (operands[2]) < 0
5908 && INTVAL (operands[2]) != -128)))
5910 operands[2] = GEN_INT (-INTVAL (operands[2]));
5911 return "sub{q}\t{%2, %0|%0, %2}";
5913 return "add{q}\t{%2, %0|%0, %2}";
5917 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5918 (const_string "incdec")
5919 (const_string "alu")))
5920 (set_attr "mode" "DI")])
5922 ; For comparisons against 1, -1 and 128, we may generate better code
5923 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5924 ; is matched then. We can't accept general immediate, because for
5925 ; case of overflows, the result is messed up.
5926 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5928 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5929 ; only for comparisons not depending on it.
5930 (define_insn "*adddi_4_rex64"
5931 [(set (reg FLAGS_REG)
5932 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5933 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5934 (clobber (match_scratch:DI 0 "=rm"))]
5936 && ix86_match_ccmode (insn, CCGCmode)"
5938 switch (get_attr_type (insn))
5941 if (operands[2] == constm1_rtx)
5942 return "inc{q}\t%0";
5945 gcc_assert (operands[2] == const1_rtx);
5946 return "dec{q}\t%0";
5950 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5951 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5952 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5953 if ((INTVAL (operands[2]) == -128
5954 || (INTVAL (operands[2]) > 0
5955 && INTVAL (operands[2]) != 128))
5956 /* Avoid overflows. */
5957 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5958 return "sub{q}\t{%2, %0|%0, %2}";
5959 operands[2] = GEN_INT (-INTVAL (operands[2]));
5960 return "add{q}\t{%2, %0|%0, %2}";
5964 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5965 (const_string "incdec")
5966 (const_string "alu")))
5967 (set_attr "mode" "DI")])
5969 (define_insn "*adddi_5_rex64"
5970 [(set (reg FLAGS_REG)
5972 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5973 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5975 (clobber (match_scratch:DI 0 "=r"))]
5977 && ix86_match_ccmode (insn, CCGOCmode)
5978 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5979 /* Current assemblers are broken and do not allow @GOTOFF in
5980 ought but a memory context. */
5981 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5983 switch (get_attr_type (insn))
5986 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5987 if (operands[2] == const1_rtx)
5988 return "inc{q}\t%0";
5991 gcc_assert (operands[2] == constm1_rtx);
5992 return "dec{q}\t%0";
5996 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5997 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5998 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5999 if (CONST_INT_P (operands[2])
6000 /* Avoid overflows. */
6001 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6002 && (INTVAL (operands[2]) == 128
6003 || (INTVAL (operands[2]) < 0
6004 && INTVAL (operands[2]) != -128)))
6006 operands[2] = GEN_INT (-INTVAL (operands[2]));
6007 return "sub{q}\t{%2, %0|%0, %2}";
6009 return "add{q}\t{%2, %0|%0, %2}";
6013 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6014 (const_string "incdec")
6015 (const_string "alu")))
6016 (set_attr "mode" "DI")])
6019 (define_insn "*addsi_1"
6020 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6021 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6022 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6023 (clobber (reg:CC FLAGS_REG))]
6024 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6026 switch (get_attr_type (insn))
6029 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6030 return "lea{l}\t{%a2, %0|%0, %a2}";
6033 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6034 if (operands[2] == const1_rtx)
6035 return "inc{l}\t%0";
6038 gcc_assert (operands[2] == constm1_rtx);
6039 return "dec{l}\t%0";
6043 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6045 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6046 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6047 if (CONST_INT_P (operands[2])
6048 && (INTVAL (operands[2]) == 128
6049 || (INTVAL (operands[2]) < 0
6050 && INTVAL (operands[2]) != -128)))
6052 operands[2] = GEN_INT (-INTVAL (operands[2]));
6053 return "sub{l}\t{%2, %0|%0, %2}";
6055 return "add{l}\t{%2, %0|%0, %2}";
6059 (cond [(eq_attr "alternative" "2")
6060 (const_string "lea")
6061 ; Current assemblers are broken and do not allow @GOTOFF in
6062 ; ought but a memory context.
6063 (match_operand:SI 2 "pic_symbolic_operand" "")
6064 (const_string "lea")
6065 (match_operand:SI 2 "incdec_operand" "")
6066 (const_string "incdec")
6068 (const_string "alu")))
6069 (set_attr "mode" "SI")])
6071 ;; Convert lea to the lea pattern to avoid flags dependency.
6073 [(set (match_operand 0 "register_operand" "")
6074 (plus (match_operand 1 "register_operand" "")
6075 (match_operand 2 "nonmemory_operand" "")))
6076 (clobber (reg:CC FLAGS_REG))]
6078 && true_regnum (operands[0]) != true_regnum (operands[1])"
6082 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6083 may confuse gen_lowpart. */
6084 if (GET_MODE (operands[0]) != Pmode)
6086 operands[1] = gen_lowpart (Pmode, operands[1]);
6087 operands[2] = gen_lowpart (Pmode, operands[2]);
6089 operands[0] = gen_lowpart (SImode, operands[0]);
6090 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6091 if (Pmode != SImode)
6092 pat = gen_rtx_SUBREG (SImode, pat, 0);
6093 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6097 ;; It may seem that nonimmediate operand is proper one for operand 1.
6098 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6099 ;; we take care in ix86_binary_operator_ok to not allow two memory
6100 ;; operands so proper swapping will be done in reload. This allow
6101 ;; patterns constructed from addsi_1 to match.
6102 (define_insn "addsi_1_zext"
6103 [(set (match_operand:DI 0 "register_operand" "=r,r")
6105 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6106 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6107 (clobber (reg:CC FLAGS_REG))]
6108 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6110 switch (get_attr_type (insn))
6113 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6114 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6117 if (operands[2] == const1_rtx)
6118 return "inc{l}\t%k0";
6121 gcc_assert (operands[2] == constm1_rtx);
6122 return "dec{l}\t%k0";
6126 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6127 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6128 if (CONST_INT_P (operands[2])
6129 && (INTVAL (operands[2]) == 128
6130 || (INTVAL (operands[2]) < 0
6131 && INTVAL (operands[2]) != -128)))
6133 operands[2] = GEN_INT (-INTVAL (operands[2]));
6134 return "sub{l}\t{%2, %k0|%k0, %2}";
6136 return "add{l}\t{%2, %k0|%k0, %2}";
6140 (cond [(eq_attr "alternative" "1")
6141 (const_string "lea")
6142 ; Current assemblers are broken and do not allow @GOTOFF in
6143 ; ought but a memory context.
6144 (match_operand:SI 2 "pic_symbolic_operand" "")
6145 (const_string "lea")
6146 (match_operand:SI 2 "incdec_operand" "")
6147 (const_string "incdec")
6149 (const_string "alu")))
6150 (set_attr "mode" "SI")])
6152 ;; Convert lea to the lea pattern to avoid flags dependency.
6154 [(set (match_operand:DI 0 "register_operand" "")
6156 (plus:SI (match_operand:SI 1 "register_operand" "")
6157 (match_operand:SI 2 "nonmemory_operand" ""))))
6158 (clobber (reg:CC FLAGS_REG))]
6159 "TARGET_64BIT && reload_completed
6160 && true_regnum (operands[0]) != true_regnum (operands[1])"
6162 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6164 operands[1] = gen_lowpart (Pmode, operands[1]);
6165 operands[2] = gen_lowpart (Pmode, operands[2]);
6168 (define_insn "*addsi_2"
6169 [(set (reg FLAGS_REG)
6171 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6172 (match_operand:SI 2 "general_operand" "rmni,rni"))
6174 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6175 (plus:SI (match_dup 1) (match_dup 2)))]
6176 "ix86_match_ccmode (insn, CCGOCmode)
6177 && ix86_binary_operator_ok (PLUS, SImode, operands)
6178 /* Current assemblers are broken and do not allow @GOTOFF in
6179 ought but a memory context. */
6180 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6182 switch (get_attr_type (insn))
6185 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6186 if (operands[2] == const1_rtx)
6187 return "inc{l}\t%0";
6190 gcc_assert (operands[2] == constm1_rtx);
6191 return "dec{l}\t%0";
6195 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6196 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6197 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6198 if (CONST_INT_P (operands[2])
6199 && (INTVAL (operands[2]) == 128
6200 || (INTVAL (operands[2]) < 0
6201 && INTVAL (operands[2]) != -128)))
6203 operands[2] = GEN_INT (-INTVAL (operands[2]));
6204 return "sub{l}\t{%2, %0|%0, %2}";
6206 return "add{l}\t{%2, %0|%0, %2}";
6210 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6211 (const_string "incdec")
6212 (const_string "alu")))
6213 (set_attr "mode" "SI")])
6215 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6216 (define_insn "*addsi_2_zext"
6217 [(set (reg FLAGS_REG)
6219 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6220 (match_operand:SI 2 "general_operand" "rmni"))
6222 (set (match_operand:DI 0 "register_operand" "=r")
6223 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6224 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6225 && ix86_binary_operator_ok (PLUS, SImode, operands)
6226 /* Current assemblers are broken and do not allow @GOTOFF in
6227 ought but a memory context. */
6228 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6230 switch (get_attr_type (insn))
6233 if (operands[2] == const1_rtx)
6234 return "inc{l}\t%k0";
6237 gcc_assert (operands[2] == constm1_rtx);
6238 return "dec{l}\t%k0";
6242 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6243 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6244 if (CONST_INT_P (operands[2])
6245 && (INTVAL (operands[2]) == 128
6246 || (INTVAL (operands[2]) < 0
6247 && INTVAL (operands[2]) != -128)))
6249 operands[2] = GEN_INT (-INTVAL (operands[2]));
6250 return "sub{l}\t{%2, %k0|%k0, %2}";
6252 return "add{l}\t{%2, %k0|%k0, %2}";
6256 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6257 (const_string "incdec")
6258 (const_string "alu")))
6259 (set_attr "mode" "SI")])
6261 (define_insn "*addsi_3"
6262 [(set (reg FLAGS_REG)
6263 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6264 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6265 (clobber (match_scratch:SI 0 "=r"))]
6266 "ix86_match_ccmode (insn, CCZmode)
6267 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6268 /* Current assemblers are broken and do not allow @GOTOFF in
6269 ought but a memory context. */
6270 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6272 switch (get_attr_type (insn))
6275 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6276 if (operands[2] == const1_rtx)
6277 return "inc{l}\t%0";
6280 gcc_assert (operands[2] == constm1_rtx);
6281 return "dec{l}\t%0";
6285 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6286 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6287 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6288 if (CONST_INT_P (operands[2])
6289 && (INTVAL (operands[2]) == 128
6290 || (INTVAL (operands[2]) < 0
6291 && INTVAL (operands[2]) != -128)))
6293 operands[2] = GEN_INT (-INTVAL (operands[2]));
6294 return "sub{l}\t{%2, %0|%0, %2}";
6296 return "add{l}\t{%2, %0|%0, %2}";
6300 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6301 (const_string "incdec")
6302 (const_string "alu")))
6303 (set_attr "mode" "SI")])
6305 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6306 (define_insn "*addsi_3_zext"
6307 [(set (reg FLAGS_REG)
6308 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6309 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6310 (set (match_operand:DI 0 "register_operand" "=r")
6311 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6312 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6313 && ix86_binary_operator_ok (PLUS, SImode, operands)
6314 /* Current assemblers are broken and do not allow @GOTOFF in
6315 ought but a memory context. */
6316 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6318 switch (get_attr_type (insn))
6321 if (operands[2] == const1_rtx)
6322 return "inc{l}\t%k0";
6325 gcc_assert (operands[2] == constm1_rtx);
6326 return "dec{l}\t%k0";
6330 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6331 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6332 if (CONST_INT_P (operands[2])
6333 && (INTVAL (operands[2]) == 128
6334 || (INTVAL (operands[2]) < 0
6335 && INTVAL (operands[2]) != -128)))
6337 operands[2] = GEN_INT (-INTVAL (operands[2]));
6338 return "sub{l}\t{%2, %k0|%k0, %2}";
6340 return "add{l}\t{%2, %k0|%k0, %2}";
6344 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6345 (const_string "incdec")
6346 (const_string "alu")))
6347 (set_attr "mode" "SI")])
6349 ; For comparisons against 1, -1 and 128, we may generate better code
6350 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6351 ; is matched then. We can't accept general immediate, because for
6352 ; case of overflows, the result is messed up.
6353 ; This pattern also don't hold of 0x80000000, since the value overflows
6355 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6356 ; only for comparisons not depending on it.
6357 (define_insn "*addsi_4"
6358 [(set (reg FLAGS_REG)
6359 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6360 (match_operand:SI 2 "const_int_operand" "n")))
6361 (clobber (match_scratch:SI 0 "=rm"))]
6362 "ix86_match_ccmode (insn, CCGCmode)
6363 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6365 switch (get_attr_type (insn))
6368 if (operands[2] == constm1_rtx)
6369 return "inc{l}\t%0";
6372 gcc_assert (operands[2] == const1_rtx);
6373 return "dec{l}\t%0";
6377 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6378 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6379 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6380 if ((INTVAL (operands[2]) == -128
6381 || (INTVAL (operands[2]) > 0
6382 && INTVAL (operands[2]) != 128)))
6383 return "sub{l}\t{%2, %0|%0, %2}";
6384 operands[2] = GEN_INT (-INTVAL (operands[2]));
6385 return "add{l}\t{%2, %0|%0, %2}";
6389 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6390 (const_string "incdec")
6391 (const_string "alu")))
6392 (set_attr "mode" "SI")])
6394 (define_insn "*addsi_5"
6395 [(set (reg FLAGS_REG)
6397 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6398 (match_operand:SI 2 "general_operand" "rmni"))
6400 (clobber (match_scratch:SI 0 "=r"))]
6401 "ix86_match_ccmode (insn, CCGOCmode)
6402 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6403 /* Current assemblers are broken and do not allow @GOTOFF in
6404 ought but a memory context. */
6405 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6407 switch (get_attr_type (insn))
6410 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6411 if (operands[2] == const1_rtx)
6412 return "inc{l}\t%0";
6415 gcc_assert (operands[2] == constm1_rtx);
6416 return "dec{l}\t%0";
6420 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6421 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6422 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6423 if (CONST_INT_P (operands[2])
6424 && (INTVAL (operands[2]) == 128
6425 || (INTVAL (operands[2]) < 0
6426 && INTVAL (operands[2]) != -128)))
6428 operands[2] = GEN_INT (-INTVAL (operands[2]));
6429 return "sub{l}\t{%2, %0|%0, %2}";
6431 return "add{l}\t{%2, %0|%0, %2}";
6435 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6436 (const_string "incdec")
6437 (const_string "alu")))
6438 (set_attr "mode" "SI")])
6440 (define_expand "addhi3"
6441 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6442 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6443 (match_operand:HI 2 "general_operand" "")))
6444 (clobber (reg:CC FLAGS_REG))])]
6445 "TARGET_HIMODE_MATH"
6446 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6448 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6449 ;; type optimizations enabled by define-splits. This is not important
6450 ;; for PII, and in fact harmful because of partial register stalls.
6452 (define_insn "*addhi_1_lea"
6453 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6454 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6455 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6456 (clobber (reg:CC FLAGS_REG))]
6457 "!TARGET_PARTIAL_REG_STALL
6458 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6460 switch (get_attr_type (insn))
6465 if (operands[2] == const1_rtx)
6466 return "inc{w}\t%0";
6469 gcc_assert (operands[2] == constm1_rtx);
6470 return "dec{w}\t%0";
6474 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6475 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6476 if (CONST_INT_P (operands[2])
6477 && (INTVAL (operands[2]) == 128
6478 || (INTVAL (operands[2]) < 0
6479 && INTVAL (operands[2]) != -128)))
6481 operands[2] = GEN_INT (-INTVAL (operands[2]));
6482 return "sub{w}\t{%2, %0|%0, %2}";
6484 return "add{w}\t{%2, %0|%0, %2}";
6488 (if_then_else (eq_attr "alternative" "2")
6489 (const_string "lea")
6490 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6491 (const_string "incdec")
6492 (const_string "alu"))))
6493 (set_attr "mode" "HI,HI,SI")])
6495 (define_insn "*addhi_1"
6496 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6497 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6498 (match_operand:HI 2 "general_operand" "ri,rm")))
6499 (clobber (reg:CC FLAGS_REG))]
6500 "TARGET_PARTIAL_REG_STALL
6501 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6503 switch (get_attr_type (insn))
6506 if (operands[2] == const1_rtx)
6507 return "inc{w}\t%0";
6510 gcc_assert (operands[2] == constm1_rtx);
6511 return "dec{w}\t%0";
6515 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6516 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6517 if (CONST_INT_P (operands[2])
6518 && (INTVAL (operands[2]) == 128
6519 || (INTVAL (operands[2]) < 0
6520 && INTVAL (operands[2]) != -128)))
6522 operands[2] = GEN_INT (-INTVAL (operands[2]));
6523 return "sub{w}\t{%2, %0|%0, %2}";
6525 return "add{w}\t{%2, %0|%0, %2}";
6529 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6530 (const_string "incdec")
6531 (const_string "alu")))
6532 (set_attr "mode" "HI")])
6534 (define_insn "*addhi_2"
6535 [(set (reg FLAGS_REG)
6537 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6538 (match_operand:HI 2 "general_operand" "rmni,rni"))
6540 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6541 (plus:HI (match_dup 1) (match_dup 2)))]
6542 "ix86_match_ccmode (insn, CCGOCmode)
6543 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6545 switch (get_attr_type (insn))
6548 if (operands[2] == const1_rtx)
6549 return "inc{w}\t%0";
6552 gcc_assert (operands[2] == constm1_rtx);
6553 return "dec{w}\t%0";
6557 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6558 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6559 if (CONST_INT_P (operands[2])
6560 && (INTVAL (operands[2]) == 128
6561 || (INTVAL (operands[2]) < 0
6562 && INTVAL (operands[2]) != -128)))
6564 operands[2] = GEN_INT (-INTVAL (operands[2]));
6565 return "sub{w}\t{%2, %0|%0, %2}";
6567 return "add{w}\t{%2, %0|%0, %2}";
6571 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6572 (const_string "incdec")
6573 (const_string "alu")))
6574 (set_attr "mode" "HI")])
6576 (define_insn "*addhi_3"
6577 [(set (reg FLAGS_REG)
6578 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6579 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6580 (clobber (match_scratch:HI 0 "=r"))]
6581 "ix86_match_ccmode (insn, CCZmode)
6582 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6584 switch (get_attr_type (insn))
6587 if (operands[2] == const1_rtx)
6588 return "inc{w}\t%0";
6591 gcc_assert (operands[2] == constm1_rtx);
6592 return "dec{w}\t%0";
6596 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6597 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6598 if (CONST_INT_P (operands[2])
6599 && (INTVAL (operands[2]) == 128
6600 || (INTVAL (operands[2]) < 0
6601 && INTVAL (operands[2]) != -128)))
6603 operands[2] = GEN_INT (-INTVAL (operands[2]));
6604 return "sub{w}\t{%2, %0|%0, %2}";
6606 return "add{w}\t{%2, %0|%0, %2}";
6610 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6611 (const_string "incdec")
6612 (const_string "alu")))
6613 (set_attr "mode" "HI")])
6615 ; See comments above addsi_4 for details.
6616 (define_insn "*addhi_4"
6617 [(set (reg FLAGS_REG)
6618 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6619 (match_operand:HI 2 "const_int_operand" "n")))
6620 (clobber (match_scratch:HI 0 "=rm"))]
6621 "ix86_match_ccmode (insn, CCGCmode)
6622 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6624 switch (get_attr_type (insn))
6627 if (operands[2] == constm1_rtx)
6628 return "inc{w}\t%0";
6631 gcc_assert (operands[2] == const1_rtx);
6632 return "dec{w}\t%0";
6636 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6637 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6638 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6639 if ((INTVAL (operands[2]) == -128
6640 || (INTVAL (operands[2]) > 0
6641 && INTVAL (operands[2]) != 128)))
6642 return "sub{w}\t{%2, %0|%0, %2}";
6643 operands[2] = GEN_INT (-INTVAL (operands[2]));
6644 return "add{w}\t{%2, %0|%0, %2}";
6648 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6649 (const_string "incdec")
6650 (const_string "alu")))
6651 (set_attr "mode" "SI")])
6654 (define_insn "*addhi_5"
6655 [(set (reg FLAGS_REG)
6657 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6658 (match_operand:HI 2 "general_operand" "rmni"))
6660 (clobber (match_scratch:HI 0 "=r"))]
6661 "ix86_match_ccmode (insn, CCGOCmode)
6662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6664 switch (get_attr_type (insn))
6667 if (operands[2] == const1_rtx)
6668 return "inc{w}\t%0";
6671 gcc_assert (operands[2] == constm1_rtx);
6672 return "dec{w}\t%0";
6676 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6677 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6678 if (CONST_INT_P (operands[2])
6679 && (INTVAL (operands[2]) == 128
6680 || (INTVAL (operands[2]) < 0
6681 && INTVAL (operands[2]) != -128)))
6683 operands[2] = GEN_INT (-INTVAL (operands[2]));
6684 return "sub{w}\t{%2, %0|%0, %2}";
6686 return "add{w}\t{%2, %0|%0, %2}";
6690 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6691 (const_string "incdec")
6692 (const_string "alu")))
6693 (set_attr "mode" "HI")])
6695 (define_expand "addqi3"
6696 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6697 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6698 (match_operand:QI 2 "general_operand" "")))
6699 (clobber (reg:CC FLAGS_REG))])]
6700 "TARGET_QIMODE_MATH"
6701 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6703 ;; %%% Potential partial reg stall on alternative 2. What to do?
6704 (define_insn "*addqi_1_lea"
6705 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6706 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6707 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6708 (clobber (reg:CC FLAGS_REG))]
6709 "!TARGET_PARTIAL_REG_STALL
6710 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6712 int widen = (which_alternative == 2);
6713 switch (get_attr_type (insn))
6718 if (operands[2] == const1_rtx)
6719 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6722 gcc_assert (operands[2] == constm1_rtx);
6723 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6727 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6728 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6729 if (CONST_INT_P (operands[2])
6730 && (INTVAL (operands[2]) == 128
6731 || (INTVAL (operands[2]) < 0
6732 && INTVAL (operands[2]) != -128)))
6734 operands[2] = GEN_INT (-INTVAL (operands[2]));
6736 return "sub{l}\t{%2, %k0|%k0, %2}";
6738 return "sub{b}\t{%2, %0|%0, %2}";
6741 return "add{l}\t{%k2, %k0|%k0, %k2}";
6743 return "add{b}\t{%2, %0|%0, %2}";
6747 (if_then_else (eq_attr "alternative" "3")
6748 (const_string "lea")
6749 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6750 (const_string "incdec")
6751 (const_string "alu"))))
6752 (set_attr "mode" "QI,QI,SI,SI")])
6754 (define_insn "*addqi_1"
6755 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6756 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6757 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6758 (clobber (reg:CC FLAGS_REG))]
6759 "TARGET_PARTIAL_REG_STALL
6760 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6762 int widen = (which_alternative == 2);
6763 switch (get_attr_type (insn))
6766 if (operands[2] == const1_rtx)
6767 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6770 gcc_assert (operands[2] == constm1_rtx);
6771 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6775 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6776 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6777 if (CONST_INT_P (operands[2])
6778 && (INTVAL (operands[2]) == 128
6779 || (INTVAL (operands[2]) < 0
6780 && INTVAL (operands[2]) != -128)))
6782 operands[2] = GEN_INT (-INTVAL (operands[2]));
6784 return "sub{l}\t{%2, %k0|%k0, %2}";
6786 return "sub{b}\t{%2, %0|%0, %2}";
6789 return "add{l}\t{%k2, %k0|%k0, %k2}";
6791 return "add{b}\t{%2, %0|%0, %2}";
6795 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6796 (const_string "incdec")
6797 (const_string "alu")))
6798 (set_attr "mode" "QI,QI,SI")])
6800 (define_insn "*addqi_1_slp"
6801 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6802 (plus:QI (match_dup 0)
6803 (match_operand:QI 1 "general_operand" "qn,qnm")))
6804 (clobber (reg:CC FLAGS_REG))]
6805 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6806 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6808 switch (get_attr_type (insn))
6811 if (operands[1] == const1_rtx)
6812 return "inc{b}\t%0";
6815 gcc_assert (operands[1] == constm1_rtx);
6816 return "dec{b}\t%0";
6820 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6821 if (CONST_INT_P (operands[1])
6822 && INTVAL (operands[1]) < 0)
6824 operands[1] = GEN_INT (-INTVAL (operands[1]));
6825 return "sub{b}\t{%1, %0|%0, %1}";
6827 return "add{b}\t{%1, %0|%0, %1}";
6831 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6832 (const_string "incdec")
6833 (const_string "alu1")))
6834 (set (attr "memory")
6835 (if_then_else (match_operand 1 "memory_operand" "")
6836 (const_string "load")
6837 (const_string "none")))
6838 (set_attr "mode" "QI")])
6840 (define_insn "*addqi_2"
6841 [(set (reg FLAGS_REG)
6843 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6844 (match_operand:QI 2 "general_operand" "qmni,qni"))
6846 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6847 (plus:QI (match_dup 1) (match_dup 2)))]
6848 "ix86_match_ccmode (insn, CCGOCmode)
6849 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6851 switch (get_attr_type (insn))
6854 if (operands[2] == const1_rtx)
6855 return "inc{b}\t%0";
6858 gcc_assert (operands[2] == constm1_rtx
6859 || (CONST_INT_P (operands[2])
6860 && INTVAL (operands[2]) == 255));
6861 return "dec{b}\t%0";
6865 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6866 if (CONST_INT_P (operands[2])
6867 && INTVAL (operands[2]) < 0)
6869 operands[2] = GEN_INT (-INTVAL (operands[2]));
6870 return "sub{b}\t{%2, %0|%0, %2}";
6872 return "add{b}\t{%2, %0|%0, %2}";
6876 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6877 (const_string "incdec")
6878 (const_string "alu")))
6879 (set_attr "mode" "QI")])
6881 (define_insn "*addqi_3"
6882 [(set (reg FLAGS_REG)
6883 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6884 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6885 (clobber (match_scratch:QI 0 "=q"))]
6886 "ix86_match_ccmode (insn, CCZmode)
6887 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6889 switch (get_attr_type (insn))
6892 if (operands[2] == const1_rtx)
6893 return "inc{b}\t%0";
6896 gcc_assert (operands[2] == constm1_rtx
6897 || (CONST_INT_P (operands[2])
6898 && INTVAL (operands[2]) == 255));
6899 return "dec{b}\t%0";
6903 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6904 if (CONST_INT_P (operands[2])
6905 && INTVAL (operands[2]) < 0)
6907 operands[2] = GEN_INT (-INTVAL (operands[2]));
6908 return "sub{b}\t{%2, %0|%0, %2}";
6910 return "add{b}\t{%2, %0|%0, %2}";
6914 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6915 (const_string "incdec")
6916 (const_string "alu")))
6917 (set_attr "mode" "QI")])
6919 ; See comments above addsi_4 for details.
6920 (define_insn "*addqi_4"
6921 [(set (reg FLAGS_REG)
6922 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6923 (match_operand:QI 2 "const_int_operand" "n")))
6924 (clobber (match_scratch:QI 0 "=qm"))]
6925 "ix86_match_ccmode (insn, CCGCmode)
6926 && (INTVAL (operands[2]) & 0xff) != 0x80"
6928 switch (get_attr_type (insn))
6931 if (operands[2] == constm1_rtx
6932 || (CONST_INT_P (operands[2])
6933 && INTVAL (operands[2]) == 255))
6934 return "inc{b}\t%0";
6937 gcc_assert (operands[2] == const1_rtx);
6938 return "dec{b}\t%0";
6942 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6943 if (INTVAL (operands[2]) < 0)
6945 operands[2] = GEN_INT (-INTVAL (operands[2]));
6946 return "add{b}\t{%2, %0|%0, %2}";
6948 return "sub{b}\t{%2, %0|%0, %2}";
6952 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6953 (const_string "incdec")
6954 (const_string "alu")))
6955 (set_attr "mode" "QI")])
6958 (define_insn "*addqi_5"
6959 [(set (reg FLAGS_REG)
6961 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6962 (match_operand:QI 2 "general_operand" "qmni"))
6964 (clobber (match_scratch:QI 0 "=q"))]
6965 "ix86_match_ccmode (insn, CCGOCmode)
6966 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6968 switch (get_attr_type (insn))
6971 if (operands[2] == const1_rtx)
6972 return "inc{b}\t%0";
6975 gcc_assert (operands[2] == constm1_rtx
6976 || (CONST_INT_P (operands[2])
6977 && INTVAL (operands[2]) == 255));
6978 return "dec{b}\t%0";
6982 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6983 if (CONST_INT_P (operands[2])
6984 && INTVAL (operands[2]) < 0)
6986 operands[2] = GEN_INT (-INTVAL (operands[2]));
6987 return "sub{b}\t{%2, %0|%0, %2}";
6989 return "add{b}\t{%2, %0|%0, %2}";
6993 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6994 (const_string "incdec")
6995 (const_string "alu")))
6996 (set_attr "mode" "QI")])
6999 (define_insn "addqi_ext_1"
7000 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7005 (match_operand 1 "ext_register_operand" "0")
7008 (match_operand:QI 2 "general_operand" "Qmn")))
7009 (clobber (reg:CC FLAGS_REG))]
7012 switch (get_attr_type (insn))
7015 if (operands[2] == const1_rtx)
7016 return "inc{b}\t%h0";
7019 gcc_assert (operands[2] == constm1_rtx
7020 || (CONST_INT_P (operands[2])
7021 && INTVAL (operands[2]) == 255));
7022 return "dec{b}\t%h0";
7026 return "add{b}\t{%2, %h0|%h0, %2}";
7030 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7031 (const_string "incdec")
7032 (const_string "alu")))
7033 (set_attr "mode" "QI")])
7035 (define_insn "*addqi_ext_1_rex64"
7036 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7041 (match_operand 1 "ext_register_operand" "0")
7044 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7045 (clobber (reg:CC FLAGS_REG))]
7048 switch (get_attr_type (insn))
7051 if (operands[2] == const1_rtx)
7052 return "inc{b}\t%h0";
7055 gcc_assert (operands[2] == constm1_rtx
7056 || (CONST_INT_P (operands[2])
7057 && INTVAL (operands[2]) == 255));
7058 return "dec{b}\t%h0";
7062 return "add{b}\t{%2, %h0|%h0, %2}";
7066 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7067 (const_string "incdec")
7068 (const_string "alu")))
7069 (set_attr "mode" "QI")])
7071 (define_insn "*addqi_ext_2"
7072 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7077 (match_operand 1 "ext_register_operand" "%0")
7081 (match_operand 2 "ext_register_operand" "Q")
7084 (clobber (reg:CC FLAGS_REG))]
7086 "add{b}\t{%h2, %h0|%h0, %h2}"
7087 [(set_attr "type" "alu")
7088 (set_attr "mode" "QI")])
7090 ;; The patterns that match these are at the end of this file.
7092 (define_expand "addxf3"
7093 [(set (match_operand:XF 0 "register_operand" "")
7094 (plus:XF (match_operand:XF 1 "register_operand" "")
7095 (match_operand:XF 2 "register_operand" "")))]
7099 (define_expand "add<mode>3"
7100 [(set (match_operand:MODEF 0 "register_operand" "")
7101 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7102 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7103 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7106 ;; Subtract instructions
7108 ;; %%% splits for subditi3
7110 (define_expand "subti3"
7111 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7112 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7113 (match_operand:TI 2 "x86_64_general_operand" "")))
7114 (clobber (reg:CC FLAGS_REG))])]
7116 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7118 (define_insn "*subti3_1"
7119 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7120 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7121 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7122 (clobber (reg:CC FLAGS_REG))]
7123 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7127 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7128 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7129 (match_operand:TI 2 "x86_64_general_operand" "")))
7130 (clobber (reg:CC FLAGS_REG))]
7131 "TARGET_64BIT && reload_completed"
7132 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7133 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7134 (parallel [(set (match_dup 3)
7135 (minus:DI (match_dup 4)
7136 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7138 (clobber (reg:CC FLAGS_REG))])]
7139 "split_ti (operands+0, 1, operands+0, operands+3);
7140 split_ti (operands+1, 1, operands+1, operands+4);
7141 split_ti (operands+2, 1, operands+2, operands+5);")
7143 ;; %%% splits for subsidi3
7145 (define_expand "subdi3"
7146 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7147 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7148 (match_operand:DI 2 "x86_64_general_operand" "")))
7149 (clobber (reg:CC FLAGS_REG))])]
7151 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7153 (define_insn "*subdi3_1"
7154 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7155 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7156 (match_operand:DI 2 "general_operand" "roiF,riF")))
7157 (clobber (reg:CC FLAGS_REG))]
7158 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7162 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7163 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7164 (match_operand:DI 2 "general_operand" "")))
7165 (clobber (reg:CC FLAGS_REG))]
7166 "!TARGET_64BIT && reload_completed"
7167 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7168 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7169 (parallel [(set (match_dup 3)
7170 (minus:SI (match_dup 4)
7171 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7173 (clobber (reg:CC FLAGS_REG))])]
7174 "split_di (operands+0, 1, operands+0, operands+3);
7175 split_di (operands+1, 1, operands+1, operands+4);
7176 split_di (operands+2, 1, operands+2, operands+5);")
7178 (define_insn "subdi3_carry_rex64"
7179 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7180 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7181 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7182 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7183 (clobber (reg:CC FLAGS_REG))]
7184 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7185 "sbb{q}\t{%2, %0|%0, %2}"
7186 [(set_attr "type" "alu")
7187 (set_attr "pent_pair" "pu")
7188 (set_attr "mode" "DI")])
7190 (define_insn "*subdi_1_rex64"
7191 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7192 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7193 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7194 (clobber (reg:CC FLAGS_REG))]
7195 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7196 "sub{q}\t{%2, %0|%0, %2}"
7197 [(set_attr "type" "alu")
7198 (set_attr "mode" "DI")])
7200 (define_insn "*subdi_2_rex64"
7201 [(set (reg FLAGS_REG)
7203 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7204 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7206 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7207 (minus:DI (match_dup 1) (match_dup 2)))]
7208 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7209 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7210 "sub{q}\t{%2, %0|%0, %2}"
7211 [(set_attr "type" "alu")
7212 (set_attr "mode" "DI")])
7214 (define_insn "*subdi_3_rex63"
7215 [(set (reg FLAGS_REG)
7216 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7217 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7218 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7219 (minus:DI (match_dup 1) (match_dup 2)))]
7220 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7221 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7222 "sub{q}\t{%2, %0|%0, %2}"
7223 [(set_attr "type" "alu")
7224 (set_attr "mode" "DI")])
7226 (define_insn "subqi3_carry"
7227 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7228 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7229 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7230 (match_operand:QI 2 "general_operand" "qi,qm"))))
7231 (clobber (reg:CC FLAGS_REG))]
7232 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7233 "sbb{b}\t{%2, %0|%0, %2}"
7234 [(set_attr "type" "alu")
7235 (set_attr "pent_pair" "pu")
7236 (set_attr "mode" "QI")])
7238 (define_insn "subhi3_carry"
7239 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7240 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7241 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7242 (match_operand:HI 2 "general_operand" "ri,rm"))))
7243 (clobber (reg:CC FLAGS_REG))]
7244 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7245 "sbb{w}\t{%2, %0|%0, %2}"
7246 [(set_attr "type" "alu")
7247 (set_attr "pent_pair" "pu")
7248 (set_attr "mode" "HI")])
7250 (define_insn "subsi3_carry"
7251 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7252 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7253 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7254 (match_operand:SI 2 "general_operand" "ri,rm"))))
7255 (clobber (reg:CC FLAGS_REG))]
7256 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7257 "sbb{l}\t{%2, %0|%0, %2}"
7258 [(set_attr "type" "alu")
7259 (set_attr "pent_pair" "pu")
7260 (set_attr "mode" "SI")])
7262 (define_insn "subsi3_carry_zext"
7263 [(set (match_operand:DI 0 "register_operand" "=r")
7265 (minus:SI (match_operand:SI 1 "register_operand" "0")
7266 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7267 (match_operand:SI 2 "general_operand" "g")))))
7268 (clobber (reg:CC FLAGS_REG))]
7269 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7270 "sbb{l}\t{%2, %k0|%k0, %2}"
7271 [(set_attr "type" "alu")
7272 (set_attr "pent_pair" "pu")
7273 (set_attr "mode" "SI")])
7275 (define_expand "subsi3"
7276 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7277 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7278 (match_operand:SI 2 "general_operand" "")))
7279 (clobber (reg:CC FLAGS_REG))])]
7281 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7283 (define_insn "*subsi_1"
7284 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7285 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7286 (match_operand:SI 2 "general_operand" "ri,rm")))
7287 (clobber (reg:CC FLAGS_REG))]
7288 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7289 "sub{l}\t{%2, %0|%0, %2}"
7290 [(set_attr "type" "alu")
7291 (set_attr "mode" "SI")])
7293 (define_insn "*subsi_1_zext"
7294 [(set (match_operand:DI 0 "register_operand" "=r")
7296 (minus:SI (match_operand:SI 1 "register_operand" "0")
7297 (match_operand:SI 2 "general_operand" "g"))))
7298 (clobber (reg:CC FLAGS_REG))]
7299 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7300 "sub{l}\t{%2, %k0|%k0, %2}"
7301 [(set_attr "type" "alu")
7302 (set_attr "mode" "SI")])
7304 (define_insn "*subsi_2"
7305 [(set (reg FLAGS_REG)
7307 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7308 (match_operand:SI 2 "general_operand" "ri,rm"))
7310 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7311 (minus:SI (match_dup 1) (match_dup 2)))]
7312 "ix86_match_ccmode (insn, CCGOCmode)
7313 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7314 "sub{l}\t{%2, %0|%0, %2}"
7315 [(set_attr "type" "alu")
7316 (set_attr "mode" "SI")])
7318 (define_insn "*subsi_2_zext"
7319 [(set (reg FLAGS_REG)
7321 (minus:SI (match_operand:SI 1 "register_operand" "0")
7322 (match_operand:SI 2 "general_operand" "g"))
7324 (set (match_operand:DI 0 "register_operand" "=r")
7326 (minus:SI (match_dup 1)
7328 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7329 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7330 "sub{l}\t{%2, %k0|%k0, %2}"
7331 [(set_attr "type" "alu")
7332 (set_attr "mode" "SI")])
7334 (define_insn "*subsi_3"
7335 [(set (reg FLAGS_REG)
7336 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7337 (match_operand:SI 2 "general_operand" "ri,rm")))
7338 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7339 (minus:SI (match_dup 1) (match_dup 2)))]
7340 "ix86_match_ccmode (insn, CCmode)
7341 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7342 "sub{l}\t{%2, %0|%0, %2}"
7343 [(set_attr "type" "alu")
7344 (set_attr "mode" "SI")])
7346 (define_insn "*subsi_3_zext"
7347 [(set (reg FLAGS_REG)
7348 (compare (match_operand:SI 1 "register_operand" "0")
7349 (match_operand:SI 2 "general_operand" "g")))
7350 (set (match_operand:DI 0 "register_operand" "=r")
7352 (minus:SI (match_dup 1)
7354 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7355 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7356 "sub{l}\t{%2, %1|%1, %2}"
7357 [(set_attr "type" "alu")
7358 (set_attr "mode" "DI")])
7360 (define_expand "subhi3"
7361 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7362 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7363 (match_operand:HI 2 "general_operand" "")))
7364 (clobber (reg:CC FLAGS_REG))])]
7365 "TARGET_HIMODE_MATH"
7366 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7368 (define_insn "*subhi_1"
7369 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7370 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7371 (match_operand:HI 2 "general_operand" "ri,rm")))
7372 (clobber (reg:CC FLAGS_REG))]
7373 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7374 "sub{w}\t{%2, %0|%0, %2}"
7375 [(set_attr "type" "alu")
7376 (set_attr "mode" "HI")])
7378 (define_insn "*subhi_2"
7379 [(set (reg FLAGS_REG)
7381 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7382 (match_operand:HI 2 "general_operand" "ri,rm"))
7384 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7385 (minus:HI (match_dup 1) (match_dup 2)))]
7386 "ix86_match_ccmode (insn, CCGOCmode)
7387 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7388 "sub{w}\t{%2, %0|%0, %2}"
7389 [(set_attr "type" "alu")
7390 (set_attr "mode" "HI")])
7392 (define_insn "*subhi_3"
7393 [(set (reg FLAGS_REG)
7394 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7395 (match_operand:HI 2 "general_operand" "ri,rm")))
7396 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7397 (minus:HI (match_dup 1) (match_dup 2)))]
7398 "ix86_match_ccmode (insn, CCmode)
7399 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7400 "sub{w}\t{%2, %0|%0, %2}"
7401 [(set_attr "type" "alu")
7402 (set_attr "mode" "HI")])
7404 (define_expand "subqi3"
7405 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7406 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7407 (match_operand:QI 2 "general_operand" "")))
7408 (clobber (reg:CC FLAGS_REG))])]
7409 "TARGET_QIMODE_MATH"
7410 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7412 (define_insn "*subqi_1"
7413 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7414 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7415 (match_operand:QI 2 "general_operand" "qn,qmn")))
7416 (clobber (reg:CC FLAGS_REG))]
7417 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7418 "sub{b}\t{%2, %0|%0, %2}"
7419 [(set_attr "type" "alu")
7420 (set_attr "mode" "QI")])
7422 (define_insn "*subqi_1_slp"
7423 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7424 (minus:QI (match_dup 0)
7425 (match_operand:QI 1 "general_operand" "qn,qmn")))
7426 (clobber (reg:CC FLAGS_REG))]
7427 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7428 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7429 "sub{b}\t{%1, %0|%0, %1}"
7430 [(set_attr "type" "alu1")
7431 (set_attr "mode" "QI")])
7433 (define_insn "*subqi_2"
7434 [(set (reg FLAGS_REG)
7436 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7437 (match_operand:QI 2 "general_operand" "qi,qm"))
7439 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7440 (minus:HI (match_dup 1) (match_dup 2)))]
7441 "ix86_match_ccmode (insn, CCGOCmode)
7442 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7443 "sub{b}\t{%2, %0|%0, %2}"
7444 [(set_attr "type" "alu")
7445 (set_attr "mode" "QI")])
7447 (define_insn "*subqi_3"
7448 [(set (reg FLAGS_REG)
7449 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7450 (match_operand:QI 2 "general_operand" "qi,qm")))
7451 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7452 (minus:HI (match_dup 1) (match_dup 2)))]
7453 "ix86_match_ccmode (insn, CCmode)
7454 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7455 "sub{b}\t{%2, %0|%0, %2}"
7456 [(set_attr "type" "alu")
7457 (set_attr "mode" "QI")])
7459 ;; The patterns that match these are at the end of this file.
7461 (define_expand "subxf3"
7462 [(set (match_operand:XF 0 "register_operand" "")
7463 (minus:XF (match_operand:XF 1 "register_operand" "")
7464 (match_operand:XF 2 "register_operand" "")))]
7468 (define_expand "sub<mode>3"
7469 [(set (match_operand:MODEF 0 "register_operand" "")
7470 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7471 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7472 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7475 ;; Multiply instructions
7477 (define_expand "muldi3"
7478 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7479 (mult:DI (match_operand:DI 1 "register_operand" "")
7480 (match_operand:DI 2 "x86_64_general_operand" "")))
7481 (clobber (reg:CC FLAGS_REG))])]
7486 ;; IMUL reg64, reg64, imm8 Direct
7487 ;; IMUL reg64, mem64, imm8 VectorPath
7488 ;; IMUL reg64, reg64, imm32 Direct
7489 ;; IMUL reg64, mem64, imm32 VectorPath
7490 ;; IMUL reg64, reg64 Direct
7491 ;; IMUL reg64, mem64 Direct
7493 (define_insn "*muldi3_1_rex64"
7494 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7495 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7496 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7497 (clobber (reg:CC FLAGS_REG))]
7499 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7501 imul{q}\t{%2, %1, %0|%0, %1, %2}
7502 imul{q}\t{%2, %1, %0|%0, %1, %2}
7503 imul{q}\t{%2, %0|%0, %2}"
7504 [(set_attr "type" "imul")
7505 (set_attr "prefix_0f" "0,0,1")
7506 (set (attr "athlon_decode")
7507 (cond [(eq_attr "cpu" "athlon")
7508 (const_string "vector")
7509 (eq_attr "alternative" "1")
7510 (const_string "vector")
7511 (and (eq_attr "alternative" "2")
7512 (match_operand 1 "memory_operand" ""))
7513 (const_string "vector")]
7514 (const_string "direct")))
7515 (set (attr "amdfam10_decode")
7516 (cond [(and (eq_attr "alternative" "0,1")
7517 (match_operand 1 "memory_operand" ""))
7518 (const_string "vector")]
7519 (const_string "direct")))
7520 (set_attr "mode" "DI")])
7522 (define_expand "mulsi3"
7523 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7524 (mult:SI (match_operand:SI 1 "register_operand" "")
7525 (match_operand:SI 2 "general_operand" "")))
7526 (clobber (reg:CC FLAGS_REG))])]
7531 ;; IMUL reg32, reg32, imm8 Direct
7532 ;; IMUL reg32, mem32, imm8 VectorPath
7533 ;; IMUL reg32, reg32, imm32 Direct
7534 ;; IMUL reg32, mem32, imm32 VectorPath
7535 ;; IMUL reg32, reg32 Direct
7536 ;; IMUL reg32, mem32 Direct
7538 (define_insn "*mulsi3_1"
7539 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7540 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7541 (match_operand:SI 2 "general_operand" "K,i,mr")))
7542 (clobber (reg:CC FLAGS_REG))]
7543 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7545 imul{l}\t{%2, %1, %0|%0, %1, %2}
7546 imul{l}\t{%2, %1, %0|%0, %1, %2}
7547 imul{l}\t{%2, %0|%0, %2}"
7548 [(set_attr "type" "imul")
7549 (set_attr "prefix_0f" "0,0,1")
7550 (set (attr "athlon_decode")
7551 (cond [(eq_attr "cpu" "athlon")
7552 (const_string "vector")
7553 (eq_attr "alternative" "1")
7554 (const_string "vector")
7555 (and (eq_attr "alternative" "2")
7556 (match_operand 1 "memory_operand" ""))
7557 (const_string "vector")]
7558 (const_string "direct")))
7559 (set (attr "amdfam10_decode")
7560 (cond [(and (eq_attr "alternative" "0,1")
7561 (match_operand 1 "memory_operand" ""))
7562 (const_string "vector")]
7563 (const_string "direct")))
7564 (set_attr "mode" "SI")])
7566 (define_insn "*mulsi3_1_zext"
7567 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7569 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7570 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7571 (clobber (reg:CC FLAGS_REG))]
7573 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7575 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7576 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7577 imul{l}\t{%2, %k0|%k0, %2}"
7578 [(set_attr "type" "imul")
7579 (set_attr "prefix_0f" "0,0,1")
7580 (set (attr "athlon_decode")
7581 (cond [(eq_attr "cpu" "athlon")
7582 (const_string "vector")
7583 (eq_attr "alternative" "1")
7584 (const_string "vector")
7585 (and (eq_attr "alternative" "2")
7586 (match_operand 1 "memory_operand" ""))
7587 (const_string "vector")]
7588 (const_string "direct")))
7589 (set (attr "amdfam10_decode")
7590 (cond [(and (eq_attr "alternative" "0,1")
7591 (match_operand 1 "memory_operand" ""))
7592 (const_string "vector")]
7593 (const_string "direct")))
7594 (set_attr "mode" "SI")])
7596 (define_expand "mulhi3"
7597 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7598 (mult:HI (match_operand:HI 1 "register_operand" "")
7599 (match_operand:HI 2 "general_operand" "")))
7600 (clobber (reg:CC FLAGS_REG))])]
7601 "TARGET_HIMODE_MATH"
7605 ;; IMUL reg16, reg16, imm8 VectorPath
7606 ;; IMUL reg16, mem16, imm8 VectorPath
7607 ;; IMUL reg16, reg16, imm16 VectorPath
7608 ;; IMUL reg16, mem16, imm16 VectorPath
7609 ;; IMUL reg16, reg16 Direct
7610 ;; IMUL reg16, mem16 Direct
7611 (define_insn "*mulhi3_1"
7612 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7613 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7614 (match_operand:HI 2 "general_operand" "K,i,mr")))
7615 (clobber (reg:CC FLAGS_REG))]
7616 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7618 imul{w}\t{%2, %1, %0|%0, %1, %2}
7619 imul{w}\t{%2, %1, %0|%0, %1, %2}
7620 imul{w}\t{%2, %0|%0, %2}"
7621 [(set_attr "type" "imul")
7622 (set_attr "prefix_0f" "0,0,1")
7623 (set (attr "athlon_decode")
7624 (cond [(eq_attr "cpu" "athlon")
7625 (const_string "vector")
7626 (eq_attr "alternative" "1,2")
7627 (const_string "vector")]
7628 (const_string "direct")))
7629 (set (attr "amdfam10_decode")
7630 (cond [(eq_attr "alternative" "0,1")
7631 (const_string "vector")]
7632 (const_string "direct")))
7633 (set_attr "mode" "HI")])
7635 (define_expand "mulqi3"
7636 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7637 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7638 (match_operand:QI 2 "register_operand" "")))
7639 (clobber (reg:CC FLAGS_REG))])]
7640 "TARGET_QIMODE_MATH"
7647 (define_insn "*mulqi3_1"
7648 [(set (match_operand:QI 0 "register_operand" "=a")
7649 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7650 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7651 (clobber (reg:CC FLAGS_REG))]
7653 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7655 [(set_attr "type" "imul")
7656 (set_attr "length_immediate" "0")
7657 (set (attr "athlon_decode")
7658 (if_then_else (eq_attr "cpu" "athlon")
7659 (const_string "vector")
7660 (const_string "direct")))
7661 (set_attr "amdfam10_decode" "direct")
7662 (set_attr "mode" "QI")])
7664 (define_expand "umulqihi3"
7665 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7666 (mult:HI (zero_extend:HI
7667 (match_operand:QI 1 "nonimmediate_operand" ""))
7669 (match_operand:QI 2 "register_operand" ""))))
7670 (clobber (reg:CC FLAGS_REG))])]
7671 "TARGET_QIMODE_MATH"
7674 (define_insn "*umulqihi3_1"
7675 [(set (match_operand:HI 0 "register_operand" "=a")
7676 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7677 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7678 (clobber (reg:CC FLAGS_REG))]
7680 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7682 [(set_attr "type" "imul")
7683 (set_attr "length_immediate" "0")
7684 (set (attr "athlon_decode")
7685 (if_then_else (eq_attr "cpu" "athlon")
7686 (const_string "vector")
7687 (const_string "direct")))
7688 (set_attr "amdfam10_decode" "direct")
7689 (set_attr "mode" "QI")])
7691 (define_expand "mulqihi3"
7692 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7693 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7694 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7695 (clobber (reg:CC FLAGS_REG))])]
7696 "TARGET_QIMODE_MATH"
7699 (define_insn "*mulqihi3_insn"
7700 [(set (match_operand:HI 0 "register_operand" "=a")
7701 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7702 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7703 (clobber (reg:CC FLAGS_REG))]
7705 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7707 [(set_attr "type" "imul")
7708 (set_attr "length_immediate" "0")
7709 (set (attr "athlon_decode")
7710 (if_then_else (eq_attr "cpu" "athlon")
7711 (const_string "vector")
7712 (const_string "direct")))
7713 (set_attr "amdfam10_decode" "direct")
7714 (set_attr "mode" "QI")])
7716 (define_expand "umulditi3"
7717 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7718 (mult:TI (zero_extend:TI
7719 (match_operand:DI 1 "nonimmediate_operand" ""))
7721 (match_operand:DI 2 "register_operand" ""))))
7722 (clobber (reg:CC FLAGS_REG))])]
7726 (define_insn "*umulditi3_insn"
7727 [(set (match_operand:TI 0 "register_operand" "=A")
7728 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7729 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7730 (clobber (reg:CC FLAGS_REG))]
7732 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7734 [(set_attr "type" "imul")
7735 (set_attr "length_immediate" "0")
7736 (set (attr "athlon_decode")
7737 (if_then_else (eq_attr "cpu" "athlon")
7738 (const_string "vector")
7739 (const_string "double")))
7740 (set_attr "amdfam10_decode" "double")
7741 (set_attr "mode" "DI")])
7743 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7744 (define_expand "umulsidi3"
7745 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7746 (mult:DI (zero_extend:DI
7747 (match_operand:SI 1 "nonimmediate_operand" ""))
7749 (match_operand:SI 2 "register_operand" ""))))
7750 (clobber (reg:CC FLAGS_REG))])]
7754 (define_insn "*umulsidi3_insn"
7755 [(set (match_operand:DI 0 "register_operand" "=A")
7756 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7757 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7758 (clobber (reg:CC FLAGS_REG))]
7760 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7762 [(set_attr "type" "imul")
7763 (set_attr "length_immediate" "0")
7764 (set (attr "athlon_decode")
7765 (if_then_else (eq_attr "cpu" "athlon")
7766 (const_string "vector")
7767 (const_string "double")))
7768 (set_attr "amdfam10_decode" "double")
7769 (set_attr "mode" "SI")])
7771 (define_expand "mulditi3"
7772 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7773 (mult:TI (sign_extend:TI
7774 (match_operand:DI 1 "nonimmediate_operand" ""))
7776 (match_operand:DI 2 "register_operand" ""))))
7777 (clobber (reg:CC FLAGS_REG))])]
7781 (define_insn "*mulditi3_insn"
7782 [(set (match_operand:TI 0 "register_operand" "=A")
7783 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7784 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7785 (clobber (reg:CC FLAGS_REG))]
7787 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7789 [(set_attr "type" "imul")
7790 (set_attr "length_immediate" "0")
7791 (set (attr "athlon_decode")
7792 (if_then_else (eq_attr "cpu" "athlon")
7793 (const_string "vector")
7794 (const_string "double")))
7795 (set_attr "amdfam10_decode" "double")
7796 (set_attr "mode" "DI")])
7798 (define_expand "mulsidi3"
7799 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7800 (mult:DI (sign_extend:DI
7801 (match_operand:SI 1 "nonimmediate_operand" ""))
7803 (match_operand:SI 2 "register_operand" ""))))
7804 (clobber (reg:CC FLAGS_REG))])]
7808 (define_insn "*mulsidi3_insn"
7809 [(set (match_operand:DI 0 "register_operand" "=A")
7810 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7811 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7812 (clobber (reg:CC FLAGS_REG))]
7814 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7816 [(set_attr "type" "imul")
7817 (set_attr "length_immediate" "0")
7818 (set (attr "athlon_decode")
7819 (if_then_else (eq_attr "cpu" "athlon")
7820 (const_string "vector")
7821 (const_string "double")))
7822 (set_attr "amdfam10_decode" "double")
7823 (set_attr "mode" "SI")])
7825 (define_expand "umuldi3_highpart"
7826 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7829 (mult:TI (zero_extend:TI
7830 (match_operand:DI 1 "nonimmediate_operand" ""))
7832 (match_operand:DI 2 "register_operand" "")))
7834 (clobber (match_scratch:DI 3 ""))
7835 (clobber (reg:CC FLAGS_REG))])]
7839 (define_insn "*umuldi3_highpart_rex64"
7840 [(set (match_operand:DI 0 "register_operand" "=d")
7843 (mult:TI (zero_extend:TI
7844 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7846 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7848 (clobber (match_scratch:DI 3 "=1"))
7849 (clobber (reg:CC FLAGS_REG))]
7851 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7853 [(set_attr "type" "imul")
7854 (set_attr "length_immediate" "0")
7855 (set (attr "athlon_decode")
7856 (if_then_else (eq_attr "cpu" "athlon")
7857 (const_string "vector")
7858 (const_string "double")))
7859 (set_attr "amdfam10_decode" "double")
7860 (set_attr "mode" "DI")])
7862 (define_expand "umulsi3_highpart"
7863 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7866 (mult:DI (zero_extend:DI
7867 (match_operand:SI 1 "nonimmediate_operand" ""))
7869 (match_operand:SI 2 "register_operand" "")))
7871 (clobber (match_scratch:SI 3 ""))
7872 (clobber (reg:CC FLAGS_REG))])]
7876 (define_insn "*umulsi3_highpart_insn"
7877 [(set (match_operand:SI 0 "register_operand" "=d")
7880 (mult:DI (zero_extend:DI
7881 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7883 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7885 (clobber (match_scratch:SI 3 "=1"))
7886 (clobber (reg:CC FLAGS_REG))]
7887 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7889 [(set_attr "type" "imul")
7890 (set_attr "length_immediate" "0")
7891 (set (attr "athlon_decode")
7892 (if_then_else (eq_attr "cpu" "athlon")
7893 (const_string "vector")
7894 (const_string "double")))
7895 (set_attr "amdfam10_decode" "double")
7896 (set_attr "mode" "SI")])
7898 (define_insn "*umulsi3_highpart_zext"
7899 [(set (match_operand:DI 0 "register_operand" "=d")
7900 (zero_extend:DI (truncate:SI
7902 (mult:DI (zero_extend:DI
7903 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7905 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7907 (clobber (match_scratch:SI 3 "=1"))
7908 (clobber (reg:CC FLAGS_REG))]
7910 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7912 [(set_attr "type" "imul")
7913 (set_attr "length_immediate" "0")
7914 (set (attr "athlon_decode")
7915 (if_then_else (eq_attr "cpu" "athlon")
7916 (const_string "vector")
7917 (const_string "double")))
7918 (set_attr "amdfam10_decode" "double")
7919 (set_attr "mode" "SI")])
7921 (define_expand "smuldi3_highpart"
7922 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7925 (mult:TI (sign_extend:TI
7926 (match_operand:DI 1 "nonimmediate_operand" ""))
7928 (match_operand:DI 2 "register_operand" "")))
7930 (clobber (match_scratch:DI 3 ""))
7931 (clobber (reg:CC FLAGS_REG))])]
7935 (define_insn "*smuldi3_highpart_rex64"
7936 [(set (match_operand:DI 0 "register_operand" "=d")
7939 (mult:TI (sign_extend:TI
7940 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7942 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7944 (clobber (match_scratch:DI 3 "=1"))
7945 (clobber (reg:CC FLAGS_REG))]
7947 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7949 [(set_attr "type" "imul")
7950 (set (attr "athlon_decode")
7951 (if_then_else (eq_attr "cpu" "athlon")
7952 (const_string "vector")
7953 (const_string "double")))
7954 (set_attr "amdfam10_decode" "double")
7955 (set_attr "mode" "DI")])
7957 (define_expand "smulsi3_highpart"
7958 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7961 (mult:DI (sign_extend:DI
7962 (match_operand:SI 1 "nonimmediate_operand" ""))
7964 (match_operand:SI 2 "register_operand" "")))
7966 (clobber (match_scratch:SI 3 ""))
7967 (clobber (reg:CC FLAGS_REG))])]
7971 (define_insn "*smulsi3_highpart_insn"
7972 [(set (match_operand:SI 0 "register_operand" "=d")
7975 (mult:DI (sign_extend:DI
7976 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7978 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7980 (clobber (match_scratch:SI 3 "=1"))
7981 (clobber (reg:CC FLAGS_REG))]
7982 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7984 [(set_attr "type" "imul")
7985 (set (attr "athlon_decode")
7986 (if_then_else (eq_attr "cpu" "athlon")
7987 (const_string "vector")
7988 (const_string "double")))
7989 (set_attr "amdfam10_decode" "double")
7990 (set_attr "mode" "SI")])
7992 (define_insn "*smulsi3_highpart_zext"
7993 [(set (match_operand:DI 0 "register_operand" "=d")
7994 (zero_extend:DI (truncate:SI
7996 (mult:DI (sign_extend:DI
7997 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7999 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8001 (clobber (match_scratch:SI 3 "=1"))
8002 (clobber (reg:CC FLAGS_REG))]
8004 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8006 [(set_attr "type" "imul")
8007 (set (attr "athlon_decode")
8008 (if_then_else (eq_attr "cpu" "athlon")
8009 (const_string "vector")
8010 (const_string "double")))
8011 (set_attr "amdfam10_decode" "double")
8012 (set_attr "mode" "SI")])
8014 ;; The patterns that match these are at the end of this file.
8016 (define_expand "mulxf3"
8017 [(set (match_operand:XF 0 "register_operand" "")
8018 (mult:XF (match_operand:XF 1 "register_operand" "")
8019 (match_operand:XF 2 "register_operand" "")))]
8023 (define_expand "mul<mode>3"
8024 [(set (match_operand:MODEF 0 "register_operand" "")
8025 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8026 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8027 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8030 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8033 ;; Divide instructions
8035 (define_insn "divqi3"
8036 [(set (match_operand:QI 0 "register_operand" "=a")
8037 (div:QI (match_operand:HI 1 "register_operand" "0")
8038 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8039 (clobber (reg:CC FLAGS_REG))]
8040 "TARGET_QIMODE_MATH"
8042 [(set_attr "type" "idiv")
8043 (set_attr "mode" "QI")])
8045 (define_insn "udivqi3"
8046 [(set (match_operand:QI 0 "register_operand" "=a")
8047 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8048 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8049 (clobber (reg:CC FLAGS_REG))]
8050 "TARGET_QIMODE_MATH"
8052 [(set_attr "type" "idiv")
8053 (set_attr "mode" "QI")])
8055 ;; The patterns that match these are at the end of this file.
8057 (define_expand "divxf3"
8058 [(set (match_operand:XF 0 "register_operand" "")
8059 (div:XF (match_operand:XF 1 "register_operand" "")
8060 (match_operand:XF 2 "register_operand" "")))]
8064 (define_expand "divdf3"
8065 [(set (match_operand:DF 0 "register_operand" "")
8066 (div:DF (match_operand:DF 1 "register_operand" "")
8067 (match_operand:DF 2 "nonimmediate_operand" "")))]
8068 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8071 (define_expand "divsf3"
8072 [(set (match_operand:SF 0 "register_operand" "")
8073 (div:SF (match_operand:SF 1 "register_operand" "")
8074 (match_operand:SF 2 "nonimmediate_operand" "")))]
8075 "TARGET_80387 || TARGET_SSE_MATH"
8077 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8078 && flag_finite_math_only && !flag_trapping_math
8079 && flag_unsafe_math_optimizations)
8081 ix86_emit_swdivsf (operands[0], operands[1],
8082 operands[2], SFmode);
8087 ;; Remainder instructions.
8089 (define_expand "divmoddi4"
8090 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8091 (div:DI (match_operand:DI 1 "register_operand" "")
8092 (match_operand:DI 2 "nonimmediate_operand" "")))
8093 (set (match_operand:DI 3 "register_operand" "")
8094 (mod:DI (match_dup 1) (match_dup 2)))
8095 (clobber (reg:CC FLAGS_REG))])]
8099 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8100 ;; Penalize eax case slightly because it results in worse scheduling
8102 (define_insn "*divmoddi4_nocltd_rex64"
8103 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8104 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8105 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8106 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8107 (mod:DI (match_dup 2) (match_dup 3)))
8108 (clobber (reg:CC FLAGS_REG))]
8109 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8111 [(set_attr "type" "multi")])
8113 (define_insn "*divmoddi4_cltd_rex64"
8114 [(set (match_operand:DI 0 "register_operand" "=a")
8115 (div:DI (match_operand:DI 2 "register_operand" "a")
8116 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8117 (set (match_operand:DI 1 "register_operand" "=&d")
8118 (mod:DI (match_dup 2) (match_dup 3)))
8119 (clobber (reg:CC FLAGS_REG))]
8120 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8122 [(set_attr "type" "multi")])
8124 (define_insn "*divmoddi_noext_rex64"
8125 [(set (match_operand:DI 0 "register_operand" "=a")
8126 (div:DI (match_operand:DI 1 "register_operand" "0")
8127 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8128 (set (match_operand:DI 3 "register_operand" "=d")
8129 (mod:DI (match_dup 1) (match_dup 2)))
8130 (use (match_operand:DI 4 "register_operand" "3"))
8131 (clobber (reg:CC FLAGS_REG))]
8134 [(set_attr "type" "idiv")
8135 (set_attr "mode" "DI")])
8138 [(set (match_operand:DI 0 "register_operand" "")
8139 (div:DI (match_operand:DI 1 "register_operand" "")
8140 (match_operand:DI 2 "nonimmediate_operand" "")))
8141 (set (match_operand:DI 3 "register_operand" "")
8142 (mod:DI (match_dup 1) (match_dup 2)))
8143 (clobber (reg:CC FLAGS_REG))]
8144 "TARGET_64BIT && reload_completed"
8145 [(parallel [(set (match_dup 3)
8146 (ashiftrt:DI (match_dup 4) (const_int 63)))
8147 (clobber (reg:CC FLAGS_REG))])
8148 (parallel [(set (match_dup 0)
8149 (div:DI (reg:DI 0) (match_dup 2)))
8151 (mod:DI (reg:DI 0) (match_dup 2)))
8153 (clobber (reg:CC FLAGS_REG))])]
8155 /* Avoid use of cltd in favor of a mov+shift. */
8156 if (!TARGET_USE_CLTD && !optimize_size)
8158 if (true_regnum (operands[1]))
8159 emit_move_insn (operands[0], operands[1]);
8161 emit_move_insn (operands[3], operands[1]);
8162 operands[4] = operands[3];
8166 gcc_assert (!true_regnum (operands[1]));
8167 operands[4] = operands[1];
8172 (define_expand "divmodsi4"
8173 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8174 (div:SI (match_operand:SI 1 "register_operand" "")
8175 (match_operand:SI 2 "nonimmediate_operand" "")))
8176 (set (match_operand:SI 3 "register_operand" "")
8177 (mod:SI (match_dup 1) (match_dup 2)))
8178 (clobber (reg:CC FLAGS_REG))])]
8182 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8183 ;; Penalize eax case slightly because it results in worse scheduling
8185 (define_insn "*divmodsi4_nocltd"
8186 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8187 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8188 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8189 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8190 (mod:SI (match_dup 2) (match_dup 3)))
8191 (clobber (reg:CC FLAGS_REG))]
8192 "!optimize_size && !TARGET_USE_CLTD"
8194 [(set_attr "type" "multi")])
8196 (define_insn "*divmodsi4_cltd"
8197 [(set (match_operand:SI 0 "register_operand" "=a")
8198 (div:SI (match_operand:SI 2 "register_operand" "a")
8199 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8200 (set (match_operand:SI 1 "register_operand" "=&d")
8201 (mod:SI (match_dup 2) (match_dup 3)))
8202 (clobber (reg:CC FLAGS_REG))]
8203 "optimize_size || TARGET_USE_CLTD"
8205 [(set_attr "type" "multi")])
8207 (define_insn "*divmodsi_noext"
8208 [(set (match_operand:SI 0 "register_operand" "=a")
8209 (div:SI (match_operand:SI 1 "register_operand" "0")
8210 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8211 (set (match_operand:SI 3 "register_operand" "=d")
8212 (mod:SI (match_dup 1) (match_dup 2)))
8213 (use (match_operand:SI 4 "register_operand" "3"))
8214 (clobber (reg:CC FLAGS_REG))]
8217 [(set_attr "type" "idiv")
8218 (set_attr "mode" "SI")])
8221 [(set (match_operand:SI 0 "register_operand" "")
8222 (div:SI (match_operand:SI 1 "register_operand" "")
8223 (match_operand:SI 2 "nonimmediate_operand" "")))
8224 (set (match_operand:SI 3 "register_operand" "")
8225 (mod:SI (match_dup 1) (match_dup 2)))
8226 (clobber (reg:CC FLAGS_REG))]
8228 [(parallel [(set (match_dup 3)
8229 (ashiftrt:SI (match_dup 4) (const_int 31)))
8230 (clobber (reg:CC FLAGS_REG))])
8231 (parallel [(set (match_dup 0)
8232 (div:SI (reg:SI 0) (match_dup 2)))
8234 (mod:SI (reg:SI 0) (match_dup 2)))
8236 (clobber (reg:CC FLAGS_REG))])]
8238 /* Avoid use of cltd in favor of a mov+shift. */
8239 if (!TARGET_USE_CLTD && !optimize_size)
8241 if (true_regnum (operands[1]))
8242 emit_move_insn (operands[0], operands[1]);
8244 emit_move_insn (operands[3], operands[1]);
8245 operands[4] = operands[3];
8249 gcc_assert (!true_regnum (operands[1]));
8250 operands[4] = operands[1];
8254 (define_insn "divmodhi4"
8255 [(set (match_operand:HI 0 "register_operand" "=a")
8256 (div:HI (match_operand:HI 1 "register_operand" "0")
8257 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8258 (set (match_operand:HI 3 "register_operand" "=&d")
8259 (mod:HI (match_dup 1) (match_dup 2)))
8260 (clobber (reg:CC FLAGS_REG))]
8261 "TARGET_HIMODE_MATH"
8263 [(set_attr "type" "multi")
8264 (set_attr "length_immediate" "0")
8265 (set_attr "mode" "SI")])
8267 (define_insn "udivmoddi4"
8268 [(set (match_operand:DI 0 "register_operand" "=a")
8269 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8270 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8271 (set (match_operand:DI 3 "register_operand" "=&d")
8272 (umod:DI (match_dup 1) (match_dup 2)))
8273 (clobber (reg:CC FLAGS_REG))]
8275 "xor{q}\t%3, %3\;div{q}\t%2"
8276 [(set_attr "type" "multi")
8277 (set_attr "length_immediate" "0")
8278 (set_attr "mode" "DI")])
8280 (define_insn "*udivmoddi4_noext"
8281 [(set (match_operand:DI 0 "register_operand" "=a")
8282 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8283 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8284 (set (match_operand:DI 3 "register_operand" "=d")
8285 (umod:DI (match_dup 1) (match_dup 2)))
8287 (clobber (reg:CC FLAGS_REG))]
8290 [(set_attr "type" "idiv")
8291 (set_attr "mode" "DI")])
8294 [(set (match_operand:DI 0 "register_operand" "")
8295 (udiv:DI (match_operand:DI 1 "register_operand" "")
8296 (match_operand:DI 2 "nonimmediate_operand" "")))
8297 (set (match_operand:DI 3 "register_operand" "")
8298 (umod:DI (match_dup 1) (match_dup 2)))
8299 (clobber (reg:CC FLAGS_REG))]
8300 "TARGET_64BIT && reload_completed"
8301 [(set (match_dup 3) (const_int 0))
8302 (parallel [(set (match_dup 0)
8303 (udiv:DI (match_dup 1) (match_dup 2)))
8305 (umod:DI (match_dup 1) (match_dup 2)))
8307 (clobber (reg:CC FLAGS_REG))])]
8310 (define_insn "udivmodsi4"
8311 [(set (match_operand:SI 0 "register_operand" "=a")
8312 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8313 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8314 (set (match_operand:SI 3 "register_operand" "=&d")
8315 (umod:SI (match_dup 1) (match_dup 2)))
8316 (clobber (reg:CC FLAGS_REG))]
8318 "xor{l}\t%3, %3\;div{l}\t%2"
8319 [(set_attr "type" "multi")
8320 (set_attr "length_immediate" "0")
8321 (set_attr "mode" "SI")])
8323 (define_insn "*udivmodsi4_noext"
8324 [(set (match_operand:SI 0 "register_operand" "=a")
8325 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8326 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8327 (set (match_operand:SI 3 "register_operand" "=d")
8328 (umod:SI (match_dup 1) (match_dup 2)))
8330 (clobber (reg:CC FLAGS_REG))]
8333 [(set_attr "type" "idiv")
8334 (set_attr "mode" "SI")])
8337 [(set (match_operand:SI 0 "register_operand" "")
8338 (udiv:SI (match_operand:SI 1 "register_operand" "")
8339 (match_operand:SI 2 "nonimmediate_operand" "")))
8340 (set (match_operand:SI 3 "register_operand" "")
8341 (umod:SI (match_dup 1) (match_dup 2)))
8342 (clobber (reg:CC FLAGS_REG))]
8344 [(set (match_dup 3) (const_int 0))
8345 (parallel [(set (match_dup 0)
8346 (udiv:SI (match_dup 1) (match_dup 2)))
8348 (umod:SI (match_dup 1) (match_dup 2)))
8350 (clobber (reg:CC FLAGS_REG))])]
8353 (define_expand "udivmodhi4"
8354 [(set (match_dup 4) (const_int 0))
8355 (parallel [(set (match_operand:HI 0 "register_operand" "")
8356 (udiv:HI (match_operand:HI 1 "register_operand" "")
8357 (match_operand:HI 2 "nonimmediate_operand" "")))
8358 (set (match_operand:HI 3 "register_operand" "")
8359 (umod:HI (match_dup 1) (match_dup 2)))
8361 (clobber (reg:CC FLAGS_REG))])]
8362 "TARGET_HIMODE_MATH"
8363 "operands[4] = gen_reg_rtx (HImode);")
8365 (define_insn "*udivmodhi_noext"
8366 [(set (match_operand:HI 0 "register_operand" "=a")
8367 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8368 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8369 (set (match_operand:HI 3 "register_operand" "=d")
8370 (umod:HI (match_dup 1) (match_dup 2)))
8371 (use (match_operand:HI 4 "register_operand" "3"))
8372 (clobber (reg:CC FLAGS_REG))]
8375 [(set_attr "type" "idiv")
8376 (set_attr "mode" "HI")])
8378 ;; We cannot use div/idiv for double division, because it causes
8379 ;; "division by zero" on the overflow and that's not what we expect
8380 ;; from truncate. Because true (non truncating) double division is
8381 ;; never generated, we can't create this insn anyway.
8384 ; [(set (match_operand:SI 0 "register_operand" "=a")
8386 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8388 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8389 ; (set (match_operand:SI 3 "register_operand" "=d")
8391 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8392 ; (clobber (reg:CC FLAGS_REG))]
8394 ; "div{l}\t{%2, %0|%0, %2}"
8395 ; [(set_attr "type" "idiv")])
8397 ;;- Logical AND instructions
8399 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8400 ;; Note that this excludes ah.
8402 (define_insn "*testdi_1_rex64"
8403 [(set (reg FLAGS_REG)
8405 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8406 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8408 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8409 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8411 test{l}\t{%k1, %k0|%k0, %k1}
8412 test{l}\t{%k1, %k0|%k0, %k1}
8413 test{q}\t{%1, %0|%0, %1}
8414 test{q}\t{%1, %0|%0, %1}
8415 test{q}\t{%1, %0|%0, %1}"
8416 [(set_attr "type" "test")
8417 (set_attr "modrm" "0,1,0,1,1")
8418 (set_attr "mode" "SI,SI,DI,DI,DI")
8419 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8421 (define_insn "testsi_1"
8422 [(set (reg FLAGS_REG)
8424 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8425 (match_operand:SI 1 "general_operand" "in,in,rin"))
8427 "ix86_match_ccmode (insn, CCNOmode)
8428 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8429 "test{l}\t{%1, %0|%0, %1}"
8430 [(set_attr "type" "test")
8431 (set_attr "modrm" "0,1,1")
8432 (set_attr "mode" "SI")
8433 (set_attr "pent_pair" "uv,np,uv")])
8435 (define_expand "testsi_ccno_1"
8436 [(set (reg:CCNO FLAGS_REG)
8438 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8439 (match_operand:SI 1 "nonmemory_operand" ""))
8444 (define_insn "*testhi_1"
8445 [(set (reg FLAGS_REG)
8446 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8447 (match_operand:HI 1 "general_operand" "n,n,rn"))
8449 "ix86_match_ccmode (insn, CCNOmode)
8450 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8451 "test{w}\t{%1, %0|%0, %1}"
8452 [(set_attr "type" "test")
8453 (set_attr "modrm" "0,1,1")
8454 (set_attr "mode" "HI")
8455 (set_attr "pent_pair" "uv,np,uv")])
8457 (define_expand "testqi_ccz_1"
8458 [(set (reg:CCZ FLAGS_REG)
8459 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8460 (match_operand:QI 1 "nonmemory_operand" ""))
8465 (define_insn "*testqi_1_maybe_si"
8466 [(set (reg FLAGS_REG)
8469 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8470 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8472 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8473 && ix86_match_ccmode (insn,
8474 CONST_INT_P (operands[1])
8475 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8477 if (which_alternative == 3)
8479 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8480 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8481 return "test{l}\t{%1, %k0|%k0, %1}";
8483 return "test{b}\t{%1, %0|%0, %1}";
8485 [(set_attr "type" "test")
8486 (set_attr "modrm" "0,1,1,1")
8487 (set_attr "mode" "QI,QI,QI,SI")
8488 (set_attr "pent_pair" "uv,np,uv,np")])
8490 (define_insn "*testqi_1"
8491 [(set (reg FLAGS_REG)
8494 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8495 (match_operand:QI 1 "general_operand" "n,n,qn"))
8497 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8498 && ix86_match_ccmode (insn, CCNOmode)"
8499 "test{b}\t{%1, %0|%0, %1}"
8500 [(set_attr "type" "test")
8501 (set_attr "modrm" "0,1,1")
8502 (set_attr "mode" "QI")
8503 (set_attr "pent_pair" "uv,np,uv")])
8505 (define_expand "testqi_ext_ccno_0"
8506 [(set (reg:CCNO FLAGS_REG)
8510 (match_operand 0 "ext_register_operand" "")
8513 (match_operand 1 "const_int_operand" ""))
8518 (define_insn "*testqi_ext_0"
8519 [(set (reg FLAGS_REG)
8523 (match_operand 0 "ext_register_operand" "Q")
8526 (match_operand 1 "const_int_operand" "n"))
8528 "ix86_match_ccmode (insn, CCNOmode)"
8529 "test{b}\t{%1, %h0|%h0, %1}"
8530 [(set_attr "type" "test")
8531 (set_attr "mode" "QI")
8532 (set_attr "length_immediate" "1")
8533 (set_attr "pent_pair" "np")])
8535 (define_insn "*testqi_ext_1"
8536 [(set (reg FLAGS_REG)
8540 (match_operand 0 "ext_register_operand" "Q")
8544 (match_operand:QI 1 "general_operand" "Qm")))
8546 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8547 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8548 "test{b}\t{%1, %h0|%h0, %1}"
8549 [(set_attr "type" "test")
8550 (set_attr "mode" "QI")])
8552 (define_insn "*testqi_ext_1_rex64"
8553 [(set (reg FLAGS_REG)
8557 (match_operand 0 "ext_register_operand" "Q")
8561 (match_operand:QI 1 "register_operand" "Q")))
8563 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8564 "test{b}\t{%1, %h0|%h0, %1}"
8565 [(set_attr "type" "test")
8566 (set_attr "mode" "QI")])
8568 (define_insn "*testqi_ext_2"
8569 [(set (reg FLAGS_REG)
8573 (match_operand 0 "ext_register_operand" "Q")
8577 (match_operand 1 "ext_register_operand" "Q")
8581 "ix86_match_ccmode (insn, CCNOmode)"
8582 "test{b}\t{%h1, %h0|%h0, %h1}"
8583 [(set_attr "type" "test")
8584 (set_attr "mode" "QI")])
8586 ;; Combine likes to form bit extractions for some tests. Humor it.
8587 (define_insn "*testqi_ext_3"
8588 [(set (reg FLAGS_REG)
8589 (compare (zero_extract:SI
8590 (match_operand 0 "nonimmediate_operand" "rm")
8591 (match_operand:SI 1 "const_int_operand" "")
8592 (match_operand:SI 2 "const_int_operand" ""))
8594 "ix86_match_ccmode (insn, CCNOmode)
8595 && INTVAL (operands[1]) > 0
8596 && INTVAL (operands[2]) >= 0
8597 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8598 && (GET_MODE (operands[0]) == SImode
8599 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8600 || GET_MODE (operands[0]) == HImode
8601 || GET_MODE (operands[0]) == QImode)"
8604 (define_insn "*testqi_ext_3_rex64"
8605 [(set (reg FLAGS_REG)
8606 (compare (zero_extract:DI
8607 (match_operand 0 "nonimmediate_operand" "rm")
8608 (match_operand:DI 1 "const_int_operand" "")
8609 (match_operand:DI 2 "const_int_operand" ""))
8612 && ix86_match_ccmode (insn, CCNOmode)
8613 && INTVAL (operands[1]) > 0
8614 && INTVAL (operands[2]) >= 0
8615 /* Ensure that resulting mask is zero or sign extended operand. */
8616 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8617 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8618 && INTVAL (operands[1]) > 32))
8619 && (GET_MODE (operands[0]) == SImode
8620 || GET_MODE (operands[0]) == DImode
8621 || GET_MODE (operands[0]) == HImode
8622 || GET_MODE (operands[0]) == QImode)"
8626 [(set (match_operand 0 "flags_reg_operand" "")
8627 (match_operator 1 "compare_operator"
8629 (match_operand 2 "nonimmediate_operand" "")
8630 (match_operand 3 "const_int_operand" "")
8631 (match_operand 4 "const_int_operand" ""))
8633 "ix86_match_ccmode (insn, CCNOmode)"
8634 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8636 rtx val = operands[2];
8637 HOST_WIDE_INT len = INTVAL (operands[3]);
8638 HOST_WIDE_INT pos = INTVAL (operands[4]);
8640 enum machine_mode mode, submode;
8642 mode = GET_MODE (val);
8645 /* ??? Combine likes to put non-volatile mem extractions in QImode
8646 no matter the size of the test. So find a mode that works. */
8647 if (! MEM_VOLATILE_P (val))
8649 mode = smallest_mode_for_size (pos + len, MODE_INT);
8650 val = adjust_address (val, mode, 0);
8653 else if (GET_CODE (val) == SUBREG
8654 && (submode = GET_MODE (SUBREG_REG (val)),
8655 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8656 && pos + len <= GET_MODE_BITSIZE (submode))
8658 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8660 val = SUBREG_REG (val);
8662 else if (mode == HImode && pos + len <= 8)
8664 /* Small HImode tests can be converted to QImode. */
8666 val = gen_lowpart (QImode, val);
8669 if (len == HOST_BITS_PER_WIDE_INT)
8672 mask = ((HOST_WIDE_INT)1 << len) - 1;
8675 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8678 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8679 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8680 ;; this is relatively important trick.
8681 ;; Do the conversion only post-reload to avoid limiting of the register class
8684 [(set (match_operand 0 "flags_reg_operand" "")
8685 (match_operator 1 "compare_operator"
8686 [(and (match_operand 2 "register_operand" "")
8687 (match_operand 3 "const_int_operand" ""))
8690 && QI_REG_P (operands[2])
8691 && GET_MODE (operands[2]) != QImode
8692 && ((ix86_match_ccmode (insn, CCZmode)
8693 && !(INTVAL (operands[3]) & ~(255 << 8)))
8694 || (ix86_match_ccmode (insn, CCNOmode)
8695 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8698 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8701 "operands[2] = gen_lowpart (SImode, operands[2]);
8702 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8705 [(set (match_operand 0 "flags_reg_operand" "")
8706 (match_operator 1 "compare_operator"
8707 [(and (match_operand 2 "nonimmediate_operand" "")
8708 (match_operand 3 "const_int_operand" ""))
8711 && GET_MODE (operands[2]) != QImode
8712 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8713 && ((ix86_match_ccmode (insn, CCZmode)
8714 && !(INTVAL (operands[3]) & ~255))
8715 || (ix86_match_ccmode (insn, CCNOmode)
8716 && !(INTVAL (operands[3]) & ~127)))"
8718 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8720 "operands[2] = gen_lowpart (QImode, operands[2]);
8721 operands[3] = gen_lowpart (QImode, operands[3]);")
8724 ;; %%% This used to optimize known byte-wide and operations to memory,
8725 ;; and sometimes to QImode registers. If this is considered useful,
8726 ;; it should be done with splitters.
8728 (define_expand "anddi3"
8729 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8730 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8731 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8732 (clobber (reg:CC FLAGS_REG))]
8734 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8736 (define_insn "*anddi_1_rex64"
8737 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8738 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8739 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8740 (clobber (reg:CC FLAGS_REG))]
8741 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8743 switch (get_attr_type (insn))
8747 enum machine_mode mode;
8749 gcc_assert (CONST_INT_P (operands[2]));
8750 if (INTVAL (operands[2]) == 0xff)
8754 gcc_assert (INTVAL (operands[2]) == 0xffff);
8758 operands[1] = gen_lowpart (mode, operands[1]);
8760 return "movz{bq|x}\t{%1,%0|%0, %1}";
8762 return "movz{wq|x}\t{%1,%0|%0, %1}";
8766 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8767 if (get_attr_mode (insn) == MODE_SI)
8768 return "and{l}\t{%k2, %k0|%k0, %k2}";
8770 return "and{q}\t{%2, %0|%0, %2}";
8773 [(set_attr "type" "alu,alu,alu,imovx")
8774 (set_attr "length_immediate" "*,*,*,0")
8775 (set_attr "mode" "SI,DI,DI,DI")])
8777 (define_insn "*anddi_2"
8778 [(set (reg FLAGS_REG)
8779 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8780 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8782 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8783 (and:DI (match_dup 1) (match_dup 2)))]
8784 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8785 && ix86_binary_operator_ok (AND, DImode, operands)"
8787 and{l}\t{%k2, %k0|%k0, %k2}
8788 and{q}\t{%2, %0|%0, %2}
8789 and{q}\t{%2, %0|%0, %2}"
8790 [(set_attr "type" "alu")
8791 (set_attr "mode" "SI,DI,DI")])
8793 (define_expand "andsi3"
8794 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8795 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8796 (match_operand:SI 2 "general_operand" "")))
8797 (clobber (reg:CC FLAGS_REG))]
8799 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8801 (define_insn "*andsi_1"
8802 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8803 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8804 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8805 (clobber (reg:CC FLAGS_REG))]
8806 "ix86_binary_operator_ok (AND, SImode, operands)"
8808 switch (get_attr_type (insn))
8812 enum machine_mode mode;
8814 gcc_assert (CONST_INT_P (operands[2]));
8815 if (INTVAL (operands[2]) == 0xff)
8819 gcc_assert (INTVAL (operands[2]) == 0xffff);
8823 operands[1] = gen_lowpart (mode, operands[1]);
8825 return "movz{bl|x}\t{%1,%0|%0, %1}";
8827 return "movz{wl|x}\t{%1,%0|%0, %1}";
8831 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8832 return "and{l}\t{%2, %0|%0, %2}";
8835 [(set_attr "type" "alu,alu,imovx")
8836 (set_attr "length_immediate" "*,*,0")
8837 (set_attr "mode" "SI")])
8840 [(set (match_operand 0 "register_operand" "")
8842 (const_int -65536)))
8843 (clobber (reg:CC FLAGS_REG))]
8844 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8845 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8846 "operands[1] = gen_lowpart (HImode, operands[0]);")
8849 [(set (match_operand 0 "ext_register_operand" "")
8852 (clobber (reg:CC FLAGS_REG))]
8853 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8854 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8855 "operands[1] = gen_lowpart (QImode, operands[0]);")
8858 [(set (match_operand 0 "ext_register_operand" "")
8860 (const_int -65281)))
8861 (clobber (reg:CC FLAGS_REG))]
8862 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8863 [(parallel [(set (zero_extract:SI (match_dup 0)
8867 (zero_extract:SI (match_dup 0)
8870 (zero_extract:SI (match_dup 0)
8873 (clobber (reg:CC FLAGS_REG))])]
8874 "operands[0] = gen_lowpart (SImode, operands[0]);")
8876 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8877 (define_insn "*andsi_1_zext"
8878 [(set (match_operand:DI 0 "register_operand" "=r")
8880 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8881 (match_operand:SI 2 "general_operand" "g"))))
8882 (clobber (reg:CC FLAGS_REG))]
8883 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8884 "and{l}\t{%2, %k0|%k0, %2}"
8885 [(set_attr "type" "alu")
8886 (set_attr "mode" "SI")])
8888 (define_insn "*andsi_2"
8889 [(set (reg FLAGS_REG)
8890 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8891 (match_operand:SI 2 "general_operand" "g,ri"))
8893 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8894 (and:SI (match_dup 1) (match_dup 2)))]
8895 "ix86_match_ccmode (insn, CCNOmode)
8896 && ix86_binary_operator_ok (AND, SImode, operands)"
8897 "and{l}\t{%2, %0|%0, %2}"
8898 [(set_attr "type" "alu")
8899 (set_attr "mode" "SI")])
8901 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8902 (define_insn "*andsi_2_zext"
8903 [(set (reg FLAGS_REG)
8904 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8905 (match_operand:SI 2 "general_operand" "g"))
8907 (set (match_operand:DI 0 "register_operand" "=r")
8908 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8909 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8910 && ix86_binary_operator_ok (AND, SImode, operands)"
8911 "and{l}\t{%2, %k0|%k0, %2}"
8912 [(set_attr "type" "alu")
8913 (set_attr "mode" "SI")])
8915 (define_expand "andhi3"
8916 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8917 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8918 (match_operand:HI 2 "general_operand" "")))
8919 (clobber (reg:CC FLAGS_REG))]
8920 "TARGET_HIMODE_MATH"
8921 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8923 (define_insn "*andhi_1"
8924 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8925 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8926 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8927 (clobber (reg:CC FLAGS_REG))]
8928 "ix86_binary_operator_ok (AND, HImode, operands)"
8930 switch (get_attr_type (insn))
8933 gcc_assert (CONST_INT_P (operands[2]));
8934 gcc_assert (INTVAL (operands[2]) == 0xff);
8935 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8938 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8940 return "and{w}\t{%2, %0|%0, %2}";
8943 [(set_attr "type" "alu,alu,imovx")
8944 (set_attr "length_immediate" "*,*,0")
8945 (set_attr "mode" "HI,HI,SI")])
8947 (define_insn "*andhi_2"
8948 [(set (reg FLAGS_REG)
8949 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8950 (match_operand:HI 2 "general_operand" "g,ri"))
8952 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8953 (and:HI (match_dup 1) (match_dup 2)))]
8954 "ix86_match_ccmode (insn, CCNOmode)
8955 && ix86_binary_operator_ok (AND, HImode, operands)"
8956 "and{w}\t{%2, %0|%0, %2}"
8957 [(set_attr "type" "alu")
8958 (set_attr "mode" "HI")])
8960 (define_expand "andqi3"
8961 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8962 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8963 (match_operand:QI 2 "general_operand" "")))
8964 (clobber (reg:CC FLAGS_REG))]
8965 "TARGET_QIMODE_MATH"
8966 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8968 ;; %%% Potential partial reg stall on alternative 2. What to do?
8969 (define_insn "*andqi_1"
8970 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8971 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8972 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8973 (clobber (reg:CC FLAGS_REG))]
8974 "ix86_binary_operator_ok (AND, QImode, operands)"
8976 and{b}\t{%2, %0|%0, %2}
8977 and{b}\t{%2, %0|%0, %2}
8978 and{l}\t{%k2, %k0|%k0, %k2}"
8979 [(set_attr "type" "alu")
8980 (set_attr "mode" "QI,QI,SI")])
8982 (define_insn "*andqi_1_slp"
8983 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8984 (and:QI (match_dup 0)
8985 (match_operand:QI 1 "general_operand" "qi,qmi")))
8986 (clobber (reg:CC FLAGS_REG))]
8987 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8988 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8989 "and{b}\t{%1, %0|%0, %1}"
8990 [(set_attr "type" "alu1")
8991 (set_attr "mode" "QI")])
8993 (define_insn "*andqi_2_maybe_si"
8994 [(set (reg FLAGS_REG)
8996 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8997 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8999 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9000 (and:QI (match_dup 1) (match_dup 2)))]
9001 "ix86_binary_operator_ok (AND, QImode, operands)
9002 && ix86_match_ccmode (insn,
9003 CONST_INT_P (operands[2])
9004 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9006 if (which_alternative == 2)
9008 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9009 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9010 return "and{l}\t{%2, %k0|%k0, %2}";
9012 return "and{b}\t{%2, %0|%0, %2}";
9014 [(set_attr "type" "alu")
9015 (set_attr "mode" "QI,QI,SI")])
9017 (define_insn "*andqi_2"
9018 [(set (reg FLAGS_REG)
9020 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9021 (match_operand:QI 2 "general_operand" "qim,qi"))
9023 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9024 (and:QI (match_dup 1) (match_dup 2)))]
9025 "ix86_match_ccmode (insn, CCNOmode)
9026 && ix86_binary_operator_ok (AND, QImode, operands)"
9027 "and{b}\t{%2, %0|%0, %2}"
9028 [(set_attr "type" "alu")
9029 (set_attr "mode" "QI")])
9031 (define_insn "*andqi_2_slp"
9032 [(set (reg FLAGS_REG)
9034 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9035 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9037 (set (strict_low_part (match_dup 0))
9038 (and:QI (match_dup 0) (match_dup 1)))]
9039 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9040 && ix86_match_ccmode (insn, CCNOmode)
9041 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9042 "and{b}\t{%1, %0|%0, %1}"
9043 [(set_attr "type" "alu1")
9044 (set_attr "mode" "QI")])
9046 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9047 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9048 ;; for a QImode operand, which of course failed.
9050 (define_insn "andqi_ext_0"
9051 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9056 (match_operand 1 "ext_register_operand" "0")
9059 (match_operand 2 "const_int_operand" "n")))
9060 (clobber (reg:CC FLAGS_REG))]
9062 "and{b}\t{%2, %h0|%h0, %2}"
9063 [(set_attr "type" "alu")
9064 (set_attr "length_immediate" "1")
9065 (set_attr "mode" "QI")])
9067 ;; Generated by peephole translating test to and. This shows up
9068 ;; often in fp comparisons.
9070 (define_insn "*andqi_ext_0_cc"
9071 [(set (reg FLAGS_REG)
9075 (match_operand 1 "ext_register_operand" "0")
9078 (match_operand 2 "const_int_operand" "n"))
9080 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9089 "ix86_match_ccmode (insn, CCNOmode)"
9090 "and{b}\t{%2, %h0|%h0, %2}"
9091 [(set_attr "type" "alu")
9092 (set_attr "length_immediate" "1")
9093 (set_attr "mode" "QI")])
9095 (define_insn "*andqi_ext_1"
9096 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9101 (match_operand 1 "ext_register_operand" "0")
9105 (match_operand:QI 2 "general_operand" "Qm"))))
9106 (clobber (reg:CC FLAGS_REG))]
9108 "and{b}\t{%2, %h0|%h0, %2}"
9109 [(set_attr "type" "alu")
9110 (set_attr "length_immediate" "0")
9111 (set_attr "mode" "QI")])
9113 (define_insn "*andqi_ext_1_rex64"
9114 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9119 (match_operand 1 "ext_register_operand" "0")
9123 (match_operand 2 "ext_register_operand" "Q"))))
9124 (clobber (reg:CC FLAGS_REG))]
9126 "and{b}\t{%2, %h0|%h0, %2}"
9127 [(set_attr "type" "alu")
9128 (set_attr "length_immediate" "0")
9129 (set_attr "mode" "QI")])
9131 (define_insn "*andqi_ext_2"
9132 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9137 (match_operand 1 "ext_register_operand" "%0")
9141 (match_operand 2 "ext_register_operand" "Q")
9144 (clobber (reg:CC FLAGS_REG))]
9146 "and{b}\t{%h2, %h0|%h0, %h2}"
9147 [(set_attr "type" "alu")
9148 (set_attr "length_immediate" "0")
9149 (set_attr "mode" "QI")])
9151 ;; Convert wide AND instructions with immediate operand to shorter QImode
9152 ;; equivalents when possible.
9153 ;; Don't do the splitting with memory operands, since it introduces risk
9154 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9155 ;; for size, but that can (should?) be handled by generic code instead.
9157 [(set (match_operand 0 "register_operand" "")
9158 (and (match_operand 1 "register_operand" "")
9159 (match_operand 2 "const_int_operand" "")))
9160 (clobber (reg:CC FLAGS_REG))]
9162 && QI_REG_P (operands[0])
9163 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9164 && !(~INTVAL (operands[2]) & ~(255 << 8))
9165 && GET_MODE (operands[0]) != QImode"
9166 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9167 (and:SI (zero_extract:SI (match_dup 1)
9168 (const_int 8) (const_int 8))
9170 (clobber (reg:CC FLAGS_REG))])]
9171 "operands[0] = gen_lowpart (SImode, operands[0]);
9172 operands[1] = gen_lowpart (SImode, operands[1]);
9173 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9175 ;; Since AND can be encoded with sign extended immediate, this is only
9176 ;; profitable when 7th bit is not set.
9178 [(set (match_operand 0 "register_operand" "")
9179 (and (match_operand 1 "general_operand" "")
9180 (match_operand 2 "const_int_operand" "")))
9181 (clobber (reg:CC FLAGS_REG))]
9183 && ANY_QI_REG_P (operands[0])
9184 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9185 && !(~INTVAL (operands[2]) & ~255)
9186 && !(INTVAL (operands[2]) & 128)
9187 && GET_MODE (operands[0]) != QImode"
9188 [(parallel [(set (strict_low_part (match_dup 0))
9189 (and:QI (match_dup 1)
9191 (clobber (reg:CC FLAGS_REG))])]
9192 "operands[0] = gen_lowpart (QImode, operands[0]);
9193 operands[1] = gen_lowpart (QImode, operands[1]);
9194 operands[2] = gen_lowpart (QImode, operands[2]);")
9196 ;; Logical inclusive OR instructions
9198 ;; %%% This used to optimize known byte-wide and operations to memory.
9199 ;; If this is considered useful, it should be done with splitters.
9201 (define_expand "iordi3"
9202 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9203 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9204 (match_operand:DI 2 "x86_64_general_operand" "")))
9205 (clobber (reg:CC FLAGS_REG))]
9207 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9209 (define_insn "*iordi_1_rex64"
9210 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9211 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9212 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9213 (clobber (reg:CC FLAGS_REG))]
9215 && ix86_binary_operator_ok (IOR, DImode, operands)"
9216 "or{q}\t{%2, %0|%0, %2}"
9217 [(set_attr "type" "alu")
9218 (set_attr "mode" "DI")])
9220 (define_insn "*iordi_2_rex64"
9221 [(set (reg FLAGS_REG)
9222 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9223 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9225 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9226 (ior:DI (match_dup 1) (match_dup 2)))]
9228 && ix86_match_ccmode (insn, CCNOmode)
9229 && ix86_binary_operator_ok (IOR, DImode, operands)"
9230 "or{q}\t{%2, %0|%0, %2}"
9231 [(set_attr "type" "alu")
9232 (set_attr "mode" "DI")])
9234 (define_insn "*iordi_3_rex64"
9235 [(set (reg FLAGS_REG)
9236 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9237 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9239 (clobber (match_scratch:DI 0 "=r"))]
9241 && ix86_match_ccmode (insn, CCNOmode)
9242 && ix86_binary_operator_ok (IOR, DImode, operands)"
9243 "or{q}\t{%2, %0|%0, %2}"
9244 [(set_attr "type" "alu")
9245 (set_attr "mode" "DI")])
9248 (define_expand "iorsi3"
9249 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9250 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9251 (match_operand:SI 2 "general_operand" "")))
9252 (clobber (reg:CC FLAGS_REG))]
9254 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9256 (define_insn "*iorsi_1"
9257 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9258 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9259 (match_operand:SI 2 "general_operand" "ri,g")))
9260 (clobber (reg:CC FLAGS_REG))]
9261 "ix86_binary_operator_ok (IOR, SImode, operands)"
9262 "or{l}\t{%2, %0|%0, %2}"
9263 [(set_attr "type" "alu")
9264 (set_attr "mode" "SI")])
9266 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9267 (define_insn "*iorsi_1_zext"
9268 [(set (match_operand:DI 0 "register_operand" "=r")
9270 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9271 (match_operand:SI 2 "general_operand" "g"))))
9272 (clobber (reg:CC FLAGS_REG))]
9273 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9274 "or{l}\t{%2, %k0|%k0, %2}"
9275 [(set_attr "type" "alu")
9276 (set_attr "mode" "SI")])
9278 (define_insn "*iorsi_1_zext_imm"
9279 [(set (match_operand:DI 0 "register_operand" "=r")
9280 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9281 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9282 (clobber (reg:CC FLAGS_REG))]
9284 "or{l}\t{%2, %k0|%k0, %2}"
9285 [(set_attr "type" "alu")
9286 (set_attr "mode" "SI")])
9288 (define_insn "*iorsi_2"
9289 [(set (reg FLAGS_REG)
9290 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9291 (match_operand:SI 2 "general_operand" "g,ri"))
9293 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9294 (ior:SI (match_dup 1) (match_dup 2)))]
9295 "ix86_match_ccmode (insn, CCNOmode)
9296 && ix86_binary_operator_ok (IOR, SImode, operands)"
9297 "or{l}\t{%2, %0|%0, %2}"
9298 [(set_attr "type" "alu")
9299 (set_attr "mode" "SI")])
9301 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9302 ;; ??? Special case for immediate operand is missing - it is tricky.
9303 (define_insn "*iorsi_2_zext"
9304 [(set (reg FLAGS_REG)
9305 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9306 (match_operand:SI 2 "general_operand" "g"))
9308 (set (match_operand:DI 0 "register_operand" "=r")
9309 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9310 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9311 && ix86_binary_operator_ok (IOR, SImode, operands)"
9312 "or{l}\t{%2, %k0|%k0, %2}"
9313 [(set_attr "type" "alu")
9314 (set_attr "mode" "SI")])
9316 (define_insn "*iorsi_2_zext_imm"
9317 [(set (reg FLAGS_REG)
9318 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9319 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9321 (set (match_operand:DI 0 "register_operand" "=r")
9322 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9323 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9324 && ix86_binary_operator_ok (IOR, SImode, operands)"
9325 "or{l}\t{%2, %k0|%k0, %2}"
9326 [(set_attr "type" "alu")
9327 (set_attr "mode" "SI")])
9329 (define_insn "*iorsi_3"
9330 [(set (reg FLAGS_REG)
9331 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9332 (match_operand:SI 2 "general_operand" "g"))
9334 (clobber (match_scratch:SI 0 "=r"))]
9335 "ix86_match_ccmode (insn, CCNOmode)
9336 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9337 "or{l}\t{%2, %0|%0, %2}"
9338 [(set_attr "type" "alu")
9339 (set_attr "mode" "SI")])
9341 (define_expand "iorhi3"
9342 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9343 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9344 (match_operand:HI 2 "general_operand" "")))
9345 (clobber (reg:CC FLAGS_REG))]
9346 "TARGET_HIMODE_MATH"
9347 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9349 (define_insn "*iorhi_1"
9350 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9351 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9352 (match_operand:HI 2 "general_operand" "g,ri")))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "ix86_binary_operator_ok (IOR, HImode, operands)"
9355 "or{w}\t{%2, %0|%0, %2}"
9356 [(set_attr "type" "alu")
9357 (set_attr "mode" "HI")])
9359 (define_insn "*iorhi_2"
9360 [(set (reg FLAGS_REG)
9361 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9362 (match_operand:HI 2 "general_operand" "g,ri"))
9364 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9365 (ior:HI (match_dup 1) (match_dup 2)))]
9366 "ix86_match_ccmode (insn, CCNOmode)
9367 && ix86_binary_operator_ok (IOR, HImode, operands)"
9368 "or{w}\t{%2, %0|%0, %2}"
9369 [(set_attr "type" "alu")
9370 (set_attr "mode" "HI")])
9372 (define_insn "*iorhi_3"
9373 [(set (reg FLAGS_REG)
9374 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9375 (match_operand:HI 2 "general_operand" "g"))
9377 (clobber (match_scratch:HI 0 "=r"))]
9378 "ix86_match_ccmode (insn, CCNOmode)
9379 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9380 "or{w}\t{%2, %0|%0, %2}"
9381 [(set_attr "type" "alu")
9382 (set_attr "mode" "HI")])
9384 (define_expand "iorqi3"
9385 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9386 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9387 (match_operand:QI 2 "general_operand" "")))
9388 (clobber (reg:CC FLAGS_REG))]
9389 "TARGET_QIMODE_MATH"
9390 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9392 ;; %%% Potential partial reg stall on alternative 2. What to do?
9393 (define_insn "*iorqi_1"
9394 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9395 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9396 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9397 (clobber (reg:CC FLAGS_REG))]
9398 "ix86_binary_operator_ok (IOR, QImode, operands)"
9400 or{b}\t{%2, %0|%0, %2}
9401 or{b}\t{%2, %0|%0, %2}
9402 or{l}\t{%k2, %k0|%k0, %k2}"
9403 [(set_attr "type" "alu")
9404 (set_attr "mode" "QI,QI,SI")])
9406 (define_insn "*iorqi_1_slp"
9407 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9408 (ior:QI (match_dup 0)
9409 (match_operand:QI 1 "general_operand" "qmi,qi")))
9410 (clobber (reg:CC FLAGS_REG))]
9411 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9412 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9413 "or{b}\t{%1, %0|%0, %1}"
9414 [(set_attr "type" "alu1")
9415 (set_attr "mode" "QI")])
9417 (define_insn "*iorqi_2"
9418 [(set (reg FLAGS_REG)
9419 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9420 (match_operand:QI 2 "general_operand" "qim,qi"))
9422 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9423 (ior:QI (match_dup 1) (match_dup 2)))]
9424 "ix86_match_ccmode (insn, CCNOmode)
9425 && ix86_binary_operator_ok (IOR, QImode, operands)"
9426 "or{b}\t{%2, %0|%0, %2}"
9427 [(set_attr "type" "alu")
9428 (set_attr "mode" "QI")])
9430 (define_insn "*iorqi_2_slp"
9431 [(set (reg FLAGS_REG)
9432 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9433 (match_operand:QI 1 "general_operand" "qim,qi"))
9435 (set (strict_low_part (match_dup 0))
9436 (ior:QI (match_dup 0) (match_dup 1)))]
9437 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9438 && ix86_match_ccmode (insn, CCNOmode)
9439 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9440 "or{b}\t{%1, %0|%0, %1}"
9441 [(set_attr "type" "alu1")
9442 (set_attr "mode" "QI")])
9444 (define_insn "*iorqi_3"
9445 [(set (reg FLAGS_REG)
9446 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9447 (match_operand:QI 2 "general_operand" "qim"))
9449 (clobber (match_scratch:QI 0 "=q"))]
9450 "ix86_match_ccmode (insn, CCNOmode)
9451 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9452 "or{b}\t{%2, %0|%0, %2}"
9453 [(set_attr "type" "alu")
9454 (set_attr "mode" "QI")])
9456 (define_insn "iorqi_ext_0"
9457 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9462 (match_operand 1 "ext_register_operand" "0")
9465 (match_operand 2 "const_int_operand" "n")))
9466 (clobber (reg:CC FLAGS_REG))]
9467 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9468 "or{b}\t{%2, %h0|%h0, %2}"
9469 [(set_attr "type" "alu")
9470 (set_attr "length_immediate" "1")
9471 (set_attr "mode" "QI")])
9473 (define_insn "*iorqi_ext_1"
9474 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9479 (match_operand 1 "ext_register_operand" "0")
9483 (match_operand:QI 2 "general_operand" "Qm"))))
9484 (clobber (reg:CC FLAGS_REG))]
9486 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9487 "or{b}\t{%2, %h0|%h0, %2}"
9488 [(set_attr "type" "alu")
9489 (set_attr "length_immediate" "0")
9490 (set_attr "mode" "QI")])
9492 (define_insn "*iorqi_ext_1_rex64"
9493 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9498 (match_operand 1 "ext_register_operand" "0")
9502 (match_operand 2 "ext_register_operand" "Q"))))
9503 (clobber (reg:CC FLAGS_REG))]
9505 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9506 "or{b}\t{%2, %h0|%h0, %2}"
9507 [(set_attr "type" "alu")
9508 (set_attr "length_immediate" "0")
9509 (set_attr "mode" "QI")])
9511 (define_insn "*iorqi_ext_2"
9512 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9516 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9519 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9522 (clobber (reg:CC FLAGS_REG))]
9523 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9524 "ior{b}\t{%h2, %h0|%h0, %h2}"
9525 [(set_attr "type" "alu")
9526 (set_attr "length_immediate" "0")
9527 (set_attr "mode" "QI")])
9530 [(set (match_operand 0 "register_operand" "")
9531 (ior (match_operand 1 "register_operand" "")
9532 (match_operand 2 "const_int_operand" "")))
9533 (clobber (reg:CC FLAGS_REG))]
9535 && QI_REG_P (operands[0])
9536 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9537 && !(INTVAL (operands[2]) & ~(255 << 8))
9538 && GET_MODE (operands[0]) != QImode"
9539 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9540 (ior:SI (zero_extract:SI (match_dup 1)
9541 (const_int 8) (const_int 8))
9543 (clobber (reg:CC FLAGS_REG))])]
9544 "operands[0] = gen_lowpart (SImode, operands[0]);
9545 operands[1] = gen_lowpart (SImode, operands[1]);
9546 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9548 ;; Since OR can be encoded with sign extended immediate, this is only
9549 ;; profitable when 7th bit is set.
9551 [(set (match_operand 0 "register_operand" "")
9552 (ior (match_operand 1 "general_operand" "")
9553 (match_operand 2 "const_int_operand" "")))
9554 (clobber (reg:CC FLAGS_REG))]
9556 && ANY_QI_REG_P (operands[0])
9557 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9558 && !(INTVAL (operands[2]) & ~255)
9559 && (INTVAL (operands[2]) & 128)
9560 && GET_MODE (operands[0]) != QImode"
9561 [(parallel [(set (strict_low_part (match_dup 0))
9562 (ior:QI (match_dup 1)
9564 (clobber (reg:CC FLAGS_REG))])]
9565 "operands[0] = gen_lowpart (QImode, operands[0]);
9566 operands[1] = gen_lowpart (QImode, operands[1]);
9567 operands[2] = gen_lowpart (QImode, operands[2]);")
9569 ;; Logical XOR instructions
9571 ;; %%% This used to optimize known byte-wide and operations to memory.
9572 ;; If this is considered useful, it should be done with splitters.
9574 (define_expand "xordi3"
9575 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9576 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9577 (match_operand:DI 2 "x86_64_general_operand" "")))
9578 (clobber (reg:CC FLAGS_REG))]
9580 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9582 (define_insn "*xordi_1_rex64"
9583 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9584 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9585 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9586 (clobber (reg:CC FLAGS_REG))]
9588 && ix86_binary_operator_ok (XOR, DImode, operands)"
9590 xor{q}\t{%2, %0|%0, %2}
9591 xor{q}\t{%2, %0|%0, %2}"
9592 [(set_attr "type" "alu")
9593 (set_attr "mode" "DI,DI")])
9595 (define_insn "*xordi_2_rex64"
9596 [(set (reg FLAGS_REG)
9597 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9598 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9600 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9601 (xor:DI (match_dup 1) (match_dup 2)))]
9603 && ix86_match_ccmode (insn, CCNOmode)
9604 && ix86_binary_operator_ok (XOR, DImode, operands)"
9606 xor{q}\t{%2, %0|%0, %2}
9607 xor{q}\t{%2, %0|%0, %2}"
9608 [(set_attr "type" "alu")
9609 (set_attr "mode" "DI,DI")])
9611 (define_insn "*xordi_3_rex64"
9612 [(set (reg FLAGS_REG)
9613 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9614 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9616 (clobber (match_scratch:DI 0 "=r"))]
9618 && ix86_match_ccmode (insn, CCNOmode)
9619 && ix86_binary_operator_ok (XOR, DImode, operands)"
9620 "xor{q}\t{%2, %0|%0, %2}"
9621 [(set_attr "type" "alu")
9622 (set_attr "mode" "DI")])
9624 (define_expand "xorsi3"
9625 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9626 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9627 (match_operand:SI 2 "general_operand" "")))
9628 (clobber (reg:CC FLAGS_REG))]
9630 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9632 (define_insn "*xorsi_1"
9633 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9634 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9635 (match_operand:SI 2 "general_operand" "ri,rm")))
9636 (clobber (reg:CC FLAGS_REG))]
9637 "ix86_binary_operator_ok (XOR, SImode, operands)"
9638 "xor{l}\t{%2, %0|%0, %2}"
9639 [(set_attr "type" "alu")
9640 (set_attr "mode" "SI")])
9642 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9643 ;; Add speccase for immediates
9644 (define_insn "*xorsi_1_zext"
9645 [(set (match_operand:DI 0 "register_operand" "=r")
9647 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9648 (match_operand:SI 2 "general_operand" "g"))))
9649 (clobber (reg:CC FLAGS_REG))]
9650 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9651 "xor{l}\t{%2, %k0|%k0, %2}"
9652 [(set_attr "type" "alu")
9653 (set_attr "mode" "SI")])
9655 (define_insn "*xorsi_1_zext_imm"
9656 [(set (match_operand:DI 0 "register_operand" "=r")
9657 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9658 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9659 (clobber (reg:CC FLAGS_REG))]
9660 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9661 "xor{l}\t{%2, %k0|%k0, %2}"
9662 [(set_attr "type" "alu")
9663 (set_attr "mode" "SI")])
9665 (define_insn "*xorsi_2"
9666 [(set (reg FLAGS_REG)
9667 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9668 (match_operand:SI 2 "general_operand" "g,ri"))
9670 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9671 (xor:SI (match_dup 1) (match_dup 2)))]
9672 "ix86_match_ccmode (insn, CCNOmode)
9673 && ix86_binary_operator_ok (XOR, SImode, operands)"
9674 "xor{l}\t{%2, %0|%0, %2}"
9675 [(set_attr "type" "alu")
9676 (set_attr "mode" "SI")])
9678 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9679 ;; ??? Special case for immediate operand is missing - it is tricky.
9680 (define_insn "*xorsi_2_zext"
9681 [(set (reg FLAGS_REG)
9682 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9683 (match_operand:SI 2 "general_operand" "g"))
9685 (set (match_operand:DI 0 "register_operand" "=r")
9686 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9687 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9688 && ix86_binary_operator_ok (XOR, SImode, operands)"
9689 "xor{l}\t{%2, %k0|%k0, %2}"
9690 [(set_attr "type" "alu")
9691 (set_attr "mode" "SI")])
9693 (define_insn "*xorsi_2_zext_imm"
9694 [(set (reg FLAGS_REG)
9695 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9696 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9698 (set (match_operand:DI 0 "register_operand" "=r")
9699 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9700 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9701 && ix86_binary_operator_ok (XOR, SImode, operands)"
9702 "xor{l}\t{%2, %k0|%k0, %2}"
9703 [(set_attr "type" "alu")
9704 (set_attr "mode" "SI")])
9706 (define_insn "*xorsi_3"
9707 [(set (reg FLAGS_REG)
9708 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9709 (match_operand:SI 2 "general_operand" "g"))
9711 (clobber (match_scratch:SI 0 "=r"))]
9712 "ix86_match_ccmode (insn, CCNOmode)
9713 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9714 "xor{l}\t{%2, %0|%0, %2}"
9715 [(set_attr "type" "alu")
9716 (set_attr "mode" "SI")])
9718 (define_expand "xorhi3"
9719 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9720 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9721 (match_operand:HI 2 "general_operand" "")))
9722 (clobber (reg:CC FLAGS_REG))]
9723 "TARGET_HIMODE_MATH"
9724 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9726 (define_insn "*xorhi_1"
9727 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9728 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9729 (match_operand:HI 2 "general_operand" "g,ri")))
9730 (clobber (reg:CC FLAGS_REG))]
9731 "ix86_binary_operator_ok (XOR, HImode, operands)"
9732 "xor{w}\t{%2, %0|%0, %2}"
9733 [(set_attr "type" "alu")
9734 (set_attr "mode" "HI")])
9736 (define_insn "*xorhi_2"
9737 [(set (reg FLAGS_REG)
9738 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9739 (match_operand:HI 2 "general_operand" "g,ri"))
9741 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9742 (xor:HI (match_dup 1) (match_dup 2)))]
9743 "ix86_match_ccmode (insn, CCNOmode)
9744 && ix86_binary_operator_ok (XOR, HImode, operands)"
9745 "xor{w}\t{%2, %0|%0, %2}"
9746 [(set_attr "type" "alu")
9747 (set_attr "mode" "HI")])
9749 (define_insn "*xorhi_3"
9750 [(set (reg FLAGS_REG)
9751 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9752 (match_operand:HI 2 "general_operand" "g"))
9754 (clobber (match_scratch:HI 0 "=r"))]
9755 "ix86_match_ccmode (insn, CCNOmode)
9756 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9757 "xor{w}\t{%2, %0|%0, %2}"
9758 [(set_attr "type" "alu")
9759 (set_attr "mode" "HI")])
9761 (define_expand "xorqi3"
9762 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9763 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9764 (match_operand:QI 2 "general_operand" "")))
9765 (clobber (reg:CC FLAGS_REG))]
9766 "TARGET_QIMODE_MATH"
9767 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9769 ;; %%% Potential partial reg stall on alternative 2. What to do?
9770 (define_insn "*xorqi_1"
9771 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9772 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9773 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9774 (clobber (reg:CC FLAGS_REG))]
9775 "ix86_binary_operator_ok (XOR, QImode, operands)"
9777 xor{b}\t{%2, %0|%0, %2}
9778 xor{b}\t{%2, %0|%0, %2}
9779 xor{l}\t{%k2, %k0|%k0, %k2}"
9780 [(set_attr "type" "alu")
9781 (set_attr "mode" "QI,QI,SI")])
9783 (define_insn "*xorqi_1_slp"
9784 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9785 (xor:QI (match_dup 0)
9786 (match_operand:QI 1 "general_operand" "qi,qmi")))
9787 (clobber (reg:CC FLAGS_REG))]
9788 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9789 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9790 "xor{b}\t{%1, %0|%0, %1}"
9791 [(set_attr "type" "alu1")
9792 (set_attr "mode" "QI")])
9794 (define_insn "xorqi_ext_0"
9795 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9800 (match_operand 1 "ext_register_operand" "0")
9803 (match_operand 2 "const_int_operand" "n")))
9804 (clobber (reg:CC FLAGS_REG))]
9805 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9806 "xor{b}\t{%2, %h0|%h0, %2}"
9807 [(set_attr "type" "alu")
9808 (set_attr "length_immediate" "1")
9809 (set_attr "mode" "QI")])
9811 (define_insn "*xorqi_ext_1"
9812 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9817 (match_operand 1 "ext_register_operand" "0")
9821 (match_operand:QI 2 "general_operand" "Qm"))))
9822 (clobber (reg:CC FLAGS_REG))]
9824 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9825 "xor{b}\t{%2, %h0|%h0, %2}"
9826 [(set_attr "type" "alu")
9827 (set_attr "length_immediate" "0")
9828 (set_attr "mode" "QI")])
9830 (define_insn "*xorqi_ext_1_rex64"
9831 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9836 (match_operand 1 "ext_register_operand" "0")
9840 (match_operand 2 "ext_register_operand" "Q"))))
9841 (clobber (reg:CC FLAGS_REG))]
9843 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9844 "xor{b}\t{%2, %h0|%h0, %2}"
9845 [(set_attr "type" "alu")
9846 (set_attr "length_immediate" "0")
9847 (set_attr "mode" "QI")])
9849 (define_insn "*xorqi_ext_2"
9850 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9854 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9857 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9860 (clobber (reg:CC FLAGS_REG))]
9861 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9862 "xor{b}\t{%h2, %h0|%h0, %h2}"
9863 [(set_attr "type" "alu")
9864 (set_attr "length_immediate" "0")
9865 (set_attr "mode" "QI")])
9867 (define_insn "*xorqi_cc_1"
9868 [(set (reg FLAGS_REG)
9870 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9871 (match_operand:QI 2 "general_operand" "qim,qi"))
9873 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9874 (xor:QI (match_dup 1) (match_dup 2)))]
9875 "ix86_match_ccmode (insn, CCNOmode)
9876 && ix86_binary_operator_ok (XOR, QImode, operands)"
9877 "xor{b}\t{%2, %0|%0, %2}"
9878 [(set_attr "type" "alu")
9879 (set_attr "mode" "QI")])
9881 (define_insn "*xorqi_2_slp"
9882 [(set (reg FLAGS_REG)
9883 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9884 (match_operand:QI 1 "general_operand" "qim,qi"))
9886 (set (strict_low_part (match_dup 0))
9887 (xor:QI (match_dup 0) (match_dup 1)))]
9888 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9889 && ix86_match_ccmode (insn, CCNOmode)
9890 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9891 "xor{b}\t{%1, %0|%0, %1}"
9892 [(set_attr "type" "alu1")
9893 (set_attr "mode" "QI")])
9895 (define_insn "*xorqi_cc_2"
9896 [(set (reg FLAGS_REG)
9898 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9899 (match_operand:QI 2 "general_operand" "qim"))
9901 (clobber (match_scratch:QI 0 "=q"))]
9902 "ix86_match_ccmode (insn, CCNOmode)
9903 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9904 "xor{b}\t{%2, %0|%0, %2}"
9905 [(set_attr "type" "alu")
9906 (set_attr "mode" "QI")])
9908 (define_insn "*xorqi_cc_ext_1"
9909 [(set (reg FLAGS_REG)
9913 (match_operand 1 "ext_register_operand" "0")
9916 (match_operand:QI 2 "general_operand" "qmn"))
9918 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9922 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9924 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9925 "xor{b}\t{%2, %h0|%h0, %2}"
9926 [(set_attr "type" "alu")
9927 (set_attr "mode" "QI")])
9929 (define_insn "*xorqi_cc_ext_1_rex64"
9930 [(set (reg FLAGS_REG)
9934 (match_operand 1 "ext_register_operand" "0")
9937 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9939 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9943 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9945 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9946 "xor{b}\t{%2, %h0|%h0, %2}"
9947 [(set_attr "type" "alu")
9948 (set_attr "mode" "QI")])
9950 (define_expand "xorqi_cc_ext_1"
9952 (set (reg:CCNO FLAGS_REG)
9956 (match_operand 1 "ext_register_operand" "")
9959 (match_operand:QI 2 "general_operand" ""))
9961 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9965 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9971 [(set (match_operand 0 "register_operand" "")
9972 (xor (match_operand 1 "register_operand" "")
9973 (match_operand 2 "const_int_operand" "")))
9974 (clobber (reg:CC FLAGS_REG))]
9976 && QI_REG_P (operands[0])
9977 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9978 && !(INTVAL (operands[2]) & ~(255 << 8))
9979 && GET_MODE (operands[0]) != QImode"
9980 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9981 (xor:SI (zero_extract:SI (match_dup 1)
9982 (const_int 8) (const_int 8))
9984 (clobber (reg:CC FLAGS_REG))])]
9985 "operands[0] = gen_lowpart (SImode, operands[0]);
9986 operands[1] = gen_lowpart (SImode, operands[1]);
9987 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9989 ;; Since XOR can be encoded with sign extended immediate, this is only
9990 ;; profitable when 7th bit is set.
9992 [(set (match_operand 0 "register_operand" "")
9993 (xor (match_operand 1 "general_operand" "")
9994 (match_operand 2 "const_int_operand" "")))
9995 (clobber (reg:CC FLAGS_REG))]
9997 && ANY_QI_REG_P (operands[0])
9998 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9999 && !(INTVAL (operands[2]) & ~255)
10000 && (INTVAL (operands[2]) & 128)
10001 && GET_MODE (operands[0]) != QImode"
10002 [(parallel [(set (strict_low_part (match_dup 0))
10003 (xor:QI (match_dup 1)
10005 (clobber (reg:CC FLAGS_REG))])]
10006 "operands[0] = gen_lowpart (QImode, operands[0]);
10007 operands[1] = gen_lowpart (QImode, operands[1]);
10008 operands[2] = gen_lowpart (QImode, operands[2]);")
10010 ;; Negation instructions
10012 (define_expand "negti2"
10013 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10014 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10015 (clobber (reg:CC FLAGS_REG))])]
10017 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10019 (define_insn "*negti2_1"
10020 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10021 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10022 (clobber (reg:CC FLAGS_REG))]
10024 && ix86_unary_operator_ok (NEG, TImode, operands)"
10028 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10029 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10030 (clobber (reg:CC FLAGS_REG))]
10031 "TARGET_64BIT && reload_completed"
10033 [(set (reg:CCZ FLAGS_REG)
10034 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10035 (set (match_dup 0) (neg:DI (match_dup 2)))])
10037 [(set (match_dup 1)
10038 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10041 (clobber (reg:CC FLAGS_REG))])
10043 [(set (match_dup 1)
10044 (neg:DI (match_dup 1)))
10045 (clobber (reg:CC FLAGS_REG))])]
10046 "split_ti (operands+1, 1, operands+2, operands+3);
10047 split_ti (operands+0, 1, operands+0, operands+1);")
10049 (define_expand "negdi2"
10050 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10051 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10052 (clobber (reg:CC FLAGS_REG))])]
10054 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10056 (define_insn "*negdi2_1"
10057 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10058 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10059 (clobber (reg:CC FLAGS_REG))]
10061 && ix86_unary_operator_ok (NEG, DImode, operands)"
10065 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10066 (neg:DI (match_operand:DI 1 "general_operand" "")))
10067 (clobber (reg:CC FLAGS_REG))]
10068 "!TARGET_64BIT && reload_completed"
10070 [(set (reg:CCZ FLAGS_REG)
10071 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10072 (set (match_dup 0) (neg:SI (match_dup 2)))])
10074 [(set (match_dup 1)
10075 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10078 (clobber (reg:CC FLAGS_REG))])
10080 [(set (match_dup 1)
10081 (neg:SI (match_dup 1)))
10082 (clobber (reg:CC FLAGS_REG))])]
10083 "split_di (operands+1, 1, operands+2, operands+3);
10084 split_di (operands+0, 1, operands+0, operands+1);")
10086 (define_insn "*negdi2_1_rex64"
10087 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10088 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10089 (clobber (reg:CC FLAGS_REG))]
10090 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10092 [(set_attr "type" "negnot")
10093 (set_attr "mode" "DI")])
10095 ;; The problem with neg is that it does not perform (compare x 0),
10096 ;; it really performs (compare 0 x), which leaves us with the zero
10097 ;; flag being the only useful item.
10099 (define_insn "*negdi2_cmpz_rex64"
10100 [(set (reg:CCZ FLAGS_REG)
10101 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10103 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10104 (neg:DI (match_dup 1)))]
10105 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10107 [(set_attr "type" "negnot")
10108 (set_attr "mode" "DI")])
10111 (define_expand "negsi2"
10112 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10113 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10114 (clobber (reg:CC FLAGS_REG))])]
10116 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10118 (define_insn "*negsi2_1"
10119 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10120 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10121 (clobber (reg:CC FLAGS_REG))]
10122 "ix86_unary_operator_ok (NEG, SImode, operands)"
10124 [(set_attr "type" "negnot")
10125 (set_attr "mode" "SI")])
10127 ;; Combine is quite creative about this pattern.
10128 (define_insn "*negsi2_1_zext"
10129 [(set (match_operand:DI 0 "register_operand" "=r")
10130 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10133 (clobber (reg:CC FLAGS_REG))]
10134 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10136 [(set_attr "type" "negnot")
10137 (set_attr "mode" "SI")])
10139 ;; The problem with neg is that it does not perform (compare x 0),
10140 ;; it really performs (compare 0 x), which leaves us with the zero
10141 ;; flag being the only useful item.
10143 (define_insn "*negsi2_cmpz"
10144 [(set (reg:CCZ FLAGS_REG)
10145 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10147 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10148 (neg:SI (match_dup 1)))]
10149 "ix86_unary_operator_ok (NEG, SImode, operands)"
10151 [(set_attr "type" "negnot")
10152 (set_attr "mode" "SI")])
10154 (define_insn "*negsi2_cmpz_zext"
10155 [(set (reg:CCZ FLAGS_REG)
10156 (compare:CCZ (lshiftrt:DI
10158 (match_operand:DI 1 "register_operand" "0")
10162 (set (match_operand:DI 0 "register_operand" "=r")
10163 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10166 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10168 [(set_attr "type" "negnot")
10169 (set_attr "mode" "SI")])
10171 (define_expand "neghi2"
10172 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10173 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10174 (clobber (reg:CC FLAGS_REG))])]
10175 "TARGET_HIMODE_MATH"
10176 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10178 (define_insn "*neghi2_1"
10179 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10180 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10181 (clobber (reg:CC FLAGS_REG))]
10182 "ix86_unary_operator_ok (NEG, HImode, operands)"
10184 [(set_attr "type" "negnot")
10185 (set_attr "mode" "HI")])
10187 (define_insn "*neghi2_cmpz"
10188 [(set (reg:CCZ FLAGS_REG)
10189 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10191 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10192 (neg:HI (match_dup 1)))]
10193 "ix86_unary_operator_ok (NEG, HImode, operands)"
10195 [(set_attr "type" "negnot")
10196 (set_attr "mode" "HI")])
10198 (define_expand "negqi2"
10199 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10200 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10201 (clobber (reg:CC FLAGS_REG))])]
10202 "TARGET_QIMODE_MATH"
10203 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10205 (define_insn "*negqi2_1"
10206 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10207 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10208 (clobber (reg:CC FLAGS_REG))]
10209 "ix86_unary_operator_ok (NEG, QImode, operands)"
10211 [(set_attr "type" "negnot")
10212 (set_attr "mode" "QI")])
10214 (define_insn "*negqi2_cmpz"
10215 [(set (reg:CCZ FLAGS_REG)
10216 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10218 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10219 (neg:QI (match_dup 1)))]
10220 "ix86_unary_operator_ok (NEG, QImode, operands)"
10222 [(set_attr "type" "negnot")
10223 (set_attr "mode" "QI")])
10225 ;; Changing of sign for FP values is doable using integer unit too.
10227 (define_expand "negsf2"
10228 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10229 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10230 "TARGET_80387 || TARGET_SSE_MATH"
10231 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
10233 (define_expand "abssf2"
10234 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10235 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10236 "TARGET_80387 || TARGET_SSE_MATH"
10237 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
10239 (define_insn "*absnegsf2_mixed"
10240 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
10241 (match_operator:SF 3 "absneg_operator"
10242 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
10243 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
10244 (clobber (reg:CC FLAGS_REG))]
10245 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10246 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10249 (define_insn "*absnegsf2_sse"
10250 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
10251 (match_operator:SF 3 "absneg_operator"
10252 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
10253 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
10254 (clobber (reg:CC FLAGS_REG))]
10256 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10259 (define_insn "*absnegsf2_i387"
10260 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
10261 (match_operator:SF 3 "absneg_operator"
10262 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
10263 (use (match_operand 2 "" ""))
10264 (clobber (reg:CC FLAGS_REG))]
10265 "TARGET_80387 && !TARGET_SSE_MATH
10266 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10269 (define_expand "negdf2"
10270 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10271 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10272 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10273 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10275 (define_expand "absdf2"
10276 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10277 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10278 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10279 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10281 (define_insn "*absnegdf2_mixed"
10282 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
10283 (match_operator:DF 3 "absneg_operator"
10284 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10285 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
10286 (clobber (reg:CC FLAGS_REG))]
10287 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10288 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10291 (define_insn "*absnegdf2_sse"
10292 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
10293 (match_operator:DF 3 "absneg_operator"
10294 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10295 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
10296 (clobber (reg:CC FLAGS_REG))]
10297 "TARGET_SSE2 && TARGET_SSE_MATH
10298 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10301 (define_insn "*absnegdf2_i387"
10302 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10303 (match_operator:DF 3 "absneg_operator"
10304 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10305 (use (match_operand 2 "" ""))
10306 (clobber (reg:CC FLAGS_REG))]
10307 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10308 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10311 (define_expand "negxf2"
10312 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10313 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10315 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10317 (define_expand "absxf2"
10318 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10319 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10321 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10323 (define_insn "*absnegxf2_i387"
10324 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10325 (match_operator:XF 3 "absneg_operator"
10326 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10327 (use (match_operand 2 "" ""))
10328 (clobber (reg:CC FLAGS_REG))]
10330 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10333 (define_expand "negtf2"
10334 [(set (match_operand:TF 0 "nonimmediate_operand" "")
10335 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10337 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10339 (define_expand "abstf2"
10340 [(set (match_operand:TF 0 "nonimmediate_operand" "")
10341 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10343 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10345 (define_insn "*absnegtf2_sse"
10346 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x,m")
10347 (match_operator:TF 3 "absneg_operator"
10348 [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
10349 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0,X"))
10350 (clobber (reg:CC FLAGS_REG))]
10352 && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
10355 ;; Splitters for fp abs and neg.
10358 [(set (match_operand 0 "fp_register_operand" "")
10359 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10360 (use (match_operand 2 "" ""))
10361 (clobber (reg:CC FLAGS_REG))]
10363 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10366 [(set (match_operand 0 "register_operand" "")
10367 (match_operator 3 "absneg_operator"
10368 [(match_operand 1 "register_operand" "")]))
10369 (use (match_operand 2 "nonimmediate_operand" ""))
10370 (clobber (reg:CC FLAGS_REG))]
10371 "reload_completed && SSE_REG_P (operands[0])"
10372 [(set (match_dup 0) (match_dup 3))]
10374 enum machine_mode mode = GET_MODE (operands[0]);
10375 enum machine_mode vmode = GET_MODE (operands[2]);
10378 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10379 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10380 if (operands_match_p (operands[0], operands[2]))
10383 operands[1] = operands[2];
10386 if (GET_CODE (operands[3]) == ABS)
10387 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10389 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10394 [(set (match_operand:SF 0 "register_operand" "")
10395 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10396 (use (match_operand:V4SF 2 "" ""))
10397 (clobber (reg:CC FLAGS_REG))]
10399 [(parallel [(set (match_dup 0) (match_dup 1))
10400 (clobber (reg:CC FLAGS_REG))])]
10403 operands[0] = gen_lowpart (SImode, operands[0]);
10404 if (GET_CODE (operands[1]) == ABS)
10406 tmp = gen_int_mode (0x7fffffff, SImode);
10407 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10411 tmp = gen_int_mode (0x80000000, SImode);
10412 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10418 [(set (match_operand:DF 0 "register_operand" "")
10419 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10420 (use (match_operand 2 "" ""))
10421 (clobber (reg:CC FLAGS_REG))]
10423 [(parallel [(set (match_dup 0) (match_dup 1))
10424 (clobber (reg:CC FLAGS_REG))])]
10429 tmp = gen_lowpart (DImode, operands[0]);
10430 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10433 if (GET_CODE (operands[1]) == ABS)
10436 tmp = gen_rtx_NOT (DImode, tmp);
10440 operands[0] = gen_highpart (SImode, operands[0]);
10441 if (GET_CODE (operands[1]) == ABS)
10443 tmp = gen_int_mode (0x7fffffff, SImode);
10444 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10448 tmp = gen_int_mode (0x80000000, SImode);
10449 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10456 [(set (match_operand:XF 0 "register_operand" "")
10457 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10458 (use (match_operand 2 "" ""))
10459 (clobber (reg:CC FLAGS_REG))]
10461 [(parallel [(set (match_dup 0) (match_dup 1))
10462 (clobber (reg:CC FLAGS_REG))])]
10465 operands[0] = gen_rtx_REG (SImode,
10466 true_regnum (operands[0])
10467 + (TARGET_64BIT ? 1 : 2));
10468 if (GET_CODE (operands[1]) == ABS)
10470 tmp = GEN_INT (0x7fff);
10471 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10475 tmp = GEN_INT (0x8000);
10476 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10482 [(set (match_operand 0 "memory_operand" "")
10483 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10484 (use (match_operand 2 "" ""))
10485 (clobber (reg:CC FLAGS_REG))]
10487 [(parallel [(set (match_dup 0) (match_dup 1))
10488 (clobber (reg:CC FLAGS_REG))])]
10490 enum machine_mode mode = GET_MODE (operands[0]);
10491 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10494 operands[0] = adjust_address (operands[0], QImode, size - 1);
10495 if (GET_CODE (operands[1]) == ABS)
10497 tmp = gen_int_mode (0x7f, QImode);
10498 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10502 tmp = gen_int_mode (0x80, QImode);
10503 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10508 ;; Conditionalize these after reload. If they match before reload, we
10509 ;; lose the clobber and ability to use integer instructions.
10511 (define_insn "*negsf2_1"
10512 [(set (match_operand:SF 0 "register_operand" "=f")
10513 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10514 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10516 [(set_attr "type" "fsgn")
10517 (set_attr "mode" "SF")])
10519 (define_insn "*negdf2_1"
10520 [(set (match_operand:DF 0 "register_operand" "=f")
10521 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10522 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10524 [(set_attr "type" "fsgn")
10525 (set_attr "mode" "DF")])
10527 (define_insn "*negxf2_1"
10528 [(set (match_operand:XF 0 "register_operand" "=f")
10529 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10532 [(set_attr "type" "fsgn")
10533 (set_attr "mode" "XF")])
10535 (define_insn "*abssf2_1"
10536 [(set (match_operand:SF 0 "register_operand" "=f")
10537 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10538 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10540 [(set_attr "type" "fsgn")
10541 (set_attr "mode" "SF")])
10543 (define_insn "*absdf2_1"
10544 [(set (match_operand:DF 0 "register_operand" "=f")
10545 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10546 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10548 [(set_attr "type" "fsgn")
10549 (set_attr "mode" "DF")])
10551 (define_insn "*absxf2_1"
10552 [(set (match_operand:XF 0 "register_operand" "=f")
10553 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10556 [(set_attr "type" "fsgn")
10557 (set_attr "mode" "DF")])
10559 (define_insn "*negextendsfdf2"
10560 [(set (match_operand:DF 0 "register_operand" "=f")
10561 (neg:DF (float_extend:DF
10562 (match_operand:SF 1 "register_operand" "0"))))]
10563 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10565 [(set_attr "type" "fsgn")
10566 (set_attr "mode" "DF")])
10568 (define_insn "*negextenddfxf2"
10569 [(set (match_operand:XF 0 "register_operand" "=f")
10570 (neg:XF (float_extend:XF
10571 (match_operand:DF 1 "register_operand" "0"))))]
10574 [(set_attr "type" "fsgn")
10575 (set_attr "mode" "XF")])
10577 (define_insn "*negextendsfxf2"
10578 [(set (match_operand:XF 0 "register_operand" "=f")
10579 (neg:XF (float_extend:XF
10580 (match_operand:SF 1 "register_operand" "0"))))]
10583 [(set_attr "type" "fsgn")
10584 (set_attr "mode" "XF")])
10586 (define_insn "*absextendsfdf2"
10587 [(set (match_operand:DF 0 "register_operand" "=f")
10588 (abs:DF (float_extend:DF
10589 (match_operand:SF 1 "register_operand" "0"))))]
10590 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10592 [(set_attr "type" "fsgn")
10593 (set_attr "mode" "DF")])
10595 (define_insn "*absextenddfxf2"
10596 [(set (match_operand:XF 0 "register_operand" "=f")
10597 (abs:XF (float_extend:XF
10598 (match_operand:DF 1 "register_operand" "0"))))]
10601 [(set_attr "type" "fsgn")
10602 (set_attr "mode" "XF")])
10604 (define_insn "*absextendsfxf2"
10605 [(set (match_operand:XF 0 "register_operand" "=f")
10606 (abs:XF (float_extend:XF
10607 (match_operand:SF 1 "register_operand" "0"))))]
10610 [(set_attr "type" "fsgn")
10611 (set_attr "mode" "XF")])
10613 ;; Copysign instructions
10615 (define_mode_iterator CSGNMODE [SF DF TF])
10616 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10618 (define_expand "copysign<mode>3"
10619 [(match_operand:CSGNMODE 0 "register_operand" "")
10620 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10621 (match_operand:CSGNMODE 2 "register_operand" "")]
10622 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10623 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10625 ix86_expand_copysign (operands);
10629 (define_insn_and_split "copysign<mode>3_const"
10630 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10632 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10633 (match_operand:CSGNMODE 2 "register_operand" "0")
10634 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10636 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10637 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10639 "&& reload_completed"
10642 ix86_split_copysign_const (operands);
10646 (define_insn "copysign<mode>3_var"
10647 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10649 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10650 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10651 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10652 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10654 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10655 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10656 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10660 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10662 [(match_operand:CSGNMODE 2 "register_operand" "")
10663 (match_operand:CSGNMODE 3 "register_operand" "")
10664 (match_operand:<CSGNVMODE> 4 "" "")
10665 (match_operand:<CSGNVMODE> 5 "" "")]
10667 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10668 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10669 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10670 && reload_completed"
10673 ix86_split_copysign_var (operands);
10677 ;; One complement instructions
10679 (define_expand "one_cmpldi2"
10680 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10681 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10683 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10685 (define_insn "*one_cmpldi2_1_rex64"
10686 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10687 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10688 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10690 [(set_attr "type" "negnot")
10691 (set_attr "mode" "DI")])
10693 (define_insn "*one_cmpldi2_2_rex64"
10694 [(set (reg FLAGS_REG)
10695 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10697 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10698 (not:DI (match_dup 1)))]
10699 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10700 && ix86_unary_operator_ok (NOT, DImode, operands)"
10702 [(set_attr "type" "alu1")
10703 (set_attr "mode" "DI")])
10706 [(set (match_operand 0 "flags_reg_operand" "")
10707 (match_operator 2 "compare_operator"
10708 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10710 (set (match_operand:DI 1 "nonimmediate_operand" "")
10711 (not:DI (match_dup 3)))]
10712 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10713 [(parallel [(set (match_dup 0)
10715 [(xor:DI (match_dup 3) (const_int -1))
10718 (xor:DI (match_dup 3) (const_int -1)))])]
10721 (define_expand "one_cmplsi2"
10722 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10723 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10725 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10727 (define_insn "*one_cmplsi2_1"
10728 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10729 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10730 "ix86_unary_operator_ok (NOT, SImode, operands)"
10732 [(set_attr "type" "negnot")
10733 (set_attr "mode" "SI")])
10735 ;; ??? Currently never generated - xor is used instead.
10736 (define_insn "*one_cmplsi2_1_zext"
10737 [(set (match_operand:DI 0 "register_operand" "=r")
10738 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10739 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10741 [(set_attr "type" "negnot")
10742 (set_attr "mode" "SI")])
10744 (define_insn "*one_cmplsi2_2"
10745 [(set (reg FLAGS_REG)
10746 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10748 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10749 (not:SI (match_dup 1)))]
10750 "ix86_match_ccmode (insn, CCNOmode)
10751 && ix86_unary_operator_ok (NOT, SImode, operands)"
10753 [(set_attr "type" "alu1")
10754 (set_attr "mode" "SI")])
10757 [(set (match_operand 0 "flags_reg_operand" "")
10758 (match_operator 2 "compare_operator"
10759 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10761 (set (match_operand:SI 1 "nonimmediate_operand" "")
10762 (not:SI (match_dup 3)))]
10763 "ix86_match_ccmode (insn, CCNOmode)"
10764 [(parallel [(set (match_dup 0)
10765 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10768 (xor:SI (match_dup 3) (const_int -1)))])]
10771 ;; ??? Currently never generated - xor is used instead.
10772 (define_insn "*one_cmplsi2_2_zext"
10773 [(set (reg FLAGS_REG)
10774 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10776 (set (match_operand:DI 0 "register_operand" "=r")
10777 (zero_extend:DI (not:SI (match_dup 1))))]
10778 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10779 && ix86_unary_operator_ok (NOT, SImode, operands)"
10781 [(set_attr "type" "alu1")
10782 (set_attr "mode" "SI")])
10785 [(set (match_operand 0 "flags_reg_operand" "")
10786 (match_operator 2 "compare_operator"
10787 [(not:SI (match_operand:SI 3 "register_operand" ""))
10789 (set (match_operand:DI 1 "register_operand" "")
10790 (zero_extend:DI (not:SI (match_dup 3))))]
10791 "ix86_match_ccmode (insn, CCNOmode)"
10792 [(parallel [(set (match_dup 0)
10793 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10796 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10799 (define_expand "one_cmplhi2"
10800 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10801 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10802 "TARGET_HIMODE_MATH"
10803 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10805 (define_insn "*one_cmplhi2_1"
10806 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10807 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10808 "ix86_unary_operator_ok (NOT, HImode, operands)"
10810 [(set_attr "type" "negnot")
10811 (set_attr "mode" "HI")])
10813 (define_insn "*one_cmplhi2_2"
10814 [(set (reg FLAGS_REG)
10815 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10817 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10818 (not:HI (match_dup 1)))]
10819 "ix86_match_ccmode (insn, CCNOmode)
10820 && ix86_unary_operator_ok (NEG, HImode, operands)"
10822 [(set_attr "type" "alu1")
10823 (set_attr "mode" "HI")])
10826 [(set (match_operand 0 "flags_reg_operand" "")
10827 (match_operator 2 "compare_operator"
10828 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10830 (set (match_operand:HI 1 "nonimmediate_operand" "")
10831 (not:HI (match_dup 3)))]
10832 "ix86_match_ccmode (insn, CCNOmode)"
10833 [(parallel [(set (match_dup 0)
10834 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10837 (xor:HI (match_dup 3) (const_int -1)))])]
10840 ;; %%% Potential partial reg stall on alternative 1. What to do?
10841 (define_expand "one_cmplqi2"
10842 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10843 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10844 "TARGET_QIMODE_MATH"
10845 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10847 (define_insn "*one_cmplqi2_1"
10848 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10849 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10850 "ix86_unary_operator_ok (NOT, QImode, operands)"
10854 [(set_attr "type" "negnot")
10855 (set_attr "mode" "QI,SI")])
10857 (define_insn "*one_cmplqi2_2"
10858 [(set (reg FLAGS_REG)
10859 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10861 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10862 (not:QI (match_dup 1)))]
10863 "ix86_match_ccmode (insn, CCNOmode)
10864 && ix86_unary_operator_ok (NOT, QImode, operands)"
10866 [(set_attr "type" "alu1")
10867 (set_attr "mode" "QI")])
10870 [(set (match_operand 0 "flags_reg_operand" "")
10871 (match_operator 2 "compare_operator"
10872 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10874 (set (match_operand:QI 1 "nonimmediate_operand" "")
10875 (not:QI (match_dup 3)))]
10876 "ix86_match_ccmode (insn, CCNOmode)"
10877 [(parallel [(set (match_dup 0)
10878 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10881 (xor:QI (match_dup 3) (const_int -1)))])]
10884 ;; Arithmetic shift instructions
10886 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10887 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10888 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10889 ;; from the assembler input.
10891 ;; This instruction shifts the target reg/mem as usual, but instead of
10892 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10893 ;; is a left shift double, bits are taken from the high order bits of
10894 ;; reg, else if the insn is a shift right double, bits are taken from the
10895 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10896 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10898 ;; Since sh[lr]d does not change the `reg' operand, that is done
10899 ;; separately, making all shifts emit pairs of shift double and normal
10900 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10901 ;; support a 63 bit shift, each shift where the count is in a reg expands
10902 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10904 ;; If the shift count is a constant, we need never emit more than one
10905 ;; shift pair, instead using moves and sign extension for counts greater
10908 (define_expand "ashlti3"
10909 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10910 (ashift:TI (match_operand:TI 1 "register_operand" "")
10911 (match_operand:QI 2 "nonmemory_operand" "")))
10912 (clobber (reg:CC FLAGS_REG))])]
10915 if (! immediate_operand (operands[2], QImode))
10917 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10920 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10924 (define_insn "ashlti3_1"
10925 [(set (match_operand:TI 0 "register_operand" "=r")
10926 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10927 (match_operand:QI 2 "register_operand" "c")))
10928 (clobber (match_scratch:DI 3 "=&r"))
10929 (clobber (reg:CC FLAGS_REG))]
10932 [(set_attr "type" "multi")])
10934 ;; This pattern must be defined before *ashlti3_2 to prevent
10935 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10937 (define_insn "sse2_ashlti3"
10938 [(set (match_operand:TI 0 "register_operand" "=x")
10939 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10940 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10943 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10944 return "pslldq\t{%2, %0|%0, %2}";
10946 [(set_attr "type" "sseishft")
10947 (set_attr "prefix_data16" "1")
10948 (set_attr "mode" "TI")])
10950 (define_insn "*ashlti3_2"
10951 [(set (match_operand:TI 0 "register_operand" "=r")
10952 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10953 (match_operand:QI 2 "immediate_operand" "O")))
10954 (clobber (reg:CC FLAGS_REG))]
10957 [(set_attr "type" "multi")])
10960 [(set (match_operand:TI 0 "register_operand" "")
10961 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10962 (match_operand:QI 2 "register_operand" "")))
10963 (clobber (match_scratch:DI 3 ""))
10964 (clobber (reg:CC FLAGS_REG))]
10965 "TARGET_64BIT && reload_completed"
10967 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10970 [(set (match_operand:TI 0 "register_operand" "")
10971 (ashift:TI (match_operand:TI 1 "register_operand" "")
10972 (match_operand:QI 2 "immediate_operand" "")))
10973 (clobber (reg:CC FLAGS_REG))]
10974 "TARGET_64BIT && reload_completed"
10976 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10978 (define_insn "x86_64_shld"
10979 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10980 (ior:DI (ashift:DI (match_dup 0)
10981 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10982 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10983 (minus:QI (const_int 64) (match_dup 2)))))
10984 (clobber (reg:CC FLAGS_REG))]
10987 shld{q}\t{%2, %1, %0|%0, %1, %2}
10988 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10989 [(set_attr "type" "ishift")
10990 (set_attr "prefix_0f" "1")
10991 (set_attr "mode" "DI")
10992 (set_attr "athlon_decode" "vector")
10993 (set_attr "amdfam10_decode" "vector")])
10995 (define_expand "x86_64_shift_adj"
10996 [(set (reg:CCZ FLAGS_REG)
10997 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11000 (set (match_operand:DI 0 "register_operand" "")
11001 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11002 (match_operand:DI 1 "register_operand" "")
11005 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11006 (match_operand:DI 3 "register_operand" "r")
11011 (define_expand "ashldi3"
11012 [(set (match_operand:DI 0 "shiftdi_operand" "")
11013 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11014 (match_operand:QI 2 "nonmemory_operand" "")))]
11016 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11018 (define_insn "*ashldi3_1_rex64"
11019 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11020 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11021 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11022 (clobber (reg:CC FLAGS_REG))]
11023 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11025 switch (get_attr_type (insn))
11028 gcc_assert (operands[2] == const1_rtx);
11029 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11030 return "add{q}\t%0, %0";
11033 gcc_assert (CONST_INT_P (operands[2]));
11034 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11035 operands[1] = gen_rtx_MULT (DImode, operands[1],
11036 GEN_INT (1 << INTVAL (operands[2])));
11037 return "lea{q}\t{%a1, %0|%0, %a1}";
11040 if (REG_P (operands[2]))
11041 return "sal{q}\t{%b2, %0|%0, %b2}";
11042 else if (operands[2] == const1_rtx
11043 && (TARGET_SHIFT1 || optimize_size))
11044 return "sal{q}\t%0";
11046 return "sal{q}\t{%2, %0|%0, %2}";
11049 [(set (attr "type")
11050 (cond [(eq_attr "alternative" "1")
11051 (const_string "lea")
11052 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11054 (match_operand 0 "register_operand" ""))
11055 (match_operand 2 "const1_operand" ""))
11056 (const_string "alu")
11058 (const_string "ishift")))
11059 (set_attr "mode" "DI")])
11061 ;; Convert lea to the lea pattern to avoid flags dependency.
11063 [(set (match_operand:DI 0 "register_operand" "")
11064 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11065 (match_operand:QI 2 "immediate_operand" "")))
11066 (clobber (reg:CC FLAGS_REG))]
11067 "TARGET_64BIT && reload_completed
11068 && true_regnum (operands[0]) != true_regnum (operands[1])"
11069 [(set (match_dup 0)
11070 (mult:DI (match_dup 1)
11072 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11074 ;; This pattern can't accept a variable shift count, since shifts by
11075 ;; zero don't affect the flags. We assume that shifts by constant
11076 ;; zero are optimized away.
11077 (define_insn "*ashldi3_cmp_rex64"
11078 [(set (reg FLAGS_REG)
11080 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11081 (match_operand:QI 2 "immediate_operand" "e"))
11083 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11084 (ashift:DI (match_dup 1) (match_dup 2)))]
11087 || !TARGET_PARTIAL_FLAG_REG_STALL
11088 || (operands[2] == const1_rtx
11090 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11091 && ix86_match_ccmode (insn, CCGOCmode)
11092 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11094 switch (get_attr_type (insn))
11097 gcc_assert (operands[2] == const1_rtx);
11098 return "add{q}\t%0, %0";
11101 if (REG_P (operands[2]))
11102 return "sal{q}\t{%b2, %0|%0, %b2}";
11103 else if (operands[2] == const1_rtx
11104 && (TARGET_SHIFT1 || optimize_size))
11105 return "sal{q}\t%0";
11107 return "sal{q}\t{%2, %0|%0, %2}";
11110 [(set (attr "type")
11111 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11113 (match_operand 0 "register_operand" ""))
11114 (match_operand 2 "const1_operand" ""))
11115 (const_string "alu")
11117 (const_string "ishift")))
11118 (set_attr "mode" "DI")])
11120 (define_insn "*ashldi3_cconly_rex64"
11121 [(set (reg FLAGS_REG)
11123 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11124 (match_operand:QI 2 "immediate_operand" "e"))
11126 (clobber (match_scratch:DI 0 "=r"))]
11129 || !TARGET_PARTIAL_FLAG_REG_STALL
11130 || (operands[2] == const1_rtx
11132 || TARGET_DOUBLE_WITH_ADD)))
11133 && ix86_match_ccmode (insn, CCGOCmode)
11134 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11136 switch (get_attr_type (insn))
11139 gcc_assert (operands[2] == const1_rtx);
11140 return "add{q}\t%0, %0";
11143 if (REG_P (operands[2]))
11144 return "sal{q}\t{%b2, %0|%0, %b2}";
11145 else if (operands[2] == const1_rtx
11146 && (TARGET_SHIFT1 || optimize_size))
11147 return "sal{q}\t%0";
11149 return "sal{q}\t{%2, %0|%0, %2}";
11152 [(set (attr "type")
11153 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11155 (match_operand 0 "register_operand" ""))
11156 (match_operand 2 "const1_operand" ""))
11157 (const_string "alu")
11159 (const_string "ishift")))
11160 (set_attr "mode" "DI")])
11162 (define_insn "*ashldi3_1"
11163 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11164 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11165 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11166 (clobber (reg:CC FLAGS_REG))]
11169 [(set_attr "type" "multi")])
11171 ;; By default we don't ask for a scratch register, because when DImode
11172 ;; values are manipulated, registers are already at a premium. But if
11173 ;; we have one handy, we won't turn it away.
11175 [(match_scratch:SI 3 "r")
11176 (parallel [(set (match_operand:DI 0 "register_operand" "")
11177 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11178 (match_operand:QI 2 "nonmemory_operand" "")))
11179 (clobber (reg:CC FLAGS_REG))])
11181 "!TARGET_64BIT && TARGET_CMOVE"
11183 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11186 [(set (match_operand:DI 0 "register_operand" "")
11187 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11188 (match_operand:QI 2 "nonmemory_operand" "")))
11189 (clobber (reg:CC FLAGS_REG))]
11190 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11191 ? epilogue_completed : reload_completed)"
11193 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11195 (define_insn "x86_shld_1"
11196 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11197 (ior:SI (ashift:SI (match_dup 0)
11198 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11199 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11200 (minus:QI (const_int 32) (match_dup 2)))))
11201 (clobber (reg:CC FLAGS_REG))]
11204 shld{l}\t{%2, %1, %0|%0, %1, %2}
11205 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11206 [(set_attr "type" "ishift")
11207 (set_attr "prefix_0f" "1")
11208 (set_attr "mode" "SI")
11209 (set_attr "pent_pair" "np")
11210 (set_attr "athlon_decode" "vector")
11211 (set_attr "amdfam10_decode" "vector")])
11213 (define_expand "x86_shift_adj_1"
11214 [(set (reg:CCZ FLAGS_REG)
11215 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11218 (set (match_operand:SI 0 "register_operand" "")
11219 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11220 (match_operand:SI 1 "register_operand" "")
11223 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11224 (match_operand:SI 3 "register_operand" "r")
11229 (define_expand "x86_shift_adj_2"
11230 [(use (match_operand:SI 0 "register_operand" ""))
11231 (use (match_operand:SI 1 "register_operand" ""))
11232 (use (match_operand:QI 2 "register_operand" ""))]
11235 rtx label = gen_label_rtx ();
11238 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11240 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11241 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11242 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11243 gen_rtx_LABEL_REF (VOIDmode, label),
11245 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11246 JUMP_LABEL (tmp) = label;
11248 emit_move_insn (operands[0], operands[1]);
11249 ix86_expand_clear (operands[1]);
11251 emit_label (label);
11252 LABEL_NUSES (label) = 1;
11257 (define_expand "ashlsi3"
11258 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11259 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11260 (match_operand:QI 2 "nonmemory_operand" "")))
11261 (clobber (reg:CC FLAGS_REG))]
11263 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11265 (define_insn "*ashlsi3_1"
11266 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11267 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11268 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11269 (clobber (reg:CC FLAGS_REG))]
11270 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11272 switch (get_attr_type (insn))
11275 gcc_assert (operands[2] == const1_rtx);
11276 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11277 return "add{l}\t%0, %0";
11283 if (REG_P (operands[2]))
11284 return "sal{l}\t{%b2, %0|%0, %b2}";
11285 else if (operands[2] == const1_rtx
11286 && (TARGET_SHIFT1 || optimize_size))
11287 return "sal{l}\t%0";
11289 return "sal{l}\t{%2, %0|%0, %2}";
11292 [(set (attr "type")
11293 (cond [(eq_attr "alternative" "1")
11294 (const_string "lea")
11295 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11297 (match_operand 0 "register_operand" ""))
11298 (match_operand 2 "const1_operand" ""))
11299 (const_string "alu")
11301 (const_string "ishift")))
11302 (set_attr "mode" "SI")])
11304 ;; Convert lea to the lea pattern to avoid flags dependency.
11306 [(set (match_operand 0 "register_operand" "")
11307 (ashift (match_operand 1 "index_register_operand" "")
11308 (match_operand:QI 2 "const_int_operand" "")))
11309 (clobber (reg:CC FLAGS_REG))]
11311 && true_regnum (operands[0]) != true_regnum (operands[1])
11312 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11316 enum machine_mode mode = GET_MODE (operands[0]);
11318 if (GET_MODE_SIZE (mode) < 4)
11319 operands[0] = gen_lowpart (SImode, operands[0]);
11321 operands[1] = gen_lowpart (Pmode, operands[1]);
11322 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11324 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11325 if (Pmode != SImode)
11326 pat = gen_rtx_SUBREG (SImode, pat, 0);
11327 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11331 ;; Rare case of shifting RSP is handled by generating move and shift
11333 [(set (match_operand 0 "register_operand" "")
11334 (ashift (match_operand 1 "register_operand" "")
11335 (match_operand:QI 2 "const_int_operand" "")))
11336 (clobber (reg:CC FLAGS_REG))]
11338 && true_regnum (operands[0]) != true_regnum (operands[1])"
11342 emit_move_insn (operands[0], operands[1]);
11343 pat = gen_rtx_SET (VOIDmode, operands[0],
11344 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11345 operands[0], operands[2]));
11346 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11347 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11351 (define_insn "*ashlsi3_1_zext"
11352 [(set (match_operand:DI 0 "register_operand" "=r,r")
11353 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11354 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11355 (clobber (reg:CC FLAGS_REG))]
11356 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11358 switch (get_attr_type (insn))
11361 gcc_assert (operands[2] == const1_rtx);
11362 return "add{l}\t%k0, %k0";
11368 if (REG_P (operands[2]))
11369 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11370 else if (operands[2] == const1_rtx
11371 && (TARGET_SHIFT1 || optimize_size))
11372 return "sal{l}\t%k0";
11374 return "sal{l}\t{%2, %k0|%k0, %2}";
11377 [(set (attr "type")
11378 (cond [(eq_attr "alternative" "1")
11379 (const_string "lea")
11380 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11382 (match_operand 2 "const1_operand" ""))
11383 (const_string "alu")
11385 (const_string "ishift")))
11386 (set_attr "mode" "SI")])
11388 ;; Convert lea to the lea pattern to avoid flags dependency.
11390 [(set (match_operand:DI 0 "register_operand" "")
11391 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11392 (match_operand:QI 2 "const_int_operand" ""))))
11393 (clobber (reg:CC FLAGS_REG))]
11394 "TARGET_64BIT && reload_completed
11395 && true_regnum (operands[0]) != true_regnum (operands[1])"
11396 [(set (match_dup 0) (zero_extend:DI
11397 (subreg:SI (mult:SI (match_dup 1)
11398 (match_dup 2)) 0)))]
11400 operands[1] = gen_lowpart (Pmode, operands[1]);
11401 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11404 ;; This pattern can't accept a variable shift count, since shifts by
11405 ;; zero don't affect the flags. We assume that shifts by constant
11406 ;; zero are optimized away.
11407 (define_insn "*ashlsi3_cmp"
11408 [(set (reg FLAGS_REG)
11410 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11411 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11413 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11414 (ashift:SI (match_dup 1) (match_dup 2)))]
11416 || !TARGET_PARTIAL_FLAG_REG_STALL
11417 || (operands[2] == const1_rtx
11419 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11420 && ix86_match_ccmode (insn, CCGOCmode)
11421 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11423 switch (get_attr_type (insn))
11426 gcc_assert (operands[2] == const1_rtx);
11427 return "add{l}\t%0, %0";
11430 if (REG_P (operands[2]))
11431 return "sal{l}\t{%b2, %0|%0, %b2}";
11432 else if (operands[2] == const1_rtx
11433 && (TARGET_SHIFT1 || optimize_size))
11434 return "sal{l}\t%0";
11436 return "sal{l}\t{%2, %0|%0, %2}";
11439 [(set (attr "type")
11440 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11442 (match_operand 0 "register_operand" ""))
11443 (match_operand 2 "const1_operand" ""))
11444 (const_string "alu")
11446 (const_string "ishift")))
11447 (set_attr "mode" "SI")])
11449 (define_insn "*ashlsi3_cconly"
11450 [(set (reg FLAGS_REG)
11452 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11453 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11455 (clobber (match_scratch:SI 0 "=r"))]
11457 || !TARGET_PARTIAL_FLAG_REG_STALL
11458 || (operands[2] == const1_rtx
11460 || TARGET_DOUBLE_WITH_ADD)))
11461 && ix86_match_ccmode (insn, CCGOCmode)
11462 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11464 switch (get_attr_type (insn))
11467 gcc_assert (operands[2] == const1_rtx);
11468 return "add{l}\t%0, %0";
11471 if (REG_P (operands[2]))
11472 return "sal{l}\t{%b2, %0|%0, %b2}";
11473 else if (operands[2] == const1_rtx
11474 && (TARGET_SHIFT1 || optimize_size))
11475 return "sal{l}\t%0";
11477 return "sal{l}\t{%2, %0|%0, %2}";
11480 [(set (attr "type")
11481 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11483 (match_operand 0 "register_operand" ""))
11484 (match_operand 2 "const1_operand" ""))
11485 (const_string "alu")
11487 (const_string "ishift")))
11488 (set_attr "mode" "SI")])
11490 (define_insn "*ashlsi3_cmp_zext"
11491 [(set (reg FLAGS_REG)
11493 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11494 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11496 (set (match_operand:DI 0 "register_operand" "=r")
11497 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11500 || !TARGET_PARTIAL_FLAG_REG_STALL
11501 || (operands[2] == const1_rtx
11503 || TARGET_DOUBLE_WITH_ADD)))
11504 && ix86_match_ccmode (insn, CCGOCmode)
11505 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11507 switch (get_attr_type (insn))
11510 gcc_assert (operands[2] == const1_rtx);
11511 return "add{l}\t%k0, %k0";
11514 if (REG_P (operands[2]))
11515 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11516 else if (operands[2] == const1_rtx
11517 && (TARGET_SHIFT1 || optimize_size))
11518 return "sal{l}\t%k0";
11520 return "sal{l}\t{%2, %k0|%k0, %2}";
11523 [(set (attr "type")
11524 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11526 (match_operand 2 "const1_operand" ""))
11527 (const_string "alu")
11529 (const_string "ishift")))
11530 (set_attr "mode" "SI")])
11532 (define_expand "ashlhi3"
11533 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11534 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11535 (match_operand:QI 2 "nonmemory_operand" "")))
11536 (clobber (reg:CC FLAGS_REG))]
11537 "TARGET_HIMODE_MATH"
11538 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11540 (define_insn "*ashlhi3_1_lea"
11541 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11542 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11543 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11544 (clobber (reg:CC FLAGS_REG))]
11545 "!TARGET_PARTIAL_REG_STALL
11546 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11548 switch (get_attr_type (insn))
11553 gcc_assert (operands[2] == const1_rtx);
11554 return "add{w}\t%0, %0";
11557 if (REG_P (operands[2]))
11558 return "sal{w}\t{%b2, %0|%0, %b2}";
11559 else if (operands[2] == const1_rtx
11560 && (TARGET_SHIFT1 || optimize_size))
11561 return "sal{w}\t%0";
11563 return "sal{w}\t{%2, %0|%0, %2}";
11566 [(set (attr "type")
11567 (cond [(eq_attr "alternative" "1")
11568 (const_string "lea")
11569 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11571 (match_operand 0 "register_operand" ""))
11572 (match_operand 2 "const1_operand" ""))
11573 (const_string "alu")
11575 (const_string "ishift")))
11576 (set_attr "mode" "HI,SI")])
11578 (define_insn "*ashlhi3_1"
11579 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11580 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11581 (match_operand:QI 2 "nonmemory_operand" "cI")))
11582 (clobber (reg:CC FLAGS_REG))]
11583 "TARGET_PARTIAL_REG_STALL
11584 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11586 switch (get_attr_type (insn))
11589 gcc_assert (operands[2] == const1_rtx);
11590 return "add{w}\t%0, %0";
11593 if (REG_P (operands[2]))
11594 return "sal{w}\t{%b2, %0|%0, %b2}";
11595 else if (operands[2] == const1_rtx
11596 && (TARGET_SHIFT1 || optimize_size))
11597 return "sal{w}\t%0";
11599 return "sal{w}\t{%2, %0|%0, %2}";
11602 [(set (attr "type")
11603 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11605 (match_operand 0 "register_operand" ""))
11606 (match_operand 2 "const1_operand" ""))
11607 (const_string "alu")
11609 (const_string "ishift")))
11610 (set_attr "mode" "HI")])
11612 ;; This pattern can't accept a variable shift count, since shifts by
11613 ;; zero don't affect the flags. We assume that shifts by constant
11614 ;; zero are optimized away.
11615 (define_insn "*ashlhi3_cmp"
11616 [(set (reg FLAGS_REG)
11618 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11619 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11621 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11622 (ashift:HI (match_dup 1) (match_dup 2)))]
11624 || !TARGET_PARTIAL_FLAG_REG_STALL
11625 || (operands[2] == const1_rtx
11627 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11628 && ix86_match_ccmode (insn, CCGOCmode)
11629 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11631 switch (get_attr_type (insn))
11634 gcc_assert (operands[2] == const1_rtx);
11635 return "add{w}\t%0, %0";
11638 if (REG_P (operands[2]))
11639 return "sal{w}\t{%b2, %0|%0, %b2}";
11640 else if (operands[2] == const1_rtx
11641 && (TARGET_SHIFT1 || optimize_size))
11642 return "sal{w}\t%0";
11644 return "sal{w}\t{%2, %0|%0, %2}";
11647 [(set (attr "type")
11648 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11650 (match_operand 0 "register_operand" ""))
11651 (match_operand 2 "const1_operand" ""))
11652 (const_string "alu")
11654 (const_string "ishift")))
11655 (set_attr "mode" "HI")])
11657 (define_insn "*ashlhi3_cconly"
11658 [(set (reg FLAGS_REG)
11660 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11661 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11663 (clobber (match_scratch:HI 0 "=r"))]
11665 || !TARGET_PARTIAL_FLAG_REG_STALL
11666 || (operands[2] == const1_rtx
11668 || TARGET_DOUBLE_WITH_ADD)))
11669 && ix86_match_ccmode (insn, CCGOCmode)
11670 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11672 switch (get_attr_type (insn))
11675 gcc_assert (operands[2] == const1_rtx);
11676 return "add{w}\t%0, %0";
11679 if (REG_P (operands[2]))
11680 return "sal{w}\t{%b2, %0|%0, %b2}";
11681 else if (operands[2] == const1_rtx
11682 && (TARGET_SHIFT1 || optimize_size))
11683 return "sal{w}\t%0";
11685 return "sal{w}\t{%2, %0|%0, %2}";
11688 [(set (attr "type")
11689 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11691 (match_operand 0 "register_operand" ""))
11692 (match_operand 2 "const1_operand" ""))
11693 (const_string "alu")
11695 (const_string "ishift")))
11696 (set_attr "mode" "HI")])
11698 (define_expand "ashlqi3"
11699 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11700 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11701 (match_operand:QI 2 "nonmemory_operand" "")))
11702 (clobber (reg:CC FLAGS_REG))]
11703 "TARGET_QIMODE_MATH"
11704 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11706 ;; %%% Potential partial reg stall on alternative 2. What to do?
11708 (define_insn "*ashlqi3_1_lea"
11709 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11710 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11711 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11712 (clobber (reg:CC FLAGS_REG))]
11713 "!TARGET_PARTIAL_REG_STALL
11714 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11716 switch (get_attr_type (insn))
11721 gcc_assert (operands[2] == const1_rtx);
11722 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11723 return "add{l}\t%k0, %k0";
11725 return "add{b}\t%0, %0";
11728 if (REG_P (operands[2]))
11730 if (get_attr_mode (insn) == MODE_SI)
11731 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11733 return "sal{b}\t{%b2, %0|%0, %b2}";
11735 else if (operands[2] == const1_rtx
11736 && (TARGET_SHIFT1 || optimize_size))
11738 if (get_attr_mode (insn) == MODE_SI)
11739 return "sal{l}\t%0";
11741 return "sal{b}\t%0";
11745 if (get_attr_mode (insn) == MODE_SI)
11746 return "sal{l}\t{%2, %k0|%k0, %2}";
11748 return "sal{b}\t{%2, %0|%0, %2}";
11752 [(set (attr "type")
11753 (cond [(eq_attr "alternative" "2")
11754 (const_string "lea")
11755 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11757 (match_operand 0 "register_operand" ""))
11758 (match_operand 2 "const1_operand" ""))
11759 (const_string "alu")
11761 (const_string "ishift")))
11762 (set_attr "mode" "QI,SI,SI")])
11764 (define_insn "*ashlqi3_1"
11765 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11766 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11767 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11768 (clobber (reg:CC FLAGS_REG))]
11769 "TARGET_PARTIAL_REG_STALL
11770 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11772 switch (get_attr_type (insn))
11775 gcc_assert (operands[2] == const1_rtx);
11776 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11777 return "add{l}\t%k0, %k0";
11779 return "add{b}\t%0, %0";
11782 if (REG_P (operands[2]))
11784 if (get_attr_mode (insn) == MODE_SI)
11785 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11787 return "sal{b}\t{%b2, %0|%0, %b2}";
11789 else if (operands[2] == const1_rtx
11790 && (TARGET_SHIFT1 || optimize_size))
11792 if (get_attr_mode (insn) == MODE_SI)
11793 return "sal{l}\t%0";
11795 return "sal{b}\t%0";
11799 if (get_attr_mode (insn) == MODE_SI)
11800 return "sal{l}\t{%2, %k0|%k0, %2}";
11802 return "sal{b}\t{%2, %0|%0, %2}";
11806 [(set (attr "type")
11807 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11809 (match_operand 0 "register_operand" ""))
11810 (match_operand 2 "const1_operand" ""))
11811 (const_string "alu")
11813 (const_string "ishift")))
11814 (set_attr "mode" "QI,SI")])
11816 ;; This pattern can't accept a variable shift count, since shifts by
11817 ;; zero don't affect the flags. We assume that shifts by constant
11818 ;; zero are optimized away.
11819 (define_insn "*ashlqi3_cmp"
11820 [(set (reg FLAGS_REG)
11822 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11823 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11825 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11826 (ashift:QI (match_dup 1) (match_dup 2)))]
11828 || !TARGET_PARTIAL_FLAG_REG_STALL
11829 || (operands[2] == const1_rtx
11831 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11832 && ix86_match_ccmode (insn, CCGOCmode)
11833 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11835 switch (get_attr_type (insn))
11838 gcc_assert (operands[2] == const1_rtx);
11839 return "add{b}\t%0, %0";
11842 if (REG_P (operands[2]))
11843 return "sal{b}\t{%b2, %0|%0, %b2}";
11844 else if (operands[2] == const1_rtx
11845 && (TARGET_SHIFT1 || optimize_size))
11846 return "sal{b}\t%0";
11848 return "sal{b}\t{%2, %0|%0, %2}";
11851 [(set (attr "type")
11852 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11854 (match_operand 0 "register_operand" ""))
11855 (match_operand 2 "const1_operand" ""))
11856 (const_string "alu")
11858 (const_string "ishift")))
11859 (set_attr "mode" "QI")])
11861 (define_insn "*ashlqi3_cconly"
11862 [(set (reg FLAGS_REG)
11864 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11865 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11867 (clobber (match_scratch:QI 0 "=q"))]
11869 || !TARGET_PARTIAL_FLAG_REG_STALL
11870 || (operands[2] == const1_rtx
11872 || TARGET_DOUBLE_WITH_ADD)))
11873 && ix86_match_ccmode (insn, CCGOCmode)
11874 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11876 switch (get_attr_type (insn))
11879 gcc_assert (operands[2] == const1_rtx);
11880 return "add{b}\t%0, %0";
11883 if (REG_P (operands[2]))
11884 return "sal{b}\t{%b2, %0|%0, %b2}";
11885 else if (operands[2] == const1_rtx
11886 && (TARGET_SHIFT1 || optimize_size))
11887 return "sal{b}\t%0";
11889 return "sal{b}\t{%2, %0|%0, %2}";
11892 [(set (attr "type")
11893 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11895 (match_operand 0 "register_operand" ""))
11896 (match_operand 2 "const1_operand" ""))
11897 (const_string "alu")
11899 (const_string "ishift")))
11900 (set_attr "mode" "QI")])
11902 ;; See comment above `ashldi3' about how this works.
11904 (define_expand "ashrti3"
11905 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11906 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11907 (match_operand:QI 2 "nonmemory_operand" "")))
11908 (clobber (reg:CC FLAGS_REG))])]
11911 if (! immediate_operand (operands[2], QImode))
11913 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11916 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11920 (define_insn "ashrti3_1"
11921 [(set (match_operand:TI 0 "register_operand" "=r")
11922 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11923 (match_operand:QI 2 "register_operand" "c")))
11924 (clobber (match_scratch:DI 3 "=&r"))
11925 (clobber (reg:CC FLAGS_REG))]
11928 [(set_attr "type" "multi")])
11930 (define_insn "*ashrti3_2"
11931 [(set (match_operand:TI 0 "register_operand" "=r")
11932 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11933 (match_operand:QI 2 "immediate_operand" "O")))
11934 (clobber (reg:CC FLAGS_REG))]
11937 [(set_attr "type" "multi")])
11940 [(set (match_operand:TI 0 "register_operand" "")
11941 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11942 (match_operand:QI 2 "register_operand" "")))
11943 (clobber (match_scratch:DI 3 ""))
11944 (clobber (reg:CC FLAGS_REG))]
11945 "TARGET_64BIT && reload_completed"
11947 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11950 [(set (match_operand:TI 0 "register_operand" "")
11951 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11952 (match_operand:QI 2 "immediate_operand" "")))
11953 (clobber (reg:CC FLAGS_REG))]
11954 "TARGET_64BIT && reload_completed"
11956 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11958 (define_insn "x86_64_shrd"
11959 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11960 (ior:DI (ashiftrt:DI (match_dup 0)
11961 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11962 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11963 (minus:QI (const_int 64) (match_dup 2)))))
11964 (clobber (reg:CC FLAGS_REG))]
11967 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11968 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11969 [(set_attr "type" "ishift")
11970 (set_attr "prefix_0f" "1")
11971 (set_attr "mode" "DI")
11972 (set_attr "athlon_decode" "vector")
11973 (set_attr "amdfam10_decode" "vector")])
11975 (define_expand "ashrdi3"
11976 [(set (match_operand:DI 0 "shiftdi_operand" "")
11977 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11978 (match_operand:QI 2 "nonmemory_operand" "")))]
11980 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11982 (define_insn "*ashrdi3_63_rex64"
11983 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11984 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11985 (match_operand:DI 2 "const_int_operand" "i,i")))
11986 (clobber (reg:CC FLAGS_REG))]
11987 "TARGET_64BIT && INTVAL (operands[2]) == 63
11988 && (TARGET_USE_CLTD || optimize_size)
11989 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11992 sar{q}\t{%2, %0|%0, %2}"
11993 [(set_attr "type" "imovx,ishift")
11994 (set_attr "prefix_0f" "0,*")
11995 (set_attr "length_immediate" "0,*")
11996 (set_attr "modrm" "0,1")
11997 (set_attr "mode" "DI")])
11999 (define_insn "*ashrdi3_1_one_bit_rex64"
12000 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12001 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12002 (match_operand:QI 2 "const1_operand" "")))
12003 (clobber (reg:CC FLAGS_REG))]
12005 && (TARGET_SHIFT1 || optimize_size)
12006 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12008 [(set_attr "type" "ishift")
12009 (set (attr "length")
12010 (if_then_else (match_operand:DI 0 "register_operand" "")
12012 (const_string "*")))])
12014 (define_insn "*ashrdi3_1_rex64"
12015 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12016 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12017 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12018 (clobber (reg:CC FLAGS_REG))]
12019 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12021 sar{q}\t{%2, %0|%0, %2}
12022 sar{q}\t{%b2, %0|%0, %b2}"
12023 [(set_attr "type" "ishift")
12024 (set_attr "mode" "DI")])
12026 ;; This pattern can't accept a variable shift count, since shifts by
12027 ;; zero don't affect the flags. We assume that shifts by constant
12028 ;; zero are optimized away.
12029 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12030 [(set (reg FLAGS_REG)
12032 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12033 (match_operand:QI 2 "const1_operand" ""))
12035 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12036 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12038 && (TARGET_SHIFT1 || optimize_size)
12039 && ix86_match_ccmode (insn, CCGOCmode)
12040 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12042 [(set_attr "type" "ishift")
12043 (set (attr "length")
12044 (if_then_else (match_operand:DI 0 "register_operand" "")
12046 (const_string "*")))])
12048 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12049 [(set (reg FLAGS_REG)
12051 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12052 (match_operand:QI 2 "const1_operand" ""))
12054 (clobber (match_scratch:DI 0 "=r"))]
12056 && (TARGET_SHIFT1 || optimize_size)
12057 && ix86_match_ccmode (insn, CCGOCmode)
12058 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12060 [(set_attr "type" "ishift")
12061 (set_attr "length" "2")])
12063 ;; This pattern can't accept a variable shift count, since shifts by
12064 ;; zero don't affect the flags. We assume that shifts by constant
12065 ;; zero are optimized away.
12066 (define_insn "*ashrdi3_cmp_rex64"
12067 [(set (reg FLAGS_REG)
12069 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12070 (match_operand:QI 2 "const_int_operand" "n"))
12072 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12073 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12075 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12076 && ix86_match_ccmode (insn, CCGOCmode)
12077 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12078 "sar{q}\t{%2, %0|%0, %2}"
12079 [(set_attr "type" "ishift")
12080 (set_attr "mode" "DI")])
12082 (define_insn "*ashrdi3_cconly_rex64"
12083 [(set (reg FLAGS_REG)
12085 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12086 (match_operand:QI 2 "const_int_operand" "n"))
12088 (clobber (match_scratch:DI 0 "=r"))]
12090 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12091 && ix86_match_ccmode (insn, CCGOCmode)
12092 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12093 "sar{q}\t{%2, %0|%0, %2}"
12094 [(set_attr "type" "ishift")
12095 (set_attr "mode" "DI")])
12097 (define_insn "*ashrdi3_1"
12098 [(set (match_operand:DI 0 "register_operand" "=r")
12099 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12100 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12101 (clobber (reg:CC FLAGS_REG))]
12104 [(set_attr "type" "multi")])
12106 ;; By default we don't ask for a scratch register, because when DImode
12107 ;; values are manipulated, registers are already at a premium. But if
12108 ;; we have one handy, we won't turn it away.
12110 [(match_scratch:SI 3 "r")
12111 (parallel [(set (match_operand:DI 0 "register_operand" "")
12112 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12113 (match_operand:QI 2 "nonmemory_operand" "")))
12114 (clobber (reg:CC FLAGS_REG))])
12116 "!TARGET_64BIT && TARGET_CMOVE"
12118 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12121 [(set (match_operand:DI 0 "register_operand" "")
12122 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12123 (match_operand:QI 2 "nonmemory_operand" "")))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12126 ? epilogue_completed : reload_completed)"
12128 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12130 (define_insn "x86_shrd_1"
12131 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12132 (ior:SI (ashiftrt:SI (match_dup 0)
12133 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12134 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12135 (minus:QI (const_int 32) (match_dup 2)))))
12136 (clobber (reg:CC FLAGS_REG))]
12139 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12140 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12141 [(set_attr "type" "ishift")
12142 (set_attr "prefix_0f" "1")
12143 (set_attr "pent_pair" "np")
12144 (set_attr "mode" "SI")])
12146 (define_expand "x86_shift_adj_3"
12147 [(use (match_operand:SI 0 "register_operand" ""))
12148 (use (match_operand:SI 1 "register_operand" ""))
12149 (use (match_operand:QI 2 "register_operand" ""))]
12152 rtx label = gen_label_rtx ();
12155 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12157 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12158 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12159 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12160 gen_rtx_LABEL_REF (VOIDmode, label),
12162 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12163 JUMP_LABEL (tmp) = label;
12165 emit_move_insn (operands[0], operands[1]);
12166 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12168 emit_label (label);
12169 LABEL_NUSES (label) = 1;
12174 (define_insn "ashrsi3_31"
12175 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12176 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12177 (match_operand:SI 2 "const_int_operand" "i,i")))
12178 (clobber (reg:CC FLAGS_REG))]
12179 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12180 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12183 sar{l}\t{%2, %0|%0, %2}"
12184 [(set_attr "type" "imovx,ishift")
12185 (set_attr "prefix_0f" "0,*")
12186 (set_attr "length_immediate" "0,*")
12187 (set_attr "modrm" "0,1")
12188 (set_attr "mode" "SI")])
12190 (define_insn "*ashrsi3_31_zext"
12191 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12192 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12193 (match_operand:SI 2 "const_int_operand" "i,i"))))
12194 (clobber (reg:CC FLAGS_REG))]
12195 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12196 && INTVAL (operands[2]) == 31
12197 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12200 sar{l}\t{%2, %k0|%k0, %2}"
12201 [(set_attr "type" "imovx,ishift")
12202 (set_attr "prefix_0f" "0,*")
12203 (set_attr "length_immediate" "0,*")
12204 (set_attr "modrm" "0,1")
12205 (set_attr "mode" "SI")])
12207 (define_expand "ashrsi3"
12208 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12209 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12210 (match_operand:QI 2 "nonmemory_operand" "")))
12211 (clobber (reg:CC FLAGS_REG))]
12213 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12215 (define_insn "*ashrsi3_1_one_bit"
12216 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12217 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12218 (match_operand:QI 2 "const1_operand" "")))
12219 (clobber (reg:CC FLAGS_REG))]
12220 "(TARGET_SHIFT1 || optimize_size)
12221 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12223 [(set_attr "type" "ishift")
12224 (set (attr "length")
12225 (if_then_else (match_operand:SI 0 "register_operand" "")
12227 (const_string "*")))])
12229 (define_insn "*ashrsi3_1_one_bit_zext"
12230 [(set (match_operand:DI 0 "register_operand" "=r")
12231 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12232 (match_operand:QI 2 "const1_operand" ""))))
12233 (clobber (reg:CC FLAGS_REG))]
12235 && (TARGET_SHIFT1 || optimize_size)
12236 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12238 [(set_attr "type" "ishift")
12239 (set_attr "length" "2")])
12241 (define_insn "*ashrsi3_1"
12242 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12243 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12244 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12245 (clobber (reg:CC FLAGS_REG))]
12246 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12248 sar{l}\t{%2, %0|%0, %2}
12249 sar{l}\t{%b2, %0|%0, %b2}"
12250 [(set_attr "type" "ishift")
12251 (set_attr "mode" "SI")])
12253 (define_insn "*ashrsi3_1_zext"
12254 [(set (match_operand:DI 0 "register_operand" "=r,r")
12255 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12256 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12257 (clobber (reg:CC FLAGS_REG))]
12258 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12260 sar{l}\t{%2, %k0|%k0, %2}
12261 sar{l}\t{%b2, %k0|%k0, %b2}"
12262 [(set_attr "type" "ishift")
12263 (set_attr "mode" "SI")])
12265 ;; This pattern can't accept a variable shift count, since shifts by
12266 ;; zero don't affect the flags. We assume that shifts by constant
12267 ;; zero are optimized away.
12268 (define_insn "*ashrsi3_one_bit_cmp"
12269 [(set (reg FLAGS_REG)
12271 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12272 (match_operand:QI 2 "const1_operand" ""))
12274 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12275 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12276 "(TARGET_SHIFT1 || optimize_size)
12277 && ix86_match_ccmode (insn, CCGOCmode)
12278 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12280 [(set_attr "type" "ishift")
12281 (set (attr "length")
12282 (if_then_else (match_operand:SI 0 "register_operand" "")
12284 (const_string "*")))])
12286 (define_insn "*ashrsi3_one_bit_cconly"
12287 [(set (reg FLAGS_REG)
12289 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12290 (match_operand:QI 2 "const1_operand" ""))
12292 (clobber (match_scratch:SI 0 "=r"))]
12293 "(TARGET_SHIFT1 || optimize_size)
12294 && ix86_match_ccmode (insn, CCGOCmode)
12295 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12297 [(set_attr "type" "ishift")
12298 (set_attr "length" "2")])
12300 (define_insn "*ashrsi3_one_bit_cmp_zext"
12301 [(set (reg FLAGS_REG)
12303 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12304 (match_operand:QI 2 "const1_operand" ""))
12306 (set (match_operand:DI 0 "register_operand" "=r")
12307 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12309 && (TARGET_SHIFT1 || optimize_size)
12310 && ix86_match_ccmode (insn, CCmode)
12311 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12313 [(set_attr "type" "ishift")
12314 (set_attr "length" "2")])
12316 ;; This pattern can't accept a variable shift count, since shifts by
12317 ;; zero don't affect the flags. We assume that shifts by constant
12318 ;; zero are optimized away.
12319 (define_insn "*ashrsi3_cmp"
12320 [(set (reg FLAGS_REG)
12322 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12323 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12325 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12326 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12327 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12328 && ix86_match_ccmode (insn, CCGOCmode)
12329 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12330 "sar{l}\t{%2, %0|%0, %2}"
12331 [(set_attr "type" "ishift")
12332 (set_attr "mode" "SI")])
12334 (define_insn "*ashrsi3_cconly"
12335 [(set (reg FLAGS_REG)
12337 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12338 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12340 (clobber (match_scratch:SI 0 "=r"))]
12341 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12342 && ix86_match_ccmode (insn, CCGOCmode)
12343 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12344 "sar{l}\t{%2, %0|%0, %2}"
12345 [(set_attr "type" "ishift")
12346 (set_attr "mode" "SI")])
12348 (define_insn "*ashrsi3_cmp_zext"
12349 [(set (reg FLAGS_REG)
12351 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12352 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12354 (set (match_operand:DI 0 "register_operand" "=r")
12355 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12357 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12358 && ix86_match_ccmode (insn, CCGOCmode)
12359 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12360 "sar{l}\t{%2, %k0|%k0, %2}"
12361 [(set_attr "type" "ishift")
12362 (set_attr "mode" "SI")])
12364 (define_expand "ashrhi3"
12365 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12366 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12367 (match_operand:QI 2 "nonmemory_operand" "")))
12368 (clobber (reg:CC FLAGS_REG))]
12369 "TARGET_HIMODE_MATH"
12370 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12372 (define_insn "*ashrhi3_1_one_bit"
12373 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12374 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12375 (match_operand:QI 2 "const1_operand" "")))
12376 (clobber (reg:CC FLAGS_REG))]
12377 "(TARGET_SHIFT1 || optimize_size)
12378 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12380 [(set_attr "type" "ishift")
12381 (set (attr "length")
12382 (if_then_else (match_operand 0 "register_operand" "")
12384 (const_string "*")))])
12386 (define_insn "*ashrhi3_1"
12387 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12388 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12389 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12390 (clobber (reg:CC FLAGS_REG))]
12391 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12393 sar{w}\t{%2, %0|%0, %2}
12394 sar{w}\t{%b2, %0|%0, %b2}"
12395 [(set_attr "type" "ishift")
12396 (set_attr "mode" "HI")])
12398 ;; This pattern can't accept a variable shift count, since shifts by
12399 ;; zero don't affect the flags. We assume that shifts by constant
12400 ;; zero are optimized away.
12401 (define_insn "*ashrhi3_one_bit_cmp"
12402 [(set (reg FLAGS_REG)
12404 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12405 (match_operand:QI 2 "const1_operand" ""))
12407 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12408 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12409 "(TARGET_SHIFT1 || optimize_size)
12410 && ix86_match_ccmode (insn, CCGOCmode)
12411 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12413 [(set_attr "type" "ishift")
12414 (set (attr "length")
12415 (if_then_else (match_operand 0 "register_operand" "")
12417 (const_string "*")))])
12419 (define_insn "*ashrhi3_one_bit_cconly"
12420 [(set (reg FLAGS_REG)
12422 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12423 (match_operand:QI 2 "const1_operand" ""))
12425 (clobber (match_scratch:HI 0 "=r"))]
12426 "(TARGET_SHIFT1 || optimize_size)
12427 && ix86_match_ccmode (insn, CCGOCmode)
12428 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12430 [(set_attr "type" "ishift")
12431 (set_attr "length" "2")])
12433 ;; This pattern can't accept a variable shift count, since shifts by
12434 ;; zero don't affect the flags. We assume that shifts by constant
12435 ;; zero are optimized away.
12436 (define_insn "*ashrhi3_cmp"
12437 [(set (reg FLAGS_REG)
12439 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12440 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12442 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12443 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12444 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12445 && ix86_match_ccmode (insn, CCGOCmode)
12446 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12447 "sar{w}\t{%2, %0|%0, %2}"
12448 [(set_attr "type" "ishift")
12449 (set_attr "mode" "HI")])
12451 (define_insn "*ashrhi3_cconly"
12452 [(set (reg FLAGS_REG)
12454 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12455 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12457 (clobber (match_scratch:HI 0 "=r"))]
12458 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12459 && ix86_match_ccmode (insn, CCGOCmode)
12460 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12461 "sar{w}\t{%2, %0|%0, %2}"
12462 [(set_attr "type" "ishift")
12463 (set_attr "mode" "HI")])
12465 (define_expand "ashrqi3"
12466 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12467 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12468 (match_operand:QI 2 "nonmemory_operand" "")))
12469 (clobber (reg:CC FLAGS_REG))]
12470 "TARGET_QIMODE_MATH"
12471 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12473 (define_insn "*ashrqi3_1_one_bit"
12474 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12475 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12476 (match_operand:QI 2 "const1_operand" "")))
12477 (clobber (reg:CC FLAGS_REG))]
12478 "(TARGET_SHIFT1 || optimize_size)
12479 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12481 [(set_attr "type" "ishift")
12482 (set (attr "length")
12483 (if_then_else (match_operand 0 "register_operand" "")
12485 (const_string "*")))])
12487 (define_insn "*ashrqi3_1_one_bit_slp"
12488 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12489 (ashiftrt:QI (match_dup 0)
12490 (match_operand:QI 1 "const1_operand" "")))
12491 (clobber (reg:CC FLAGS_REG))]
12492 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12493 && (TARGET_SHIFT1 || optimize_size)
12494 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12496 [(set_attr "type" "ishift1")
12497 (set (attr "length")
12498 (if_then_else (match_operand 0 "register_operand" "")
12500 (const_string "*")))])
12502 (define_insn "*ashrqi3_1"
12503 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12504 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12505 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12506 (clobber (reg:CC FLAGS_REG))]
12507 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12509 sar{b}\t{%2, %0|%0, %2}
12510 sar{b}\t{%b2, %0|%0, %b2}"
12511 [(set_attr "type" "ishift")
12512 (set_attr "mode" "QI")])
12514 (define_insn "*ashrqi3_1_slp"
12515 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12516 (ashiftrt:QI (match_dup 0)
12517 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12518 (clobber (reg:CC FLAGS_REG))]
12519 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12520 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12522 sar{b}\t{%1, %0|%0, %1}
12523 sar{b}\t{%b1, %0|%0, %b1}"
12524 [(set_attr "type" "ishift1")
12525 (set_attr "mode" "QI")])
12527 ;; This pattern can't accept a variable shift count, since shifts by
12528 ;; zero don't affect the flags. We assume that shifts by constant
12529 ;; zero are optimized away.
12530 (define_insn "*ashrqi3_one_bit_cmp"
12531 [(set (reg FLAGS_REG)
12533 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12534 (match_operand:QI 2 "const1_operand" "I"))
12536 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12537 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12538 "(TARGET_SHIFT1 || optimize_size)
12539 && ix86_match_ccmode (insn, CCGOCmode)
12540 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12542 [(set_attr "type" "ishift")
12543 (set (attr "length")
12544 (if_then_else (match_operand 0 "register_operand" "")
12546 (const_string "*")))])
12548 (define_insn "*ashrqi3_one_bit_cconly"
12549 [(set (reg FLAGS_REG)
12551 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12552 (match_operand:QI 2 "const1_operand" "I"))
12554 (clobber (match_scratch:QI 0 "=q"))]
12555 "(TARGET_SHIFT1 || optimize_size)
12556 && ix86_match_ccmode (insn, CCGOCmode)
12557 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12559 [(set_attr "type" "ishift")
12560 (set_attr "length" "2")])
12562 ;; This pattern can't accept a variable shift count, since shifts by
12563 ;; zero don't affect the flags. We assume that shifts by constant
12564 ;; zero are optimized away.
12565 (define_insn "*ashrqi3_cmp"
12566 [(set (reg FLAGS_REG)
12568 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12569 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12571 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12572 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12573 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12574 && ix86_match_ccmode (insn, CCGOCmode)
12575 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12576 "sar{b}\t{%2, %0|%0, %2}"
12577 [(set_attr "type" "ishift")
12578 (set_attr "mode" "QI")])
12580 (define_insn "*ashrqi3_cconly"
12581 [(set (reg FLAGS_REG)
12583 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12584 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12586 (clobber (match_scratch:QI 0 "=q"))]
12587 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12588 && ix86_match_ccmode (insn, CCGOCmode)
12589 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12590 "sar{b}\t{%2, %0|%0, %2}"
12591 [(set_attr "type" "ishift")
12592 (set_attr "mode" "QI")])
12595 ;; Logical shift instructions
12597 ;; See comment above `ashldi3' about how this works.
12599 (define_expand "lshrti3"
12600 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12601 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12602 (match_operand:QI 2 "nonmemory_operand" "")))
12603 (clobber (reg:CC FLAGS_REG))])]
12606 if (! immediate_operand (operands[2], QImode))
12608 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12611 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12615 (define_insn "lshrti3_1"
12616 [(set (match_operand:TI 0 "register_operand" "=r")
12617 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12618 (match_operand:QI 2 "register_operand" "c")))
12619 (clobber (match_scratch:DI 3 "=&r"))
12620 (clobber (reg:CC FLAGS_REG))]
12623 [(set_attr "type" "multi")])
12625 ;; This pattern must be defined before *lshrti3_2 to prevent
12626 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12628 (define_insn "sse2_lshrti3"
12629 [(set (match_operand:TI 0 "register_operand" "=x")
12630 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12631 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12634 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12635 return "psrldq\t{%2, %0|%0, %2}";
12637 [(set_attr "type" "sseishft")
12638 (set_attr "prefix_data16" "1")
12639 (set_attr "mode" "TI")])
12641 (define_insn "*lshrti3_2"
12642 [(set (match_operand:TI 0 "register_operand" "=r")
12643 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12644 (match_operand:QI 2 "immediate_operand" "O")))
12645 (clobber (reg:CC FLAGS_REG))]
12648 [(set_attr "type" "multi")])
12651 [(set (match_operand:TI 0 "register_operand" "")
12652 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12653 (match_operand:QI 2 "register_operand" "")))
12654 (clobber (match_scratch:DI 3 ""))
12655 (clobber (reg:CC FLAGS_REG))]
12656 "TARGET_64BIT && reload_completed"
12658 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12661 [(set (match_operand:TI 0 "register_operand" "")
12662 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12663 (match_operand:QI 2 "immediate_operand" "")))
12664 (clobber (reg:CC FLAGS_REG))]
12665 "TARGET_64BIT && reload_completed"
12667 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12669 (define_expand "lshrdi3"
12670 [(set (match_operand:DI 0 "shiftdi_operand" "")
12671 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12672 (match_operand:QI 2 "nonmemory_operand" "")))]
12674 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12676 (define_insn "*lshrdi3_1_one_bit_rex64"
12677 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12678 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12679 (match_operand:QI 2 "const1_operand" "")))
12680 (clobber (reg:CC FLAGS_REG))]
12682 && (TARGET_SHIFT1 || optimize_size)
12683 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12685 [(set_attr "type" "ishift")
12686 (set (attr "length")
12687 (if_then_else (match_operand:DI 0 "register_operand" "")
12689 (const_string "*")))])
12691 (define_insn "*lshrdi3_1_rex64"
12692 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12693 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12694 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12695 (clobber (reg:CC FLAGS_REG))]
12696 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12698 shr{q}\t{%2, %0|%0, %2}
12699 shr{q}\t{%b2, %0|%0, %b2}"
12700 [(set_attr "type" "ishift")
12701 (set_attr "mode" "DI")])
12703 ;; This pattern can't accept a variable shift count, since shifts by
12704 ;; zero don't affect the flags. We assume that shifts by constant
12705 ;; zero are optimized away.
12706 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12707 [(set (reg FLAGS_REG)
12709 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12710 (match_operand:QI 2 "const1_operand" ""))
12712 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12713 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12715 && (TARGET_SHIFT1 || optimize_size)
12716 && ix86_match_ccmode (insn, CCGOCmode)
12717 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12719 [(set_attr "type" "ishift")
12720 (set (attr "length")
12721 (if_then_else (match_operand:DI 0 "register_operand" "")
12723 (const_string "*")))])
12725 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12726 [(set (reg FLAGS_REG)
12728 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12729 (match_operand:QI 2 "const1_operand" ""))
12731 (clobber (match_scratch:DI 0 "=r"))]
12733 && (TARGET_SHIFT1 || optimize_size)
12734 && ix86_match_ccmode (insn, CCGOCmode)
12735 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12737 [(set_attr "type" "ishift")
12738 (set_attr "length" "2")])
12740 ;; This pattern can't accept a variable shift count, since shifts by
12741 ;; zero don't affect the flags. We assume that shifts by constant
12742 ;; zero are optimized away.
12743 (define_insn "*lshrdi3_cmp_rex64"
12744 [(set (reg FLAGS_REG)
12746 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12747 (match_operand:QI 2 "const_int_operand" "e"))
12749 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12750 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12752 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12753 && ix86_match_ccmode (insn, CCGOCmode)
12754 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12755 "shr{q}\t{%2, %0|%0, %2}"
12756 [(set_attr "type" "ishift")
12757 (set_attr "mode" "DI")])
12759 (define_insn "*lshrdi3_cconly_rex64"
12760 [(set (reg FLAGS_REG)
12762 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12763 (match_operand:QI 2 "const_int_operand" "e"))
12765 (clobber (match_scratch:DI 0 "=r"))]
12767 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12768 && ix86_match_ccmode (insn, CCGOCmode)
12769 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12770 "shr{q}\t{%2, %0|%0, %2}"
12771 [(set_attr "type" "ishift")
12772 (set_attr "mode" "DI")])
12774 (define_insn "*lshrdi3_1"
12775 [(set (match_operand:DI 0 "register_operand" "=r")
12776 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12777 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12778 (clobber (reg:CC FLAGS_REG))]
12781 [(set_attr "type" "multi")])
12783 ;; By default we don't ask for a scratch register, because when DImode
12784 ;; values are manipulated, registers are already at a premium. But if
12785 ;; we have one handy, we won't turn it away.
12787 [(match_scratch:SI 3 "r")
12788 (parallel [(set (match_operand:DI 0 "register_operand" "")
12789 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12790 (match_operand:QI 2 "nonmemory_operand" "")))
12791 (clobber (reg:CC FLAGS_REG))])
12793 "!TARGET_64BIT && TARGET_CMOVE"
12795 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12798 [(set (match_operand:DI 0 "register_operand" "")
12799 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12800 (match_operand:QI 2 "nonmemory_operand" "")))
12801 (clobber (reg:CC FLAGS_REG))]
12802 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12803 ? epilogue_completed : reload_completed)"
12805 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12807 (define_expand "lshrsi3"
12808 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12809 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12810 (match_operand:QI 2 "nonmemory_operand" "")))
12811 (clobber (reg:CC FLAGS_REG))]
12813 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12815 (define_insn "*lshrsi3_1_one_bit"
12816 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12817 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12818 (match_operand:QI 2 "const1_operand" "")))
12819 (clobber (reg:CC FLAGS_REG))]
12820 "(TARGET_SHIFT1 || optimize_size)
12821 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12823 [(set_attr "type" "ishift")
12824 (set (attr "length")
12825 (if_then_else (match_operand:SI 0 "register_operand" "")
12827 (const_string "*")))])
12829 (define_insn "*lshrsi3_1_one_bit_zext"
12830 [(set (match_operand:DI 0 "register_operand" "=r")
12831 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12832 (match_operand:QI 2 "const1_operand" "")))
12833 (clobber (reg:CC FLAGS_REG))]
12835 && (TARGET_SHIFT1 || optimize_size)
12836 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12838 [(set_attr "type" "ishift")
12839 (set_attr "length" "2")])
12841 (define_insn "*lshrsi3_1"
12842 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12843 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12844 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12845 (clobber (reg:CC FLAGS_REG))]
12846 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12848 shr{l}\t{%2, %0|%0, %2}
12849 shr{l}\t{%b2, %0|%0, %b2}"
12850 [(set_attr "type" "ishift")
12851 (set_attr "mode" "SI")])
12853 (define_insn "*lshrsi3_1_zext"
12854 [(set (match_operand:DI 0 "register_operand" "=r,r")
12856 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12857 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12858 (clobber (reg:CC FLAGS_REG))]
12859 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12861 shr{l}\t{%2, %k0|%k0, %2}
12862 shr{l}\t{%b2, %k0|%k0, %b2}"
12863 [(set_attr "type" "ishift")
12864 (set_attr "mode" "SI")])
12866 ;; This pattern can't accept a variable shift count, since shifts by
12867 ;; zero don't affect the flags. We assume that shifts by constant
12868 ;; zero are optimized away.
12869 (define_insn "*lshrsi3_one_bit_cmp"
12870 [(set (reg FLAGS_REG)
12872 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12873 (match_operand:QI 2 "const1_operand" ""))
12875 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12876 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12877 "(TARGET_SHIFT1 || optimize_size)
12878 && ix86_match_ccmode (insn, CCGOCmode)
12879 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12881 [(set_attr "type" "ishift")
12882 (set (attr "length")
12883 (if_then_else (match_operand:SI 0 "register_operand" "")
12885 (const_string "*")))])
12887 (define_insn "*lshrsi3_one_bit_cconly"
12888 [(set (reg FLAGS_REG)
12890 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12891 (match_operand:QI 2 "const1_operand" ""))
12893 (clobber (match_scratch:SI 0 "=r"))]
12894 "(TARGET_SHIFT1 || optimize_size)
12895 && ix86_match_ccmode (insn, CCGOCmode)
12896 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12898 [(set_attr "type" "ishift")
12899 (set_attr "length" "2")])
12901 (define_insn "*lshrsi3_cmp_one_bit_zext"
12902 [(set (reg FLAGS_REG)
12904 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12905 (match_operand:QI 2 "const1_operand" ""))
12907 (set (match_operand:DI 0 "register_operand" "=r")
12908 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12910 && (TARGET_SHIFT1 || optimize_size)
12911 && ix86_match_ccmode (insn, CCGOCmode)
12912 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12914 [(set_attr "type" "ishift")
12915 (set_attr "length" "2")])
12917 ;; This pattern can't accept a variable shift count, since shifts by
12918 ;; zero don't affect the flags. We assume that shifts by constant
12919 ;; zero are optimized away.
12920 (define_insn "*lshrsi3_cmp"
12921 [(set (reg FLAGS_REG)
12923 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12924 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12926 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12927 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12928 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12929 && ix86_match_ccmode (insn, CCGOCmode)
12930 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12931 "shr{l}\t{%2, %0|%0, %2}"
12932 [(set_attr "type" "ishift")
12933 (set_attr "mode" "SI")])
12935 (define_insn "*lshrsi3_cconly"
12936 [(set (reg FLAGS_REG)
12938 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12939 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12941 (clobber (match_scratch:SI 0 "=r"))]
12942 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12943 && ix86_match_ccmode (insn, CCGOCmode)
12944 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12945 "shr{l}\t{%2, %0|%0, %2}"
12946 [(set_attr "type" "ishift")
12947 (set_attr "mode" "SI")])
12949 (define_insn "*lshrsi3_cmp_zext"
12950 [(set (reg FLAGS_REG)
12952 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12953 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12955 (set (match_operand:DI 0 "register_operand" "=r")
12956 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12958 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12959 && ix86_match_ccmode (insn, CCGOCmode)
12960 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12961 "shr{l}\t{%2, %k0|%k0, %2}"
12962 [(set_attr "type" "ishift")
12963 (set_attr "mode" "SI")])
12965 (define_expand "lshrhi3"
12966 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12967 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12968 (match_operand:QI 2 "nonmemory_operand" "")))
12969 (clobber (reg:CC FLAGS_REG))]
12970 "TARGET_HIMODE_MATH"
12971 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12973 (define_insn "*lshrhi3_1_one_bit"
12974 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12975 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12976 (match_operand:QI 2 "const1_operand" "")))
12977 (clobber (reg:CC FLAGS_REG))]
12978 "(TARGET_SHIFT1 || optimize_size)
12979 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12981 [(set_attr "type" "ishift")
12982 (set (attr "length")
12983 (if_then_else (match_operand 0 "register_operand" "")
12985 (const_string "*")))])
12987 (define_insn "*lshrhi3_1"
12988 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12989 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12990 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12991 (clobber (reg:CC FLAGS_REG))]
12992 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12994 shr{w}\t{%2, %0|%0, %2}
12995 shr{w}\t{%b2, %0|%0, %b2}"
12996 [(set_attr "type" "ishift")
12997 (set_attr "mode" "HI")])
12999 ;; This pattern can't accept a variable shift count, since shifts by
13000 ;; zero don't affect the flags. We assume that shifts by constant
13001 ;; zero are optimized away.
13002 (define_insn "*lshrhi3_one_bit_cmp"
13003 [(set (reg FLAGS_REG)
13005 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13006 (match_operand:QI 2 "const1_operand" ""))
13008 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13009 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13010 "(TARGET_SHIFT1 || optimize_size)
13011 && ix86_match_ccmode (insn, CCGOCmode)
13012 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13014 [(set_attr "type" "ishift")
13015 (set (attr "length")
13016 (if_then_else (match_operand:SI 0 "register_operand" "")
13018 (const_string "*")))])
13020 (define_insn "*lshrhi3_one_bit_cconly"
13021 [(set (reg FLAGS_REG)
13023 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13024 (match_operand:QI 2 "const1_operand" ""))
13026 (clobber (match_scratch:HI 0 "=r"))]
13027 "(TARGET_SHIFT1 || optimize_size)
13028 && ix86_match_ccmode (insn, CCGOCmode)
13029 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13031 [(set_attr "type" "ishift")
13032 (set_attr "length" "2")])
13034 ;; This pattern can't accept a variable shift count, since shifts by
13035 ;; zero don't affect the flags. We assume that shifts by constant
13036 ;; zero are optimized away.
13037 (define_insn "*lshrhi3_cmp"
13038 [(set (reg FLAGS_REG)
13040 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13041 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13043 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13044 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13045 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13046 && ix86_match_ccmode (insn, CCGOCmode)
13047 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13048 "shr{w}\t{%2, %0|%0, %2}"
13049 [(set_attr "type" "ishift")
13050 (set_attr "mode" "HI")])
13052 (define_insn "*lshrhi3_cconly"
13053 [(set (reg FLAGS_REG)
13055 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13056 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13058 (clobber (match_scratch:HI 0 "=r"))]
13059 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13060 && ix86_match_ccmode (insn, CCGOCmode)
13061 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13062 "shr{w}\t{%2, %0|%0, %2}"
13063 [(set_attr "type" "ishift")
13064 (set_attr "mode" "HI")])
13066 (define_expand "lshrqi3"
13067 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13068 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13069 (match_operand:QI 2 "nonmemory_operand" "")))
13070 (clobber (reg:CC FLAGS_REG))]
13071 "TARGET_QIMODE_MATH"
13072 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13074 (define_insn "*lshrqi3_1_one_bit"
13075 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13076 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13077 (match_operand:QI 2 "const1_operand" "")))
13078 (clobber (reg:CC FLAGS_REG))]
13079 "(TARGET_SHIFT1 || optimize_size)
13080 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13082 [(set_attr "type" "ishift")
13083 (set (attr "length")
13084 (if_then_else (match_operand 0 "register_operand" "")
13086 (const_string "*")))])
13088 (define_insn "*lshrqi3_1_one_bit_slp"
13089 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13090 (lshiftrt:QI (match_dup 0)
13091 (match_operand:QI 1 "const1_operand" "")))
13092 (clobber (reg:CC FLAGS_REG))]
13093 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13094 && (TARGET_SHIFT1 || optimize_size)"
13096 [(set_attr "type" "ishift1")
13097 (set (attr "length")
13098 (if_then_else (match_operand 0 "register_operand" "")
13100 (const_string "*")))])
13102 (define_insn "*lshrqi3_1"
13103 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13104 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13105 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13106 (clobber (reg:CC FLAGS_REG))]
13107 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13109 shr{b}\t{%2, %0|%0, %2}
13110 shr{b}\t{%b2, %0|%0, %b2}"
13111 [(set_attr "type" "ishift")
13112 (set_attr "mode" "QI")])
13114 (define_insn "*lshrqi3_1_slp"
13115 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13116 (lshiftrt:QI (match_dup 0)
13117 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13118 (clobber (reg:CC FLAGS_REG))]
13119 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13120 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13122 shr{b}\t{%1, %0|%0, %1}
13123 shr{b}\t{%b1, %0|%0, %b1}"
13124 [(set_attr "type" "ishift1")
13125 (set_attr "mode" "QI")])
13127 ;; This pattern can't accept a variable shift count, since shifts by
13128 ;; zero don't affect the flags. We assume that shifts by constant
13129 ;; zero are optimized away.
13130 (define_insn "*lshrqi2_one_bit_cmp"
13131 [(set (reg FLAGS_REG)
13133 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13134 (match_operand:QI 2 "const1_operand" ""))
13136 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13137 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13138 "(TARGET_SHIFT1 || optimize_size)
13139 && ix86_match_ccmode (insn, CCGOCmode)
13140 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13142 [(set_attr "type" "ishift")
13143 (set (attr "length")
13144 (if_then_else (match_operand:SI 0 "register_operand" "")
13146 (const_string "*")))])
13148 (define_insn "*lshrqi2_one_bit_cconly"
13149 [(set (reg FLAGS_REG)
13151 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13152 (match_operand:QI 2 "const1_operand" ""))
13154 (clobber (match_scratch:QI 0 "=q"))]
13155 "(TARGET_SHIFT1 || optimize_size)
13156 && ix86_match_ccmode (insn, CCGOCmode)
13157 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13159 [(set_attr "type" "ishift")
13160 (set_attr "length" "2")])
13162 ;; This pattern can't accept a variable shift count, since shifts by
13163 ;; zero don't affect the flags. We assume that shifts by constant
13164 ;; zero are optimized away.
13165 (define_insn "*lshrqi2_cmp"
13166 [(set (reg FLAGS_REG)
13168 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13169 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13171 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13172 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13173 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13174 && ix86_match_ccmode (insn, CCGOCmode)
13175 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13176 "shr{b}\t{%2, %0|%0, %2}"
13177 [(set_attr "type" "ishift")
13178 (set_attr "mode" "QI")])
13180 (define_insn "*lshrqi2_cconly"
13181 [(set (reg FLAGS_REG)
13183 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13184 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13186 (clobber (match_scratch:QI 0 "=q"))]
13187 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13188 && ix86_match_ccmode (insn, CCGOCmode)
13189 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13190 "shr{b}\t{%2, %0|%0, %2}"
13191 [(set_attr "type" "ishift")
13192 (set_attr "mode" "QI")])
13194 ;; Rotate instructions
13196 (define_expand "rotldi3"
13197 [(set (match_operand:DI 0 "shiftdi_operand" "")
13198 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13199 (match_operand:QI 2 "nonmemory_operand" "")))
13200 (clobber (reg:CC FLAGS_REG))]
13205 ix86_expand_binary_operator (ROTATE, DImode, operands);
13208 if (!const_1_to_31_operand (operands[2], VOIDmode))
13210 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13214 ;; Implement rotation using two double-precision shift instructions
13215 ;; and a scratch register.
13216 (define_insn_and_split "ix86_rotldi3"
13217 [(set (match_operand:DI 0 "register_operand" "=r")
13218 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13219 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13220 (clobber (reg:CC FLAGS_REG))
13221 (clobber (match_scratch:SI 3 "=&r"))]
13224 "&& reload_completed"
13225 [(set (match_dup 3) (match_dup 4))
13227 [(set (match_dup 4)
13228 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13229 (lshiftrt:SI (match_dup 5)
13230 (minus:QI (const_int 32) (match_dup 2)))))
13231 (clobber (reg:CC FLAGS_REG))])
13233 [(set (match_dup 5)
13234 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13235 (lshiftrt:SI (match_dup 3)
13236 (minus:QI (const_int 32) (match_dup 2)))))
13237 (clobber (reg:CC FLAGS_REG))])]
13238 "split_di (operands, 1, operands + 4, operands + 5);")
13240 (define_insn "*rotlsi3_1_one_bit_rex64"
13241 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13242 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13243 (match_operand:QI 2 "const1_operand" "")))
13244 (clobber (reg:CC FLAGS_REG))]
13246 && (TARGET_SHIFT1 || optimize_size)
13247 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13249 [(set_attr "type" "rotate")
13250 (set (attr "length")
13251 (if_then_else (match_operand:DI 0 "register_operand" "")
13253 (const_string "*")))])
13255 (define_insn "*rotldi3_1_rex64"
13256 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13257 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13258 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13259 (clobber (reg:CC FLAGS_REG))]
13260 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13262 rol{q}\t{%2, %0|%0, %2}
13263 rol{q}\t{%b2, %0|%0, %b2}"
13264 [(set_attr "type" "rotate")
13265 (set_attr "mode" "DI")])
13267 (define_expand "rotlsi3"
13268 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13269 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13270 (match_operand:QI 2 "nonmemory_operand" "")))
13271 (clobber (reg:CC FLAGS_REG))]
13273 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13275 (define_insn "*rotlsi3_1_one_bit"
13276 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13277 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13278 (match_operand:QI 2 "const1_operand" "")))
13279 (clobber (reg:CC FLAGS_REG))]
13280 "(TARGET_SHIFT1 || optimize_size)
13281 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13283 [(set_attr "type" "rotate")
13284 (set (attr "length")
13285 (if_then_else (match_operand:SI 0 "register_operand" "")
13287 (const_string "*")))])
13289 (define_insn "*rotlsi3_1_one_bit_zext"
13290 [(set (match_operand:DI 0 "register_operand" "=r")
13292 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13293 (match_operand:QI 2 "const1_operand" ""))))
13294 (clobber (reg:CC FLAGS_REG))]
13296 && (TARGET_SHIFT1 || optimize_size)
13297 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13299 [(set_attr "type" "rotate")
13300 (set_attr "length" "2")])
13302 (define_insn "*rotlsi3_1"
13303 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13304 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13305 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13306 (clobber (reg:CC FLAGS_REG))]
13307 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13309 rol{l}\t{%2, %0|%0, %2}
13310 rol{l}\t{%b2, %0|%0, %b2}"
13311 [(set_attr "type" "rotate")
13312 (set_attr "mode" "SI")])
13314 (define_insn "*rotlsi3_1_zext"
13315 [(set (match_operand:DI 0 "register_operand" "=r,r")
13317 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13318 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13319 (clobber (reg:CC FLAGS_REG))]
13320 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13322 rol{l}\t{%2, %k0|%k0, %2}
13323 rol{l}\t{%b2, %k0|%k0, %b2}"
13324 [(set_attr "type" "rotate")
13325 (set_attr "mode" "SI")])
13327 (define_expand "rotlhi3"
13328 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13329 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13330 (match_operand:QI 2 "nonmemory_operand" "")))
13331 (clobber (reg:CC FLAGS_REG))]
13332 "TARGET_HIMODE_MATH"
13333 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13335 (define_insn "*rotlhi3_1_one_bit"
13336 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13337 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13338 (match_operand:QI 2 "const1_operand" "")))
13339 (clobber (reg:CC FLAGS_REG))]
13340 "(TARGET_SHIFT1 || optimize_size)
13341 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13343 [(set_attr "type" "rotate")
13344 (set (attr "length")
13345 (if_then_else (match_operand 0 "register_operand" "")
13347 (const_string "*")))])
13349 (define_insn "*rotlhi3_1"
13350 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13351 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13352 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13353 (clobber (reg:CC FLAGS_REG))]
13354 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13356 rol{w}\t{%2, %0|%0, %2}
13357 rol{w}\t{%b2, %0|%0, %b2}"
13358 [(set_attr "type" "rotate")
13359 (set_attr "mode" "HI")])
13362 [(set (match_operand:HI 0 "register_operand" "")
13363 (rotate:HI (match_dup 0) (const_int 8)))
13364 (clobber (reg:CC FLAGS_REG))]
13366 [(parallel [(set (strict_low_part (match_dup 0))
13367 (bswap:HI (match_dup 0)))
13368 (clobber (reg:CC FLAGS_REG))])]
13371 (define_expand "rotlqi3"
13372 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13373 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13374 (match_operand:QI 2 "nonmemory_operand" "")))
13375 (clobber (reg:CC FLAGS_REG))]
13376 "TARGET_QIMODE_MATH"
13377 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13379 (define_insn "*rotlqi3_1_one_bit_slp"
13380 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13381 (rotate:QI (match_dup 0)
13382 (match_operand:QI 1 "const1_operand" "")))
13383 (clobber (reg:CC FLAGS_REG))]
13384 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13385 && (TARGET_SHIFT1 || optimize_size)"
13387 [(set_attr "type" "rotate1")
13388 (set (attr "length")
13389 (if_then_else (match_operand 0 "register_operand" "")
13391 (const_string "*")))])
13393 (define_insn "*rotlqi3_1_one_bit"
13394 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13395 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13396 (match_operand:QI 2 "const1_operand" "")))
13397 (clobber (reg:CC FLAGS_REG))]
13398 "(TARGET_SHIFT1 || optimize_size)
13399 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13401 [(set_attr "type" "rotate")
13402 (set (attr "length")
13403 (if_then_else (match_operand 0 "register_operand" "")
13405 (const_string "*")))])
13407 (define_insn "*rotlqi3_1_slp"
13408 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13409 (rotate:QI (match_dup 0)
13410 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13411 (clobber (reg:CC FLAGS_REG))]
13412 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13413 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13415 rol{b}\t{%1, %0|%0, %1}
13416 rol{b}\t{%b1, %0|%0, %b1}"
13417 [(set_attr "type" "rotate1")
13418 (set_attr "mode" "QI")])
13420 (define_insn "*rotlqi3_1"
13421 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13422 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13423 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13424 (clobber (reg:CC FLAGS_REG))]
13425 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13427 rol{b}\t{%2, %0|%0, %2}
13428 rol{b}\t{%b2, %0|%0, %b2}"
13429 [(set_attr "type" "rotate")
13430 (set_attr "mode" "QI")])
13432 (define_expand "rotrdi3"
13433 [(set (match_operand:DI 0 "shiftdi_operand" "")
13434 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13435 (match_operand:QI 2 "nonmemory_operand" "")))
13436 (clobber (reg:CC FLAGS_REG))]
13441 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13444 if (!const_1_to_31_operand (operands[2], VOIDmode))
13446 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13450 ;; Implement rotation using two double-precision shift instructions
13451 ;; and a scratch register.
13452 (define_insn_and_split "ix86_rotrdi3"
13453 [(set (match_operand:DI 0 "register_operand" "=r")
13454 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13455 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13456 (clobber (reg:CC FLAGS_REG))
13457 (clobber (match_scratch:SI 3 "=&r"))]
13460 "&& reload_completed"
13461 [(set (match_dup 3) (match_dup 4))
13463 [(set (match_dup 4)
13464 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13465 (ashift:SI (match_dup 5)
13466 (minus:QI (const_int 32) (match_dup 2)))))
13467 (clobber (reg:CC FLAGS_REG))])
13469 [(set (match_dup 5)
13470 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13471 (ashift:SI (match_dup 3)
13472 (minus:QI (const_int 32) (match_dup 2)))))
13473 (clobber (reg:CC FLAGS_REG))])]
13474 "split_di (operands, 1, operands + 4, operands + 5);")
13476 (define_insn "*rotrdi3_1_one_bit_rex64"
13477 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13478 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13479 (match_operand:QI 2 "const1_operand" "")))
13480 (clobber (reg:CC FLAGS_REG))]
13482 && (TARGET_SHIFT1 || optimize_size)
13483 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13485 [(set_attr "type" "rotate")
13486 (set (attr "length")
13487 (if_then_else (match_operand:DI 0 "register_operand" "")
13489 (const_string "*")))])
13491 (define_insn "*rotrdi3_1_rex64"
13492 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13493 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13494 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13495 (clobber (reg:CC FLAGS_REG))]
13496 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13498 ror{q}\t{%2, %0|%0, %2}
13499 ror{q}\t{%b2, %0|%0, %b2}"
13500 [(set_attr "type" "rotate")
13501 (set_attr "mode" "DI")])
13503 (define_expand "rotrsi3"
13504 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13505 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13506 (match_operand:QI 2 "nonmemory_operand" "")))
13507 (clobber (reg:CC FLAGS_REG))]
13509 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13511 (define_insn "*rotrsi3_1_one_bit"
13512 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13513 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13514 (match_operand:QI 2 "const1_operand" "")))
13515 (clobber (reg:CC FLAGS_REG))]
13516 "(TARGET_SHIFT1 || optimize_size)
13517 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13519 [(set_attr "type" "rotate")
13520 (set (attr "length")
13521 (if_then_else (match_operand:SI 0 "register_operand" "")
13523 (const_string "*")))])
13525 (define_insn "*rotrsi3_1_one_bit_zext"
13526 [(set (match_operand:DI 0 "register_operand" "=r")
13528 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13529 (match_operand:QI 2 "const1_operand" ""))))
13530 (clobber (reg:CC FLAGS_REG))]
13532 && (TARGET_SHIFT1 || optimize_size)
13533 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13535 [(set_attr "type" "rotate")
13536 (set (attr "length")
13537 (if_then_else (match_operand:SI 0 "register_operand" "")
13539 (const_string "*")))])
13541 (define_insn "*rotrsi3_1"
13542 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13543 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13544 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13545 (clobber (reg:CC FLAGS_REG))]
13546 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13548 ror{l}\t{%2, %0|%0, %2}
13549 ror{l}\t{%b2, %0|%0, %b2}"
13550 [(set_attr "type" "rotate")
13551 (set_attr "mode" "SI")])
13553 (define_insn "*rotrsi3_1_zext"
13554 [(set (match_operand:DI 0 "register_operand" "=r,r")
13556 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13557 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13558 (clobber (reg:CC FLAGS_REG))]
13559 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13561 ror{l}\t{%2, %k0|%k0, %2}
13562 ror{l}\t{%b2, %k0|%k0, %b2}"
13563 [(set_attr "type" "rotate")
13564 (set_attr "mode" "SI")])
13566 (define_expand "rotrhi3"
13567 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13568 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13569 (match_operand:QI 2 "nonmemory_operand" "")))
13570 (clobber (reg:CC FLAGS_REG))]
13571 "TARGET_HIMODE_MATH"
13572 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13574 (define_insn "*rotrhi3_one_bit"
13575 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13576 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13577 (match_operand:QI 2 "const1_operand" "")))
13578 (clobber (reg:CC FLAGS_REG))]
13579 "(TARGET_SHIFT1 || optimize_size)
13580 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13582 [(set_attr "type" "rotate")
13583 (set (attr "length")
13584 (if_then_else (match_operand 0 "register_operand" "")
13586 (const_string "*")))])
13588 (define_insn "*rotrhi3_1"
13589 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13590 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13591 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13592 (clobber (reg:CC FLAGS_REG))]
13593 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13595 ror{w}\t{%2, %0|%0, %2}
13596 ror{w}\t{%b2, %0|%0, %b2}"
13597 [(set_attr "type" "rotate")
13598 (set_attr "mode" "HI")])
13601 [(set (match_operand:HI 0 "register_operand" "")
13602 (rotatert:HI (match_dup 0) (const_int 8)))
13603 (clobber (reg:CC FLAGS_REG))]
13605 [(parallel [(set (strict_low_part (match_dup 0))
13606 (bswap:HI (match_dup 0)))
13607 (clobber (reg:CC FLAGS_REG))])]
13610 (define_expand "rotrqi3"
13611 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13612 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13613 (match_operand:QI 2 "nonmemory_operand" "")))
13614 (clobber (reg:CC FLAGS_REG))]
13615 "TARGET_QIMODE_MATH"
13616 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13618 (define_insn "*rotrqi3_1_one_bit"
13619 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13620 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13621 (match_operand:QI 2 "const1_operand" "")))
13622 (clobber (reg:CC FLAGS_REG))]
13623 "(TARGET_SHIFT1 || optimize_size)
13624 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13626 [(set_attr "type" "rotate")
13627 (set (attr "length")
13628 (if_then_else (match_operand 0 "register_operand" "")
13630 (const_string "*")))])
13632 (define_insn "*rotrqi3_1_one_bit_slp"
13633 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13634 (rotatert:QI (match_dup 0)
13635 (match_operand:QI 1 "const1_operand" "")))
13636 (clobber (reg:CC FLAGS_REG))]
13637 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13638 && (TARGET_SHIFT1 || optimize_size)"
13640 [(set_attr "type" "rotate1")
13641 (set (attr "length")
13642 (if_then_else (match_operand 0 "register_operand" "")
13644 (const_string "*")))])
13646 (define_insn "*rotrqi3_1"
13647 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13648 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13649 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13650 (clobber (reg:CC FLAGS_REG))]
13651 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13653 ror{b}\t{%2, %0|%0, %2}
13654 ror{b}\t{%b2, %0|%0, %b2}"
13655 [(set_attr "type" "rotate")
13656 (set_attr "mode" "QI")])
13658 (define_insn "*rotrqi3_1_slp"
13659 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13660 (rotatert:QI (match_dup 0)
13661 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13662 (clobber (reg:CC FLAGS_REG))]
13663 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13664 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13666 ror{b}\t{%1, %0|%0, %1}
13667 ror{b}\t{%b1, %0|%0, %b1}"
13668 [(set_attr "type" "rotate1")
13669 (set_attr "mode" "QI")])
13671 ;; Bit set / bit test instructions
13673 (define_expand "extv"
13674 [(set (match_operand:SI 0 "register_operand" "")
13675 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13676 (match_operand:SI 2 "const8_operand" "")
13677 (match_operand:SI 3 "const8_operand" "")))]
13680 /* Handle extractions from %ah et al. */
13681 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13684 /* From mips.md: extract_bit_field doesn't verify that our source
13685 matches the predicate, so check it again here. */
13686 if (! ext_register_operand (operands[1], VOIDmode))
13690 (define_expand "extzv"
13691 [(set (match_operand:SI 0 "register_operand" "")
13692 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13693 (match_operand:SI 2 "const8_operand" "")
13694 (match_operand:SI 3 "const8_operand" "")))]
13697 /* Handle extractions from %ah et al. */
13698 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13701 /* From mips.md: extract_bit_field doesn't verify that our source
13702 matches the predicate, so check it again here. */
13703 if (! ext_register_operand (operands[1], VOIDmode))
13707 (define_expand "insv"
13708 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13709 (match_operand 1 "const8_operand" "")
13710 (match_operand 2 "const8_operand" ""))
13711 (match_operand 3 "register_operand" ""))]
13714 /* Handle insertions to %ah et al. */
13715 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13718 /* From mips.md: insert_bit_field doesn't verify that our source
13719 matches the predicate, so check it again here. */
13720 if (! ext_register_operand (operands[0], VOIDmode))
13724 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13726 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13731 ;; %%% bts, btr, btc, bt.
13732 ;; In general these instructions are *slow* when applied to memory,
13733 ;; since they enforce atomic operation. When applied to registers,
13734 ;; it depends on the cpu implementation. They're never faster than
13735 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13736 ;; no point. But in 64-bit, we can't hold the relevant immediates
13737 ;; within the instruction itself, so operating on bits in the high
13738 ;; 32-bits of a register becomes easier.
13740 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13741 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13742 ;; negdf respectively, so they can never be disabled entirely.
13744 (define_insn "*btsq"
13745 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13747 (match_operand:DI 1 "const_0_to_63_operand" ""))
13749 (clobber (reg:CC FLAGS_REG))]
13750 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13752 [(set_attr "type" "alu1")])
13754 (define_insn "*btrq"
13755 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13757 (match_operand:DI 1 "const_0_to_63_operand" ""))
13759 (clobber (reg:CC FLAGS_REG))]
13760 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13762 [(set_attr "type" "alu1")])
13764 (define_insn "*btcq"
13765 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13767 (match_operand:DI 1 "const_0_to_63_operand" ""))
13768 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13769 (clobber (reg:CC FLAGS_REG))]
13770 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13772 [(set_attr "type" "alu1")])
13774 ;; Allow Nocona to avoid these instructions if a register is available.
13777 [(match_scratch:DI 2 "r")
13778 (parallel [(set (zero_extract:DI
13779 (match_operand:DI 0 "register_operand" "")
13781 (match_operand:DI 1 "const_0_to_63_operand" ""))
13783 (clobber (reg:CC FLAGS_REG))])]
13784 "TARGET_64BIT && !TARGET_USE_BT"
13787 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13790 if (HOST_BITS_PER_WIDE_INT >= 64)
13791 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13792 else if (i < HOST_BITS_PER_WIDE_INT)
13793 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13795 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13797 op1 = immed_double_const (lo, hi, DImode);
13800 emit_move_insn (operands[2], op1);
13804 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13809 [(match_scratch:DI 2 "r")
13810 (parallel [(set (zero_extract:DI
13811 (match_operand:DI 0 "register_operand" "")
13813 (match_operand:DI 1 "const_0_to_63_operand" ""))
13815 (clobber (reg:CC FLAGS_REG))])]
13816 "TARGET_64BIT && !TARGET_USE_BT"
13819 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13822 if (HOST_BITS_PER_WIDE_INT >= 64)
13823 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13824 else if (i < HOST_BITS_PER_WIDE_INT)
13825 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13827 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13829 op1 = immed_double_const (~lo, ~hi, DImode);
13832 emit_move_insn (operands[2], op1);
13836 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13841 [(match_scratch:DI 2 "r")
13842 (parallel [(set (zero_extract:DI
13843 (match_operand:DI 0 "register_operand" "")
13845 (match_operand:DI 1 "const_0_to_63_operand" ""))
13846 (not:DI (zero_extract:DI
13847 (match_dup 0) (const_int 1) (match_dup 1))))
13848 (clobber (reg:CC FLAGS_REG))])]
13849 "TARGET_64BIT && !TARGET_USE_BT"
13852 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13855 if (HOST_BITS_PER_WIDE_INT >= 64)
13856 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13857 else if (i < HOST_BITS_PER_WIDE_INT)
13858 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13860 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13862 op1 = immed_double_const (lo, hi, DImode);
13865 emit_move_insn (operands[2], op1);
13869 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13873 ;; Store-flag instructions.
13875 ;; For all sCOND expanders, also expand the compare or test insn that
13876 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13878 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13879 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13880 ;; way, which can later delete the movzx if only QImode is needed.
13882 (define_expand "seq"
13883 [(set (match_operand:QI 0 "register_operand" "")
13884 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13886 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13888 (define_expand "sne"
13889 [(set (match_operand:QI 0 "register_operand" "")
13890 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13892 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13894 (define_expand "sgt"
13895 [(set (match_operand:QI 0 "register_operand" "")
13896 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13898 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13900 (define_expand "sgtu"
13901 [(set (match_operand:QI 0 "register_operand" "")
13902 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13904 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13906 (define_expand "slt"
13907 [(set (match_operand:QI 0 "register_operand" "")
13908 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13910 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13912 (define_expand "sltu"
13913 [(set (match_operand:QI 0 "register_operand" "")
13914 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13916 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13918 (define_expand "sge"
13919 [(set (match_operand:QI 0 "register_operand" "")
13920 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13922 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13924 (define_expand "sgeu"
13925 [(set (match_operand:QI 0 "register_operand" "")
13926 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13928 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13930 (define_expand "sle"
13931 [(set (match_operand:QI 0 "register_operand" "")
13932 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13934 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13936 (define_expand "sleu"
13937 [(set (match_operand:QI 0 "register_operand" "")
13938 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13940 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13942 (define_expand "sunordered"
13943 [(set (match_operand:QI 0 "register_operand" "")
13944 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13945 "TARGET_80387 || TARGET_SSE"
13946 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13948 (define_expand "sordered"
13949 [(set (match_operand:QI 0 "register_operand" "")
13950 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13952 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13954 (define_expand "suneq"
13955 [(set (match_operand:QI 0 "register_operand" "")
13956 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13957 "TARGET_80387 || TARGET_SSE"
13958 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13960 (define_expand "sunge"
13961 [(set (match_operand:QI 0 "register_operand" "")
13962 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13963 "TARGET_80387 || TARGET_SSE"
13964 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13966 (define_expand "sungt"
13967 [(set (match_operand:QI 0 "register_operand" "")
13968 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13969 "TARGET_80387 || TARGET_SSE"
13970 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13972 (define_expand "sunle"
13973 [(set (match_operand:QI 0 "register_operand" "")
13974 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13975 "TARGET_80387 || TARGET_SSE"
13976 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13978 (define_expand "sunlt"
13979 [(set (match_operand:QI 0 "register_operand" "")
13980 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13981 "TARGET_80387 || TARGET_SSE"
13982 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13984 (define_expand "sltgt"
13985 [(set (match_operand:QI 0 "register_operand" "")
13986 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13987 "TARGET_80387 || TARGET_SSE"
13988 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13990 (define_insn "*setcc_1"
13991 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13992 (match_operator:QI 1 "ix86_comparison_operator"
13993 [(reg FLAGS_REG) (const_int 0)]))]
13996 [(set_attr "type" "setcc")
13997 (set_attr "mode" "QI")])
13999 (define_insn "*setcc_2"
14000 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14001 (match_operator:QI 1 "ix86_comparison_operator"
14002 [(reg FLAGS_REG) (const_int 0)]))]
14005 [(set_attr "type" "setcc")
14006 (set_attr "mode" "QI")])
14008 ;; In general it is not safe to assume too much about CCmode registers,
14009 ;; so simplify-rtx stops when it sees a second one. Under certain
14010 ;; conditions this is safe on x86, so help combine not create
14017 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14018 (ne:QI (match_operator 1 "ix86_comparison_operator"
14019 [(reg FLAGS_REG) (const_int 0)])
14022 [(set (match_dup 0) (match_dup 1))]
14024 PUT_MODE (operands[1], QImode);
14028 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14029 (ne:QI (match_operator 1 "ix86_comparison_operator"
14030 [(reg FLAGS_REG) (const_int 0)])
14033 [(set (match_dup 0) (match_dup 1))]
14035 PUT_MODE (operands[1], QImode);
14039 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14040 (eq:QI (match_operator 1 "ix86_comparison_operator"
14041 [(reg FLAGS_REG) (const_int 0)])
14044 [(set (match_dup 0) (match_dup 1))]
14046 rtx new_op1 = copy_rtx (operands[1]);
14047 operands[1] = new_op1;
14048 PUT_MODE (new_op1, QImode);
14049 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14050 GET_MODE (XEXP (new_op1, 0))));
14052 /* Make sure that (a) the CCmode we have for the flags is strong
14053 enough for the reversed compare or (b) we have a valid FP compare. */
14054 if (! ix86_comparison_operator (new_op1, VOIDmode))
14059 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14060 (eq:QI (match_operator 1 "ix86_comparison_operator"
14061 [(reg FLAGS_REG) (const_int 0)])
14064 [(set (match_dup 0) (match_dup 1))]
14066 rtx new_op1 = copy_rtx (operands[1]);
14067 operands[1] = new_op1;
14068 PUT_MODE (new_op1, QImode);
14069 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14070 GET_MODE (XEXP (new_op1, 0))));
14072 /* Make sure that (a) the CCmode we have for the flags is strong
14073 enough for the reversed compare or (b) we have a valid FP compare. */
14074 if (! ix86_comparison_operator (new_op1, VOIDmode))
14078 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14079 ;; subsequent logical operations are used to imitate conditional moves.
14080 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14083 (define_insn "*sse_setccsf"
14084 [(set (match_operand:SF 0 "register_operand" "=x")
14085 (match_operator:SF 1 "sse_comparison_operator"
14086 [(match_operand:SF 2 "register_operand" "0")
14087 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
14088 "TARGET_SSE && !TARGET_SSE5"
14089 "cmp%D1ss\t{%3, %0|%0, %3}"
14090 [(set_attr "type" "ssecmp")
14091 (set_attr "mode" "SF")])
14093 (define_insn "*sse_setccdf"
14094 [(set (match_operand:DF 0 "register_operand" "=x")
14095 (match_operator:DF 1 "sse_comparison_operator"
14096 [(match_operand:DF 2 "register_operand" "0")
14097 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
14098 "TARGET_SSE2 && !TARGET_SSE5"
14099 "cmp%D1sd\t{%3, %0|%0, %3}"
14100 [(set_attr "type" "ssecmp")
14101 (set_attr "mode" "DF")])
14103 (define_insn "*sse5_setcc<mode>"
14104 [(set (match_operand:MODEF 0 "register_operand" "=x")
14105 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14106 [(match_operand:MODEF 2 "register_operand" "x")
14107 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14109 "com%Y1ss\t{%3, %2, %0|%0, %2, %3}"
14110 [(set_attr "type" "sse4arg")
14111 (set_attr "mode" "<MODE>")])
14114 ;; Basic conditional jump instructions.
14115 ;; We ignore the overflow flag for signed branch instructions.
14117 ;; For all bCOND expanders, also expand the compare or test insn that
14118 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14120 (define_expand "beq"
14122 (if_then_else (match_dup 1)
14123 (label_ref (match_operand 0 "" ""))
14126 "ix86_expand_branch (EQ, operands[0]); DONE;")
14128 (define_expand "bne"
14130 (if_then_else (match_dup 1)
14131 (label_ref (match_operand 0 "" ""))
14134 "ix86_expand_branch (NE, operands[0]); DONE;")
14136 (define_expand "bgt"
14138 (if_then_else (match_dup 1)
14139 (label_ref (match_operand 0 "" ""))
14142 "ix86_expand_branch (GT, operands[0]); DONE;")
14144 (define_expand "bgtu"
14146 (if_then_else (match_dup 1)
14147 (label_ref (match_operand 0 "" ""))
14150 "ix86_expand_branch (GTU, operands[0]); DONE;")
14152 (define_expand "blt"
14154 (if_then_else (match_dup 1)
14155 (label_ref (match_operand 0 "" ""))
14158 "ix86_expand_branch (LT, operands[0]); DONE;")
14160 (define_expand "bltu"
14162 (if_then_else (match_dup 1)
14163 (label_ref (match_operand 0 "" ""))
14166 "ix86_expand_branch (LTU, operands[0]); DONE;")
14168 (define_expand "bge"
14170 (if_then_else (match_dup 1)
14171 (label_ref (match_operand 0 "" ""))
14174 "ix86_expand_branch (GE, operands[0]); DONE;")
14176 (define_expand "bgeu"
14178 (if_then_else (match_dup 1)
14179 (label_ref (match_operand 0 "" ""))
14182 "ix86_expand_branch (GEU, operands[0]); DONE;")
14184 (define_expand "ble"
14186 (if_then_else (match_dup 1)
14187 (label_ref (match_operand 0 "" ""))
14190 "ix86_expand_branch (LE, operands[0]); DONE;")
14192 (define_expand "bleu"
14194 (if_then_else (match_dup 1)
14195 (label_ref (match_operand 0 "" ""))
14198 "ix86_expand_branch (LEU, operands[0]); DONE;")
14200 (define_expand "bunordered"
14202 (if_then_else (match_dup 1)
14203 (label_ref (match_operand 0 "" ""))
14205 "TARGET_80387 || TARGET_SSE_MATH"
14206 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14208 (define_expand "bordered"
14210 (if_then_else (match_dup 1)
14211 (label_ref (match_operand 0 "" ""))
14213 "TARGET_80387 || TARGET_SSE_MATH"
14214 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14216 (define_expand "buneq"
14218 (if_then_else (match_dup 1)
14219 (label_ref (match_operand 0 "" ""))
14221 "TARGET_80387 || TARGET_SSE_MATH"
14222 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14224 (define_expand "bunge"
14226 (if_then_else (match_dup 1)
14227 (label_ref (match_operand 0 "" ""))
14229 "TARGET_80387 || TARGET_SSE_MATH"
14230 "ix86_expand_branch (UNGE, operands[0]); DONE;")
14232 (define_expand "bungt"
14234 (if_then_else (match_dup 1)
14235 (label_ref (match_operand 0 "" ""))
14237 "TARGET_80387 || TARGET_SSE_MATH"
14238 "ix86_expand_branch (UNGT, operands[0]); DONE;")
14240 (define_expand "bunle"
14242 (if_then_else (match_dup 1)
14243 (label_ref (match_operand 0 "" ""))
14245 "TARGET_80387 || TARGET_SSE_MATH"
14246 "ix86_expand_branch (UNLE, operands[0]); DONE;")
14248 (define_expand "bunlt"
14250 (if_then_else (match_dup 1)
14251 (label_ref (match_operand 0 "" ""))
14253 "TARGET_80387 || TARGET_SSE_MATH"
14254 "ix86_expand_branch (UNLT, operands[0]); DONE;")
14256 (define_expand "bltgt"
14258 (if_then_else (match_dup 1)
14259 (label_ref (match_operand 0 "" ""))
14261 "TARGET_80387 || TARGET_SSE_MATH"
14262 "ix86_expand_branch (LTGT, operands[0]); DONE;")
14264 (define_insn "*jcc_1"
14266 (if_then_else (match_operator 1 "ix86_comparison_operator"
14267 [(reg FLAGS_REG) (const_int 0)])
14268 (label_ref (match_operand 0 "" ""))
14272 [(set_attr "type" "ibr")
14273 (set_attr "modrm" "0")
14274 (set (attr "length")
14275 (if_then_else (and (ge (minus (match_dup 0) (pc))
14277 (lt (minus (match_dup 0) (pc))
14282 (define_insn "*jcc_2"
14284 (if_then_else (match_operator 1 "ix86_comparison_operator"
14285 [(reg FLAGS_REG) (const_int 0)])
14287 (label_ref (match_operand 0 "" ""))))]
14290 [(set_attr "type" "ibr")
14291 (set_attr "modrm" "0")
14292 (set (attr "length")
14293 (if_then_else (and (ge (minus (match_dup 0) (pc))
14295 (lt (minus (match_dup 0) (pc))
14300 ;; In general it is not safe to assume too much about CCmode registers,
14301 ;; so simplify-rtx stops when it sees a second one. Under certain
14302 ;; conditions this is safe on x86, so help combine not create
14310 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14311 [(reg FLAGS_REG) (const_int 0)])
14313 (label_ref (match_operand 1 "" ""))
14317 (if_then_else (match_dup 0)
14318 (label_ref (match_dup 1))
14321 PUT_MODE (operands[0], VOIDmode);
14326 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14327 [(reg FLAGS_REG) (const_int 0)])
14329 (label_ref (match_operand 1 "" ""))
14333 (if_then_else (match_dup 0)
14334 (label_ref (match_dup 1))
14337 rtx new_op0 = copy_rtx (operands[0]);
14338 operands[0] = new_op0;
14339 PUT_MODE (new_op0, VOIDmode);
14340 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14341 GET_MODE (XEXP (new_op0, 0))));
14343 /* Make sure that (a) the CCmode we have for the flags is strong
14344 enough for the reversed compare or (b) we have a valid FP compare. */
14345 if (! ix86_comparison_operator (new_op0, VOIDmode))
14349 ;; Define combination compare-and-branch fp compare instructions to use
14350 ;; during early optimization. Splitting the operation apart early makes
14351 ;; for bad code when we want to reverse the operation.
14353 (define_insn "*fp_jcc_1_mixed"
14355 (if_then_else (match_operator 0 "comparison_operator"
14356 [(match_operand 1 "register_operand" "f,x")
14357 (match_operand 2 "nonimmediate_operand" "f,xm")])
14358 (label_ref (match_operand 3 "" ""))
14360 (clobber (reg:CCFP FPSR_REG))
14361 (clobber (reg:CCFP FLAGS_REG))]
14362 "TARGET_MIX_SSE_I387
14363 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14364 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14365 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14368 (define_insn "*fp_jcc_1_sse"
14370 (if_then_else (match_operator 0 "comparison_operator"
14371 [(match_operand 1 "register_operand" "x")
14372 (match_operand 2 "nonimmediate_operand" "xm")])
14373 (label_ref (match_operand 3 "" ""))
14375 (clobber (reg:CCFP FPSR_REG))
14376 (clobber (reg:CCFP FLAGS_REG))]
14378 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14379 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14380 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14383 (define_insn "*fp_jcc_1_387"
14385 (if_then_else (match_operator 0 "comparison_operator"
14386 [(match_operand 1 "register_operand" "f")
14387 (match_operand 2 "register_operand" "f")])
14388 (label_ref (match_operand 3 "" ""))
14390 (clobber (reg:CCFP FPSR_REG))
14391 (clobber (reg:CCFP FLAGS_REG))]
14392 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14394 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14395 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14398 (define_insn "*fp_jcc_2_mixed"
14400 (if_then_else (match_operator 0 "comparison_operator"
14401 [(match_operand 1 "register_operand" "f,x")
14402 (match_operand 2 "nonimmediate_operand" "f,xm")])
14404 (label_ref (match_operand 3 "" ""))))
14405 (clobber (reg:CCFP FPSR_REG))
14406 (clobber (reg:CCFP FLAGS_REG))]
14407 "TARGET_MIX_SSE_I387
14408 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14409 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14410 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14413 (define_insn "*fp_jcc_2_sse"
14415 (if_then_else (match_operator 0 "comparison_operator"
14416 [(match_operand 1 "register_operand" "x")
14417 (match_operand 2 "nonimmediate_operand" "xm")])
14419 (label_ref (match_operand 3 "" ""))))
14420 (clobber (reg:CCFP FPSR_REG))
14421 (clobber (reg:CCFP FLAGS_REG))]
14423 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14424 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14425 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14428 (define_insn "*fp_jcc_2_387"
14430 (if_then_else (match_operator 0 "comparison_operator"
14431 [(match_operand 1 "register_operand" "f")
14432 (match_operand 2 "register_operand" "f")])
14434 (label_ref (match_operand 3 "" ""))))
14435 (clobber (reg:CCFP FPSR_REG))
14436 (clobber (reg:CCFP FLAGS_REG))]
14437 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14439 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14440 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14443 (define_insn "*fp_jcc_3_387"
14445 (if_then_else (match_operator 0 "comparison_operator"
14446 [(match_operand 1 "register_operand" "f")
14447 (match_operand 2 "nonimmediate_operand" "fm")])
14448 (label_ref (match_operand 3 "" ""))
14450 (clobber (reg:CCFP FPSR_REG))
14451 (clobber (reg:CCFP FLAGS_REG))
14452 (clobber (match_scratch:HI 4 "=a"))]
14454 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14455 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14456 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14457 && SELECT_CC_MODE (GET_CODE (operands[0]),
14458 operands[1], operands[2]) == CCFPmode
14459 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14462 (define_insn "*fp_jcc_4_387"
14464 (if_then_else (match_operator 0 "comparison_operator"
14465 [(match_operand 1 "register_operand" "f")
14466 (match_operand 2 "nonimmediate_operand" "fm")])
14468 (label_ref (match_operand 3 "" ""))))
14469 (clobber (reg:CCFP FPSR_REG))
14470 (clobber (reg:CCFP FLAGS_REG))
14471 (clobber (match_scratch:HI 4 "=a"))]
14473 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14474 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14475 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14476 && SELECT_CC_MODE (GET_CODE (operands[0]),
14477 operands[1], operands[2]) == CCFPmode
14478 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14481 (define_insn "*fp_jcc_5_387"
14483 (if_then_else (match_operator 0 "comparison_operator"
14484 [(match_operand 1 "register_operand" "f")
14485 (match_operand 2 "register_operand" "f")])
14486 (label_ref (match_operand 3 "" ""))
14488 (clobber (reg:CCFP FPSR_REG))
14489 (clobber (reg:CCFP FLAGS_REG))
14490 (clobber (match_scratch:HI 4 "=a"))]
14491 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14492 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14493 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14496 (define_insn "*fp_jcc_6_387"
14498 (if_then_else (match_operator 0 "comparison_operator"
14499 [(match_operand 1 "register_operand" "f")
14500 (match_operand 2 "register_operand" "f")])
14502 (label_ref (match_operand 3 "" ""))))
14503 (clobber (reg:CCFP FPSR_REG))
14504 (clobber (reg:CCFP FLAGS_REG))
14505 (clobber (match_scratch:HI 4 "=a"))]
14506 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14507 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14508 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14511 (define_insn "*fp_jcc_7_387"
14513 (if_then_else (match_operator 0 "comparison_operator"
14514 [(match_operand 1 "register_operand" "f")
14515 (match_operand 2 "const0_operand" "X")])
14516 (label_ref (match_operand 3 "" ""))
14518 (clobber (reg:CCFP FPSR_REG))
14519 (clobber (reg:CCFP FLAGS_REG))
14520 (clobber (match_scratch:HI 4 "=a"))]
14521 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14522 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14523 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14524 && SELECT_CC_MODE (GET_CODE (operands[0]),
14525 operands[1], operands[2]) == CCFPmode
14526 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14529 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14530 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14531 ;; with a precedence over other operators and is always put in the first
14532 ;; place. Swap condition and operands to match ficom instruction.
14534 (define_insn "*fp_jcc_8<mode>_387"
14536 (if_then_else (match_operator 0 "comparison_operator"
14537 [(match_operator 1 "float_operator"
14538 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14539 (match_operand 3 "register_operand" "f,f")])
14540 (label_ref (match_operand 4 "" ""))
14542 (clobber (reg:CCFP FPSR_REG))
14543 (clobber (reg:CCFP FLAGS_REG))
14544 (clobber (match_scratch:HI 5 "=a,a"))]
14545 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14546 && TARGET_USE_<MODE>MODE_FIOP
14547 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14548 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14549 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14550 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14555 (if_then_else (match_operator 0 "comparison_operator"
14556 [(match_operand 1 "register_operand" "")
14557 (match_operand 2 "nonimmediate_operand" "")])
14558 (match_operand 3 "" "")
14559 (match_operand 4 "" "")))
14560 (clobber (reg:CCFP FPSR_REG))
14561 (clobber (reg:CCFP FLAGS_REG))]
14565 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14566 operands[3], operands[4], NULL_RTX, NULL_RTX);
14572 (if_then_else (match_operator 0 "comparison_operator"
14573 [(match_operand 1 "register_operand" "")
14574 (match_operand 2 "general_operand" "")])
14575 (match_operand 3 "" "")
14576 (match_operand 4 "" "")))
14577 (clobber (reg:CCFP FPSR_REG))
14578 (clobber (reg:CCFP FLAGS_REG))
14579 (clobber (match_scratch:HI 5 "=a"))]
14583 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14584 operands[3], operands[4], operands[5], NULL_RTX);
14590 (if_then_else (match_operator 0 "comparison_operator"
14591 [(match_operator 1 "float_operator"
14592 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14593 (match_operand 3 "register_operand" "")])
14594 (match_operand 4 "" "")
14595 (match_operand 5 "" "")))
14596 (clobber (reg:CCFP FPSR_REG))
14597 (clobber (reg:CCFP FLAGS_REG))
14598 (clobber (match_scratch:HI 6 "=a"))]
14602 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14603 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14604 operands[3], operands[7],
14605 operands[4], operands[5], operands[6], NULL_RTX);
14609 ;; %%% Kill this when reload knows how to do it.
14612 (if_then_else (match_operator 0 "comparison_operator"
14613 [(match_operator 1 "float_operator"
14614 [(match_operand:X87MODEI12 2 "register_operand" "")])
14615 (match_operand 3 "register_operand" "")])
14616 (match_operand 4 "" "")
14617 (match_operand 5 "" "")))
14618 (clobber (reg:CCFP FPSR_REG))
14619 (clobber (reg:CCFP FLAGS_REG))
14620 (clobber (match_scratch:HI 6 "=a"))]
14624 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14625 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14626 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14627 operands[3], operands[7],
14628 operands[4], operands[5], operands[6], operands[2]);
14632 ;; Unconditional and other jump instructions
14634 (define_insn "jump"
14636 (label_ref (match_operand 0 "" "")))]
14639 [(set_attr "type" "ibr")
14640 (set (attr "length")
14641 (if_then_else (and (ge (minus (match_dup 0) (pc))
14643 (lt (minus (match_dup 0) (pc))
14647 (set_attr "modrm" "0")])
14649 (define_expand "indirect_jump"
14650 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14654 (define_insn "*indirect_jump"
14655 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14658 [(set_attr "type" "ibr")
14659 (set_attr "length_immediate" "0")])
14661 (define_insn "*indirect_jump_rtx64"
14662 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14665 [(set_attr "type" "ibr")
14666 (set_attr "length_immediate" "0")])
14668 (define_expand "tablejump"
14669 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14670 (use (label_ref (match_operand 1 "" "")))])]
14673 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14674 relative. Convert the relative address to an absolute address. */
14678 enum rtx_code code;
14680 /* We can't use @GOTOFF for text labels on VxWorks;
14681 see gotoff_operand. */
14682 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14686 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14688 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14692 op1 = pic_offset_table_rtx;
14697 op0 = pic_offset_table_rtx;
14701 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14706 (define_insn "*tablejump_1"
14707 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14708 (use (label_ref (match_operand 1 "" "")))]
14711 [(set_attr "type" "ibr")
14712 (set_attr "length_immediate" "0")])
14714 (define_insn "*tablejump_1_rtx64"
14715 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14716 (use (label_ref (match_operand 1 "" "")))]
14719 [(set_attr "type" "ibr")
14720 (set_attr "length_immediate" "0")])
14722 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14725 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14726 (set (match_operand:QI 1 "register_operand" "")
14727 (match_operator:QI 2 "ix86_comparison_operator"
14728 [(reg FLAGS_REG) (const_int 0)]))
14729 (set (match_operand 3 "q_regs_operand" "")
14730 (zero_extend (match_dup 1)))]
14731 "(peep2_reg_dead_p (3, operands[1])
14732 || operands_match_p (operands[1], operands[3]))
14733 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14734 [(set (match_dup 4) (match_dup 0))
14735 (set (strict_low_part (match_dup 5))
14738 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14739 operands[5] = gen_lowpart (QImode, operands[3]);
14740 ix86_expand_clear (operands[3]);
14743 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14746 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14747 (set (match_operand:QI 1 "register_operand" "")
14748 (match_operator:QI 2 "ix86_comparison_operator"
14749 [(reg FLAGS_REG) (const_int 0)]))
14750 (parallel [(set (match_operand 3 "q_regs_operand" "")
14751 (zero_extend (match_dup 1)))
14752 (clobber (reg:CC FLAGS_REG))])]
14753 "(peep2_reg_dead_p (3, operands[1])
14754 || operands_match_p (operands[1], operands[3]))
14755 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14756 [(set (match_dup 4) (match_dup 0))
14757 (set (strict_low_part (match_dup 5))
14760 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14761 operands[5] = gen_lowpart (QImode, operands[3]);
14762 ix86_expand_clear (operands[3]);
14765 ;; Call instructions.
14767 ;; The predicates normally associated with named expanders are not properly
14768 ;; checked for calls. This is a bug in the generic code, but it isn't that
14769 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14771 ;; Call subroutine returning no value.
14773 (define_expand "call_pop"
14774 [(parallel [(call (match_operand:QI 0 "" "")
14775 (match_operand:SI 1 "" ""))
14776 (set (reg:SI SP_REG)
14777 (plus:SI (reg:SI SP_REG)
14778 (match_operand:SI 3 "" "")))])]
14781 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14785 (define_insn "*call_pop_0"
14786 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14787 (match_operand:SI 1 "" ""))
14788 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14789 (match_operand:SI 2 "immediate_operand" "")))]
14792 if (SIBLING_CALL_P (insn))
14795 return "call\t%P0";
14797 [(set_attr "type" "call")])
14799 (define_insn "*call_pop_1"
14800 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14801 (match_operand:SI 1 "" ""))
14802 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14803 (match_operand:SI 2 "immediate_operand" "i")))]
14806 if (constant_call_address_operand (operands[0], Pmode))
14808 if (SIBLING_CALL_P (insn))
14811 return "call\t%P0";
14813 if (SIBLING_CALL_P (insn))
14816 return "call\t%A0";
14818 [(set_attr "type" "call")])
14820 (define_expand "call"
14821 [(call (match_operand:QI 0 "" "")
14822 (match_operand 1 "" ""))
14823 (use (match_operand 2 "" ""))]
14826 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14830 (define_expand "sibcall"
14831 [(call (match_operand:QI 0 "" "")
14832 (match_operand 1 "" ""))
14833 (use (match_operand 2 "" ""))]
14836 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14840 (define_insn "*call_0"
14841 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14842 (match_operand 1 "" ""))]
14845 if (SIBLING_CALL_P (insn))
14848 return "call\t%P0";
14850 [(set_attr "type" "call")])
14852 (define_insn "*call_1"
14853 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14854 (match_operand 1 "" ""))]
14855 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14857 if (constant_call_address_operand (operands[0], Pmode))
14858 return "call\t%P0";
14859 return "call\t%A0";
14861 [(set_attr "type" "call")])
14863 (define_insn "*sibcall_1"
14864 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14865 (match_operand 1 "" ""))]
14866 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14868 if (constant_call_address_operand (operands[0], Pmode))
14872 [(set_attr "type" "call")])
14874 (define_insn "*call_1_rex64"
14875 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14876 (match_operand 1 "" ""))]
14877 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14878 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14880 if (constant_call_address_operand (operands[0], Pmode))
14881 return "call\t%P0";
14882 return "call\t%A0";
14884 [(set_attr "type" "call")])
14886 (define_insn "*call_1_rex64_large"
14887 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14888 (match_operand 1 "" ""))]
14889 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14891 [(set_attr "type" "call")])
14893 (define_insn "*sibcall_1_rex64"
14894 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14895 (match_operand 1 "" ""))]
14896 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14898 [(set_attr "type" "call")])
14900 (define_insn "*sibcall_1_rex64_v"
14901 [(call (mem:QI (reg:DI R11_REG))
14902 (match_operand 0 "" ""))]
14903 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14905 [(set_attr "type" "call")])
14908 ;; Call subroutine, returning value in operand 0
14910 (define_expand "call_value_pop"
14911 [(parallel [(set (match_operand 0 "" "")
14912 (call (match_operand:QI 1 "" "")
14913 (match_operand:SI 2 "" "")))
14914 (set (reg:SI SP_REG)
14915 (plus:SI (reg:SI SP_REG)
14916 (match_operand:SI 4 "" "")))])]
14919 ix86_expand_call (operands[0], operands[1], operands[2],
14920 operands[3], operands[4], 0);
14924 (define_expand "call_value"
14925 [(set (match_operand 0 "" "")
14926 (call (match_operand:QI 1 "" "")
14927 (match_operand:SI 2 "" "")))
14928 (use (match_operand:SI 3 "" ""))]
14929 ;; Operand 2 not used on the i386.
14932 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14936 (define_expand "sibcall_value"
14937 [(set (match_operand 0 "" "")
14938 (call (match_operand:QI 1 "" "")
14939 (match_operand:SI 2 "" "")))
14940 (use (match_operand:SI 3 "" ""))]
14941 ;; Operand 2 not used on the i386.
14944 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14948 ;; Call subroutine returning any type.
14950 (define_expand "untyped_call"
14951 [(parallel [(call (match_operand 0 "" "")
14953 (match_operand 1 "" "")
14954 (match_operand 2 "" "")])]
14959 /* In order to give reg-stack an easier job in validating two
14960 coprocessor registers as containing a possible return value,
14961 simply pretend the untyped call returns a complex long double
14964 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14965 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14966 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14969 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14971 rtx set = XVECEXP (operands[2], 0, i);
14972 emit_move_insn (SET_DEST (set), SET_SRC (set));
14975 /* The optimizer does not know that the call sets the function value
14976 registers we stored in the result block. We avoid problems by
14977 claiming that all hard registers are used and clobbered at this
14979 emit_insn (gen_blockage ());
14984 ;; Prologue and epilogue instructions
14986 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14987 ;; all of memory. This blocks insns from being moved across this point.
14989 (define_insn "blockage"
14990 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14993 [(set_attr "length" "0")])
14995 ;; As USE insns aren't meaningful after reload, this is used instead
14996 ;; to prevent deleting instructions setting registers for PIC code
14997 (define_insn "prologue_use"
14998 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15001 [(set_attr "length" "0")])
15003 ;; Insn emitted into the body of a function to return from a function.
15004 ;; This is only done if the function's epilogue is known to be simple.
15005 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15007 (define_expand "return"
15009 "ix86_can_use_return_insn_p ()"
15011 if (current_function_pops_args)
15013 rtx popc = GEN_INT (current_function_pops_args);
15014 emit_jump_insn (gen_return_pop_internal (popc));
15019 (define_insn "return_internal"
15023 [(set_attr "length" "1")
15024 (set_attr "length_immediate" "0")
15025 (set_attr "modrm" "0")])
15027 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15028 ;; instruction Athlon and K8 have.
15030 (define_insn "return_internal_long"
15032 (unspec [(const_int 0)] UNSPEC_REP)]
15035 [(set_attr "length" "1")
15036 (set_attr "length_immediate" "0")
15037 (set_attr "prefix_rep" "1")
15038 (set_attr "modrm" "0")])
15040 (define_insn "return_pop_internal"
15042 (use (match_operand:SI 0 "const_int_operand" ""))]
15045 [(set_attr "length" "3")
15046 (set_attr "length_immediate" "2")
15047 (set_attr "modrm" "0")])
15049 (define_insn "return_indirect_internal"
15051 (use (match_operand:SI 0 "register_operand" "r"))]
15054 [(set_attr "type" "ibr")
15055 (set_attr "length_immediate" "0")])
15061 [(set_attr "length" "1")
15062 (set_attr "length_immediate" "0")
15063 (set_attr "modrm" "0")])
15065 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15066 ;; branch prediction penalty for the third jump in a 16-byte
15069 (define_insn "align"
15070 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15073 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15074 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15076 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15077 The align insn is used to avoid 3 jump instructions in the row to improve
15078 branch prediction and the benefits hardly outweigh the cost of extra 8
15079 nops on the average inserted by full alignment pseudo operation. */
15083 [(set_attr "length" "16")])
15085 (define_expand "prologue"
15088 "ix86_expand_prologue (); DONE;")
15090 (define_insn "set_got"
15091 [(set (match_operand:SI 0 "register_operand" "=r")
15092 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15093 (clobber (reg:CC FLAGS_REG))]
15095 { return output_set_got (operands[0], NULL_RTX); }
15096 [(set_attr "type" "multi")
15097 (set_attr "length" "12")])
15099 (define_insn "set_got_labelled"
15100 [(set (match_operand:SI 0 "register_operand" "=r")
15101 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15103 (clobber (reg:CC FLAGS_REG))]
15105 { return output_set_got (operands[0], operands[1]); }
15106 [(set_attr "type" "multi")
15107 (set_attr "length" "12")])
15109 (define_insn "set_got_rex64"
15110 [(set (match_operand:DI 0 "register_operand" "=r")
15111 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15113 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
15114 [(set_attr "type" "lea")
15115 (set_attr "length" "6")])
15117 (define_insn "set_rip_rex64"
15118 [(set (match_operand:DI 0 "register_operand" "=r")
15119 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15121 "lea{q}\t%l1(%%rip), %0"
15122 [(set_attr "type" "lea")
15123 (set_attr "length" "6")])
15125 (define_insn "set_got_offset_rex64"
15126 [(set (match_operand:DI 0 "register_operand" "=r")
15127 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15129 "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
15130 [(set_attr "type" "imov")
15131 (set_attr "length" "11")])
15133 (define_expand "epilogue"
15136 "ix86_expand_epilogue (1); DONE;")
15138 (define_expand "sibcall_epilogue"
15141 "ix86_expand_epilogue (0); DONE;")
15143 (define_expand "eh_return"
15144 [(use (match_operand 0 "register_operand" ""))]
15147 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15149 /* Tricky bit: we write the address of the handler to which we will
15150 be returning into someone else's stack frame, one word below the
15151 stack address we wish to restore. */
15152 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15153 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15154 tmp = gen_rtx_MEM (Pmode, tmp);
15155 emit_move_insn (tmp, ra);
15157 if (Pmode == SImode)
15158 emit_jump_insn (gen_eh_return_si (sa));
15160 emit_jump_insn (gen_eh_return_di (sa));
15165 (define_insn_and_split "eh_return_si"
15167 (unspec [(match_operand:SI 0 "register_operand" "c")]
15168 UNSPEC_EH_RETURN))]
15173 "ix86_expand_epilogue (2); DONE;")
15175 (define_insn_and_split "eh_return_di"
15177 (unspec [(match_operand:DI 0 "register_operand" "c")]
15178 UNSPEC_EH_RETURN))]
15183 "ix86_expand_epilogue (2); DONE;")
15185 (define_insn "leave"
15186 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15187 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15188 (clobber (mem:BLK (scratch)))]
15191 [(set_attr "type" "leave")])
15193 (define_insn "leave_rex64"
15194 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15195 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15196 (clobber (mem:BLK (scratch)))]
15199 [(set_attr "type" "leave")])
15201 (define_expand "ffssi2"
15203 [(set (match_operand:SI 0 "register_operand" "")
15204 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15205 (clobber (match_scratch:SI 2 ""))
15206 (clobber (reg:CC FLAGS_REG))])]
15211 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15216 (define_expand "ffs_cmove"
15217 [(set (match_dup 2) (const_int -1))
15218 (parallel [(set (reg:CCZ FLAGS_REG)
15219 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15221 (set (match_operand:SI 0 "nonimmediate_operand" "")
15222 (ctz:SI (match_dup 1)))])
15223 (set (match_dup 0) (if_then_else:SI
15224 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15227 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15228 (clobber (reg:CC FLAGS_REG))])]
15230 "operands[2] = gen_reg_rtx (SImode);")
15232 (define_insn_and_split "*ffs_no_cmove"
15233 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15234 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15235 (clobber (match_scratch:SI 2 "=&q"))
15236 (clobber (reg:CC FLAGS_REG))]
15239 "&& reload_completed"
15240 [(parallel [(set (reg:CCZ FLAGS_REG)
15241 (compare:CCZ (match_dup 1) (const_int 0)))
15242 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15243 (set (strict_low_part (match_dup 3))
15244 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15245 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15246 (clobber (reg:CC FLAGS_REG))])
15247 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15248 (clobber (reg:CC FLAGS_REG))])
15249 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15250 (clobber (reg:CC FLAGS_REG))])]
15252 operands[3] = gen_lowpart (QImode, operands[2]);
15253 ix86_expand_clear (operands[2]);
15256 (define_insn "*ffssi_1"
15257 [(set (reg:CCZ FLAGS_REG)
15258 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15260 (set (match_operand:SI 0 "register_operand" "=r")
15261 (ctz:SI (match_dup 1)))]
15263 "bsf{l}\t{%1, %0|%0, %1}"
15264 [(set_attr "prefix_0f" "1")])
15266 (define_expand "ffsdi2"
15267 [(set (match_dup 2) (const_int -1))
15268 (parallel [(set (reg:CCZ FLAGS_REG)
15269 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15271 (set (match_operand:DI 0 "nonimmediate_operand" "")
15272 (ctz:DI (match_dup 1)))])
15273 (set (match_dup 0) (if_then_else:DI
15274 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15277 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15278 (clobber (reg:CC FLAGS_REG))])]
15280 "operands[2] = gen_reg_rtx (DImode);")
15282 (define_insn "*ffsdi_1"
15283 [(set (reg:CCZ FLAGS_REG)
15284 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15286 (set (match_operand:DI 0 "register_operand" "=r")
15287 (ctz:DI (match_dup 1)))]
15289 "bsf{q}\t{%1, %0|%0, %1}"
15290 [(set_attr "prefix_0f" "1")])
15292 (define_insn "ctzsi2"
15293 [(set (match_operand:SI 0 "register_operand" "=r")
15294 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15295 (clobber (reg:CC FLAGS_REG))]
15297 "bsf{l}\t{%1, %0|%0, %1}"
15298 [(set_attr "prefix_0f" "1")])
15300 (define_insn "ctzdi2"
15301 [(set (match_operand:DI 0 "register_operand" "=r")
15302 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15303 (clobber (reg:CC FLAGS_REG))]
15305 "bsf{q}\t{%1, %0|%0, %1}"
15306 [(set_attr "prefix_0f" "1")])
15308 (define_expand "clzsi2"
15310 [(set (match_operand:SI 0 "register_operand" "")
15311 (minus:SI (const_int 31)
15312 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15313 (clobber (reg:CC FLAGS_REG))])
15315 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15316 (clobber (reg:CC FLAGS_REG))])]
15321 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15326 (define_insn "clzsi2_abm"
15327 [(set (match_operand:SI 0 "register_operand" "=r")
15328 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15329 (clobber (reg:CC FLAGS_REG))]
15331 "lzcnt{l}\t{%1, %0|%0, %1}"
15332 [(set_attr "prefix_rep" "1")
15333 (set_attr "type" "bitmanip")
15334 (set_attr "mode" "SI")])
15336 (define_insn "*bsr"
15337 [(set (match_operand:SI 0 "register_operand" "=r")
15338 (minus:SI (const_int 31)
15339 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15340 (clobber (reg:CC FLAGS_REG))]
15342 "bsr{l}\t{%1, %0|%0, %1}"
15343 [(set_attr "prefix_0f" "1")
15344 (set_attr "mode" "SI")])
15346 (define_insn "popcountsi2"
15347 [(set (match_operand:SI 0 "register_operand" "=r")
15348 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15349 (clobber (reg:CC FLAGS_REG))]
15351 "popcnt{l}\t{%1, %0|%0, %1}"
15352 [(set_attr "prefix_rep" "1")
15353 (set_attr "type" "bitmanip")
15354 (set_attr "mode" "SI")])
15356 (define_insn "*popcountsi2_cmp"
15357 [(set (reg FLAGS_REG)
15359 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15361 (set (match_operand:SI 0 "register_operand" "=r")
15362 (popcount:SI (match_dup 1)))]
15363 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15364 "popcnt{l}\t{%1, %0|%0, %1}"
15365 [(set_attr "prefix_rep" "1")
15366 (set_attr "type" "bitmanip")
15367 (set_attr "mode" "SI")])
15369 (define_insn "*popcountsi2_cmp_zext"
15370 [(set (reg FLAGS_REG)
15372 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15374 (set (match_operand:DI 0 "register_operand" "=r")
15375 (zero_extend:DI(popcount:SI (match_dup 1))))]
15376 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15377 "popcnt{l}\t{%1, %0|%0, %1}"
15378 [(set_attr "prefix_rep" "1")
15379 (set_attr "type" "bitmanip")
15380 (set_attr "mode" "SI")])
15382 (define_expand "bswapsi2"
15383 [(set (match_operand:SI 0 "register_operand" "")
15384 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15389 rtx x = operands[0];
15391 emit_move_insn (x, operands[1]);
15392 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15393 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15394 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15399 (define_insn "*bswapsi_1"
15400 [(set (match_operand:SI 0 "register_operand" "=r")
15401 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15404 [(set_attr "prefix_0f" "1")
15405 (set_attr "length" "2")])
15407 (define_insn "*bswaphi_lowpart_1"
15408 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15409 (bswap:HI (match_dup 0)))
15410 (clobber (reg:CC FLAGS_REG))]
15411 "TARGET_USE_XCHGB || optimize_size"
15413 xchg{b}\t{%h0, %b0|%b0, %h0}
15414 rol{w}\t{$8, %0|%0, 8}"
15415 [(set_attr "length" "2,4")
15416 (set_attr "mode" "QI,HI")])
15418 (define_insn "bswaphi_lowpart"
15419 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15420 (bswap:HI (match_dup 0)))
15421 (clobber (reg:CC FLAGS_REG))]
15423 "rol{w}\t{$8, %0|%0, 8}"
15424 [(set_attr "length" "4")
15425 (set_attr "mode" "HI")])
15427 (define_insn "bswapdi2"
15428 [(set (match_operand:DI 0 "register_operand" "=r")
15429 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15432 [(set_attr "prefix_0f" "1")
15433 (set_attr "length" "3")])
15435 (define_expand "clzdi2"
15437 [(set (match_operand:DI 0 "register_operand" "")
15438 (minus:DI (const_int 63)
15439 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15440 (clobber (reg:CC FLAGS_REG))])
15442 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15443 (clobber (reg:CC FLAGS_REG))])]
15448 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15453 (define_insn "clzdi2_abm"
15454 [(set (match_operand:DI 0 "register_operand" "=r")
15455 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15456 (clobber (reg:CC FLAGS_REG))]
15457 "TARGET_64BIT && TARGET_ABM"
15458 "lzcnt{q}\t{%1, %0|%0, %1}"
15459 [(set_attr "prefix_rep" "1")
15460 (set_attr "type" "bitmanip")
15461 (set_attr "mode" "DI")])
15463 (define_insn "*bsr_rex64"
15464 [(set (match_operand:DI 0 "register_operand" "=r")
15465 (minus:DI (const_int 63)
15466 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15467 (clobber (reg:CC FLAGS_REG))]
15469 "bsr{q}\t{%1, %0|%0, %1}"
15470 [(set_attr "prefix_0f" "1")
15471 (set_attr "mode" "DI")])
15473 (define_insn "popcountdi2"
15474 [(set (match_operand:DI 0 "register_operand" "=r")
15475 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15476 (clobber (reg:CC FLAGS_REG))]
15477 "TARGET_64BIT && TARGET_POPCNT"
15478 "popcnt{q}\t{%1, %0|%0, %1}"
15479 [(set_attr "prefix_rep" "1")
15480 (set_attr "type" "bitmanip")
15481 (set_attr "mode" "DI")])
15483 (define_insn "*popcountdi2_cmp"
15484 [(set (reg FLAGS_REG)
15486 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15488 (set (match_operand:DI 0 "register_operand" "=r")
15489 (popcount:DI (match_dup 1)))]
15490 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15491 "popcnt{q}\t{%1, %0|%0, %1}"
15492 [(set_attr "prefix_rep" "1")
15493 (set_attr "type" "bitmanip")
15494 (set_attr "mode" "DI")])
15496 (define_expand "clzhi2"
15498 [(set (match_operand:HI 0 "register_operand" "")
15499 (minus:HI (const_int 15)
15500 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15501 (clobber (reg:CC FLAGS_REG))])
15503 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15504 (clobber (reg:CC FLAGS_REG))])]
15509 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15514 (define_insn "clzhi2_abm"
15515 [(set (match_operand:HI 0 "register_operand" "=r")
15516 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15517 (clobber (reg:CC FLAGS_REG))]
15519 "lzcnt{w}\t{%1, %0|%0, %1}"
15520 [(set_attr "prefix_rep" "1")
15521 (set_attr "type" "bitmanip")
15522 (set_attr "mode" "HI")])
15524 (define_insn "*bsrhi"
15525 [(set (match_operand:HI 0 "register_operand" "=r")
15526 (minus:HI (const_int 15)
15527 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15528 (clobber (reg:CC FLAGS_REG))]
15530 "bsr{w}\t{%1, %0|%0, %1}"
15531 [(set_attr "prefix_0f" "1")
15532 (set_attr "mode" "HI")])
15534 (define_insn "popcounthi2"
15535 [(set (match_operand:HI 0 "register_operand" "=r")
15536 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15537 (clobber (reg:CC FLAGS_REG))]
15539 "popcnt{w}\t{%1, %0|%0, %1}"
15540 [(set_attr "prefix_rep" "1")
15541 (set_attr "type" "bitmanip")
15542 (set_attr "mode" "HI")])
15544 (define_insn "*popcounthi2_cmp"
15545 [(set (reg FLAGS_REG)
15547 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15549 (set (match_operand:HI 0 "register_operand" "=r")
15550 (popcount:HI (match_dup 1)))]
15551 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15552 "popcnt{w}\t{%1, %0|%0, %1}"
15553 [(set_attr "prefix_rep" "1")
15554 (set_attr "type" "bitmanip")
15555 (set_attr "mode" "HI")])
15557 (define_expand "paritydi2"
15558 [(set (match_operand:DI 0 "register_operand" "")
15559 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15562 rtx scratch = gen_reg_rtx (QImode);
15565 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15566 NULL_RTX, operands[1]));
15568 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15569 gen_rtx_REG (CCmode, FLAGS_REG),
15571 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15574 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15577 rtx tmp = gen_reg_rtx (SImode);
15579 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15580 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15585 (define_insn_and_split "paritydi2_cmp"
15586 [(set (reg:CC FLAGS_REG)
15587 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15588 (clobber (match_scratch:DI 0 "=r,X"))
15589 (clobber (match_scratch:SI 1 "=r,r"))
15590 (clobber (match_scratch:HI 2 "=Q,Q"))]
15593 "&& reload_completed"
15595 [(set (match_dup 1)
15596 (xor:SI (match_dup 1) (match_dup 4)))
15597 (clobber (reg:CC FLAGS_REG))])
15599 [(set (reg:CC FLAGS_REG)
15600 (parity:CC (match_dup 1)))
15601 (clobber (match_dup 1))
15602 (clobber (match_dup 2))])]
15604 operands[4] = gen_lowpart (SImode, operands[3]);
15606 if (MEM_P (operands[3]))
15607 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15608 else if (! TARGET_64BIT)
15609 operands[1] = gen_highpart (SImode, operands[3]);
15612 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15613 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15617 (define_expand "paritysi2"
15618 [(set (match_operand:SI 0 "register_operand" "")
15619 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15622 rtx scratch = gen_reg_rtx (QImode);
15625 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15627 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15628 gen_rtx_REG (CCmode, FLAGS_REG),
15630 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15632 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15636 (define_insn_and_split "paritysi2_cmp"
15637 [(set (reg:CC FLAGS_REG)
15638 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15639 (clobber (match_scratch:SI 0 "=r,X"))
15640 (clobber (match_scratch:HI 1 "=Q,Q"))]
15643 "&& reload_completed"
15645 [(set (match_dup 1)
15646 (xor:HI (match_dup 1) (match_dup 3)))
15647 (clobber (reg:CC FLAGS_REG))])
15649 [(set (reg:CC FLAGS_REG)
15650 (parity:CC (match_dup 1)))
15651 (clobber (match_dup 1))])]
15653 operands[3] = gen_lowpart (HImode, operands[2]);
15655 if (MEM_P (operands[2]))
15656 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15659 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15660 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15664 (define_insn "*parityhi2_cmp"
15665 [(set (reg:CC FLAGS_REG)
15666 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15667 (clobber (match_scratch:HI 0 "=Q"))]
15669 "xor{b}\t{%h0, %b0|%b0, %h0}"
15670 [(set_attr "length" "2")
15671 (set_attr "mode" "HI")])
15673 (define_insn "*parityqi2_cmp"
15674 [(set (reg:CC FLAGS_REG)
15675 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15678 [(set_attr "length" "2")
15679 (set_attr "mode" "QI")])
15681 ;; Thread-local storage patterns for ELF.
15683 ;; Note that these code sequences must appear exactly as shown
15684 ;; in order to allow linker relaxation.
15686 (define_insn "*tls_global_dynamic_32_gnu"
15687 [(set (match_operand:SI 0 "register_operand" "=a")
15688 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15689 (match_operand:SI 2 "tls_symbolic_operand" "")
15690 (match_operand:SI 3 "call_insn_operand" "")]
15692 (clobber (match_scratch:SI 4 "=d"))
15693 (clobber (match_scratch:SI 5 "=c"))
15694 (clobber (reg:CC FLAGS_REG))]
15695 "!TARGET_64BIT && TARGET_GNU_TLS"
15696 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15697 [(set_attr "type" "multi")
15698 (set_attr "length" "12")])
15700 (define_insn "*tls_global_dynamic_32_sun"
15701 [(set (match_operand:SI 0 "register_operand" "=a")
15702 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15703 (match_operand:SI 2 "tls_symbolic_operand" "")
15704 (match_operand:SI 3 "call_insn_operand" "")]
15706 (clobber (match_scratch:SI 4 "=d"))
15707 (clobber (match_scratch:SI 5 "=c"))
15708 (clobber (reg:CC FLAGS_REG))]
15709 "!TARGET_64BIT && TARGET_SUN_TLS"
15710 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15711 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15712 [(set_attr "type" "multi")
15713 (set_attr "length" "14")])
15715 (define_expand "tls_global_dynamic_32"
15716 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15719 (match_operand:SI 1 "tls_symbolic_operand" "")
15722 (clobber (match_scratch:SI 4 ""))
15723 (clobber (match_scratch:SI 5 ""))
15724 (clobber (reg:CC FLAGS_REG))])]
15728 operands[2] = pic_offset_table_rtx;
15731 operands[2] = gen_reg_rtx (Pmode);
15732 emit_insn (gen_set_got (operands[2]));
15734 if (TARGET_GNU2_TLS)
15736 emit_insn (gen_tls_dynamic_gnu2_32
15737 (operands[0], operands[1], operands[2]));
15740 operands[3] = ix86_tls_get_addr ();
15743 (define_insn "*tls_global_dynamic_64"
15744 [(set (match_operand:DI 0 "register_operand" "=a")
15745 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15746 (match_operand:DI 3 "" "")))
15747 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15750 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15751 [(set_attr "type" "multi")
15752 (set_attr "length" "16")])
15754 (define_expand "tls_global_dynamic_64"
15755 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15756 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15757 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15761 if (TARGET_GNU2_TLS)
15763 emit_insn (gen_tls_dynamic_gnu2_64
15764 (operands[0], operands[1]));
15767 operands[2] = ix86_tls_get_addr ();
15770 (define_insn "*tls_local_dynamic_base_32_gnu"
15771 [(set (match_operand:SI 0 "register_operand" "=a")
15772 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15773 (match_operand:SI 2 "call_insn_operand" "")]
15774 UNSPEC_TLS_LD_BASE))
15775 (clobber (match_scratch:SI 3 "=d"))
15776 (clobber (match_scratch:SI 4 "=c"))
15777 (clobber (reg:CC FLAGS_REG))]
15778 "!TARGET_64BIT && TARGET_GNU_TLS"
15779 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15780 [(set_attr "type" "multi")
15781 (set_attr "length" "11")])
15783 (define_insn "*tls_local_dynamic_base_32_sun"
15784 [(set (match_operand:SI 0 "register_operand" "=a")
15785 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15786 (match_operand:SI 2 "call_insn_operand" "")]
15787 UNSPEC_TLS_LD_BASE))
15788 (clobber (match_scratch:SI 3 "=d"))
15789 (clobber (match_scratch:SI 4 "=c"))
15790 (clobber (reg:CC FLAGS_REG))]
15791 "!TARGET_64BIT && TARGET_SUN_TLS"
15792 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15793 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15794 [(set_attr "type" "multi")
15795 (set_attr "length" "13")])
15797 (define_expand "tls_local_dynamic_base_32"
15798 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15799 (unspec:SI [(match_dup 1) (match_dup 2)]
15800 UNSPEC_TLS_LD_BASE))
15801 (clobber (match_scratch:SI 3 ""))
15802 (clobber (match_scratch:SI 4 ""))
15803 (clobber (reg:CC FLAGS_REG))])]
15807 operands[1] = pic_offset_table_rtx;
15810 operands[1] = gen_reg_rtx (Pmode);
15811 emit_insn (gen_set_got (operands[1]));
15813 if (TARGET_GNU2_TLS)
15815 emit_insn (gen_tls_dynamic_gnu2_32
15816 (operands[0], ix86_tls_module_base (), operands[1]));
15819 operands[2] = ix86_tls_get_addr ();
15822 (define_insn "*tls_local_dynamic_base_64"
15823 [(set (match_operand:DI 0 "register_operand" "=a")
15824 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15825 (match_operand:DI 2 "" "")))
15826 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15828 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15829 [(set_attr "type" "multi")
15830 (set_attr "length" "12")])
15832 (define_expand "tls_local_dynamic_base_64"
15833 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15834 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15835 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15838 if (TARGET_GNU2_TLS)
15840 emit_insn (gen_tls_dynamic_gnu2_64
15841 (operands[0], ix86_tls_module_base ()));
15844 operands[1] = ix86_tls_get_addr ();
15847 ;; Local dynamic of a single variable is a lose. Show combine how
15848 ;; to convert that back to global dynamic.
15850 (define_insn_and_split "*tls_local_dynamic_32_once"
15851 [(set (match_operand:SI 0 "register_operand" "=a")
15852 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15853 (match_operand:SI 2 "call_insn_operand" "")]
15854 UNSPEC_TLS_LD_BASE)
15855 (const:SI (unspec:SI
15856 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15858 (clobber (match_scratch:SI 4 "=d"))
15859 (clobber (match_scratch:SI 5 "=c"))
15860 (clobber (reg:CC FLAGS_REG))]
15864 [(parallel [(set (match_dup 0)
15865 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15867 (clobber (match_dup 4))
15868 (clobber (match_dup 5))
15869 (clobber (reg:CC FLAGS_REG))])]
15872 ;; Load and add the thread base pointer from %gs:0.
15874 (define_insn "*load_tp_si"
15875 [(set (match_operand:SI 0 "register_operand" "=r")
15876 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15878 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15879 [(set_attr "type" "imov")
15880 (set_attr "modrm" "0")
15881 (set_attr "length" "7")
15882 (set_attr "memory" "load")
15883 (set_attr "imm_disp" "false")])
15885 (define_insn "*add_tp_si"
15886 [(set (match_operand:SI 0 "register_operand" "=r")
15887 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15888 (match_operand:SI 1 "register_operand" "0")))
15889 (clobber (reg:CC FLAGS_REG))]
15891 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15892 [(set_attr "type" "alu")
15893 (set_attr "modrm" "0")
15894 (set_attr "length" "7")
15895 (set_attr "memory" "load")
15896 (set_attr "imm_disp" "false")])
15898 (define_insn "*load_tp_di"
15899 [(set (match_operand:DI 0 "register_operand" "=r")
15900 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15902 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15903 [(set_attr "type" "imov")
15904 (set_attr "modrm" "0")
15905 (set_attr "length" "7")
15906 (set_attr "memory" "load")
15907 (set_attr "imm_disp" "false")])
15909 (define_insn "*add_tp_di"
15910 [(set (match_operand:DI 0 "register_operand" "=r")
15911 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15912 (match_operand:DI 1 "register_operand" "0")))
15913 (clobber (reg:CC FLAGS_REG))]
15915 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15916 [(set_attr "type" "alu")
15917 (set_attr "modrm" "0")
15918 (set_attr "length" "7")
15919 (set_attr "memory" "load")
15920 (set_attr "imm_disp" "false")])
15922 ;; GNU2 TLS patterns can be split.
15924 (define_expand "tls_dynamic_gnu2_32"
15925 [(set (match_dup 3)
15926 (plus:SI (match_operand:SI 2 "register_operand" "")
15928 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15931 [(set (match_operand:SI 0 "register_operand" "")
15932 (unspec:SI [(match_dup 1) (match_dup 3)
15933 (match_dup 2) (reg:SI SP_REG)]
15935 (clobber (reg:CC FLAGS_REG))])]
15936 "!TARGET_64BIT && TARGET_GNU2_TLS"
15938 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15939 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15942 (define_insn "*tls_dynamic_lea_32"
15943 [(set (match_operand:SI 0 "register_operand" "=r")
15944 (plus:SI (match_operand:SI 1 "register_operand" "b")
15946 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15947 UNSPEC_TLSDESC))))]
15948 "!TARGET_64BIT && TARGET_GNU2_TLS"
15949 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15950 [(set_attr "type" "lea")
15951 (set_attr "mode" "SI")
15952 (set_attr "length" "6")
15953 (set_attr "length_address" "4")])
15955 (define_insn "*tls_dynamic_call_32"
15956 [(set (match_operand:SI 0 "register_operand" "=a")
15957 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15958 (match_operand:SI 2 "register_operand" "0")
15959 ;; we have to make sure %ebx still points to the GOT
15960 (match_operand:SI 3 "register_operand" "b")
15963 (clobber (reg:CC FLAGS_REG))]
15964 "!TARGET_64BIT && TARGET_GNU2_TLS"
15965 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15966 [(set_attr "type" "call")
15967 (set_attr "length" "2")
15968 (set_attr "length_address" "0")])
15970 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15971 [(set (match_operand:SI 0 "register_operand" "=&a")
15973 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15974 (match_operand:SI 4 "" "")
15975 (match_operand:SI 2 "register_operand" "b")
15978 (const:SI (unspec:SI
15979 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15981 (clobber (reg:CC FLAGS_REG))]
15982 "!TARGET_64BIT && TARGET_GNU2_TLS"
15985 [(set (match_dup 0) (match_dup 5))]
15987 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15988 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15991 (define_expand "tls_dynamic_gnu2_64"
15992 [(set (match_dup 2)
15993 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15996 [(set (match_operand:DI 0 "register_operand" "")
15997 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15999 (clobber (reg:CC FLAGS_REG))])]
16000 "TARGET_64BIT && TARGET_GNU2_TLS"
16002 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16003 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16006 (define_insn "*tls_dynamic_lea_64"
16007 [(set (match_operand:DI 0 "register_operand" "=r")
16008 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16010 "TARGET_64BIT && TARGET_GNU2_TLS"
16011 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
16012 [(set_attr "type" "lea")
16013 (set_attr "mode" "DI")
16014 (set_attr "length" "7")
16015 (set_attr "length_address" "4")])
16017 (define_insn "*tls_dynamic_call_64"
16018 [(set (match_operand:DI 0 "register_operand" "=a")
16019 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16020 (match_operand:DI 2 "register_operand" "0")
16023 (clobber (reg:CC FLAGS_REG))]
16024 "TARGET_64BIT && TARGET_GNU2_TLS"
16025 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16026 [(set_attr "type" "call")
16027 (set_attr "length" "2")
16028 (set_attr "length_address" "0")])
16030 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16031 [(set (match_operand:DI 0 "register_operand" "=&a")
16033 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16034 (match_operand:DI 3 "" "")
16037 (const:DI (unspec:DI
16038 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16040 (clobber (reg:CC FLAGS_REG))]
16041 "TARGET_64BIT && TARGET_GNU2_TLS"
16044 [(set (match_dup 0) (match_dup 4))]
16046 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16047 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16052 ;; These patterns match the binary 387 instructions for addM3, subM3,
16053 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16054 ;; SFmode. The first is the normal insn, the second the same insn but
16055 ;; with one operand a conversion, and the third the same insn but with
16056 ;; the other operand a conversion. The conversion may be SFmode or
16057 ;; SImode if the target mode DFmode, but only SImode if the target mode
16060 ;; Gcc is slightly more smart about handling normal two address instructions
16061 ;; so use special patterns for add and mull.
16063 (define_insn "*fop_sf_comm_mixed"
16064 [(set (match_operand:SF 0 "register_operand" "=f,x")
16065 (match_operator:SF 3 "binary_fp_operator"
16066 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
16067 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
16068 "TARGET_MIX_SSE_I387
16069 && COMMUTATIVE_ARITH_P (operands[3])
16070 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16071 "* return output_387_binary_op (insn, operands);"
16072 [(set (attr "type")
16073 (if_then_else (eq_attr "alternative" "1")
16074 (if_then_else (match_operand:SF 3 "mult_operator" "")
16075 (const_string "ssemul")
16076 (const_string "sseadd"))
16077 (if_then_else (match_operand:SF 3 "mult_operator" "")
16078 (const_string "fmul")
16079 (const_string "fop"))))
16080 (set_attr "mode" "SF")])
16082 (define_insn "*fop_sf_comm_sse"
16083 [(set (match_operand:SF 0 "register_operand" "=x")
16084 (match_operator:SF 3 "binary_fp_operator"
16085 [(match_operand:SF 1 "nonimmediate_operand" "%0")
16086 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16088 && COMMUTATIVE_ARITH_P (operands[3])
16089 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16090 "* return output_387_binary_op (insn, operands);"
16091 [(set (attr "type")
16092 (if_then_else (match_operand:SF 3 "mult_operator" "")
16093 (const_string "ssemul")
16094 (const_string "sseadd")))
16095 (set_attr "mode" "SF")])
16097 (define_insn "*fop_sf_comm_i387"
16098 [(set (match_operand:SF 0 "register_operand" "=f")
16099 (match_operator:SF 3 "binary_fp_operator"
16100 [(match_operand:SF 1 "nonimmediate_operand" "%0")
16101 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
16103 && COMMUTATIVE_ARITH_P (operands[3])
16104 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16105 "* return output_387_binary_op (insn, operands);"
16106 [(set (attr "type")
16107 (if_then_else (match_operand:SF 3 "mult_operator" "")
16108 (const_string "fmul")
16109 (const_string "fop")))
16110 (set_attr "mode" "SF")])
16112 (define_insn "*fop_sf_1_mixed"
16113 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
16114 (match_operator:SF 3 "binary_fp_operator"
16115 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
16116 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
16117 "TARGET_MIX_SSE_I387
16118 && !COMMUTATIVE_ARITH_P (operands[3])
16119 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16120 "* return output_387_binary_op (insn, operands);"
16121 [(set (attr "type")
16122 (cond [(and (eq_attr "alternative" "2")
16123 (match_operand:SF 3 "mult_operator" ""))
16124 (const_string "ssemul")
16125 (and (eq_attr "alternative" "2")
16126 (match_operand:SF 3 "div_operator" ""))
16127 (const_string "ssediv")
16128 (eq_attr "alternative" "2")
16129 (const_string "sseadd")
16130 (match_operand:SF 3 "mult_operator" "")
16131 (const_string "fmul")
16132 (match_operand:SF 3 "div_operator" "")
16133 (const_string "fdiv")
16135 (const_string "fop")))
16136 (set_attr "mode" "SF")])
16138 (define_insn "*rcpsf2_sse"
16139 [(set (match_operand:SF 0 "register_operand" "=x")
16140 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16143 "rcpss\t{%1, %0|%0, %1}"
16144 [(set_attr "type" "sse")
16145 (set_attr "mode" "SF")])
16147 (define_insn "*fop_sf_1_sse"
16148 [(set (match_operand:SF 0 "register_operand" "=x")
16149 (match_operator:SF 3 "binary_fp_operator"
16150 [(match_operand:SF 1 "register_operand" "0")
16151 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16153 && !COMMUTATIVE_ARITH_P (operands[3])"
16154 "* return output_387_binary_op (insn, operands);"
16155 [(set (attr "type")
16156 (cond [(match_operand:SF 3 "mult_operator" "")
16157 (const_string "ssemul")
16158 (match_operand:SF 3 "div_operator" "")
16159 (const_string "ssediv")
16161 (const_string "sseadd")))
16162 (set_attr "mode" "SF")])
16164 ;; This pattern is not fully shadowed by the pattern above.
16165 (define_insn "*fop_sf_1_i387"
16166 [(set (match_operand:SF 0 "register_operand" "=f,f")
16167 (match_operator:SF 3 "binary_fp_operator"
16168 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16169 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16170 "TARGET_80387 && !TARGET_SSE_MATH
16171 && !COMMUTATIVE_ARITH_P (operands[3])
16172 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16173 "* return output_387_binary_op (insn, operands);"
16174 [(set (attr "type")
16175 (cond [(match_operand:SF 3 "mult_operator" "")
16176 (const_string "fmul")
16177 (match_operand:SF 3 "div_operator" "")
16178 (const_string "fdiv")
16180 (const_string "fop")))
16181 (set_attr "mode" "SF")])
16183 ;; ??? Add SSE splitters for these!
16184 (define_insn "*fop_sf_2<mode>_i387"
16185 [(set (match_operand:SF 0 "register_operand" "=f,f")
16186 (match_operator:SF 3 "binary_fp_operator"
16187 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16188 (match_operand:SF 2 "register_operand" "0,0")]))]
16189 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16190 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16191 [(set (attr "type")
16192 (cond [(match_operand:SF 3 "mult_operator" "")
16193 (const_string "fmul")
16194 (match_operand:SF 3 "div_operator" "")
16195 (const_string "fdiv")
16197 (const_string "fop")))
16198 (set_attr "fp_int_src" "true")
16199 (set_attr "mode" "<MODE>")])
16201 (define_insn "*fop_sf_3<mode>_i387"
16202 [(set (match_operand:SF 0 "register_operand" "=f,f")
16203 (match_operator:SF 3 "binary_fp_operator"
16204 [(match_operand:SF 1 "register_operand" "0,0")
16205 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16206 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16207 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16208 [(set (attr "type")
16209 (cond [(match_operand:SF 3 "mult_operator" "")
16210 (const_string "fmul")
16211 (match_operand:SF 3 "div_operator" "")
16212 (const_string "fdiv")
16214 (const_string "fop")))
16215 (set_attr "fp_int_src" "true")
16216 (set_attr "mode" "<MODE>")])
16218 (define_insn "*fop_df_comm_mixed"
16219 [(set (match_operand:DF 0 "register_operand" "=f,x")
16220 (match_operator:DF 3 "binary_fp_operator"
16221 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16222 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16223 "TARGET_SSE2 && TARGET_MIX_SSE_I387
16224 && COMMUTATIVE_ARITH_P (operands[3])
16225 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16226 "* return output_387_binary_op (insn, operands);"
16227 [(set (attr "type")
16228 (if_then_else (eq_attr "alternative" "1")
16229 (if_then_else (match_operand:DF 3 "mult_operator" "")
16230 (const_string "ssemul")
16231 (const_string "sseadd"))
16232 (if_then_else (match_operand:DF 3 "mult_operator" "")
16233 (const_string "fmul")
16234 (const_string "fop"))))
16235 (set_attr "mode" "DF")])
16237 (define_insn "*fop_df_comm_sse"
16238 [(set (match_operand:DF 0 "register_operand" "=x")
16239 (match_operator:DF 3 "binary_fp_operator"
16240 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16241 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16242 "TARGET_SSE2 && TARGET_SSE_MATH
16243 && COMMUTATIVE_ARITH_P (operands[3])
16244 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16245 "* return output_387_binary_op (insn, operands);"
16246 [(set (attr "type")
16247 (if_then_else (match_operand:DF 3 "mult_operator" "")
16248 (const_string "ssemul")
16249 (const_string "sseadd")))
16250 (set_attr "mode" "DF")])
16252 (define_insn "*fop_df_comm_i387"
16253 [(set (match_operand:DF 0 "register_operand" "=f")
16254 (match_operator:DF 3 "binary_fp_operator"
16255 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16256 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16258 && COMMUTATIVE_ARITH_P (operands[3])
16259 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16260 "* return output_387_binary_op (insn, operands);"
16261 [(set (attr "type")
16262 (if_then_else (match_operand:DF 3 "mult_operator" "")
16263 (const_string "fmul")
16264 (const_string "fop")))
16265 (set_attr "mode" "DF")])
16267 (define_insn "*fop_df_1_mixed"
16268 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16269 (match_operator:DF 3 "binary_fp_operator"
16270 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16271 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16272 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16273 && !COMMUTATIVE_ARITH_P (operands[3])
16274 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16275 "* return output_387_binary_op (insn, operands);"
16276 [(set (attr "type")
16277 (cond [(and (eq_attr "alternative" "2")
16278 (match_operand:DF 3 "mult_operator" ""))
16279 (const_string "ssemul")
16280 (and (eq_attr "alternative" "2")
16281 (match_operand:DF 3 "div_operator" ""))
16282 (const_string "ssediv")
16283 (eq_attr "alternative" "2")
16284 (const_string "sseadd")
16285 (match_operand:DF 3 "mult_operator" "")
16286 (const_string "fmul")
16287 (match_operand:DF 3 "div_operator" "")
16288 (const_string "fdiv")
16290 (const_string "fop")))
16291 (set_attr "mode" "DF")])
16293 (define_insn "*fop_df_1_sse"
16294 [(set (match_operand:DF 0 "register_operand" "=x")
16295 (match_operator:DF 3 "binary_fp_operator"
16296 [(match_operand:DF 1 "register_operand" "0")
16297 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16298 "TARGET_SSE2 && TARGET_SSE_MATH
16299 && !COMMUTATIVE_ARITH_P (operands[3])"
16300 "* return output_387_binary_op (insn, operands);"
16301 [(set_attr "mode" "DF")
16303 (cond [(match_operand:DF 3 "mult_operator" "")
16304 (const_string "ssemul")
16305 (match_operand:DF 3 "div_operator" "")
16306 (const_string "ssediv")
16308 (const_string "sseadd")))])
16310 ;; This pattern is not fully shadowed by the pattern above.
16311 (define_insn "*fop_df_1_i387"
16312 [(set (match_operand:DF 0 "register_operand" "=f,f")
16313 (match_operator:DF 3 "binary_fp_operator"
16314 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16315 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16316 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16317 && !COMMUTATIVE_ARITH_P (operands[3])
16318 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16319 "* return output_387_binary_op (insn, operands);"
16320 [(set (attr "type")
16321 (cond [(match_operand:DF 3 "mult_operator" "")
16322 (const_string "fmul")
16323 (match_operand:DF 3 "div_operator" "")
16324 (const_string "fdiv")
16326 (const_string "fop")))
16327 (set_attr "mode" "DF")])
16329 ;; ??? Add SSE splitters for these!
16330 (define_insn "*fop_df_2<mode>_i387"
16331 [(set (match_operand:DF 0 "register_operand" "=f,f")
16332 (match_operator:DF 3 "binary_fp_operator"
16333 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16334 (match_operand:DF 2 "register_operand" "0,0")]))]
16335 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16336 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16337 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16338 [(set (attr "type")
16339 (cond [(match_operand:DF 3 "mult_operator" "")
16340 (const_string "fmul")
16341 (match_operand:DF 3 "div_operator" "")
16342 (const_string "fdiv")
16344 (const_string "fop")))
16345 (set_attr "fp_int_src" "true")
16346 (set_attr "mode" "<MODE>")])
16348 (define_insn "*fop_df_3<mode>_i387"
16349 [(set (match_operand:DF 0 "register_operand" "=f,f")
16350 (match_operator:DF 3 "binary_fp_operator"
16351 [(match_operand:DF 1 "register_operand" "0,0")
16352 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16353 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16354 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16355 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16356 [(set (attr "type")
16357 (cond [(match_operand:DF 3 "mult_operator" "")
16358 (const_string "fmul")
16359 (match_operand:DF 3 "div_operator" "")
16360 (const_string "fdiv")
16362 (const_string "fop")))
16363 (set_attr "fp_int_src" "true")
16364 (set_attr "mode" "<MODE>")])
16366 (define_insn "*fop_df_4_i387"
16367 [(set (match_operand:DF 0 "register_operand" "=f,f")
16368 (match_operator:DF 3 "binary_fp_operator"
16369 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16370 (match_operand:DF 2 "register_operand" "0,f")]))]
16371 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16372 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16373 "* return output_387_binary_op (insn, operands);"
16374 [(set (attr "type")
16375 (cond [(match_operand:DF 3 "mult_operator" "")
16376 (const_string "fmul")
16377 (match_operand:DF 3 "div_operator" "")
16378 (const_string "fdiv")
16380 (const_string "fop")))
16381 (set_attr "mode" "SF")])
16383 (define_insn "*fop_df_5_i387"
16384 [(set (match_operand:DF 0 "register_operand" "=f,f")
16385 (match_operator:DF 3 "binary_fp_operator"
16386 [(match_operand:DF 1 "register_operand" "0,f")
16388 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16389 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16390 "* return output_387_binary_op (insn, operands);"
16391 [(set (attr "type")
16392 (cond [(match_operand:DF 3 "mult_operator" "")
16393 (const_string "fmul")
16394 (match_operand:DF 3 "div_operator" "")
16395 (const_string "fdiv")
16397 (const_string "fop")))
16398 (set_attr "mode" "SF")])
16400 (define_insn "*fop_df_6_i387"
16401 [(set (match_operand:DF 0 "register_operand" "=f,f")
16402 (match_operator:DF 3 "binary_fp_operator"
16404 (match_operand:SF 1 "register_operand" "0,f"))
16406 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16407 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16408 "* return output_387_binary_op (insn, operands);"
16409 [(set (attr "type")
16410 (cond [(match_operand:DF 3 "mult_operator" "")
16411 (const_string "fmul")
16412 (match_operand:DF 3 "div_operator" "")
16413 (const_string "fdiv")
16415 (const_string "fop")))
16416 (set_attr "mode" "SF")])
16418 (define_insn "*fop_xf_comm_i387"
16419 [(set (match_operand:XF 0 "register_operand" "=f")
16420 (match_operator:XF 3 "binary_fp_operator"
16421 [(match_operand:XF 1 "register_operand" "%0")
16422 (match_operand:XF 2 "register_operand" "f")]))]
16424 && COMMUTATIVE_ARITH_P (operands[3])"
16425 "* return output_387_binary_op (insn, operands);"
16426 [(set (attr "type")
16427 (if_then_else (match_operand:XF 3 "mult_operator" "")
16428 (const_string "fmul")
16429 (const_string "fop")))
16430 (set_attr "mode" "XF")])
16432 (define_insn "*fop_xf_1_i387"
16433 [(set (match_operand:XF 0 "register_operand" "=f,f")
16434 (match_operator:XF 3 "binary_fp_operator"
16435 [(match_operand:XF 1 "register_operand" "0,f")
16436 (match_operand:XF 2 "register_operand" "f,0")]))]
16438 && !COMMUTATIVE_ARITH_P (operands[3])"
16439 "* return output_387_binary_op (insn, operands);"
16440 [(set (attr "type")
16441 (cond [(match_operand:XF 3 "mult_operator" "")
16442 (const_string "fmul")
16443 (match_operand:XF 3 "div_operator" "")
16444 (const_string "fdiv")
16446 (const_string "fop")))
16447 (set_attr "mode" "XF")])
16449 (define_insn "*fop_xf_2<mode>_i387"
16450 [(set (match_operand:XF 0 "register_operand" "=f,f")
16451 (match_operator:XF 3 "binary_fp_operator"
16452 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16453 (match_operand:XF 2 "register_operand" "0,0")]))]
16454 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16455 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16456 [(set (attr "type")
16457 (cond [(match_operand:XF 3 "mult_operator" "")
16458 (const_string "fmul")
16459 (match_operand:XF 3 "div_operator" "")
16460 (const_string "fdiv")
16462 (const_string "fop")))
16463 (set_attr "fp_int_src" "true")
16464 (set_attr "mode" "<MODE>")])
16466 (define_insn "*fop_xf_3<mode>_i387"
16467 [(set (match_operand:XF 0 "register_operand" "=f,f")
16468 (match_operator:XF 3 "binary_fp_operator"
16469 [(match_operand:XF 1 "register_operand" "0,0")
16470 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16471 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16472 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16473 [(set (attr "type")
16474 (cond [(match_operand:XF 3 "mult_operator" "")
16475 (const_string "fmul")
16476 (match_operand:XF 3 "div_operator" "")
16477 (const_string "fdiv")
16479 (const_string "fop")))
16480 (set_attr "fp_int_src" "true")
16481 (set_attr "mode" "<MODE>")])
16483 (define_insn "*fop_xf_4_i387"
16484 [(set (match_operand:XF 0 "register_operand" "=f,f")
16485 (match_operator:XF 3 "binary_fp_operator"
16487 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16488 (match_operand:XF 2 "register_operand" "0,f")]))]
16490 "* return output_387_binary_op (insn, operands);"
16491 [(set (attr "type")
16492 (cond [(match_operand:XF 3 "mult_operator" "")
16493 (const_string "fmul")
16494 (match_operand:XF 3 "div_operator" "")
16495 (const_string "fdiv")
16497 (const_string "fop")))
16498 (set_attr "mode" "SF")])
16500 (define_insn "*fop_xf_5_i387"
16501 [(set (match_operand:XF 0 "register_operand" "=f,f")
16502 (match_operator:XF 3 "binary_fp_operator"
16503 [(match_operand:XF 1 "register_operand" "0,f")
16505 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16507 "* return output_387_binary_op (insn, operands);"
16508 [(set (attr "type")
16509 (cond [(match_operand:XF 3 "mult_operator" "")
16510 (const_string "fmul")
16511 (match_operand:XF 3 "div_operator" "")
16512 (const_string "fdiv")
16514 (const_string "fop")))
16515 (set_attr "mode" "SF")])
16517 (define_insn "*fop_xf_6_i387"
16518 [(set (match_operand:XF 0 "register_operand" "=f,f")
16519 (match_operator:XF 3 "binary_fp_operator"
16521 (match_operand:MODEF 1 "register_operand" "0,f"))
16523 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16525 "* return output_387_binary_op (insn, operands);"
16526 [(set (attr "type")
16527 (cond [(match_operand:XF 3 "mult_operator" "")
16528 (const_string "fmul")
16529 (match_operand:XF 3 "div_operator" "")
16530 (const_string "fdiv")
16532 (const_string "fop")))
16533 (set_attr "mode" "SF")])
16536 [(set (match_operand 0 "register_operand" "")
16537 (match_operator 3 "binary_fp_operator"
16538 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16539 (match_operand 2 "register_operand" "")]))]
16541 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16544 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16545 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16546 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16547 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16548 GET_MODE (operands[3]),
16551 ix86_free_from_memory (GET_MODE (operands[1]));
16556 [(set (match_operand 0 "register_operand" "")
16557 (match_operator 3 "binary_fp_operator"
16558 [(match_operand 1 "register_operand" "")
16559 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16561 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16564 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16565 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16566 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16567 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16568 GET_MODE (operands[3]),
16571 ix86_free_from_memory (GET_MODE (operands[2]));
16575 ;; FPU special functions.
16577 ;; This pattern implements a no-op XFmode truncation for
16578 ;; all fancy i386 XFmode math functions.
16580 (define_insn "truncxf<mode>2_i387_noop_unspec"
16581 [(set (match_operand:MODEF 0 "register_operand" "=f")
16582 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16583 UNSPEC_TRUNC_NOOP))]
16584 "TARGET_USE_FANCY_MATH_387"
16585 "* return output_387_reg_move (insn, operands);"
16586 [(set_attr "type" "fmov")
16587 (set_attr "mode" "<MODE>")])
16589 (define_insn "sqrtxf2"
16590 [(set (match_operand:XF 0 "register_operand" "=f")
16591 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16592 "TARGET_USE_FANCY_MATH_387"
16594 [(set_attr "type" "fpspc")
16595 (set_attr "mode" "XF")
16596 (set_attr "athlon_decode" "direct")
16597 (set_attr "amdfam10_decode" "direct")])
16599 (define_insn "sqrt_extend<mode>xf2_i387"
16600 [(set (match_operand:XF 0 "register_operand" "=f")
16603 (match_operand:MODEF 1 "register_operand" "0"))))]
16604 "TARGET_USE_FANCY_MATH_387"
16606 [(set_attr "type" "fpspc")
16607 (set_attr "mode" "XF")
16608 (set_attr "athlon_decode" "direct")
16609 (set_attr "amdfam10_decode" "direct")])
16611 (define_insn "*rsqrtsf2_sse"
16612 [(set (match_operand:SF 0 "register_operand" "=x")
16613 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16616 "rsqrtss\t{%1, %0|%0, %1}"
16617 [(set_attr "type" "sse")
16618 (set_attr "mode" "SF")])
16620 (define_expand "rsqrtsf2"
16621 [(set (match_operand:SF 0 "register_operand" "")
16622 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16624 "TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16625 && flag_finite_math_only && !flag_trapping_math
16626 && flag_unsafe_math_optimizations"
16628 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16632 (define_insn "*sqrt<mode>2_sse"
16633 [(set (match_operand:MODEF 0 "register_operand" "=x")
16635 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16636 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16637 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16638 [(set_attr "type" "sse")
16639 (set_attr "mode" "<MODE>")
16640 (set_attr "athlon_decode" "*")
16641 (set_attr "amdfam10_decode" "*")])
16643 (define_expand "sqrt<mode>2"
16644 [(set (match_operand:MODEF 0 "register_operand" "")
16646 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16647 "TARGET_USE_FANCY_MATH_387
16648 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16650 if (<MODE>mode == SFmode
16651 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16652 && flag_finite_math_only && !flag_trapping_math
16653 && flag_unsafe_math_optimizations)
16655 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16659 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16661 rtx op0 = gen_reg_rtx (XFmode);
16662 rtx op1 = force_reg (<MODE>mode, operands[1]);
16664 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16665 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16670 (define_insn "fpremxf4_i387"
16671 [(set (match_operand:XF 0 "register_operand" "=f")
16672 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16673 (match_operand:XF 3 "register_operand" "1")]
16675 (set (match_operand:XF 1 "register_operand" "=u")
16676 (unspec:XF [(match_dup 2) (match_dup 3)]
16678 (set (reg:CCFP FPSR_REG)
16679 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16681 "TARGET_USE_FANCY_MATH_387"
16683 [(set_attr "type" "fpspc")
16684 (set_attr "mode" "XF")])
16686 (define_expand "fmodxf3"
16687 [(use (match_operand:XF 0 "register_operand" ""))
16688 (use (match_operand:XF 1 "register_operand" ""))
16689 (use (match_operand:XF 2 "register_operand" ""))]
16690 "TARGET_USE_FANCY_MATH_387"
16692 rtx label = gen_label_rtx ();
16696 if (rtx_equal_p (operands[1], operands[2]))
16698 op2 = gen_reg_rtx (XFmode);
16699 emit_move_insn (op2, operands[2]);
16704 emit_label (label);
16705 emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16706 ix86_emit_fp_unordered_jump (label);
16707 LABEL_NUSES (label) = 1;
16709 emit_move_insn (operands[0], operands[1]);
16713 (define_expand "fmod<mode>3"
16714 [(use (match_operand:MODEF 0 "register_operand" ""))
16715 (use (match_operand:MODEF 1 "general_operand" ""))
16716 (use (match_operand:MODEF 2 "general_operand" ""))]
16717 "TARGET_USE_FANCY_MATH_387"
16719 rtx label = gen_label_rtx ();
16721 rtx op1 = gen_reg_rtx (XFmode);
16722 rtx op2 = gen_reg_rtx (XFmode);
16724 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16725 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16727 emit_label (label);
16728 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16729 ix86_emit_fp_unordered_jump (label);
16730 LABEL_NUSES (label) = 1;
16732 /* Truncate the result properly for strict SSE math. */
16733 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16734 && !TARGET_MIX_SSE_I387)
16735 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16737 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16742 (define_insn "fprem1xf4_i387"
16743 [(set (match_operand:XF 0 "register_operand" "=f")
16744 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16745 (match_operand:XF 3 "register_operand" "1")]
16747 (set (match_operand:XF 1 "register_operand" "=u")
16748 (unspec:XF [(match_dup 2) (match_dup 3)]
16750 (set (reg:CCFP FPSR_REG)
16751 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16753 "TARGET_USE_FANCY_MATH_387"
16755 [(set_attr "type" "fpspc")
16756 (set_attr "mode" "XF")])
16758 (define_expand "remainderxf3"
16759 [(use (match_operand:XF 0 "register_operand" ""))
16760 (use (match_operand:XF 1 "register_operand" ""))
16761 (use (match_operand:XF 2 "register_operand" ""))]
16762 "TARGET_USE_FANCY_MATH_387"
16764 rtx label = gen_label_rtx ();
16768 if (rtx_equal_p (operands[1], operands[2]))
16770 op2 = gen_reg_rtx (XFmode);
16771 emit_move_insn (op2, operands[2]);
16776 emit_label (label);
16777 emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16778 ix86_emit_fp_unordered_jump (label);
16779 LABEL_NUSES (label) = 1;
16781 emit_move_insn (operands[0], operands[1]);
16785 (define_expand "remainder<mode>3"
16786 [(use (match_operand:MODEF 0 "register_operand" ""))
16787 (use (match_operand:MODEF 1 "general_operand" ""))
16788 (use (match_operand:MODEF 2 "general_operand" ""))]
16789 "TARGET_USE_FANCY_MATH_387"
16791 rtx label = gen_label_rtx ();
16793 rtx op1 = gen_reg_rtx (XFmode);
16794 rtx op2 = gen_reg_rtx (XFmode);
16796 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16797 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16799 emit_label (label);
16801 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16802 ix86_emit_fp_unordered_jump (label);
16803 LABEL_NUSES (label) = 1;
16805 /* Truncate the result properly for strict SSE math. */
16806 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16807 && !TARGET_MIX_SSE_I387)
16808 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16810 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16815 (define_insn "*sinxf2_i387"
16816 [(set (match_operand:XF 0 "register_operand" "=f")
16817 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16818 "TARGET_USE_FANCY_MATH_387
16819 && flag_unsafe_math_optimizations"
16821 [(set_attr "type" "fpspc")
16822 (set_attr "mode" "XF")])
16824 (define_insn "*sin_extend<mode>xf2_i387"
16825 [(set (match_operand:XF 0 "register_operand" "=f")
16826 (unspec:XF [(float_extend:XF
16827 (match_operand:MODEF 1 "register_operand" "0"))]
16829 "TARGET_USE_FANCY_MATH_387
16830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16831 || TARGET_MIX_SSE_I387)
16832 && flag_unsafe_math_optimizations"
16834 [(set_attr "type" "fpspc")
16835 (set_attr "mode" "XF")])
16837 (define_insn "*cosxf2_i387"
16838 [(set (match_operand:XF 0 "register_operand" "=f")
16839 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16840 "TARGET_USE_FANCY_MATH_387
16841 && flag_unsafe_math_optimizations"
16843 [(set_attr "type" "fpspc")
16844 (set_attr "mode" "XF")])
16846 (define_insn "*cos_extend<mode>xf2_i387"
16847 [(set (match_operand:XF 0 "register_operand" "=f")
16848 (unspec:XF [(float_extend:XF
16849 (match_operand:MODEF 1 "register_operand" "0"))]
16851 "TARGET_USE_FANCY_MATH_387
16852 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16853 || TARGET_MIX_SSE_I387)
16854 && flag_unsafe_math_optimizations"
16856 [(set_attr "type" "fpspc")
16857 (set_attr "mode" "XF")])
16859 ;; When sincos pattern is defined, sin and cos builtin functions will be
16860 ;; expanded to sincos pattern with one of its outputs left unused.
16861 ;; CSE pass will figure out if two sincos patterns can be combined,
16862 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16863 ;; depending on the unused output.
16865 (define_insn "sincosxf3"
16866 [(set (match_operand:XF 0 "register_operand" "=f")
16867 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16868 UNSPEC_SINCOS_COS))
16869 (set (match_operand:XF 1 "register_operand" "=u")
16870 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16871 "TARGET_USE_FANCY_MATH_387
16872 && flag_unsafe_math_optimizations"
16874 [(set_attr "type" "fpspc")
16875 (set_attr "mode" "XF")])
16878 [(set (match_operand:XF 0 "register_operand" "")
16879 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16880 UNSPEC_SINCOS_COS))
16881 (set (match_operand:XF 1 "register_operand" "")
16882 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16883 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16884 && !(reload_completed || reload_in_progress)"
16885 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16889 [(set (match_operand:XF 0 "register_operand" "")
16890 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16891 UNSPEC_SINCOS_COS))
16892 (set (match_operand:XF 1 "register_operand" "")
16893 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16894 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16895 && !(reload_completed || reload_in_progress)"
16896 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16899 (define_insn "sincos_extend<mode>xf3_i387"
16900 [(set (match_operand:XF 0 "register_operand" "=f")
16901 (unspec:XF [(float_extend:XF
16902 (match_operand:MODEF 2 "register_operand" "0"))]
16903 UNSPEC_SINCOS_COS))
16904 (set (match_operand:XF 1 "register_operand" "=u")
16905 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16906 "TARGET_USE_FANCY_MATH_387
16907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16908 || TARGET_MIX_SSE_I387)
16909 && flag_unsafe_math_optimizations"
16911 [(set_attr "type" "fpspc")
16912 (set_attr "mode" "XF")])
16915 [(set (match_operand:XF 0 "register_operand" "")
16916 (unspec:XF [(float_extend:XF
16917 (match_operand:MODEF 2 "register_operand" ""))]
16918 UNSPEC_SINCOS_COS))
16919 (set (match_operand:XF 1 "register_operand" "")
16920 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16921 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16922 && !(reload_completed || reload_in_progress)"
16923 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16927 [(set (match_operand:XF 0 "register_operand" "")
16928 (unspec:XF [(float_extend:XF
16929 (match_operand:MODEF 2 "register_operand" ""))]
16930 UNSPEC_SINCOS_COS))
16931 (set (match_operand:XF 1 "register_operand" "")
16932 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16933 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16934 && !(reload_completed || reload_in_progress)"
16935 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16938 (define_expand "sincos<mode>3"
16939 [(use (match_operand:MODEF 0 "register_operand" ""))
16940 (use (match_operand:MODEF 1 "register_operand" ""))
16941 (use (match_operand:MODEF 2 "register_operand" ""))]
16942 "TARGET_USE_FANCY_MATH_387
16943 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16944 || TARGET_MIX_SSE_I387)
16945 && flag_unsafe_math_optimizations"
16947 rtx op0 = gen_reg_rtx (XFmode);
16948 rtx op1 = gen_reg_rtx (XFmode);
16950 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16951 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16952 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16956 (define_insn "fptanxf4_i387"
16957 [(set (match_operand:XF 0 "register_operand" "=f")
16958 (match_operand:XF 3 "const_double_operand" "F"))
16959 (set (match_operand:XF 1 "register_operand" "=u")
16960 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16962 "TARGET_USE_FANCY_MATH_387
16963 && flag_unsafe_math_optimizations
16964 && standard_80387_constant_p (operands[3]) == 2"
16966 [(set_attr "type" "fpspc")
16967 (set_attr "mode" "XF")])
16969 (define_insn "fptan_extend<mode>xf4_i387"
16970 [(set (match_operand:MODEF 0 "register_operand" "=f")
16971 (match_operand:MODEF 3 "const_double_operand" "F"))
16972 (set (match_operand:XF 1 "register_operand" "=u")
16973 (unspec:XF [(float_extend:XF
16974 (match_operand:MODEF 2 "register_operand" "0"))]
16976 "TARGET_USE_FANCY_MATH_387
16977 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16978 || TARGET_MIX_SSE_I387)
16979 && flag_unsafe_math_optimizations
16980 && standard_80387_constant_p (operands[3]) == 2"
16982 [(set_attr "type" "fpspc")
16983 (set_attr "mode" "XF")])
16985 (define_expand "tanxf2"
16986 [(use (match_operand:XF 0 "register_operand" ""))
16987 (use (match_operand:XF 1 "register_operand" ""))]
16988 "TARGET_USE_FANCY_MATH_387
16989 && flag_unsafe_math_optimizations"
16991 rtx one = gen_reg_rtx (XFmode);
16992 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16994 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16998 (define_expand "tan<mode>2"
16999 [(use (match_operand:MODEF 0 "register_operand" ""))
17000 (use (match_operand:MODEF 1 "register_operand" ""))]
17001 "TARGET_USE_FANCY_MATH_387
17002 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17003 || TARGET_MIX_SSE_I387)
17004 && flag_unsafe_math_optimizations"
17006 rtx op0 = gen_reg_rtx (XFmode);
17008 rtx one = gen_reg_rtx (<MODE>mode);
17009 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17011 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17012 operands[1], op2));
17013 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17017 (define_insn "*fpatanxf3_i387"
17018 [(set (match_operand:XF 0 "register_operand" "=f")
17019 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17020 (match_operand:XF 2 "register_operand" "u")]
17022 (clobber (match_scratch:XF 3 "=2"))]
17023 "TARGET_USE_FANCY_MATH_387
17024 && flag_unsafe_math_optimizations"
17026 [(set_attr "type" "fpspc")
17027 (set_attr "mode" "XF")])
17029 (define_insn "fpatan_extend<mode>xf3_i387"
17030 [(set (match_operand:XF 0 "register_operand" "=f")
17031 (unspec:XF [(float_extend:XF
17032 (match_operand:MODEF 1 "register_operand" "0"))
17034 (match_operand:MODEF 2 "register_operand" "u"))]
17036 (clobber (match_scratch:XF 3 "=2"))]
17037 "TARGET_USE_FANCY_MATH_387
17038 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17039 || TARGET_MIX_SSE_I387)
17040 && flag_unsafe_math_optimizations"
17042 [(set_attr "type" "fpspc")
17043 (set_attr "mode" "XF")])
17045 (define_expand "atan2xf3"
17046 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17047 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17048 (match_operand:XF 1 "register_operand" "")]
17050 (clobber (match_scratch:XF 3 ""))])]
17051 "TARGET_USE_FANCY_MATH_387
17052 && flag_unsafe_math_optimizations"
17055 (define_expand "atan2<mode>3"
17056 [(use (match_operand:MODEF 0 "register_operand" ""))
17057 (use (match_operand:MODEF 1 "register_operand" ""))
17058 (use (match_operand:MODEF 2 "register_operand" ""))]
17059 "TARGET_USE_FANCY_MATH_387
17060 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17061 || TARGET_MIX_SSE_I387)
17062 && flag_unsafe_math_optimizations"
17064 rtx op0 = gen_reg_rtx (XFmode);
17066 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17067 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17071 (define_expand "atanxf2"
17072 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17073 (unspec:XF [(match_dup 2)
17074 (match_operand:XF 1 "register_operand" "")]
17076 (clobber (match_scratch:XF 3 ""))])]
17077 "TARGET_USE_FANCY_MATH_387
17078 && flag_unsafe_math_optimizations"
17080 operands[2] = gen_reg_rtx (XFmode);
17081 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17084 (define_expand "atan<mode>2"
17085 [(use (match_operand:MODEF 0 "register_operand" ""))
17086 (use (match_operand:MODEF 1 "register_operand" ""))]
17087 "TARGET_USE_FANCY_MATH_387
17088 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17089 || TARGET_MIX_SSE_I387)
17090 && flag_unsafe_math_optimizations"
17092 rtx op0 = gen_reg_rtx (XFmode);
17094 rtx op2 = gen_reg_rtx (<MODE>mode);
17095 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17097 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17098 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17102 (define_expand "asinxf2"
17103 [(set (match_dup 2)
17104 (mult:XF (match_operand:XF 1 "register_operand" "")
17106 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17107 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17108 (parallel [(set (match_operand:XF 0 "register_operand" "")
17109 (unspec:XF [(match_dup 5) (match_dup 1)]
17111 (clobber (match_scratch:XF 6 ""))])]
17112 "TARGET_USE_FANCY_MATH_387
17113 && flag_unsafe_math_optimizations && !optimize_size"
17117 for (i = 2; i < 6; i++)
17118 operands[i] = gen_reg_rtx (XFmode);
17120 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17123 (define_expand "asin<mode>2"
17124 [(use (match_operand:MODEF 0 "register_operand" ""))
17125 (use (match_operand:MODEF 1 "general_operand" ""))]
17126 "TARGET_USE_FANCY_MATH_387
17127 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17128 || TARGET_MIX_SSE_I387)
17129 && flag_unsafe_math_optimizations && !optimize_size"
17131 rtx op0 = gen_reg_rtx (XFmode);
17132 rtx op1 = gen_reg_rtx (XFmode);
17134 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17135 emit_insn (gen_asinxf2 (op0, op1));
17136 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17140 (define_expand "acosxf2"
17141 [(set (match_dup 2)
17142 (mult:XF (match_operand:XF 1 "register_operand" "")
17144 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17145 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17146 (parallel [(set (match_operand:XF 0 "register_operand" "")
17147 (unspec:XF [(match_dup 1) (match_dup 5)]
17149 (clobber (match_scratch:XF 6 ""))])]
17150 "TARGET_USE_FANCY_MATH_387
17151 && flag_unsafe_math_optimizations && !optimize_size"
17155 for (i = 2; i < 6; i++)
17156 operands[i] = gen_reg_rtx (XFmode);
17158 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17161 (define_expand "acos<mode>2"
17162 [(use (match_operand:MODEF 0 "register_operand" ""))
17163 (use (match_operand:MODEF 1 "general_operand" ""))]
17164 "TARGET_USE_FANCY_MATH_387
17165 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17166 || TARGET_MIX_SSE_I387)
17167 && flag_unsafe_math_optimizations && !optimize_size"
17169 rtx op0 = gen_reg_rtx (XFmode);
17170 rtx op1 = gen_reg_rtx (XFmode);
17172 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17173 emit_insn (gen_acosxf2 (op0, op1));
17174 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17178 (define_insn "fyl2xxf3_i387"
17179 [(set (match_operand:XF 0 "register_operand" "=f")
17180 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17181 (match_operand:XF 2 "register_operand" "u")]
17183 (clobber (match_scratch:XF 3 "=2"))]
17184 "TARGET_USE_FANCY_MATH_387
17185 && flag_unsafe_math_optimizations"
17187 [(set_attr "type" "fpspc")
17188 (set_attr "mode" "XF")])
17190 (define_insn "fyl2x_extend<mode>xf3_i387"
17191 [(set (match_operand:XF 0 "register_operand" "=f")
17192 (unspec:XF [(float_extend:XF
17193 (match_operand:MODEF 1 "register_operand" "0"))
17194 (match_operand:XF 2 "register_operand" "u")]
17196 (clobber (match_scratch:XF 3 "=2"))]
17197 "TARGET_USE_FANCY_MATH_387
17198 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17199 || TARGET_MIX_SSE_I387)
17200 && flag_unsafe_math_optimizations"
17202 [(set_attr "type" "fpspc")
17203 (set_attr "mode" "XF")])
17205 (define_expand "logxf2"
17206 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17207 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17208 (match_dup 2)] UNSPEC_FYL2X))
17209 (clobber (match_scratch:XF 3 ""))])]
17210 "TARGET_USE_FANCY_MATH_387
17211 && flag_unsafe_math_optimizations"
17213 operands[2] = gen_reg_rtx (XFmode);
17214 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17217 (define_expand "log<mode>2"
17218 [(use (match_operand:MODEF 0 "register_operand" ""))
17219 (use (match_operand:MODEF 1 "register_operand" ""))]
17220 "TARGET_USE_FANCY_MATH_387
17221 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17222 || TARGET_MIX_SSE_I387)
17223 && flag_unsafe_math_optimizations"
17225 rtx op0 = gen_reg_rtx (XFmode);
17227 rtx op2 = gen_reg_rtx (XFmode);
17228 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17230 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17231 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17235 (define_expand "log10xf2"
17236 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17237 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17238 (match_dup 2)] UNSPEC_FYL2X))
17239 (clobber (match_scratch:XF 3 ""))])]
17240 "TARGET_USE_FANCY_MATH_387
17241 && flag_unsafe_math_optimizations"
17243 operands[2] = gen_reg_rtx (XFmode);
17244 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17247 (define_expand "log10<mode>2"
17248 [(use (match_operand:MODEF 0 "register_operand" ""))
17249 (use (match_operand:MODEF 1 "register_operand" ""))]
17250 "TARGET_USE_FANCY_MATH_387
17251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17252 || TARGET_MIX_SSE_I387)
17253 && flag_unsafe_math_optimizations"
17255 rtx op0 = gen_reg_rtx (XFmode);
17257 rtx op2 = gen_reg_rtx (XFmode);
17258 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17260 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17261 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17265 (define_expand "log2xf2"
17266 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17267 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17268 (match_dup 2)] UNSPEC_FYL2X))
17269 (clobber (match_scratch:XF 3 ""))])]
17270 "TARGET_USE_FANCY_MATH_387
17271 && flag_unsafe_math_optimizations"
17273 operands[2] = gen_reg_rtx (XFmode);
17274 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17277 (define_expand "log2<mode>2"
17278 [(use (match_operand:MODEF 0 "register_operand" ""))
17279 (use (match_operand:MODEF 1 "register_operand" ""))]
17280 "TARGET_USE_FANCY_MATH_387
17281 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17282 || TARGET_MIX_SSE_I387)
17283 && flag_unsafe_math_optimizations"
17285 rtx op0 = gen_reg_rtx (XFmode);
17287 rtx op2 = gen_reg_rtx (XFmode);
17288 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17290 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17291 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17295 (define_insn "fyl2xp1xf3_i387"
17296 [(set (match_operand:XF 0 "register_operand" "=f")
17297 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17298 (match_operand:XF 2 "register_operand" "u")]
17300 (clobber (match_scratch:XF 3 "=2"))]
17301 "TARGET_USE_FANCY_MATH_387
17302 && flag_unsafe_math_optimizations"
17304 [(set_attr "type" "fpspc")
17305 (set_attr "mode" "XF")])
17307 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17308 [(set (match_operand:XF 0 "register_operand" "=f")
17309 (unspec:XF [(float_extend:XF
17310 (match_operand:MODEF 1 "register_operand" "0"))
17311 (match_operand:XF 2 "register_operand" "u")]
17313 (clobber (match_scratch:XF 3 "=2"))]
17314 "TARGET_USE_FANCY_MATH_387
17315 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17316 || TARGET_MIX_SSE_I387)
17317 && flag_unsafe_math_optimizations"
17319 [(set_attr "type" "fpspc")
17320 (set_attr "mode" "XF")])
17322 (define_expand "log1pxf2"
17323 [(use (match_operand:XF 0 "register_operand" ""))
17324 (use (match_operand:XF 1 "register_operand" ""))]
17325 "TARGET_USE_FANCY_MATH_387
17326 && flag_unsafe_math_optimizations && !optimize_size"
17328 ix86_emit_i387_log1p (operands[0], operands[1]);
17332 (define_expand "log1p<mode>2"
17333 [(use (match_operand:MODEF 0 "register_operand" ""))
17334 (use (match_operand:MODEF 1 "register_operand" ""))]
17335 "TARGET_USE_FANCY_MATH_387
17336 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17337 || TARGET_MIX_SSE_I387)
17338 && flag_unsafe_math_optimizations && !optimize_size"
17340 rtx op0 = gen_reg_rtx (XFmode);
17342 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17344 ix86_emit_i387_log1p (op0, operands[1]);
17345 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17349 (define_insn "fxtractxf3_i387"
17350 [(set (match_operand:XF 0 "register_operand" "=f")
17351 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17352 UNSPEC_XTRACT_FRACT))
17353 (set (match_operand:XF 1 "register_operand" "=u")
17354 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17355 "TARGET_USE_FANCY_MATH_387
17356 && flag_unsafe_math_optimizations"
17358 [(set_attr "type" "fpspc")
17359 (set_attr "mode" "XF")])
17361 (define_insn "fxtract_extend<mode>xf3_i387"
17362 [(set (match_operand:XF 0 "register_operand" "=f")
17363 (unspec:XF [(float_extend:XF
17364 (match_operand:MODEF 2 "register_operand" "0"))]
17365 UNSPEC_XTRACT_FRACT))
17366 (set (match_operand:XF 1 "register_operand" "=u")
17367 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17368 "TARGET_USE_FANCY_MATH_387
17369 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17370 || TARGET_MIX_SSE_I387)
17371 && flag_unsafe_math_optimizations"
17373 [(set_attr "type" "fpspc")
17374 (set_attr "mode" "XF")])
17376 (define_expand "logbxf2"
17377 [(parallel [(set (match_dup 2)
17378 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17379 UNSPEC_XTRACT_FRACT))
17380 (set (match_operand:XF 0 "register_operand" "")
17381 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17382 "TARGET_USE_FANCY_MATH_387
17383 && flag_unsafe_math_optimizations"
17385 operands[2] = gen_reg_rtx (XFmode);
17388 (define_expand "logb<mode>2"
17389 [(use (match_operand:MODEF 0 "register_operand" ""))
17390 (use (match_operand:MODEF 1 "register_operand" ""))]
17391 "TARGET_USE_FANCY_MATH_387
17392 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17393 || TARGET_MIX_SSE_I387)
17394 && flag_unsafe_math_optimizations"
17396 rtx op0 = gen_reg_rtx (XFmode);
17397 rtx op1 = gen_reg_rtx (XFmode);
17399 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17400 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17404 (define_expand "ilogbxf2"
17405 [(use (match_operand:SI 0 "register_operand" ""))
17406 (use (match_operand:XF 1 "register_operand" ""))]
17407 "TARGET_USE_FANCY_MATH_387
17408 && flag_unsafe_math_optimizations && !optimize_size"
17410 rtx op0 = gen_reg_rtx (XFmode);
17411 rtx op1 = gen_reg_rtx (XFmode);
17413 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17414 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17418 (define_expand "ilogb<mode>2"
17419 [(use (match_operand:SI 0 "register_operand" ""))
17420 (use (match_operand:MODEF 1 "register_operand" ""))]
17421 "TARGET_USE_FANCY_MATH_387
17422 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17423 || TARGET_MIX_SSE_I387)
17424 && flag_unsafe_math_optimizations && !optimize_size"
17426 rtx op0 = gen_reg_rtx (XFmode);
17427 rtx op1 = gen_reg_rtx (XFmode);
17429 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17430 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17434 (define_insn "*f2xm1xf2_i387"
17435 [(set (match_operand:XF 0 "register_operand" "=f")
17436 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17438 "TARGET_USE_FANCY_MATH_387
17439 && flag_unsafe_math_optimizations"
17441 [(set_attr "type" "fpspc")
17442 (set_attr "mode" "XF")])
17444 (define_insn "*fscalexf4_i387"
17445 [(set (match_operand:XF 0 "register_operand" "=f")
17446 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17447 (match_operand:XF 3 "register_operand" "1")]
17448 UNSPEC_FSCALE_FRACT))
17449 (set (match_operand:XF 1 "register_operand" "=u")
17450 (unspec:XF [(match_dup 2) (match_dup 3)]
17451 UNSPEC_FSCALE_EXP))]
17452 "TARGET_USE_FANCY_MATH_387
17453 && flag_unsafe_math_optimizations"
17455 [(set_attr "type" "fpspc")
17456 (set_attr "mode" "XF")])
17458 (define_expand "expNcorexf3"
17459 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17460 (match_operand:XF 2 "register_operand" "")))
17461 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17462 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17463 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17464 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17465 (parallel [(set (match_operand:XF 0 "register_operand" "")
17466 (unspec:XF [(match_dup 8) (match_dup 4)]
17467 UNSPEC_FSCALE_FRACT))
17469 (unspec:XF [(match_dup 8) (match_dup 4)]
17470 UNSPEC_FSCALE_EXP))])]
17471 "TARGET_USE_FANCY_MATH_387
17472 && flag_unsafe_math_optimizations && !optimize_size"
17476 for (i = 3; i < 10; i++)
17477 operands[i] = gen_reg_rtx (XFmode);
17479 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17482 (define_expand "expxf2"
17483 [(use (match_operand:XF 0 "register_operand" ""))
17484 (use (match_operand:XF 1 "register_operand" ""))]
17485 "TARGET_USE_FANCY_MATH_387
17486 && flag_unsafe_math_optimizations && !optimize_size"
17488 rtx op2 = gen_reg_rtx (XFmode);
17489 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17491 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17495 (define_expand "exp<mode>2"
17496 [(use (match_operand:MODEF 0 "register_operand" ""))
17497 (use (match_operand:MODEF 1 "general_operand" ""))]
17498 "TARGET_USE_FANCY_MATH_387
17499 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17500 || TARGET_MIX_SSE_I387)
17501 && flag_unsafe_math_optimizations && !optimize_size"
17503 rtx op0 = gen_reg_rtx (XFmode);
17504 rtx op1 = gen_reg_rtx (XFmode);
17506 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17507 emit_insn (gen_expxf2 (op0, op1));
17508 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17512 (define_expand "exp10xf2"
17513 [(use (match_operand:XF 0 "register_operand" ""))
17514 (use (match_operand:XF 1 "register_operand" ""))]
17515 "TARGET_USE_FANCY_MATH_387
17516 && flag_unsafe_math_optimizations && !optimize_size"
17518 rtx op2 = gen_reg_rtx (XFmode);
17519 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17521 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17525 (define_expand "exp10<mode>2"
17526 [(use (match_operand:MODEF 0 "register_operand" ""))
17527 (use (match_operand:MODEF 1 "general_operand" ""))]
17528 "TARGET_USE_FANCY_MATH_387
17529 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17530 || TARGET_MIX_SSE_I387)
17531 && flag_unsafe_math_optimizations && !optimize_size"
17533 rtx op0 = gen_reg_rtx (XFmode);
17534 rtx op1 = gen_reg_rtx (XFmode);
17536 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17537 emit_insn (gen_exp10xf2 (op0, op1));
17538 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17542 (define_expand "exp2xf2"
17543 [(use (match_operand:XF 0 "register_operand" ""))
17544 (use (match_operand:XF 1 "register_operand" ""))]
17545 "TARGET_USE_FANCY_MATH_387
17546 && flag_unsafe_math_optimizations && !optimize_size"
17548 rtx op2 = gen_reg_rtx (XFmode);
17549 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17551 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17555 (define_expand "exp2<mode>2"
17556 [(use (match_operand:MODEF 0 "register_operand" ""))
17557 (use (match_operand:MODEF 1 "general_operand" ""))]
17558 "TARGET_USE_FANCY_MATH_387
17559 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17560 || TARGET_MIX_SSE_I387)
17561 && flag_unsafe_math_optimizations && !optimize_size"
17563 rtx op0 = gen_reg_rtx (XFmode);
17564 rtx op1 = gen_reg_rtx (XFmode);
17566 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17567 emit_insn (gen_exp2xf2 (op0, op1));
17568 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17572 (define_expand "expm1xf2"
17573 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17575 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17576 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17577 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17578 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17579 (parallel [(set (match_dup 7)
17580 (unspec:XF [(match_dup 6) (match_dup 4)]
17581 UNSPEC_FSCALE_FRACT))
17583 (unspec:XF [(match_dup 6) (match_dup 4)]
17584 UNSPEC_FSCALE_EXP))])
17585 (parallel [(set (match_dup 10)
17586 (unspec:XF [(match_dup 9) (match_dup 8)]
17587 UNSPEC_FSCALE_FRACT))
17588 (set (match_dup 11)
17589 (unspec:XF [(match_dup 9) (match_dup 8)]
17590 UNSPEC_FSCALE_EXP))])
17591 (set (match_dup 12) (minus:XF (match_dup 10)
17592 (float_extend:XF (match_dup 13))))
17593 (set (match_operand:XF 0 "register_operand" "")
17594 (plus:XF (match_dup 12) (match_dup 7)))]
17595 "TARGET_USE_FANCY_MATH_387
17596 && flag_unsafe_math_optimizations && !optimize_size"
17600 for (i = 2; i < 13; i++)
17601 operands[i] = gen_reg_rtx (XFmode);
17604 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17606 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17609 (define_expand "expm1<mode>2"
17610 [(use (match_operand:MODEF 0 "register_operand" ""))
17611 (use (match_operand:MODEF 1 "general_operand" ""))]
17612 "TARGET_USE_FANCY_MATH_387
17613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17614 || TARGET_MIX_SSE_I387)
17615 && flag_unsafe_math_optimizations && !optimize_size"
17617 rtx op0 = gen_reg_rtx (XFmode);
17618 rtx op1 = gen_reg_rtx (XFmode);
17620 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17621 emit_insn (gen_expm1xf2 (op0, op1));
17622 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17626 (define_expand "ldexpxf3"
17627 [(set (match_dup 3)
17628 (float:XF (match_operand:SI 2 "register_operand" "")))
17629 (parallel [(set (match_operand:XF 0 " register_operand" "")
17630 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17632 UNSPEC_FSCALE_FRACT))
17634 (unspec:XF [(match_dup 1) (match_dup 3)]
17635 UNSPEC_FSCALE_EXP))])]
17636 "TARGET_USE_FANCY_MATH_387
17637 && flag_unsafe_math_optimizations && !optimize_size"
17639 operands[3] = gen_reg_rtx (XFmode);
17640 operands[4] = gen_reg_rtx (XFmode);
17643 (define_expand "ldexp<mode>3"
17644 [(use (match_operand:MODEF 0 "register_operand" ""))
17645 (use (match_operand:MODEF 1 "general_operand" ""))
17646 (use (match_operand:SI 2 "register_operand" ""))]
17647 "TARGET_USE_FANCY_MATH_387
17648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17649 || TARGET_MIX_SSE_I387)
17650 && flag_unsafe_math_optimizations && !optimize_size"
17652 rtx op0 = gen_reg_rtx (XFmode);
17653 rtx op1 = gen_reg_rtx (XFmode);
17655 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17656 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17657 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17661 (define_expand "scalbxf3"
17662 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17663 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17664 (match_operand:XF 2 "register_operand" "")]
17665 UNSPEC_FSCALE_FRACT))
17667 (unspec:XF [(match_dup 1) (match_dup 2)]
17668 UNSPEC_FSCALE_EXP))])]
17669 "TARGET_USE_FANCY_MATH_387
17670 && flag_unsafe_math_optimizations && !optimize_size"
17672 operands[3] = gen_reg_rtx (XFmode);
17675 (define_expand "scalb<mode>3"
17676 [(use (match_operand:MODEF 0 "register_operand" ""))
17677 (use (match_operand:MODEF 1 "general_operand" ""))
17678 (use (match_operand:MODEF 2 "register_operand" ""))]
17679 "TARGET_USE_FANCY_MATH_387
17680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17681 || TARGET_MIX_SSE_I387)
17682 && flag_unsafe_math_optimizations && !optimize_size"
17684 rtx op0 = gen_reg_rtx (XFmode);
17685 rtx op1 = gen_reg_rtx (XFmode);
17686 rtx op2 = gen_reg_rtx (XFmode);
17688 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17689 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17690 emit_insn (gen_scalbxf3 (op0, op1, op2));
17691 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17696 (define_insn "sse4_1_round<mode>2"
17697 [(set (match_operand:MODEF 0 "register_operand" "=x")
17698 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17699 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17702 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17703 [(set_attr "type" "ssecvt")
17704 (set_attr "prefix_extra" "1")
17705 (set_attr "mode" "<MODE>")])
17707 (define_insn "rintxf2"
17708 [(set (match_operand:XF 0 "register_operand" "=f")
17709 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17711 "TARGET_USE_FANCY_MATH_387
17712 && flag_unsafe_math_optimizations"
17714 [(set_attr "type" "fpspc")
17715 (set_attr "mode" "XF")])
17717 (define_expand "rint<mode>2"
17718 [(use (match_operand:MODEF 0 "register_operand" ""))
17719 (use (match_operand:MODEF 1 "register_operand" ""))]
17720 "(TARGET_USE_FANCY_MATH_387
17721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17722 || TARGET_MIX_SSE_I387)
17723 && flag_unsafe_math_optimizations)
17724 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17725 && !flag_trapping_math
17726 && (TARGET_ROUND || !optimize_size))"
17728 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17729 && !flag_trapping_math
17730 && (TARGET_ROUND || !optimize_size))
17733 emit_insn (gen_sse4_1_round<mode>2
17734 (operands[0], operands[1], GEN_INT (0x04)));
17736 ix86_expand_rint (operand0, operand1);
17740 rtx op0 = gen_reg_rtx (XFmode);
17741 rtx op1 = gen_reg_rtx (XFmode);
17743 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17744 emit_insn (gen_rintxf2 (op0, op1));
17746 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17751 (define_expand "round<mode>2"
17752 [(match_operand:MODEF 0 "register_operand" "")
17753 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17754 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17755 && !flag_trapping_math && !flag_rounding_math
17758 if (TARGET_64BIT || (<MODE>mode != DFmode))
17759 ix86_expand_round (operand0, operand1);
17761 ix86_expand_rounddf_32 (operand0, operand1);
17765 (define_insn_and_split "*fistdi2_1"
17766 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17767 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17769 "TARGET_USE_FANCY_MATH_387
17770 && !(reload_completed || reload_in_progress)"
17775 if (memory_operand (operands[0], VOIDmode))
17776 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17779 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17780 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17785 [(set_attr "type" "fpspc")
17786 (set_attr "mode" "DI")])
17788 (define_insn "fistdi2"
17789 [(set (match_operand:DI 0 "memory_operand" "=m")
17790 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17792 (clobber (match_scratch:XF 2 "=&1f"))]
17793 "TARGET_USE_FANCY_MATH_387"
17794 "* return output_fix_trunc (insn, operands, 0);"
17795 [(set_attr "type" "fpspc")
17796 (set_attr "mode" "DI")])
17798 (define_insn "fistdi2_with_temp"
17799 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17800 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17802 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17803 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17804 "TARGET_USE_FANCY_MATH_387"
17806 [(set_attr "type" "fpspc")
17807 (set_attr "mode" "DI")])
17810 [(set (match_operand:DI 0 "register_operand" "")
17811 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17813 (clobber (match_operand:DI 2 "memory_operand" ""))
17814 (clobber (match_scratch 3 ""))]
17816 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17817 (clobber (match_dup 3))])
17818 (set (match_dup 0) (match_dup 2))]
17822 [(set (match_operand:DI 0 "memory_operand" "")
17823 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17825 (clobber (match_operand:DI 2 "memory_operand" ""))
17826 (clobber (match_scratch 3 ""))]
17828 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17829 (clobber (match_dup 3))])]
17832 (define_insn_and_split "*fist<mode>2_1"
17833 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17834 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17836 "TARGET_USE_FANCY_MATH_387
17837 && !(reload_completed || reload_in_progress)"
17842 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17843 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17847 [(set_attr "type" "fpspc")
17848 (set_attr "mode" "<MODE>")])
17850 (define_insn "fist<mode>2"
17851 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17852 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17854 "TARGET_USE_FANCY_MATH_387"
17855 "* return output_fix_trunc (insn, operands, 0);"
17856 [(set_attr "type" "fpspc")
17857 (set_attr "mode" "<MODE>")])
17859 (define_insn "fist<mode>2_with_temp"
17860 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17861 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17863 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17864 "TARGET_USE_FANCY_MATH_387"
17866 [(set_attr "type" "fpspc")
17867 (set_attr "mode" "<MODE>")])
17870 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17871 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17873 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17875 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17876 (set (match_dup 0) (match_dup 2))]
17880 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17881 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17883 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17885 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17888 (define_expand "lrintxf<mode>2"
17889 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17890 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17892 "TARGET_USE_FANCY_MATH_387"
17895 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17896 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17897 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17898 UNSPEC_FIX_NOTRUNC))]
17899 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17900 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17903 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17904 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17905 (match_operand:MODEF 1 "register_operand" "")]
17906 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17907 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17908 && !flag_trapping_math && !flag_rounding_math
17911 ix86_expand_lround (operand0, operand1);
17915 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17916 (define_insn_and_split "frndintxf2_floor"
17917 [(set (match_operand:XF 0 "register_operand" "")
17918 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17919 UNSPEC_FRNDINT_FLOOR))
17920 (clobber (reg:CC FLAGS_REG))]
17921 "TARGET_USE_FANCY_MATH_387
17922 && flag_unsafe_math_optimizations
17923 && !(reload_completed || reload_in_progress)"
17928 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17930 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17931 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17933 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17934 operands[2], operands[3]));
17937 [(set_attr "type" "frndint")
17938 (set_attr "i387_cw" "floor")
17939 (set_attr "mode" "XF")])
17941 (define_insn "frndintxf2_floor_i387"
17942 [(set (match_operand:XF 0 "register_operand" "=f")
17943 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17944 UNSPEC_FRNDINT_FLOOR))
17945 (use (match_operand:HI 2 "memory_operand" "m"))
17946 (use (match_operand:HI 3 "memory_operand" "m"))]
17947 "TARGET_USE_FANCY_MATH_387
17948 && flag_unsafe_math_optimizations"
17949 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17950 [(set_attr "type" "frndint")
17951 (set_attr "i387_cw" "floor")
17952 (set_attr "mode" "XF")])
17954 (define_expand "floorxf2"
17955 [(use (match_operand:XF 0 "register_operand" ""))
17956 (use (match_operand:XF 1 "register_operand" ""))]
17957 "TARGET_USE_FANCY_MATH_387
17958 && flag_unsafe_math_optimizations && !optimize_size"
17960 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17964 (define_expand "floor<mode>2"
17965 [(use (match_operand:MODEF 0 "register_operand" ""))
17966 (use (match_operand:MODEF 1 "register_operand" ""))]
17967 "(TARGET_USE_FANCY_MATH_387
17968 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17969 || TARGET_MIX_SSE_I387)
17970 && flag_unsafe_math_optimizations && !optimize_size)
17971 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17972 && !flag_trapping_math
17973 && (TARGET_ROUND || !optimize_size))"
17975 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17976 && !flag_trapping_math
17977 && (TARGET_ROUND || !optimize_size))
17980 emit_insn (gen_sse4_1_round<mode>2
17981 (operands[0], operands[1], GEN_INT (0x01)));
17982 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17983 ix86_expand_floorceil (operand0, operand1, true);
17985 ix86_expand_floorceildf_32 (operand0, operand1, true);
17989 rtx op0 = gen_reg_rtx (XFmode);
17990 rtx op1 = gen_reg_rtx (XFmode);
17992 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17993 emit_insn (gen_frndintxf2_floor (op0, op1));
17995 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18000 (define_insn_and_split "*fist<mode>2_floor_1"
18001 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18002 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18003 UNSPEC_FIST_FLOOR))
18004 (clobber (reg:CC FLAGS_REG))]
18005 "TARGET_USE_FANCY_MATH_387
18006 && flag_unsafe_math_optimizations
18007 && !(reload_completed || reload_in_progress)"
18012 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18014 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18015 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18016 if (memory_operand (operands[0], VOIDmode))
18017 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18018 operands[2], operands[3]));
18021 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18022 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18023 operands[2], operands[3],
18028 [(set_attr "type" "fistp")
18029 (set_attr "i387_cw" "floor")
18030 (set_attr "mode" "<MODE>")])
18032 (define_insn "fistdi2_floor"
18033 [(set (match_operand:DI 0 "memory_operand" "=m")
18034 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18035 UNSPEC_FIST_FLOOR))
18036 (use (match_operand:HI 2 "memory_operand" "m"))
18037 (use (match_operand:HI 3 "memory_operand" "m"))
18038 (clobber (match_scratch:XF 4 "=&1f"))]
18039 "TARGET_USE_FANCY_MATH_387
18040 && flag_unsafe_math_optimizations"
18041 "* return output_fix_trunc (insn, operands, 0);"
18042 [(set_attr "type" "fistp")
18043 (set_attr "i387_cw" "floor")
18044 (set_attr "mode" "DI")])
18046 (define_insn "fistdi2_floor_with_temp"
18047 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18048 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18049 UNSPEC_FIST_FLOOR))
18050 (use (match_operand:HI 2 "memory_operand" "m,m"))
18051 (use (match_operand:HI 3 "memory_operand" "m,m"))
18052 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18053 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18054 "TARGET_USE_FANCY_MATH_387
18055 && flag_unsafe_math_optimizations"
18057 [(set_attr "type" "fistp")
18058 (set_attr "i387_cw" "floor")
18059 (set_attr "mode" "DI")])
18062 [(set (match_operand:DI 0 "register_operand" "")
18063 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18064 UNSPEC_FIST_FLOOR))
18065 (use (match_operand:HI 2 "memory_operand" ""))
18066 (use (match_operand:HI 3 "memory_operand" ""))
18067 (clobber (match_operand:DI 4 "memory_operand" ""))
18068 (clobber (match_scratch 5 ""))]
18070 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18071 (use (match_dup 2))
18072 (use (match_dup 3))
18073 (clobber (match_dup 5))])
18074 (set (match_dup 0) (match_dup 4))]
18078 [(set (match_operand:DI 0 "memory_operand" "")
18079 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18080 UNSPEC_FIST_FLOOR))
18081 (use (match_operand:HI 2 "memory_operand" ""))
18082 (use (match_operand:HI 3 "memory_operand" ""))
18083 (clobber (match_operand:DI 4 "memory_operand" ""))
18084 (clobber (match_scratch 5 ""))]
18086 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18087 (use (match_dup 2))
18088 (use (match_dup 3))
18089 (clobber (match_dup 5))])]
18092 (define_insn "fist<mode>2_floor"
18093 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18094 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18095 UNSPEC_FIST_FLOOR))
18096 (use (match_operand:HI 2 "memory_operand" "m"))
18097 (use (match_operand:HI 3 "memory_operand" "m"))]
18098 "TARGET_USE_FANCY_MATH_387
18099 && flag_unsafe_math_optimizations"
18100 "* return output_fix_trunc (insn, operands, 0);"
18101 [(set_attr "type" "fistp")
18102 (set_attr "i387_cw" "floor")
18103 (set_attr "mode" "<MODE>")])
18105 (define_insn "fist<mode>2_floor_with_temp"
18106 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18107 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18108 UNSPEC_FIST_FLOOR))
18109 (use (match_operand:HI 2 "memory_operand" "m,m"))
18110 (use (match_operand:HI 3 "memory_operand" "m,m"))
18111 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18112 "TARGET_USE_FANCY_MATH_387
18113 && flag_unsafe_math_optimizations"
18115 [(set_attr "type" "fistp")
18116 (set_attr "i387_cw" "floor")
18117 (set_attr "mode" "<MODE>")])
18120 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18121 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18122 UNSPEC_FIST_FLOOR))
18123 (use (match_operand:HI 2 "memory_operand" ""))
18124 (use (match_operand:HI 3 "memory_operand" ""))
18125 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18127 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18128 UNSPEC_FIST_FLOOR))
18129 (use (match_dup 2))
18130 (use (match_dup 3))])
18131 (set (match_dup 0) (match_dup 4))]
18135 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18136 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18137 UNSPEC_FIST_FLOOR))
18138 (use (match_operand:HI 2 "memory_operand" ""))
18139 (use (match_operand:HI 3 "memory_operand" ""))
18140 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18142 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18143 UNSPEC_FIST_FLOOR))
18144 (use (match_dup 2))
18145 (use (match_dup 3))])]
18148 (define_expand "lfloorxf<mode>2"
18149 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18150 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18151 UNSPEC_FIST_FLOOR))
18152 (clobber (reg:CC FLAGS_REG))])]
18153 "TARGET_USE_FANCY_MATH_387
18154 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18155 && flag_unsafe_math_optimizations"
18158 (define_expand "lfloor<mode>di2"
18159 [(match_operand:DI 0 "nonimmediate_operand" "")
18160 (match_operand:MODEF 1 "register_operand" "")]
18161 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18162 && !flag_trapping_math
18165 ix86_expand_lfloorceil (operand0, operand1, true);
18169 (define_expand "lfloor<mode>si2"
18170 [(match_operand:SI 0 "nonimmediate_operand" "")
18171 (match_operand:MODEF 1 "register_operand" "")]
18172 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18173 && !flag_trapping_math
18174 && (!optimize_size || !TARGET_64BIT)"
18176 ix86_expand_lfloorceil (operand0, operand1, true);
18180 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18181 (define_insn_and_split "frndintxf2_ceil"
18182 [(set (match_operand:XF 0 "register_operand" "")
18183 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18184 UNSPEC_FRNDINT_CEIL))
18185 (clobber (reg:CC FLAGS_REG))]
18186 "TARGET_USE_FANCY_MATH_387
18187 && flag_unsafe_math_optimizations
18188 && !(reload_completed || reload_in_progress)"
18193 ix86_optimize_mode_switching[I387_CEIL] = 1;
18195 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18196 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18198 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18199 operands[2], operands[3]));
18202 [(set_attr "type" "frndint")
18203 (set_attr "i387_cw" "ceil")
18204 (set_attr "mode" "XF")])
18206 (define_insn "frndintxf2_ceil_i387"
18207 [(set (match_operand:XF 0 "register_operand" "=f")
18208 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18209 UNSPEC_FRNDINT_CEIL))
18210 (use (match_operand:HI 2 "memory_operand" "m"))
18211 (use (match_operand:HI 3 "memory_operand" "m"))]
18212 "TARGET_USE_FANCY_MATH_387
18213 && flag_unsafe_math_optimizations"
18214 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18215 [(set_attr "type" "frndint")
18216 (set_attr "i387_cw" "ceil")
18217 (set_attr "mode" "XF")])
18219 (define_expand "ceilxf2"
18220 [(use (match_operand:XF 0 "register_operand" ""))
18221 (use (match_operand:XF 1 "register_operand" ""))]
18222 "TARGET_USE_FANCY_MATH_387
18223 && flag_unsafe_math_optimizations && !optimize_size"
18225 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18229 (define_expand "ceil<mode>2"
18230 [(use (match_operand:MODEF 0 "register_operand" ""))
18231 (use (match_operand:MODEF 1 "register_operand" ""))]
18232 "(TARGET_USE_FANCY_MATH_387
18233 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18234 || TARGET_MIX_SSE_I387)
18235 && flag_unsafe_math_optimizations && !optimize_size)
18236 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18237 && !flag_trapping_math
18238 && (TARGET_ROUND || !optimize_size))"
18240 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18241 && !flag_trapping_math
18242 && (TARGET_ROUND || !optimize_size))
18245 emit_insn (gen_sse4_1_round<mode>2
18246 (operands[0], operands[1], GEN_INT (0x02)));
18247 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18248 ix86_expand_floorceil (operand0, operand1, false);
18250 ix86_expand_floorceildf_32 (operand0, operand1, false);
18254 rtx op0 = gen_reg_rtx (XFmode);
18255 rtx op1 = gen_reg_rtx (XFmode);
18257 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18258 emit_insn (gen_frndintxf2_ceil (op0, op1));
18260 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18265 (define_insn_and_split "*fist<mode>2_ceil_1"
18266 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18267 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18269 (clobber (reg:CC FLAGS_REG))]
18270 "TARGET_USE_FANCY_MATH_387
18271 && flag_unsafe_math_optimizations
18272 && !(reload_completed || reload_in_progress)"
18277 ix86_optimize_mode_switching[I387_CEIL] = 1;
18279 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18280 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18281 if (memory_operand (operands[0], VOIDmode))
18282 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18283 operands[2], operands[3]));
18286 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18287 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18288 operands[2], operands[3],
18293 [(set_attr "type" "fistp")
18294 (set_attr "i387_cw" "ceil")
18295 (set_attr "mode" "<MODE>")])
18297 (define_insn "fistdi2_ceil"
18298 [(set (match_operand:DI 0 "memory_operand" "=m")
18299 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18301 (use (match_operand:HI 2 "memory_operand" "m"))
18302 (use (match_operand:HI 3 "memory_operand" "m"))
18303 (clobber (match_scratch:XF 4 "=&1f"))]
18304 "TARGET_USE_FANCY_MATH_387
18305 && flag_unsafe_math_optimizations"
18306 "* return output_fix_trunc (insn, operands, 0);"
18307 [(set_attr "type" "fistp")
18308 (set_attr "i387_cw" "ceil")
18309 (set_attr "mode" "DI")])
18311 (define_insn "fistdi2_ceil_with_temp"
18312 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18313 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18315 (use (match_operand:HI 2 "memory_operand" "m,m"))
18316 (use (match_operand:HI 3 "memory_operand" "m,m"))
18317 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18318 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18319 "TARGET_USE_FANCY_MATH_387
18320 && flag_unsafe_math_optimizations"
18322 [(set_attr "type" "fistp")
18323 (set_attr "i387_cw" "ceil")
18324 (set_attr "mode" "DI")])
18327 [(set (match_operand:DI 0 "register_operand" "")
18328 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18330 (use (match_operand:HI 2 "memory_operand" ""))
18331 (use (match_operand:HI 3 "memory_operand" ""))
18332 (clobber (match_operand:DI 4 "memory_operand" ""))
18333 (clobber (match_scratch 5 ""))]
18335 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18336 (use (match_dup 2))
18337 (use (match_dup 3))
18338 (clobber (match_dup 5))])
18339 (set (match_dup 0) (match_dup 4))]
18343 [(set (match_operand:DI 0 "memory_operand" "")
18344 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18346 (use (match_operand:HI 2 "memory_operand" ""))
18347 (use (match_operand:HI 3 "memory_operand" ""))
18348 (clobber (match_operand:DI 4 "memory_operand" ""))
18349 (clobber (match_scratch 5 ""))]
18351 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18352 (use (match_dup 2))
18353 (use (match_dup 3))
18354 (clobber (match_dup 5))])]
18357 (define_insn "fist<mode>2_ceil"
18358 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18359 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18361 (use (match_operand:HI 2 "memory_operand" "m"))
18362 (use (match_operand:HI 3 "memory_operand" "m"))]
18363 "TARGET_USE_FANCY_MATH_387
18364 && flag_unsafe_math_optimizations"
18365 "* return output_fix_trunc (insn, operands, 0);"
18366 [(set_attr "type" "fistp")
18367 (set_attr "i387_cw" "ceil")
18368 (set_attr "mode" "<MODE>")])
18370 (define_insn "fist<mode>2_ceil_with_temp"
18371 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18372 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18374 (use (match_operand:HI 2 "memory_operand" "m,m"))
18375 (use (match_operand:HI 3 "memory_operand" "m,m"))
18376 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18377 "TARGET_USE_FANCY_MATH_387
18378 && flag_unsafe_math_optimizations"
18380 [(set_attr "type" "fistp")
18381 (set_attr "i387_cw" "ceil")
18382 (set_attr "mode" "<MODE>")])
18385 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18386 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18388 (use (match_operand:HI 2 "memory_operand" ""))
18389 (use (match_operand:HI 3 "memory_operand" ""))
18390 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18392 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18394 (use (match_dup 2))
18395 (use (match_dup 3))])
18396 (set (match_dup 0) (match_dup 4))]
18400 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18401 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18403 (use (match_operand:HI 2 "memory_operand" ""))
18404 (use (match_operand:HI 3 "memory_operand" ""))
18405 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18407 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18409 (use (match_dup 2))
18410 (use (match_dup 3))])]
18413 (define_expand "lceilxf<mode>2"
18414 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18415 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18417 (clobber (reg:CC FLAGS_REG))])]
18418 "TARGET_USE_FANCY_MATH_387
18419 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18420 && flag_unsafe_math_optimizations"
18423 (define_expand "lceil<mode>di2"
18424 [(match_operand:DI 0 "nonimmediate_operand" "")
18425 (match_operand:MODEF 1 "register_operand" "")]
18426 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18427 && !flag_trapping_math"
18429 ix86_expand_lfloorceil (operand0, operand1, false);
18433 (define_expand "lceil<mode>si2"
18434 [(match_operand:SI 0 "nonimmediate_operand" "")
18435 (match_operand:MODEF 1 "register_operand" "")]
18436 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18437 && !flag_trapping_math"
18439 ix86_expand_lfloorceil (operand0, operand1, false);
18443 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18444 (define_insn_and_split "frndintxf2_trunc"
18445 [(set (match_operand:XF 0 "register_operand" "")
18446 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18447 UNSPEC_FRNDINT_TRUNC))
18448 (clobber (reg:CC FLAGS_REG))]
18449 "TARGET_USE_FANCY_MATH_387
18450 && flag_unsafe_math_optimizations
18451 && !(reload_completed || reload_in_progress)"
18456 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18458 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18459 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18461 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18462 operands[2], operands[3]));
18465 [(set_attr "type" "frndint")
18466 (set_attr "i387_cw" "trunc")
18467 (set_attr "mode" "XF")])
18469 (define_insn "frndintxf2_trunc_i387"
18470 [(set (match_operand:XF 0 "register_operand" "=f")
18471 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18472 UNSPEC_FRNDINT_TRUNC))
18473 (use (match_operand:HI 2 "memory_operand" "m"))
18474 (use (match_operand:HI 3 "memory_operand" "m"))]
18475 "TARGET_USE_FANCY_MATH_387
18476 && flag_unsafe_math_optimizations"
18477 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18478 [(set_attr "type" "frndint")
18479 (set_attr "i387_cw" "trunc")
18480 (set_attr "mode" "XF")])
18482 (define_expand "btruncxf2"
18483 [(use (match_operand:XF 0 "register_operand" ""))
18484 (use (match_operand:XF 1 "register_operand" ""))]
18485 "TARGET_USE_FANCY_MATH_387
18486 && flag_unsafe_math_optimizations && !optimize_size"
18488 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18492 (define_expand "btrunc<mode>2"
18493 [(use (match_operand:MODEF 0 "register_operand" ""))
18494 (use (match_operand:MODEF 1 "register_operand" ""))]
18495 "(TARGET_USE_FANCY_MATH_387
18496 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18497 || TARGET_MIX_SSE_I387)
18498 && flag_unsafe_math_optimizations && !optimize_size)
18499 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18500 && !flag_trapping_math
18501 && (TARGET_ROUND || !optimize_size))"
18503 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18504 && !flag_trapping_math
18505 && (TARGET_ROUND || !optimize_size))
18508 emit_insn (gen_sse4_1_round<mode>2
18509 (operands[0], operands[1], GEN_INT (0x03)));
18510 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18511 ix86_expand_trunc (operand0, operand1);
18513 ix86_expand_truncdf_32 (operand0, operand1);
18517 rtx op0 = gen_reg_rtx (XFmode);
18518 rtx op1 = gen_reg_rtx (XFmode);
18520 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18521 emit_insn (gen_frndintxf2_trunc (op0, op1));
18523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18528 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18529 (define_insn_and_split "frndintxf2_mask_pm"
18530 [(set (match_operand:XF 0 "register_operand" "")
18531 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18532 UNSPEC_FRNDINT_MASK_PM))
18533 (clobber (reg:CC FLAGS_REG))]
18534 "TARGET_USE_FANCY_MATH_387
18535 && flag_unsafe_math_optimizations
18536 && !(reload_completed || reload_in_progress)"
18541 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18543 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18544 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18546 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18547 operands[2], operands[3]));
18550 [(set_attr "type" "frndint")
18551 (set_attr "i387_cw" "mask_pm")
18552 (set_attr "mode" "XF")])
18554 (define_insn "frndintxf2_mask_pm_i387"
18555 [(set (match_operand:XF 0 "register_operand" "=f")
18556 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18557 UNSPEC_FRNDINT_MASK_PM))
18558 (use (match_operand:HI 2 "memory_operand" "m"))
18559 (use (match_operand:HI 3 "memory_operand" "m"))]
18560 "TARGET_USE_FANCY_MATH_387
18561 && flag_unsafe_math_optimizations"
18562 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18563 [(set_attr "type" "frndint")
18564 (set_attr "i387_cw" "mask_pm")
18565 (set_attr "mode" "XF")])
18567 (define_expand "nearbyintxf2"
18568 [(use (match_operand:XF 0 "register_operand" ""))
18569 (use (match_operand:XF 1 "register_operand" ""))]
18570 "TARGET_USE_FANCY_MATH_387
18571 && flag_unsafe_math_optimizations"
18573 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18578 (define_expand "nearbyint<mode>2"
18579 [(use (match_operand:MODEF 0 "register_operand" ""))
18580 (use (match_operand:MODEF 1 "register_operand" ""))]
18581 "TARGET_USE_FANCY_MATH_387
18582 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18583 || TARGET_MIX_SSE_I387)
18584 && flag_unsafe_math_optimizations"
18586 rtx op0 = gen_reg_rtx (XFmode);
18587 rtx op1 = gen_reg_rtx (XFmode);
18589 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18590 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18592 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18596 (define_insn "fxam<mode>2_i387"
18597 [(set (match_operand:HI 0 "register_operand" "=a")
18599 [(match_operand:X87MODEF 1 "register_operand" "f")]
18601 "TARGET_USE_FANCY_MATH_387"
18602 "fxam\n\tfnstsw\t%0"
18603 [(set_attr "type" "multi")
18604 (set_attr "unit" "i387")
18605 (set_attr "mode" "<MODE>")])
18607 (define_expand "isinf<mode>2"
18608 [(use (match_operand:SI 0 "register_operand" ""))
18609 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18610 "TARGET_USE_FANCY_MATH_387
18611 && TARGET_C99_FUNCTIONS
18612 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18614 rtx mask = GEN_INT (0x45);
18615 rtx val = GEN_INT (0x05);
18619 rtx scratch = gen_reg_rtx (HImode);
18620 rtx res = gen_reg_rtx (QImode);
18622 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18623 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18624 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18625 cond = gen_rtx_fmt_ee (EQ, QImode,
18626 gen_rtx_REG (CCmode, FLAGS_REG),
18628 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18629 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18633 (define_expand "signbit<mode>2"
18634 [(use (match_operand:SI 0 "register_operand" ""))
18635 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18636 "TARGET_USE_FANCY_MATH_387
18637 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18639 rtx mask = GEN_INT (0x0200);
18641 rtx scratch = gen_reg_rtx (HImode);
18643 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18644 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18648 ;; Block operation instructions
18650 (define_expand "movmemsi"
18651 [(use (match_operand:BLK 0 "memory_operand" ""))
18652 (use (match_operand:BLK 1 "memory_operand" ""))
18653 (use (match_operand:SI 2 "nonmemory_operand" ""))
18654 (use (match_operand:SI 3 "const_int_operand" ""))
18655 (use (match_operand:SI 4 "const_int_operand" ""))
18656 (use (match_operand:SI 5 "const_int_operand" ""))]
18659 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18660 operands[4], operands[5]))
18666 (define_expand "movmemdi"
18667 [(use (match_operand:BLK 0 "memory_operand" ""))
18668 (use (match_operand:BLK 1 "memory_operand" ""))
18669 (use (match_operand:DI 2 "nonmemory_operand" ""))
18670 (use (match_operand:DI 3 "const_int_operand" ""))
18671 (use (match_operand:SI 4 "const_int_operand" ""))
18672 (use (match_operand:SI 5 "const_int_operand" ""))]
18675 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18676 operands[4], operands[5]))
18682 ;; Most CPUs don't like single string operations
18683 ;; Handle this case here to simplify previous expander.
18685 (define_expand "strmov"
18686 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18687 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18688 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18689 (clobber (reg:CC FLAGS_REG))])
18690 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18691 (clobber (reg:CC FLAGS_REG))])]
18694 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18696 /* If .md ever supports :P for Pmode, these can be directly
18697 in the pattern above. */
18698 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18699 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18701 if (TARGET_SINGLE_STRINGOP || optimize_size)
18703 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18704 operands[2], operands[3],
18705 operands[5], operands[6]));
18709 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18712 (define_expand "strmov_singleop"
18713 [(parallel [(set (match_operand 1 "memory_operand" "")
18714 (match_operand 3 "memory_operand" ""))
18715 (set (match_operand 0 "register_operand" "")
18716 (match_operand 4 "" ""))
18717 (set (match_operand 2 "register_operand" "")
18718 (match_operand 5 "" ""))])]
18719 "TARGET_SINGLE_STRINGOP || optimize_size"
18722 (define_insn "*strmovdi_rex_1"
18723 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18724 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18725 (set (match_operand:DI 0 "register_operand" "=D")
18726 (plus:DI (match_dup 2)
18728 (set (match_operand:DI 1 "register_operand" "=S")
18729 (plus:DI (match_dup 3)
18731 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18733 [(set_attr "type" "str")
18734 (set_attr "mode" "DI")
18735 (set_attr "memory" "both")])
18737 (define_insn "*strmovsi_1"
18738 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18739 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18740 (set (match_operand:SI 0 "register_operand" "=D")
18741 (plus:SI (match_dup 2)
18743 (set (match_operand:SI 1 "register_operand" "=S")
18744 (plus:SI (match_dup 3)
18746 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18748 [(set_attr "type" "str")
18749 (set_attr "mode" "SI")
18750 (set_attr "memory" "both")])
18752 (define_insn "*strmovsi_rex_1"
18753 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18754 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18755 (set (match_operand:DI 0 "register_operand" "=D")
18756 (plus:DI (match_dup 2)
18758 (set (match_operand:DI 1 "register_operand" "=S")
18759 (plus:DI (match_dup 3)
18761 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18763 [(set_attr "type" "str")
18764 (set_attr "mode" "SI")
18765 (set_attr "memory" "both")])
18767 (define_insn "*strmovhi_1"
18768 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18769 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18770 (set (match_operand:SI 0 "register_operand" "=D")
18771 (plus:SI (match_dup 2)
18773 (set (match_operand:SI 1 "register_operand" "=S")
18774 (plus:SI (match_dup 3)
18776 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18778 [(set_attr "type" "str")
18779 (set_attr "memory" "both")
18780 (set_attr "mode" "HI")])
18782 (define_insn "*strmovhi_rex_1"
18783 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18784 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18785 (set (match_operand:DI 0 "register_operand" "=D")
18786 (plus:DI (match_dup 2)
18788 (set (match_operand:DI 1 "register_operand" "=S")
18789 (plus:DI (match_dup 3)
18791 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18793 [(set_attr "type" "str")
18794 (set_attr "memory" "both")
18795 (set_attr "mode" "HI")])
18797 (define_insn "*strmovqi_1"
18798 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18799 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18800 (set (match_operand:SI 0 "register_operand" "=D")
18801 (plus:SI (match_dup 2)
18803 (set (match_operand:SI 1 "register_operand" "=S")
18804 (plus:SI (match_dup 3)
18806 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18808 [(set_attr "type" "str")
18809 (set_attr "memory" "both")
18810 (set_attr "mode" "QI")])
18812 (define_insn "*strmovqi_rex_1"
18813 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18814 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18815 (set (match_operand:DI 0 "register_operand" "=D")
18816 (plus:DI (match_dup 2)
18818 (set (match_operand:DI 1 "register_operand" "=S")
18819 (plus:DI (match_dup 3)
18821 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18823 [(set_attr "type" "str")
18824 (set_attr "memory" "both")
18825 (set_attr "mode" "QI")])
18827 (define_expand "rep_mov"
18828 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18829 (set (match_operand 0 "register_operand" "")
18830 (match_operand 5 "" ""))
18831 (set (match_operand 2 "register_operand" "")
18832 (match_operand 6 "" ""))
18833 (set (match_operand 1 "memory_operand" "")
18834 (match_operand 3 "memory_operand" ""))
18835 (use (match_dup 4))])]
18839 (define_insn "*rep_movdi_rex64"
18840 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18841 (set (match_operand:DI 0 "register_operand" "=D")
18842 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18844 (match_operand:DI 3 "register_operand" "0")))
18845 (set (match_operand:DI 1 "register_operand" "=S")
18846 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18847 (match_operand:DI 4 "register_operand" "1")))
18848 (set (mem:BLK (match_dup 3))
18849 (mem:BLK (match_dup 4)))
18850 (use (match_dup 5))]
18853 [(set_attr "type" "str")
18854 (set_attr "prefix_rep" "1")
18855 (set_attr "memory" "both")
18856 (set_attr "mode" "DI")])
18858 (define_insn "*rep_movsi"
18859 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18860 (set (match_operand:SI 0 "register_operand" "=D")
18861 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18863 (match_operand:SI 3 "register_operand" "0")))
18864 (set (match_operand:SI 1 "register_operand" "=S")
18865 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18866 (match_operand:SI 4 "register_operand" "1")))
18867 (set (mem:BLK (match_dup 3))
18868 (mem:BLK (match_dup 4)))
18869 (use (match_dup 5))]
18872 [(set_attr "type" "str")
18873 (set_attr "prefix_rep" "1")
18874 (set_attr "memory" "both")
18875 (set_attr "mode" "SI")])
18877 (define_insn "*rep_movsi_rex64"
18878 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18879 (set (match_operand:DI 0 "register_operand" "=D")
18880 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18882 (match_operand:DI 3 "register_operand" "0")))
18883 (set (match_operand:DI 1 "register_operand" "=S")
18884 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18885 (match_operand:DI 4 "register_operand" "1")))
18886 (set (mem:BLK (match_dup 3))
18887 (mem:BLK (match_dup 4)))
18888 (use (match_dup 5))]
18891 [(set_attr "type" "str")
18892 (set_attr "prefix_rep" "1")
18893 (set_attr "memory" "both")
18894 (set_attr "mode" "SI")])
18896 (define_insn "*rep_movqi"
18897 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18898 (set (match_operand:SI 0 "register_operand" "=D")
18899 (plus:SI (match_operand:SI 3 "register_operand" "0")
18900 (match_operand:SI 5 "register_operand" "2")))
18901 (set (match_operand:SI 1 "register_operand" "=S")
18902 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18903 (set (mem:BLK (match_dup 3))
18904 (mem:BLK (match_dup 4)))
18905 (use (match_dup 5))]
18908 [(set_attr "type" "str")
18909 (set_attr "prefix_rep" "1")
18910 (set_attr "memory" "both")
18911 (set_attr "mode" "SI")])
18913 (define_insn "*rep_movqi_rex64"
18914 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18915 (set (match_operand:DI 0 "register_operand" "=D")
18916 (plus:DI (match_operand:DI 3 "register_operand" "0")
18917 (match_operand:DI 5 "register_operand" "2")))
18918 (set (match_operand:DI 1 "register_operand" "=S")
18919 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18920 (set (mem:BLK (match_dup 3))
18921 (mem:BLK (match_dup 4)))
18922 (use (match_dup 5))]
18925 [(set_attr "type" "str")
18926 (set_attr "prefix_rep" "1")
18927 (set_attr "memory" "both")
18928 (set_attr "mode" "SI")])
18930 (define_expand "setmemsi"
18931 [(use (match_operand:BLK 0 "memory_operand" ""))
18932 (use (match_operand:SI 1 "nonmemory_operand" ""))
18933 (use (match_operand 2 "const_int_operand" ""))
18934 (use (match_operand 3 "const_int_operand" ""))
18935 (use (match_operand:SI 4 "const_int_operand" ""))
18936 (use (match_operand:SI 5 "const_int_operand" ""))]
18939 if (ix86_expand_setmem (operands[0], operands[1],
18940 operands[2], operands[3],
18941 operands[4], operands[5]))
18947 (define_expand "setmemdi"
18948 [(use (match_operand:BLK 0 "memory_operand" ""))
18949 (use (match_operand:DI 1 "nonmemory_operand" ""))
18950 (use (match_operand 2 "const_int_operand" ""))
18951 (use (match_operand 3 "const_int_operand" ""))
18952 (use (match_operand 4 "const_int_operand" ""))
18953 (use (match_operand 5 "const_int_operand" ""))]
18956 if (ix86_expand_setmem (operands[0], operands[1],
18957 operands[2], operands[3],
18958 operands[4], operands[5]))
18964 ;; Most CPUs don't like single string operations
18965 ;; Handle this case here to simplify previous expander.
18967 (define_expand "strset"
18968 [(set (match_operand 1 "memory_operand" "")
18969 (match_operand 2 "register_operand" ""))
18970 (parallel [(set (match_operand 0 "register_operand" "")
18972 (clobber (reg:CC FLAGS_REG))])]
18975 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18976 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18978 /* If .md ever supports :P for Pmode, this can be directly
18979 in the pattern above. */
18980 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18981 GEN_INT (GET_MODE_SIZE (GET_MODE
18983 if (TARGET_SINGLE_STRINGOP || optimize_size)
18985 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18991 (define_expand "strset_singleop"
18992 [(parallel [(set (match_operand 1 "memory_operand" "")
18993 (match_operand 2 "register_operand" ""))
18994 (set (match_operand 0 "register_operand" "")
18995 (match_operand 3 "" ""))])]
18996 "TARGET_SINGLE_STRINGOP || optimize_size"
18999 (define_insn "*strsetdi_rex_1"
19000 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19001 (match_operand:DI 2 "register_operand" "a"))
19002 (set (match_operand:DI 0 "register_operand" "=D")
19003 (plus:DI (match_dup 1)
19005 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19007 [(set_attr "type" "str")
19008 (set_attr "memory" "store")
19009 (set_attr "mode" "DI")])
19011 (define_insn "*strsetsi_1"
19012 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19013 (match_operand:SI 2 "register_operand" "a"))
19014 (set (match_operand:SI 0 "register_operand" "=D")
19015 (plus:SI (match_dup 1)
19017 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19019 [(set_attr "type" "str")
19020 (set_attr "memory" "store")
19021 (set_attr "mode" "SI")])
19023 (define_insn "*strsetsi_rex_1"
19024 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19025 (match_operand:SI 2 "register_operand" "a"))
19026 (set (match_operand:DI 0 "register_operand" "=D")
19027 (plus:DI (match_dup 1)
19029 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19031 [(set_attr "type" "str")
19032 (set_attr "memory" "store")
19033 (set_attr "mode" "SI")])
19035 (define_insn "*strsethi_1"
19036 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19037 (match_operand:HI 2 "register_operand" "a"))
19038 (set (match_operand:SI 0 "register_operand" "=D")
19039 (plus:SI (match_dup 1)
19041 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19043 [(set_attr "type" "str")
19044 (set_attr "memory" "store")
19045 (set_attr "mode" "HI")])
19047 (define_insn "*strsethi_rex_1"
19048 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19049 (match_operand:HI 2 "register_operand" "a"))
19050 (set (match_operand:DI 0 "register_operand" "=D")
19051 (plus:DI (match_dup 1)
19053 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19055 [(set_attr "type" "str")
19056 (set_attr "memory" "store")
19057 (set_attr "mode" "HI")])
19059 (define_insn "*strsetqi_1"
19060 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19061 (match_operand:QI 2 "register_operand" "a"))
19062 (set (match_operand:SI 0 "register_operand" "=D")
19063 (plus:SI (match_dup 1)
19065 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19067 [(set_attr "type" "str")
19068 (set_attr "memory" "store")
19069 (set_attr "mode" "QI")])
19071 (define_insn "*strsetqi_rex_1"
19072 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19073 (match_operand:QI 2 "register_operand" "a"))
19074 (set (match_operand:DI 0 "register_operand" "=D")
19075 (plus:DI (match_dup 1)
19077 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19079 [(set_attr "type" "str")
19080 (set_attr "memory" "store")
19081 (set_attr "mode" "QI")])
19083 (define_expand "rep_stos"
19084 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19085 (set (match_operand 0 "register_operand" "")
19086 (match_operand 4 "" ""))
19087 (set (match_operand 2 "memory_operand" "") (const_int 0))
19088 (use (match_operand 3 "register_operand" ""))
19089 (use (match_dup 1))])]
19093 (define_insn "*rep_stosdi_rex64"
19094 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19095 (set (match_operand:DI 0 "register_operand" "=D")
19096 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19098 (match_operand:DI 3 "register_operand" "0")))
19099 (set (mem:BLK (match_dup 3))
19101 (use (match_operand:DI 2 "register_operand" "a"))
19102 (use (match_dup 4))]
19105 [(set_attr "type" "str")
19106 (set_attr "prefix_rep" "1")
19107 (set_attr "memory" "store")
19108 (set_attr "mode" "DI")])
19110 (define_insn "*rep_stossi"
19111 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19112 (set (match_operand:SI 0 "register_operand" "=D")
19113 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19115 (match_operand:SI 3 "register_operand" "0")))
19116 (set (mem:BLK (match_dup 3))
19118 (use (match_operand:SI 2 "register_operand" "a"))
19119 (use (match_dup 4))]
19122 [(set_attr "type" "str")
19123 (set_attr "prefix_rep" "1")
19124 (set_attr "memory" "store")
19125 (set_attr "mode" "SI")])
19127 (define_insn "*rep_stossi_rex64"
19128 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19129 (set (match_operand:DI 0 "register_operand" "=D")
19130 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19132 (match_operand:DI 3 "register_operand" "0")))
19133 (set (mem:BLK (match_dup 3))
19135 (use (match_operand:SI 2 "register_operand" "a"))
19136 (use (match_dup 4))]
19139 [(set_attr "type" "str")
19140 (set_attr "prefix_rep" "1")
19141 (set_attr "memory" "store")
19142 (set_attr "mode" "SI")])
19144 (define_insn "*rep_stosqi"
19145 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19146 (set (match_operand:SI 0 "register_operand" "=D")
19147 (plus:SI (match_operand:SI 3 "register_operand" "0")
19148 (match_operand:SI 4 "register_operand" "1")))
19149 (set (mem:BLK (match_dup 3))
19151 (use (match_operand:QI 2 "register_operand" "a"))
19152 (use (match_dup 4))]
19155 [(set_attr "type" "str")
19156 (set_attr "prefix_rep" "1")
19157 (set_attr "memory" "store")
19158 (set_attr "mode" "QI")])
19160 (define_insn "*rep_stosqi_rex64"
19161 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19162 (set (match_operand:DI 0 "register_operand" "=D")
19163 (plus:DI (match_operand:DI 3 "register_operand" "0")
19164 (match_operand:DI 4 "register_operand" "1")))
19165 (set (mem:BLK (match_dup 3))
19167 (use (match_operand:QI 2 "register_operand" "a"))
19168 (use (match_dup 4))]
19171 [(set_attr "type" "str")
19172 (set_attr "prefix_rep" "1")
19173 (set_attr "memory" "store")
19174 (set_attr "mode" "QI")])
19176 (define_expand "cmpstrnsi"
19177 [(set (match_operand:SI 0 "register_operand" "")
19178 (compare:SI (match_operand:BLK 1 "general_operand" "")
19179 (match_operand:BLK 2 "general_operand" "")))
19180 (use (match_operand 3 "general_operand" ""))
19181 (use (match_operand 4 "immediate_operand" ""))]
19182 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19184 rtx addr1, addr2, out, outlow, count, countreg, align;
19186 /* Can't use this if the user has appropriated esi or edi. */
19187 if (global_regs[4] || global_regs[5])
19192 out = gen_reg_rtx (SImode);
19194 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19195 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19196 if (addr1 != XEXP (operands[1], 0))
19197 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19198 if (addr2 != XEXP (operands[2], 0))
19199 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19201 count = operands[3];
19202 countreg = ix86_zero_extend_to_Pmode (count);
19204 /* %%% Iff we are testing strict equality, we can use known alignment
19205 to good advantage. This may be possible with combine, particularly
19206 once cc0 is dead. */
19207 align = operands[4];
19209 if (CONST_INT_P (count))
19211 if (INTVAL (count) == 0)
19213 emit_move_insn (operands[0], const0_rtx);
19216 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19217 operands[1], operands[2]));
19222 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19224 emit_insn (gen_cmpsi_1 (countreg, countreg));
19225 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19226 operands[1], operands[2]));
19229 outlow = gen_lowpart (QImode, out);
19230 emit_insn (gen_cmpintqi (outlow));
19231 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19233 if (operands[0] != out)
19234 emit_move_insn (operands[0], out);
19239 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19241 (define_expand "cmpintqi"
19242 [(set (match_dup 1)
19243 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19245 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19246 (parallel [(set (match_operand:QI 0 "register_operand" "")
19247 (minus:QI (match_dup 1)
19249 (clobber (reg:CC FLAGS_REG))])]
19251 "operands[1] = gen_reg_rtx (QImode);
19252 operands[2] = gen_reg_rtx (QImode);")
19254 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19255 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19257 (define_expand "cmpstrnqi_nz_1"
19258 [(parallel [(set (reg:CC FLAGS_REG)
19259 (compare:CC (match_operand 4 "memory_operand" "")
19260 (match_operand 5 "memory_operand" "")))
19261 (use (match_operand 2 "register_operand" ""))
19262 (use (match_operand:SI 3 "immediate_operand" ""))
19263 (clobber (match_operand 0 "register_operand" ""))
19264 (clobber (match_operand 1 "register_operand" ""))
19265 (clobber (match_dup 2))])]
19269 (define_insn "*cmpstrnqi_nz_1"
19270 [(set (reg:CC FLAGS_REG)
19271 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19272 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19273 (use (match_operand:SI 6 "register_operand" "2"))
19274 (use (match_operand:SI 3 "immediate_operand" "i"))
19275 (clobber (match_operand:SI 0 "register_operand" "=S"))
19276 (clobber (match_operand:SI 1 "register_operand" "=D"))
19277 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19280 [(set_attr "type" "str")
19281 (set_attr "mode" "QI")
19282 (set_attr "prefix_rep" "1")])
19284 (define_insn "*cmpstrnqi_nz_rex_1"
19285 [(set (reg:CC FLAGS_REG)
19286 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19287 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19288 (use (match_operand:DI 6 "register_operand" "2"))
19289 (use (match_operand:SI 3 "immediate_operand" "i"))
19290 (clobber (match_operand:DI 0 "register_operand" "=S"))
19291 (clobber (match_operand:DI 1 "register_operand" "=D"))
19292 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19295 [(set_attr "type" "str")
19296 (set_attr "mode" "QI")
19297 (set_attr "prefix_rep" "1")])
19299 ;; The same, but the count is not known to not be zero.
19301 (define_expand "cmpstrnqi_1"
19302 [(parallel [(set (reg:CC FLAGS_REG)
19303 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19305 (compare:CC (match_operand 4 "memory_operand" "")
19306 (match_operand 5 "memory_operand" ""))
19308 (use (match_operand:SI 3 "immediate_operand" ""))
19309 (use (reg:CC FLAGS_REG))
19310 (clobber (match_operand 0 "register_operand" ""))
19311 (clobber (match_operand 1 "register_operand" ""))
19312 (clobber (match_dup 2))])]
19316 (define_insn "*cmpstrnqi_1"
19317 [(set (reg:CC FLAGS_REG)
19318 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19320 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19321 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19323 (use (match_operand:SI 3 "immediate_operand" "i"))
19324 (use (reg:CC FLAGS_REG))
19325 (clobber (match_operand:SI 0 "register_operand" "=S"))
19326 (clobber (match_operand:SI 1 "register_operand" "=D"))
19327 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19330 [(set_attr "type" "str")
19331 (set_attr "mode" "QI")
19332 (set_attr "prefix_rep" "1")])
19334 (define_insn "*cmpstrnqi_rex_1"
19335 [(set (reg:CC FLAGS_REG)
19336 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19338 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19339 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19341 (use (match_operand:SI 3 "immediate_operand" "i"))
19342 (use (reg:CC FLAGS_REG))
19343 (clobber (match_operand:DI 0 "register_operand" "=S"))
19344 (clobber (match_operand:DI 1 "register_operand" "=D"))
19345 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19348 [(set_attr "type" "str")
19349 (set_attr "mode" "QI")
19350 (set_attr "prefix_rep" "1")])
19352 (define_expand "strlensi"
19353 [(set (match_operand:SI 0 "register_operand" "")
19354 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19355 (match_operand:QI 2 "immediate_operand" "")
19356 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19359 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19365 (define_expand "strlendi"
19366 [(set (match_operand:DI 0 "register_operand" "")
19367 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19368 (match_operand:QI 2 "immediate_operand" "")
19369 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19372 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19378 (define_expand "strlenqi_1"
19379 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19380 (clobber (match_operand 1 "register_operand" ""))
19381 (clobber (reg:CC FLAGS_REG))])]
19385 (define_insn "*strlenqi_1"
19386 [(set (match_operand:SI 0 "register_operand" "=&c")
19387 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19388 (match_operand:QI 2 "register_operand" "a")
19389 (match_operand:SI 3 "immediate_operand" "i")
19390 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19391 (clobber (match_operand:SI 1 "register_operand" "=D"))
19392 (clobber (reg:CC FLAGS_REG))]
19395 [(set_attr "type" "str")
19396 (set_attr "mode" "QI")
19397 (set_attr "prefix_rep" "1")])
19399 (define_insn "*strlenqi_rex_1"
19400 [(set (match_operand:DI 0 "register_operand" "=&c")
19401 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19402 (match_operand:QI 2 "register_operand" "a")
19403 (match_operand:DI 3 "immediate_operand" "i")
19404 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19405 (clobber (match_operand:DI 1 "register_operand" "=D"))
19406 (clobber (reg:CC FLAGS_REG))]
19409 [(set_attr "type" "str")
19410 (set_attr "mode" "QI")
19411 (set_attr "prefix_rep" "1")])
19413 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19414 ;; handled in combine, but it is not currently up to the task.
19415 ;; When used for their truth value, the cmpstrn* expanders generate
19424 ;; The intermediate three instructions are unnecessary.
19426 ;; This one handles cmpstrn*_nz_1...
19429 (set (reg:CC FLAGS_REG)
19430 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19431 (mem:BLK (match_operand 5 "register_operand" ""))))
19432 (use (match_operand 6 "register_operand" ""))
19433 (use (match_operand:SI 3 "immediate_operand" ""))
19434 (clobber (match_operand 0 "register_operand" ""))
19435 (clobber (match_operand 1 "register_operand" ""))
19436 (clobber (match_operand 2 "register_operand" ""))])
19437 (set (match_operand:QI 7 "register_operand" "")
19438 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19439 (set (match_operand:QI 8 "register_operand" "")
19440 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19441 (set (reg FLAGS_REG)
19442 (compare (match_dup 7) (match_dup 8)))
19444 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19446 (set (reg:CC FLAGS_REG)
19447 (compare:CC (mem:BLK (match_dup 4))
19448 (mem:BLK (match_dup 5))))
19449 (use (match_dup 6))
19450 (use (match_dup 3))
19451 (clobber (match_dup 0))
19452 (clobber (match_dup 1))
19453 (clobber (match_dup 2))])]
19456 ;; ...and this one handles cmpstrn*_1.
19459 (set (reg:CC FLAGS_REG)
19460 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19462 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19463 (mem:BLK (match_operand 5 "register_operand" "")))
19465 (use (match_operand:SI 3 "immediate_operand" ""))
19466 (use (reg:CC FLAGS_REG))
19467 (clobber (match_operand 0 "register_operand" ""))
19468 (clobber (match_operand 1 "register_operand" ""))
19469 (clobber (match_operand 2 "register_operand" ""))])
19470 (set (match_operand:QI 7 "register_operand" "")
19471 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19472 (set (match_operand:QI 8 "register_operand" "")
19473 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19474 (set (reg FLAGS_REG)
19475 (compare (match_dup 7) (match_dup 8)))
19477 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19479 (set (reg:CC FLAGS_REG)
19480 (if_then_else:CC (ne (match_dup 6)
19482 (compare:CC (mem:BLK (match_dup 4))
19483 (mem:BLK (match_dup 5)))
19485 (use (match_dup 3))
19486 (use (reg:CC FLAGS_REG))
19487 (clobber (match_dup 0))
19488 (clobber (match_dup 1))
19489 (clobber (match_dup 2))])]
19494 ;; Conditional move instructions.
19496 (define_expand "movdicc"
19497 [(set (match_operand:DI 0 "register_operand" "")
19498 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19499 (match_operand:DI 2 "general_operand" "")
19500 (match_operand:DI 3 "general_operand" "")))]
19502 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19504 (define_insn "x86_movdicc_0_m1_rex64"
19505 [(set (match_operand:DI 0 "register_operand" "=r")
19506 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19509 (clobber (reg:CC FLAGS_REG))]
19512 ; Since we don't have the proper number of operands for an alu insn,
19513 ; fill in all the blanks.
19514 [(set_attr "type" "alu")
19515 (set_attr "pent_pair" "pu")
19516 (set_attr "memory" "none")
19517 (set_attr "imm_disp" "false")
19518 (set_attr "mode" "DI")
19519 (set_attr "length_immediate" "0")])
19521 (define_insn "*movdicc_c_rex64"
19522 [(set (match_operand:DI 0 "register_operand" "=r,r")
19523 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19524 [(reg FLAGS_REG) (const_int 0)])
19525 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19526 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19527 "TARGET_64BIT && TARGET_CMOVE
19528 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19530 cmov%O2%C1\t{%2, %0|%0, %2}
19531 cmov%O2%c1\t{%3, %0|%0, %3}"
19532 [(set_attr "type" "icmov")
19533 (set_attr "mode" "DI")])
19535 (define_expand "movsicc"
19536 [(set (match_operand:SI 0 "register_operand" "")
19537 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19538 (match_operand:SI 2 "general_operand" "")
19539 (match_operand:SI 3 "general_operand" "")))]
19541 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19543 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19544 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19545 ;; So just document what we're doing explicitly.
19547 (define_insn "x86_movsicc_0_m1"
19548 [(set (match_operand:SI 0 "register_operand" "=r")
19549 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19552 (clobber (reg:CC FLAGS_REG))]
19555 ; Since we don't have the proper number of operands for an alu insn,
19556 ; fill in all the blanks.
19557 [(set_attr "type" "alu")
19558 (set_attr "pent_pair" "pu")
19559 (set_attr "memory" "none")
19560 (set_attr "imm_disp" "false")
19561 (set_attr "mode" "SI")
19562 (set_attr "length_immediate" "0")])
19564 (define_insn "*movsicc_noc"
19565 [(set (match_operand:SI 0 "register_operand" "=r,r")
19566 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19567 [(reg FLAGS_REG) (const_int 0)])
19568 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19569 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19571 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19573 cmov%O2%C1\t{%2, %0|%0, %2}
19574 cmov%O2%c1\t{%3, %0|%0, %3}"
19575 [(set_attr "type" "icmov")
19576 (set_attr "mode" "SI")])
19578 (define_expand "movhicc"
19579 [(set (match_operand:HI 0 "register_operand" "")
19580 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19581 (match_operand:HI 2 "general_operand" "")
19582 (match_operand:HI 3 "general_operand" "")))]
19583 "TARGET_HIMODE_MATH"
19584 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19586 (define_insn "*movhicc_noc"
19587 [(set (match_operand:HI 0 "register_operand" "=r,r")
19588 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19589 [(reg FLAGS_REG) (const_int 0)])
19590 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19591 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19593 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19595 cmov%O2%C1\t{%2, %0|%0, %2}
19596 cmov%O2%c1\t{%3, %0|%0, %3}"
19597 [(set_attr "type" "icmov")
19598 (set_attr "mode" "HI")])
19600 (define_expand "movqicc"
19601 [(set (match_operand:QI 0 "register_operand" "")
19602 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19603 (match_operand:QI 2 "general_operand" "")
19604 (match_operand:QI 3 "general_operand" "")))]
19605 "TARGET_QIMODE_MATH"
19606 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19608 (define_insn_and_split "*movqicc_noc"
19609 [(set (match_operand:QI 0 "register_operand" "=r,r")
19610 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19611 [(match_operand 4 "flags_reg_operand" "")
19613 (match_operand:QI 2 "register_operand" "r,0")
19614 (match_operand:QI 3 "register_operand" "0,r")))]
19615 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19617 "&& reload_completed"
19618 [(set (match_dup 0)
19619 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19622 "operands[0] = gen_lowpart (SImode, operands[0]);
19623 operands[2] = gen_lowpart (SImode, operands[2]);
19624 operands[3] = gen_lowpart (SImode, operands[3]);"
19625 [(set_attr "type" "icmov")
19626 (set_attr "mode" "SI")])
19628 (define_expand "movsfcc"
19629 [(set (match_operand:SF 0 "register_operand" "")
19630 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19631 (match_operand:SF 2 "register_operand" "")
19632 (match_operand:SF 3 "register_operand" "")))]
19633 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19634 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19636 (define_insn "*movsfcc_1_387"
19637 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19638 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19639 [(reg FLAGS_REG) (const_int 0)])
19640 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19641 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19642 "TARGET_80387 && TARGET_CMOVE
19643 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19645 fcmov%F1\t{%2, %0|%0, %2}
19646 fcmov%f1\t{%3, %0|%0, %3}
19647 cmov%O2%C1\t{%2, %0|%0, %2}
19648 cmov%O2%c1\t{%3, %0|%0, %3}"
19649 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19650 (set_attr "mode" "SF,SF,SI,SI")])
19652 (define_expand "movdfcc"
19653 [(set (match_operand:DF 0 "register_operand" "")
19654 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19655 (match_operand:DF 2 "register_operand" "")
19656 (match_operand:DF 3 "register_operand" "")))]
19657 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19658 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19660 (define_insn "*movdfcc_1"
19661 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19662 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19663 [(reg FLAGS_REG) (const_int 0)])
19664 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19665 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19666 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19667 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19669 fcmov%F1\t{%2, %0|%0, %2}
19670 fcmov%f1\t{%3, %0|%0, %3}
19673 [(set_attr "type" "fcmov,fcmov,multi,multi")
19674 (set_attr "mode" "DF")])
19676 (define_insn "*movdfcc_1_rex64"
19677 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19678 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19679 [(reg FLAGS_REG) (const_int 0)])
19680 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19681 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19682 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19683 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19685 fcmov%F1\t{%2, %0|%0, %2}
19686 fcmov%f1\t{%3, %0|%0, %3}
19687 cmov%O2%C1\t{%2, %0|%0, %2}
19688 cmov%O2%c1\t{%3, %0|%0, %3}"
19689 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19690 (set_attr "mode" "DF")])
19693 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19694 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19695 [(match_operand 4 "flags_reg_operand" "")
19697 (match_operand:DF 2 "nonimmediate_operand" "")
19698 (match_operand:DF 3 "nonimmediate_operand" "")))]
19699 "!TARGET_64BIT && reload_completed"
19700 [(set (match_dup 2)
19701 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19705 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19708 "split_di (operands+2, 1, operands+5, operands+6);
19709 split_di (operands+3, 1, operands+7, operands+8);
19710 split_di (operands, 1, operands+2, operands+3);")
19712 (define_expand "movxfcc"
19713 [(set (match_operand:XF 0 "register_operand" "")
19714 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19715 (match_operand:XF 2 "register_operand" "")
19716 (match_operand:XF 3 "register_operand" "")))]
19717 "TARGET_80387 && TARGET_CMOVE"
19718 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19720 (define_insn "*movxfcc_1"
19721 [(set (match_operand:XF 0 "register_operand" "=f,f")
19722 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19723 [(reg FLAGS_REG) (const_int 0)])
19724 (match_operand:XF 2 "register_operand" "f,0")
19725 (match_operand:XF 3 "register_operand" "0,f")))]
19726 "TARGET_80387 && TARGET_CMOVE"
19728 fcmov%F1\t{%2, %0|%0, %2}
19729 fcmov%f1\t{%3, %0|%0, %3}"
19730 [(set_attr "type" "fcmov")
19731 (set_attr "mode" "XF")])
19733 ;; SSE5 conditional move
19734 (define_insn "*sse5_pcmov_<mode>"
19735 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,x")
19736 (if_then_else:MODEF
19737 (match_operand:MODEF 1 "nonimmediate_operand" "xm,x,0,0")
19738 (match_operand:MODEF 2 "nonimmediate_operand" "0,0,x,xm")
19739 (match_operand:MODEF 3 "vector_move_operand" "x,xm,xm,x")))]
19740 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19741 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19742 [(set_attr "type" "sse4arg")])
19744 ;; These versions of the min/max patterns are intentionally ignorant of
19745 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19746 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19747 ;; are undefined in this condition, we're certain this is correct.
19749 (define_insn "sminsf3"
19750 [(set (match_operand:SF 0 "register_operand" "=x")
19751 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19752 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19754 "minss\t{%2, %0|%0, %2}"
19755 [(set_attr "type" "sseadd")
19756 (set_attr "mode" "SF")])
19758 (define_insn "smaxsf3"
19759 [(set (match_operand:SF 0 "register_operand" "=x")
19760 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19761 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19763 "maxss\t{%2, %0|%0, %2}"
19764 [(set_attr "type" "sseadd")
19765 (set_attr "mode" "SF")])
19767 (define_insn "smindf3"
19768 [(set (match_operand:DF 0 "register_operand" "=x")
19769 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19770 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19771 "TARGET_SSE2 && TARGET_SSE_MATH"
19772 "minsd\t{%2, %0|%0, %2}"
19773 [(set_attr "type" "sseadd")
19774 (set_attr "mode" "DF")])
19776 (define_insn "smaxdf3"
19777 [(set (match_operand:DF 0 "register_operand" "=x")
19778 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19779 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19780 "TARGET_SSE2 && TARGET_SSE_MATH"
19781 "maxsd\t{%2, %0|%0, %2}"
19782 [(set_attr "type" "sseadd")
19783 (set_attr "mode" "DF")])
19785 ;; These versions of the min/max patterns implement exactly the operations
19786 ;; min = (op1 < op2 ? op1 : op2)
19787 ;; max = (!(op1 < op2) ? op1 : op2)
19788 ;; Their operands are not commutative, and thus they may be used in the
19789 ;; presence of -0.0 and NaN.
19791 (define_insn "*ieee_sminsf3"
19792 [(set (match_operand:SF 0 "register_operand" "=x")
19793 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19794 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19797 "minss\t{%2, %0|%0, %2}"
19798 [(set_attr "type" "sseadd")
19799 (set_attr "mode" "SF")])
19801 (define_insn "*ieee_smaxsf3"
19802 [(set (match_operand:SF 0 "register_operand" "=x")
19803 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19804 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19807 "maxss\t{%2, %0|%0, %2}"
19808 [(set_attr "type" "sseadd")
19809 (set_attr "mode" "SF")])
19811 (define_insn "*ieee_smindf3"
19812 [(set (match_operand:DF 0 "register_operand" "=x")
19813 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19814 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19816 "TARGET_SSE2 && TARGET_SSE_MATH"
19817 "minsd\t{%2, %0|%0, %2}"
19818 [(set_attr "type" "sseadd")
19819 (set_attr "mode" "DF")])
19821 (define_insn "*ieee_smaxdf3"
19822 [(set (match_operand:DF 0 "register_operand" "=x")
19823 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19824 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19826 "TARGET_SSE2 && TARGET_SSE_MATH"
19827 "maxsd\t{%2, %0|%0, %2}"
19828 [(set_attr "type" "sseadd")
19829 (set_attr "mode" "DF")])
19831 ;; Make two stack loads independent:
19833 ;; fld %st(0) -> fld bb
19834 ;; fmul bb fmul %st(1), %st
19836 ;; Actually we only match the last two instructions for simplicity.
19838 [(set (match_operand 0 "fp_register_operand" "")
19839 (match_operand 1 "fp_register_operand" ""))
19841 (match_operator 2 "binary_fp_operator"
19843 (match_operand 3 "memory_operand" "")]))]
19844 "REGNO (operands[0]) != REGNO (operands[1])"
19845 [(set (match_dup 0) (match_dup 3))
19846 (set (match_dup 0) (match_dup 4))]
19848 ;; The % modifier is not operational anymore in peephole2's, so we have to
19849 ;; swap the operands manually in the case of addition and multiplication.
19850 "if (COMMUTATIVE_ARITH_P (operands[2]))
19851 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19852 operands[0], operands[1]);
19854 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19855 operands[1], operands[0]);")
19857 ;; Conditional addition patterns
19858 (define_expand "addqicc"
19859 [(match_operand:QI 0 "register_operand" "")
19860 (match_operand 1 "comparison_operator" "")
19861 (match_operand:QI 2 "register_operand" "")
19862 (match_operand:QI 3 "const_int_operand" "")]
19864 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19866 (define_expand "addhicc"
19867 [(match_operand:HI 0 "register_operand" "")
19868 (match_operand 1 "comparison_operator" "")
19869 (match_operand:HI 2 "register_operand" "")
19870 (match_operand:HI 3 "const_int_operand" "")]
19872 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19874 (define_expand "addsicc"
19875 [(match_operand:SI 0 "register_operand" "")
19876 (match_operand 1 "comparison_operator" "")
19877 (match_operand:SI 2 "register_operand" "")
19878 (match_operand:SI 3 "const_int_operand" "")]
19880 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19882 (define_expand "adddicc"
19883 [(match_operand:DI 0 "register_operand" "")
19884 (match_operand 1 "comparison_operator" "")
19885 (match_operand:DI 2 "register_operand" "")
19886 (match_operand:DI 3 "const_int_operand" "")]
19888 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19891 ;; Misc patterns (?)
19893 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19894 ;; Otherwise there will be nothing to keep
19896 ;; [(set (reg ebp) (reg esp))]
19897 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19898 ;; (clobber (eflags)]
19899 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19901 ;; in proper program order.
19902 (define_insn "pro_epilogue_adjust_stack_1"
19903 [(set (match_operand:SI 0 "register_operand" "=r,r")
19904 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19905 (match_operand:SI 2 "immediate_operand" "i,i")))
19906 (clobber (reg:CC FLAGS_REG))
19907 (clobber (mem:BLK (scratch)))]
19910 switch (get_attr_type (insn))
19913 return "mov{l}\t{%1, %0|%0, %1}";
19916 if (CONST_INT_P (operands[2])
19917 && (INTVAL (operands[2]) == 128
19918 || (INTVAL (operands[2]) < 0
19919 && INTVAL (operands[2]) != -128)))
19921 operands[2] = GEN_INT (-INTVAL (operands[2]));
19922 return "sub{l}\t{%2, %0|%0, %2}";
19924 return "add{l}\t{%2, %0|%0, %2}";
19927 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19928 return "lea{l}\t{%a2, %0|%0, %a2}";
19931 gcc_unreachable ();
19934 [(set (attr "type")
19935 (cond [(eq_attr "alternative" "0")
19936 (const_string "alu")
19937 (match_operand:SI 2 "const0_operand" "")
19938 (const_string "imov")
19940 (const_string "lea")))
19941 (set_attr "mode" "SI")])
19943 (define_insn "pro_epilogue_adjust_stack_rex64"
19944 [(set (match_operand:DI 0 "register_operand" "=r,r")
19945 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19946 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19947 (clobber (reg:CC FLAGS_REG))
19948 (clobber (mem:BLK (scratch)))]
19951 switch (get_attr_type (insn))
19954 return "mov{q}\t{%1, %0|%0, %1}";
19957 if (CONST_INT_P (operands[2])
19958 /* Avoid overflows. */
19959 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19960 && (INTVAL (operands[2]) == 128
19961 || (INTVAL (operands[2]) < 0
19962 && INTVAL (operands[2]) != -128)))
19964 operands[2] = GEN_INT (-INTVAL (operands[2]));
19965 return "sub{q}\t{%2, %0|%0, %2}";
19967 return "add{q}\t{%2, %0|%0, %2}";
19970 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19971 return "lea{q}\t{%a2, %0|%0, %a2}";
19974 gcc_unreachable ();
19977 [(set (attr "type")
19978 (cond [(eq_attr "alternative" "0")
19979 (const_string "alu")
19980 (match_operand:DI 2 "const0_operand" "")
19981 (const_string "imov")
19983 (const_string "lea")))
19984 (set_attr "mode" "DI")])
19986 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19987 [(set (match_operand:DI 0 "register_operand" "=r,r")
19988 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19989 (match_operand:DI 3 "immediate_operand" "i,i")))
19990 (use (match_operand:DI 2 "register_operand" "r,r"))
19991 (clobber (reg:CC FLAGS_REG))
19992 (clobber (mem:BLK (scratch)))]
19995 switch (get_attr_type (insn))
19998 return "add{q}\t{%2, %0|%0, %2}";
20001 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20002 return "lea{q}\t{%a2, %0|%0, %a2}";
20005 gcc_unreachable ();
20008 [(set_attr "type" "alu,lea")
20009 (set_attr "mode" "DI")])
20011 (define_insn "allocate_stack_worker_32"
20012 [(set (match_operand:SI 0 "register_operand" "+a")
20013 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
20014 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
20015 (clobber (reg:CC FLAGS_REG))]
20016 "!TARGET_64BIT && TARGET_STACK_PROBE"
20018 [(set_attr "type" "multi")
20019 (set_attr "length" "5")])
20021 (define_insn "allocate_stack_worker_64"
20022 [(set (match_operand:DI 0 "register_operand" "=a")
20023 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
20024 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
20025 (clobber (reg:DI R10_REG))
20026 (clobber (reg:DI R11_REG))
20027 (clobber (reg:CC FLAGS_REG))]
20028 "TARGET_64BIT && TARGET_STACK_PROBE"
20030 [(set_attr "type" "multi")
20031 (set_attr "length" "5")])
20033 (define_expand "allocate_stack"
20034 [(match_operand 0 "register_operand" "")
20035 (match_operand 1 "general_operand" "")]
20036 "TARGET_STACK_PROBE"
20040 #ifndef CHECK_STACK_LIMIT
20041 #define CHECK_STACK_LIMIT 0
20044 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20045 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20047 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20048 stack_pointer_rtx, 0, OPTAB_DIRECT);
20049 if (x != stack_pointer_rtx)
20050 emit_move_insn (stack_pointer_rtx, x);
20054 x = copy_to_mode_reg (Pmode, operands[1]);
20056 x = gen_allocate_stack_worker_64 (x);
20058 x = gen_allocate_stack_worker_32 (x);
20062 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20066 (define_expand "builtin_setjmp_receiver"
20067 [(label_ref (match_operand 0 "" ""))]
20068 "!TARGET_64BIT && flag_pic"
20073 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20074 rtx label_rtx = gen_label_rtx ();
20075 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20076 xops[0] = xops[1] = picreg;
20077 xops[2] = gen_rtx_CONST (SImode,
20078 gen_rtx_MINUS (SImode,
20079 gen_rtx_LABEL_REF (SImode, label_rtx),
20080 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
20081 ix86_expand_binary_operator (MINUS, SImode, xops);
20084 emit_insn (gen_set_got (pic_offset_table_rtx));
20088 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20091 [(set (match_operand 0 "register_operand" "")
20092 (match_operator 3 "promotable_binary_operator"
20093 [(match_operand 1 "register_operand" "")
20094 (match_operand 2 "aligned_operand" "")]))
20095 (clobber (reg:CC FLAGS_REG))]
20096 "! TARGET_PARTIAL_REG_STALL && reload_completed
20097 && ((GET_MODE (operands[0]) == HImode
20098 && ((!optimize_size && !TARGET_FAST_PREFIX)
20099 /* ??? next two lines just !satisfies_constraint_K (...) */
20100 || !CONST_INT_P (operands[2])
20101 || satisfies_constraint_K (operands[2])))
20102 || (GET_MODE (operands[0]) == QImode
20103 && (TARGET_PROMOTE_QImode || optimize_size)))"
20104 [(parallel [(set (match_dup 0)
20105 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20106 (clobber (reg:CC FLAGS_REG))])]
20107 "operands[0] = gen_lowpart (SImode, operands[0]);
20108 operands[1] = gen_lowpart (SImode, operands[1]);
20109 if (GET_CODE (operands[3]) != ASHIFT)
20110 operands[2] = gen_lowpart (SImode, operands[2]);
20111 PUT_MODE (operands[3], SImode);")
20113 ; Promote the QImode tests, as i386 has encoding of the AND
20114 ; instruction with 32-bit sign-extended immediate and thus the
20115 ; instruction size is unchanged, except in the %eax case for
20116 ; which it is increased by one byte, hence the ! optimize_size.
20118 [(set (match_operand 0 "flags_reg_operand" "")
20119 (match_operator 2 "compare_operator"
20120 [(and (match_operand 3 "aligned_operand" "")
20121 (match_operand 4 "const_int_operand" ""))
20123 (set (match_operand 1 "register_operand" "")
20124 (and (match_dup 3) (match_dup 4)))]
20125 "! TARGET_PARTIAL_REG_STALL && reload_completed
20127 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20128 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20129 /* Ensure that the operand will remain sign-extended immediate. */
20130 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20131 [(parallel [(set (match_dup 0)
20132 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20135 (and:SI (match_dup 3) (match_dup 4)))])]
20138 = gen_int_mode (INTVAL (operands[4])
20139 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20140 operands[1] = gen_lowpart (SImode, operands[1]);
20141 operands[3] = gen_lowpart (SImode, operands[3]);
20144 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20145 ; the TEST instruction with 32-bit sign-extended immediate and thus
20146 ; the instruction size would at least double, which is not what we
20147 ; want even with ! optimize_size.
20149 [(set (match_operand 0 "flags_reg_operand" "")
20150 (match_operator 1 "compare_operator"
20151 [(and (match_operand:HI 2 "aligned_operand" "")
20152 (match_operand:HI 3 "const_int_operand" ""))
20154 "! TARGET_PARTIAL_REG_STALL && reload_completed
20155 && ! TARGET_FAST_PREFIX
20157 /* Ensure that the operand will remain sign-extended immediate. */
20158 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20159 [(set (match_dup 0)
20160 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20164 = gen_int_mode (INTVAL (operands[3])
20165 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20166 operands[2] = gen_lowpart (SImode, operands[2]);
20170 [(set (match_operand 0 "register_operand" "")
20171 (neg (match_operand 1 "register_operand" "")))
20172 (clobber (reg:CC FLAGS_REG))]
20173 "! TARGET_PARTIAL_REG_STALL && reload_completed
20174 && (GET_MODE (operands[0]) == HImode
20175 || (GET_MODE (operands[0]) == QImode
20176 && (TARGET_PROMOTE_QImode || optimize_size)))"
20177 [(parallel [(set (match_dup 0)
20178 (neg:SI (match_dup 1)))
20179 (clobber (reg:CC FLAGS_REG))])]
20180 "operands[0] = gen_lowpart (SImode, operands[0]);
20181 operands[1] = gen_lowpart (SImode, operands[1]);")
20184 [(set (match_operand 0 "register_operand" "")
20185 (not (match_operand 1 "register_operand" "")))]
20186 "! TARGET_PARTIAL_REG_STALL && reload_completed
20187 && (GET_MODE (operands[0]) == HImode
20188 || (GET_MODE (operands[0]) == QImode
20189 && (TARGET_PROMOTE_QImode || optimize_size)))"
20190 [(set (match_dup 0)
20191 (not:SI (match_dup 1)))]
20192 "operands[0] = gen_lowpart (SImode, operands[0]);
20193 operands[1] = gen_lowpart (SImode, operands[1]);")
20196 [(set (match_operand 0 "register_operand" "")
20197 (if_then_else (match_operator 1 "comparison_operator"
20198 [(reg FLAGS_REG) (const_int 0)])
20199 (match_operand 2 "register_operand" "")
20200 (match_operand 3 "register_operand" "")))]
20201 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20202 && (GET_MODE (operands[0]) == HImode
20203 || (GET_MODE (operands[0]) == QImode
20204 && (TARGET_PROMOTE_QImode || optimize_size)))"
20205 [(set (match_dup 0)
20206 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20207 "operands[0] = gen_lowpart (SImode, operands[0]);
20208 operands[2] = gen_lowpart (SImode, operands[2]);
20209 operands[3] = gen_lowpart (SImode, operands[3]);")
20212 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20213 ;; transform a complex memory operation into two memory to register operations.
20215 ;; Don't push memory operands
20217 [(set (match_operand:SI 0 "push_operand" "")
20218 (match_operand:SI 1 "memory_operand" ""))
20219 (match_scratch:SI 2 "r")]
20220 "!optimize_size && !TARGET_PUSH_MEMORY
20221 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20222 [(set (match_dup 2) (match_dup 1))
20223 (set (match_dup 0) (match_dup 2))]
20227 [(set (match_operand:DI 0 "push_operand" "")
20228 (match_operand:DI 1 "memory_operand" ""))
20229 (match_scratch:DI 2 "r")]
20230 "!optimize_size && !TARGET_PUSH_MEMORY
20231 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20232 [(set (match_dup 2) (match_dup 1))
20233 (set (match_dup 0) (match_dup 2))]
20236 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20239 [(set (match_operand:SF 0 "push_operand" "")
20240 (match_operand:SF 1 "memory_operand" ""))
20241 (match_scratch:SF 2 "r")]
20242 "!optimize_size && !TARGET_PUSH_MEMORY
20243 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20244 [(set (match_dup 2) (match_dup 1))
20245 (set (match_dup 0) (match_dup 2))]
20249 [(set (match_operand:HI 0 "push_operand" "")
20250 (match_operand:HI 1 "memory_operand" ""))
20251 (match_scratch:HI 2 "r")]
20252 "!optimize_size && !TARGET_PUSH_MEMORY
20253 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20254 [(set (match_dup 2) (match_dup 1))
20255 (set (match_dup 0) (match_dup 2))]
20259 [(set (match_operand:QI 0 "push_operand" "")
20260 (match_operand:QI 1 "memory_operand" ""))
20261 (match_scratch:QI 2 "q")]
20262 "!optimize_size && !TARGET_PUSH_MEMORY
20263 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20264 [(set (match_dup 2) (match_dup 1))
20265 (set (match_dup 0) (match_dup 2))]
20268 ;; Don't move an immediate directly to memory when the instruction
20271 [(match_scratch:SI 1 "r")
20272 (set (match_operand:SI 0 "memory_operand" "")
20275 && ! TARGET_USE_MOV0
20276 && TARGET_SPLIT_LONG_MOVES
20277 && get_attr_length (insn) >= ix86_cost->large_insn
20278 && peep2_regno_dead_p (0, FLAGS_REG)"
20279 [(parallel [(set (match_dup 1) (const_int 0))
20280 (clobber (reg:CC FLAGS_REG))])
20281 (set (match_dup 0) (match_dup 1))]
20285 [(match_scratch:HI 1 "r")
20286 (set (match_operand:HI 0 "memory_operand" "")
20289 && ! TARGET_USE_MOV0
20290 && TARGET_SPLIT_LONG_MOVES
20291 && get_attr_length (insn) >= ix86_cost->large_insn
20292 && peep2_regno_dead_p (0, FLAGS_REG)"
20293 [(parallel [(set (match_dup 2) (const_int 0))
20294 (clobber (reg:CC FLAGS_REG))])
20295 (set (match_dup 0) (match_dup 1))]
20296 "operands[2] = gen_lowpart (SImode, operands[1]);")
20299 [(match_scratch:QI 1 "q")
20300 (set (match_operand:QI 0 "memory_operand" "")
20303 && ! TARGET_USE_MOV0
20304 && TARGET_SPLIT_LONG_MOVES
20305 && get_attr_length (insn) >= ix86_cost->large_insn
20306 && peep2_regno_dead_p (0, FLAGS_REG)"
20307 [(parallel [(set (match_dup 2) (const_int 0))
20308 (clobber (reg:CC FLAGS_REG))])
20309 (set (match_dup 0) (match_dup 1))]
20310 "operands[2] = gen_lowpart (SImode, operands[1]);")
20313 [(match_scratch:SI 2 "r")
20314 (set (match_operand:SI 0 "memory_operand" "")
20315 (match_operand:SI 1 "immediate_operand" ""))]
20317 && TARGET_SPLIT_LONG_MOVES
20318 && get_attr_length (insn) >= ix86_cost->large_insn"
20319 [(set (match_dup 2) (match_dup 1))
20320 (set (match_dup 0) (match_dup 2))]
20324 [(match_scratch:HI 2 "r")
20325 (set (match_operand:HI 0 "memory_operand" "")
20326 (match_operand:HI 1 "immediate_operand" ""))]
20328 && TARGET_SPLIT_LONG_MOVES
20329 && get_attr_length (insn) >= ix86_cost->large_insn"
20330 [(set (match_dup 2) (match_dup 1))
20331 (set (match_dup 0) (match_dup 2))]
20335 [(match_scratch:QI 2 "q")
20336 (set (match_operand:QI 0 "memory_operand" "")
20337 (match_operand:QI 1 "immediate_operand" ""))]
20339 && TARGET_SPLIT_LONG_MOVES
20340 && get_attr_length (insn) >= ix86_cost->large_insn"
20341 [(set (match_dup 2) (match_dup 1))
20342 (set (match_dup 0) (match_dup 2))]
20345 ;; Don't compare memory with zero, load and use a test instead.
20347 [(set (match_operand 0 "flags_reg_operand" "")
20348 (match_operator 1 "compare_operator"
20349 [(match_operand:SI 2 "memory_operand" "")
20351 (match_scratch:SI 3 "r")]
20352 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20353 [(set (match_dup 3) (match_dup 2))
20354 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20357 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20358 ;; Don't split NOTs with a displacement operand, because resulting XOR
20359 ;; will not be pairable anyway.
20361 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20362 ;; represented using a modRM byte. The XOR replacement is long decoded,
20363 ;; so this split helps here as well.
20365 ;; Note: Can't do this as a regular split because we can't get proper
20366 ;; lifetime information then.
20369 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20370 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20372 && ((TARGET_NOT_UNPAIRABLE
20373 && (!MEM_P (operands[0])
20374 || !memory_displacement_operand (operands[0], SImode)))
20375 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20376 && peep2_regno_dead_p (0, FLAGS_REG)"
20377 [(parallel [(set (match_dup 0)
20378 (xor:SI (match_dup 1) (const_int -1)))
20379 (clobber (reg:CC FLAGS_REG))])]
20383 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20384 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20386 && ((TARGET_NOT_UNPAIRABLE
20387 && (!MEM_P (operands[0])
20388 || !memory_displacement_operand (operands[0], HImode)))
20389 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20390 && peep2_regno_dead_p (0, FLAGS_REG)"
20391 [(parallel [(set (match_dup 0)
20392 (xor:HI (match_dup 1) (const_int -1)))
20393 (clobber (reg:CC FLAGS_REG))])]
20397 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20398 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20400 && ((TARGET_NOT_UNPAIRABLE
20401 && (!MEM_P (operands[0])
20402 || !memory_displacement_operand (operands[0], QImode)))
20403 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20404 && peep2_regno_dead_p (0, FLAGS_REG)"
20405 [(parallel [(set (match_dup 0)
20406 (xor:QI (match_dup 1) (const_int -1)))
20407 (clobber (reg:CC FLAGS_REG))])]
20410 ;; Non pairable "test imm, reg" instructions can be translated to
20411 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20412 ;; byte opcode instead of two, have a short form for byte operands),
20413 ;; so do it for other CPUs as well. Given that the value was dead,
20414 ;; this should not create any new dependencies. Pass on the sub-word
20415 ;; versions if we're concerned about partial register stalls.
20418 [(set (match_operand 0 "flags_reg_operand" "")
20419 (match_operator 1 "compare_operator"
20420 [(and:SI (match_operand:SI 2 "register_operand" "")
20421 (match_operand:SI 3 "immediate_operand" ""))
20423 "ix86_match_ccmode (insn, CCNOmode)
20424 && (true_regnum (operands[2]) != 0
20425 || satisfies_constraint_K (operands[3]))
20426 && peep2_reg_dead_p (1, operands[2])"
20428 [(set (match_dup 0)
20429 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20432 (and:SI (match_dup 2) (match_dup 3)))])]
20435 ;; We don't need to handle HImode case, because it will be promoted to SImode
20436 ;; on ! TARGET_PARTIAL_REG_STALL
20439 [(set (match_operand 0 "flags_reg_operand" "")
20440 (match_operator 1 "compare_operator"
20441 [(and:QI (match_operand:QI 2 "register_operand" "")
20442 (match_operand:QI 3 "immediate_operand" ""))
20444 "! TARGET_PARTIAL_REG_STALL
20445 && ix86_match_ccmode (insn, CCNOmode)
20446 && true_regnum (operands[2]) != 0
20447 && peep2_reg_dead_p (1, operands[2])"
20449 [(set (match_dup 0)
20450 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20453 (and:QI (match_dup 2) (match_dup 3)))])]
20457 [(set (match_operand 0 "flags_reg_operand" "")
20458 (match_operator 1 "compare_operator"
20461 (match_operand 2 "ext_register_operand" "")
20464 (match_operand 3 "const_int_operand" ""))
20466 "! TARGET_PARTIAL_REG_STALL
20467 && ix86_match_ccmode (insn, CCNOmode)
20468 && true_regnum (operands[2]) != 0
20469 && peep2_reg_dead_p (1, operands[2])"
20470 [(parallel [(set (match_dup 0)
20479 (set (zero_extract:SI (match_dup 2)
20490 ;; Don't do logical operations with memory inputs.
20492 [(match_scratch:SI 2 "r")
20493 (parallel [(set (match_operand:SI 0 "register_operand" "")
20494 (match_operator:SI 3 "arith_or_logical_operator"
20496 (match_operand:SI 1 "memory_operand" "")]))
20497 (clobber (reg:CC FLAGS_REG))])]
20498 "! optimize_size && ! TARGET_READ_MODIFY"
20499 [(set (match_dup 2) (match_dup 1))
20500 (parallel [(set (match_dup 0)
20501 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20502 (clobber (reg:CC FLAGS_REG))])]
20506 [(match_scratch:SI 2 "r")
20507 (parallel [(set (match_operand:SI 0 "register_operand" "")
20508 (match_operator:SI 3 "arith_or_logical_operator"
20509 [(match_operand:SI 1 "memory_operand" "")
20511 (clobber (reg:CC FLAGS_REG))])]
20512 "! optimize_size && ! TARGET_READ_MODIFY"
20513 [(set (match_dup 2) (match_dup 1))
20514 (parallel [(set (match_dup 0)
20515 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20516 (clobber (reg:CC FLAGS_REG))])]
20519 ; Don't do logical operations with memory outputs
20521 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20522 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20523 ; the same decoder scheduling characteristics as the original.
20526 [(match_scratch:SI 2 "r")
20527 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20528 (match_operator:SI 3 "arith_or_logical_operator"
20530 (match_operand:SI 1 "nonmemory_operand" "")]))
20531 (clobber (reg:CC FLAGS_REG))])]
20532 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20533 [(set (match_dup 2) (match_dup 0))
20534 (parallel [(set (match_dup 2)
20535 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20536 (clobber (reg:CC FLAGS_REG))])
20537 (set (match_dup 0) (match_dup 2))]
20541 [(match_scratch:SI 2 "r")
20542 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20543 (match_operator:SI 3 "arith_or_logical_operator"
20544 [(match_operand:SI 1 "nonmemory_operand" "")
20546 (clobber (reg:CC FLAGS_REG))])]
20547 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20548 [(set (match_dup 2) (match_dup 0))
20549 (parallel [(set (match_dup 2)
20550 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20551 (clobber (reg:CC FLAGS_REG))])
20552 (set (match_dup 0) (match_dup 2))]
20555 ;; Attempt to always use XOR for zeroing registers.
20557 [(set (match_operand 0 "register_operand" "")
20558 (match_operand 1 "const0_operand" ""))]
20559 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20560 && (! TARGET_USE_MOV0 || optimize_size)
20561 && GENERAL_REG_P (operands[0])
20562 && peep2_regno_dead_p (0, FLAGS_REG)"
20563 [(parallel [(set (match_dup 0) (const_int 0))
20564 (clobber (reg:CC FLAGS_REG))])]
20566 operands[0] = gen_lowpart (word_mode, operands[0]);
20570 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20572 "(GET_MODE (operands[0]) == QImode
20573 || GET_MODE (operands[0]) == HImode)
20574 && (! TARGET_USE_MOV0 || optimize_size)
20575 && peep2_regno_dead_p (0, FLAGS_REG)"
20576 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20577 (clobber (reg:CC FLAGS_REG))])])
20579 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20581 [(set (match_operand 0 "register_operand" "")
20583 "(GET_MODE (operands[0]) == HImode
20584 || GET_MODE (operands[0]) == SImode
20585 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20586 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20587 && peep2_regno_dead_p (0, FLAGS_REG)"
20588 [(parallel [(set (match_dup 0) (const_int -1))
20589 (clobber (reg:CC FLAGS_REG))])]
20590 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20593 ;; Attempt to convert simple leas to adds. These can be created by
20596 [(set (match_operand:SI 0 "register_operand" "")
20597 (plus:SI (match_dup 0)
20598 (match_operand:SI 1 "nonmemory_operand" "")))]
20599 "peep2_regno_dead_p (0, FLAGS_REG)"
20600 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20601 (clobber (reg:CC FLAGS_REG))])]
20605 [(set (match_operand:SI 0 "register_operand" "")
20606 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20607 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20608 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20609 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20610 (clobber (reg:CC FLAGS_REG))])]
20611 "operands[2] = gen_lowpart (SImode, operands[2]);")
20614 [(set (match_operand:DI 0 "register_operand" "")
20615 (plus:DI (match_dup 0)
20616 (match_operand:DI 1 "x86_64_general_operand" "")))]
20617 "peep2_regno_dead_p (0, FLAGS_REG)"
20618 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20619 (clobber (reg:CC FLAGS_REG))])]
20623 [(set (match_operand:SI 0 "register_operand" "")
20624 (mult:SI (match_dup 0)
20625 (match_operand:SI 1 "const_int_operand" "")))]
20626 "exact_log2 (INTVAL (operands[1])) >= 0
20627 && peep2_regno_dead_p (0, FLAGS_REG)"
20628 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20629 (clobber (reg:CC FLAGS_REG))])]
20630 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20633 [(set (match_operand:DI 0 "register_operand" "")
20634 (mult:DI (match_dup 0)
20635 (match_operand:DI 1 "const_int_operand" "")))]
20636 "exact_log2 (INTVAL (operands[1])) >= 0
20637 && peep2_regno_dead_p (0, FLAGS_REG)"
20638 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20639 (clobber (reg:CC FLAGS_REG))])]
20640 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20643 [(set (match_operand:SI 0 "register_operand" "")
20644 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20645 (match_operand:DI 2 "const_int_operand" "")) 0))]
20646 "exact_log2 (INTVAL (operands[2])) >= 0
20647 && REGNO (operands[0]) == REGNO (operands[1])
20648 && peep2_regno_dead_p (0, FLAGS_REG)"
20649 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20650 (clobber (reg:CC FLAGS_REG))])]
20651 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20653 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20654 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20655 ;; many CPUs it is also faster, since special hardware to avoid esp
20656 ;; dependencies is present.
20658 ;; While some of these conversions may be done using splitters, we use peepholes
20659 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20661 ;; Convert prologue esp subtractions to push.
20662 ;; We need register to push. In order to keep verify_flow_info happy we have
20664 ;; - use scratch and clobber it in order to avoid dependencies
20665 ;; - use already live register
20666 ;; We can't use the second way right now, since there is no reliable way how to
20667 ;; verify that given register is live. First choice will also most likely in
20668 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20669 ;; call clobbered registers are dead. We may want to use base pointer as an
20670 ;; alternative when no register is available later.
20673 [(match_scratch:SI 0 "r")
20674 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20675 (clobber (reg:CC FLAGS_REG))
20676 (clobber (mem:BLK (scratch)))])]
20677 "optimize_size || !TARGET_SUB_ESP_4"
20678 [(clobber (match_dup 0))
20679 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20680 (clobber (mem:BLK (scratch)))])])
20683 [(match_scratch:SI 0 "r")
20684 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20685 (clobber (reg:CC FLAGS_REG))
20686 (clobber (mem:BLK (scratch)))])]
20687 "optimize_size || !TARGET_SUB_ESP_8"
20688 [(clobber (match_dup 0))
20689 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20690 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20691 (clobber (mem:BLK (scratch)))])])
20693 ;; Convert esp subtractions to push.
20695 [(match_scratch:SI 0 "r")
20696 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20697 (clobber (reg:CC FLAGS_REG))])]
20698 "optimize_size || !TARGET_SUB_ESP_4"
20699 [(clobber (match_dup 0))
20700 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20703 [(match_scratch:SI 0 "r")
20704 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20705 (clobber (reg:CC FLAGS_REG))])]
20706 "optimize_size || !TARGET_SUB_ESP_8"
20707 [(clobber (match_dup 0))
20708 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20709 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20711 ;; Convert epilogue deallocator to pop.
20713 [(match_scratch:SI 0 "r")
20714 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20715 (clobber (reg:CC FLAGS_REG))
20716 (clobber (mem:BLK (scratch)))])]
20717 "optimize_size || !TARGET_ADD_ESP_4"
20718 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20719 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20720 (clobber (mem:BLK (scratch)))])]
20723 ;; Two pops case is tricky, since pop causes dependency on destination register.
20724 ;; We use two registers if available.
20726 [(match_scratch:SI 0 "r")
20727 (match_scratch:SI 1 "r")
20728 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20729 (clobber (reg:CC FLAGS_REG))
20730 (clobber (mem:BLK (scratch)))])]
20731 "optimize_size || !TARGET_ADD_ESP_8"
20732 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20733 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20734 (clobber (mem:BLK (scratch)))])
20735 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20736 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20740 [(match_scratch:SI 0 "r")
20741 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20742 (clobber (reg:CC FLAGS_REG))
20743 (clobber (mem:BLK (scratch)))])]
20745 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20746 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20747 (clobber (mem:BLK (scratch)))])
20748 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20749 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20752 ;; Convert esp additions to pop.
20754 [(match_scratch:SI 0 "r")
20755 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20756 (clobber (reg:CC FLAGS_REG))])]
20758 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20759 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20762 ;; Two pops case is tricky, since pop causes dependency on destination register.
20763 ;; We use two registers if available.
20765 [(match_scratch:SI 0 "r")
20766 (match_scratch:SI 1 "r")
20767 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20768 (clobber (reg:CC FLAGS_REG))])]
20770 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20771 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20772 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20773 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20777 [(match_scratch:SI 0 "r")
20778 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20779 (clobber (reg:CC FLAGS_REG))])]
20781 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20782 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20783 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20784 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20787 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20788 ;; required and register dies. Similarly for 128 to plus -128.
20790 [(set (match_operand 0 "flags_reg_operand" "")
20791 (match_operator 1 "compare_operator"
20792 [(match_operand 2 "register_operand" "")
20793 (match_operand 3 "const_int_operand" "")]))]
20794 "(INTVAL (operands[3]) == -1
20795 || INTVAL (operands[3]) == 1
20796 || INTVAL (operands[3]) == 128)
20797 && ix86_match_ccmode (insn, CCGCmode)
20798 && peep2_reg_dead_p (1, operands[2])"
20799 [(parallel [(set (match_dup 0)
20800 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20801 (clobber (match_dup 2))])]
20805 [(match_scratch:DI 0 "r")
20806 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20807 (clobber (reg:CC FLAGS_REG))
20808 (clobber (mem:BLK (scratch)))])]
20809 "optimize_size || !TARGET_SUB_ESP_4"
20810 [(clobber (match_dup 0))
20811 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20812 (clobber (mem:BLK (scratch)))])])
20815 [(match_scratch:DI 0 "r")
20816 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20817 (clobber (reg:CC FLAGS_REG))
20818 (clobber (mem:BLK (scratch)))])]
20819 "optimize_size || !TARGET_SUB_ESP_8"
20820 [(clobber (match_dup 0))
20821 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20822 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20823 (clobber (mem:BLK (scratch)))])])
20825 ;; Convert esp subtractions to push.
20827 [(match_scratch:DI 0 "r")
20828 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20829 (clobber (reg:CC FLAGS_REG))])]
20830 "optimize_size || !TARGET_SUB_ESP_4"
20831 [(clobber (match_dup 0))
20832 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20835 [(match_scratch:DI 0 "r")
20836 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20837 (clobber (reg:CC FLAGS_REG))])]
20838 "optimize_size || !TARGET_SUB_ESP_8"
20839 [(clobber (match_dup 0))
20840 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20841 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20843 ;; Convert epilogue deallocator to pop.
20845 [(match_scratch:DI 0 "r")
20846 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20847 (clobber (reg:CC FLAGS_REG))
20848 (clobber (mem:BLK (scratch)))])]
20849 "optimize_size || !TARGET_ADD_ESP_4"
20850 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20851 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20852 (clobber (mem:BLK (scratch)))])]
20855 ;; Two pops case is tricky, since pop causes dependency on destination register.
20856 ;; We use two registers if available.
20858 [(match_scratch:DI 0 "r")
20859 (match_scratch:DI 1 "r")
20860 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20861 (clobber (reg:CC FLAGS_REG))
20862 (clobber (mem:BLK (scratch)))])]
20863 "optimize_size || !TARGET_ADD_ESP_8"
20864 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20865 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20866 (clobber (mem:BLK (scratch)))])
20867 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20868 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20872 [(match_scratch:DI 0 "r")
20873 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20874 (clobber (reg:CC FLAGS_REG))
20875 (clobber (mem:BLK (scratch)))])]
20877 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20878 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20879 (clobber (mem:BLK (scratch)))])
20880 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20881 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20884 ;; Convert esp additions to pop.
20886 [(match_scratch:DI 0 "r")
20887 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20888 (clobber (reg:CC FLAGS_REG))])]
20890 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20891 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20894 ;; Two pops case is tricky, since pop causes dependency on destination register.
20895 ;; We use two registers if available.
20897 [(match_scratch:DI 0 "r")
20898 (match_scratch:DI 1 "r")
20899 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20900 (clobber (reg:CC FLAGS_REG))])]
20902 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20903 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20904 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20905 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20909 [(match_scratch:DI 0 "r")
20910 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20911 (clobber (reg:CC FLAGS_REG))])]
20913 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20914 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20915 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20916 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20919 ;; Convert imul by three, five and nine into lea
20922 [(set (match_operand:SI 0 "register_operand" "")
20923 (mult:SI (match_operand:SI 1 "register_operand" "")
20924 (match_operand:SI 2 "const_int_operand" "")))
20925 (clobber (reg:CC FLAGS_REG))])]
20926 "INTVAL (operands[2]) == 3
20927 || INTVAL (operands[2]) == 5
20928 || INTVAL (operands[2]) == 9"
20929 [(set (match_dup 0)
20930 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20932 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20936 [(set (match_operand:SI 0 "register_operand" "")
20937 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20938 (match_operand:SI 2 "const_int_operand" "")))
20939 (clobber (reg:CC FLAGS_REG))])]
20941 && (INTVAL (operands[2]) == 3
20942 || INTVAL (operands[2]) == 5
20943 || INTVAL (operands[2]) == 9)"
20944 [(set (match_dup 0) (match_dup 1))
20946 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20948 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20952 [(set (match_operand:DI 0 "register_operand" "")
20953 (mult:DI (match_operand:DI 1 "register_operand" "")
20954 (match_operand:DI 2 "const_int_operand" "")))
20955 (clobber (reg:CC FLAGS_REG))])]
20957 && (INTVAL (operands[2]) == 3
20958 || INTVAL (operands[2]) == 5
20959 || INTVAL (operands[2]) == 9)"
20960 [(set (match_dup 0)
20961 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20963 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20967 [(set (match_operand:DI 0 "register_operand" "")
20968 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20969 (match_operand:DI 2 "const_int_operand" "")))
20970 (clobber (reg:CC FLAGS_REG))])]
20973 && (INTVAL (operands[2]) == 3
20974 || INTVAL (operands[2]) == 5
20975 || INTVAL (operands[2]) == 9)"
20976 [(set (match_dup 0) (match_dup 1))
20978 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20980 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20982 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20983 ;; imul $32bit_imm, reg, reg is direct decoded.
20985 [(match_scratch:DI 3 "r")
20986 (parallel [(set (match_operand:DI 0 "register_operand" "")
20987 (mult:DI (match_operand:DI 1 "memory_operand" "")
20988 (match_operand:DI 2 "immediate_operand" "")))
20989 (clobber (reg:CC FLAGS_REG))])]
20990 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20991 && !satisfies_constraint_K (operands[2])"
20992 [(set (match_dup 3) (match_dup 1))
20993 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20994 (clobber (reg:CC FLAGS_REG))])]
20998 [(match_scratch:SI 3 "r")
20999 (parallel [(set (match_operand:SI 0 "register_operand" "")
21000 (mult:SI (match_operand:SI 1 "memory_operand" "")
21001 (match_operand:SI 2 "immediate_operand" "")))
21002 (clobber (reg:CC FLAGS_REG))])]
21003 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
21004 && !satisfies_constraint_K (operands[2])"
21005 [(set (match_dup 3) (match_dup 1))
21006 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21007 (clobber (reg:CC FLAGS_REG))])]
21011 [(match_scratch:SI 3 "r")
21012 (parallel [(set (match_operand:DI 0 "register_operand" "")
21014 (mult:SI (match_operand:SI 1 "memory_operand" "")
21015 (match_operand:SI 2 "immediate_operand" ""))))
21016 (clobber (reg:CC FLAGS_REG))])]
21017 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
21018 && !satisfies_constraint_K (operands[2])"
21019 [(set (match_dup 3) (match_dup 1))
21020 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21021 (clobber (reg:CC FLAGS_REG))])]
21024 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21025 ;; Convert it into imul reg, reg
21026 ;; It would be better to force assembler to encode instruction using long
21027 ;; immediate, but there is apparently no way to do so.
21029 [(parallel [(set (match_operand:DI 0 "register_operand" "")
21030 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21031 (match_operand:DI 2 "const_int_operand" "")))
21032 (clobber (reg:CC FLAGS_REG))])
21033 (match_scratch:DI 3 "r")]
21034 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
21035 && satisfies_constraint_K (operands[2])"
21036 [(set (match_dup 3) (match_dup 2))
21037 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21038 (clobber (reg:CC FLAGS_REG))])]
21040 if (!rtx_equal_p (operands[0], operands[1]))
21041 emit_move_insn (operands[0], operands[1]);
21045 [(parallel [(set (match_operand:SI 0 "register_operand" "")
21046 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21047 (match_operand:SI 2 "const_int_operand" "")))
21048 (clobber (reg:CC FLAGS_REG))])
21049 (match_scratch:SI 3 "r")]
21050 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
21051 && satisfies_constraint_K (operands[2])"
21052 [(set (match_dup 3) (match_dup 2))
21053 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21054 (clobber (reg:CC FLAGS_REG))])]
21056 if (!rtx_equal_p (operands[0], operands[1]))
21057 emit_move_insn (operands[0], operands[1]);
21061 [(parallel [(set (match_operand:HI 0 "register_operand" "")
21062 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21063 (match_operand:HI 2 "immediate_operand" "")))
21064 (clobber (reg:CC FLAGS_REG))])
21065 (match_scratch:HI 3 "r")]
21066 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
21067 [(set (match_dup 3) (match_dup 2))
21068 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21069 (clobber (reg:CC FLAGS_REG))])]
21071 if (!rtx_equal_p (operands[0], operands[1]))
21072 emit_move_insn (operands[0], operands[1]);
21075 ;; After splitting up read-modify operations, array accesses with memory
21076 ;; operands might end up in form:
21078 ;; movl 4(%esp), %edx
21080 ;; instead of pre-splitting:
21082 ;; addl 4(%esp), %eax
21084 ;; movl 4(%esp), %edx
21085 ;; leal (%edx,%eax,4), %eax
21088 [(parallel [(set (match_operand 0 "register_operand" "")
21089 (ashift (match_operand 1 "register_operand" "")
21090 (match_operand 2 "const_int_operand" "")))
21091 (clobber (reg:CC FLAGS_REG))])
21092 (set (match_operand 3 "register_operand")
21093 (match_operand 4 "x86_64_general_operand" ""))
21094 (parallel [(set (match_operand 5 "register_operand" "")
21095 (plus (match_operand 6 "register_operand" "")
21096 (match_operand 7 "register_operand" "")))
21097 (clobber (reg:CC FLAGS_REG))])]
21098 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21099 /* Validate MODE for lea. */
21100 && ((!TARGET_PARTIAL_REG_STALL
21101 && (GET_MODE (operands[0]) == QImode
21102 || GET_MODE (operands[0]) == HImode))
21103 || GET_MODE (operands[0]) == SImode
21104 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21105 /* We reorder load and the shift. */
21106 && !rtx_equal_p (operands[1], operands[3])
21107 && !reg_overlap_mentioned_p (operands[0], operands[4])
21108 /* Last PLUS must consist of operand 0 and 3. */
21109 && !rtx_equal_p (operands[0], operands[3])
21110 && (rtx_equal_p (operands[3], operands[6])
21111 || rtx_equal_p (operands[3], operands[7]))
21112 && (rtx_equal_p (operands[0], operands[6])
21113 || rtx_equal_p (operands[0], operands[7]))
21114 /* The intermediate operand 0 must die or be same as output. */
21115 && (rtx_equal_p (operands[0], operands[5])
21116 || peep2_reg_dead_p (3, operands[0]))"
21117 [(set (match_dup 3) (match_dup 4))
21118 (set (match_dup 0) (match_dup 1))]
21120 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21121 int scale = 1 << INTVAL (operands[2]);
21122 rtx index = gen_lowpart (Pmode, operands[1]);
21123 rtx base = gen_lowpart (Pmode, operands[3]);
21124 rtx dest = gen_lowpart (mode, operands[5]);
21126 operands[1] = gen_rtx_PLUS (Pmode, base,
21127 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21129 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21130 operands[0] = dest;
21133 ;; Call-value patterns last so that the wildcard operand does not
21134 ;; disrupt insn-recog's switch tables.
21136 (define_insn "*call_value_pop_0"
21137 [(set (match_operand 0 "" "")
21138 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21139 (match_operand:SI 2 "" "")))
21140 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21141 (match_operand:SI 3 "immediate_operand" "")))]
21144 if (SIBLING_CALL_P (insn))
21147 return "call\t%P1";
21149 [(set_attr "type" "callv")])
21151 (define_insn "*call_value_pop_1"
21152 [(set (match_operand 0 "" "")
21153 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21154 (match_operand:SI 2 "" "")))
21155 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21156 (match_operand:SI 3 "immediate_operand" "i")))]
21159 if (constant_call_address_operand (operands[1], Pmode))
21161 if (SIBLING_CALL_P (insn))
21164 return "call\t%P1";
21166 if (SIBLING_CALL_P (insn))
21169 return "call\t%A1";
21171 [(set_attr "type" "callv")])
21173 (define_insn "*call_value_0"
21174 [(set (match_operand 0 "" "")
21175 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21176 (match_operand:SI 2 "" "")))]
21179 if (SIBLING_CALL_P (insn))
21182 return "call\t%P1";
21184 [(set_attr "type" "callv")])
21186 (define_insn "*call_value_0_rex64"
21187 [(set (match_operand 0 "" "")
21188 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21189 (match_operand:DI 2 "const_int_operand" "")))]
21192 if (SIBLING_CALL_P (insn))
21195 return "call\t%P1";
21197 [(set_attr "type" "callv")])
21199 (define_insn "*call_value_1"
21200 [(set (match_operand 0 "" "")
21201 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21202 (match_operand:SI 2 "" "")))]
21203 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21205 if (constant_call_address_operand (operands[1], Pmode))
21206 return "call\t%P1";
21207 return "call\t%A1";
21209 [(set_attr "type" "callv")])
21211 (define_insn "*sibcall_value_1"
21212 [(set (match_operand 0 "" "")
21213 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21214 (match_operand:SI 2 "" "")))]
21215 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21217 if (constant_call_address_operand (operands[1], Pmode))
21221 [(set_attr "type" "callv")])
21223 (define_insn "*call_value_1_rex64"
21224 [(set (match_operand 0 "" "")
21225 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21226 (match_operand:DI 2 "" "")))]
21227 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21228 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21230 if (constant_call_address_operand (operands[1], Pmode))
21231 return "call\t%P1";
21232 return "call\t%A1";
21234 [(set_attr "type" "callv")])
21236 (define_insn "*call_value_1_rex64_large"
21237 [(set (match_operand 0 "" "")
21238 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21239 (match_operand:DI 2 "" "")))]
21240 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21242 [(set_attr "type" "callv")])
21244 (define_insn "*sibcall_value_1_rex64"
21245 [(set (match_operand 0 "" "")
21246 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21247 (match_operand:DI 2 "" "")))]
21248 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21250 [(set_attr "type" "callv")])
21252 (define_insn "*sibcall_value_1_rex64_v"
21253 [(set (match_operand 0 "" "")
21254 (call (mem:QI (reg:DI R11_REG))
21255 (match_operand:DI 1 "" "")))]
21256 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21258 [(set_attr "type" "callv")])
21260 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21261 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21262 ;; caught for use by garbage collectors and the like. Using an insn that
21263 ;; maps to SIGILL makes it more likely the program will rightfully die.
21264 ;; Keeping with tradition, "6" is in honor of #UD.
21265 (define_insn "trap"
21266 [(trap_if (const_int 1) (const_int 6))]
21268 { return ASM_SHORT "0x0b0f"; }
21269 [(set_attr "length" "2")])
21271 (define_expand "sse_prologue_save"
21272 [(parallel [(set (match_operand:BLK 0 "" "")
21273 (unspec:BLK [(reg:DI 21)
21280 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21281 (use (match_operand:DI 1 "register_operand" ""))
21282 (use (match_operand:DI 2 "immediate_operand" ""))
21283 (use (label_ref:DI (match_operand 3 "" "")))])]
21287 (define_insn "*sse_prologue_save_insn"
21288 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21289 (match_operand:DI 4 "const_int_operand" "n")))
21290 (unspec:BLK [(reg:DI 21)
21297 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21298 (use (match_operand:DI 1 "register_operand" "r"))
21299 (use (match_operand:DI 2 "const_int_operand" "i"))
21300 (use (label_ref:DI (match_operand 3 "" "X")))]
21302 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21303 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21307 operands[0] = gen_rtx_MEM (Pmode,
21308 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21309 output_asm_insn (\"jmp\\t%A1\", operands);
21310 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21312 operands[4] = adjust_address (operands[0], DImode, i*16);
21313 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21314 PUT_MODE (operands[4], TImode);
21315 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21316 output_asm_insn (\"rex\", operands);
21317 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21319 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21320 CODE_LABEL_NUMBER (operands[3]));
21324 [(set_attr "type" "other")
21325 (set_attr "length_immediate" "0")
21326 (set_attr "length_address" "0")
21327 (set_attr "length" "135")
21328 (set_attr "memory" "store")
21329 (set_attr "modrm" "0")
21330 (set_attr "mode" "DI")])
21332 (define_expand "prefetch"
21333 [(prefetch (match_operand 0 "address_operand" "")
21334 (match_operand:SI 1 "const_int_operand" "")
21335 (match_operand:SI 2 "const_int_operand" ""))]
21336 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21338 int rw = INTVAL (operands[1]);
21339 int locality = INTVAL (operands[2]);
21341 gcc_assert (rw == 0 || rw == 1);
21342 gcc_assert (locality >= 0 && locality <= 3);
21343 gcc_assert (GET_MODE (operands[0]) == Pmode
21344 || GET_MODE (operands[0]) == VOIDmode);
21346 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21347 supported by SSE counterpart or the SSE prefetch is not available
21348 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21350 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21351 operands[2] = GEN_INT (3);
21353 operands[1] = const0_rtx;
21356 (define_insn "*prefetch_sse"
21357 [(prefetch (match_operand:SI 0 "address_operand" "p")
21359 (match_operand:SI 1 "const_int_operand" ""))]
21360 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21362 static const char * const patterns[4] = {
21363 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21366 int locality = INTVAL (operands[1]);
21367 gcc_assert (locality >= 0 && locality <= 3);
21369 return patterns[locality];
21371 [(set_attr "type" "sse")
21372 (set_attr "memory" "none")])
21374 (define_insn "*prefetch_sse_rex"
21375 [(prefetch (match_operand:DI 0 "address_operand" "p")
21377 (match_operand:SI 1 "const_int_operand" ""))]
21378 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21380 static const char * const patterns[4] = {
21381 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21384 int locality = INTVAL (operands[1]);
21385 gcc_assert (locality >= 0 && locality <= 3);
21387 return patterns[locality];
21389 [(set_attr "type" "sse")
21390 (set_attr "memory" "none")])
21392 (define_insn "*prefetch_3dnow"
21393 [(prefetch (match_operand:SI 0 "address_operand" "p")
21394 (match_operand:SI 1 "const_int_operand" "n")
21396 "TARGET_3DNOW && !TARGET_64BIT"
21398 if (INTVAL (operands[1]) == 0)
21399 return "prefetch\t%a0";
21401 return "prefetchw\t%a0";
21403 [(set_attr "type" "mmx")
21404 (set_attr "memory" "none")])
21406 (define_insn "*prefetch_3dnow_rex"
21407 [(prefetch (match_operand:DI 0 "address_operand" "p")
21408 (match_operand:SI 1 "const_int_operand" "n")
21410 "TARGET_3DNOW && TARGET_64BIT"
21412 if (INTVAL (operands[1]) == 0)
21413 return "prefetch\t%a0";
21415 return "prefetchw\t%a0";
21417 [(set_attr "type" "mmx")
21418 (set_attr "memory" "none")])
21420 (define_expand "stack_protect_set"
21421 [(match_operand 0 "memory_operand" "")
21422 (match_operand 1 "memory_operand" "")]
21425 #ifdef TARGET_THREAD_SSP_OFFSET
21427 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21428 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21430 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21431 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21434 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21436 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21441 (define_insn "stack_protect_set_si"
21442 [(set (match_operand:SI 0 "memory_operand" "=m")
21443 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21444 (set (match_scratch:SI 2 "=&r") (const_int 0))
21445 (clobber (reg:CC FLAGS_REG))]
21447 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21448 [(set_attr "type" "multi")])
21450 (define_insn "stack_protect_set_di"
21451 [(set (match_operand:DI 0 "memory_operand" "=m")
21452 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21453 (set (match_scratch:DI 2 "=&r") (const_int 0))
21454 (clobber (reg:CC FLAGS_REG))]
21456 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21457 [(set_attr "type" "multi")])
21459 (define_insn "stack_tls_protect_set_si"
21460 [(set (match_operand:SI 0 "memory_operand" "=m")
21461 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21462 (set (match_scratch:SI 2 "=&r") (const_int 0))
21463 (clobber (reg:CC FLAGS_REG))]
21465 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21466 [(set_attr "type" "multi")])
21468 (define_insn "stack_tls_protect_set_di"
21469 [(set (match_operand:DI 0 "memory_operand" "=m")
21470 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21471 (set (match_scratch:DI 2 "=&r") (const_int 0))
21472 (clobber (reg:CC FLAGS_REG))]
21475 /* The kernel uses a different segment register for performance reasons; a
21476 system call would not have to trash the userspace segment register,
21477 which would be expensive */
21478 if (ix86_cmodel != CM_KERNEL)
21479 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21481 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21483 [(set_attr "type" "multi")])
21485 (define_expand "stack_protect_test"
21486 [(match_operand 0 "memory_operand" "")
21487 (match_operand 1 "memory_operand" "")
21488 (match_operand 2 "" "")]
21491 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21492 ix86_compare_op0 = operands[0];
21493 ix86_compare_op1 = operands[1];
21494 ix86_compare_emitted = flags;
21496 #ifdef TARGET_THREAD_SSP_OFFSET
21498 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21499 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21501 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21502 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21505 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21507 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21509 emit_jump_insn (gen_beq (operands[2]));
21513 (define_insn "stack_protect_test_si"
21514 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21515 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21516 (match_operand:SI 2 "memory_operand" "m")]
21518 (clobber (match_scratch:SI 3 "=&r"))]
21520 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21521 [(set_attr "type" "multi")])
21523 (define_insn "stack_protect_test_di"
21524 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21525 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21526 (match_operand:DI 2 "memory_operand" "m")]
21528 (clobber (match_scratch:DI 3 "=&r"))]
21530 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21531 [(set_attr "type" "multi")])
21533 (define_insn "stack_tls_protect_test_si"
21534 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21535 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21536 (match_operand:SI 2 "const_int_operand" "i")]
21537 UNSPEC_SP_TLS_TEST))
21538 (clobber (match_scratch:SI 3 "=r"))]
21540 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21541 [(set_attr "type" "multi")])
21543 (define_insn "stack_tls_protect_test_di"
21544 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21545 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21546 (match_operand:DI 2 "const_int_operand" "i")]
21547 UNSPEC_SP_TLS_TEST))
21548 (clobber (match_scratch:DI 3 "=r"))]
21551 /* The kernel uses a different segment register for performance reasons; a
21552 system call would not have to trash the userspace segment register,
21553 which would be expensive */
21554 if (ix86_cmodel != CM_KERNEL)
21555 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21557 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21559 [(set_attr "type" "multi")])
21561 (define_mode_iterator CRC32MODE [QI HI SI])
21562 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21563 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21565 (define_insn "sse4_2_crc32<mode>"
21566 [(set (match_operand:SI 0 "register_operand" "=r")
21568 [(match_operand:SI 1 "register_operand" "0")
21569 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21572 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21573 [(set_attr "type" "sselog1")
21574 (set_attr "prefix_rep" "1")
21575 (set_attr "prefix_extra" "1")
21576 (set_attr "mode" "SI")])
21578 (define_insn "sse4_2_crc32di"
21579 [(set (match_operand:DI 0 "register_operand" "=r")
21581 [(match_operand:DI 1 "register_operand" "0")
21582 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21584 "TARGET_SSE4_2 && TARGET_64BIT"
21585 "crc32q\t{%2, %0|%0, %2}"
21586 [(set_attr "type" "sselog1")
21587 (set_attr "prefix_rep" "1")
21588 (set_attr "prefix_extra" "1")
21589 (set_attr "mode" "DI")])
21593 (include "sync.md")