1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
63 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_SET_GOT_OFFSET 17)
74 (UNSPEC_TLS_LD_BASE 20)
77 ; Other random patterns
86 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
87 (UNSPEC_TRUNC_NOOP 39)
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 40)
108 ; Generic math support
110 (UNSPEC_IEEE_MIN 51) ; not commutative
111 (UNSPEC_IEEE_MAX 52) ; not commutative
126 (UNSPEC_FRNDINT_FLOOR 70)
127 (UNSPEC_FRNDINT_CEIL 71)
128 (UNSPEC_FRNDINT_TRUNC 72)
129 (UNSPEC_FRNDINT_MASK_PM 73)
130 (UNSPEC_FIST_FLOOR 74)
131 (UNSPEC_FIST_CEIL 75)
133 ; x87 Double output FP
134 (UNSPEC_SINCOS_COS 80)
135 (UNSPEC_SINCOS_SIN 81)
136 (UNSPEC_XTRACT_FRACT 84)
137 (UNSPEC_XTRACT_EXP 85)
138 (UNSPEC_FSCALE_FRACT 86)
139 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
161 (UNSPEC_INSERTQI 132)
166 (UNSPEC_INSERTPS 135)
168 (UNSPEC_MOVNTDQA 137)
170 (UNSPEC_PHMINPOSUW 139)
176 (UNSPEC_PCMPESTR 144)
177 (UNSPEC_PCMPISTR 145)
180 (UNSPEC_SSE5_INTRINSIC 150)
181 (UNSPEC_SSE5_UNSIGNED_CMP 151)
182 (UNSPEC_SSE5_TRUEFALSE 152)
183 (UNSPEC_SSE5_PERMUTE 153)
184 (UNSPEC_SSE5_ASHIFT 154)
185 (UNSPEC_SSE5_LSHIFT 155)
187 (UNSPEC_CVTPH2PS 157)
188 (UNSPEC_CVTPS2PH 158)
192 (UNSPEC_AESENCLAST 160)
194 (UNSPEC_AESDECLAST 162)
196 (UNSPEC_AESKEYGENASSIST 164)
203 [(UNSPECV_BLOCKAGE 0)
204 (UNSPECV_STACK_PROBE 1)
213 (UNSPECV_CMPXCHG_1 10)
214 (UNSPECV_CMPXCHG_2 11)
217 (UNSPECV_PROLOGUE_USE 14)
220 ;; Constants to represent pcomtrue/pcomfalse variants
230 ;; Registers by name.
246 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
249 ;; In C guard expressions, put expressions which may be compile-time
250 ;; constants first. This allows for better optimization. For
251 ;; example, write "TARGET_64BIT && reload_completed", not
252 ;; "reload_completed && TARGET_64BIT".
255 ;; Processor type. This attribute must exactly match the processor_type
256 ;; enumeration in i386.h.
257 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
258 nocona,core2,generic32,generic64,amdfam10"
259 (const (symbol_ref "ix86_tune")))
261 ;; A basic instruction type. Refinements due to arguments to be
262 ;; provided in other attributes.
265 alu,alu1,negnot,imov,imovx,lea,
266 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
267 icmp,test,ibr,setcc,icmov,
268 push,pop,call,callv,leave,
270 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
271 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
272 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
274 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
275 (const_string "other"))
277 ;; Main data type used by the insn
279 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
280 (const_string "unknown"))
282 ;; The CPU unit operations uses.
283 (define_attr "unit" "integer,i387,sse,mmx,unknown"
284 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
285 (const_string "i387")
286 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
287 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
288 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
290 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
292 (eq_attr "type" "other")
293 (const_string "unknown")]
294 (const_string "integer")))
296 ;; The (bounding maximum) length of an instruction immediate.
297 (define_attr "length_immediate" ""
298 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
301 (eq_attr "unit" "i387,sse,mmx")
303 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
305 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
306 (eq_attr "type" "imov,test")
307 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
308 (eq_attr "type" "call")
309 (if_then_else (match_operand 0 "constant_call_address_operand" "")
312 (eq_attr "type" "callv")
313 (if_then_else (match_operand 1 "constant_call_address_operand" "")
316 ;; We don't know the size before shorten_branches. Expect
317 ;; the instruction to fit for better scheduling.
318 (eq_attr "type" "ibr")
321 (symbol_ref "/* Update immediate_length and other attributes! */
322 gcc_unreachable (),1")))
324 ;; The (bounding maximum) length of an instruction address.
325 (define_attr "length_address" ""
326 (cond [(eq_attr "type" "str,other,multi,fxch")
328 (and (eq_attr "type" "call")
329 (match_operand 0 "constant_call_address_operand" ""))
331 (and (eq_attr "type" "callv")
332 (match_operand 1 "constant_call_address_operand" ""))
335 (symbol_ref "ix86_attr_length_address_default (insn)")))
337 ;; Set when length prefix is used.
338 (define_attr "prefix_data16" ""
339 (if_then_else (ior (eq_attr "mode" "HI")
340 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
344 ;; Set when string REP prefix is used.
345 (define_attr "prefix_rep" ""
346 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
350 ;; Set when 0f opcode prefix is used.
351 (define_attr "prefix_0f" ""
353 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
354 (eq_attr "unit" "sse,mmx"))
358 ;; Set when REX opcode prefix is used.
359 (define_attr "prefix_rex" ""
360 (cond [(and (eq_attr "mode" "DI")
361 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
363 (and (eq_attr "mode" "QI")
364 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
367 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
373 ;; There are also additional prefixes in SSSE3.
374 (define_attr "prefix_extra" "" (const_int 0))
376 ;; Set when modrm byte is used.
377 (define_attr "modrm" ""
378 (cond [(eq_attr "type" "str,leave")
380 (eq_attr "unit" "i387")
382 (and (eq_attr "type" "incdec")
383 (ior (match_operand:SI 1 "register_operand" "")
384 (match_operand:HI 1 "register_operand" "")))
386 (and (eq_attr "type" "push")
387 (not (match_operand 1 "memory_operand" "")))
389 (and (eq_attr "type" "pop")
390 (not (match_operand 0 "memory_operand" "")))
392 (and (eq_attr "type" "imov")
393 (ior (and (match_operand 0 "register_operand" "")
394 (match_operand 1 "immediate_operand" ""))
395 (ior (and (match_operand 0 "ax_reg_operand" "")
396 (match_operand 1 "memory_displacement_only_operand" ""))
397 (and (match_operand 0 "memory_displacement_only_operand" "")
398 (match_operand 1 "ax_reg_operand" "")))))
400 (and (eq_attr "type" "call")
401 (match_operand 0 "constant_call_address_operand" ""))
403 (and (eq_attr "type" "callv")
404 (match_operand 1 "constant_call_address_operand" ""))
409 ;; The (bounding maximum) length of an instruction in bytes.
410 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
411 ;; Later we may want to split them and compute proper length as for
413 (define_attr "length" ""
414 (cond [(eq_attr "type" "other,multi,fistp,frndint")
416 (eq_attr "type" "fcmp")
418 (eq_attr "unit" "i387")
420 (plus (attr "prefix_data16")
421 (attr "length_address")))]
422 (plus (plus (attr "modrm")
423 (plus (attr "prefix_0f")
424 (plus (attr "prefix_rex")
425 (plus (attr "prefix_extra")
427 (plus (attr "prefix_rep")
428 (plus (attr "prefix_data16")
429 (plus (attr "length_immediate")
430 (attr "length_address")))))))
432 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
433 ;; `store' if there is a simple memory reference therein, or `unknown'
434 ;; if the instruction is complex.
436 (define_attr "memory" "none,load,store,both,unknown"
437 (cond [(eq_attr "type" "other,multi,str")
438 (const_string "unknown")
439 (eq_attr "type" "lea,fcmov,fpspc")
440 (const_string "none")
441 (eq_attr "type" "fistp,leave")
442 (const_string "both")
443 (eq_attr "type" "frndint")
444 (const_string "load")
445 (eq_attr "type" "push")
446 (if_then_else (match_operand 1 "memory_operand" "")
447 (const_string "both")
448 (const_string "store"))
449 (eq_attr "type" "pop")
450 (if_then_else (match_operand 0 "memory_operand" "")
451 (const_string "both")
452 (const_string "load"))
453 (eq_attr "type" "setcc")
454 (if_then_else (match_operand 0 "memory_operand" "")
455 (const_string "store")
456 (const_string "none"))
457 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
458 (if_then_else (ior (match_operand 0 "memory_operand" "")
459 (match_operand 1 "memory_operand" ""))
460 (const_string "load")
461 (const_string "none"))
462 (eq_attr "type" "ibr")
463 (if_then_else (match_operand 0 "memory_operand" "")
464 (const_string "load")
465 (const_string "none"))
466 (eq_attr "type" "call")
467 (if_then_else (match_operand 0 "constant_call_address_operand" "")
468 (const_string "none")
469 (const_string "load"))
470 (eq_attr "type" "callv")
471 (if_then_else (match_operand 1 "constant_call_address_operand" "")
472 (const_string "none")
473 (const_string "load"))
474 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
475 (match_operand 1 "memory_operand" ""))
476 (const_string "both")
477 (and (match_operand 0 "memory_operand" "")
478 (match_operand 1 "memory_operand" ""))
479 (const_string "both")
480 (match_operand 0 "memory_operand" "")
481 (const_string "store")
482 (match_operand 1 "memory_operand" "")
483 (const_string "load")
485 "!alu1,negnot,ishift1,
486 imov,imovx,icmp,test,bitmanip,
488 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
489 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
490 (match_operand 2 "memory_operand" ""))
491 (const_string "load")
492 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
493 (match_operand 3 "memory_operand" ""))
494 (const_string "load")
496 (const_string "none")))
498 ;; Indicates if an instruction has both an immediate and a displacement.
500 (define_attr "imm_disp" "false,true,unknown"
501 (cond [(eq_attr "type" "other,multi")
502 (const_string "unknown")
503 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
504 (and (match_operand 0 "memory_displacement_operand" "")
505 (match_operand 1 "immediate_operand" "")))
506 (const_string "true")
507 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
508 (and (match_operand 0 "memory_displacement_operand" "")
509 (match_operand 2 "immediate_operand" "")))
510 (const_string "true")
512 (const_string "false")))
514 ;; Indicates if an FP operation has an integer source.
516 (define_attr "fp_int_src" "false,true"
517 (const_string "false"))
519 ;; Defines rounding mode of an FP operation.
521 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
522 (const_string "any"))
524 ;; Describe a user's asm statement.
525 (define_asm_attributes
526 [(set_attr "length" "128")
527 (set_attr "type" "multi")])
529 ;; All integer comparison codes.
530 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
532 ;; All floating-point comparison codes.
533 (define_code_iterator fp_cond [unordered ordered
534 uneq unge ungt unle unlt ltgt ])
536 (define_code_iterator plusminus [plus minus])
538 ;; Base name for define_insn and insn mnemonic.
539 (define_code_attr addsub [(plus "add") (minus "sub")])
541 ;; Mark commutative operators as such in constraints.
542 (define_code_attr comm [(plus "%") (minus "")])
544 ;; Mapping of signed max and min
545 (define_code_iterator smaxmin [smax smin])
547 ;; Mapping of unsigned max and min
548 (define_code_iterator umaxmin [umax umin])
550 ;; Base name for integer and FP insn mnemonic
551 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
552 (umax "maxu") (umin "minu")])
553 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
555 ;; Mapping of parallel logic operators
556 (define_code_iterator plogic [and ior xor])
558 ;; Base name for insn mnemonic.
559 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
561 ;; Mapping of abs neg operators
562 (define_code_iterator absneg [abs neg])
564 ;; Base name for x87 insn mnemonic.
565 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
567 ;; All single word integer modes.
568 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
570 ;; Instruction suffix for integer modes.
571 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
573 ;; Register class for integer modes.
574 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
576 ;; Immediate operand constraint for integer modes.
577 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
579 ;; General operand predicate for integer modes.
580 (define_mode_attr general_operand
581 [(QI "general_operand")
582 (HI "general_operand")
583 (SI "general_operand")
584 (DI "x86_64_general_operand")])
586 ;; SSE and x87 SFmode and DFmode floating point modes
587 (define_mode_iterator MODEF [SF DF])
589 ;; All x87 floating point modes
590 (define_mode_iterator X87MODEF [SF DF XF])
592 ;; All integer modes handled by x87 fisttp operator.
593 (define_mode_iterator X87MODEI [HI SI DI])
595 ;; All integer modes handled by integer x87 operators.
596 (define_mode_iterator X87MODEI12 [HI SI])
598 ;; All integer modes handled by SSE cvtts?2si* operators.
599 (define_mode_iterator SSEMODEI24 [SI DI])
601 ;; SSE asm suffix for floating point modes
602 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
604 ;; SSE vector mode corresponding to a scalar mode
605 (define_mode_attr ssevecmode
606 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
608 ;; Instruction suffix for REX 64bit operators.
609 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
611 ;; Scheduling descriptions
613 (include "pentium.md")
616 (include "athlon.md")
620 ;; Operand and operator predicates and constraints
622 (include "predicates.md")
623 (include "constraints.md")
626 ;; Compare instructions.
628 ;; All compare insns have expanders that save the operands away without
629 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
630 ;; after the cmp) will actually emit the cmpM.
632 (define_expand "cmpti"
633 [(set (reg:CC FLAGS_REG)
634 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
635 (match_operand:TI 1 "x86_64_general_operand" "")))]
638 if (MEM_P (operands[0]) && MEM_P (operands[1]))
639 operands[0] = force_reg (TImode, operands[0]);
640 ix86_compare_op0 = operands[0];
641 ix86_compare_op1 = operands[1];
645 (define_expand "cmpdi"
646 [(set (reg:CC FLAGS_REG)
647 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
648 (match_operand:DI 1 "x86_64_general_operand" "")))]
651 if (MEM_P (operands[0]) && MEM_P (operands[1]))
652 operands[0] = force_reg (DImode, operands[0]);
653 ix86_compare_op0 = operands[0];
654 ix86_compare_op1 = operands[1];
658 (define_expand "cmpsi"
659 [(set (reg:CC FLAGS_REG)
660 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
661 (match_operand:SI 1 "general_operand" "")))]
664 if (MEM_P (operands[0]) && MEM_P (operands[1]))
665 operands[0] = force_reg (SImode, operands[0]);
666 ix86_compare_op0 = operands[0];
667 ix86_compare_op1 = operands[1];
671 (define_expand "cmphi"
672 [(set (reg:CC FLAGS_REG)
673 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
674 (match_operand:HI 1 "general_operand" "")))]
677 if (MEM_P (operands[0]) && MEM_P (operands[1]))
678 operands[0] = force_reg (HImode, operands[0]);
679 ix86_compare_op0 = operands[0];
680 ix86_compare_op1 = operands[1];
684 (define_expand "cmpqi"
685 [(set (reg:CC FLAGS_REG)
686 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
687 (match_operand:QI 1 "general_operand" "")))]
690 if (MEM_P (operands[0]) && MEM_P (operands[1]))
691 operands[0] = force_reg (QImode, operands[0]);
692 ix86_compare_op0 = operands[0];
693 ix86_compare_op1 = operands[1];
697 (define_insn "cmpdi_ccno_1_rex64"
698 [(set (reg FLAGS_REG)
699 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
700 (match_operand:DI 1 "const0_operand" "n,n")))]
701 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
704 cmp{q}\t{%1, %0|%0, %1}"
705 [(set_attr "type" "test,icmp")
706 (set_attr "length_immediate" "0,1")
707 (set_attr "mode" "DI")])
709 (define_insn "*cmpdi_minus_1_rex64"
710 [(set (reg FLAGS_REG)
711 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
712 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
714 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
715 "cmp{q}\t{%1, %0|%0, %1}"
716 [(set_attr "type" "icmp")
717 (set_attr "mode" "DI")])
719 (define_expand "cmpdi_1_rex64"
720 [(set (reg:CC FLAGS_REG)
721 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
722 (match_operand:DI 1 "general_operand" "")))]
726 (define_insn "cmpdi_1_insn_rex64"
727 [(set (reg FLAGS_REG)
728 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
729 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
730 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
731 "cmp{q}\t{%1, %0|%0, %1}"
732 [(set_attr "type" "icmp")
733 (set_attr "mode" "DI")])
736 (define_insn "*cmpsi_ccno_1"
737 [(set (reg FLAGS_REG)
738 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
739 (match_operand:SI 1 "const0_operand" "n,n")))]
740 "ix86_match_ccmode (insn, CCNOmode)"
743 cmp{l}\t{%1, %0|%0, %1}"
744 [(set_attr "type" "test,icmp")
745 (set_attr "length_immediate" "0,1")
746 (set_attr "mode" "SI")])
748 (define_insn "*cmpsi_minus_1"
749 [(set (reg FLAGS_REG)
750 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
751 (match_operand:SI 1 "general_operand" "ri,mr"))
753 "ix86_match_ccmode (insn, CCGOCmode)"
754 "cmp{l}\t{%1, %0|%0, %1}"
755 [(set_attr "type" "icmp")
756 (set_attr "mode" "SI")])
758 (define_expand "cmpsi_1"
759 [(set (reg:CC FLAGS_REG)
760 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
761 (match_operand:SI 1 "general_operand" "")))]
765 (define_insn "*cmpsi_1_insn"
766 [(set (reg FLAGS_REG)
767 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
768 (match_operand:SI 1 "general_operand" "ri,mr")))]
769 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
770 && ix86_match_ccmode (insn, CCmode)"
771 "cmp{l}\t{%1, %0|%0, %1}"
772 [(set_attr "type" "icmp")
773 (set_attr "mode" "SI")])
775 (define_insn "*cmphi_ccno_1"
776 [(set (reg FLAGS_REG)
777 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
778 (match_operand:HI 1 "const0_operand" "n,n")))]
779 "ix86_match_ccmode (insn, CCNOmode)"
782 cmp{w}\t{%1, %0|%0, %1}"
783 [(set_attr "type" "test,icmp")
784 (set_attr "length_immediate" "0,1")
785 (set_attr "mode" "HI")])
787 (define_insn "*cmphi_minus_1"
788 [(set (reg FLAGS_REG)
789 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
790 (match_operand:HI 1 "general_operand" "ri,mr"))
792 "ix86_match_ccmode (insn, CCGOCmode)"
793 "cmp{w}\t{%1, %0|%0, %1}"
794 [(set_attr "type" "icmp")
795 (set_attr "mode" "HI")])
797 (define_insn "*cmphi_1"
798 [(set (reg FLAGS_REG)
799 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
800 (match_operand:HI 1 "general_operand" "ri,mr")))]
801 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
802 && ix86_match_ccmode (insn, CCmode)"
803 "cmp{w}\t{%1, %0|%0, %1}"
804 [(set_attr "type" "icmp")
805 (set_attr "mode" "HI")])
807 (define_insn "*cmpqi_ccno_1"
808 [(set (reg FLAGS_REG)
809 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
810 (match_operand:QI 1 "const0_operand" "n,n")))]
811 "ix86_match_ccmode (insn, CCNOmode)"
814 cmp{b}\t{$0, %0|%0, 0}"
815 [(set_attr "type" "test,icmp")
816 (set_attr "length_immediate" "0,1")
817 (set_attr "mode" "QI")])
819 (define_insn "*cmpqi_1"
820 [(set (reg FLAGS_REG)
821 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
822 (match_operand:QI 1 "general_operand" "qi,mq")))]
823 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
824 && ix86_match_ccmode (insn, CCmode)"
825 "cmp{b}\t{%1, %0|%0, %1}"
826 [(set_attr "type" "icmp")
827 (set_attr "mode" "QI")])
829 (define_insn "*cmpqi_minus_1"
830 [(set (reg FLAGS_REG)
831 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
832 (match_operand:QI 1 "general_operand" "qi,mq"))
834 "ix86_match_ccmode (insn, CCGOCmode)"
835 "cmp{b}\t{%1, %0|%0, %1}"
836 [(set_attr "type" "icmp")
837 (set_attr "mode" "QI")])
839 (define_insn "*cmpqi_ext_1"
840 [(set (reg FLAGS_REG)
842 (match_operand:QI 0 "general_operand" "Qm")
845 (match_operand 1 "ext_register_operand" "Q")
848 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
849 "cmp{b}\t{%h1, %0|%0, %h1}"
850 [(set_attr "type" "icmp")
851 (set_attr "mode" "QI")])
853 (define_insn "*cmpqi_ext_1_rex64"
854 [(set (reg FLAGS_REG)
856 (match_operand:QI 0 "register_operand" "Q")
859 (match_operand 1 "ext_register_operand" "Q")
862 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
863 "cmp{b}\t{%h1, %0|%0, %h1}"
864 [(set_attr "type" "icmp")
865 (set_attr "mode" "QI")])
867 (define_insn "*cmpqi_ext_2"
868 [(set (reg FLAGS_REG)
872 (match_operand 0 "ext_register_operand" "Q")
875 (match_operand:QI 1 "const0_operand" "n")))]
876 "ix86_match_ccmode (insn, CCNOmode)"
878 [(set_attr "type" "test")
879 (set_attr "length_immediate" "0")
880 (set_attr "mode" "QI")])
882 (define_expand "cmpqi_ext_3"
883 [(set (reg:CC FLAGS_REG)
887 (match_operand 0 "ext_register_operand" "")
890 (match_operand:QI 1 "general_operand" "")))]
894 (define_insn "cmpqi_ext_3_insn"
895 [(set (reg FLAGS_REG)
899 (match_operand 0 "ext_register_operand" "Q")
902 (match_operand:QI 1 "general_operand" "Qmn")))]
903 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
904 "cmp{b}\t{%1, %h0|%h0, %1}"
905 [(set_attr "type" "icmp")
906 (set_attr "mode" "QI")])
908 (define_insn "cmpqi_ext_3_insn_rex64"
909 [(set (reg FLAGS_REG)
913 (match_operand 0 "ext_register_operand" "Q")
916 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
917 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
918 "cmp{b}\t{%1, %h0|%h0, %1}"
919 [(set_attr "type" "icmp")
920 (set_attr "mode" "QI")])
922 (define_insn "*cmpqi_ext_4"
923 [(set (reg FLAGS_REG)
927 (match_operand 0 "ext_register_operand" "Q")
932 (match_operand 1 "ext_register_operand" "Q")
935 "ix86_match_ccmode (insn, CCmode)"
936 "cmp{b}\t{%h1, %h0|%h0, %h1}"
937 [(set_attr "type" "icmp")
938 (set_attr "mode" "QI")])
940 ;; These implement float point compares.
941 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
942 ;; which would allow mix and match FP modes on the compares. Which is what
943 ;; the old patterns did, but with many more of them.
945 (define_expand "cmpxf"
946 [(set (reg:CC FLAGS_REG)
947 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
948 (match_operand:XF 1 "nonmemory_operand" "")))]
951 ix86_compare_op0 = operands[0];
952 ix86_compare_op1 = operands[1];
956 (define_expand "cmp<mode>"
957 [(set (reg:CC FLAGS_REG)
958 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
959 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
960 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
962 ix86_compare_op0 = operands[0];
963 ix86_compare_op1 = operands[1];
967 ;; FP compares, step 1:
968 ;; Set the FP condition codes.
970 ;; CCFPmode compare with exceptions
971 ;; CCFPUmode compare with no exceptions
973 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
974 ;; used to manage the reg stack popping would not be preserved.
976 (define_insn "*cmpfp_0"
977 [(set (match_operand:HI 0 "register_operand" "=a")
980 (match_operand 1 "register_operand" "f")
981 (match_operand 2 "const0_operand" "X"))]
983 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
984 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
985 "* return output_fp_compare (insn, operands, 0, 0);"
986 [(set_attr "type" "multi")
987 (set_attr "unit" "i387")
989 (cond [(match_operand:SF 1 "" "")
991 (match_operand:DF 1 "" "")
994 (const_string "XF")))])
996 (define_insn_and_split "*cmpfp_0_cc"
997 [(set (reg:CCFP FLAGS_REG)
999 (match_operand 1 "register_operand" "f")
1000 (match_operand 2 "const0_operand" "X")))
1001 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1002 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1003 && TARGET_SAHF && !TARGET_CMOVE
1004 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1006 "&& reload_completed"
1009 [(compare:CCFP (match_dup 1)(match_dup 2))]
1011 (set (reg:CC FLAGS_REG)
1012 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1014 [(set_attr "type" "multi")
1015 (set_attr "unit" "i387")
1017 (cond [(match_operand:SF 1 "" "")
1019 (match_operand:DF 1 "" "")
1022 (const_string "XF")))])
1024 (define_insn "*cmpfp_xf"
1025 [(set (match_operand:HI 0 "register_operand" "=a")
1028 (match_operand:XF 1 "register_operand" "f")
1029 (match_operand:XF 2 "register_operand" "f"))]
1032 "* return output_fp_compare (insn, operands, 0, 0);"
1033 [(set_attr "type" "multi")
1034 (set_attr "unit" "i387")
1035 (set_attr "mode" "XF")])
1037 (define_insn_and_split "*cmpfp_xf_cc"
1038 [(set (reg:CCFP FLAGS_REG)
1040 (match_operand:XF 1 "register_operand" "f")
1041 (match_operand:XF 2 "register_operand" "f")))
1042 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1044 && TARGET_SAHF && !TARGET_CMOVE"
1046 "&& reload_completed"
1049 [(compare:CCFP (match_dup 1)(match_dup 2))]
1051 (set (reg:CC FLAGS_REG)
1052 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1054 [(set_attr "type" "multi")
1055 (set_attr "unit" "i387")
1056 (set_attr "mode" "XF")])
1058 (define_insn "*cmpfp_<mode>"
1059 [(set (match_operand:HI 0 "register_operand" "=a")
1062 (match_operand:MODEF 1 "register_operand" "f")
1063 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1066 "* return output_fp_compare (insn, operands, 0, 0);"
1067 [(set_attr "type" "multi")
1068 (set_attr "unit" "i387")
1069 (set_attr "mode" "<MODE>")])
1071 (define_insn_and_split "*cmpfp_<mode>_cc"
1072 [(set (reg:CCFP FLAGS_REG)
1074 (match_operand:MODEF 1 "register_operand" "f")
1075 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1076 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1078 && TARGET_SAHF && !TARGET_CMOVE"
1080 "&& reload_completed"
1083 [(compare:CCFP (match_dup 1)(match_dup 2))]
1085 (set (reg:CC FLAGS_REG)
1086 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1088 [(set_attr "type" "multi")
1089 (set_attr "unit" "i387")
1090 (set_attr "mode" "<MODE>")])
1092 (define_insn "*cmpfp_u"
1093 [(set (match_operand:HI 0 "register_operand" "=a")
1096 (match_operand 1 "register_operand" "f")
1097 (match_operand 2 "register_operand" "f"))]
1099 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1100 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1101 "* return output_fp_compare (insn, operands, 0, 1);"
1102 [(set_attr "type" "multi")
1103 (set_attr "unit" "i387")
1105 (cond [(match_operand:SF 1 "" "")
1107 (match_operand:DF 1 "" "")
1110 (const_string "XF")))])
1112 (define_insn_and_split "*cmpfp_u_cc"
1113 [(set (reg:CCFPU FLAGS_REG)
1115 (match_operand 1 "register_operand" "f")
1116 (match_operand 2 "register_operand" "f")))
1117 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1118 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1119 && TARGET_SAHF && !TARGET_CMOVE
1120 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1122 "&& reload_completed"
1125 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1127 (set (reg:CC FLAGS_REG)
1128 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1130 [(set_attr "type" "multi")
1131 (set_attr "unit" "i387")
1133 (cond [(match_operand:SF 1 "" "")
1135 (match_operand:DF 1 "" "")
1138 (const_string "XF")))])
1140 (define_insn "*cmpfp_<mode>"
1141 [(set (match_operand:HI 0 "register_operand" "=a")
1144 (match_operand 1 "register_operand" "f")
1145 (match_operator 3 "float_operator"
1146 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1148 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1149 && TARGET_USE_<MODE>MODE_FIOP
1150 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1151 "* return output_fp_compare (insn, operands, 0, 0);"
1152 [(set_attr "type" "multi")
1153 (set_attr "unit" "i387")
1154 (set_attr "fp_int_src" "true")
1155 (set_attr "mode" "<MODE>")])
1157 (define_insn_and_split "*cmpfp_<mode>_cc"
1158 [(set (reg:CCFP FLAGS_REG)
1160 (match_operand 1 "register_operand" "f")
1161 (match_operator 3 "float_operator"
1162 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1163 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1164 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1165 && TARGET_SAHF && !TARGET_CMOVE
1166 && TARGET_USE_<MODE>MODE_FIOP
1167 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1169 "&& reload_completed"
1174 (match_op_dup 3 [(match_dup 2)]))]
1176 (set (reg:CC FLAGS_REG)
1177 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1179 [(set_attr "type" "multi")
1180 (set_attr "unit" "i387")
1181 (set_attr "fp_int_src" "true")
1182 (set_attr "mode" "<MODE>")])
1184 ;; FP compares, step 2
1185 ;; Move the fpsw to ax.
1187 (define_insn "x86_fnstsw_1"
1188 [(set (match_operand:HI 0 "register_operand" "=a")
1189 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1192 [(set_attr "length" "2")
1193 (set_attr "mode" "SI")
1194 (set_attr "unit" "i387")])
1196 ;; FP compares, step 3
1197 ;; Get ax into flags, general case.
1199 (define_insn "x86_sahf_1"
1200 [(set (reg:CC FLAGS_REG)
1201 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1205 #ifdef HAVE_AS_IX86_SAHF
1208 return ".byte\t0x9e";
1211 [(set_attr "length" "1")
1212 (set_attr "athlon_decode" "vector")
1213 (set_attr "amdfam10_decode" "direct")
1214 (set_attr "mode" "SI")])
1216 ;; Pentium Pro can do steps 1 through 3 in one go.
1217 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1218 (define_insn "*cmpfp_i_mixed"
1219 [(set (reg:CCFP FLAGS_REG)
1220 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1221 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1222 "TARGET_MIX_SSE_I387
1223 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1224 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1225 "* return output_fp_compare (insn, operands, 1, 0);"
1226 [(set_attr "type" "fcmp,ssecomi")
1228 (if_then_else (match_operand:SF 1 "" "")
1230 (const_string "DF")))
1231 (set_attr "athlon_decode" "vector")
1232 (set_attr "amdfam10_decode" "direct")])
1234 (define_insn "*cmpfp_i_sse"
1235 [(set (reg:CCFP FLAGS_REG)
1236 (compare:CCFP (match_operand 0 "register_operand" "x")
1237 (match_operand 1 "nonimmediate_operand" "xm")))]
1239 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1240 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1241 "* return output_fp_compare (insn, operands, 1, 0);"
1242 [(set_attr "type" "ssecomi")
1244 (if_then_else (match_operand:SF 1 "" "")
1246 (const_string "DF")))
1247 (set_attr "athlon_decode" "vector")
1248 (set_attr "amdfam10_decode" "direct")])
1250 (define_insn "*cmpfp_i_i387"
1251 [(set (reg:CCFP FLAGS_REG)
1252 (compare:CCFP (match_operand 0 "register_operand" "f")
1253 (match_operand 1 "register_operand" "f")))]
1254 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1256 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1257 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1258 "* return output_fp_compare (insn, operands, 1, 0);"
1259 [(set_attr "type" "fcmp")
1261 (cond [(match_operand:SF 1 "" "")
1263 (match_operand:DF 1 "" "")
1266 (const_string "XF")))
1267 (set_attr "athlon_decode" "vector")
1268 (set_attr "amdfam10_decode" "direct")])
1270 (define_insn "*cmpfp_iu_mixed"
1271 [(set (reg:CCFPU FLAGS_REG)
1272 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1273 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1274 "TARGET_MIX_SSE_I387
1275 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1276 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1277 "* return output_fp_compare (insn, operands, 1, 1);"
1278 [(set_attr "type" "fcmp,ssecomi")
1280 (if_then_else (match_operand:SF 1 "" "")
1282 (const_string "DF")))
1283 (set_attr "athlon_decode" "vector")
1284 (set_attr "amdfam10_decode" "direct")])
1286 (define_insn "*cmpfp_iu_sse"
1287 [(set (reg:CCFPU FLAGS_REG)
1288 (compare:CCFPU (match_operand 0 "register_operand" "x")
1289 (match_operand 1 "nonimmediate_operand" "xm")))]
1291 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1292 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1293 "* return output_fp_compare (insn, operands, 1, 1);"
1294 [(set_attr "type" "ssecomi")
1296 (if_then_else (match_operand:SF 1 "" "")
1298 (const_string "DF")))
1299 (set_attr "athlon_decode" "vector")
1300 (set_attr "amdfam10_decode" "direct")])
1302 (define_insn "*cmpfp_iu_387"
1303 [(set (reg:CCFPU FLAGS_REG)
1304 (compare:CCFPU (match_operand 0 "register_operand" "f")
1305 (match_operand 1 "register_operand" "f")))]
1306 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1308 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1309 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1310 "* return output_fp_compare (insn, operands, 1, 1);"
1311 [(set_attr "type" "fcmp")
1313 (cond [(match_operand:SF 1 "" "")
1315 (match_operand:DF 1 "" "")
1318 (const_string "XF")))
1319 (set_attr "athlon_decode" "vector")
1320 (set_attr "amdfam10_decode" "direct")])
1322 ;; Move instructions.
1324 ;; General case of fullword move.
1326 (define_expand "movsi"
1327 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1328 (match_operand:SI 1 "general_operand" ""))]
1330 "ix86_expand_move (SImode, operands); DONE;")
1332 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1335 ;; %%% We don't use a post-inc memory reference because x86 is not a
1336 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1337 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1338 ;; targets without our curiosities, and it is just as easy to represent
1339 ;; this differently.
1341 (define_insn "*pushsi2"
1342 [(set (match_operand:SI 0 "push_operand" "=<")
1343 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1346 [(set_attr "type" "push")
1347 (set_attr "mode" "SI")])
1349 ;; For 64BIT abi we always round up to 8 bytes.
1350 (define_insn "*pushsi2_rex64"
1351 [(set (match_operand:SI 0 "push_operand" "=X")
1352 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1355 [(set_attr "type" "push")
1356 (set_attr "mode" "SI")])
1358 (define_insn "*pushsi2_prologue"
1359 [(set (match_operand:SI 0 "push_operand" "=<")
1360 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1361 (clobber (mem:BLK (scratch)))]
1364 [(set_attr "type" "push")
1365 (set_attr "mode" "SI")])
1367 (define_insn "*popsi1_epilogue"
1368 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1369 (mem:SI (reg:SI SP_REG)))
1370 (set (reg:SI SP_REG)
1371 (plus:SI (reg:SI SP_REG) (const_int 4)))
1372 (clobber (mem:BLK (scratch)))]
1375 [(set_attr "type" "pop")
1376 (set_attr "mode" "SI")])
1378 (define_insn "popsi1"
1379 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1380 (mem:SI (reg:SI SP_REG)))
1381 (set (reg:SI SP_REG)
1382 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1385 [(set_attr "type" "pop")
1386 (set_attr "mode" "SI")])
1388 (define_insn "*movsi_xor"
1389 [(set (match_operand:SI 0 "register_operand" "=r")
1390 (match_operand:SI 1 "const0_operand" "i"))
1391 (clobber (reg:CC FLAGS_REG))]
1392 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1394 [(set_attr "type" "alu1")
1395 (set_attr "mode" "SI")
1396 (set_attr "length_immediate" "0")])
1398 (define_insn "*movsi_or"
1399 [(set (match_operand:SI 0 "register_operand" "=r")
1400 (match_operand:SI 1 "immediate_operand" "i"))
1401 (clobber (reg:CC FLAGS_REG))]
1403 && operands[1] == constm1_rtx
1404 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1406 operands[1] = constm1_rtx;
1407 return "or{l}\t{%1, %0|%0, %1}";
1409 [(set_attr "type" "alu1")
1410 (set_attr "mode" "SI")
1411 (set_attr "length_immediate" "1")])
1413 (define_insn "*movsi_1"
1414 [(set (match_operand:SI 0 "nonimmediate_operand"
1415 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1416 (match_operand:SI 1 "general_operand"
1417 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1418 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1420 switch (get_attr_type (insn))
1423 if (get_attr_mode (insn) == MODE_TI)
1424 return "pxor\t%0, %0";
1425 return "xorps\t%0, %0";
1428 switch (get_attr_mode (insn))
1431 return "movdqa\t{%1, %0|%0, %1}";
1433 return "movaps\t{%1, %0|%0, %1}";
1435 return "movd\t{%1, %0|%0, %1}";
1437 return "movss\t{%1, %0|%0, %1}";
1443 return "pxor\t%0, %0";
1446 if (get_attr_mode (insn) == MODE_DI)
1447 return "movq\t{%1, %0|%0, %1}";
1448 return "movd\t{%1, %0|%0, %1}";
1451 return "lea{l}\t{%1, %0|%0, %1}";
1454 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1455 return "mov{l}\t{%1, %0|%0, %1}";
1459 (cond [(eq_attr "alternative" "2")
1460 (const_string "mmxadd")
1461 (eq_attr "alternative" "3,4,5")
1462 (const_string "mmxmov")
1463 (eq_attr "alternative" "6")
1464 (const_string "sselog1")
1465 (eq_attr "alternative" "7,8,9,10,11")
1466 (const_string "ssemov")
1467 (match_operand:DI 1 "pic_32bit_operand" "")
1468 (const_string "lea")
1470 (const_string "imov")))
1472 (cond [(eq_attr "alternative" "2,3")
1474 (eq_attr "alternative" "6,7")
1476 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1477 (const_string "V4SF")
1478 (const_string "TI"))
1479 (and (eq_attr "alternative" "8,9,10,11")
1480 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1483 (const_string "SI")))])
1485 ;; Stores and loads of ax to arbitrary constant address.
1486 ;; We fake an second form of instruction to force reload to load address
1487 ;; into register when rax is not available
1488 (define_insn "*movabssi_1_rex64"
1489 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1490 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1491 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1493 movabs{l}\t{%1, %P0|%P0, %1}
1494 mov{l}\t{%1, %a0|%a0, %1}"
1495 [(set_attr "type" "imov")
1496 (set_attr "modrm" "0,*")
1497 (set_attr "length_address" "8,0")
1498 (set_attr "length_immediate" "0,*")
1499 (set_attr "memory" "store")
1500 (set_attr "mode" "SI")])
1502 (define_insn "*movabssi_2_rex64"
1503 [(set (match_operand:SI 0 "register_operand" "=a,r")
1504 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1505 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1507 movabs{l}\t{%P1, %0|%0, %P1}
1508 mov{l}\t{%a1, %0|%0, %a1}"
1509 [(set_attr "type" "imov")
1510 (set_attr "modrm" "0,*")
1511 (set_attr "length_address" "8,0")
1512 (set_attr "length_immediate" "0")
1513 (set_attr "memory" "load")
1514 (set_attr "mode" "SI")])
1516 (define_insn "*swapsi"
1517 [(set (match_operand:SI 0 "register_operand" "+r")
1518 (match_operand:SI 1 "register_operand" "+r"))
1523 [(set_attr "type" "imov")
1524 (set_attr "mode" "SI")
1525 (set_attr "pent_pair" "np")
1526 (set_attr "athlon_decode" "vector")
1527 (set_attr "amdfam10_decode" "double")])
1529 (define_expand "movhi"
1530 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1531 (match_operand:HI 1 "general_operand" ""))]
1533 "ix86_expand_move (HImode, operands); DONE;")
1535 (define_insn "*pushhi2"
1536 [(set (match_operand:HI 0 "push_operand" "=X")
1537 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1540 [(set_attr "type" "push")
1541 (set_attr "mode" "SI")])
1543 ;; For 64BIT abi we always round up to 8 bytes.
1544 (define_insn "*pushhi2_rex64"
1545 [(set (match_operand:HI 0 "push_operand" "=X")
1546 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1549 [(set_attr "type" "push")
1550 (set_attr "mode" "DI")])
1552 (define_insn "*movhi_1"
1553 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1554 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1555 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1557 switch (get_attr_type (insn))
1560 /* movzwl is faster than movw on p2 due to partial word stalls,
1561 though not as fast as an aligned movl. */
1562 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1564 if (get_attr_mode (insn) == MODE_SI)
1565 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1567 return "mov{w}\t{%1, %0|%0, %1}";
1571 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1572 (const_string "imov")
1573 (and (eq_attr "alternative" "0")
1574 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1576 (eq (symbol_ref "TARGET_HIMODE_MATH")
1578 (const_string "imov")
1579 (and (eq_attr "alternative" "1,2")
1580 (match_operand:HI 1 "aligned_operand" ""))
1581 (const_string "imov")
1582 (and (ne (symbol_ref "TARGET_MOVX")
1584 (eq_attr "alternative" "0,2"))
1585 (const_string "imovx")
1587 (const_string "imov")))
1589 (cond [(eq_attr "type" "imovx")
1591 (and (eq_attr "alternative" "1,2")
1592 (match_operand:HI 1 "aligned_operand" ""))
1594 (and (eq_attr "alternative" "0")
1595 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1597 (eq (symbol_ref "TARGET_HIMODE_MATH")
1601 (const_string "HI")))])
1603 ;; Stores and loads of ax to arbitrary constant address.
1604 ;; We fake an second form of instruction to force reload to load address
1605 ;; into register when rax is not available
1606 (define_insn "*movabshi_1_rex64"
1607 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1608 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1609 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1611 movabs{w}\t{%1, %P0|%P0, %1}
1612 mov{w}\t{%1, %a0|%a0, %1}"
1613 [(set_attr "type" "imov")
1614 (set_attr "modrm" "0,*")
1615 (set_attr "length_address" "8,0")
1616 (set_attr "length_immediate" "0,*")
1617 (set_attr "memory" "store")
1618 (set_attr "mode" "HI")])
1620 (define_insn "*movabshi_2_rex64"
1621 [(set (match_operand:HI 0 "register_operand" "=a,r")
1622 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1623 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1625 movabs{w}\t{%P1, %0|%0, %P1}
1626 mov{w}\t{%a1, %0|%0, %a1}"
1627 [(set_attr "type" "imov")
1628 (set_attr "modrm" "0,*")
1629 (set_attr "length_address" "8,0")
1630 (set_attr "length_immediate" "0")
1631 (set_attr "memory" "load")
1632 (set_attr "mode" "HI")])
1634 (define_insn "*swaphi_1"
1635 [(set (match_operand:HI 0 "register_operand" "+r")
1636 (match_operand:HI 1 "register_operand" "+r"))
1639 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1641 [(set_attr "type" "imov")
1642 (set_attr "mode" "SI")
1643 (set_attr "pent_pair" "np")
1644 (set_attr "athlon_decode" "vector")
1645 (set_attr "amdfam10_decode" "double")])
1647 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1648 (define_insn "*swaphi_2"
1649 [(set (match_operand:HI 0 "register_operand" "+r")
1650 (match_operand:HI 1 "register_operand" "+r"))
1653 "TARGET_PARTIAL_REG_STALL"
1655 [(set_attr "type" "imov")
1656 (set_attr "mode" "HI")
1657 (set_attr "pent_pair" "np")
1658 (set_attr "athlon_decode" "vector")])
1660 (define_expand "movstricthi"
1661 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1662 (match_operand:HI 1 "general_operand" ""))]
1663 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1665 /* Don't generate memory->memory moves, go through a register */
1666 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1667 operands[1] = force_reg (HImode, operands[1]);
1670 (define_insn "*movstricthi_1"
1671 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1672 (match_operand:HI 1 "general_operand" "rn,m"))]
1673 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1674 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1675 "mov{w}\t{%1, %0|%0, %1}"
1676 [(set_attr "type" "imov")
1677 (set_attr "mode" "HI")])
1679 (define_insn "*movstricthi_xor"
1680 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1681 (match_operand:HI 1 "const0_operand" "i"))
1682 (clobber (reg:CC FLAGS_REG))]
1684 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1686 [(set_attr "type" "alu1")
1687 (set_attr "mode" "HI")
1688 (set_attr "length_immediate" "0")])
1690 (define_expand "movqi"
1691 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1692 (match_operand:QI 1 "general_operand" ""))]
1694 "ix86_expand_move (QImode, operands); DONE;")
1696 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1697 ;; "push a byte". But actually we use pushl, which has the effect
1698 ;; of rounding the amount pushed up to a word.
1700 (define_insn "*pushqi2"
1701 [(set (match_operand:QI 0 "push_operand" "=X")
1702 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1705 [(set_attr "type" "push")
1706 (set_attr "mode" "SI")])
1708 ;; For 64BIT abi we always round up to 8 bytes.
1709 (define_insn "*pushqi2_rex64"
1710 [(set (match_operand:QI 0 "push_operand" "=X")
1711 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1714 [(set_attr "type" "push")
1715 (set_attr "mode" "DI")])
1717 ;; Situation is quite tricky about when to choose full sized (SImode) move
1718 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1719 ;; partial register dependency machines (such as AMD Athlon), where QImode
1720 ;; moves issue extra dependency and for partial register stalls machines
1721 ;; that don't use QImode patterns (and QImode move cause stall on the next
1724 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1725 ;; register stall machines with, where we use QImode instructions, since
1726 ;; partial register stall can be caused there. Then we use movzx.
1727 (define_insn "*movqi_1"
1728 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1729 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1730 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1732 switch (get_attr_type (insn))
1735 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1736 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1738 if (get_attr_mode (insn) == MODE_SI)
1739 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1741 return "mov{b}\t{%1, %0|%0, %1}";
1745 (cond [(and (eq_attr "alternative" "5")
1746 (not (match_operand:QI 1 "aligned_operand" "")))
1747 (const_string "imovx")
1748 (ne (symbol_ref "optimize_size") (const_int 0))
1749 (const_string "imov")
1750 (and (eq_attr "alternative" "3")
1751 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1753 (eq (symbol_ref "TARGET_QIMODE_MATH")
1755 (const_string "imov")
1756 (eq_attr "alternative" "3,5")
1757 (const_string "imovx")
1758 (and (ne (symbol_ref "TARGET_MOVX")
1760 (eq_attr "alternative" "2"))
1761 (const_string "imovx")
1763 (const_string "imov")))
1765 (cond [(eq_attr "alternative" "3,4,5")
1767 (eq_attr "alternative" "6")
1769 (eq_attr "type" "imovx")
1771 (and (eq_attr "type" "imov")
1772 (and (eq_attr "alternative" "0,1")
1773 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1775 (and (eq (symbol_ref "optimize_size")
1777 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1780 ;; Avoid partial register stalls when not using QImode arithmetic
1781 (and (eq_attr "type" "imov")
1782 (and (eq_attr "alternative" "0,1")
1783 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1785 (eq (symbol_ref "TARGET_QIMODE_MATH")
1789 (const_string "QI")))])
1791 (define_expand "reload_outqi"
1792 [(parallel [(match_operand:QI 0 "" "=m")
1793 (match_operand:QI 1 "register_operand" "r")
1794 (match_operand:QI 2 "register_operand" "=&q")])]
1798 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1800 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1801 if (! q_regs_operand (op1, QImode))
1803 emit_insn (gen_movqi (op2, op1));
1806 emit_insn (gen_movqi (op0, op1));
1810 (define_insn "*swapqi_1"
1811 [(set (match_operand:QI 0 "register_operand" "+r")
1812 (match_operand:QI 1 "register_operand" "+r"))
1815 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1817 [(set_attr "type" "imov")
1818 (set_attr "mode" "SI")
1819 (set_attr "pent_pair" "np")
1820 (set_attr "athlon_decode" "vector")
1821 (set_attr "amdfam10_decode" "vector")])
1823 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1824 (define_insn "*swapqi_2"
1825 [(set (match_operand:QI 0 "register_operand" "+q")
1826 (match_operand:QI 1 "register_operand" "+q"))
1829 "TARGET_PARTIAL_REG_STALL"
1831 [(set_attr "type" "imov")
1832 (set_attr "mode" "QI")
1833 (set_attr "pent_pair" "np")
1834 (set_attr "athlon_decode" "vector")])
1836 (define_expand "movstrictqi"
1837 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1838 (match_operand:QI 1 "general_operand" ""))]
1839 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1841 /* Don't generate memory->memory moves, go through a register. */
1842 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1843 operands[1] = force_reg (QImode, operands[1]);
1846 (define_insn "*movstrictqi_1"
1847 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1848 (match_operand:QI 1 "general_operand" "*qn,m"))]
1849 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1850 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1851 "mov{b}\t{%1, %0|%0, %1}"
1852 [(set_attr "type" "imov")
1853 (set_attr "mode" "QI")])
1855 (define_insn "*movstrictqi_xor"
1856 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1857 (match_operand:QI 1 "const0_operand" "i"))
1858 (clobber (reg:CC FLAGS_REG))]
1859 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1861 [(set_attr "type" "alu1")
1862 (set_attr "mode" "QI")
1863 (set_attr "length_immediate" "0")])
1865 (define_insn "*movsi_extv_1"
1866 [(set (match_operand:SI 0 "register_operand" "=R")
1867 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1871 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1872 [(set_attr "type" "imovx")
1873 (set_attr "mode" "SI")])
1875 (define_insn "*movhi_extv_1"
1876 [(set (match_operand:HI 0 "register_operand" "=R")
1877 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1881 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1882 [(set_attr "type" "imovx")
1883 (set_attr "mode" "SI")])
1885 (define_insn "*movqi_extv_1"
1886 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1887 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1892 switch (get_attr_type (insn))
1895 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1897 return "mov{b}\t{%h1, %0|%0, %h1}";
1901 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1902 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1903 (ne (symbol_ref "TARGET_MOVX")
1905 (const_string "imovx")
1906 (const_string "imov")))
1908 (if_then_else (eq_attr "type" "imovx")
1910 (const_string "QI")))])
1912 (define_insn "*movqi_extv_1_rex64"
1913 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1914 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1919 switch (get_attr_type (insn))
1922 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1924 return "mov{b}\t{%h1, %0|%0, %h1}";
1928 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1929 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1930 (ne (symbol_ref "TARGET_MOVX")
1932 (const_string "imovx")
1933 (const_string "imov")))
1935 (if_then_else (eq_attr "type" "imovx")
1937 (const_string "QI")))])
1939 ;; Stores and loads of ax to arbitrary constant address.
1940 ;; We fake an second form of instruction to force reload to load address
1941 ;; into register when rax is not available
1942 (define_insn "*movabsqi_1_rex64"
1943 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1944 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1945 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1947 movabs{b}\t{%1, %P0|%P0, %1}
1948 mov{b}\t{%1, %a0|%a0, %1}"
1949 [(set_attr "type" "imov")
1950 (set_attr "modrm" "0,*")
1951 (set_attr "length_address" "8,0")
1952 (set_attr "length_immediate" "0,*")
1953 (set_attr "memory" "store")
1954 (set_attr "mode" "QI")])
1956 (define_insn "*movabsqi_2_rex64"
1957 [(set (match_operand:QI 0 "register_operand" "=a,r")
1958 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1959 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1961 movabs{b}\t{%P1, %0|%0, %P1}
1962 mov{b}\t{%a1, %0|%0, %a1}"
1963 [(set_attr "type" "imov")
1964 (set_attr "modrm" "0,*")
1965 (set_attr "length_address" "8,0")
1966 (set_attr "length_immediate" "0")
1967 (set_attr "memory" "load")
1968 (set_attr "mode" "QI")])
1970 (define_insn "*movdi_extzv_1"
1971 [(set (match_operand:DI 0 "register_operand" "=R")
1972 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1976 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1977 [(set_attr "type" "imovx")
1978 (set_attr "mode" "DI")])
1980 (define_insn "*movsi_extzv_1"
1981 [(set (match_operand:SI 0 "register_operand" "=R")
1982 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1986 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1987 [(set_attr "type" "imovx")
1988 (set_attr "mode" "SI")])
1990 (define_insn "*movqi_extzv_2"
1991 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1992 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1997 switch (get_attr_type (insn))
2000 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2002 return "mov{b}\t{%h1, %0|%0, %h1}";
2006 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2007 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2008 (ne (symbol_ref "TARGET_MOVX")
2010 (const_string "imovx")
2011 (const_string "imov")))
2013 (if_then_else (eq_attr "type" "imovx")
2015 (const_string "QI")))])
2017 (define_insn "*movqi_extzv_2_rex64"
2018 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2019 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2024 switch (get_attr_type (insn))
2027 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2029 return "mov{b}\t{%h1, %0|%0, %h1}";
2033 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2034 (ne (symbol_ref "TARGET_MOVX")
2036 (const_string "imovx")
2037 (const_string "imov")))
2039 (if_then_else (eq_attr "type" "imovx")
2041 (const_string "QI")))])
2043 (define_insn "movsi_insv_1"
2044 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2047 (match_operand:SI 1 "general_operand" "Qmn"))]
2049 "mov{b}\t{%b1, %h0|%h0, %b1}"
2050 [(set_attr "type" "imov")
2051 (set_attr "mode" "QI")])
2053 (define_insn "*movsi_insv_1_rex64"
2054 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2057 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2059 "mov{b}\t{%b1, %h0|%h0, %b1}"
2060 [(set_attr "type" "imov")
2061 (set_attr "mode" "QI")])
2063 (define_insn "movdi_insv_1_rex64"
2064 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2067 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2069 "mov{b}\t{%b1, %h0|%h0, %b1}"
2070 [(set_attr "type" "imov")
2071 (set_attr "mode" "QI")])
2073 (define_insn "*movqi_insv_2"
2074 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2077 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2080 "mov{b}\t{%h1, %h0|%h0, %h1}"
2081 [(set_attr "type" "imov")
2082 (set_attr "mode" "QI")])
2084 (define_expand "movdi"
2085 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2086 (match_operand:DI 1 "general_operand" ""))]
2088 "ix86_expand_move (DImode, operands); DONE;")
2090 (define_insn "*pushdi"
2091 [(set (match_operand:DI 0 "push_operand" "=<")
2092 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2096 (define_insn "*pushdi2_rex64"
2097 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2098 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2103 [(set_attr "type" "push,multi")
2104 (set_attr "mode" "DI")])
2106 ;; Convert impossible pushes of immediate to existing instructions.
2107 ;; First try to get scratch register and go through it. In case this
2108 ;; fails, push sign extended lower part first and then overwrite
2109 ;; upper part by 32bit move.
2111 [(match_scratch:DI 2 "r")
2112 (set (match_operand:DI 0 "push_operand" "")
2113 (match_operand:DI 1 "immediate_operand" ""))]
2114 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2115 && !x86_64_immediate_operand (operands[1], DImode)"
2116 [(set (match_dup 2) (match_dup 1))
2117 (set (match_dup 0) (match_dup 2))]
2120 ;; We need to define this as both peepholer and splitter for case
2121 ;; peephole2 pass is not run.
2122 ;; "&& 1" is needed to keep it from matching the previous pattern.
2124 [(set (match_operand:DI 0 "push_operand" "")
2125 (match_operand:DI 1 "immediate_operand" ""))]
2126 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2127 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2128 [(set (match_dup 0) (match_dup 1))
2129 (set (match_dup 2) (match_dup 3))]
2130 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2131 operands[1] = gen_lowpart (DImode, operands[2]);
2132 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2137 [(set (match_operand:DI 0 "push_operand" "")
2138 (match_operand:DI 1 "immediate_operand" ""))]
2139 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2140 ? epilogue_completed : reload_completed)
2141 && !symbolic_operand (operands[1], DImode)
2142 && !x86_64_immediate_operand (operands[1], DImode)"
2143 [(set (match_dup 0) (match_dup 1))
2144 (set (match_dup 2) (match_dup 3))]
2145 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2146 operands[1] = gen_lowpart (DImode, operands[2]);
2147 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2151 (define_insn "*pushdi2_prologue_rex64"
2152 [(set (match_operand:DI 0 "push_operand" "=<")
2153 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2154 (clobber (mem:BLK (scratch)))]
2157 [(set_attr "type" "push")
2158 (set_attr "mode" "DI")])
2160 (define_insn "*popdi1_epilogue_rex64"
2161 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2162 (mem:DI (reg:DI SP_REG)))
2163 (set (reg:DI SP_REG)
2164 (plus:DI (reg:DI SP_REG) (const_int 8)))
2165 (clobber (mem:BLK (scratch)))]
2168 [(set_attr "type" "pop")
2169 (set_attr "mode" "DI")])
2171 (define_insn "popdi1"
2172 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2173 (mem:DI (reg:DI SP_REG)))
2174 (set (reg:DI SP_REG)
2175 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2178 [(set_attr "type" "pop")
2179 (set_attr "mode" "DI")])
2181 (define_insn "*movdi_xor_rex64"
2182 [(set (match_operand:DI 0 "register_operand" "=r")
2183 (match_operand:DI 1 "const0_operand" "i"))
2184 (clobber (reg:CC FLAGS_REG))]
2185 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2186 && reload_completed"
2188 [(set_attr "type" "alu1")
2189 (set_attr "mode" "SI")
2190 (set_attr "length_immediate" "0")])
2192 (define_insn "*movdi_or_rex64"
2193 [(set (match_operand:DI 0 "register_operand" "=r")
2194 (match_operand:DI 1 "const_int_operand" "i"))
2195 (clobber (reg:CC FLAGS_REG))]
2196 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2198 && operands[1] == constm1_rtx"
2200 operands[1] = constm1_rtx;
2201 return "or{q}\t{%1, %0|%0, %1}";
2203 [(set_attr "type" "alu1")
2204 (set_attr "mode" "DI")
2205 (set_attr "length_immediate" "1")])
2207 (define_insn "*movdi_2"
2208 [(set (match_operand:DI 0 "nonimmediate_operand"
2209 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2210 (match_operand:DI 1 "general_operand"
2211 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2212 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2217 movq\t{%1, %0|%0, %1}
2218 movq\t{%1, %0|%0, %1}
2220 movq\t{%1, %0|%0, %1}
2221 movdqa\t{%1, %0|%0, %1}
2222 movq\t{%1, %0|%0, %1}
2224 movlps\t{%1, %0|%0, %1}
2225 movaps\t{%1, %0|%0, %1}
2226 movlps\t{%1, %0|%0, %1}"
2227 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2228 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2231 [(set (match_operand:DI 0 "push_operand" "")
2232 (match_operand:DI 1 "general_operand" ""))]
2233 "!TARGET_64BIT && reload_completed
2234 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2236 "ix86_split_long_move (operands); DONE;")
2238 ;; %%% This multiword shite has got to go.
2240 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2241 (match_operand:DI 1 "general_operand" ""))]
2242 "!TARGET_64BIT && reload_completed
2243 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2244 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2246 "ix86_split_long_move (operands); DONE;")
2248 (define_insn "*movdi_1_rex64"
2249 [(set (match_operand:DI 0 "nonimmediate_operand"
2250 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2251 (match_operand:DI 1 "general_operand"
2252 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2253 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2255 switch (get_attr_type (insn))
2258 if (SSE_REG_P (operands[0]))
2259 return "movq2dq\t{%1, %0|%0, %1}";
2261 return "movdq2q\t{%1, %0|%0, %1}";
2264 if (get_attr_mode (insn) == MODE_TI)
2265 return "movdqa\t{%1, %0|%0, %1}";
2269 /* Moves from and into integer register is done using movd
2270 opcode with REX prefix. */
2271 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2272 return "movd\t{%1, %0|%0, %1}";
2273 return "movq\t{%1, %0|%0, %1}";
2277 return "pxor\t%0, %0";
2283 return "lea{q}\t{%a1, %0|%0, %a1}";
2286 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2287 if (get_attr_mode (insn) == MODE_SI)
2288 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2289 else if (which_alternative == 2)
2290 return "movabs{q}\t{%1, %0|%0, %1}";
2292 return "mov{q}\t{%1, %0|%0, %1}";
2296 (cond [(eq_attr "alternative" "5")
2297 (const_string "mmxadd")
2298 (eq_attr "alternative" "6,7,8,9,10")
2299 (const_string "mmxmov")
2300 (eq_attr "alternative" "11")
2301 (const_string "sselog1")
2302 (eq_attr "alternative" "12,13,14,15,16")
2303 (const_string "ssemov")
2304 (eq_attr "alternative" "17,18")
2305 (const_string "ssecvt")
2306 (eq_attr "alternative" "4")
2307 (const_string "multi")
2308 (match_operand:DI 1 "pic_32bit_operand" "")
2309 (const_string "lea")
2311 (const_string "imov")))
2312 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2313 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2314 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2316 ;; Stores and loads of ax to arbitrary constant address.
2317 ;; We fake an second form of instruction to force reload to load address
2318 ;; into register when rax is not available
2319 (define_insn "*movabsdi_1_rex64"
2320 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2321 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2322 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2324 movabs{q}\t{%1, %P0|%P0, %1}
2325 mov{q}\t{%1, %a0|%a0, %1}"
2326 [(set_attr "type" "imov")
2327 (set_attr "modrm" "0,*")
2328 (set_attr "length_address" "8,0")
2329 (set_attr "length_immediate" "0,*")
2330 (set_attr "memory" "store")
2331 (set_attr "mode" "DI")])
2333 (define_insn "*movabsdi_2_rex64"
2334 [(set (match_operand:DI 0 "register_operand" "=a,r")
2335 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2336 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2338 movabs{q}\t{%P1, %0|%0, %P1}
2339 mov{q}\t{%a1, %0|%0, %a1}"
2340 [(set_attr "type" "imov")
2341 (set_attr "modrm" "0,*")
2342 (set_attr "length_address" "8,0")
2343 (set_attr "length_immediate" "0")
2344 (set_attr "memory" "load")
2345 (set_attr "mode" "DI")])
2347 ;; Convert impossible stores of immediate to existing instructions.
2348 ;; First try to get scratch register and go through it. In case this
2349 ;; fails, move by 32bit parts.
2351 [(match_scratch:DI 2 "r")
2352 (set (match_operand:DI 0 "memory_operand" "")
2353 (match_operand:DI 1 "immediate_operand" ""))]
2354 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2355 && !x86_64_immediate_operand (operands[1], DImode)"
2356 [(set (match_dup 2) (match_dup 1))
2357 (set (match_dup 0) (match_dup 2))]
2360 ;; We need to define this as both peepholer and splitter for case
2361 ;; peephole2 pass is not run.
2362 ;; "&& 1" is needed to keep it from matching the previous pattern.
2364 [(set (match_operand:DI 0 "memory_operand" "")
2365 (match_operand:DI 1 "immediate_operand" ""))]
2366 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2367 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2368 [(set (match_dup 2) (match_dup 3))
2369 (set (match_dup 4) (match_dup 5))]
2370 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2373 [(set (match_operand:DI 0 "memory_operand" "")
2374 (match_operand:DI 1 "immediate_operand" ""))]
2375 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2376 ? epilogue_completed : reload_completed)
2377 && !symbolic_operand (operands[1], DImode)
2378 && !x86_64_immediate_operand (operands[1], DImode)"
2379 [(set (match_dup 2) (match_dup 3))
2380 (set (match_dup 4) (match_dup 5))]
2381 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2383 (define_insn "*swapdi_rex64"
2384 [(set (match_operand:DI 0 "register_operand" "+r")
2385 (match_operand:DI 1 "register_operand" "+r"))
2390 [(set_attr "type" "imov")
2391 (set_attr "mode" "DI")
2392 (set_attr "pent_pair" "np")
2393 (set_attr "athlon_decode" "vector")
2394 (set_attr "amdfam10_decode" "double")])
2396 (define_expand "movti"
2397 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2398 (match_operand:TI 1 "nonimmediate_operand" ""))]
2399 "TARGET_SSE || TARGET_64BIT"
2402 ix86_expand_move (TImode, operands);
2403 else if (push_operand (operands[0], TImode))
2404 ix86_expand_push (TImode, operands[1]);
2406 ix86_expand_vector_move (TImode, operands);
2410 (define_insn "*movti_internal"
2411 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2412 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2413 "TARGET_SSE && !TARGET_64BIT
2414 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2416 switch (which_alternative)
2419 if (get_attr_mode (insn) == MODE_V4SF)
2420 return "xorps\t%0, %0";
2422 return "pxor\t%0, %0";
2425 /* TDmode values are passed as TImode on the stack. Moving them
2426 to stack may result in unaligned memory access. */
2427 if (misaligned_operand (operands[0], TImode)
2428 || misaligned_operand (operands[1], TImode))
2430 if (get_attr_mode (insn) == MODE_V4SF)
2431 return "movups\t{%1, %0|%0, %1}";
2433 return "movdqu\t{%1, %0|%0, %1}";
2437 if (get_attr_mode (insn) == MODE_V4SF)
2438 return "movaps\t{%1, %0|%0, %1}";
2440 return "movdqa\t{%1, %0|%0, %1}";
2446 [(set_attr "type" "sselog1,ssemov,ssemov")
2448 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2449 (ne (symbol_ref "optimize_size") (const_int 0)))
2450 (const_string "V4SF")
2451 (and (eq_attr "alternative" "2")
2452 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2454 (const_string "V4SF")]
2455 (const_string "TI")))])
2457 (define_insn "*movti_rex64"
2458 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2459 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2461 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2463 switch (which_alternative)
2469 if (get_attr_mode (insn) == MODE_V4SF)
2470 return "xorps\t%0, %0";
2472 return "pxor\t%0, %0";
2475 /* TDmode values are passed as TImode on the stack. Moving them
2476 to stack may result in unaligned memory access. */
2477 if (misaligned_operand (operands[0], TImode)
2478 || misaligned_operand (operands[1], TImode))
2480 if (get_attr_mode (insn) == MODE_V4SF)
2481 return "movups\t{%1, %0|%0, %1}";
2483 return "movdqu\t{%1, %0|%0, %1}";
2487 if (get_attr_mode (insn) == MODE_V4SF)
2488 return "movaps\t{%1, %0|%0, %1}";
2490 return "movdqa\t{%1, %0|%0, %1}";
2496 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2498 (cond [(eq_attr "alternative" "2,3")
2500 (ne (symbol_ref "optimize_size")
2502 (const_string "V4SF")
2503 (const_string "TI"))
2504 (eq_attr "alternative" "4")
2506 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2508 (ne (symbol_ref "optimize_size")
2510 (const_string "V4SF")
2511 (const_string "TI"))]
2512 (const_string "DI")))])
2515 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2516 (match_operand:TI 1 "general_operand" ""))]
2517 "reload_completed && !SSE_REG_P (operands[0])
2518 && !SSE_REG_P (operands[1])"
2520 "ix86_split_long_move (operands); DONE;")
2522 ;; This expands to what emit_move_complex would generate if we didn't
2523 ;; have a movti pattern. Having this avoids problems with reload on
2524 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2525 ;; to have around all the time.
2526 (define_expand "movcdi"
2527 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2528 (match_operand:CDI 1 "general_operand" ""))]
2531 if (push_operand (operands[0], CDImode))
2532 emit_move_complex_push (CDImode, operands[0], operands[1]);
2534 emit_move_complex_parts (operands[0], operands[1]);
2538 (define_expand "movsf"
2539 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2540 (match_operand:SF 1 "general_operand" ""))]
2542 "ix86_expand_move (SFmode, operands); DONE;")
2544 (define_insn "*pushsf"
2545 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2546 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2549 /* Anything else should be already split before reg-stack. */
2550 gcc_assert (which_alternative == 1);
2551 return "push{l}\t%1";
2553 [(set_attr "type" "multi,push,multi")
2554 (set_attr "unit" "i387,*,*")
2555 (set_attr "mode" "SF,SI,SF")])
2557 (define_insn "*pushsf_rex64"
2558 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2559 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2562 /* Anything else should be already split before reg-stack. */
2563 gcc_assert (which_alternative == 1);
2564 return "push{q}\t%q1";
2566 [(set_attr "type" "multi,push,multi")
2567 (set_attr "unit" "i387,*,*")
2568 (set_attr "mode" "SF,DI,SF")])
2571 [(set (match_operand:SF 0 "push_operand" "")
2572 (match_operand:SF 1 "memory_operand" ""))]
2574 && MEM_P (operands[1])
2575 && (operands[2] = find_constant_src (insn))"
2580 ;; %%% Kill this when call knows how to work this out.
2582 [(set (match_operand:SF 0 "push_operand" "")
2583 (match_operand:SF 1 "any_fp_register_operand" ""))]
2585 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2586 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2589 [(set (match_operand:SF 0 "push_operand" "")
2590 (match_operand:SF 1 "any_fp_register_operand" ""))]
2592 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2593 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2595 (define_insn "*movsf_1"
2596 [(set (match_operand:SF 0 "nonimmediate_operand"
2597 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2598 (match_operand:SF 1 "general_operand"
2599 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2600 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2601 && (reload_in_progress || reload_completed
2602 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2603 || (!TARGET_SSE_MATH && optimize_size
2604 && standard_80387_constant_p (operands[1]))
2605 || GET_CODE (operands[1]) != CONST_DOUBLE
2606 || memory_operand (operands[0], SFmode))"
2608 switch (which_alternative)
2612 return output_387_reg_move (insn, operands);
2615 return standard_80387_constant_opcode (operands[1]);
2619 return "mov{l}\t{%1, %0|%0, %1}";
2621 if (get_attr_mode (insn) == MODE_TI)
2622 return "pxor\t%0, %0";
2624 return "xorps\t%0, %0";
2626 if (get_attr_mode (insn) == MODE_V4SF)
2627 return "movaps\t{%1, %0|%0, %1}";
2629 return "movss\t{%1, %0|%0, %1}";
2631 return "movss\t{%1, %0|%0, %1}";
2634 case 12: case 13: case 14: case 15:
2635 return "movd\t{%1, %0|%0, %1}";
2638 return "movq\t{%1, %0|%0, %1}";
2644 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2646 (cond [(eq_attr "alternative" "3,4,9,10")
2648 (eq_attr "alternative" "5")
2650 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2652 (ne (symbol_ref "TARGET_SSE2")
2654 (eq (symbol_ref "optimize_size")
2657 (const_string "V4SF"))
2658 /* For architectures resolving dependencies on
2659 whole SSE registers use APS move to break dependency
2660 chains, otherwise use short move to avoid extra work.
2662 Do the same for architectures resolving dependencies on
2663 the parts. While in DF mode it is better to always handle
2664 just register parts, the SF mode is different due to lack
2665 of instructions to load just part of the register. It is
2666 better to maintain the whole registers in single format
2667 to avoid problems on using packed logical operations. */
2668 (eq_attr "alternative" "6")
2670 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2672 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2674 (const_string "V4SF")
2675 (const_string "SF"))
2676 (eq_attr "alternative" "11")
2677 (const_string "DI")]
2678 (const_string "SF")))])
2680 (define_insn "*swapsf"
2681 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2682 (match_operand:SF 1 "fp_register_operand" "+f"))
2685 "reload_completed || TARGET_80387"
2687 if (STACK_TOP_P (operands[0]))
2692 [(set_attr "type" "fxch")
2693 (set_attr "mode" "SF")])
2695 (define_expand "movdf"
2696 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2697 (match_operand:DF 1 "general_operand" ""))]
2699 "ix86_expand_move (DFmode, operands); DONE;")
2701 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2702 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2703 ;; On the average, pushdf using integers can be still shorter. Allow this
2704 ;; pattern for optimize_size too.
2706 (define_insn "*pushdf_nointeger"
2707 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2708 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2709 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2711 /* This insn should be already split before reg-stack. */
2714 [(set_attr "type" "multi")
2715 (set_attr "unit" "i387,*,*,*")
2716 (set_attr "mode" "DF,SI,SI,DF")])
2718 (define_insn "*pushdf_integer"
2719 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2720 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2721 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2723 /* This insn should be already split before reg-stack. */
2726 [(set_attr "type" "multi")
2727 (set_attr "unit" "i387,*,*")
2728 (set_attr "mode" "DF,SI,DF")])
2730 ;; %%% Kill this when call knows how to work this out.
2732 [(set (match_operand:DF 0 "push_operand" "")
2733 (match_operand:DF 1 "any_fp_register_operand" ""))]
2734 "!TARGET_64BIT && reload_completed"
2735 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2736 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2740 [(set (match_operand:DF 0 "push_operand" "")
2741 (match_operand:DF 1 "any_fp_register_operand" ""))]
2742 "TARGET_64BIT && reload_completed"
2743 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2744 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2748 [(set (match_operand:DF 0 "push_operand" "")
2749 (match_operand:DF 1 "general_operand" ""))]
2752 "ix86_split_long_move (operands); DONE;")
2754 ;; Moving is usually shorter when only FP registers are used. This separate
2755 ;; movdf pattern avoids the use of integer registers for FP operations
2756 ;; when optimizing for size.
2758 (define_insn "*movdf_nointeger"
2759 [(set (match_operand:DF 0 "nonimmediate_operand"
2760 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2761 (match_operand:DF 1 "general_operand"
2762 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2763 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2764 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2765 && (reload_in_progress || reload_completed
2766 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2767 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2768 && !memory_operand (operands[0], DFmode)
2769 && standard_80387_constant_p (operands[1]))
2770 || GET_CODE (operands[1]) != CONST_DOUBLE
2772 || !TARGET_MEMORY_MISMATCH_STALL
2773 || reload_in_progress || reload_completed)
2774 && memory_operand (operands[0], DFmode)))"
2776 switch (which_alternative)
2780 return output_387_reg_move (insn, operands);
2783 return standard_80387_constant_opcode (operands[1]);
2789 switch (get_attr_mode (insn))
2792 return "xorps\t%0, %0";
2794 return "xorpd\t%0, %0";
2796 return "pxor\t%0, %0";
2803 switch (get_attr_mode (insn))
2806 return "movaps\t{%1, %0|%0, %1}";
2808 return "movapd\t{%1, %0|%0, %1}";
2810 return "movdqa\t{%1, %0|%0, %1}";
2812 return "movq\t{%1, %0|%0, %1}";
2814 return "movsd\t{%1, %0|%0, %1}";
2816 return "movlpd\t{%1, %0|%0, %1}";
2818 return "movlps\t{%1, %0|%0, %1}";
2827 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2829 (cond [(eq_attr "alternative" "0,1,2")
2831 (eq_attr "alternative" "3,4")
2834 /* For SSE1, we have many fewer alternatives. */
2835 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2836 (cond [(eq_attr "alternative" "5,6")
2837 (const_string "V4SF")
2839 (const_string "V2SF"))
2841 /* xorps is one byte shorter. */
2842 (eq_attr "alternative" "5")
2843 (cond [(ne (symbol_ref "optimize_size")
2845 (const_string "V4SF")
2846 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2850 (const_string "V2DF"))
2852 /* For architectures resolving dependencies on
2853 whole SSE registers use APD move to break dependency
2854 chains, otherwise use short move to avoid extra work.
2856 movaps encodes one byte shorter. */
2857 (eq_attr "alternative" "6")
2859 [(ne (symbol_ref "optimize_size")
2861 (const_string "V4SF")
2862 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2864 (const_string "V2DF")
2866 (const_string "DF"))
2867 /* For architectures resolving dependencies on register
2868 parts we may avoid extra work to zero out upper part
2870 (eq_attr "alternative" "7")
2872 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2874 (const_string "V1DF")
2875 (const_string "DF"))
2877 (const_string "DF")))])
2879 (define_insn "*movdf_integer_rex64"
2880 [(set (match_operand:DF 0 "nonimmediate_operand"
2881 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2882 (match_operand:DF 1 "general_operand"
2883 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2884 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2885 && (reload_in_progress || reload_completed
2886 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2887 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2888 && standard_80387_constant_p (operands[1]))
2889 || GET_CODE (operands[1]) != CONST_DOUBLE
2890 || memory_operand (operands[0], DFmode))"
2892 switch (which_alternative)
2896 return output_387_reg_move (insn, operands);
2899 return standard_80387_constant_opcode (operands[1]);
2906 switch (get_attr_mode (insn))
2909 return "xorps\t%0, %0";
2911 return "xorpd\t%0, %0";
2913 return "pxor\t%0, %0";
2920 switch (get_attr_mode (insn))
2923 return "movaps\t{%1, %0|%0, %1}";
2925 return "movapd\t{%1, %0|%0, %1}";
2927 return "movdqa\t{%1, %0|%0, %1}";
2929 return "movq\t{%1, %0|%0, %1}";
2931 return "movsd\t{%1, %0|%0, %1}";
2933 return "movlpd\t{%1, %0|%0, %1}";
2935 return "movlps\t{%1, %0|%0, %1}";
2942 return "movd\t{%1, %0|%0, %1}";
2948 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2950 (cond [(eq_attr "alternative" "0,1,2")
2952 (eq_attr "alternative" "3,4,9,10")
2955 /* For SSE1, we have many fewer alternatives. */
2956 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2957 (cond [(eq_attr "alternative" "5,6")
2958 (const_string "V4SF")
2960 (const_string "V2SF"))
2962 /* xorps is one byte shorter. */
2963 (eq_attr "alternative" "5")
2964 (cond [(ne (symbol_ref "optimize_size")
2966 (const_string "V4SF")
2967 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2971 (const_string "V2DF"))
2973 /* For architectures resolving dependencies on
2974 whole SSE registers use APD move to break dependency
2975 chains, otherwise use short move to avoid extra work.
2977 movaps encodes one byte shorter. */
2978 (eq_attr "alternative" "6")
2980 [(ne (symbol_ref "optimize_size")
2982 (const_string "V4SF")
2983 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2985 (const_string "V2DF")
2987 (const_string "DF"))
2988 /* For architectures resolving dependencies on register
2989 parts we may avoid extra work to zero out upper part
2991 (eq_attr "alternative" "7")
2993 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2995 (const_string "V1DF")
2996 (const_string "DF"))
2998 (const_string "DF")))])
3000 (define_insn "*movdf_integer"
3001 [(set (match_operand:DF 0 "nonimmediate_operand"
3002 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3003 (match_operand:DF 1 "general_operand"
3004 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3005 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3006 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3007 && (reload_in_progress || reload_completed
3008 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3009 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3010 && standard_80387_constant_p (operands[1]))
3011 || GET_CODE (operands[1]) != CONST_DOUBLE
3012 || memory_operand (operands[0], DFmode))"
3014 switch (which_alternative)
3018 return output_387_reg_move (insn, operands);
3021 return standard_80387_constant_opcode (operands[1]);
3028 switch (get_attr_mode (insn))
3031 return "xorps\t%0, %0";
3033 return "xorpd\t%0, %0";
3035 return "pxor\t%0, %0";
3042 switch (get_attr_mode (insn))
3045 return "movaps\t{%1, %0|%0, %1}";
3047 return "movapd\t{%1, %0|%0, %1}";
3049 return "movdqa\t{%1, %0|%0, %1}";
3051 return "movq\t{%1, %0|%0, %1}";
3053 return "movsd\t{%1, %0|%0, %1}";
3055 return "movlpd\t{%1, %0|%0, %1}";
3057 return "movlps\t{%1, %0|%0, %1}";
3066 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3068 (cond [(eq_attr "alternative" "0,1,2")
3070 (eq_attr "alternative" "3,4")
3073 /* For SSE1, we have many fewer alternatives. */
3074 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3075 (cond [(eq_attr "alternative" "5,6")
3076 (const_string "V4SF")
3078 (const_string "V2SF"))
3080 /* xorps is one byte shorter. */
3081 (eq_attr "alternative" "5")
3082 (cond [(ne (symbol_ref "optimize_size")
3084 (const_string "V4SF")
3085 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3089 (const_string "V2DF"))
3091 /* For architectures resolving dependencies on
3092 whole SSE registers use APD move to break dependency
3093 chains, otherwise use short move to avoid extra work.
3095 movaps encodes one byte shorter. */
3096 (eq_attr "alternative" "6")
3098 [(ne (symbol_ref "optimize_size")
3100 (const_string "V4SF")
3101 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3103 (const_string "V2DF")
3105 (const_string "DF"))
3106 /* For architectures resolving dependencies on register
3107 parts we may avoid extra work to zero out upper part
3109 (eq_attr "alternative" "7")
3111 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3113 (const_string "V1DF")
3114 (const_string "DF"))
3116 (const_string "DF")))])
3119 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3120 (match_operand:DF 1 "general_operand" ""))]
3122 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3123 && ! (ANY_FP_REG_P (operands[0]) ||
3124 (GET_CODE (operands[0]) == SUBREG
3125 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3126 && ! (ANY_FP_REG_P (operands[1]) ||
3127 (GET_CODE (operands[1]) == SUBREG
3128 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3130 "ix86_split_long_move (operands); DONE;")
3132 (define_insn "*swapdf"
3133 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3134 (match_operand:DF 1 "fp_register_operand" "+f"))
3137 "reload_completed || TARGET_80387"
3139 if (STACK_TOP_P (operands[0]))
3144 [(set_attr "type" "fxch")
3145 (set_attr "mode" "DF")])
3147 (define_expand "movxf"
3148 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3149 (match_operand:XF 1 "general_operand" ""))]
3151 "ix86_expand_move (XFmode, operands); DONE;")
3153 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3154 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3155 ;; Pushing using integer instructions is longer except for constants
3156 ;; and direct memory references.
3157 ;; (assuming that any given constant is pushed only once, but this ought to be
3158 ;; handled elsewhere).
3160 (define_insn "*pushxf_nointeger"
3161 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3162 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3165 /* This insn should be already split before reg-stack. */
3168 [(set_attr "type" "multi")
3169 (set_attr "unit" "i387,*,*")
3170 (set_attr "mode" "XF,SI,SI")])
3172 (define_insn "*pushxf_integer"
3173 [(set (match_operand:XF 0 "push_operand" "=<,<")
3174 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3177 /* This insn should be already split before reg-stack. */
3180 [(set_attr "type" "multi")
3181 (set_attr "unit" "i387,*")
3182 (set_attr "mode" "XF,SI")])
3185 [(set (match_operand 0 "push_operand" "")
3186 (match_operand 1 "general_operand" ""))]
3188 && (GET_MODE (operands[0]) == XFmode
3189 || GET_MODE (operands[0]) == DFmode)
3190 && !ANY_FP_REG_P (operands[1])"
3192 "ix86_split_long_move (operands); DONE;")
3195 [(set (match_operand:XF 0 "push_operand" "")
3196 (match_operand:XF 1 "any_fp_register_operand" ""))]
3198 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3199 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3200 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3203 [(set (match_operand:XF 0 "push_operand" "")
3204 (match_operand:XF 1 "any_fp_register_operand" ""))]
3206 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3207 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3208 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3210 ;; Do not use integer registers when optimizing for size
3211 (define_insn "*movxf_nointeger"
3212 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3213 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3215 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3216 && (reload_in_progress || reload_completed
3217 || (optimize_size && standard_80387_constant_p (operands[1]))
3218 || GET_CODE (operands[1]) != CONST_DOUBLE
3219 || memory_operand (operands[0], XFmode))"
3221 switch (which_alternative)
3225 return output_387_reg_move (insn, operands);
3228 return standard_80387_constant_opcode (operands[1]);
3236 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3237 (set_attr "mode" "XF,XF,XF,SI,SI")])
3239 (define_insn "*movxf_integer"
3240 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3241 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3243 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3244 && (reload_in_progress || reload_completed
3245 || (optimize_size && standard_80387_constant_p (operands[1]))
3246 || GET_CODE (operands[1]) != CONST_DOUBLE
3247 || memory_operand (operands[0], XFmode))"
3249 switch (which_alternative)
3253 return output_387_reg_move (insn, operands);
3256 return standard_80387_constant_opcode (operands[1]);
3265 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3266 (set_attr "mode" "XF,XF,XF,SI,SI")])
3268 (define_expand "movtf"
3269 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3270 (match_operand:TF 1 "nonimmediate_operand" ""))]
3273 ix86_expand_move (TFmode, operands);
3277 (define_insn "*movtf_internal"
3278 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3279 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3281 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3283 switch (which_alternative)
3287 if (get_attr_mode (insn) == MODE_V4SF)
3288 return "movaps\t{%1, %0|%0, %1}";
3290 return "movdqa\t{%1, %0|%0, %1}";
3292 if (get_attr_mode (insn) == MODE_V4SF)
3293 return "xorps\t%0, %0";
3295 return "pxor\t%0, %0";
3303 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3305 (cond [(eq_attr "alternative" "0,2")
3307 (ne (symbol_ref "optimize_size")
3309 (const_string "V4SF")
3310 (const_string "TI"))
3311 (eq_attr "alternative" "1")
3313 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3315 (ne (symbol_ref "optimize_size")
3317 (const_string "V4SF")
3318 (const_string "TI"))]
3319 (const_string "DI")))])
3322 [(set (match_operand 0 "nonimmediate_operand" "")
3323 (match_operand 1 "general_operand" ""))]
3325 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3326 && GET_MODE (operands[0]) == XFmode
3327 && ! (ANY_FP_REG_P (operands[0]) ||
3328 (GET_CODE (operands[0]) == SUBREG
3329 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3330 && ! (ANY_FP_REG_P (operands[1]) ||
3331 (GET_CODE (operands[1]) == SUBREG
3332 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3334 "ix86_split_long_move (operands); DONE;")
3337 [(set (match_operand 0 "register_operand" "")
3338 (match_operand 1 "memory_operand" ""))]
3340 && MEM_P (operands[1])
3341 && (GET_MODE (operands[0]) == TFmode
3342 || GET_MODE (operands[0]) == XFmode
3343 || GET_MODE (operands[0]) == SFmode
3344 || GET_MODE (operands[0]) == DFmode)
3345 && (operands[2] = find_constant_src (insn))"
3346 [(set (match_dup 0) (match_dup 2))]
3348 rtx c = operands[2];
3349 rtx r = operands[0];
3351 if (GET_CODE (r) == SUBREG)
3356 if (!standard_sse_constant_p (c))
3359 else if (FP_REG_P (r))
3361 if (!standard_80387_constant_p (c))
3364 else if (MMX_REG_P (r))
3369 [(set (match_operand 0 "register_operand" "")
3370 (float_extend (match_operand 1 "memory_operand" "")))]
3372 && MEM_P (operands[1])
3373 && (GET_MODE (operands[0]) == TFmode
3374 || GET_MODE (operands[0]) == XFmode
3375 || GET_MODE (operands[0]) == SFmode
3376 || GET_MODE (operands[0]) == DFmode)
3377 && (operands[2] = find_constant_src (insn))"
3378 [(set (match_dup 0) (match_dup 2))]
3380 rtx c = operands[2];
3381 rtx r = operands[0];
3383 if (GET_CODE (r) == SUBREG)
3388 if (!standard_sse_constant_p (c))
3391 else if (FP_REG_P (r))
3393 if (!standard_80387_constant_p (c))
3396 else if (MMX_REG_P (r))
3400 (define_insn "swapxf"
3401 [(set (match_operand:XF 0 "register_operand" "+f")
3402 (match_operand:XF 1 "register_operand" "+f"))
3407 if (STACK_TOP_P (operands[0]))
3412 [(set_attr "type" "fxch")
3413 (set_attr "mode" "XF")])
3415 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3417 [(set (match_operand:X87MODEF 0 "register_operand" "")
3418 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3419 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3420 && (standard_80387_constant_p (operands[1]) == 8
3421 || standard_80387_constant_p (operands[1]) == 9)"
3422 [(set (match_dup 0)(match_dup 1))
3424 (neg:X87MODEF (match_dup 0)))]
3428 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3429 if (real_isnegzero (&r))
3430 operands[1] = CONST0_RTX (<MODE>mode);
3432 operands[1] = CONST1_RTX (<MODE>mode);
3436 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3437 (match_operand:TF 1 "general_operand" ""))]
3439 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3441 "ix86_split_long_move (operands); DONE;")
3443 ;; Zero extension instructions
3445 (define_expand "zero_extendhisi2"
3446 [(set (match_operand:SI 0 "register_operand" "")
3447 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3450 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3452 operands[1] = force_reg (HImode, operands[1]);
3453 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3458 (define_insn "zero_extendhisi2_and"
3459 [(set (match_operand:SI 0 "register_operand" "=r")
3460 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3461 (clobber (reg:CC FLAGS_REG))]
3462 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3464 [(set_attr "type" "alu1")
3465 (set_attr "mode" "SI")])
3468 [(set (match_operand:SI 0 "register_operand" "")
3469 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3470 (clobber (reg:CC FLAGS_REG))]
3471 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3472 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3473 (clobber (reg:CC FLAGS_REG))])]
3476 (define_insn "*zero_extendhisi2_movzwl"
3477 [(set (match_operand:SI 0 "register_operand" "=r")
3478 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3479 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3480 "movz{wl|x}\t{%1, %0|%0, %1}"
3481 [(set_attr "type" "imovx")
3482 (set_attr "mode" "SI")])
3484 (define_expand "zero_extendqihi2"
3486 [(set (match_operand:HI 0 "register_operand" "")
3487 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3488 (clobber (reg:CC FLAGS_REG))])]
3492 (define_insn "*zero_extendqihi2_and"
3493 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3494 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3495 (clobber (reg:CC FLAGS_REG))]
3496 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3498 [(set_attr "type" "alu1")
3499 (set_attr "mode" "HI")])
3501 (define_insn "*zero_extendqihi2_movzbw_and"
3502 [(set (match_operand:HI 0 "register_operand" "=r,r")
3503 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3504 (clobber (reg:CC FLAGS_REG))]
3505 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3507 [(set_attr "type" "imovx,alu1")
3508 (set_attr "mode" "HI")])
3510 ; zero extend to SImode here to avoid partial register stalls
3511 (define_insn "*zero_extendqihi2_movzbl"
3512 [(set (match_operand:HI 0 "register_operand" "=r")
3513 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3514 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3515 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3516 [(set_attr "type" "imovx")
3517 (set_attr "mode" "SI")])
3519 ;; For the movzbw case strip only the clobber
3521 [(set (match_operand:HI 0 "register_operand" "")
3522 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3523 (clobber (reg:CC FLAGS_REG))]
3525 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3526 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3527 [(set (match_operand:HI 0 "register_operand" "")
3528 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3530 ;; When source and destination does not overlap, clear destination
3531 ;; first and then do the movb
3533 [(set (match_operand:HI 0 "register_operand" "")
3534 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3535 (clobber (reg:CC FLAGS_REG))]
3537 && ANY_QI_REG_P (operands[0])
3538 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3539 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3540 [(set (match_dup 0) (const_int 0))
3541 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3542 "operands[2] = gen_lowpart (QImode, operands[0]);")
3544 ;; Rest is handled by single and.
3546 [(set (match_operand:HI 0 "register_operand" "")
3547 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3548 (clobber (reg:CC FLAGS_REG))]
3550 && true_regnum (operands[0]) == true_regnum (operands[1])"
3551 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3552 (clobber (reg:CC FLAGS_REG))])]
3555 (define_expand "zero_extendqisi2"
3557 [(set (match_operand:SI 0 "register_operand" "")
3558 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3559 (clobber (reg:CC FLAGS_REG))])]
3563 (define_insn "*zero_extendqisi2_and"
3564 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3565 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3566 (clobber (reg:CC FLAGS_REG))]
3567 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3569 [(set_attr "type" "alu1")
3570 (set_attr "mode" "SI")])
3572 (define_insn "*zero_extendqisi2_movzbw_and"
3573 [(set (match_operand:SI 0 "register_operand" "=r,r")
3574 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3575 (clobber (reg:CC FLAGS_REG))]
3576 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3578 [(set_attr "type" "imovx,alu1")
3579 (set_attr "mode" "SI")])
3581 (define_insn "*zero_extendqisi2_movzbw"
3582 [(set (match_operand:SI 0 "register_operand" "=r")
3583 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3584 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3585 "movz{bl|x}\t{%1, %0|%0, %1}"
3586 [(set_attr "type" "imovx")
3587 (set_attr "mode" "SI")])
3589 ;; For the movzbl case strip only the clobber
3591 [(set (match_operand:SI 0 "register_operand" "")
3592 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3593 (clobber (reg:CC FLAGS_REG))]
3595 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3596 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3598 (zero_extend:SI (match_dup 1)))])
3600 ;; When source and destination does not overlap, clear destination
3601 ;; first and then do the movb
3603 [(set (match_operand:SI 0 "register_operand" "")
3604 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3605 (clobber (reg:CC FLAGS_REG))]
3607 && ANY_QI_REG_P (operands[0])
3608 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3609 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3610 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3611 [(set (match_dup 0) (const_int 0))
3612 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3613 "operands[2] = gen_lowpart (QImode, operands[0]);")
3615 ;; Rest is handled by single and.
3617 [(set (match_operand:SI 0 "register_operand" "")
3618 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3619 (clobber (reg:CC FLAGS_REG))]
3621 && true_regnum (operands[0]) == true_regnum (operands[1])"
3622 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3623 (clobber (reg:CC FLAGS_REG))])]
3626 ;; %%% Kill me once multi-word ops are sane.
3627 (define_expand "zero_extendsidi2"
3628 [(set (match_operand:DI 0 "register_operand" "")
3629 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3634 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3639 (define_insn "zero_extendsidi2_32"
3640 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3642 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3643 (clobber (reg:CC FLAGS_REG))]
3649 movd\t{%1, %0|%0, %1}
3650 movd\t{%1, %0|%0, %1}
3651 movd\t{%1, %0|%0, %1}
3652 movd\t{%1, %0|%0, %1}"
3653 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3654 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3656 (define_insn "zero_extendsidi2_rex64"
3657 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3659 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3662 mov\t{%k1, %k0|%k0, %k1}
3664 movd\t{%1, %0|%0, %1}
3665 movd\t{%1, %0|%0, %1}
3666 movd\t{%1, %0|%0, %1}
3667 movd\t{%1, %0|%0, %1}"
3668 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3669 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3672 [(set (match_operand:DI 0 "memory_operand" "")
3673 (zero_extend:DI (match_dup 0)))]
3675 [(set (match_dup 4) (const_int 0))]
3676 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3679 [(set (match_operand:DI 0 "register_operand" "")
3680 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3681 (clobber (reg:CC FLAGS_REG))]
3682 "!TARGET_64BIT && reload_completed
3683 && true_regnum (operands[0]) == true_regnum (operands[1])"
3684 [(set (match_dup 4) (const_int 0))]
3685 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3688 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3689 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3690 (clobber (reg:CC FLAGS_REG))]
3691 "!TARGET_64BIT && reload_completed
3692 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3693 [(set (match_dup 3) (match_dup 1))
3694 (set (match_dup 4) (const_int 0))]
3695 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3697 (define_insn "zero_extendhidi2"
3698 [(set (match_operand:DI 0 "register_operand" "=r")
3699 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3701 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3702 [(set_attr "type" "imovx")
3703 (set_attr "mode" "DI")])
3705 (define_insn "zero_extendqidi2"
3706 [(set (match_operand:DI 0 "register_operand" "=r")
3707 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3709 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3710 [(set_attr "type" "imovx")
3711 (set_attr "mode" "DI")])
3713 ;; Sign extension instructions
3715 (define_expand "extendsidi2"
3716 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3717 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3718 (clobber (reg:CC FLAGS_REG))
3719 (clobber (match_scratch:SI 2 ""))])]
3724 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3729 (define_insn "*extendsidi2_1"
3730 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3731 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3732 (clobber (reg:CC FLAGS_REG))
3733 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3737 (define_insn "extendsidi2_rex64"
3738 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3739 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3743 movs{lq|x}\t{%1,%0|%0, %1}"
3744 [(set_attr "type" "imovx")
3745 (set_attr "mode" "DI")
3746 (set_attr "prefix_0f" "0")
3747 (set_attr "modrm" "0,1")])
3749 (define_insn "extendhidi2"
3750 [(set (match_operand:DI 0 "register_operand" "=r")
3751 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3753 "movs{wq|x}\t{%1,%0|%0, %1}"
3754 [(set_attr "type" "imovx")
3755 (set_attr "mode" "DI")])
3757 (define_insn "extendqidi2"
3758 [(set (match_operand:DI 0 "register_operand" "=r")
3759 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3761 "movs{bq|x}\t{%1,%0|%0, %1}"
3762 [(set_attr "type" "imovx")
3763 (set_attr "mode" "DI")])
3765 ;; Extend to memory case when source register does die.
3767 [(set (match_operand:DI 0 "memory_operand" "")
3768 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3769 (clobber (reg:CC FLAGS_REG))
3770 (clobber (match_operand:SI 2 "register_operand" ""))]
3772 && dead_or_set_p (insn, operands[1])
3773 && !reg_mentioned_p (operands[1], operands[0]))"
3774 [(set (match_dup 3) (match_dup 1))
3775 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3776 (clobber (reg:CC FLAGS_REG))])
3777 (set (match_dup 4) (match_dup 1))]
3778 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3780 ;; Extend to memory case when source register does not die.
3782 [(set (match_operand:DI 0 "memory_operand" "")
3783 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3784 (clobber (reg:CC FLAGS_REG))
3785 (clobber (match_operand:SI 2 "register_operand" ""))]
3789 split_di (&operands[0], 1, &operands[3], &operands[4]);
3791 emit_move_insn (operands[3], operands[1]);
3793 /* Generate a cltd if possible and doing so it profitable. */
3794 if ((optimize_size || TARGET_USE_CLTD)
3795 && true_regnum (operands[1]) == AX_REG
3796 && true_regnum (operands[2]) == DX_REG)
3798 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3802 emit_move_insn (operands[2], operands[1]);
3803 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3805 emit_move_insn (operands[4], operands[2]);
3809 ;; Extend to register case. Optimize case where source and destination
3810 ;; registers match and cases where we can use cltd.
3812 [(set (match_operand:DI 0 "register_operand" "")
3813 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3814 (clobber (reg:CC FLAGS_REG))
3815 (clobber (match_scratch:SI 2 ""))]
3819 split_di (&operands[0], 1, &operands[3], &operands[4]);
3821 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3822 emit_move_insn (operands[3], operands[1]);
3824 /* Generate a cltd if possible and doing so it profitable. */
3825 if ((optimize_size || TARGET_USE_CLTD)
3826 && true_regnum (operands[3]) == AX_REG)
3828 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3832 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3833 emit_move_insn (operands[4], operands[1]);
3835 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3839 (define_insn "extendhisi2"
3840 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3841 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3844 switch (get_attr_prefix_0f (insn))
3847 return "{cwtl|cwde}";
3849 return "movs{wl|x}\t{%1,%0|%0, %1}";
3852 [(set_attr "type" "imovx")
3853 (set_attr "mode" "SI")
3854 (set (attr "prefix_0f")
3855 ;; movsx is short decodable while cwtl is vector decoded.
3856 (if_then_else (and (eq_attr "cpu" "!k6")
3857 (eq_attr "alternative" "0"))
3859 (const_string "1")))
3861 (if_then_else (eq_attr "prefix_0f" "0")
3863 (const_string "1")))])
3865 (define_insn "*extendhisi2_zext"
3866 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3868 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3871 switch (get_attr_prefix_0f (insn))
3874 return "{cwtl|cwde}";
3876 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3879 [(set_attr "type" "imovx")
3880 (set_attr "mode" "SI")
3881 (set (attr "prefix_0f")
3882 ;; movsx is short decodable while cwtl is vector decoded.
3883 (if_then_else (and (eq_attr "cpu" "!k6")
3884 (eq_attr "alternative" "0"))
3886 (const_string "1")))
3888 (if_then_else (eq_attr "prefix_0f" "0")
3890 (const_string "1")))])
3892 (define_insn "extendqihi2"
3893 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3894 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3897 switch (get_attr_prefix_0f (insn))
3900 return "{cbtw|cbw}";
3902 return "movs{bw|x}\t{%1,%0|%0, %1}";
3905 [(set_attr "type" "imovx")
3906 (set_attr "mode" "HI")
3907 (set (attr "prefix_0f")
3908 ;; movsx is short decodable while cwtl is vector decoded.
3909 (if_then_else (and (eq_attr "cpu" "!k6")
3910 (eq_attr "alternative" "0"))
3912 (const_string "1")))
3914 (if_then_else (eq_attr "prefix_0f" "0")
3916 (const_string "1")))])
3918 (define_insn "extendqisi2"
3919 [(set (match_operand:SI 0 "register_operand" "=r")
3920 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3922 "movs{bl|x}\t{%1,%0|%0, %1}"
3923 [(set_attr "type" "imovx")
3924 (set_attr "mode" "SI")])
3926 (define_insn "*extendqisi2_zext"
3927 [(set (match_operand:DI 0 "register_operand" "=r")
3929 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3931 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3932 [(set_attr "type" "imovx")
3933 (set_attr "mode" "SI")])
3935 ;; Conversions between float and double.
3937 ;; These are all no-ops in the model used for the 80387. So just
3940 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3941 (define_insn "*dummy_extendsfdf2"
3942 [(set (match_operand:DF 0 "push_operand" "=<")
3943 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3948 [(set (match_operand:DF 0 "push_operand" "")
3949 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3951 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3952 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3955 [(set (match_operand:DF 0 "push_operand" "")
3956 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3958 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3959 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3961 (define_insn "*dummy_extendsfxf2"
3962 [(set (match_operand:XF 0 "push_operand" "=<")
3963 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3968 [(set (match_operand:XF 0 "push_operand" "")
3969 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3971 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3972 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3973 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3976 [(set (match_operand:XF 0 "push_operand" "")
3977 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3979 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3980 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3981 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3984 [(set (match_operand:XF 0 "push_operand" "")
3985 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3987 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3988 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3989 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3992 [(set (match_operand:XF 0 "push_operand" "")
3993 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3995 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3996 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3997 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3999 (define_expand "extendsfdf2"
4000 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4001 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4002 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4004 /* ??? Needed for compress_float_constant since all fp constants
4005 are LEGITIMATE_CONSTANT_P. */
4006 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4008 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4009 && standard_80387_constant_p (operands[1]) > 0)
4011 operands[1] = simplify_const_unary_operation
4012 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4013 emit_move_insn_1 (operands[0], operands[1]);
4016 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4020 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4022 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4024 We do the conversion post reload to avoid producing of 128bit spills
4025 that might lead to ICE on 32bit target. The sequence unlikely combine
4028 [(set (match_operand:DF 0 "register_operand" "")
4030 (match_operand:SF 1 "nonimmediate_operand" "")))]
4031 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4032 && reload_completed && SSE_REG_P (operands[0])"
4037 (parallel [(const_int 0) (const_int 1)]))))]
4039 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4040 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4041 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4042 Try to avoid move when unpacking can be done in source. */
4043 if (REG_P (operands[1]))
4045 /* If it is unsafe to overwrite upper half of source, we need
4046 to move to destination and unpack there. */
4047 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4048 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4049 && true_regnum (operands[0]) != true_regnum (operands[1]))
4051 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4052 emit_move_insn (tmp, operands[1]);
4055 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4056 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4059 emit_insn (gen_vec_setv4sf_0 (operands[3],
4060 CONST0_RTX (V4SFmode), operands[1]));
4063 (define_insn "*extendsfdf2_mixed"
4064 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4066 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4067 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4069 switch (which_alternative)
4073 return output_387_reg_move (insn, operands);
4076 return "cvtss2sd\t{%1, %0|%0, %1}";
4082 [(set_attr "type" "fmov,fmov,ssecvt")
4083 (set_attr "mode" "SF,XF,DF")])
4085 (define_insn "*extendsfdf2_sse"
4086 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4087 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4088 "TARGET_SSE2 && TARGET_SSE_MATH"
4089 "cvtss2sd\t{%1, %0|%0, %1}"
4090 [(set_attr "type" "ssecvt")
4091 (set_attr "mode" "DF")])
4093 (define_insn "*extendsfdf2_i387"
4094 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4095 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4097 "* return output_387_reg_move (insn, operands);"
4098 [(set_attr "type" "fmov")
4099 (set_attr "mode" "SF,XF")])
4101 (define_expand "extend<mode>xf2"
4102 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4103 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4106 /* ??? Needed for compress_float_constant since all fp constants
4107 are LEGITIMATE_CONSTANT_P. */
4108 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4110 if (standard_80387_constant_p (operands[1]) > 0)
4112 operands[1] = simplify_const_unary_operation
4113 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4114 emit_move_insn_1 (operands[0], operands[1]);
4117 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4121 (define_insn "*extend<mode>xf2_i387"
4122 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4124 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4126 "* return output_387_reg_move (insn, operands);"
4127 [(set_attr "type" "fmov")
4128 (set_attr "mode" "<MODE>,XF")])
4130 ;; %%% This seems bad bad news.
4131 ;; This cannot output into an f-reg because there is no way to be sure
4132 ;; of truncating in that case. Otherwise this is just like a simple move
4133 ;; insn. So we pretend we can output to a reg in order to get better
4134 ;; register preferencing, but we really use a stack slot.
4136 ;; Conversion from DFmode to SFmode.
4138 (define_expand "truncdfsf2"
4139 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4141 (match_operand:DF 1 "nonimmediate_operand" "")))]
4142 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4144 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4146 else if (flag_unsafe_math_optimizations)
4150 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4151 rtx temp = assign_386_stack_local (SFmode, slot);
4152 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4157 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4159 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4161 We do the conversion post reload to avoid producing of 128bit spills
4162 that might lead to ICE on 32bit target. The sequence unlikely combine
4165 [(set (match_operand:SF 0 "register_operand" "")
4167 (match_operand:DF 1 "nonimmediate_operand" "")))]
4168 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4169 && reload_completed && SSE_REG_P (operands[0])"
4172 (float_truncate:V2SF
4176 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4177 operands[3] = CONST0_RTX (V2SFmode);
4178 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4179 /* Use movsd for loading from memory, unpcklpd for registers.
4180 Try to avoid move when unpacking can be done in source, or SSE3
4181 movddup is available. */
4182 if (REG_P (operands[1]))
4185 && true_regnum (operands[0]) != true_regnum (operands[1])
4186 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4187 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4189 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4190 emit_move_insn (tmp, operands[1]);
4193 else if (!TARGET_SSE3)
4194 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4195 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4198 emit_insn (gen_sse2_loadlpd (operands[4],
4199 CONST0_RTX (V2DFmode), operands[1]));
4202 (define_expand "truncdfsf2_with_temp"
4203 [(parallel [(set (match_operand:SF 0 "" "")
4204 (float_truncate:SF (match_operand:DF 1 "" "")))
4205 (clobber (match_operand:SF 2 "" ""))])]
4208 (define_insn "*truncdfsf_fast_mixed"
4209 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4211 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4212 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4214 switch (which_alternative)
4217 return output_387_reg_move (insn, operands);
4219 return "cvtsd2ss\t{%1, %0|%0, %1}";
4224 [(set_attr "type" "fmov,ssecvt")
4225 (set_attr "mode" "SF")])
4227 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4228 ;; because nothing we do here is unsafe.
4229 (define_insn "*truncdfsf_fast_sse"
4230 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4232 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4233 "TARGET_SSE2 && TARGET_SSE_MATH"
4234 "cvtsd2ss\t{%1, %0|%0, %1}"
4235 [(set_attr "type" "ssecvt")
4236 (set_attr "mode" "SF")])
4238 (define_insn "*truncdfsf_fast_i387"
4239 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4241 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4242 "TARGET_80387 && flag_unsafe_math_optimizations"
4243 "* return output_387_reg_move (insn, operands);"
4244 [(set_attr "type" "fmov")
4245 (set_attr "mode" "SF")])
4247 (define_insn "*truncdfsf_mixed"
4248 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4250 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4251 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4252 "TARGET_MIX_SSE_I387"
4254 switch (which_alternative)
4257 return output_387_reg_move (insn, operands);
4262 return "cvtsd2ss\t{%1, %0|%0, %1}";
4267 [(set_attr "type" "fmov,multi,ssecvt")
4268 (set_attr "unit" "*,i387,*")
4269 (set_attr "mode" "SF")])
4271 (define_insn "*truncdfsf_i387"
4272 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4274 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4275 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4278 switch (which_alternative)
4281 return output_387_reg_move (insn, operands);
4289 [(set_attr "type" "fmov,multi")
4290 (set_attr "unit" "*,i387")
4291 (set_attr "mode" "SF")])
4293 (define_insn "*truncdfsf2_i387_1"
4294 [(set (match_operand:SF 0 "memory_operand" "=m")
4296 (match_operand:DF 1 "register_operand" "f")))]
4298 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299 && !TARGET_MIX_SSE_I387"
4300 "* return output_387_reg_move (insn, operands);"
4301 [(set_attr "type" "fmov")
4302 (set_attr "mode" "SF")])
4305 [(set (match_operand:SF 0 "register_operand" "")
4307 (match_operand:DF 1 "fp_register_operand" "")))
4308 (clobber (match_operand 2 "" ""))]
4310 [(set (match_dup 2) (match_dup 1))
4311 (set (match_dup 0) (match_dup 2))]
4313 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4316 ;; Conversion from XFmode to {SF,DF}mode
4318 (define_expand "truncxf<mode>2"
4319 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4320 (float_truncate:MODEF
4321 (match_operand:XF 1 "register_operand" "")))
4322 (clobber (match_dup 2))])]
4325 if (flag_unsafe_math_optimizations)
4327 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4328 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4329 if (reg != operands[0])
4330 emit_move_insn (operands[0], reg);
4335 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4336 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4340 (define_insn "*truncxfsf2_mixed"
4341 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4343 (match_operand:XF 1 "register_operand" "f,f")))
4344 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4347 gcc_assert (!which_alternative);
4348 return output_387_reg_move (insn, operands);
4350 [(set_attr "type" "fmov,multi")
4351 (set_attr "unit" "*,i387")
4352 (set_attr "mode" "SF")])
4354 (define_insn "*truncxfdf2_mixed"
4355 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4357 (match_operand:XF 1 "register_operand" "f,f")))
4358 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4361 gcc_assert (!which_alternative);
4362 return output_387_reg_move (insn, operands);
4364 [(set_attr "type" "fmov,multi")
4365 (set_attr "unit" "*,i387")
4366 (set_attr "mode" "DF")])
4368 (define_insn "truncxf<mode>2_i387_noop"
4369 [(set (match_operand:MODEF 0 "register_operand" "=f")
4370 (float_truncate:MODEF
4371 (match_operand:XF 1 "register_operand" "f")))]
4372 "TARGET_80387 && flag_unsafe_math_optimizations"
4373 "* return output_387_reg_move (insn, operands);"
4374 [(set_attr "type" "fmov")
4375 (set_attr "mode" "<MODE>")])
4377 (define_insn "*truncxf<mode>2_i387"
4378 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4379 (float_truncate:MODEF
4380 (match_operand:XF 1 "register_operand" "f")))]
4382 "* return output_387_reg_move (insn, operands);"
4383 [(set_attr "type" "fmov")
4384 (set_attr "mode" "<MODE>")])
4387 [(set (match_operand:MODEF 0 "register_operand" "")
4388 (float_truncate:MODEF
4389 (match_operand:XF 1 "register_operand" "")))
4390 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4391 "TARGET_80387 && reload_completed"
4392 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4393 (set (match_dup 0) (match_dup 2))]
4397 [(set (match_operand:MODEF 0 "memory_operand" "")
4398 (float_truncate:MODEF
4399 (match_operand:XF 1 "register_operand" "")))
4400 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4402 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4405 ;; Signed conversion to DImode.
4407 (define_expand "fix_truncxfdi2"
4408 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4409 (fix:DI (match_operand:XF 1 "register_operand" "")))
4410 (clobber (reg:CC FLAGS_REG))])]
4415 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4420 (define_expand "fix_trunc<mode>di2"
4421 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4422 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4423 (clobber (reg:CC FLAGS_REG))])]
4424 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4427 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4429 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4432 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4434 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4435 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4436 if (out != operands[0])
4437 emit_move_insn (operands[0], out);
4442 ;; Signed conversion to SImode.
4444 (define_expand "fix_truncxfsi2"
4445 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4446 (fix:SI (match_operand:XF 1 "register_operand" "")))
4447 (clobber (reg:CC FLAGS_REG))])]
4452 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4457 (define_expand "fix_trunc<mode>si2"
4458 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4459 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4460 (clobber (reg:CC FLAGS_REG))])]
4461 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4464 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4466 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4469 if (SSE_FLOAT_MODE_P (<MODE>mode))
4471 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4472 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4473 if (out != operands[0])
4474 emit_move_insn (operands[0], out);
4479 ;; Signed conversion to HImode.
4481 (define_expand "fix_trunc<mode>hi2"
4482 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4483 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4484 (clobber (reg:CC FLAGS_REG))])]
4486 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4490 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4495 ;; Unsigned conversion to SImode.
4497 (define_expand "fixuns_trunc<mode>si2"
4499 [(set (match_operand:SI 0 "register_operand" "")
4501 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4503 (clobber (match_scratch:<ssevecmode> 3 ""))
4504 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4505 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4507 enum machine_mode mode = <MODE>mode;
4508 enum machine_mode vecmode = <ssevecmode>mode;
4509 REAL_VALUE_TYPE TWO31r;
4512 real_ldexp (&TWO31r, &dconst1, 31);
4513 two31 = const_double_from_real_value (TWO31r, mode);
4514 two31 = ix86_build_const_vector (mode, true, two31);
4515 operands[2] = force_reg (vecmode, two31);
4518 (define_insn_and_split "*fixuns_trunc<mode>_1"
4519 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4521 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4522 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4523 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4524 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4525 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4527 "&& reload_completed"
4530 ix86_split_convert_uns_si_sse (operands);
4534 ;; Unsigned conversion to HImode.
4535 ;; Without these patterns, we'll try the unsigned SI conversion which
4536 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4538 (define_expand "fixuns_trunc<mode>hi2"
4540 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4541 (set (match_operand:HI 0 "nonimmediate_operand" "")
4542 (subreg:HI (match_dup 2) 0))]
4543 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4544 "operands[2] = gen_reg_rtx (SImode);")
4546 ;; When SSE is available, it is always faster to use it!
4547 (define_insn "fix_trunc<mode>di_sse"
4548 [(set (match_operand:DI 0 "register_operand" "=r,r")
4549 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4550 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4551 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4552 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4553 [(set_attr "type" "sseicvt")
4554 (set_attr "mode" "<MODE>")
4555 (set_attr "athlon_decode" "double,vector")
4556 (set_attr "amdfam10_decode" "double,double")])
4558 (define_insn "fix_trunc<mode>si_sse"
4559 [(set (match_operand:SI 0 "register_operand" "=r,r")
4560 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4561 "SSE_FLOAT_MODE_P (<MODE>mode)
4562 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4563 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4564 [(set_attr "type" "sseicvt")
4565 (set_attr "mode" "<MODE>")
4566 (set_attr "athlon_decode" "double,vector")
4567 (set_attr "amdfam10_decode" "double,double")])
4569 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4571 [(set (match_operand:MODEF 0 "register_operand" "")
4572 (match_operand:MODEF 1 "memory_operand" ""))
4573 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4574 (fix:SSEMODEI24 (match_dup 0)))]
4575 "TARGET_SHORTEN_X87_SSE
4576 && peep2_reg_dead_p (2, operands[0])"
4577 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4580 ;; Avoid vector decoded forms of the instruction.
4582 [(match_scratch:DF 2 "Y2")
4583 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4584 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4585 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4586 [(set (match_dup 2) (match_dup 1))
4587 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4591 [(match_scratch:SF 2 "x")
4592 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4593 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4594 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4595 [(set (match_dup 2) (match_dup 1))
4596 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4599 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4600 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4601 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4602 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4604 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4605 && (TARGET_64BIT || <MODE>mode != DImode))
4607 && !(reload_completed || reload_in_progress)"
4612 if (memory_operand (operands[0], VOIDmode))
4613 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4616 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4617 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4623 [(set_attr "type" "fisttp")
4624 (set_attr "mode" "<MODE>")])
4626 (define_insn "fix_trunc<mode>_i387_fisttp"
4627 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4628 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4629 (clobber (match_scratch:XF 2 "=&1f"))]
4630 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4632 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4633 && (TARGET_64BIT || <MODE>mode != DImode))
4634 && TARGET_SSE_MATH)"
4635 "* return output_fix_trunc (insn, operands, 1);"
4636 [(set_attr "type" "fisttp")
4637 (set_attr "mode" "<MODE>")])
4639 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4640 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4641 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4642 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4643 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4644 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4646 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4647 && (TARGET_64BIT || <MODE>mode != DImode))
4648 && TARGET_SSE_MATH)"
4650 [(set_attr "type" "fisttp")
4651 (set_attr "mode" "<MODE>")])
4654 [(set (match_operand:X87MODEI 0 "register_operand" "")
4655 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4656 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4657 (clobber (match_scratch 3 ""))]
4659 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4660 (clobber (match_dup 3))])
4661 (set (match_dup 0) (match_dup 2))]
4665 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4666 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4667 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4668 (clobber (match_scratch 3 ""))]
4670 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4671 (clobber (match_dup 3))])]
4674 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4675 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4676 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4677 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4678 ;; function in i386.c.
4679 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4680 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4681 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4682 (clobber (reg:CC FLAGS_REG))]
4683 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4685 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4686 && (TARGET_64BIT || <MODE>mode != DImode))
4687 && !(reload_completed || reload_in_progress)"
4692 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4694 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4695 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4696 if (memory_operand (operands[0], VOIDmode))
4697 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4698 operands[2], operands[3]));
4701 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4702 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4703 operands[2], operands[3],
4708 [(set_attr "type" "fistp")
4709 (set_attr "i387_cw" "trunc")
4710 (set_attr "mode" "<MODE>")])
4712 (define_insn "fix_truncdi_i387"
4713 [(set (match_operand:DI 0 "memory_operand" "=m")
4714 (fix:DI (match_operand 1 "register_operand" "f")))
4715 (use (match_operand:HI 2 "memory_operand" "m"))
4716 (use (match_operand:HI 3 "memory_operand" "m"))
4717 (clobber (match_scratch:XF 4 "=&1f"))]
4718 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4720 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4721 "* return output_fix_trunc (insn, operands, 0);"
4722 [(set_attr "type" "fistp")
4723 (set_attr "i387_cw" "trunc")
4724 (set_attr "mode" "DI")])
4726 (define_insn "fix_truncdi_i387_with_temp"
4727 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4728 (fix:DI (match_operand 1 "register_operand" "f,f")))
4729 (use (match_operand:HI 2 "memory_operand" "m,m"))
4730 (use (match_operand:HI 3 "memory_operand" "m,m"))
4731 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4732 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4733 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4735 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4737 [(set_attr "type" "fistp")
4738 (set_attr "i387_cw" "trunc")
4739 (set_attr "mode" "DI")])
4742 [(set (match_operand:DI 0 "register_operand" "")
4743 (fix:DI (match_operand 1 "register_operand" "")))
4744 (use (match_operand:HI 2 "memory_operand" ""))
4745 (use (match_operand:HI 3 "memory_operand" ""))
4746 (clobber (match_operand:DI 4 "memory_operand" ""))
4747 (clobber (match_scratch 5 ""))]
4749 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4752 (clobber (match_dup 5))])
4753 (set (match_dup 0) (match_dup 4))]
4757 [(set (match_operand:DI 0 "memory_operand" "")
4758 (fix:DI (match_operand 1 "register_operand" "")))
4759 (use (match_operand:HI 2 "memory_operand" ""))
4760 (use (match_operand:HI 3 "memory_operand" ""))
4761 (clobber (match_operand:DI 4 "memory_operand" ""))
4762 (clobber (match_scratch 5 ""))]
4764 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4767 (clobber (match_dup 5))])]
4770 (define_insn "fix_trunc<mode>_i387"
4771 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4772 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4773 (use (match_operand:HI 2 "memory_operand" "m"))
4774 (use (match_operand:HI 3 "memory_operand" "m"))]
4775 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4777 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4778 "* return output_fix_trunc (insn, operands, 0);"
4779 [(set_attr "type" "fistp")
4780 (set_attr "i387_cw" "trunc")
4781 (set_attr "mode" "<MODE>")])
4783 (define_insn "fix_trunc<mode>_i387_with_temp"
4784 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4785 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4786 (use (match_operand:HI 2 "memory_operand" "m,m"))
4787 (use (match_operand:HI 3 "memory_operand" "m,m"))
4788 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4789 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4791 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4793 [(set_attr "type" "fistp")
4794 (set_attr "i387_cw" "trunc")
4795 (set_attr "mode" "<MODE>")])
4798 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4799 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4800 (use (match_operand:HI 2 "memory_operand" ""))
4801 (use (match_operand:HI 3 "memory_operand" ""))
4802 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4804 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4806 (use (match_dup 3))])
4807 (set (match_dup 0) (match_dup 4))]
4811 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4812 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4813 (use (match_operand:HI 2 "memory_operand" ""))
4814 (use (match_operand:HI 3 "memory_operand" ""))
4815 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4817 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4819 (use (match_dup 3))])]
4822 (define_insn "x86_fnstcw_1"
4823 [(set (match_operand:HI 0 "memory_operand" "=m")
4824 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4827 [(set_attr "length" "2")
4828 (set_attr "mode" "HI")
4829 (set_attr "unit" "i387")])
4831 (define_insn "x86_fldcw_1"
4832 [(set (reg:HI FPCR_REG)
4833 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4836 [(set_attr "length" "2")
4837 (set_attr "mode" "HI")
4838 (set_attr "unit" "i387")
4839 (set_attr "athlon_decode" "vector")
4840 (set_attr "amdfam10_decode" "vector")])
4842 ;; Conversion between fixed point and floating point.
4844 ;; Even though we only accept memory inputs, the backend _really_
4845 ;; wants to be able to do this between registers.
4847 (define_expand "floathi<mode>2"
4848 [(set (match_operand:X87MODEF 0 "register_operand" "")
4849 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4852 || TARGET_MIX_SSE_I387)"
4855 ;; Pre-reload splitter to add memory clobber to the pattern.
4856 (define_insn_and_split "*floathi<mode>2_1"
4857 [(set (match_operand:X87MODEF 0 "register_operand" "")
4858 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4860 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4861 || TARGET_MIX_SSE_I387)
4862 && !(reload_completed || reload_in_progress)"
4865 [(parallel [(set (match_dup 0)
4866 (float:X87MODEF (match_dup 1)))
4867 (clobber (match_dup 2))])]
4868 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4870 (define_insn "*floathi<mode>2_i387_with_temp"
4871 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4872 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4873 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4875 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4876 || TARGET_MIX_SSE_I387)"
4878 [(set_attr "type" "fmov,multi")
4879 (set_attr "mode" "<MODE>")
4880 (set_attr "unit" "*,i387")
4881 (set_attr "fp_int_src" "true")])
4883 (define_insn "*floathi<mode>2_i387"
4884 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4885 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4887 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4888 || TARGET_MIX_SSE_I387)"
4890 [(set_attr "type" "fmov")
4891 (set_attr "mode" "<MODE>")
4892 (set_attr "fp_int_src" "true")])
4895 [(set (match_operand:X87MODEF 0 "register_operand" "")
4896 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4897 (clobber (match_operand:HI 2 "memory_operand" ""))]
4899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4900 || TARGET_MIX_SSE_I387)
4901 && reload_completed"
4902 [(set (match_dup 2) (match_dup 1))
4903 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4907 [(set (match_operand:X87MODEF 0 "register_operand" "")
4908 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4909 (clobber (match_operand:HI 2 "memory_operand" ""))]
4911 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4912 || TARGET_MIX_SSE_I387)
4913 && reload_completed"
4914 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4917 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4918 [(set (match_operand:X87MODEF 0 "register_operand" "")
4920 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4922 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4923 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4926 ;; Pre-reload splitter to add memory clobber to the pattern.
4927 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4928 [(set (match_operand:X87MODEF 0 "register_operand" "")
4929 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4931 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4932 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4933 || TARGET_MIX_SSE_I387))
4934 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4935 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4936 && ((<SSEMODEI24:MODE>mode == SImode
4937 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4938 && flag_trapping_math)
4939 || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4940 && !(reload_completed || reload_in_progress)"
4943 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4944 (clobber (match_dup 2))])]
4946 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4948 /* Avoid store forwarding (partial memory) stall penalty
4949 by passing DImode value through XMM registers. */
4950 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4951 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4954 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4961 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4962 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4964 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4965 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4966 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4967 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4969 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4970 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4971 (set_attr "unit" "*,i387,*,*,*")
4972 (set_attr "athlon_decode" "*,*,double,direct,double")
4973 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4974 (set_attr "fp_int_src" "true")])
4976 (define_insn "*floatsi<mode>2_vector_mixed"
4977 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4978 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4979 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4980 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4984 [(set_attr "type" "fmov,sseicvt")
4985 (set_attr "mode" "<MODE>,<ssevecmode>")
4986 (set_attr "unit" "i387,*")
4987 (set_attr "athlon_decode" "*,direct")
4988 (set_attr "amdfam10_decode" "*,double")
4989 (set_attr "fp_int_src" "true")])
4991 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4992 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4994 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4995 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4996 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4997 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4999 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5000 (set_attr "mode" "<MODEF:MODE>")
5001 (set_attr "unit" "*,i387,*,*")
5002 (set_attr "athlon_decode" "*,*,double,direct")
5003 (set_attr "amdfam10_decode" "*,*,vector,double")
5004 (set_attr "fp_int_src" "true")])
5007 [(set (match_operand:MODEF 0 "register_operand" "")
5008 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5009 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5010 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5011 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5012 && TARGET_INTER_UNIT_CONVERSIONS
5014 && (SSE_REG_P (operands[0])
5015 || (GET_CODE (operands[0]) == SUBREG
5016 && SSE_REG_P (operands[0])))"
5017 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5021 [(set (match_operand:MODEF 0 "register_operand" "")
5022 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5023 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5024 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5025 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5026 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5028 && (SSE_REG_P (operands[0])
5029 || (GET_CODE (operands[0]) == SUBREG
5030 && SSE_REG_P (operands[0])))"
5031 [(set (match_dup 2) (match_dup 1))
5032 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5035 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5036 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5038 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5039 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5040 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5041 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5044 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5045 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5046 [(set_attr "type" "fmov,sseicvt,sseicvt")
5047 (set_attr "mode" "<MODEF:MODE>")
5048 (set_attr "unit" "i387,*,*")
5049 (set_attr "athlon_decode" "*,double,direct")
5050 (set_attr "amdfam10_decode" "*,vector,double")
5051 (set_attr "fp_int_src" "true")])
5053 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5054 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5056 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5057 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5058 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5059 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5062 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5063 [(set_attr "type" "fmov,sseicvt")
5064 (set_attr "mode" "<MODEF:MODE>")
5065 (set_attr "athlon_decode" "*,direct")
5066 (set_attr "amdfam10_decode" "*,double")
5067 (set_attr "fp_int_src" "true")])
5069 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5070 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5072 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5073 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5074 "TARGET_SSE2 && TARGET_SSE_MATH
5075 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5077 [(set_attr "type" "sseicvt")
5078 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5079 (set_attr "athlon_decode" "double,direct,double")
5080 (set_attr "amdfam10_decode" "vector,double,double")
5081 (set_attr "fp_int_src" "true")])
5083 (define_insn "*floatsi<mode>2_vector_sse"
5084 [(set (match_operand:MODEF 0 "register_operand" "=x")
5085 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5086 "TARGET_SSE2 && TARGET_SSE_MATH
5087 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5089 [(set_attr "type" "sseicvt")
5090 (set_attr "mode" "<MODE>")
5091 (set_attr "athlon_decode" "direct")
5092 (set_attr "amdfam10_decode" "double")
5093 (set_attr "fp_int_src" "true")])
5096 [(set (match_operand:MODEF 0 "register_operand" "")
5097 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5098 (clobber (match_operand:SI 2 "memory_operand" ""))]
5099 "TARGET_SSE2 && TARGET_SSE_MATH
5100 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5102 && (SSE_REG_P (operands[0])
5103 || (GET_CODE (operands[0]) == SUBREG
5104 && SSE_REG_P (operands[0])))"
5107 rtx op1 = operands[1];
5109 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5111 if (GET_CODE (op1) == SUBREG)
5112 op1 = SUBREG_REG (op1);
5114 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5116 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5117 emit_insn (gen_sse2_loadld (operands[4],
5118 CONST0_RTX (V4SImode), operands[1]));
5120 /* We can ignore possible trapping value in the
5121 high part of SSE register for non-trapping math. */
5122 else if (SSE_REG_P (op1) && !flag_trapping_math)
5123 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5126 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5127 emit_move_insn (operands[2], operands[1]);
5128 emit_insn (gen_sse2_loadld (operands[4],
5129 CONST0_RTX (V4SImode), operands[2]));
5132 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5137 [(set (match_operand:MODEF 0 "register_operand" "")
5138 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5139 (clobber (match_operand:SI 2 "memory_operand" ""))]
5140 "TARGET_SSE2 && TARGET_SSE_MATH
5141 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5143 && (SSE_REG_P (operands[0])
5144 || (GET_CODE (operands[0]) == SUBREG
5145 && SSE_REG_P (operands[0])))"
5148 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5150 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5152 emit_insn (gen_sse2_loadld (operands[4],
5153 CONST0_RTX (V4SImode), operands[1]));
5155 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5160 [(set (match_operand:MODEF 0 "register_operand" "")
5161 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5162 "TARGET_SSE2 && TARGET_SSE_MATH
5163 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5165 && (SSE_REG_P (operands[0])
5166 || (GET_CODE (operands[0]) == SUBREG
5167 && SSE_REG_P (operands[0])))"
5170 rtx op1 = operands[1];
5172 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5174 if (GET_CODE (op1) == SUBREG)
5175 op1 = SUBREG_REG (op1);
5177 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5179 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5180 emit_insn (gen_sse2_loadld (operands[4],
5181 CONST0_RTX (V4SImode), operands[1]));
5183 /* We can ignore possible trapping value in the
5184 high part of SSE register for non-trapping math. */
5185 else if (SSE_REG_P (op1) && !flag_trapping_math)
5186 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5192 [(set (match_operand:MODEF 0 "register_operand" "")
5193 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5194 "TARGET_SSE2 && TARGET_SSE_MATH
5195 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5197 && (SSE_REG_P (operands[0])
5198 || (GET_CODE (operands[0]) == SUBREG
5199 && SSE_REG_P (operands[0])))"
5202 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5204 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5206 emit_insn (gen_sse2_loadld (operands[4],
5207 CONST0_RTX (V4SImode), operands[1]));
5209 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5213 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5214 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5216 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5217 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5218 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5219 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5221 [(set_attr "type" "sseicvt")
5222 (set_attr "mode" "<MODEF:MODE>")
5223 (set_attr "athlon_decode" "double,direct")
5224 (set_attr "amdfam10_decode" "vector,double")
5225 (set_attr "fp_int_src" "true")])
5227 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5228 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5230 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5231 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5232 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5233 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5235 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5236 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5237 [(set_attr "type" "sseicvt")
5238 (set_attr "mode" "<MODEF:MODE>")
5239 (set_attr "athlon_decode" "double,direct")
5240 (set_attr "amdfam10_decode" "vector,double")
5241 (set_attr "fp_int_src" "true")])
5244 [(set (match_operand:MODEF 0 "register_operand" "")
5245 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5246 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5247 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5248 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5249 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5251 && (SSE_REG_P (operands[0])
5252 || (GET_CODE (operands[0]) == SUBREG
5253 && SSE_REG_P (operands[0])))"
5254 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5257 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5258 [(set (match_operand:MODEF 0 "register_operand" "=x")
5260 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5261 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5262 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5263 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5264 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5265 [(set_attr "type" "sseicvt")
5266 (set_attr "mode" "<MODEF:MODE>")
5267 (set_attr "athlon_decode" "direct")
5268 (set_attr "amdfam10_decode" "double")
5269 (set_attr "fp_int_src" "true")])
5272 [(set (match_operand:MODEF 0 "register_operand" "")
5273 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5274 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5275 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5276 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5277 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5279 && (SSE_REG_P (operands[0])
5280 || (GET_CODE (operands[0]) == SUBREG
5281 && SSE_REG_P (operands[0])))"
5282 [(set (match_dup 2) (match_dup 1))
5283 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5287 [(set (match_operand:MODEF 0 "register_operand" "")
5288 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5289 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5290 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5291 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5293 && (SSE_REG_P (operands[0])
5294 || (GET_CODE (operands[0]) == SUBREG
5295 && SSE_REG_P (operands[0])))"
5296 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5299 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5300 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5302 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5303 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5308 [(set_attr "type" "fmov,multi")
5309 (set_attr "mode" "<X87MODEF:MODE>")
5310 (set_attr "unit" "*,i387")
5311 (set_attr "fp_int_src" "true")])
5313 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5314 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5316 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5319 [(set_attr "type" "fmov")
5320 (set_attr "mode" "<X87MODEF:MODE>")
5321 (set_attr "fp_int_src" "true")])
5324 [(set (match_operand:X87MODEF 0 "register_operand" "")
5325 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5326 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5329 && FP_REG_P (operands[0])"
5330 [(set (match_dup 2) (match_dup 1))
5331 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5335 [(set (match_operand:X87MODEF 0 "register_operand" "")
5336 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5337 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5340 && FP_REG_P (operands[0])"
5341 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5344 ;; Avoid store forwarding (partial memory) stall penalty
5345 ;; by passing DImode value through XMM registers. */
5347 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5348 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5350 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5351 (clobber (match_scratch:V4SI 3 "=X,x"))
5352 (clobber (match_scratch:V4SI 4 "=X,x"))
5353 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5354 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5355 && !TARGET_64BIT && !optimize_size"
5357 [(set_attr "type" "multi")
5358 (set_attr "mode" "<X87MODEF:MODE>")
5359 (set_attr "unit" "i387")
5360 (set_attr "fp_int_src" "true")])
5363 [(set (match_operand:X87MODEF 0 "register_operand" "")
5364 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5365 (clobber (match_scratch:V4SI 3 ""))
5366 (clobber (match_scratch:V4SI 4 ""))
5367 (clobber (match_operand:DI 2 "memory_operand" ""))]
5368 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5369 && !TARGET_64BIT && !optimize_size
5371 && FP_REG_P (operands[0])"
5372 [(set (match_dup 2) (match_dup 3))
5373 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5375 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5376 Assemble the 64-bit DImode value in an xmm register. */
5377 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5378 gen_rtx_SUBREG (SImode, operands[1], 0)));
5379 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5380 gen_rtx_SUBREG (SImode, operands[1], 4)));
5381 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5383 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5387 [(set (match_operand:X87MODEF 0 "register_operand" "")
5388 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5389 (clobber (match_scratch:V4SI 3 ""))
5390 (clobber (match_scratch:V4SI 4 ""))
5391 (clobber (match_operand:DI 2 "memory_operand" ""))]
5392 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5393 && !TARGET_64BIT && !optimize_size
5395 && FP_REG_P (operands[0])"
5396 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5399 ;; Avoid store forwarding (partial memory) stall penalty by extending
5400 ;; SImode value to DImode through XMM register instead of pushing two
5401 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5402 ;; targets benefit from this optimization. Also note that fild
5403 ;; loads from memory only.
5405 (define_insn "*floatunssi<mode>2_1"
5406 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5407 (unsigned_float:X87MODEF
5408 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5409 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5410 (clobber (match_scratch:SI 3 "=X,x"))]
5412 && TARGET_80387 && TARGET_SSE"
5414 [(set_attr "type" "multi")
5415 (set_attr "mode" "<MODE>")])
5418 [(set (match_operand:X87MODEF 0 "register_operand" "")
5419 (unsigned_float:X87MODEF
5420 (match_operand:SI 1 "register_operand" "")))
5421 (clobber (match_operand:DI 2 "memory_operand" ""))
5422 (clobber (match_scratch:SI 3 ""))]
5424 && TARGET_80387 && TARGET_SSE
5425 && reload_completed"
5426 [(set (match_dup 2) (match_dup 1))
5428 (float:X87MODEF (match_dup 2)))]
5429 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5432 [(set (match_operand:X87MODEF 0 "register_operand" "")
5433 (unsigned_float:X87MODEF
5434 (match_operand:SI 1 "memory_operand" "")))
5435 (clobber (match_operand:DI 2 "memory_operand" ""))
5436 (clobber (match_scratch:SI 3 ""))]
5438 && TARGET_80387 && TARGET_SSE
5439 && reload_completed"
5440 [(set (match_dup 2) (match_dup 3))
5442 (float:X87MODEF (match_dup 2)))]
5444 emit_move_insn (operands[3], operands[1]);
5445 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5448 (define_expand "floatunssi<mode>2"
5450 [(set (match_operand:X87MODEF 0 "register_operand" "")
5451 (unsigned_float:X87MODEF
5452 (match_operand:SI 1 "nonimmediate_operand" "")))
5453 (clobber (match_dup 2))
5454 (clobber (match_scratch:SI 3 ""))])]
5456 && ((TARGET_80387 && TARGET_SSE)
5457 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5459 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5461 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5466 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5467 operands[2] = assign_386_stack_local (DImode, slot);
5471 (define_expand "floatunsdisf2"
5472 [(use (match_operand:SF 0 "register_operand" ""))
5473 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5474 "TARGET_64BIT && TARGET_SSE_MATH"
5475 "x86_emit_floatuns (operands); DONE;")
5477 (define_expand "floatunsdidf2"
5478 [(use (match_operand:DF 0 "register_operand" ""))
5479 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5480 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5481 && TARGET_SSE2 && TARGET_SSE_MATH"
5484 x86_emit_floatuns (operands);
5486 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5492 ;; %%% splits for addditi3
5494 (define_expand "addti3"
5495 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5496 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5497 (match_operand:TI 2 "x86_64_general_operand" "")))
5498 (clobber (reg:CC FLAGS_REG))]
5500 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5502 (define_insn "*addti3_1"
5503 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5504 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5505 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5506 (clobber (reg:CC FLAGS_REG))]
5507 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5511 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5512 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5513 (match_operand:TI 2 "x86_64_general_operand" "")))
5514 (clobber (reg:CC FLAGS_REG))]
5515 "TARGET_64BIT && reload_completed"
5516 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5518 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5519 (parallel [(set (match_dup 3)
5520 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5523 (clobber (reg:CC FLAGS_REG))])]
5524 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5526 ;; %%% splits for addsidi3
5527 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5528 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5529 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5531 (define_expand "adddi3"
5532 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5533 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5534 (match_operand:DI 2 "x86_64_general_operand" "")))
5535 (clobber (reg:CC FLAGS_REG))]
5537 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5539 (define_insn "*adddi3_1"
5540 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5541 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5542 (match_operand:DI 2 "general_operand" "roiF,riF")))
5543 (clobber (reg:CC FLAGS_REG))]
5544 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5548 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5549 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5550 (match_operand:DI 2 "general_operand" "")))
5551 (clobber (reg:CC FLAGS_REG))]
5552 "!TARGET_64BIT && reload_completed"
5553 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5555 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5556 (parallel [(set (match_dup 3)
5557 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5560 (clobber (reg:CC FLAGS_REG))])]
5561 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5563 (define_insn "adddi3_carry_rex64"
5564 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5565 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5566 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5567 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5568 (clobber (reg:CC FLAGS_REG))]
5569 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5570 "adc{q}\t{%2, %0|%0, %2}"
5571 [(set_attr "type" "alu")
5572 (set_attr "pent_pair" "pu")
5573 (set_attr "mode" "DI")])
5575 (define_insn "*adddi3_cc_rex64"
5576 [(set (reg:CC FLAGS_REG)
5577 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5578 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5580 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5581 (plus:DI (match_dup 1) (match_dup 2)))]
5582 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5583 "add{q}\t{%2, %0|%0, %2}"
5584 [(set_attr "type" "alu")
5585 (set_attr "mode" "DI")])
5587 (define_insn "*<addsub><mode>3_cc_overflow"
5588 [(set (reg:CCC FLAGS_REG)
5591 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5592 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5594 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5595 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5596 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5597 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5598 [(set_attr "type" "alu")
5599 (set_attr "mode" "<MODE>")])
5601 (define_insn "*add<mode>3_cconly_overflow"
5602 [(set (reg:CCC FLAGS_REG)
5604 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5605 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5607 (clobber (match_scratch:SWI 0 "=<r>"))]
5608 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5609 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5610 [(set_attr "type" "alu")
5611 (set_attr "mode" "<MODE>")])
5613 (define_insn "*sub<mode>3_cconly_overflow"
5614 [(set (reg:CCC FLAGS_REG)
5616 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5617 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5620 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5621 [(set_attr "type" "icmp")
5622 (set_attr "mode" "<MODE>")])
5624 (define_insn "*<addsub>si3_zext_cc_overflow"
5625 [(set (reg:CCC FLAGS_REG)
5627 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5628 (match_operand:SI 2 "general_operand" "g"))
5630 (set (match_operand:DI 0 "register_operand" "=r")
5631 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5632 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5633 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5634 [(set_attr "type" "alu")
5635 (set_attr "mode" "SI")])
5637 (define_insn "addqi3_carry"
5638 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5639 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5640 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5641 (match_operand:QI 2 "general_operand" "qi,qm")))
5642 (clobber (reg:CC FLAGS_REG))]
5643 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5644 "adc{b}\t{%2, %0|%0, %2}"
5645 [(set_attr "type" "alu")
5646 (set_attr "pent_pair" "pu")
5647 (set_attr "mode" "QI")])
5649 (define_insn "addhi3_carry"
5650 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5651 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5652 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5653 (match_operand:HI 2 "general_operand" "ri,rm")))
5654 (clobber (reg:CC FLAGS_REG))]
5655 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5656 "adc{w}\t{%2, %0|%0, %2}"
5657 [(set_attr "type" "alu")
5658 (set_attr "pent_pair" "pu")
5659 (set_attr "mode" "HI")])
5661 (define_insn "addsi3_carry"
5662 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5663 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5664 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5665 (match_operand:SI 2 "general_operand" "ri,rm")))
5666 (clobber (reg:CC FLAGS_REG))]
5667 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5668 "adc{l}\t{%2, %0|%0, %2}"
5669 [(set_attr "type" "alu")
5670 (set_attr "pent_pair" "pu")
5671 (set_attr "mode" "SI")])
5673 (define_insn "*addsi3_carry_zext"
5674 [(set (match_operand:DI 0 "register_operand" "=r")
5676 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5677 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5678 (match_operand:SI 2 "general_operand" "g"))))
5679 (clobber (reg:CC FLAGS_REG))]
5680 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5681 "adc{l}\t{%2, %k0|%k0, %2}"
5682 [(set_attr "type" "alu")
5683 (set_attr "pent_pair" "pu")
5684 (set_attr "mode" "SI")])
5686 (define_insn "*addsi3_cc"
5687 [(set (reg:CC FLAGS_REG)
5688 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5689 (match_operand:SI 2 "general_operand" "ri,rm")]
5691 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5692 (plus:SI (match_dup 1) (match_dup 2)))]
5693 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5694 "add{l}\t{%2, %0|%0, %2}"
5695 [(set_attr "type" "alu")
5696 (set_attr "mode" "SI")])
5698 (define_insn "addqi3_cc"
5699 [(set (reg:CC FLAGS_REG)
5700 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5701 (match_operand:QI 2 "general_operand" "qi,qm")]
5703 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5704 (plus:QI (match_dup 1) (match_dup 2)))]
5705 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5706 "add{b}\t{%2, %0|%0, %2}"
5707 [(set_attr "type" "alu")
5708 (set_attr "mode" "QI")])
5710 (define_expand "addsi3"
5711 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5712 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5713 (match_operand:SI 2 "general_operand" "")))
5714 (clobber (reg:CC FLAGS_REG))])]
5716 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5718 (define_insn "*lea_1"
5719 [(set (match_operand:SI 0 "register_operand" "=r")
5720 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5722 "lea{l}\t{%a1, %0|%0, %a1}"
5723 [(set_attr "type" "lea")
5724 (set_attr "mode" "SI")])
5726 (define_insn "*lea_1_rex64"
5727 [(set (match_operand:SI 0 "register_operand" "=r")
5728 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5730 "lea{l}\t{%a1, %0|%0, %a1}"
5731 [(set_attr "type" "lea")
5732 (set_attr "mode" "SI")])
5734 (define_insn "*lea_1_zext"
5735 [(set (match_operand:DI 0 "register_operand" "=r")
5737 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5739 "lea{l}\t{%a1, %k0|%k0, %a1}"
5740 [(set_attr "type" "lea")
5741 (set_attr "mode" "SI")])
5743 (define_insn "*lea_2_rex64"
5744 [(set (match_operand:DI 0 "register_operand" "=r")
5745 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5747 "lea{q}\t{%a1, %0|%0, %a1}"
5748 [(set_attr "type" "lea")
5749 (set_attr "mode" "DI")])
5751 ;; The lea patterns for non-Pmodes needs to be matched by several
5752 ;; insns converted to real lea by splitters.
5754 (define_insn_and_split "*lea_general_1"
5755 [(set (match_operand 0 "register_operand" "=r")
5756 (plus (plus (match_operand 1 "index_register_operand" "l")
5757 (match_operand 2 "register_operand" "r"))
5758 (match_operand 3 "immediate_operand" "i")))]
5759 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5760 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5761 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5762 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5763 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5764 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5765 || GET_MODE (operands[3]) == VOIDmode)"
5767 "&& reload_completed"
5771 operands[0] = gen_lowpart (SImode, operands[0]);
5772 operands[1] = gen_lowpart (Pmode, operands[1]);
5773 operands[2] = gen_lowpart (Pmode, operands[2]);
5774 operands[3] = gen_lowpart (Pmode, operands[3]);
5775 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5777 if (Pmode != SImode)
5778 pat = gen_rtx_SUBREG (SImode, pat, 0);
5779 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5782 [(set_attr "type" "lea")
5783 (set_attr "mode" "SI")])
5785 (define_insn_and_split "*lea_general_1_zext"
5786 [(set (match_operand:DI 0 "register_operand" "=r")
5788 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5789 (match_operand:SI 2 "register_operand" "r"))
5790 (match_operand:SI 3 "immediate_operand" "i"))))]
5793 "&& reload_completed"
5795 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5797 (match_dup 3)) 0)))]
5799 operands[1] = gen_lowpart (Pmode, operands[1]);
5800 operands[2] = gen_lowpart (Pmode, operands[2]);
5801 operands[3] = gen_lowpart (Pmode, operands[3]);
5803 [(set_attr "type" "lea")
5804 (set_attr "mode" "SI")])
5806 (define_insn_and_split "*lea_general_2"
5807 [(set (match_operand 0 "register_operand" "=r")
5808 (plus (mult (match_operand 1 "index_register_operand" "l")
5809 (match_operand 2 "const248_operand" "i"))
5810 (match_operand 3 "nonmemory_operand" "ri")))]
5811 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5812 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5813 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5814 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5815 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5816 || GET_MODE (operands[3]) == VOIDmode)"
5818 "&& reload_completed"
5822 operands[0] = gen_lowpart (SImode, operands[0]);
5823 operands[1] = gen_lowpart (Pmode, operands[1]);
5824 operands[3] = gen_lowpart (Pmode, operands[3]);
5825 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5827 if (Pmode != SImode)
5828 pat = gen_rtx_SUBREG (SImode, pat, 0);
5829 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5832 [(set_attr "type" "lea")
5833 (set_attr "mode" "SI")])
5835 (define_insn_and_split "*lea_general_2_zext"
5836 [(set (match_operand:DI 0 "register_operand" "=r")
5838 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5839 (match_operand:SI 2 "const248_operand" "n"))
5840 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5843 "&& reload_completed"
5845 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5847 (match_dup 3)) 0)))]
5849 operands[1] = gen_lowpart (Pmode, operands[1]);
5850 operands[3] = gen_lowpart (Pmode, operands[3]);
5852 [(set_attr "type" "lea")
5853 (set_attr "mode" "SI")])
5855 (define_insn_and_split "*lea_general_3"
5856 [(set (match_operand 0 "register_operand" "=r")
5857 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5858 (match_operand 2 "const248_operand" "i"))
5859 (match_operand 3 "register_operand" "r"))
5860 (match_operand 4 "immediate_operand" "i")))]
5861 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5862 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5863 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5864 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5865 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5867 "&& reload_completed"
5871 operands[0] = gen_lowpart (SImode, operands[0]);
5872 operands[1] = gen_lowpart (Pmode, operands[1]);
5873 operands[3] = gen_lowpart (Pmode, operands[3]);
5874 operands[4] = gen_lowpart (Pmode, operands[4]);
5875 pat = gen_rtx_PLUS (Pmode,
5876 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5880 if (Pmode != SImode)
5881 pat = gen_rtx_SUBREG (SImode, pat, 0);
5882 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5885 [(set_attr "type" "lea")
5886 (set_attr "mode" "SI")])
5888 (define_insn_and_split "*lea_general_3_zext"
5889 [(set (match_operand:DI 0 "register_operand" "=r")
5891 (plus:SI (plus:SI (mult:SI
5892 (match_operand:SI 1 "index_register_operand" "l")
5893 (match_operand:SI 2 "const248_operand" "n"))
5894 (match_operand:SI 3 "register_operand" "r"))
5895 (match_operand:SI 4 "immediate_operand" "i"))))]
5898 "&& reload_completed"
5900 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5903 (match_dup 4)) 0)))]
5905 operands[1] = gen_lowpart (Pmode, operands[1]);
5906 operands[3] = gen_lowpart (Pmode, operands[3]);
5907 operands[4] = gen_lowpart (Pmode, operands[4]);
5909 [(set_attr "type" "lea")
5910 (set_attr "mode" "SI")])
5912 (define_insn "*adddi_1_rex64"
5913 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5914 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5915 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5916 (clobber (reg:CC FLAGS_REG))]
5917 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5919 switch (get_attr_type (insn))
5922 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5923 return "lea{q}\t{%a2, %0|%0, %a2}";
5926 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5927 if (operands[2] == const1_rtx)
5928 return "inc{q}\t%0";
5931 gcc_assert (operands[2] == constm1_rtx);
5932 return "dec{q}\t%0";
5936 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5938 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5939 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5940 if (CONST_INT_P (operands[2])
5941 /* Avoid overflows. */
5942 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5943 && (INTVAL (operands[2]) == 128
5944 || (INTVAL (operands[2]) < 0
5945 && INTVAL (operands[2]) != -128)))
5947 operands[2] = GEN_INT (-INTVAL (operands[2]));
5948 return "sub{q}\t{%2, %0|%0, %2}";
5950 return "add{q}\t{%2, %0|%0, %2}";
5954 (cond [(eq_attr "alternative" "2")
5955 (const_string "lea")
5956 ; Current assemblers are broken and do not allow @GOTOFF in
5957 ; ought but a memory context.
5958 (match_operand:DI 2 "pic_symbolic_operand" "")
5959 (const_string "lea")
5960 (match_operand:DI 2 "incdec_operand" "")
5961 (const_string "incdec")
5963 (const_string "alu")))
5964 (set_attr "mode" "DI")])
5966 ;; Convert lea to the lea pattern to avoid flags dependency.
5968 [(set (match_operand:DI 0 "register_operand" "")
5969 (plus:DI (match_operand:DI 1 "register_operand" "")
5970 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5971 (clobber (reg:CC FLAGS_REG))]
5972 "TARGET_64BIT && reload_completed
5973 && true_regnum (operands[0]) != true_regnum (operands[1])"
5975 (plus:DI (match_dup 1)
5979 (define_insn "*adddi_2_rex64"
5980 [(set (reg FLAGS_REG)
5982 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5983 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5985 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5986 (plus:DI (match_dup 1) (match_dup 2)))]
5987 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5988 && ix86_binary_operator_ok (PLUS, DImode, operands)
5989 /* Current assemblers are broken and do not allow @GOTOFF in
5990 ought but a memory context. */
5991 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5993 switch (get_attr_type (insn))
5996 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5997 if (operands[2] == const1_rtx)
5998 return "inc{q}\t%0";
6001 gcc_assert (operands[2] == constm1_rtx);
6002 return "dec{q}\t%0";
6006 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6007 /* ???? We ought to handle there the 32bit case too
6008 - do we need new constraint? */
6009 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6011 if (CONST_INT_P (operands[2])
6012 /* Avoid overflows. */
6013 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6014 && (INTVAL (operands[2]) == 128
6015 || (INTVAL (operands[2]) < 0
6016 && INTVAL (operands[2]) != -128)))
6018 operands[2] = GEN_INT (-INTVAL (operands[2]));
6019 return "sub{q}\t{%2, %0|%0, %2}";
6021 return "add{q}\t{%2, %0|%0, %2}";
6025 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6026 (const_string "incdec")
6027 (const_string "alu")))
6028 (set_attr "mode" "DI")])
6030 (define_insn "*adddi_3_rex64"
6031 [(set (reg FLAGS_REG)
6032 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6033 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6034 (clobber (match_scratch:DI 0 "=r"))]
6036 && ix86_match_ccmode (insn, CCZmode)
6037 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6038 /* Current assemblers are broken and do not allow @GOTOFF in
6039 ought but a memory context. */
6040 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6042 switch (get_attr_type (insn))
6045 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6046 if (operands[2] == const1_rtx)
6047 return "inc{q}\t%0";
6050 gcc_assert (operands[2] == constm1_rtx);
6051 return "dec{q}\t%0";
6055 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6056 /* ???? We ought to handle there the 32bit case too
6057 - do we need new constraint? */
6058 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6059 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6060 if (CONST_INT_P (operands[2])
6061 /* Avoid overflows. */
6062 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6063 && (INTVAL (operands[2]) == 128
6064 || (INTVAL (operands[2]) < 0
6065 && INTVAL (operands[2]) != -128)))
6067 operands[2] = GEN_INT (-INTVAL (operands[2]));
6068 return "sub{q}\t{%2, %0|%0, %2}";
6070 return "add{q}\t{%2, %0|%0, %2}";
6074 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6075 (const_string "incdec")
6076 (const_string "alu")))
6077 (set_attr "mode" "DI")])
6079 ; For comparisons against 1, -1 and 128, we may generate better code
6080 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6081 ; is matched then. We can't accept general immediate, because for
6082 ; case of overflows, the result is messed up.
6083 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6085 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6086 ; only for comparisons not depending on it.
6087 (define_insn "*adddi_4_rex64"
6088 [(set (reg FLAGS_REG)
6089 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6090 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6091 (clobber (match_scratch:DI 0 "=rm"))]
6093 && ix86_match_ccmode (insn, CCGCmode)"
6095 switch (get_attr_type (insn))
6098 if (operands[2] == constm1_rtx)
6099 return "inc{q}\t%0";
6102 gcc_assert (operands[2] == const1_rtx);
6103 return "dec{q}\t%0";
6107 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6108 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6109 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6110 if ((INTVAL (operands[2]) == -128
6111 || (INTVAL (operands[2]) > 0
6112 && INTVAL (operands[2]) != 128))
6113 /* Avoid overflows. */
6114 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6115 return "sub{q}\t{%2, %0|%0, %2}";
6116 operands[2] = GEN_INT (-INTVAL (operands[2]));
6117 return "add{q}\t{%2, %0|%0, %2}";
6121 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6122 (const_string "incdec")
6123 (const_string "alu")))
6124 (set_attr "mode" "DI")])
6126 (define_insn "*adddi_5_rex64"
6127 [(set (reg FLAGS_REG)
6129 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6130 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6132 (clobber (match_scratch:DI 0 "=r"))]
6134 && ix86_match_ccmode (insn, CCGOCmode)
6135 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6136 /* Current assemblers are broken and do not allow @GOTOFF in
6137 ought but a memory context. */
6138 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6140 switch (get_attr_type (insn))
6143 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6144 if (operands[2] == const1_rtx)
6145 return "inc{q}\t%0";
6148 gcc_assert (operands[2] == constm1_rtx);
6149 return "dec{q}\t%0";
6153 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6154 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6155 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6156 if (CONST_INT_P (operands[2])
6157 /* Avoid overflows. */
6158 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6159 && (INTVAL (operands[2]) == 128
6160 || (INTVAL (operands[2]) < 0
6161 && INTVAL (operands[2]) != -128)))
6163 operands[2] = GEN_INT (-INTVAL (operands[2]));
6164 return "sub{q}\t{%2, %0|%0, %2}";
6166 return "add{q}\t{%2, %0|%0, %2}";
6170 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6171 (const_string "incdec")
6172 (const_string "alu")))
6173 (set_attr "mode" "DI")])
6176 (define_insn "*addsi_1"
6177 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6178 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6179 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6180 (clobber (reg:CC FLAGS_REG))]
6181 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6183 switch (get_attr_type (insn))
6186 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6187 return "lea{l}\t{%a2, %0|%0, %a2}";
6190 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6191 if (operands[2] == const1_rtx)
6192 return "inc{l}\t%0";
6195 gcc_assert (operands[2] == constm1_rtx);
6196 return "dec{l}\t%0";
6200 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6202 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6203 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6204 if (CONST_INT_P (operands[2])
6205 && (INTVAL (operands[2]) == 128
6206 || (INTVAL (operands[2]) < 0
6207 && INTVAL (operands[2]) != -128)))
6209 operands[2] = GEN_INT (-INTVAL (operands[2]));
6210 return "sub{l}\t{%2, %0|%0, %2}";
6212 return "add{l}\t{%2, %0|%0, %2}";
6216 (cond [(eq_attr "alternative" "2")
6217 (const_string "lea")
6218 ; Current assemblers are broken and do not allow @GOTOFF in
6219 ; ought but a memory context.
6220 (match_operand:SI 2 "pic_symbolic_operand" "")
6221 (const_string "lea")
6222 (match_operand:SI 2 "incdec_operand" "")
6223 (const_string "incdec")
6225 (const_string "alu")))
6226 (set_attr "mode" "SI")])
6228 ;; Convert lea to the lea pattern to avoid flags dependency.
6230 [(set (match_operand 0 "register_operand" "")
6231 (plus (match_operand 1 "register_operand" "")
6232 (match_operand 2 "nonmemory_operand" "")))
6233 (clobber (reg:CC FLAGS_REG))]
6235 && true_regnum (operands[0]) != true_regnum (operands[1])"
6239 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6240 may confuse gen_lowpart. */
6241 if (GET_MODE (operands[0]) != Pmode)
6243 operands[1] = gen_lowpart (Pmode, operands[1]);
6244 operands[2] = gen_lowpart (Pmode, operands[2]);
6246 operands[0] = gen_lowpart (SImode, operands[0]);
6247 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6248 if (Pmode != SImode)
6249 pat = gen_rtx_SUBREG (SImode, pat, 0);
6250 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6254 ;; It may seem that nonimmediate operand is proper one for operand 1.
6255 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6256 ;; we take care in ix86_binary_operator_ok to not allow two memory
6257 ;; operands so proper swapping will be done in reload. This allow
6258 ;; patterns constructed from addsi_1 to match.
6259 (define_insn "addsi_1_zext"
6260 [(set (match_operand:DI 0 "register_operand" "=r,r")
6262 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6263 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6264 (clobber (reg:CC FLAGS_REG))]
6265 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6267 switch (get_attr_type (insn))
6270 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6271 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6274 if (operands[2] == const1_rtx)
6275 return "inc{l}\t%k0";
6278 gcc_assert (operands[2] == constm1_rtx);
6279 return "dec{l}\t%k0";
6283 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6284 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6285 if (CONST_INT_P (operands[2])
6286 && (INTVAL (operands[2]) == 128
6287 || (INTVAL (operands[2]) < 0
6288 && INTVAL (operands[2]) != -128)))
6290 operands[2] = GEN_INT (-INTVAL (operands[2]));
6291 return "sub{l}\t{%2, %k0|%k0, %2}";
6293 return "add{l}\t{%2, %k0|%k0, %2}";
6297 (cond [(eq_attr "alternative" "1")
6298 (const_string "lea")
6299 ; Current assemblers are broken and do not allow @GOTOFF in
6300 ; ought but a memory context.
6301 (match_operand:SI 2 "pic_symbolic_operand" "")
6302 (const_string "lea")
6303 (match_operand:SI 2 "incdec_operand" "")
6304 (const_string "incdec")
6306 (const_string "alu")))
6307 (set_attr "mode" "SI")])
6309 ;; Convert lea to the lea pattern to avoid flags dependency.
6311 [(set (match_operand:DI 0 "register_operand" "")
6313 (plus:SI (match_operand:SI 1 "register_operand" "")
6314 (match_operand:SI 2 "nonmemory_operand" ""))))
6315 (clobber (reg:CC FLAGS_REG))]
6316 "TARGET_64BIT && reload_completed
6317 && true_regnum (operands[0]) != true_regnum (operands[1])"
6319 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6321 operands[1] = gen_lowpart (Pmode, operands[1]);
6322 operands[2] = gen_lowpart (Pmode, operands[2]);
6325 (define_insn "*addsi_2"
6326 [(set (reg FLAGS_REG)
6328 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6329 (match_operand:SI 2 "general_operand" "rmni,rni"))
6331 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6332 (plus:SI (match_dup 1) (match_dup 2)))]
6333 "ix86_match_ccmode (insn, CCGOCmode)
6334 && ix86_binary_operator_ok (PLUS, SImode, operands)
6335 /* Current assemblers are broken and do not allow @GOTOFF in
6336 ought but a memory context. */
6337 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6339 switch (get_attr_type (insn))
6342 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6343 if (operands[2] == const1_rtx)
6344 return "inc{l}\t%0";
6347 gcc_assert (operands[2] == constm1_rtx);
6348 return "dec{l}\t%0";
6352 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6353 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6354 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6355 if (CONST_INT_P (operands[2])
6356 && (INTVAL (operands[2]) == 128
6357 || (INTVAL (operands[2]) < 0
6358 && INTVAL (operands[2]) != -128)))
6360 operands[2] = GEN_INT (-INTVAL (operands[2]));
6361 return "sub{l}\t{%2, %0|%0, %2}";
6363 return "add{l}\t{%2, %0|%0, %2}";
6367 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6368 (const_string "incdec")
6369 (const_string "alu")))
6370 (set_attr "mode" "SI")])
6372 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6373 (define_insn "*addsi_2_zext"
6374 [(set (reg FLAGS_REG)
6376 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6377 (match_operand:SI 2 "general_operand" "rmni"))
6379 (set (match_operand:DI 0 "register_operand" "=r")
6380 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6381 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6382 && ix86_binary_operator_ok (PLUS, SImode, operands)
6383 /* Current assemblers are broken and do not allow @GOTOFF in
6384 ought but a memory context. */
6385 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6387 switch (get_attr_type (insn))
6390 if (operands[2] == const1_rtx)
6391 return "inc{l}\t%k0";
6394 gcc_assert (operands[2] == constm1_rtx);
6395 return "dec{l}\t%k0";
6399 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6400 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6401 if (CONST_INT_P (operands[2])
6402 && (INTVAL (operands[2]) == 128
6403 || (INTVAL (operands[2]) < 0
6404 && INTVAL (operands[2]) != -128)))
6406 operands[2] = GEN_INT (-INTVAL (operands[2]));
6407 return "sub{l}\t{%2, %k0|%k0, %2}";
6409 return "add{l}\t{%2, %k0|%k0, %2}";
6413 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6414 (const_string "incdec")
6415 (const_string "alu")))
6416 (set_attr "mode" "SI")])
6418 (define_insn "*addsi_3"
6419 [(set (reg FLAGS_REG)
6420 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6421 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6422 (clobber (match_scratch:SI 0 "=r"))]
6423 "ix86_match_ccmode (insn, CCZmode)
6424 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6425 /* Current assemblers are broken and do not allow @GOTOFF in
6426 ought but a memory context. */
6427 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6429 switch (get_attr_type (insn))
6432 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6433 if (operands[2] == const1_rtx)
6434 return "inc{l}\t%0";
6437 gcc_assert (operands[2] == constm1_rtx);
6438 return "dec{l}\t%0";
6442 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6443 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6444 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6445 if (CONST_INT_P (operands[2])
6446 && (INTVAL (operands[2]) == 128
6447 || (INTVAL (operands[2]) < 0
6448 && INTVAL (operands[2]) != -128)))
6450 operands[2] = GEN_INT (-INTVAL (operands[2]));
6451 return "sub{l}\t{%2, %0|%0, %2}";
6453 return "add{l}\t{%2, %0|%0, %2}";
6457 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6458 (const_string "incdec")
6459 (const_string "alu")))
6460 (set_attr "mode" "SI")])
6462 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6463 (define_insn "*addsi_3_zext"
6464 [(set (reg FLAGS_REG)
6465 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6466 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6467 (set (match_operand:DI 0 "register_operand" "=r")
6468 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6469 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6470 && ix86_binary_operator_ok (PLUS, SImode, operands)
6471 /* Current assemblers are broken and do not allow @GOTOFF in
6472 ought but a memory context. */
6473 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6475 switch (get_attr_type (insn))
6478 if (operands[2] == const1_rtx)
6479 return "inc{l}\t%k0";
6482 gcc_assert (operands[2] == constm1_rtx);
6483 return "dec{l}\t%k0";
6487 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6488 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6489 if (CONST_INT_P (operands[2])
6490 && (INTVAL (operands[2]) == 128
6491 || (INTVAL (operands[2]) < 0
6492 && INTVAL (operands[2]) != -128)))
6494 operands[2] = GEN_INT (-INTVAL (operands[2]));
6495 return "sub{l}\t{%2, %k0|%k0, %2}";
6497 return "add{l}\t{%2, %k0|%k0, %2}";
6501 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6502 (const_string "incdec")
6503 (const_string "alu")))
6504 (set_attr "mode" "SI")])
6506 ; For comparisons against 1, -1 and 128, we may generate better code
6507 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6508 ; is matched then. We can't accept general immediate, because for
6509 ; case of overflows, the result is messed up.
6510 ; This pattern also don't hold of 0x80000000, since the value overflows
6512 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6513 ; only for comparisons not depending on it.
6514 (define_insn "*addsi_4"
6515 [(set (reg FLAGS_REG)
6516 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6517 (match_operand:SI 2 "const_int_operand" "n")))
6518 (clobber (match_scratch:SI 0 "=rm"))]
6519 "ix86_match_ccmode (insn, CCGCmode)
6520 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6522 switch (get_attr_type (insn))
6525 if (operands[2] == constm1_rtx)
6526 return "inc{l}\t%0";
6529 gcc_assert (operands[2] == const1_rtx);
6530 return "dec{l}\t%0";
6534 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6535 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6536 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6537 if ((INTVAL (operands[2]) == -128
6538 || (INTVAL (operands[2]) > 0
6539 && INTVAL (operands[2]) != 128)))
6540 return "sub{l}\t{%2, %0|%0, %2}";
6541 operands[2] = GEN_INT (-INTVAL (operands[2]));
6542 return "add{l}\t{%2, %0|%0, %2}";
6546 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6547 (const_string "incdec")
6548 (const_string "alu")))
6549 (set_attr "mode" "SI")])
6551 (define_insn "*addsi_5"
6552 [(set (reg FLAGS_REG)
6554 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6555 (match_operand:SI 2 "general_operand" "rmni"))
6557 (clobber (match_scratch:SI 0 "=r"))]
6558 "ix86_match_ccmode (insn, CCGOCmode)
6559 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6560 /* Current assemblers are broken and do not allow @GOTOFF in
6561 ought but a memory context. */
6562 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6564 switch (get_attr_type (insn))
6567 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6568 if (operands[2] == const1_rtx)
6569 return "inc{l}\t%0";
6572 gcc_assert (operands[2] == constm1_rtx);
6573 return "dec{l}\t%0";
6577 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6578 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6579 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6580 if (CONST_INT_P (operands[2])
6581 && (INTVAL (operands[2]) == 128
6582 || (INTVAL (operands[2]) < 0
6583 && INTVAL (operands[2]) != -128)))
6585 operands[2] = GEN_INT (-INTVAL (operands[2]));
6586 return "sub{l}\t{%2, %0|%0, %2}";
6588 return "add{l}\t{%2, %0|%0, %2}";
6592 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6593 (const_string "incdec")
6594 (const_string "alu")))
6595 (set_attr "mode" "SI")])
6597 (define_expand "addhi3"
6598 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6599 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6600 (match_operand:HI 2 "general_operand" "")))
6601 (clobber (reg:CC FLAGS_REG))])]
6602 "TARGET_HIMODE_MATH"
6603 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6605 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6606 ;; type optimizations enabled by define-splits. This is not important
6607 ;; for PII, and in fact harmful because of partial register stalls.
6609 (define_insn "*addhi_1_lea"
6610 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6611 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6612 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6613 (clobber (reg:CC FLAGS_REG))]
6614 "!TARGET_PARTIAL_REG_STALL
6615 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6617 switch (get_attr_type (insn))
6622 if (operands[2] == const1_rtx)
6623 return "inc{w}\t%0";
6626 gcc_assert (operands[2] == constm1_rtx);
6627 return "dec{w}\t%0";
6631 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6632 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6633 if (CONST_INT_P (operands[2])
6634 && (INTVAL (operands[2]) == 128
6635 || (INTVAL (operands[2]) < 0
6636 && INTVAL (operands[2]) != -128)))
6638 operands[2] = GEN_INT (-INTVAL (operands[2]));
6639 return "sub{w}\t{%2, %0|%0, %2}";
6641 return "add{w}\t{%2, %0|%0, %2}";
6645 (if_then_else (eq_attr "alternative" "2")
6646 (const_string "lea")
6647 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6648 (const_string "incdec")
6649 (const_string "alu"))))
6650 (set_attr "mode" "HI,HI,SI")])
6652 (define_insn "*addhi_1"
6653 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6654 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6655 (match_operand:HI 2 "general_operand" "ri,rm")))
6656 (clobber (reg:CC FLAGS_REG))]
6657 "TARGET_PARTIAL_REG_STALL
6658 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6660 switch (get_attr_type (insn))
6663 if (operands[2] == const1_rtx)
6664 return "inc{w}\t%0";
6667 gcc_assert (operands[2] == constm1_rtx);
6668 return "dec{w}\t%0";
6672 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6673 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6674 if (CONST_INT_P (operands[2])
6675 && (INTVAL (operands[2]) == 128
6676 || (INTVAL (operands[2]) < 0
6677 && INTVAL (operands[2]) != -128)))
6679 operands[2] = GEN_INT (-INTVAL (operands[2]));
6680 return "sub{w}\t{%2, %0|%0, %2}";
6682 return "add{w}\t{%2, %0|%0, %2}";
6686 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6687 (const_string "incdec")
6688 (const_string "alu")))
6689 (set_attr "mode" "HI")])
6691 (define_insn "*addhi_2"
6692 [(set (reg FLAGS_REG)
6694 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6695 (match_operand:HI 2 "general_operand" "rmni,rni"))
6697 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6698 (plus:HI (match_dup 1) (match_dup 2)))]
6699 "ix86_match_ccmode (insn, CCGOCmode)
6700 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6702 switch (get_attr_type (insn))
6705 if (operands[2] == const1_rtx)
6706 return "inc{w}\t%0";
6709 gcc_assert (operands[2] == constm1_rtx);
6710 return "dec{w}\t%0";
6714 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6715 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6716 if (CONST_INT_P (operands[2])
6717 && (INTVAL (operands[2]) == 128
6718 || (INTVAL (operands[2]) < 0
6719 && INTVAL (operands[2]) != -128)))
6721 operands[2] = GEN_INT (-INTVAL (operands[2]));
6722 return "sub{w}\t{%2, %0|%0, %2}";
6724 return "add{w}\t{%2, %0|%0, %2}";
6728 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6729 (const_string "incdec")
6730 (const_string "alu")))
6731 (set_attr "mode" "HI")])
6733 (define_insn "*addhi_3"
6734 [(set (reg FLAGS_REG)
6735 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6736 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6737 (clobber (match_scratch:HI 0 "=r"))]
6738 "ix86_match_ccmode (insn, CCZmode)
6739 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6741 switch (get_attr_type (insn))
6744 if (operands[2] == const1_rtx)
6745 return "inc{w}\t%0";
6748 gcc_assert (operands[2] == constm1_rtx);
6749 return "dec{w}\t%0";
6753 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6754 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6755 if (CONST_INT_P (operands[2])
6756 && (INTVAL (operands[2]) == 128
6757 || (INTVAL (operands[2]) < 0
6758 && INTVAL (operands[2]) != -128)))
6760 operands[2] = GEN_INT (-INTVAL (operands[2]));
6761 return "sub{w}\t{%2, %0|%0, %2}";
6763 return "add{w}\t{%2, %0|%0, %2}";
6767 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6768 (const_string "incdec")
6769 (const_string "alu")))
6770 (set_attr "mode" "HI")])
6772 ; See comments above addsi_4 for details.
6773 (define_insn "*addhi_4"
6774 [(set (reg FLAGS_REG)
6775 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6776 (match_operand:HI 2 "const_int_operand" "n")))
6777 (clobber (match_scratch:HI 0 "=rm"))]
6778 "ix86_match_ccmode (insn, CCGCmode)
6779 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6781 switch (get_attr_type (insn))
6784 if (operands[2] == constm1_rtx)
6785 return "inc{w}\t%0";
6788 gcc_assert (operands[2] == const1_rtx);
6789 return "dec{w}\t%0";
6793 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6794 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6795 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6796 if ((INTVAL (operands[2]) == -128
6797 || (INTVAL (operands[2]) > 0
6798 && INTVAL (operands[2]) != 128)))
6799 return "sub{w}\t{%2, %0|%0, %2}";
6800 operands[2] = GEN_INT (-INTVAL (operands[2]));
6801 return "add{w}\t{%2, %0|%0, %2}";
6805 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6806 (const_string "incdec")
6807 (const_string "alu")))
6808 (set_attr "mode" "SI")])
6811 (define_insn "*addhi_5"
6812 [(set (reg FLAGS_REG)
6814 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6815 (match_operand:HI 2 "general_operand" "rmni"))
6817 (clobber (match_scratch:HI 0 "=r"))]
6818 "ix86_match_ccmode (insn, CCGOCmode)
6819 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6821 switch (get_attr_type (insn))
6824 if (operands[2] == const1_rtx)
6825 return "inc{w}\t%0";
6828 gcc_assert (operands[2] == constm1_rtx);
6829 return "dec{w}\t%0";
6833 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6834 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6835 if (CONST_INT_P (operands[2])
6836 && (INTVAL (operands[2]) == 128
6837 || (INTVAL (operands[2]) < 0
6838 && INTVAL (operands[2]) != -128)))
6840 operands[2] = GEN_INT (-INTVAL (operands[2]));
6841 return "sub{w}\t{%2, %0|%0, %2}";
6843 return "add{w}\t{%2, %0|%0, %2}";
6847 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6848 (const_string "incdec")
6849 (const_string "alu")))
6850 (set_attr "mode" "HI")])
6852 (define_expand "addqi3"
6853 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6854 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6855 (match_operand:QI 2 "general_operand" "")))
6856 (clobber (reg:CC FLAGS_REG))])]
6857 "TARGET_QIMODE_MATH"
6858 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6860 ;; %%% Potential partial reg stall on alternative 2. What to do?
6861 (define_insn "*addqi_1_lea"
6862 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6863 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6864 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6865 (clobber (reg:CC FLAGS_REG))]
6866 "!TARGET_PARTIAL_REG_STALL
6867 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6869 int widen = (which_alternative == 2);
6870 switch (get_attr_type (insn))
6875 if (operands[2] == const1_rtx)
6876 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6879 gcc_assert (operands[2] == constm1_rtx);
6880 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6884 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6885 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6886 if (CONST_INT_P (operands[2])
6887 && (INTVAL (operands[2]) == 128
6888 || (INTVAL (operands[2]) < 0
6889 && INTVAL (operands[2]) != -128)))
6891 operands[2] = GEN_INT (-INTVAL (operands[2]));
6893 return "sub{l}\t{%2, %k0|%k0, %2}";
6895 return "sub{b}\t{%2, %0|%0, %2}";
6898 return "add{l}\t{%k2, %k0|%k0, %k2}";
6900 return "add{b}\t{%2, %0|%0, %2}";
6904 (if_then_else (eq_attr "alternative" "3")
6905 (const_string "lea")
6906 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6907 (const_string "incdec")
6908 (const_string "alu"))))
6909 (set_attr "mode" "QI,QI,SI,SI")])
6911 (define_insn "*addqi_1"
6912 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6913 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6914 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6915 (clobber (reg:CC FLAGS_REG))]
6916 "TARGET_PARTIAL_REG_STALL
6917 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6919 int widen = (which_alternative == 2);
6920 switch (get_attr_type (insn))
6923 if (operands[2] == const1_rtx)
6924 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6927 gcc_assert (operands[2] == constm1_rtx);
6928 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6932 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6933 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6934 if (CONST_INT_P (operands[2])
6935 && (INTVAL (operands[2]) == 128
6936 || (INTVAL (operands[2]) < 0
6937 && INTVAL (operands[2]) != -128)))
6939 operands[2] = GEN_INT (-INTVAL (operands[2]));
6941 return "sub{l}\t{%2, %k0|%k0, %2}";
6943 return "sub{b}\t{%2, %0|%0, %2}";
6946 return "add{l}\t{%k2, %k0|%k0, %k2}";
6948 return "add{b}\t{%2, %0|%0, %2}";
6952 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6953 (const_string "incdec")
6954 (const_string "alu")))
6955 (set_attr "mode" "QI,QI,SI")])
6957 (define_insn "*addqi_1_slp"
6958 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6959 (plus:QI (match_dup 0)
6960 (match_operand:QI 1 "general_operand" "qn,qnm")))
6961 (clobber (reg:CC FLAGS_REG))]
6962 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6963 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6965 switch (get_attr_type (insn))
6968 if (operands[1] == const1_rtx)
6969 return "inc{b}\t%0";
6972 gcc_assert (operands[1] == constm1_rtx);
6973 return "dec{b}\t%0";
6977 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6978 if (CONST_INT_P (operands[1])
6979 && INTVAL (operands[1]) < 0)
6981 operands[1] = GEN_INT (-INTVAL (operands[1]));
6982 return "sub{b}\t{%1, %0|%0, %1}";
6984 return "add{b}\t{%1, %0|%0, %1}";
6988 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6989 (const_string "incdec")
6990 (const_string "alu1")))
6991 (set (attr "memory")
6992 (if_then_else (match_operand 1 "memory_operand" "")
6993 (const_string "load")
6994 (const_string "none")))
6995 (set_attr "mode" "QI")])
6997 (define_insn "*addqi_2"
6998 [(set (reg FLAGS_REG)
7000 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7001 (match_operand:QI 2 "general_operand" "qmni,qni"))
7003 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7004 (plus:QI (match_dup 1) (match_dup 2)))]
7005 "ix86_match_ccmode (insn, CCGOCmode)
7006 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7008 switch (get_attr_type (insn))
7011 if (operands[2] == const1_rtx)
7012 return "inc{b}\t%0";
7015 gcc_assert (operands[2] == constm1_rtx
7016 || (CONST_INT_P (operands[2])
7017 && INTVAL (operands[2]) == 255));
7018 return "dec{b}\t%0";
7022 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7023 if (CONST_INT_P (operands[2])
7024 && INTVAL (operands[2]) < 0)
7026 operands[2] = GEN_INT (-INTVAL (operands[2]));
7027 return "sub{b}\t{%2, %0|%0, %2}";
7029 return "add{b}\t{%2, %0|%0, %2}";
7033 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7034 (const_string "incdec")
7035 (const_string "alu")))
7036 (set_attr "mode" "QI")])
7038 (define_insn "*addqi_3"
7039 [(set (reg FLAGS_REG)
7040 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
7041 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7042 (clobber (match_scratch:QI 0 "=q"))]
7043 "ix86_match_ccmode (insn, CCZmode)
7044 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7046 switch (get_attr_type (insn))
7049 if (operands[2] == const1_rtx)
7050 return "inc{b}\t%0";
7053 gcc_assert (operands[2] == constm1_rtx
7054 || (CONST_INT_P (operands[2])
7055 && INTVAL (operands[2]) == 255));
7056 return "dec{b}\t%0";
7060 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7061 if (CONST_INT_P (operands[2])
7062 && INTVAL (operands[2]) < 0)
7064 operands[2] = GEN_INT (-INTVAL (operands[2]));
7065 return "sub{b}\t{%2, %0|%0, %2}";
7067 return "add{b}\t{%2, %0|%0, %2}";
7071 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7072 (const_string "incdec")
7073 (const_string "alu")))
7074 (set_attr "mode" "QI")])
7076 ; See comments above addsi_4 for details.
7077 (define_insn "*addqi_4"
7078 [(set (reg FLAGS_REG)
7079 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7080 (match_operand:QI 2 "const_int_operand" "n")))
7081 (clobber (match_scratch:QI 0 "=qm"))]
7082 "ix86_match_ccmode (insn, CCGCmode)
7083 && (INTVAL (operands[2]) & 0xff) != 0x80"
7085 switch (get_attr_type (insn))
7088 if (operands[2] == constm1_rtx
7089 || (CONST_INT_P (operands[2])
7090 && INTVAL (operands[2]) == 255))
7091 return "inc{b}\t%0";
7094 gcc_assert (operands[2] == const1_rtx);
7095 return "dec{b}\t%0";
7099 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7100 if (INTVAL (operands[2]) < 0)
7102 operands[2] = GEN_INT (-INTVAL (operands[2]));
7103 return "add{b}\t{%2, %0|%0, %2}";
7105 return "sub{b}\t{%2, %0|%0, %2}";
7109 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7110 (const_string "incdec")
7111 (const_string "alu")))
7112 (set_attr "mode" "QI")])
7115 (define_insn "*addqi_5"
7116 [(set (reg FLAGS_REG)
7118 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7119 (match_operand:QI 2 "general_operand" "qmni"))
7121 (clobber (match_scratch:QI 0 "=q"))]
7122 "ix86_match_ccmode (insn, CCGOCmode)
7123 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7125 switch (get_attr_type (insn))
7128 if (operands[2] == const1_rtx)
7129 return "inc{b}\t%0";
7132 gcc_assert (operands[2] == constm1_rtx
7133 || (CONST_INT_P (operands[2])
7134 && INTVAL (operands[2]) == 255));
7135 return "dec{b}\t%0";
7139 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7140 if (CONST_INT_P (operands[2])
7141 && INTVAL (operands[2]) < 0)
7143 operands[2] = GEN_INT (-INTVAL (operands[2]));
7144 return "sub{b}\t{%2, %0|%0, %2}";
7146 return "add{b}\t{%2, %0|%0, %2}";
7150 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7151 (const_string "incdec")
7152 (const_string "alu")))
7153 (set_attr "mode" "QI")])
7156 (define_insn "addqi_ext_1"
7157 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7162 (match_operand 1 "ext_register_operand" "0")
7165 (match_operand:QI 2 "general_operand" "Qmn")))
7166 (clobber (reg:CC FLAGS_REG))]
7169 switch (get_attr_type (insn))
7172 if (operands[2] == const1_rtx)
7173 return "inc{b}\t%h0";
7176 gcc_assert (operands[2] == constm1_rtx
7177 || (CONST_INT_P (operands[2])
7178 && INTVAL (operands[2]) == 255));
7179 return "dec{b}\t%h0";
7183 return "add{b}\t{%2, %h0|%h0, %2}";
7187 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7188 (const_string "incdec")
7189 (const_string "alu")))
7190 (set_attr "mode" "QI")])
7192 (define_insn "*addqi_ext_1_rex64"
7193 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7198 (match_operand 1 "ext_register_operand" "0")
7201 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7202 (clobber (reg:CC FLAGS_REG))]
7205 switch (get_attr_type (insn))
7208 if (operands[2] == const1_rtx)
7209 return "inc{b}\t%h0";
7212 gcc_assert (operands[2] == constm1_rtx
7213 || (CONST_INT_P (operands[2])
7214 && INTVAL (operands[2]) == 255));
7215 return "dec{b}\t%h0";
7219 return "add{b}\t{%2, %h0|%h0, %2}";
7223 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7224 (const_string "incdec")
7225 (const_string "alu")))
7226 (set_attr "mode" "QI")])
7228 (define_insn "*addqi_ext_2"
7229 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7234 (match_operand 1 "ext_register_operand" "%0")
7238 (match_operand 2 "ext_register_operand" "Q")
7241 (clobber (reg:CC FLAGS_REG))]
7243 "add{b}\t{%h2, %h0|%h0, %h2}"
7244 [(set_attr "type" "alu")
7245 (set_attr "mode" "QI")])
7247 ;; The patterns that match these are at the end of this file.
7249 (define_expand "addxf3"
7250 [(set (match_operand:XF 0 "register_operand" "")
7251 (plus:XF (match_operand:XF 1 "register_operand" "")
7252 (match_operand:XF 2 "register_operand" "")))]
7256 (define_expand "add<mode>3"
7257 [(set (match_operand:MODEF 0 "register_operand" "")
7258 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7259 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7260 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7263 ;; Subtract instructions
7265 ;; %%% splits for subditi3
7267 (define_expand "subti3"
7268 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7269 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7270 (match_operand:TI 2 "x86_64_general_operand" "")))
7271 (clobber (reg:CC FLAGS_REG))])]
7273 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7275 (define_insn "*subti3_1"
7276 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7277 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7278 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7279 (clobber (reg:CC FLAGS_REG))]
7280 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7284 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7285 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7286 (match_operand:TI 2 "x86_64_general_operand" "")))
7287 (clobber (reg:CC FLAGS_REG))]
7288 "TARGET_64BIT && reload_completed"
7289 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7290 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7291 (parallel [(set (match_dup 3)
7292 (minus:DI (match_dup 4)
7293 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7295 (clobber (reg:CC FLAGS_REG))])]
7296 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7298 ;; %%% splits for subsidi3
7300 (define_expand "subdi3"
7301 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7302 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7303 (match_operand:DI 2 "x86_64_general_operand" "")))
7304 (clobber (reg:CC FLAGS_REG))])]
7306 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7308 (define_insn "*subdi3_1"
7309 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7310 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7311 (match_operand:DI 2 "general_operand" "roiF,riF")))
7312 (clobber (reg:CC FLAGS_REG))]
7313 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7317 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7318 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7319 (match_operand:DI 2 "general_operand" "")))
7320 (clobber (reg:CC FLAGS_REG))]
7321 "!TARGET_64BIT && reload_completed"
7322 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7323 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7324 (parallel [(set (match_dup 3)
7325 (minus:SI (match_dup 4)
7326 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7328 (clobber (reg:CC FLAGS_REG))])]
7329 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7331 (define_insn "subdi3_carry_rex64"
7332 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7333 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7334 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7335 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7336 (clobber (reg:CC FLAGS_REG))]
7337 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7338 "sbb{q}\t{%2, %0|%0, %2}"
7339 [(set_attr "type" "alu")
7340 (set_attr "pent_pair" "pu")
7341 (set_attr "mode" "DI")])
7343 (define_insn "*subdi_1_rex64"
7344 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7345 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7346 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7347 (clobber (reg:CC FLAGS_REG))]
7348 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7349 "sub{q}\t{%2, %0|%0, %2}"
7350 [(set_attr "type" "alu")
7351 (set_attr "mode" "DI")])
7353 (define_insn "*subdi_2_rex64"
7354 [(set (reg FLAGS_REG)
7356 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7357 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7359 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7360 (minus:DI (match_dup 1) (match_dup 2)))]
7361 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7362 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7363 "sub{q}\t{%2, %0|%0, %2}"
7364 [(set_attr "type" "alu")
7365 (set_attr "mode" "DI")])
7367 (define_insn "*subdi_3_rex63"
7368 [(set (reg FLAGS_REG)
7369 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7370 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7371 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7372 (minus:DI (match_dup 1) (match_dup 2)))]
7373 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7374 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7375 "sub{q}\t{%2, %0|%0, %2}"
7376 [(set_attr "type" "alu")
7377 (set_attr "mode" "DI")])
7379 (define_insn "subqi3_carry"
7380 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7381 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7382 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7383 (match_operand:QI 2 "general_operand" "qi,qm"))))
7384 (clobber (reg:CC FLAGS_REG))]
7385 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7386 "sbb{b}\t{%2, %0|%0, %2}"
7387 [(set_attr "type" "alu")
7388 (set_attr "pent_pair" "pu")
7389 (set_attr "mode" "QI")])
7391 (define_insn "subhi3_carry"
7392 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7393 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7394 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7395 (match_operand:HI 2 "general_operand" "ri,rm"))))
7396 (clobber (reg:CC FLAGS_REG))]
7397 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7398 "sbb{w}\t{%2, %0|%0, %2}"
7399 [(set_attr "type" "alu")
7400 (set_attr "pent_pair" "pu")
7401 (set_attr "mode" "HI")])
7403 (define_insn "subsi3_carry"
7404 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7405 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7406 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7407 (match_operand:SI 2 "general_operand" "ri,rm"))))
7408 (clobber (reg:CC FLAGS_REG))]
7409 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7410 "sbb{l}\t{%2, %0|%0, %2}"
7411 [(set_attr "type" "alu")
7412 (set_attr "pent_pair" "pu")
7413 (set_attr "mode" "SI")])
7415 (define_insn "subsi3_carry_zext"
7416 [(set (match_operand:DI 0 "register_operand" "=r")
7418 (minus:SI (match_operand:SI 1 "register_operand" "0")
7419 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7420 (match_operand:SI 2 "general_operand" "g")))))
7421 (clobber (reg:CC FLAGS_REG))]
7422 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7423 "sbb{l}\t{%2, %k0|%k0, %2}"
7424 [(set_attr "type" "alu")
7425 (set_attr "pent_pair" "pu")
7426 (set_attr "mode" "SI")])
7428 (define_expand "subsi3"
7429 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7430 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7431 (match_operand:SI 2 "general_operand" "")))
7432 (clobber (reg:CC FLAGS_REG))])]
7434 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7436 (define_insn "*subsi_1"
7437 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7438 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7439 (match_operand:SI 2 "general_operand" "ri,rm")))
7440 (clobber (reg:CC FLAGS_REG))]
7441 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7442 "sub{l}\t{%2, %0|%0, %2}"
7443 [(set_attr "type" "alu")
7444 (set_attr "mode" "SI")])
7446 (define_insn "*subsi_1_zext"
7447 [(set (match_operand:DI 0 "register_operand" "=r")
7449 (minus:SI (match_operand:SI 1 "register_operand" "0")
7450 (match_operand:SI 2 "general_operand" "g"))))
7451 (clobber (reg:CC FLAGS_REG))]
7452 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7453 "sub{l}\t{%2, %k0|%k0, %2}"
7454 [(set_attr "type" "alu")
7455 (set_attr "mode" "SI")])
7457 (define_insn "*subsi_2"
7458 [(set (reg FLAGS_REG)
7460 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7461 (match_operand:SI 2 "general_operand" "ri,rm"))
7463 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7464 (minus:SI (match_dup 1) (match_dup 2)))]
7465 "ix86_match_ccmode (insn, CCGOCmode)
7466 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7467 "sub{l}\t{%2, %0|%0, %2}"
7468 [(set_attr "type" "alu")
7469 (set_attr "mode" "SI")])
7471 (define_insn "*subsi_2_zext"
7472 [(set (reg FLAGS_REG)
7474 (minus:SI (match_operand:SI 1 "register_operand" "0")
7475 (match_operand:SI 2 "general_operand" "g"))
7477 (set (match_operand:DI 0 "register_operand" "=r")
7479 (minus:SI (match_dup 1)
7481 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7482 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7483 "sub{l}\t{%2, %k0|%k0, %2}"
7484 [(set_attr "type" "alu")
7485 (set_attr "mode" "SI")])
7487 (define_insn "*subsi_3"
7488 [(set (reg FLAGS_REG)
7489 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7490 (match_operand:SI 2 "general_operand" "ri,rm")))
7491 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7492 (minus:SI (match_dup 1) (match_dup 2)))]
7493 "ix86_match_ccmode (insn, CCmode)
7494 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7495 "sub{l}\t{%2, %0|%0, %2}"
7496 [(set_attr "type" "alu")
7497 (set_attr "mode" "SI")])
7499 (define_insn "*subsi_3_zext"
7500 [(set (reg FLAGS_REG)
7501 (compare (match_operand:SI 1 "register_operand" "0")
7502 (match_operand:SI 2 "general_operand" "g")))
7503 (set (match_operand:DI 0 "register_operand" "=r")
7505 (minus:SI (match_dup 1)
7507 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7508 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7509 "sub{l}\t{%2, %1|%1, %2}"
7510 [(set_attr "type" "alu")
7511 (set_attr "mode" "DI")])
7513 (define_expand "subhi3"
7514 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7515 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7516 (match_operand:HI 2 "general_operand" "")))
7517 (clobber (reg:CC FLAGS_REG))])]
7518 "TARGET_HIMODE_MATH"
7519 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7521 (define_insn "*subhi_1"
7522 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7523 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7524 (match_operand:HI 2 "general_operand" "ri,rm")))
7525 (clobber (reg:CC FLAGS_REG))]
7526 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7527 "sub{w}\t{%2, %0|%0, %2}"
7528 [(set_attr "type" "alu")
7529 (set_attr "mode" "HI")])
7531 (define_insn "*subhi_2"
7532 [(set (reg FLAGS_REG)
7534 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7535 (match_operand:HI 2 "general_operand" "ri,rm"))
7537 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7538 (minus:HI (match_dup 1) (match_dup 2)))]
7539 "ix86_match_ccmode (insn, CCGOCmode)
7540 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7541 "sub{w}\t{%2, %0|%0, %2}"
7542 [(set_attr "type" "alu")
7543 (set_attr "mode" "HI")])
7545 (define_insn "*subhi_3"
7546 [(set (reg FLAGS_REG)
7547 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7548 (match_operand:HI 2 "general_operand" "ri,rm")))
7549 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7550 (minus:HI (match_dup 1) (match_dup 2)))]
7551 "ix86_match_ccmode (insn, CCmode)
7552 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7553 "sub{w}\t{%2, %0|%0, %2}"
7554 [(set_attr "type" "alu")
7555 (set_attr "mode" "HI")])
7557 (define_expand "subqi3"
7558 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7559 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7560 (match_operand:QI 2 "general_operand" "")))
7561 (clobber (reg:CC FLAGS_REG))])]
7562 "TARGET_QIMODE_MATH"
7563 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7565 (define_insn "*subqi_1"
7566 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7567 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7568 (match_operand:QI 2 "general_operand" "qn,qmn")))
7569 (clobber (reg:CC FLAGS_REG))]
7570 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7571 "sub{b}\t{%2, %0|%0, %2}"
7572 [(set_attr "type" "alu")
7573 (set_attr "mode" "QI")])
7575 (define_insn "*subqi_1_slp"
7576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7577 (minus:QI (match_dup 0)
7578 (match_operand:QI 1 "general_operand" "qn,qmn")))
7579 (clobber (reg:CC FLAGS_REG))]
7580 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7581 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7582 "sub{b}\t{%1, %0|%0, %1}"
7583 [(set_attr "type" "alu1")
7584 (set_attr "mode" "QI")])
7586 (define_insn "*subqi_2"
7587 [(set (reg FLAGS_REG)
7589 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7590 (match_operand:QI 2 "general_operand" "qi,qm"))
7592 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7593 (minus:HI (match_dup 1) (match_dup 2)))]
7594 "ix86_match_ccmode (insn, CCGOCmode)
7595 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7596 "sub{b}\t{%2, %0|%0, %2}"
7597 [(set_attr "type" "alu")
7598 (set_attr "mode" "QI")])
7600 (define_insn "*subqi_3"
7601 [(set (reg FLAGS_REG)
7602 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7603 (match_operand:QI 2 "general_operand" "qi,qm")))
7604 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7605 (minus:HI (match_dup 1) (match_dup 2)))]
7606 "ix86_match_ccmode (insn, CCmode)
7607 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7608 "sub{b}\t{%2, %0|%0, %2}"
7609 [(set_attr "type" "alu")
7610 (set_attr "mode" "QI")])
7612 ;; The patterns that match these are at the end of this file.
7614 (define_expand "subxf3"
7615 [(set (match_operand:XF 0 "register_operand" "")
7616 (minus:XF (match_operand:XF 1 "register_operand" "")
7617 (match_operand:XF 2 "register_operand" "")))]
7621 (define_expand "sub<mode>3"
7622 [(set (match_operand:MODEF 0 "register_operand" "")
7623 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7624 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7625 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7628 ;; Multiply instructions
7630 (define_expand "muldi3"
7631 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7632 (mult:DI (match_operand:DI 1 "register_operand" "")
7633 (match_operand:DI 2 "x86_64_general_operand" "")))
7634 (clobber (reg:CC FLAGS_REG))])]
7639 ;; IMUL reg64, reg64, imm8 Direct
7640 ;; IMUL reg64, mem64, imm8 VectorPath
7641 ;; IMUL reg64, reg64, imm32 Direct
7642 ;; IMUL reg64, mem64, imm32 VectorPath
7643 ;; IMUL reg64, reg64 Direct
7644 ;; IMUL reg64, mem64 Direct
7646 (define_insn "*muldi3_1_rex64"
7647 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7648 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7649 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7650 (clobber (reg:CC FLAGS_REG))]
7652 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7654 imul{q}\t{%2, %1, %0|%0, %1, %2}
7655 imul{q}\t{%2, %1, %0|%0, %1, %2}
7656 imul{q}\t{%2, %0|%0, %2}"
7657 [(set_attr "type" "imul")
7658 (set_attr "prefix_0f" "0,0,1")
7659 (set (attr "athlon_decode")
7660 (cond [(eq_attr "cpu" "athlon")
7661 (const_string "vector")
7662 (eq_attr "alternative" "1")
7663 (const_string "vector")
7664 (and (eq_attr "alternative" "2")
7665 (match_operand 1 "memory_operand" ""))
7666 (const_string "vector")]
7667 (const_string "direct")))
7668 (set (attr "amdfam10_decode")
7669 (cond [(and (eq_attr "alternative" "0,1")
7670 (match_operand 1 "memory_operand" ""))
7671 (const_string "vector")]
7672 (const_string "direct")))
7673 (set_attr "mode" "DI")])
7675 (define_expand "mulsi3"
7676 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7677 (mult:SI (match_operand:SI 1 "register_operand" "")
7678 (match_operand:SI 2 "general_operand" "")))
7679 (clobber (reg:CC FLAGS_REG))])]
7684 ;; IMUL reg32, reg32, imm8 Direct
7685 ;; IMUL reg32, mem32, imm8 VectorPath
7686 ;; IMUL reg32, reg32, imm32 Direct
7687 ;; IMUL reg32, mem32, imm32 VectorPath
7688 ;; IMUL reg32, reg32 Direct
7689 ;; IMUL reg32, mem32 Direct
7691 (define_insn "*mulsi3_1"
7692 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7693 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7694 (match_operand:SI 2 "general_operand" "K,i,mr")))
7695 (clobber (reg:CC FLAGS_REG))]
7696 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7698 imul{l}\t{%2, %1, %0|%0, %1, %2}
7699 imul{l}\t{%2, %1, %0|%0, %1, %2}
7700 imul{l}\t{%2, %0|%0, %2}"
7701 [(set_attr "type" "imul")
7702 (set_attr "prefix_0f" "0,0,1")
7703 (set (attr "athlon_decode")
7704 (cond [(eq_attr "cpu" "athlon")
7705 (const_string "vector")
7706 (eq_attr "alternative" "1")
7707 (const_string "vector")
7708 (and (eq_attr "alternative" "2")
7709 (match_operand 1 "memory_operand" ""))
7710 (const_string "vector")]
7711 (const_string "direct")))
7712 (set (attr "amdfam10_decode")
7713 (cond [(and (eq_attr "alternative" "0,1")
7714 (match_operand 1 "memory_operand" ""))
7715 (const_string "vector")]
7716 (const_string "direct")))
7717 (set_attr "mode" "SI")])
7719 (define_insn "*mulsi3_1_zext"
7720 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7722 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7723 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7724 (clobber (reg:CC FLAGS_REG))]
7726 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7728 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7729 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7730 imul{l}\t{%2, %k0|%k0, %2}"
7731 [(set_attr "type" "imul")
7732 (set_attr "prefix_0f" "0,0,1")
7733 (set (attr "athlon_decode")
7734 (cond [(eq_attr "cpu" "athlon")
7735 (const_string "vector")
7736 (eq_attr "alternative" "1")
7737 (const_string "vector")
7738 (and (eq_attr "alternative" "2")
7739 (match_operand 1 "memory_operand" ""))
7740 (const_string "vector")]
7741 (const_string "direct")))
7742 (set (attr "amdfam10_decode")
7743 (cond [(and (eq_attr "alternative" "0,1")
7744 (match_operand 1 "memory_operand" ""))
7745 (const_string "vector")]
7746 (const_string "direct")))
7747 (set_attr "mode" "SI")])
7749 (define_expand "mulhi3"
7750 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7751 (mult:HI (match_operand:HI 1 "register_operand" "")
7752 (match_operand:HI 2 "general_operand" "")))
7753 (clobber (reg:CC FLAGS_REG))])]
7754 "TARGET_HIMODE_MATH"
7758 ;; IMUL reg16, reg16, imm8 VectorPath
7759 ;; IMUL reg16, mem16, imm8 VectorPath
7760 ;; IMUL reg16, reg16, imm16 VectorPath
7761 ;; IMUL reg16, mem16, imm16 VectorPath
7762 ;; IMUL reg16, reg16 Direct
7763 ;; IMUL reg16, mem16 Direct
7764 (define_insn "*mulhi3_1"
7765 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7766 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7767 (match_operand:HI 2 "general_operand" "K,i,mr")))
7768 (clobber (reg:CC FLAGS_REG))]
7769 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7771 imul{w}\t{%2, %1, %0|%0, %1, %2}
7772 imul{w}\t{%2, %1, %0|%0, %1, %2}
7773 imul{w}\t{%2, %0|%0, %2}"
7774 [(set_attr "type" "imul")
7775 (set_attr "prefix_0f" "0,0,1")
7776 (set (attr "athlon_decode")
7777 (cond [(eq_attr "cpu" "athlon")
7778 (const_string "vector")
7779 (eq_attr "alternative" "1,2")
7780 (const_string "vector")]
7781 (const_string "direct")))
7782 (set (attr "amdfam10_decode")
7783 (cond [(eq_attr "alternative" "0,1")
7784 (const_string "vector")]
7785 (const_string "direct")))
7786 (set_attr "mode" "HI")])
7788 (define_expand "mulqi3"
7789 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7790 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7791 (match_operand:QI 2 "register_operand" "")))
7792 (clobber (reg:CC FLAGS_REG))])]
7793 "TARGET_QIMODE_MATH"
7800 (define_insn "*mulqi3_1"
7801 [(set (match_operand:QI 0 "register_operand" "=a")
7802 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7803 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7804 (clobber (reg:CC FLAGS_REG))]
7806 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7808 [(set_attr "type" "imul")
7809 (set_attr "length_immediate" "0")
7810 (set (attr "athlon_decode")
7811 (if_then_else (eq_attr "cpu" "athlon")
7812 (const_string "vector")
7813 (const_string "direct")))
7814 (set_attr "amdfam10_decode" "direct")
7815 (set_attr "mode" "QI")])
7817 (define_expand "umulqihi3"
7818 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7819 (mult:HI (zero_extend:HI
7820 (match_operand:QI 1 "nonimmediate_operand" ""))
7822 (match_operand:QI 2 "register_operand" ""))))
7823 (clobber (reg:CC FLAGS_REG))])]
7824 "TARGET_QIMODE_MATH"
7827 (define_insn "*umulqihi3_1"
7828 [(set (match_operand:HI 0 "register_operand" "=a")
7829 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7830 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7831 (clobber (reg:CC FLAGS_REG))]
7833 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7835 [(set_attr "type" "imul")
7836 (set_attr "length_immediate" "0")
7837 (set (attr "athlon_decode")
7838 (if_then_else (eq_attr "cpu" "athlon")
7839 (const_string "vector")
7840 (const_string "direct")))
7841 (set_attr "amdfam10_decode" "direct")
7842 (set_attr "mode" "QI")])
7844 (define_expand "mulqihi3"
7845 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7846 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7847 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7848 (clobber (reg:CC FLAGS_REG))])]
7849 "TARGET_QIMODE_MATH"
7852 (define_insn "*mulqihi3_insn"
7853 [(set (match_operand:HI 0 "register_operand" "=a")
7854 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7855 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7856 (clobber (reg:CC FLAGS_REG))]
7858 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7860 [(set_attr "type" "imul")
7861 (set_attr "length_immediate" "0")
7862 (set (attr "athlon_decode")
7863 (if_then_else (eq_attr "cpu" "athlon")
7864 (const_string "vector")
7865 (const_string "direct")))
7866 (set_attr "amdfam10_decode" "direct")
7867 (set_attr "mode" "QI")])
7869 (define_expand "umulditi3"
7870 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7871 (mult:TI (zero_extend:TI
7872 (match_operand:DI 1 "nonimmediate_operand" ""))
7874 (match_operand:DI 2 "register_operand" ""))))
7875 (clobber (reg:CC FLAGS_REG))])]
7879 (define_insn "*umulditi3_insn"
7880 [(set (match_operand:TI 0 "register_operand" "=A")
7881 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7882 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7883 (clobber (reg:CC FLAGS_REG))]
7885 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7887 [(set_attr "type" "imul")
7888 (set_attr "length_immediate" "0")
7889 (set (attr "athlon_decode")
7890 (if_then_else (eq_attr "cpu" "athlon")
7891 (const_string "vector")
7892 (const_string "double")))
7893 (set_attr "amdfam10_decode" "double")
7894 (set_attr "mode" "DI")])
7896 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7897 (define_expand "umulsidi3"
7898 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7899 (mult:DI (zero_extend:DI
7900 (match_operand:SI 1 "nonimmediate_operand" ""))
7902 (match_operand:SI 2 "register_operand" ""))))
7903 (clobber (reg:CC FLAGS_REG))])]
7907 (define_insn "*umulsidi3_insn"
7908 [(set (match_operand:DI 0 "register_operand" "=A")
7909 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7910 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7911 (clobber (reg:CC FLAGS_REG))]
7913 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7915 [(set_attr "type" "imul")
7916 (set_attr "length_immediate" "0")
7917 (set (attr "athlon_decode")
7918 (if_then_else (eq_attr "cpu" "athlon")
7919 (const_string "vector")
7920 (const_string "double")))
7921 (set_attr "amdfam10_decode" "double")
7922 (set_attr "mode" "SI")])
7924 (define_expand "mulditi3"
7925 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7926 (mult:TI (sign_extend:TI
7927 (match_operand:DI 1 "nonimmediate_operand" ""))
7929 (match_operand:DI 2 "register_operand" ""))))
7930 (clobber (reg:CC FLAGS_REG))])]
7934 (define_insn "*mulditi3_insn"
7935 [(set (match_operand:TI 0 "register_operand" "=A")
7936 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7937 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7938 (clobber (reg:CC FLAGS_REG))]
7940 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7942 [(set_attr "type" "imul")
7943 (set_attr "length_immediate" "0")
7944 (set (attr "athlon_decode")
7945 (if_then_else (eq_attr "cpu" "athlon")
7946 (const_string "vector")
7947 (const_string "double")))
7948 (set_attr "amdfam10_decode" "double")
7949 (set_attr "mode" "DI")])
7951 (define_expand "mulsidi3"
7952 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7953 (mult:DI (sign_extend:DI
7954 (match_operand:SI 1 "nonimmediate_operand" ""))
7956 (match_operand:SI 2 "register_operand" ""))))
7957 (clobber (reg:CC FLAGS_REG))])]
7961 (define_insn "*mulsidi3_insn"
7962 [(set (match_operand:DI 0 "register_operand" "=A")
7963 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7964 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7965 (clobber (reg:CC FLAGS_REG))]
7967 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7969 [(set_attr "type" "imul")
7970 (set_attr "length_immediate" "0")
7971 (set (attr "athlon_decode")
7972 (if_then_else (eq_attr "cpu" "athlon")
7973 (const_string "vector")
7974 (const_string "double")))
7975 (set_attr "amdfam10_decode" "double")
7976 (set_attr "mode" "SI")])
7978 (define_expand "umuldi3_highpart"
7979 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7982 (mult:TI (zero_extend:TI
7983 (match_operand:DI 1 "nonimmediate_operand" ""))
7985 (match_operand:DI 2 "register_operand" "")))
7987 (clobber (match_scratch:DI 3 ""))
7988 (clobber (reg:CC FLAGS_REG))])]
7992 (define_insn "*umuldi3_highpart_rex64"
7993 [(set (match_operand:DI 0 "register_operand" "=d")
7996 (mult:TI (zero_extend:TI
7997 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7999 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8001 (clobber (match_scratch:DI 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 "length_immediate" "0")
8008 (set (attr "athlon_decode")
8009 (if_then_else (eq_attr "cpu" "athlon")
8010 (const_string "vector")
8011 (const_string "double")))
8012 (set_attr "amdfam10_decode" "double")
8013 (set_attr "mode" "DI")])
8015 (define_expand "umulsi3_highpart"
8016 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8019 (mult:DI (zero_extend:DI
8020 (match_operand:SI 1 "nonimmediate_operand" ""))
8022 (match_operand:SI 2 "register_operand" "")))
8024 (clobber (match_scratch:SI 3 ""))
8025 (clobber (reg:CC FLAGS_REG))])]
8029 (define_insn "*umulsi3_highpart_insn"
8030 [(set (match_operand:SI 0 "register_operand" "=d")
8033 (mult:DI (zero_extend:DI
8034 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8036 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8038 (clobber (match_scratch:SI 3 "=1"))
8039 (clobber (reg:CC FLAGS_REG))]
8040 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8042 [(set_attr "type" "imul")
8043 (set_attr "length_immediate" "0")
8044 (set (attr "athlon_decode")
8045 (if_then_else (eq_attr "cpu" "athlon")
8046 (const_string "vector")
8047 (const_string "double")))
8048 (set_attr "amdfam10_decode" "double")
8049 (set_attr "mode" "SI")])
8051 (define_insn "*umulsi3_highpart_zext"
8052 [(set (match_operand:DI 0 "register_operand" "=d")
8053 (zero_extend:DI (truncate:SI
8055 (mult:DI (zero_extend:DI
8056 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8058 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8060 (clobber (match_scratch:SI 3 "=1"))
8061 (clobber (reg:CC FLAGS_REG))]
8063 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8065 [(set_attr "type" "imul")
8066 (set_attr "length_immediate" "0")
8067 (set (attr "athlon_decode")
8068 (if_then_else (eq_attr "cpu" "athlon")
8069 (const_string "vector")
8070 (const_string "double")))
8071 (set_attr "amdfam10_decode" "double")
8072 (set_attr "mode" "SI")])
8074 (define_expand "smuldi3_highpart"
8075 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8078 (mult:TI (sign_extend:TI
8079 (match_operand:DI 1 "nonimmediate_operand" ""))
8081 (match_operand:DI 2 "register_operand" "")))
8083 (clobber (match_scratch:DI 3 ""))
8084 (clobber (reg:CC FLAGS_REG))])]
8088 (define_insn "*smuldi3_highpart_rex64"
8089 [(set (match_operand:DI 0 "register_operand" "=d")
8092 (mult:TI (sign_extend:TI
8093 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8095 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8097 (clobber (match_scratch:DI 3 "=1"))
8098 (clobber (reg:CC FLAGS_REG))]
8100 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8102 [(set_attr "type" "imul")
8103 (set (attr "athlon_decode")
8104 (if_then_else (eq_attr "cpu" "athlon")
8105 (const_string "vector")
8106 (const_string "double")))
8107 (set_attr "amdfam10_decode" "double")
8108 (set_attr "mode" "DI")])
8110 (define_expand "smulsi3_highpart"
8111 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8114 (mult:DI (sign_extend:DI
8115 (match_operand:SI 1 "nonimmediate_operand" ""))
8117 (match_operand:SI 2 "register_operand" "")))
8119 (clobber (match_scratch:SI 3 ""))
8120 (clobber (reg:CC FLAGS_REG))])]
8124 (define_insn "*smulsi3_highpart_insn"
8125 [(set (match_operand:SI 0 "register_operand" "=d")
8128 (mult:DI (sign_extend:DI
8129 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8131 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8133 (clobber (match_scratch:SI 3 "=1"))
8134 (clobber (reg:CC FLAGS_REG))]
8135 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8137 [(set_attr "type" "imul")
8138 (set (attr "athlon_decode")
8139 (if_then_else (eq_attr "cpu" "athlon")
8140 (const_string "vector")
8141 (const_string "double")))
8142 (set_attr "amdfam10_decode" "double")
8143 (set_attr "mode" "SI")])
8145 (define_insn "*smulsi3_highpart_zext"
8146 [(set (match_operand:DI 0 "register_operand" "=d")
8147 (zero_extend:DI (truncate:SI
8149 (mult:DI (sign_extend:DI
8150 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8152 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8154 (clobber (match_scratch:SI 3 "=1"))
8155 (clobber (reg:CC FLAGS_REG))]
8157 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8159 [(set_attr "type" "imul")
8160 (set (attr "athlon_decode")
8161 (if_then_else (eq_attr "cpu" "athlon")
8162 (const_string "vector")
8163 (const_string "double")))
8164 (set_attr "amdfam10_decode" "double")
8165 (set_attr "mode" "SI")])
8167 ;; The patterns that match these are at the end of this file.
8169 (define_expand "mulxf3"
8170 [(set (match_operand:XF 0 "register_operand" "")
8171 (mult:XF (match_operand:XF 1 "register_operand" "")
8172 (match_operand:XF 2 "register_operand" "")))]
8176 (define_expand "mul<mode>3"
8177 [(set (match_operand:MODEF 0 "register_operand" "")
8178 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8179 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8180 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8183 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8186 ;; Divide instructions
8188 (define_insn "divqi3"
8189 [(set (match_operand:QI 0 "register_operand" "=a")
8190 (div:QI (match_operand:HI 1 "register_operand" "0")
8191 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8192 (clobber (reg:CC FLAGS_REG))]
8193 "TARGET_QIMODE_MATH"
8195 [(set_attr "type" "idiv")
8196 (set_attr "mode" "QI")])
8198 (define_insn "udivqi3"
8199 [(set (match_operand:QI 0 "register_operand" "=a")
8200 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8201 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8202 (clobber (reg:CC FLAGS_REG))]
8203 "TARGET_QIMODE_MATH"
8205 [(set_attr "type" "idiv")
8206 (set_attr "mode" "QI")])
8208 ;; The patterns that match these are at the end of this file.
8210 (define_expand "divxf3"
8211 [(set (match_operand:XF 0 "register_operand" "")
8212 (div:XF (match_operand:XF 1 "register_operand" "")
8213 (match_operand:XF 2 "register_operand" "")))]
8217 (define_expand "divdf3"
8218 [(set (match_operand:DF 0 "register_operand" "")
8219 (div:DF (match_operand:DF 1 "register_operand" "")
8220 (match_operand:DF 2 "nonimmediate_operand" "")))]
8221 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8224 (define_expand "divsf3"
8225 [(set (match_operand:SF 0 "register_operand" "")
8226 (div:SF (match_operand:SF 1 "register_operand" "")
8227 (match_operand:SF 2 "nonimmediate_operand" "")))]
8228 "TARGET_80387 || TARGET_SSE_MATH"
8230 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8231 && flag_finite_math_only && !flag_trapping_math
8232 && flag_unsafe_math_optimizations)
8234 ix86_emit_swdivsf (operands[0], operands[1],
8235 operands[2], SFmode);
8240 ;; Remainder instructions.
8242 (define_expand "divmoddi4"
8243 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8244 (div:DI (match_operand:DI 1 "register_operand" "")
8245 (match_operand:DI 2 "nonimmediate_operand" "")))
8246 (set (match_operand:DI 3 "register_operand" "")
8247 (mod:DI (match_dup 1) (match_dup 2)))
8248 (clobber (reg:CC FLAGS_REG))])]
8252 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8253 ;; Penalize eax case slightly because it results in worse scheduling
8255 (define_insn "*divmoddi4_nocltd_rex64"
8256 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8257 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8258 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8259 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8260 (mod:DI (match_dup 2) (match_dup 3)))
8261 (clobber (reg:CC FLAGS_REG))]
8262 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8264 [(set_attr "type" "multi")])
8266 (define_insn "*divmoddi4_cltd_rex64"
8267 [(set (match_operand:DI 0 "register_operand" "=a")
8268 (div:DI (match_operand:DI 2 "register_operand" "a")
8269 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8270 (set (match_operand:DI 1 "register_operand" "=&d")
8271 (mod:DI (match_dup 2) (match_dup 3)))
8272 (clobber (reg:CC FLAGS_REG))]
8273 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8275 [(set_attr "type" "multi")])
8277 (define_insn "*divmoddi_noext_rex64"
8278 [(set (match_operand:DI 0 "register_operand" "=a")
8279 (div:DI (match_operand:DI 1 "register_operand" "0")
8280 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8281 (set (match_operand:DI 3 "register_operand" "=d")
8282 (mod:DI (match_dup 1) (match_dup 2)))
8283 (use (match_operand:DI 4 "register_operand" "3"))
8284 (clobber (reg:CC FLAGS_REG))]
8287 [(set_attr "type" "idiv")
8288 (set_attr "mode" "DI")])
8291 [(set (match_operand:DI 0 "register_operand" "")
8292 (div:DI (match_operand:DI 1 "register_operand" "")
8293 (match_operand:DI 2 "nonimmediate_operand" "")))
8294 (set (match_operand:DI 3 "register_operand" "")
8295 (mod:DI (match_dup 1) (match_dup 2)))
8296 (clobber (reg:CC FLAGS_REG))]
8297 "TARGET_64BIT && reload_completed"
8298 [(parallel [(set (match_dup 3)
8299 (ashiftrt:DI (match_dup 4) (const_int 63)))
8300 (clobber (reg:CC FLAGS_REG))])
8301 (parallel [(set (match_dup 0)
8302 (div:DI (reg:DI 0) (match_dup 2)))
8304 (mod:DI (reg:DI 0) (match_dup 2)))
8306 (clobber (reg:CC FLAGS_REG))])]
8308 /* Avoid use of cltd in favor of a mov+shift. */
8309 if (!TARGET_USE_CLTD && !optimize_size)
8311 if (true_regnum (operands[1]))
8312 emit_move_insn (operands[0], operands[1]);
8314 emit_move_insn (operands[3], operands[1]);
8315 operands[4] = operands[3];
8319 gcc_assert (!true_regnum (operands[1]));
8320 operands[4] = operands[1];
8325 (define_expand "divmodsi4"
8326 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8327 (div:SI (match_operand:SI 1 "register_operand" "")
8328 (match_operand:SI 2 "nonimmediate_operand" "")))
8329 (set (match_operand:SI 3 "register_operand" "")
8330 (mod:SI (match_dup 1) (match_dup 2)))
8331 (clobber (reg:CC FLAGS_REG))])]
8335 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8336 ;; Penalize eax case slightly because it results in worse scheduling
8338 (define_insn "*divmodsi4_nocltd"
8339 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8340 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8341 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8342 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8343 (mod:SI (match_dup 2) (match_dup 3)))
8344 (clobber (reg:CC FLAGS_REG))]
8345 "!optimize_size && !TARGET_USE_CLTD"
8347 [(set_attr "type" "multi")])
8349 (define_insn "*divmodsi4_cltd"
8350 [(set (match_operand:SI 0 "register_operand" "=a")
8351 (div:SI (match_operand:SI 2 "register_operand" "a")
8352 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8353 (set (match_operand:SI 1 "register_operand" "=&d")
8354 (mod:SI (match_dup 2) (match_dup 3)))
8355 (clobber (reg:CC FLAGS_REG))]
8356 "optimize_size || TARGET_USE_CLTD"
8358 [(set_attr "type" "multi")])
8360 (define_insn "*divmodsi_noext"
8361 [(set (match_operand:SI 0 "register_operand" "=a")
8362 (div:SI (match_operand:SI 1 "register_operand" "0")
8363 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8364 (set (match_operand:SI 3 "register_operand" "=d")
8365 (mod:SI (match_dup 1) (match_dup 2)))
8366 (use (match_operand:SI 4 "register_operand" "3"))
8367 (clobber (reg:CC FLAGS_REG))]
8370 [(set_attr "type" "idiv")
8371 (set_attr "mode" "SI")])
8374 [(set (match_operand:SI 0 "register_operand" "")
8375 (div:SI (match_operand:SI 1 "register_operand" "")
8376 (match_operand:SI 2 "nonimmediate_operand" "")))
8377 (set (match_operand:SI 3 "register_operand" "")
8378 (mod:SI (match_dup 1) (match_dup 2)))
8379 (clobber (reg:CC FLAGS_REG))]
8381 [(parallel [(set (match_dup 3)
8382 (ashiftrt:SI (match_dup 4) (const_int 31)))
8383 (clobber (reg:CC FLAGS_REG))])
8384 (parallel [(set (match_dup 0)
8385 (div:SI (reg:SI 0) (match_dup 2)))
8387 (mod:SI (reg:SI 0) (match_dup 2)))
8389 (clobber (reg:CC FLAGS_REG))])]
8391 /* Avoid use of cltd in favor of a mov+shift. */
8392 if (!TARGET_USE_CLTD && !optimize_size)
8394 if (true_regnum (operands[1]))
8395 emit_move_insn (operands[0], operands[1]);
8397 emit_move_insn (operands[3], operands[1]);
8398 operands[4] = operands[3];
8402 gcc_assert (!true_regnum (operands[1]));
8403 operands[4] = operands[1];
8407 (define_insn "divmodhi4"
8408 [(set (match_operand:HI 0 "register_operand" "=a")
8409 (div:HI (match_operand:HI 1 "register_operand" "0")
8410 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8411 (set (match_operand:HI 3 "register_operand" "=&d")
8412 (mod:HI (match_dup 1) (match_dup 2)))
8413 (clobber (reg:CC FLAGS_REG))]
8414 "TARGET_HIMODE_MATH"
8416 [(set_attr "type" "multi")
8417 (set_attr "length_immediate" "0")
8418 (set_attr "mode" "SI")])
8420 (define_insn "udivmoddi4"
8421 [(set (match_operand:DI 0 "register_operand" "=a")
8422 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8423 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8424 (set (match_operand:DI 3 "register_operand" "=&d")
8425 (umod:DI (match_dup 1) (match_dup 2)))
8426 (clobber (reg:CC FLAGS_REG))]
8428 "xor{q}\t%3, %3\;div{q}\t%2"
8429 [(set_attr "type" "multi")
8430 (set_attr "length_immediate" "0")
8431 (set_attr "mode" "DI")])
8433 (define_insn "*udivmoddi4_noext"
8434 [(set (match_operand:DI 0 "register_operand" "=a")
8435 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8436 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8437 (set (match_operand:DI 3 "register_operand" "=d")
8438 (umod:DI (match_dup 1) (match_dup 2)))
8440 (clobber (reg:CC FLAGS_REG))]
8443 [(set_attr "type" "idiv")
8444 (set_attr "mode" "DI")])
8447 [(set (match_operand:DI 0 "register_operand" "")
8448 (udiv:DI (match_operand:DI 1 "register_operand" "")
8449 (match_operand:DI 2 "nonimmediate_operand" "")))
8450 (set (match_operand:DI 3 "register_operand" "")
8451 (umod:DI (match_dup 1) (match_dup 2)))
8452 (clobber (reg:CC FLAGS_REG))]
8453 "TARGET_64BIT && reload_completed"
8454 [(set (match_dup 3) (const_int 0))
8455 (parallel [(set (match_dup 0)
8456 (udiv:DI (match_dup 1) (match_dup 2)))
8458 (umod:DI (match_dup 1) (match_dup 2)))
8460 (clobber (reg:CC FLAGS_REG))])]
8463 (define_insn "udivmodsi4"
8464 [(set (match_operand:SI 0 "register_operand" "=a")
8465 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8466 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8467 (set (match_operand:SI 3 "register_operand" "=&d")
8468 (umod:SI (match_dup 1) (match_dup 2)))
8469 (clobber (reg:CC FLAGS_REG))]
8471 "xor{l}\t%3, %3\;div{l}\t%2"
8472 [(set_attr "type" "multi")
8473 (set_attr "length_immediate" "0")
8474 (set_attr "mode" "SI")])
8476 (define_insn "*udivmodsi4_noext"
8477 [(set (match_operand:SI 0 "register_operand" "=a")
8478 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8479 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8480 (set (match_operand:SI 3 "register_operand" "=d")
8481 (umod:SI (match_dup 1) (match_dup 2)))
8483 (clobber (reg:CC FLAGS_REG))]
8486 [(set_attr "type" "idiv")
8487 (set_attr "mode" "SI")])
8490 [(set (match_operand:SI 0 "register_operand" "")
8491 (udiv:SI (match_operand:SI 1 "register_operand" "")
8492 (match_operand:SI 2 "nonimmediate_operand" "")))
8493 (set (match_operand:SI 3 "register_operand" "")
8494 (umod:SI (match_dup 1) (match_dup 2)))
8495 (clobber (reg:CC FLAGS_REG))]
8497 [(set (match_dup 3) (const_int 0))
8498 (parallel [(set (match_dup 0)
8499 (udiv:SI (match_dup 1) (match_dup 2)))
8501 (umod:SI (match_dup 1) (match_dup 2)))
8503 (clobber (reg:CC FLAGS_REG))])]
8506 (define_expand "udivmodhi4"
8507 [(set (match_dup 4) (const_int 0))
8508 (parallel [(set (match_operand:HI 0 "register_operand" "")
8509 (udiv:HI (match_operand:HI 1 "register_operand" "")
8510 (match_operand:HI 2 "nonimmediate_operand" "")))
8511 (set (match_operand:HI 3 "register_operand" "")
8512 (umod:HI (match_dup 1) (match_dup 2)))
8514 (clobber (reg:CC FLAGS_REG))])]
8515 "TARGET_HIMODE_MATH"
8516 "operands[4] = gen_reg_rtx (HImode);")
8518 (define_insn "*udivmodhi_noext"
8519 [(set (match_operand:HI 0 "register_operand" "=a")
8520 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8521 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8522 (set (match_operand:HI 3 "register_operand" "=d")
8523 (umod:HI (match_dup 1) (match_dup 2)))
8524 (use (match_operand:HI 4 "register_operand" "3"))
8525 (clobber (reg:CC FLAGS_REG))]
8528 [(set_attr "type" "idiv")
8529 (set_attr "mode" "HI")])
8531 ;; We cannot use div/idiv for double division, because it causes
8532 ;; "division by zero" on the overflow and that's not what we expect
8533 ;; from truncate. Because true (non truncating) double division is
8534 ;; never generated, we can't create this insn anyway.
8537 ; [(set (match_operand:SI 0 "register_operand" "=a")
8539 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8541 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8542 ; (set (match_operand:SI 3 "register_operand" "=d")
8544 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8545 ; (clobber (reg:CC FLAGS_REG))]
8547 ; "div{l}\t{%2, %0|%0, %2}"
8548 ; [(set_attr "type" "idiv")])
8550 ;;- Logical AND instructions
8552 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8553 ;; Note that this excludes ah.
8555 (define_insn "*testdi_1_rex64"
8556 [(set (reg FLAGS_REG)
8558 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8559 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8561 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8562 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8564 test{l}\t{%k1, %k0|%k0, %k1}
8565 test{l}\t{%k1, %k0|%k0, %k1}
8566 test{q}\t{%1, %0|%0, %1}
8567 test{q}\t{%1, %0|%0, %1}
8568 test{q}\t{%1, %0|%0, %1}"
8569 [(set_attr "type" "test")
8570 (set_attr "modrm" "0,1,0,1,1")
8571 (set_attr "mode" "SI,SI,DI,DI,DI")
8572 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8574 (define_insn "testsi_1"
8575 [(set (reg FLAGS_REG)
8577 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8578 (match_operand:SI 1 "general_operand" "in,in,rin"))
8580 "ix86_match_ccmode (insn, CCNOmode)
8581 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8582 "test{l}\t{%1, %0|%0, %1}"
8583 [(set_attr "type" "test")
8584 (set_attr "modrm" "0,1,1")
8585 (set_attr "mode" "SI")
8586 (set_attr "pent_pair" "uv,np,uv")])
8588 (define_expand "testsi_ccno_1"
8589 [(set (reg:CCNO FLAGS_REG)
8591 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8592 (match_operand:SI 1 "nonmemory_operand" ""))
8597 (define_insn "*testhi_1"
8598 [(set (reg FLAGS_REG)
8599 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8600 (match_operand:HI 1 "general_operand" "n,n,rn"))
8602 "ix86_match_ccmode (insn, CCNOmode)
8603 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8604 "test{w}\t{%1, %0|%0, %1}"
8605 [(set_attr "type" "test")
8606 (set_attr "modrm" "0,1,1")
8607 (set_attr "mode" "HI")
8608 (set_attr "pent_pair" "uv,np,uv")])
8610 (define_expand "testqi_ccz_1"
8611 [(set (reg:CCZ FLAGS_REG)
8612 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8613 (match_operand:QI 1 "nonmemory_operand" ""))
8618 (define_insn "*testqi_1_maybe_si"
8619 [(set (reg FLAGS_REG)
8622 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8623 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8625 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8626 && ix86_match_ccmode (insn,
8627 CONST_INT_P (operands[1])
8628 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8630 if (which_alternative == 3)
8632 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8633 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8634 return "test{l}\t{%1, %k0|%k0, %1}";
8636 return "test{b}\t{%1, %0|%0, %1}";
8638 [(set_attr "type" "test")
8639 (set_attr "modrm" "0,1,1,1")
8640 (set_attr "mode" "QI,QI,QI,SI")
8641 (set_attr "pent_pair" "uv,np,uv,np")])
8643 (define_insn "*testqi_1"
8644 [(set (reg FLAGS_REG)
8647 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8648 (match_operand:QI 1 "general_operand" "n,n,qn"))
8650 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8651 && ix86_match_ccmode (insn, CCNOmode)"
8652 "test{b}\t{%1, %0|%0, %1}"
8653 [(set_attr "type" "test")
8654 (set_attr "modrm" "0,1,1")
8655 (set_attr "mode" "QI")
8656 (set_attr "pent_pair" "uv,np,uv")])
8658 (define_expand "testqi_ext_ccno_0"
8659 [(set (reg:CCNO FLAGS_REG)
8663 (match_operand 0 "ext_register_operand" "")
8666 (match_operand 1 "const_int_operand" ""))
8671 (define_insn "*testqi_ext_0"
8672 [(set (reg FLAGS_REG)
8676 (match_operand 0 "ext_register_operand" "Q")
8679 (match_operand 1 "const_int_operand" "n"))
8681 "ix86_match_ccmode (insn, CCNOmode)"
8682 "test{b}\t{%1, %h0|%h0, %1}"
8683 [(set_attr "type" "test")
8684 (set_attr "mode" "QI")
8685 (set_attr "length_immediate" "1")
8686 (set_attr "pent_pair" "np")])
8688 (define_insn "*testqi_ext_1"
8689 [(set (reg FLAGS_REG)
8693 (match_operand 0 "ext_register_operand" "Q")
8697 (match_operand:QI 1 "general_operand" "Qm")))
8699 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8700 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8701 "test{b}\t{%1, %h0|%h0, %1}"
8702 [(set_attr "type" "test")
8703 (set_attr "mode" "QI")])
8705 (define_insn "*testqi_ext_1_rex64"
8706 [(set (reg FLAGS_REG)
8710 (match_operand 0 "ext_register_operand" "Q")
8714 (match_operand:QI 1 "register_operand" "Q")))
8716 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8717 "test{b}\t{%1, %h0|%h0, %1}"
8718 [(set_attr "type" "test")
8719 (set_attr "mode" "QI")])
8721 (define_insn "*testqi_ext_2"
8722 [(set (reg FLAGS_REG)
8726 (match_operand 0 "ext_register_operand" "Q")
8730 (match_operand 1 "ext_register_operand" "Q")
8734 "ix86_match_ccmode (insn, CCNOmode)"
8735 "test{b}\t{%h1, %h0|%h0, %h1}"
8736 [(set_attr "type" "test")
8737 (set_attr "mode" "QI")])
8739 ;; Combine likes to form bit extractions for some tests. Humor it.
8740 (define_insn "*testqi_ext_3"
8741 [(set (reg FLAGS_REG)
8742 (compare (zero_extract:SI
8743 (match_operand 0 "nonimmediate_operand" "rm")
8744 (match_operand:SI 1 "const_int_operand" "")
8745 (match_operand:SI 2 "const_int_operand" ""))
8747 "ix86_match_ccmode (insn, CCNOmode)
8748 && INTVAL (operands[1]) > 0
8749 && INTVAL (operands[2]) >= 0
8750 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8751 && (GET_MODE (operands[0]) == SImode
8752 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8753 || GET_MODE (operands[0]) == HImode
8754 || GET_MODE (operands[0]) == QImode)"
8757 (define_insn "*testqi_ext_3_rex64"
8758 [(set (reg FLAGS_REG)
8759 (compare (zero_extract:DI
8760 (match_operand 0 "nonimmediate_operand" "rm")
8761 (match_operand:DI 1 "const_int_operand" "")
8762 (match_operand:DI 2 "const_int_operand" ""))
8765 && ix86_match_ccmode (insn, CCNOmode)
8766 && INTVAL (operands[1]) > 0
8767 && INTVAL (operands[2]) >= 0
8768 /* Ensure that resulting mask is zero or sign extended operand. */
8769 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8770 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8771 && INTVAL (operands[1]) > 32))
8772 && (GET_MODE (operands[0]) == SImode
8773 || GET_MODE (operands[0]) == DImode
8774 || GET_MODE (operands[0]) == HImode
8775 || GET_MODE (operands[0]) == QImode)"
8779 [(set (match_operand 0 "flags_reg_operand" "")
8780 (match_operator 1 "compare_operator"
8782 (match_operand 2 "nonimmediate_operand" "")
8783 (match_operand 3 "const_int_operand" "")
8784 (match_operand 4 "const_int_operand" ""))
8786 "ix86_match_ccmode (insn, CCNOmode)"
8787 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8789 rtx val = operands[2];
8790 HOST_WIDE_INT len = INTVAL (operands[3]);
8791 HOST_WIDE_INT pos = INTVAL (operands[4]);
8793 enum machine_mode mode, submode;
8795 mode = GET_MODE (val);
8798 /* ??? Combine likes to put non-volatile mem extractions in QImode
8799 no matter the size of the test. So find a mode that works. */
8800 if (! MEM_VOLATILE_P (val))
8802 mode = smallest_mode_for_size (pos + len, MODE_INT);
8803 val = adjust_address (val, mode, 0);
8806 else if (GET_CODE (val) == SUBREG
8807 && (submode = GET_MODE (SUBREG_REG (val)),
8808 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8809 && pos + len <= GET_MODE_BITSIZE (submode))
8811 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8813 val = SUBREG_REG (val);
8815 else if (mode == HImode && pos + len <= 8)
8817 /* Small HImode tests can be converted to QImode. */
8819 val = gen_lowpart (QImode, val);
8822 if (len == HOST_BITS_PER_WIDE_INT)
8825 mask = ((HOST_WIDE_INT)1 << len) - 1;
8828 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8831 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8832 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8833 ;; this is relatively important trick.
8834 ;; Do the conversion only post-reload to avoid limiting of the register class
8837 [(set (match_operand 0 "flags_reg_operand" "")
8838 (match_operator 1 "compare_operator"
8839 [(and (match_operand 2 "register_operand" "")
8840 (match_operand 3 "const_int_operand" ""))
8843 && QI_REG_P (operands[2])
8844 && GET_MODE (operands[2]) != QImode
8845 && ((ix86_match_ccmode (insn, CCZmode)
8846 && !(INTVAL (operands[3]) & ~(255 << 8)))
8847 || (ix86_match_ccmode (insn, CCNOmode)
8848 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8851 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8854 "operands[2] = gen_lowpart (SImode, operands[2]);
8855 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8858 [(set (match_operand 0 "flags_reg_operand" "")
8859 (match_operator 1 "compare_operator"
8860 [(and (match_operand 2 "nonimmediate_operand" "")
8861 (match_operand 3 "const_int_operand" ""))
8864 && GET_MODE (operands[2]) != QImode
8865 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8866 && ((ix86_match_ccmode (insn, CCZmode)
8867 && !(INTVAL (operands[3]) & ~255))
8868 || (ix86_match_ccmode (insn, CCNOmode)
8869 && !(INTVAL (operands[3]) & ~127)))"
8871 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8873 "operands[2] = gen_lowpart (QImode, operands[2]);
8874 operands[3] = gen_lowpart (QImode, operands[3]);")
8877 ;; %%% This used to optimize known byte-wide and operations to memory,
8878 ;; and sometimes to QImode registers. If this is considered useful,
8879 ;; it should be done with splitters.
8881 (define_expand "anddi3"
8882 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8883 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8884 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8885 (clobber (reg:CC FLAGS_REG))]
8887 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8889 (define_insn "*anddi_1_rex64"
8890 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8891 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8892 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8893 (clobber (reg:CC FLAGS_REG))]
8894 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8896 switch (get_attr_type (insn))
8900 enum machine_mode mode;
8902 gcc_assert (CONST_INT_P (operands[2]));
8903 if (INTVAL (operands[2]) == 0xff)
8907 gcc_assert (INTVAL (operands[2]) == 0xffff);
8911 operands[1] = gen_lowpart (mode, operands[1]);
8913 return "movz{bq|x}\t{%1,%0|%0, %1}";
8915 return "movz{wq|x}\t{%1,%0|%0, %1}";
8919 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8920 if (get_attr_mode (insn) == MODE_SI)
8921 return "and{l}\t{%k2, %k0|%k0, %k2}";
8923 return "and{q}\t{%2, %0|%0, %2}";
8926 [(set_attr "type" "alu,alu,alu,imovx")
8927 (set_attr "length_immediate" "*,*,*,0")
8928 (set_attr "mode" "SI,DI,DI,DI")])
8930 (define_insn "*anddi_2"
8931 [(set (reg FLAGS_REG)
8932 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8933 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8935 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8936 (and:DI (match_dup 1) (match_dup 2)))]
8937 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8938 && ix86_binary_operator_ok (AND, DImode, operands)"
8940 and{l}\t{%k2, %k0|%k0, %k2}
8941 and{q}\t{%2, %0|%0, %2}
8942 and{q}\t{%2, %0|%0, %2}"
8943 [(set_attr "type" "alu")
8944 (set_attr "mode" "SI,DI,DI")])
8946 (define_expand "andsi3"
8947 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8948 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8949 (match_operand:SI 2 "general_operand" "")))
8950 (clobber (reg:CC FLAGS_REG))]
8952 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8954 (define_insn "*andsi_1"
8955 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8956 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8957 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8958 (clobber (reg:CC FLAGS_REG))]
8959 "ix86_binary_operator_ok (AND, SImode, operands)"
8961 switch (get_attr_type (insn))
8965 enum machine_mode mode;
8967 gcc_assert (CONST_INT_P (operands[2]));
8968 if (INTVAL (operands[2]) == 0xff)
8972 gcc_assert (INTVAL (operands[2]) == 0xffff);
8976 operands[1] = gen_lowpart (mode, operands[1]);
8978 return "movz{bl|x}\t{%1,%0|%0, %1}";
8980 return "movz{wl|x}\t{%1,%0|%0, %1}";
8984 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8985 return "and{l}\t{%2, %0|%0, %2}";
8988 [(set_attr "type" "alu,alu,imovx")
8989 (set_attr "length_immediate" "*,*,0")
8990 (set_attr "mode" "SI")])
8993 [(set (match_operand 0 "register_operand" "")
8995 (const_int -65536)))
8996 (clobber (reg:CC FLAGS_REG))]
8997 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8998 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8999 "operands[1] = gen_lowpart (HImode, operands[0]);")
9002 [(set (match_operand 0 "ext_register_operand" "")
9005 (clobber (reg:CC FLAGS_REG))]
9006 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9007 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9008 "operands[1] = gen_lowpart (QImode, operands[0]);")
9011 [(set (match_operand 0 "ext_register_operand" "")
9013 (const_int -65281)))
9014 (clobber (reg:CC FLAGS_REG))]
9015 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9016 [(parallel [(set (zero_extract:SI (match_dup 0)
9020 (zero_extract:SI (match_dup 0)
9023 (zero_extract:SI (match_dup 0)
9026 (clobber (reg:CC FLAGS_REG))])]
9027 "operands[0] = gen_lowpart (SImode, operands[0]);")
9029 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9030 (define_insn "*andsi_1_zext"
9031 [(set (match_operand:DI 0 "register_operand" "=r")
9033 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9034 (match_operand:SI 2 "general_operand" "g"))))
9035 (clobber (reg:CC FLAGS_REG))]
9036 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9037 "and{l}\t{%2, %k0|%k0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9041 (define_insn "*andsi_2"
9042 [(set (reg FLAGS_REG)
9043 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9044 (match_operand:SI 2 "general_operand" "g,ri"))
9046 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9047 (and:SI (match_dup 1) (match_dup 2)))]
9048 "ix86_match_ccmode (insn, CCNOmode)
9049 && ix86_binary_operator_ok (AND, SImode, operands)"
9050 "and{l}\t{%2, %0|%0, %2}"
9051 [(set_attr "type" "alu")
9052 (set_attr "mode" "SI")])
9054 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9055 (define_insn "*andsi_2_zext"
9056 [(set (reg FLAGS_REG)
9057 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9058 (match_operand:SI 2 "general_operand" "g"))
9060 (set (match_operand:DI 0 "register_operand" "=r")
9061 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9062 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9063 && ix86_binary_operator_ok (AND, SImode, operands)"
9064 "and{l}\t{%2, %k0|%k0, %2}"
9065 [(set_attr "type" "alu")
9066 (set_attr "mode" "SI")])
9068 (define_expand "andhi3"
9069 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9070 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9071 (match_operand:HI 2 "general_operand" "")))
9072 (clobber (reg:CC FLAGS_REG))]
9073 "TARGET_HIMODE_MATH"
9074 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9076 (define_insn "*andhi_1"
9077 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9078 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9079 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9080 (clobber (reg:CC FLAGS_REG))]
9081 "ix86_binary_operator_ok (AND, HImode, operands)"
9083 switch (get_attr_type (insn))
9086 gcc_assert (CONST_INT_P (operands[2]));
9087 gcc_assert (INTVAL (operands[2]) == 0xff);
9088 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9091 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9093 return "and{w}\t{%2, %0|%0, %2}";
9096 [(set_attr "type" "alu,alu,imovx")
9097 (set_attr "length_immediate" "*,*,0")
9098 (set_attr "mode" "HI,HI,SI")])
9100 (define_insn "*andhi_2"
9101 [(set (reg FLAGS_REG)
9102 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9103 (match_operand:HI 2 "general_operand" "g,ri"))
9105 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9106 (and:HI (match_dup 1) (match_dup 2)))]
9107 "ix86_match_ccmode (insn, CCNOmode)
9108 && ix86_binary_operator_ok (AND, HImode, operands)"
9109 "and{w}\t{%2, %0|%0, %2}"
9110 [(set_attr "type" "alu")
9111 (set_attr "mode" "HI")])
9113 (define_expand "andqi3"
9114 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9115 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9116 (match_operand:QI 2 "general_operand" "")))
9117 (clobber (reg:CC FLAGS_REG))]
9118 "TARGET_QIMODE_MATH"
9119 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9121 ;; %%% Potential partial reg stall on alternative 2. What to do?
9122 (define_insn "*andqi_1"
9123 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9124 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9125 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9126 (clobber (reg:CC FLAGS_REG))]
9127 "ix86_binary_operator_ok (AND, QImode, operands)"
9129 and{b}\t{%2, %0|%0, %2}
9130 and{b}\t{%2, %0|%0, %2}
9131 and{l}\t{%k2, %k0|%k0, %k2}"
9132 [(set_attr "type" "alu")
9133 (set_attr "mode" "QI,QI,SI")])
9135 (define_insn "*andqi_1_slp"
9136 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9137 (and:QI (match_dup 0)
9138 (match_operand:QI 1 "general_operand" "qi,qmi")))
9139 (clobber (reg:CC FLAGS_REG))]
9140 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9141 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9142 "and{b}\t{%1, %0|%0, %1}"
9143 [(set_attr "type" "alu1")
9144 (set_attr "mode" "QI")])
9146 (define_insn "*andqi_2_maybe_si"
9147 [(set (reg FLAGS_REG)
9149 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9150 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9152 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9153 (and:QI (match_dup 1) (match_dup 2)))]
9154 "ix86_binary_operator_ok (AND, QImode, operands)
9155 && ix86_match_ccmode (insn,
9156 CONST_INT_P (operands[2])
9157 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9159 if (which_alternative == 2)
9161 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9162 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9163 return "and{l}\t{%2, %k0|%k0, %2}";
9165 return "and{b}\t{%2, %0|%0, %2}";
9167 [(set_attr "type" "alu")
9168 (set_attr "mode" "QI,QI,SI")])
9170 (define_insn "*andqi_2"
9171 [(set (reg FLAGS_REG)
9173 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9174 (match_operand:QI 2 "general_operand" "qim,qi"))
9176 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9177 (and:QI (match_dup 1) (match_dup 2)))]
9178 "ix86_match_ccmode (insn, CCNOmode)
9179 && ix86_binary_operator_ok (AND, QImode, operands)"
9180 "and{b}\t{%2, %0|%0, %2}"
9181 [(set_attr "type" "alu")
9182 (set_attr "mode" "QI")])
9184 (define_insn "*andqi_2_slp"
9185 [(set (reg FLAGS_REG)
9187 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9188 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9190 (set (strict_low_part (match_dup 0))
9191 (and:QI (match_dup 0) (match_dup 1)))]
9192 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9193 && ix86_match_ccmode (insn, CCNOmode)
9194 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9195 "and{b}\t{%1, %0|%0, %1}"
9196 [(set_attr "type" "alu1")
9197 (set_attr "mode" "QI")])
9199 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9200 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9201 ;; for a QImode operand, which of course failed.
9203 (define_insn "andqi_ext_0"
9204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9209 (match_operand 1 "ext_register_operand" "0")
9212 (match_operand 2 "const_int_operand" "n")))
9213 (clobber (reg:CC FLAGS_REG))]
9215 "and{b}\t{%2, %h0|%h0, %2}"
9216 [(set_attr "type" "alu")
9217 (set_attr "length_immediate" "1")
9218 (set_attr "mode" "QI")])
9220 ;; Generated by peephole translating test to and. This shows up
9221 ;; often in fp comparisons.
9223 (define_insn "*andqi_ext_0_cc"
9224 [(set (reg FLAGS_REG)
9228 (match_operand 1 "ext_register_operand" "0")
9231 (match_operand 2 "const_int_operand" "n"))
9233 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9242 "ix86_match_ccmode (insn, CCNOmode)"
9243 "and{b}\t{%2, %h0|%h0, %2}"
9244 [(set_attr "type" "alu")
9245 (set_attr "length_immediate" "1")
9246 (set_attr "mode" "QI")])
9248 (define_insn "*andqi_ext_1"
9249 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9254 (match_operand 1 "ext_register_operand" "0")
9258 (match_operand:QI 2 "general_operand" "Qm"))))
9259 (clobber (reg:CC FLAGS_REG))]
9261 "and{b}\t{%2, %h0|%h0, %2}"
9262 [(set_attr "type" "alu")
9263 (set_attr "length_immediate" "0")
9264 (set_attr "mode" "QI")])
9266 (define_insn "*andqi_ext_1_rex64"
9267 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9272 (match_operand 1 "ext_register_operand" "0")
9276 (match_operand 2 "ext_register_operand" "Q"))))
9277 (clobber (reg:CC FLAGS_REG))]
9279 "and{b}\t{%2, %h0|%h0, %2}"
9280 [(set_attr "type" "alu")
9281 (set_attr "length_immediate" "0")
9282 (set_attr "mode" "QI")])
9284 (define_insn "*andqi_ext_2"
9285 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9290 (match_operand 1 "ext_register_operand" "%0")
9294 (match_operand 2 "ext_register_operand" "Q")
9297 (clobber (reg:CC FLAGS_REG))]
9299 "and{b}\t{%h2, %h0|%h0, %h2}"
9300 [(set_attr "type" "alu")
9301 (set_attr "length_immediate" "0")
9302 (set_attr "mode" "QI")])
9304 ;; Convert wide AND instructions with immediate operand to shorter QImode
9305 ;; equivalents when possible.
9306 ;; Don't do the splitting with memory operands, since it introduces risk
9307 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9308 ;; for size, but that can (should?) be handled by generic code instead.
9310 [(set (match_operand 0 "register_operand" "")
9311 (and (match_operand 1 "register_operand" "")
9312 (match_operand 2 "const_int_operand" "")))
9313 (clobber (reg:CC FLAGS_REG))]
9315 && QI_REG_P (operands[0])
9316 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9317 && !(~INTVAL (operands[2]) & ~(255 << 8))
9318 && GET_MODE (operands[0]) != QImode"
9319 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9320 (and:SI (zero_extract:SI (match_dup 1)
9321 (const_int 8) (const_int 8))
9323 (clobber (reg:CC FLAGS_REG))])]
9324 "operands[0] = gen_lowpart (SImode, operands[0]);
9325 operands[1] = gen_lowpart (SImode, operands[1]);
9326 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9328 ;; Since AND can be encoded with sign extended immediate, this is only
9329 ;; profitable when 7th bit is not set.
9331 [(set (match_operand 0 "register_operand" "")
9332 (and (match_operand 1 "general_operand" "")
9333 (match_operand 2 "const_int_operand" "")))
9334 (clobber (reg:CC FLAGS_REG))]
9336 && ANY_QI_REG_P (operands[0])
9337 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9338 && !(~INTVAL (operands[2]) & ~255)
9339 && !(INTVAL (operands[2]) & 128)
9340 && GET_MODE (operands[0]) != QImode"
9341 [(parallel [(set (strict_low_part (match_dup 0))
9342 (and:QI (match_dup 1)
9344 (clobber (reg:CC FLAGS_REG))])]
9345 "operands[0] = gen_lowpart (QImode, operands[0]);
9346 operands[1] = gen_lowpart (QImode, operands[1]);
9347 operands[2] = gen_lowpart (QImode, operands[2]);")
9349 ;; Logical inclusive OR instructions
9351 ;; %%% This used to optimize known byte-wide and operations to memory.
9352 ;; If this is considered useful, it should be done with splitters.
9354 (define_expand "iordi3"
9355 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9356 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9357 (match_operand:DI 2 "x86_64_general_operand" "")))
9358 (clobber (reg:CC FLAGS_REG))]
9360 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9362 (define_insn "*iordi_1_rex64"
9363 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9364 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9365 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9366 (clobber (reg:CC FLAGS_REG))]
9368 && ix86_binary_operator_ok (IOR, DImode, operands)"
9369 "or{q}\t{%2, %0|%0, %2}"
9370 [(set_attr "type" "alu")
9371 (set_attr "mode" "DI")])
9373 (define_insn "*iordi_2_rex64"
9374 [(set (reg FLAGS_REG)
9375 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9376 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9378 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9379 (ior:DI (match_dup 1) (match_dup 2)))]
9381 && ix86_match_ccmode (insn, CCNOmode)
9382 && ix86_binary_operator_ok (IOR, DImode, operands)"
9383 "or{q}\t{%2, %0|%0, %2}"
9384 [(set_attr "type" "alu")
9385 (set_attr "mode" "DI")])
9387 (define_insn "*iordi_3_rex64"
9388 [(set (reg FLAGS_REG)
9389 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9390 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9392 (clobber (match_scratch:DI 0 "=r"))]
9394 && ix86_match_ccmode (insn, CCNOmode)
9395 && ix86_binary_operator_ok (IOR, DImode, operands)"
9396 "or{q}\t{%2, %0|%0, %2}"
9397 [(set_attr "type" "alu")
9398 (set_attr "mode" "DI")])
9401 (define_expand "iorsi3"
9402 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9403 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9404 (match_operand:SI 2 "general_operand" "")))
9405 (clobber (reg:CC FLAGS_REG))]
9407 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9409 (define_insn "*iorsi_1"
9410 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9411 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9412 (match_operand:SI 2 "general_operand" "ri,g")))
9413 (clobber (reg:CC FLAGS_REG))]
9414 "ix86_binary_operator_ok (IOR, SImode, operands)"
9415 "or{l}\t{%2, %0|%0, %2}"
9416 [(set_attr "type" "alu")
9417 (set_attr "mode" "SI")])
9419 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9420 (define_insn "*iorsi_1_zext"
9421 [(set (match_operand:DI 0 "register_operand" "=r")
9423 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9424 (match_operand:SI 2 "general_operand" "g"))))
9425 (clobber (reg:CC FLAGS_REG))]
9426 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9427 "or{l}\t{%2, %k0|%k0, %2}"
9428 [(set_attr "type" "alu")
9429 (set_attr "mode" "SI")])
9431 (define_insn "*iorsi_1_zext_imm"
9432 [(set (match_operand:DI 0 "register_operand" "=r")
9433 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9434 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9435 (clobber (reg:CC FLAGS_REG))]
9437 "or{l}\t{%2, %k0|%k0, %2}"
9438 [(set_attr "type" "alu")
9439 (set_attr "mode" "SI")])
9441 (define_insn "*iorsi_2"
9442 [(set (reg FLAGS_REG)
9443 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9444 (match_operand:SI 2 "general_operand" "g,ri"))
9446 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9447 (ior:SI (match_dup 1) (match_dup 2)))]
9448 "ix86_match_ccmode (insn, CCNOmode)
9449 && ix86_binary_operator_ok (IOR, SImode, operands)"
9450 "or{l}\t{%2, %0|%0, %2}"
9451 [(set_attr "type" "alu")
9452 (set_attr "mode" "SI")])
9454 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9455 ;; ??? Special case for immediate operand is missing - it is tricky.
9456 (define_insn "*iorsi_2_zext"
9457 [(set (reg FLAGS_REG)
9458 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9459 (match_operand:SI 2 "general_operand" "g"))
9461 (set (match_operand:DI 0 "register_operand" "=r")
9462 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9463 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9464 && ix86_binary_operator_ok (IOR, SImode, operands)"
9465 "or{l}\t{%2, %k0|%k0, %2}"
9466 [(set_attr "type" "alu")
9467 (set_attr "mode" "SI")])
9469 (define_insn "*iorsi_2_zext_imm"
9470 [(set (reg FLAGS_REG)
9471 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9472 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9474 (set (match_operand:DI 0 "register_operand" "=r")
9475 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9476 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9477 && ix86_binary_operator_ok (IOR, SImode, operands)"
9478 "or{l}\t{%2, %k0|%k0, %2}"
9479 [(set_attr "type" "alu")
9480 (set_attr "mode" "SI")])
9482 (define_insn "*iorsi_3"
9483 [(set (reg FLAGS_REG)
9484 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9485 (match_operand:SI 2 "general_operand" "g"))
9487 (clobber (match_scratch:SI 0 "=r"))]
9488 "ix86_match_ccmode (insn, CCNOmode)
9489 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9490 "or{l}\t{%2, %0|%0, %2}"
9491 [(set_attr "type" "alu")
9492 (set_attr "mode" "SI")])
9494 (define_expand "iorhi3"
9495 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9496 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9497 (match_operand:HI 2 "general_operand" "")))
9498 (clobber (reg:CC FLAGS_REG))]
9499 "TARGET_HIMODE_MATH"
9500 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9502 (define_insn "*iorhi_1"
9503 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9504 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9505 (match_operand:HI 2 "general_operand" "g,ri")))
9506 (clobber (reg:CC FLAGS_REG))]
9507 "ix86_binary_operator_ok (IOR, HImode, operands)"
9508 "or{w}\t{%2, %0|%0, %2}"
9509 [(set_attr "type" "alu")
9510 (set_attr "mode" "HI")])
9512 (define_insn "*iorhi_2"
9513 [(set (reg FLAGS_REG)
9514 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9515 (match_operand:HI 2 "general_operand" "g,ri"))
9517 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9518 (ior:HI (match_dup 1) (match_dup 2)))]
9519 "ix86_match_ccmode (insn, CCNOmode)
9520 && ix86_binary_operator_ok (IOR, HImode, operands)"
9521 "or{w}\t{%2, %0|%0, %2}"
9522 [(set_attr "type" "alu")
9523 (set_attr "mode" "HI")])
9525 (define_insn "*iorhi_3"
9526 [(set (reg FLAGS_REG)
9527 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9528 (match_operand:HI 2 "general_operand" "g"))
9530 (clobber (match_scratch:HI 0 "=r"))]
9531 "ix86_match_ccmode (insn, CCNOmode)
9532 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9533 "or{w}\t{%2, %0|%0, %2}"
9534 [(set_attr "type" "alu")
9535 (set_attr "mode" "HI")])
9537 (define_expand "iorqi3"
9538 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9539 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9540 (match_operand:QI 2 "general_operand" "")))
9541 (clobber (reg:CC FLAGS_REG))]
9542 "TARGET_QIMODE_MATH"
9543 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9545 ;; %%% Potential partial reg stall on alternative 2. What to do?
9546 (define_insn "*iorqi_1"
9547 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9548 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9549 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9550 (clobber (reg:CC FLAGS_REG))]
9551 "ix86_binary_operator_ok (IOR, QImode, operands)"
9553 or{b}\t{%2, %0|%0, %2}
9554 or{b}\t{%2, %0|%0, %2}
9555 or{l}\t{%k2, %k0|%k0, %k2}"
9556 [(set_attr "type" "alu")
9557 (set_attr "mode" "QI,QI,SI")])
9559 (define_insn "*iorqi_1_slp"
9560 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9561 (ior:QI (match_dup 0)
9562 (match_operand:QI 1 "general_operand" "qmi,qi")))
9563 (clobber (reg:CC FLAGS_REG))]
9564 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9565 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9566 "or{b}\t{%1, %0|%0, %1}"
9567 [(set_attr "type" "alu1")
9568 (set_attr "mode" "QI")])
9570 (define_insn "*iorqi_2"
9571 [(set (reg FLAGS_REG)
9572 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9573 (match_operand:QI 2 "general_operand" "qim,qi"))
9575 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9576 (ior:QI (match_dup 1) (match_dup 2)))]
9577 "ix86_match_ccmode (insn, CCNOmode)
9578 && ix86_binary_operator_ok (IOR, QImode, operands)"
9579 "or{b}\t{%2, %0|%0, %2}"
9580 [(set_attr "type" "alu")
9581 (set_attr "mode" "QI")])
9583 (define_insn "*iorqi_2_slp"
9584 [(set (reg FLAGS_REG)
9585 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9586 (match_operand:QI 1 "general_operand" "qim,qi"))
9588 (set (strict_low_part (match_dup 0))
9589 (ior:QI (match_dup 0) (match_dup 1)))]
9590 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9591 && ix86_match_ccmode (insn, CCNOmode)
9592 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9593 "or{b}\t{%1, %0|%0, %1}"
9594 [(set_attr "type" "alu1")
9595 (set_attr "mode" "QI")])
9597 (define_insn "*iorqi_3"
9598 [(set (reg FLAGS_REG)
9599 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9600 (match_operand:QI 2 "general_operand" "qim"))
9602 (clobber (match_scratch:QI 0 "=q"))]
9603 "ix86_match_ccmode (insn, CCNOmode)
9604 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9605 "or{b}\t{%2, %0|%0, %2}"
9606 [(set_attr "type" "alu")
9607 (set_attr "mode" "QI")])
9609 (define_insn "iorqi_ext_0"
9610 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9615 (match_operand 1 "ext_register_operand" "0")
9618 (match_operand 2 "const_int_operand" "n")))
9619 (clobber (reg:CC FLAGS_REG))]
9620 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9621 "or{b}\t{%2, %h0|%h0, %2}"
9622 [(set_attr "type" "alu")
9623 (set_attr "length_immediate" "1")
9624 (set_attr "mode" "QI")])
9626 (define_insn "*iorqi_ext_1"
9627 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9632 (match_operand 1 "ext_register_operand" "0")
9636 (match_operand:QI 2 "general_operand" "Qm"))))
9637 (clobber (reg:CC FLAGS_REG))]
9639 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9640 "or{b}\t{%2, %h0|%h0, %2}"
9641 [(set_attr "type" "alu")
9642 (set_attr "length_immediate" "0")
9643 (set_attr "mode" "QI")])
9645 (define_insn "*iorqi_ext_1_rex64"
9646 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9651 (match_operand 1 "ext_register_operand" "0")
9655 (match_operand 2 "ext_register_operand" "Q"))))
9656 (clobber (reg:CC FLAGS_REG))]
9658 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9659 "or{b}\t{%2, %h0|%h0, %2}"
9660 [(set_attr "type" "alu")
9661 (set_attr "length_immediate" "0")
9662 (set_attr "mode" "QI")])
9664 (define_insn "*iorqi_ext_2"
9665 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9669 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9672 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9675 (clobber (reg:CC FLAGS_REG))]
9676 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9677 "ior{b}\t{%h2, %h0|%h0, %h2}"
9678 [(set_attr "type" "alu")
9679 (set_attr "length_immediate" "0")
9680 (set_attr "mode" "QI")])
9683 [(set (match_operand 0 "register_operand" "")
9684 (ior (match_operand 1 "register_operand" "")
9685 (match_operand 2 "const_int_operand" "")))
9686 (clobber (reg:CC FLAGS_REG))]
9688 && QI_REG_P (operands[0])
9689 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9690 && !(INTVAL (operands[2]) & ~(255 << 8))
9691 && GET_MODE (operands[0]) != QImode"
9692 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9693 (ior:SI (zero_extract:SI (match_dup 1)
9694 (const_int 8) (const_int 8))
9696 (clobber (reg:CC FLAGS_REG))])]
9697 "operands[0] = gen_lowpart (SImode, operands[0]);
9698 operands[1] = gen_lowpart (SImode, operands[1]);
9699 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9701 ;; Since OR can be encoded with sign extended immediate, this is only
9702 ;; profitable when 7th bit is set.
9704 [(set (match_operand 0 "register_operand" "")
9705 (ior (match_operand 1 "general_operand" "")
9706 (match_operand 2 "const_int_operand" "")))
9707 (clobber (reg:CC FLAGS_REG))]
9709 && ANY_QI_REG_P (operands[0])
9710 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9711 && !(INTVAL (operands[2]) & ~255)
9712 && (INTVAL (operands[2]) & 128)
9713 && GET_MODE (operands[0]) != QImode"
9714 [(parallel [(set (strict_low_part (match_dup 0))
9715 (ior:QI (match_dup 1)
9717 (clobber (reg:CC FLAGS_REG))])]
9718 "operands[0] = gen_lowpart (QImode, operands[0]);
9719 operands[1] = gen_lowpart (QImode, operands[1]);
9720 operands[2] = gen_lowpart (QImode, operands[2]);")
9722 ;; Logical XOR instructions
9724 ;; %%% This used to optimize known byte-wide and operations to memory.
9725 ;; If this is considered useful, it should be done with splitters.
9727 (define_expand "xordi3"
9728 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9729 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9730 (match_operand:DI 2 "x86_64_general_operand" "")))
9731 (clobber (reg:CC FLAGS_REG))]
9733 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9735 (define_insn "*xordi_1_rex64"
9736 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9737 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9738 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9739 (clobber (reg:CC FLAGS_REG))]
9741 && ix86_binary_operator_ok (XOR, DImode, operands)"
9743 xor{q}\t{%2, %0|%0, %2}
9744 xor{q}\t{%2, %0|%0, %2}"
9745 [(set_attr "type" "alu")
9746 (set_attr "mode" "DI,DI")])
9748 (define_insn "*xordi_2_rex64"
9749 [(set (reg FLAGS_REG)
9750 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9751 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9753 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9754 (xor:DI (match_dup 1) (match_dup 2)))]
9756 && ix86_match_ccmode (insn, CCNOmode)
9757 && ix86_binary_operator_ok (XOR, DImode, operands)"
9759 xor{q}\t{%2, %0|%0, %2}
9760 xor{q}\t{%2, %0|%0, %2}"
9761 [(set_attr "type" "alu")
9762 (set_attr "mode" "DI,DI")])
9764 (define_insn "*xordi_3_rex64"
9765 [(set (reg FLAGS_REG)
9766 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9767 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9769 (clobber (match_scratch:DI 0 "=r"))]
9771 && ix86_match_ccmode (insn, CCNOmode)
9772 && ix86_binary_operator_ok (XOR, DImode, operands)"
9773 "xor{q}\t{%2, %0|%0, %2}"
9774 [(set_attr "type" "alu")
9775 (set_attr "mode" "DI")])
9777 (define_expand "xorsi3"
9778 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9779 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9780 (match_operand:SI 2 "general_operand" "")))
9781 (clobber (reg:CC FLAGS_REG))]
9783 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9785 (define_insn "*xorsi_1"
9786 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9787 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9788 (match_operand:SI 2 "general_operand" "ri,rm")))
9789 (clobber (reg:CC FLAGS_REG))]
9790 "ix86_binary_operator_ok (XOR, SImode, operands)"
9791 "xor{l}\t{%2, %0|%0, %2}"
9792 [(set_attr "type" "alu")
9793 (set_attr "mode" "SI")])
9795 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9796 ;; Add speccase for immediates
9797 (define_insn "*xorsi_1_zext"
9798 [(set (match_operand:DI 0 "register_operand" "=r")
9800 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9801 (match_operand:SI 2 "general_operand" "g"))))
9802 (clobber (reg:CC FLAGS_REG))]
9803 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9804 "xor{l}\t{%2, %k0|%k0, %2}"
9805 [(set_attr "type" "alu")
9806 (set_attr "mode" "SI")])
9808 (define_insn "*xorsi_1_zext_imm"
9809 [(set (match_operand:DI 0 "register_operand" "=r")
9810 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9811 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9814 "xor{l}\t{%2, %k0|%k0, %2}"
9815 [(set_attr "type" "alu")
9816 (set_attr "mode" "SI")])
9818 (define_insn "*xorsi_2"
9819 [(set (reg FLAGS_REG)
9820 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9821 (match_operand:SI 2 "general_operand" "g,ri"))
9823 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9824 (xor:SI (match_dup 1) (match_dup 2)))]
9825 "ix86_match_ccmode (insn, CCNOmode)
9826 && ix86_binary_operator_ok (XOR, SImode, operands)"
9827 "xor{l}\t{%2, %0|%0, %2}"
9828 [(set_attr "type" "alu")
9829 (set_attr "mode" "SI")])
9831 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9832 ;; ??? Special case for immediate operand is missing - it is tricky.
9833 (define_insn "*xorsi_2_zext"
9834 [(set (reg FLAGS_REG)
9835 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9836 (match_operand:SI 2 "general_operand" "g"))
9838 (set (match_operand:DI 0 "register_operand" "=r")
9839 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9840 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9841 && ix86_binary_operator_ok (XOR, SImode, operands)"
9842 "xor{l}\t{%2, %k0|%k0, %2}"
9843 [(set_attr "type" "alu")
9844 (set_attr "mode" "SI")])
9846 (define_insn "*xorsi_2_zext_imm"
9847 [(set (reg FLAGS_REG)
9848 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9849 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9851 (set (match_operand:DI 0 "register_operand" "=r")
9852 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9853 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9854 && ix86_binary_operator_ok (XOR, SImode, operands)"
9855 "xor{l}\t{%2, %k0|%k0, %2}"
9856 [(set_attr "type" "alu")
9857 (set_attr "mode" "SI")])
9859 (define_insn "*xorsi_3"
9860 [(set (reg FLAGS_REG)
9861 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9862 (match_operand:SI 2 "general_operand" "g"))
9864 (clobber (match_scratch:SI 0 "=r"))]
9865 "ix86_match_ccmode (insn, CCNOmode)
9866 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9867 "xor{l}\t{%2, %0|%0, %2}"
9868 [(set_attr "type" "alu")
9869 (set_attr "mode" "SI")])
9871 (define_expand "xorhi3"
9872 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9873 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9874 (match_operand:HI 2 "general_operand" "")))
9875 (clobber (reg:CC FLAGS_REG))]
9876 "TARGET_HIMODE_MATH"
9877 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9879 (define_insn "*xorhi_1"
9880 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9881 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9882 (match_operand:HI 2 "general_operand" "g,ri")))
9883 (clobber (reg:CC FLAGS_REG))]
9884 "ix86_binary_operator_ok (XOR, HImode, operands)"
9885 "xor{w}\t{%2, %0|%0, %2}"
9886 [(set_attr "type" "alu")
9887 (set_attr "mode" "HI")])
9889 (define_insn "*xorhi_2"
9890 [(set (reg FLAGS_REG)
9891 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9892 (match_operand:HI 2 "general_operand" "g,ri"))
9894 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9895 (xor:HI (match_dup 1) (match_dup 2)))]
9896 "ix86_match_ccmode (insn, CCNOmode)
9897 && ix86_binary_operator_ok (XOR, HImode, operands)"
9898 "xor{w}\t{%2, %0|%0, %2}"
9899 [(set_attr "type" "alu")
9900 (set_attr "mode" "HI")])
9902 (define_insn "*xorhi_3"
9903 [(set (reg FLAGS_REG)
9904 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9905 (match_operand:HI 2 "general_operand" "g"))
9907 (clobber (match_scratch:HI 0 "=r"))]
9908 "ix86_match_ccmode (insn, CCNOmode)
9909 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9910 "xor{w}\t{%2, %0|%0, %2}"
9911 [(set_attr "type" "alu")
9912 (set_attr "mode" "HI")])
9914 (define_expand "xorqi3"
9915 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9916 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9917 (match_operand:QI 2 "general_operand" "")))
9918 (clobber (reg:CC FLAGS_REG))]
9919 "TARGET_QIMODE_MATH"
9920 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9922 ;; %%% Potential partial reg stall on alternative 2. What to do?
9923 (define_insn "*xorqi_1"
9924 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9925 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9926 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9927 (clobber (reg:CC FLAGS_REG))]
9928 "ix86_binary_operator_ok (XOR, QImode, operands)"
9930 xor{b}\t{%2, %0|%0, %2}
9931 xor{b}\t{%2, %0|%0, %2}
9932 xor{l}\t{%k2, %k0|%k0, %k2}"
9933 [(set_attr "type" "alu")
9934 (set_attr "mode" "QI,QI,SI")])
9936 (define_insn "*xorqi_1_slp"
9937 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9938 (xor:QI (match_dup 0)
9939 (match_operand:QI 1 "general_operand" "qi,qmi")))
9940 (clobber (reg:CC FLAGS_REG))]
9941 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9942 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9943 "xor{b}\t{%1, %0|%0, %1}"
9944 [(set_attr "type" "alu1")
9945 (set_attr "mode" "QI")])
9947 (define_insn "xorqi_ext_0"
9948 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9953 (match_operand 1 "ext_register_operand" "0")
9956 (match_operand 2 "const_int_operand" "n")))
9957 (clobber (reg:CC FLAGS_REG))]
9958 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9959 "xor{b}\t{%2, %h0|%h0, %2}"
9960 [(set_attr "type" "alu")
9961 (set_attr "length_immediate" "1")
9962 (set_attr "mode" "QI")])
9964 (define_insn "*xorqi_ext_1"
9965 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9970 (match_operand 1 "ext_register_operand" "0")
9974 (match_operand:QI 2 "general_operand" "Qm"))))
9975 (clobber (reg:CC FLAGS_REG))]
9977 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9978 "xor{b}\t{%2, %h0|%h0, %2}"
9979 [(set_attr "type" "alu")
9980 (set_attr "length_immediate" "0")
9981 (set_attr "mode" "QI")])
9983 (define_insn "*xorqi_ext_1_rex64"
9984 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9989 (match_operand 1 "ext_register_operand" "0")
9993 (match_operand 2 "ext_register_operand" "Q"))))
9994 (clobber (reg:CC FLAGS_REG))]
9996 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9997 "xor{b}\t{%2, %h0|%h0, %2}"
9998 [(set_attr "type" "alu")
9999 (set_attr "length_immediate" "0")
10000 (set_attr "mode" "QI")])
10002 (define_insn "*xorqi_ext_2"
10003 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10007 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10010 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10013 (clobber (reg:CC FLAGS_REG))]
10014 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
10015 "xor{b}\t{%h2, %h0|%h0, %h2}"
10016 [(set_attr "type" "alu")
10017 (set_attr "length_immediate" "0")
10018 (set_attr "mode" "QI")])
10020 (define_insn "*xorqi_cc_1"
10021 [(set (reg FLAGS_REG)
10023 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10024 (match_operand:QI 2 "general_operand" "qim,qi"))
10026 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10027 (xor:QI (match_dup 1) (match_dup 2)))]
10028 "ix86_match_ccmode (insn, CCNOmode)
10029 && ix86_binary_operator_ok (XOR, QImode, operands)"
10030 "xor{b}\t{%2, %0|%0, %2}"
10031 [(set_attr "type" "alu")
10032 (set_attr "mode" "QI")])
10034 (define_insn "*xorqi_2_slp"
10035 [(set (reg FLAGS_REG)
10036 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10037 (match_operand:QI 1 "general_operand" "qim,qi"))
10039 (set (strict_low_part (match_dup 0))
10040 (xor:QI (match_dup 0) (match_dup 1)))]
10041 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10042 && ix86_match_ccmode (insn, CCNOmode)
10043 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10044 "xor{b}\t{%1, %0|%0, %1}"
10045 [(set_attr "type" "alu1")
10046 (set_attr "mode" "QI")])
10048 (define_insn "*xorqi_cc_2"
10049 [(set (reg FLAGS_REG)
10051 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10052 (match_operand:QI 2 "general_operand" "qim"))
10054 (clobber (match_scratch:QI 0 "=q"))]
10055 "ix86_match_ccmode (insn, CCNOmode)
10056 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10057 "xor{b}\t{%2, %0|%0, %2}"
10058 [(set_attr "type" "alu")
10059 (set_attr "mode" "QI")])
10061 (define_insn "*xorqi_cc_ext_1"
10062 [(set (reg FLAGS_REG)
10066 (match_operand 1 "ext_register_operand" "0")
10069 (match_operand:QI 2 "general_operand" "qmn"))
10071 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10075 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10077 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10078 "xor{b}\t{%2, %h0|%h0, %2}"
10079 [(set_attr "type" "alu")
10080 (set_attr "mode" "QI")])
10082 (define_insn "*xorqi_cc_ext_1_rex64"
10083 [(set (reg FLAGS_REG)
10087 (match_operand 1 "ext_register_operand" "0")
10090 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10092 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10096 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10098 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10099 "xor{b}\t{%2, %h0|%h0, %2}"
10100 [(set_attr "type" "alu")
10101 (set_attr "mode" "QI")])
10103 (define_expand "xorqi_cc_ext_1"
10105 (set (reg:CCNO FLAGS_REG)
10109 (match_operand 1 "ext_register_operand" "")
10112 (match_operand:QI 2 "general_operand" ""))
10114 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10118 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10124 [(set (match_operand 0 "register_operand" "")
10125 (xor (match_operand 1 "register_operand" "")
10126 (match_operand 2 "const_int_operand" "")))
10127 (clobber (reg:CC FLAGS_REG))]
10129 && QI_REG_P (operands[0])
10130 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10131 && !(INTVAL (operands[2]) & ~(255 << 8))
10132 && GET_MODE (operands[0]) != QImode"
10133 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10134 (xor:SI (zero_extract:SI (match_dup 1)
10135 (const_int 8) (const_int 8))
10137 (clobber (reg:CC FLAGS_REG))])]
10138 "operands[0] = gen_lowpart (SImode, operands[0]);
10139 operands[1] = gen_lowpart (SImode, operands[1]);
10140 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10142 ;; Since XOR can be encoded with sign extended immediate, this is only
10143 ;; profitable when 7th bit is set.
10145 [(set (match_operand 0 "register_operand" "")
10146 (xor (match_operand 1 "general_operand" "")
10147 (match_operand 2 "const_int_operand" "")))
10148 (clobber (reg:CC FLAGS_REG))]
10150 && ANY_QI_REG_P (operands[0])
10151 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10152 && !(INTVAL (operands[2]) & ~255)
10153 && (INTVAL (operands[2]) & 128)
10154 && GET_MODE (operands[0]) != QImode"
10155 [(parallel [(set (strict_low_part (match_dup 0))
10156 (xor:QI (match_dup 1)
10158 (clobber (reg:CC FLAGS_REG))])]
10159 "operands[0] = gen_lowpart (QImode, operands[0]);
10160 operands[1] = gen_lowpart (QImode, operands[1]);
10161 operands[2] = gen_lowpart (QImode, operands[2]);")
10163 ;; Negation instructions
10165 (define_expand "negti2"
10166 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10167 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10168 (clobber (reg:CC FLAGS_REG))])]
10170 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10172 (define_insn "*negti2_1"
10173 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10174 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10175 (clobber (reg:CC FLAGS_REG))]
10177 && ix86_unary_operator_ok (NEG, TImode, operands)"
10181 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10182 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10183 (clobber (reg:CC FLAGS_REG))]
10184 "TARGET_64BIT && reload_completed"
10186 [(set (reg:CCZ FLAGS_REG)
10187 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10188 (set (match_dup 0) (neg:DI (match_dup 1)))])
10190 [(set (match_dup 2)
10191 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10194 (clobber (reg:CC FLAGS_REG))])
10196 [(set (match_dup 2)
10197 (neg:DI (match_dup 2)))
10198 (clobber (reg:CC FLAGS_REG))])]
10199 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10201 (define_expand "negdi2"
10202 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10203 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10204 (clobber (reg:CC FLAGS_REG))])]
10206 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10208 (define_insn "*negdi2_1"
10209 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10210 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10211 (clobber (reg:CC FLAGS_REG))]
10213 && ix86_unary_operator_ok (NEG, DImode, operands)"
10217 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10218 (neg:DI (match_operand:DI 1 "general_operand" "")))
10219 (clobber (reg:CC FLAGS_REG))]
10220 "!TARGET_64BIT && reload_completed"
10222 [(set (reg:CCZ FLAGS_REG)
10223 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10224 (set (match_dup 0) (neg:SI (match_dup 1)))])
10226 [(set (match_dup 2)
10227 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10230 (clobber (reg:CC FLAGS_REG))])
10232 [(set (match_dup 2)
10233 (neg:SI (match_dup 2)))
10234 (clobber (reg:CC FLAGS_REG))])]
10235 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10237 (define_insn "*negdi2_1_rex64"
10238 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10239 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10240 (clobber (reg:CC FLAGS_REG))]
10241 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10243 [(set_attr "type" "negnot")
10244 (set_attr "mode" "DI")])
10246 ;; The problem with neg is that it does not perform (compare x 0),
10247 ;; it really performs (compare 0 x), which leaves us with the zero
10248 ;; flag being the only useful item.
10250 (define_insn "*negdi2_cmpz_rex64"
10251 [(set (reg:CCZ FLAGS_REG)
10252 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10254 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10255 (neg:DI (match_dup 1)))]
10256 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10258 [(set_attr "type" "negnot")
10259 (set_attr "mode" "DI")])
10262 (define_expand "negsi2"
10263 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10264 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10265 (clobber (reg:CC FLAGS_REG))])]
10267 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10269 (define_insn "*negsi2_1"
10270 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10271 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10272 (clobber (reg:CC FLAGS_REG))]
10273 "ix86_unary_operator_ok (NEG, SImode, operands)"
10275 [(set_attr "type" "negnot")
10276 (set_attr "mode" "SI")])
10278 ;; Combine is quite creative about this pattern.
10279 (define_insn "*negsi2_1_zext"
10280 [(set (match_operand:DI 0 "register_operand" "=r")
10281 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10284 (clobber (reg:CC FLAGS_REG))]
10285 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10287 [(set_attr "type" "negnot")
10288 (set_attr "mode" "SI")])
10290 ;; The problem with neg is that it does not perform (compare x 0),
10291 ;; it really performs (compare 0 x), which leaves us with the zero
10292 ;; flag being the only useful item.
10294 (define_insn "*negsi2_cmpz"
10295 [(set (reg:CCZ FLAGS_REG)
10296 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10298 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10299 (neg:SI (match_dup 1)))]
10300 "ix86_unary_operator_ok (NEG, SImode, operands)"
10302 [(set_attr "type" "negnot")
10303 (set_attr "mode" "SI")])
10305 (define_insn "*negsi2_cmpz_zext"
10306 [(set (reg:CCZ FLAGS_REG)
10307 (compare:CCZ (lshiftrt:DI
10309 (match_operand:DI 1 "register_operand" "0")
10313 (set (match_operand:DI 0 "register_operand" "=r")
10314 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10317 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10319 [(set_attr "type" "negnot")
10320 (set_attr "mode" "SI")])
10322 (define_expand "neghi2"
10323 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10324 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10325 (clobber (reg:CC FLAGS_REG))])]
10326 "TARGET_HIMODE_MATH"
10327 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10329 (define_insn "*neghi2_1"
10330 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10331 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10332 (clobber (reg:CC FLAGS_REG))]
10333 "ix86_unary_operator_ok (NEG, HImode, operands)"
10335 [(set_attr "type" "negnot")
10336 (set_attr "mode" "HI")])
10338 (define_insn "*neghi2_cmpz"
10339 [(set (reg:CCZ FLAGS_REG)
10340 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10342 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10343 (neg:HI (match_dup 1)))]
10344 "ix86_unary_operator_ok (NEG, HImode, operands)"
10346 [(set_attr "type" "negnot")
10347 (set_attr "mode" "HI")])
10349 (define_expand "negqi2"
10350 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10351 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10352 (clobber (reg:CC FLAGS_REG))])]
10353 "TARGET_QIMODE_MATH"
10354 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10356 (define_insn "*negqi2_1"
10357 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10358 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10359 (clobber (reg:CC FLAGS_REG))]
10360 "ix86_unary_operator_ok (NEG, QImode, operands)"
10362 [(set_attr "type" "negnot")
10363 (set_attr "mode" "QI")])
10365 (define_insn "*negqi2_cmpz"
10366 [(set (reg:CCZ FLAGS_REG)
10367 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10369 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10370 (neg:QI (match_dup 1)))]
10371 "ix86_unary_operator_ok (NEG, QImode, operands)"
10373 [(set_attr "type" "negnot")
10374 (set_attr "mode" "QI")])
10376 ;; Changing of sign for FP values is doable using integer unit too.
10378 (define_expand "<code><mode>2"
10379 [(set (match_operand:X87MODEF 0 "register_operand" "")
10380 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10381 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10382 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10384 (define_insn "*absneg<mode>2_mixed"
10385 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10386 (match_operator:MODEF 3 "absneg_operator"
10387 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10388 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10393 (define_insn "*absneg<mode>2_sse"
10394 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10395 (match_operator:MODEF 3 "absneg_operator"
10396 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10397 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10398 (clobber (reg:CC FLAGS_REG))]
10399 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10402 (define_insn "*absneg<mode>2_i387"
10403 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10404 (match_operator:X87MODEF 3 "absneg_operator"
10405 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10406 (use (match_operand 2 "" ""))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10411 (define_expand "<code>tf2"
10412 [(set (match_operand:TF 0 "register_operand" "")
10413 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10415 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10417 (define_insn "*absnegtf2_sse"
10418 [(set (match_operand:TF 0 "register_operand" "=x,x")
10419 (match_operator:TF 3 "absneg_operator"
10420 [(match_operand:TF 1 "register_operand" "0,x")]))
10421 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10422 (clobber (reg:CC FLAGS_REG))]
10426 ;; Splitters for fp abs and neg.
10429 [(set (match_operand 0 "fp_register_operand" "")
10430 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10431 (use (match_operand 2 "" ""))
10432 (clobber (reg:CC FLAGS_REG))]
10434 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10437 [(set (match_operand 0 "register_operand" "")
10438 (match_operator 3 "absneg_operator"
10439 [(match_operand 1 "register_operand" "")]))
10440 (use (match_operand 2 "nonimmediate_operand" ""))
10441 (clobber (reg:CC FLAGS_REG))]
10442 "reload_completed && SSE_REG_P (operands[0])"
10443 [(set (match_dup 0) (match_dup 3))]
10445 enum machine_mode mode = GET_MODE (operands[0]);
10446 enum machine_mode vmode = GET_MODE (operands[2]);
10449 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10450 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10451 if (operands_match_p (operands[0], operands[2]))
10454 operands[1] = operands[2];
10457 if (GET_CODE (operands[3]) == ABS)
10458 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10460 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10465 [(set (match_operand:SF 0 "register_operand" "")
10466 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10467 (use (match_operand:V4SF 2 "" ""))
10468 (clobber (reg:CC FLAGS_REG))]
10470 [(parallel [(set (match_dup 0) (match_dup 1))
10471 (clobber (reg:CC FLAGS_REG))])]
10474 operands[0] = gen_lowpart (SImode, operands[0]);
10475 if (GET_CODE (operands[1]) == ABS)
10477 tmp = gen_int_mode (0x7fffffff, SImode);
10478 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10482 tmp = gen_int_mode (0x80000000, SImode);
10483 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10489 [(set (match_operand:DF 0 "register_operand" "")
10490 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10491 (use (match_operand 2 "" ""))
10492 (clobber (reg:CC FLAGS_REG))]
10494 [(parallel [(set (match_dup 0) (match_dup 1))
10495 (clobber (reg:CC FLAGS_REG))])]
10500 tmp = gen_lowpart (DImode, operands[0]);
10501 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10504 if (GET_CODE (operands[1]) == ABS)
10507 tmp = gen_rtx_NOT (DImode, tmp);
10511 operands[0] = gen_highpart (SImode, operands[0]);
10512 if (GET_CODE (operands[1]) == ABS)
10514 tmp = gen_int_mode (0x7fffffff, SImode);
10515 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10519 tmp = gen_int_mode (0x80000000, SImode);
10520 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10527 [(set (match_operand:XF 0 "register_operand" "")
10528 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10529 (use (match_operand 2 "" ""))
10530 (clobber (reg:CC FLAGS_REG))]
10532 [(parallel [(set (match_dup 0) (match_dup 1))
10533 (clobber (reg:CC FLAGS_REG))])]
10536 operands[0] = gen_rtx_REG (SImode,
10537 true_regnum (operands[0])
10538 + (TARGET_64BIT ? 1 : 2));
10539 if (GET_CODE (operands[1]) == ABS)
10541 tmp = GEN_INT (0x7fff);
10542 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10546 tmp = GEN_INT (0x8000);
10547 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10552 ;; Conditionalize these after reload. If they match before reload, we
10553 ;; lose the clobber and ability to use integer instructions.
10555 (define_insn "*<code><mode>2_1"
10556 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10557 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10559 && (reload_completed
10560 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10562 [(set_attr "type" "fsgn")
10563 (set_attr "mode" "<MODE>")])
10565 (define_insn "*<code>extendsfdf2"
10566 [(set (match_operand:DF 0 "register_operand" "=f")
10567 (absneg:DF (float_extend:DF
10568 (match_operand:SF 1 "register_operand" "0"))))]
10569 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10571 [(set_attr "type" "fsgn")
10572 (set_attr "mode" "DF")])
10574 (define_insn "*<code>extendsfxf2"
10575 [(set (match_operand:XF 0 "register_operand" "=f")
10576 (absneg:XF (float_extend:XF
10577 (match_operand:SF 1 "register_operand" "0"))))]
10580 [(set_attr "type" "fsgn")
10581 (set_attr "mode" "XF")])
10583 (define_insn "*<code>extenddfxf2"
10584 [(set (match_operand:XF 0 "register_operand" "=f")
10585 (absneg:XF (float_extend:XF
10586 (match_operand:DF 1 "register_operand" "0"))))]
10589 [(set_attr "type" "fsgn")
10590 (set_attr "mode" "XF")])
10592 ;; Copysign instructions
10594 (define_mode_iterator CSGNMODE [SF DF TF])
10595 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10597 (define_expand "copysign<mode>3"
10598 [(match_operand:CSGNMODE 0 "register_operand" "")
10599 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10600 (match_operand:CSGNMODE 2 "register_operand" "")]
10601 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10602 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10604 ix86_expand_copysign (operands);
10608 (define_insn_and_split "copysign<mode>3_const"
10609 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10611 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10612 (match_operand:CSGNMODE 2 "register_operand" "0")
10613 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10615 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10616 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10618 "&& reload_completed"
10621 ix86_split_copysign_const (operands);
10625 (define_insn "copysign<mode>3_var"
10626 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10628 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10629 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10630 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10631 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10633 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10634 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10635 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10639 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10641 [(match_operand:CSGNMODE 2 "register_operand" "")
10642 (match_operand:CSGNMODE 3 "register_operand" "")
10643 (match_operand:<CSGNVMODE> 4 "" "")
10644 (match_operand:<CSGNVMODE> 5 "" "")]
10646 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10647 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10648 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10649 && reload_completed"
10652 ix86_split_copysign_var (operands);
10656 ;; One complement instructions
10658 (define_expand "one_cmpldi2"
10659 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10660 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10662 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10664 (define_insn "*one_cmpldi2_1_rex64"
10665 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10666 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10667 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10669 [(set_attr "type" "negnot")
10670 (set_attr "mode" "DI")])
10672 (define_insn "*one_cmpldi2_2_rex64"
10673 [(set (reg FLAGS_REG)
10674 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10676 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10677 (not:DI (match_dup 1)))]
10678 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10679 && ix86_unary_operator_ok (NOT, DImode, operands)"
10681 [(set_attr "type" "alu1")
10682 (set_attr "mode" "DI")])
10685 [(set (match_operand 0 "flags_reg_operand" "")
10686 (match_operator 2 "compare_operator"
10687 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10689 (set (match_operand:DI 1 "nonimmediate_operand" "")
10690 (not:DI (match_dup 3)))]
10691 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10692 [(parallel [(set (match_dup 0)
10694 [(xor:DI (match_dup 3) (const_int -1))
10697 (xor:DI (match_dup 3) (const_int -1)))])]
10700 (define_expand "one_cmplsi2"
10701 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10702 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10704 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10706 (define_insn "*one_cmplsi2_1"
10707 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10708 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10709 "ix86_unary_operator_ok (NOT, SImode, operands)"
10711 [(set_attr "type" "negnot")
10712 (set_attr "mode" "SI")])
10714 ;; ??? Currently never generated - xor is used instead.
10715 (define_insn "*one_cmplsi2_1_zext"
10716 [(set (match_operand:DI 0 "register_operand" "=r")
10717 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10718 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10720 [(set_attr "type" "negnot")
10721 (set_attr "mode" "SI")])
10723 (define_insn "*one_cmplsi2_2"
10724 [(set (reg FLAGS_REG)
10725 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10727 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10728 (not:SI (match_dup 1)))]
10729 "ix86_match_ccmode (insn, CCNOmode)
10730 && ix86_unary_operator_ok (NOT, SImode, operands)"
10732 [(set_attr "type" "alu1")
10733 (set_attr "mode" "SI")])
10736 [(set (match_operand 0 "flags_reg_operand" "")
10737 (match_operator 2 "compare_operator"
10738 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10740 (set (match_operand:SI 1 "nonimmediate_operand" "")
10741 (not:SI (match_dup 3)))]
10742 "ix86_match_ccmode (insn, CCNOmode)"
10743 [(parallel [(set (match_dup 0)
10744 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10747 (xor:SI (match_dup 3) (const_int -1)))])]
10750 ;; ??? Currently never generated - xor is used instead.
10751 (define_insn "*one_cmplsi2_2_zext"
10752 [(set (reg FLAGS_REG)
10753 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10755 (set (match_operand:DI 0 "register_operand" "=r")
10756 (zero_extend:DI (not:SI (match_dup 1))))]
10757 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10758 && ix86_unary_operator_ok (NOT, SImode, operands)"
10760 [(set_attr "type" "alu1")
10761 (set_attr "mode" "SI")])
10764 [(set (match_operand 0 "flags_reg_operand" "")
10765 (match_operator 2 "compare_operator"
10766 [(not:SI (match_operand:SI 3 "register_operand" ""))
10768 (set (match_operand:DI 1 "register_operand" "")
10769 (zero_extend:DI (not:SI (match_dup 3))))]
10770 "ix86_match_ccmode (insn, CCNOmode)"
10771 [(parallel [(set (match_dup 0)
10772 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10775 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10778 (define_expand "one_cmplhi2"
10779 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10780 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10781 "TARGET_HIMODE_MATH"
10782 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10784 (define_insn "*one_cmplhi2_1"
10785 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10786 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10787 "ix86_unary_operator_ok (NOT, HImode, operands)"
10789 [(set_attr "type" "negnot")
10790 (set_attr "mode" "HI")])
10792 (define_insn "*one_cmplhi2_2"
10793 [(set (reg FLAGS_REG)
10794 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10796 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10797 (not:HI (match_dup 1)))]
10798 "ix86_match_ccmode (insn, CCNOmode)
10799 && ix86_unary_operator_ok (NEG, HImode, operands)"
10801 [(set_attr "type" "alu1")
10802 (set_attr "mode" "HI")])
10805 [(set (match_operand 0 "flags_reg_operand" "")
10806 (match_operator 2 "compare_operator"
10807 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10809 (set (match_operand:HI 1 "nonimmediate_operand" "")
10810 (not:HI (match_dup 3)))]
10811 "ix86_match_ccmode (insn, CCNOmode)"
10812 [(parallel [(set (match_dup 0)
10813 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10816 (xor:HI (match_dup 3) (const_int -1)))])]
10819 ;; %%% Potential partial reg stall on alternative 1. What to do?
10820 (define_expand "one_cmplqi2"
10821 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10822 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10823 "TARGET_QIMODE_MATH"
10824 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10826 (define_insn "*one_cmplqi2_1"
10827 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10828 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10829 "ix86_unary_operator_ok (NOT, QImode, operands)"
10833 [(set_attr "type" "negnot")
10834 (set_attr "mode" "QI,SI")])
10836 (define_insn "*one_cmplqi2_2"
10837 [(set (reg FLAGS_REG)
10838 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10840 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10841 (not:QI (match_dup 1)))]
10842 "ix86_match_ccmode (insn, CCNOmode)
10843 && ix86_unary_operator_ok (NOT, QImode, operands)"
10845 [(set_attr "type" "alu1")
10846 (set_attr "mode" "QI")])
10849 [(set (match_operand 0 "flags_reg_operand" "")
10850 (match_operator 2 "compare_operator"
10851 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10853 (set (match_operand:QI 1 "nonimmediate_operand" "")
10854 (not:QI (match_dup 3)))]
10855 "ix86_match_ccmode (insn, CCNOmode)"
10856 [(parallel [(set (match_dup 0)
10857 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10860 (xor:QI (match_dup 3) (const_int -1)))])]
10863 ;; Arithmetic shift instructions
10865 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10866 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10867 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10868 ;; from the assembler input.
10870 ;; This instruction shifts the target reg/mem as usual, but instead of
10871 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10872 ;; is a left shift double, bits are taken from the high order bits of
10873 ;; reg, else if the insn is a shift right double, bits are taken from the
10874 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10875 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10877 ;; Since sh[lr]d does not change the `reg' operand, that is done
10878 ;; separately, making all shifts emit pairs of shift double and normal
10879 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10880 ;; support a 63 bit shift, each shift where the count is in a reg expands
10881 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10883 ;; If the shift count is a constant, we need never emit more than one
10884 ;; shift pair, instead using moves and sign extension for counts greater
10887 (define_expand "ashlti3"
10888 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10889 (ashift:TI (match_operand:TI 1 "register_operand" "")
10890 (match_operand:QI 2 "nonmemory_operand" "")))
10891 (clobber (reg:CC FLAGS_REG))])]
10894 if (! immediate_operand (operands[2], QImode))
10896 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10899 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10903 (define_insn "ashlti3_1"
10904 [(set (match_operand:TI 0 "register_operand" "=r")
10905 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10906 (match_operand:QI 2 "register_operand" "c")))
10907 (clobber (match_scratch:DI 3 "=&r"))
10908 (clobber (reg:CC FLAGS_REG))]
10911 [(set_attr "type" "multi")])
10913 ;; This pattern must be defined before *ashlti3_2 to prevent
10914 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10916 (define_insn "sse2_ashlti3"
10917 [(set (match_operand:TI 0 "register_operand" "=x")
10918 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10919 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10922 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10923 return "pslldq\t{%2, %0|%0, %2}";
10925 [(set_attr "type" "sseishft")
10926 (set_attr "prefix_data16" "1")
10927 (set_attr "mode" "TI")])
10929 (define_insn "*ashlti3_2"
10930 [(set (match_operand:TI 0 "register_operand" "=r")
10931 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10932 (match_operand:QI 2 "immediate_operand" "O")))
10933 (clobber (reg:CC FLAGS_REG))]
10936 [(set_attr "type" "multi")])
10939 [(set (match_operand:TI 0 "register_operand" "")
10940 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10941 (match_operand:QI 2 "register_operand" "")))
10942 (clobber (match_scratch:DI 3 ""))
10943 (clobber (reg:CC FLAGS_REG))]
10944 "TARGET_64BIT && reload_completed"
10946 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10949 [(set (match_operand:TI 0 "register_operand" "")
10950 (ashift:TI (match_operand:TI 1 "register_operand" "")
10951 (match_operand:QI 2 "immediate_operand" "")))
10952 (clobber (reg:CC FLAGS_REG))]
10953 "TARGET_64BIT && reload_completed"
10955 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10957 (define_insn "x86_64_shld"
10958 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10959 (ior:DI (ashift:DI (match_dup 0)
10960 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10961 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10962 (minus:QI (const_int 64) (match_dup 2)))))
10963 (clobber (reg:CC FLAGS_REG))]
10966 shld{q}\t{%2, %1, %0|%0, %1, %2}
10967 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10968 [(set_attr "type" "ishift")
10969 (set_attr "prefix_0f" "1")
10970 (set_attr "mode" "DI")
10971 (set_attr "athlon_decode" "vector")
10972 (set_attr "amdfam10_decode" "vector")])
10974 (define_expand "x86_64_shift_adj"
10975 [(set (reg:CCZ FLAGS_REG)
10976 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10979 (set (match_operand:DI 0 "register_operand" "")
10980 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10981 (match_operand:DI 1 "register_operand" "")
10984 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10985 (match_operand:DI 3 "register_operand" "r")
10990 (define_expand "ashldi3"
10991 [(set (match_operand:DI 0 "shiftdi_operand" "")
10992 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10993 (match_operand:QI 2 "nonmemory_operand" "")))]
10995 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10997 (define_insn "*ashldi3_1_rex64"
10998 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10999 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11000 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11001 (clobber (reg:CC FLAGS_REG))]
11002 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11004 switch (get_attr_type (insn))
11007 gcc_assert (operands[2] == const1_rtx);
11008 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11009 return "add{q}\t%0, %0";
11012 gcc_assert (CONST_INT_P (operands[2]));
11013 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11014 operands[1] = gen_rtx_MULT (DImode, operands[1],
11015 GEN_INT (1 << INTVAL (operands[2])));
11016 return "lea{q}\t{%a1, %0|%0, %a1}";
11019 if (REG_P (operands[2]))
11020 return "sal{q}\t{%b2, %0|%0, %b2}";
11021 else if (operands[2] == const1_rtx
11022 && (TARGET_SHIFT1 || optimize_size))
11023 return "sal{q}\t%0";
11025 return "sal{q}\t{%2, %0|%0, %2}";
11028 [(set (attr "type")
11029 (cond [(eq_attr "alternative" "1")
11030 (const_string "lea")
11031 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11033 (match_operand 0 "register_operand" ""))
11034 (match_operand 2 "const1_operand" ""))
11035 (const_string "alu")
11037 (const_string "ishift")))
11038 (set_attr "mode" "DI")])
11040 ;; Convert lea to the lea pattern to avoid flags dependency.
11042 [(set (match_operand:DI 0 "register_operand" "")
11043 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11044 (match_operand:QI 2 "immediate_operand" "")))
11045 (clobber (reg:CC FLAGS_REG))]
11046 "TARGET_64BIT && reload_completed
11047 && true_regnum (operands[0]) != true_regnum (operands[1])"
11048 [(set (match_dup 0)
11049 (mult:DI (match_dup 1)
11051 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11053 ;; This pattern can't accept a variable shift count, since shifts by
11054 ;; zero don't affect the flags. We assume that shifts by constant
11055 ;; zero are optimized away.
11056 (define_insn "*ashldi3_cmp_rex64"
11057 [(set (reg FLAGS_REG)
11059 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11060 (match_operand:QI 2 "immediate_operand" "e"))
11062 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11063 (ashift:DI (match_dup 1) (match_dup 2)))]
11066 || !TARGET_PARTIAL_FLAG_REG_STALL
11067 || (operands[2] == const1_rtx
11069 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11070 && ix86_match_ccmode (insn, CCGOCmode)
11071 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11073 switch (get_attr_type (insn))
11076 gcc_assert (operands[2] == const1_rtx);
11077 return "add{q}\t%0, %0";
11080 if (REG_P (operands[2]))
11081 return "sal{q}\t{%b2, %0|%0, %b2}";
11082 else if (operands[2] == const1_rtx
11083 && (TARGET_SHIFT1 || optimize_size))
11084 return "sal{q}\t%0";
11086 return "sal{q}\t{%2, %0|%0, %2}";
11089 [(set (attr "type")
11090 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11092 (match_operand 0 "register_operand" ""))
11093 (match_operand 2 "const1_operand" ""))
11094 (const_string "alu")
11096 (const_string "ishift")))
11097 (set_attr "mode" "DI")])
11099 (define_insn "*ashldi3_cconly_rex64"
11100 [(set (reg FLAGS_REG)
11102 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11103 (match_operand:QI 2 "immediate_operand" "e"))
11105 (clobber (match_scratch:DI 0 "=r"))]
11108 || !TARGET_PARTIAL_FLAG_REG_STALL
11109 || (operands[2] == const1_rtx
11111 || TARGET_DOUBLE_WITH_ADD)))
11112 && ix86_match_ccmode (insn, CCGOCmode)
11113 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11115 switch (get_attr_type (insn))
11118 gcc_assert (operands[2] == const1_rtx);
11119 return "add{q}\t%0, %0";
11122 if (REG_P (operands[2]))
11123 return "sal{q}\t{%b2, %0|%0, %b2}";
11124 else if (operands[2] == const1_rtx
11125 && (TARGET_SHIFT1 || optimize_size))
11126 return "sal{q}\t%0";
11128 return "sal{q}\t{%2, %0|%0, %2}";
11131 [(set (attr "type")
11132 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11134 (match_operand 0 "register_operand" ""))
11135 (match_operand 2 "const1_operand" ""))
11136 (const_string "alu")
11138 (const_string "ishift")))
11139 (set_attr "mode" "DI")])
11141 (define_insn "*ashldi3_1"
11142 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11143 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11144 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11145 (clobber (reg:CC FLAGS_REG))]
11148 [(set_attr "type" "multi")])
11150 ;; By default we don't ask for a scratch register, because when DImode
11151 ;; values are manipulated, registers are already at a premium. But if
11152 ;; we have one handy, we won't turn it away.
11154 [(match_scratch:SI 3 "r")
11155 (parallel [(set (match_operand:DI 0 "register_operand" "")
11156 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11157 (match_operand:QI 2 "nonmemory_operand" "")))
11158 (clobber (reg:CC FLAGS_REG))])
11160 "!TARGET_64BIT && TARGET_CMOVE"
11162 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11165 [(set (match_operand:DI 0 "register_operand" "")
11166 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11167 (match_operand:QI 2 "nonmemory_operand" "")))
11168 (clobber (reg:CC FLAGS_REG))]
11169 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11170 ? epilogue_completed : reload_completed)"
11172 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11174 (define_insn "x86_shld_1"
11175 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11176 (ior:SI (ashift:SI (match_dup 0)
11177 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11178 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11179 (minus:QI (const_int 32) (match_dup 2)))))
11180 (clobber (reg:CC FLAGS_REG))]
11183 shld{l}\t{%2, %1, %0|%0, %1, %2}
11184 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11185 [(set_attr "type" "ishift")
11186 (set_attr "prefix_0f" "1")
11187 (set_attr "mode" "SI")
11188 (set_attr "pent_pair" "np")
11189 (set_attr "athlon_decode" "vector")
11190 (set_attr "amdfam10_decode" "vector")])
11192 (define_expand "x86_shift_adj_1"
11193 [(set (reg:CCZ FLAGS_REG)
11194 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11197 (set (match_operand:SI 0 "register_operand" "")
11198 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11199 (match_operand:SI 1 "register_operand" "")
11202 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11203 (match_operand:SI 3 "register_operand" "r")
11208 (define_expand "x86_shift_adj_2"
11209 [(use (match_operand:SI 0 "register_operand" ""))
11210 (use (match_operand:SI 1 "register_operand" ""))
11211 (use (match_operand:QI 2 "register_operand" ""))]
11214 rtx label = gen_label_rtx ();
11217 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11219 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11220 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11221 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11222 gen_rtx_LABEL_REF (VOIDmode, label),
11224 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11225 JUMP_LABEL (tmp) = label;
11227 emit_move_insn (operands[0], operands[1]);
11228 ix86_expand_clear (operands[1]);
11230 emit_label (label);
11231 LABEL_NUSES (label) = 1;
11236 (define_expand "ashlsi3"
11237 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11238 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11239 (match_operand:QI 2 "nonmemory_operand" "")))
11240 (clobber (reg:CC FLAGS_REG))]
11242 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11244 (define_insn "*ashlsi3_1"
11245 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11246 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11247 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11248 (clobber (reg:CC FLAGS_REG))]
11249 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11251 switch (get_attr_type (insn))
11254 gcc_assert (operands[2] == const1_rtx);
11255 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11256 return "add{l}\t%0, %0";
11262 if (REG_P (operands[2]))
11263 return "sal{l}\t{%b2, %0|%0, %b2}";
11264 else if (operands[2] == const1_rtx
11265 && (TARGET_SHIFT1 || optimize_size))
11266 return "sal{l}\t%0";
11268 return "sal{l}\t{%2, %0|%0, %2}";
11271 [(set (attr "type")
11272 (cond [(eq_attr "alternative" "1")
11273 (const_string "lea")
11274 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11276 (match_operand 0 "register_operand" ""))
11277 (match_operand 2 "const1_operand" ""))
11278 (const_string "alu")
11280 (const_string "ishift")))
11281 (set_attr "mode" "SI")])
11283 ;; Convert lea to the lea pattern to avoid flags dependency.
11285 [(set (match_operand 0 "register_operand" "")
11286 (ashift (match_operand 1 "index_register_operand" "")
11287 (match_operand:QI 2 "const_int_operand" "")))
11288 (clobber (reg:CC FLAGS_REG))]
11290 && true_regnum (operands[0]) != true_regnum (operands[1])
11291 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11295 enum machine_mode mode = GET_MODE (operands[0]);
11297 if (GET_MODE_SIZE (mode) < 4)
11298 operands[0] = gen_lowpart (SImode, operands[0]);
11300 operands[1] = gen_lowpart (Pmode, operands[1]);
11301 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11303 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11304 if (Pmode != SImode)
11305 pat = gen_rtx_SUBREG (SImode, pat, 0);
11306 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11310 ;; Rare case of shifting RSP is handled by generating move and shift
11312 [(set (match_operand 0 "register_operand" "")
11313 (ashift (match_operand 1 "register_operand" "")
11314 (match_operand:QI 2 "const_int_operand" "")))
11315 (clobber (reg:CC FLAGS_REG))]
11317 && true_regnum (operands[0]) != true_regnum (operands[1])"
11321 emit_move_insn (operands[0], operands[1]);
11322 pat = gen_rtx_SET (VOIDmode, operands[0],
11323 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11324 operands[0], operands[2]));
11325 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11326 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11330 (define_insn "*ashlsi3_1_zext"
11331 [(set (match_operand:DI 0 "register_operand" "=r,r")
11332 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11333 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11334 (clobber (reg:CC FLAGS_REG))]
11335 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11337 switch (get_attr_type (insn))
11340 gcc_assert (operands[2] == const1_rtx);
11341 return "add{l}\t%k0, %k0";
11347 if (REG_P (operands[2]))
11348 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11349 else if (operands[2] == const1_rtx
11350 && (TARGET_SHIFT1 || optimize_size))
11351 return "sal{l}\t%k0";
11353 return "sal{l}\t{%2, %k0|%k0, %2}";
11356 [(set (attr "type")
11357 (cond [(eq_attr "alternative" "1")
11358 (const_string "lea")
11359 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11361 (match_operand 2 "const1_operand" ""))
11362 (const_string "alu")
11364 (const_string "ishift")))
11365 (set_attr "mode" "SI")])
11367 ;; Convert lea to the lea pattern to avoid flags dependency.
11369 [(set (match_operand:DI 0 "register_operand" "")
11370 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11371 (match_operand:QI 2 "const_int_operand" ""))))
11372 (clobber (reg:CC FLAGS_REG))]
11373 "TARGET_64BIT && reload_completed
11374 && true_regnum (operands[0]) != true_regnum (operands[1])"
11375 [(set (match_dup 0) (zero_extend:DI
11376 (subreg:SI (mult:SI (match_dup 1)
11377 (match_dup 2)) 0)))]
11379 operands[1] = gen_lowpart (Pmode, operands[1]);
11380 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11383 ;; This pattern can't accept a variable shift count, since shifts by
11384 ;; zero don't affect the flags. We assume that shifts by constant
11385 ;; zero are optimized away.
11386 (define_insn "*ashlsi3_cmp"
11387 [(set (reg FLAGS_REG)
11389 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11390 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11392 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11393 (ashift:SI (match_dup 1) (match_dup 2)))]
11395 || !TARGET_PARTIAL_FLAG_REG_STALL
11396 || (operands[2] == const1_rtx
11398 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11399 && ix86_match_ccmode (insn, CCGOCmode)
11400 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11402 switch (get_attr_type (insn))
11405 gcc_assert (operands[2] == const1_rtx);
11406 return "add{l}\t%0, %0";
11409 if (REG_P (operands[2]))
11410 return "sal{l}\t{%b2, %0|%0, %b2}";
11411 else if (operands[2] == const1_rtx
11412 && (TARGET_SHIFT1 || optimize_size))
11413 return "sal{l}\t%0";
11415 return "sal{l}\t{%2, %0|%0, %2}";
11418 [(set (attr "type")
11419 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11421 (match_operand 0 "register_operand" ""))
11422 (match_operand 2 "const1_operand" ""))
11423 (const_string "alu")
11425 (const_string "ishift")))
11426 (set_attr "mode" "SI")])
11428 (define_insn "*ashlsi3_cconly"
11429 [(set (reg FLAGS_REG)
11431 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11432 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11434 (clobber (match_scratch:SI 0 "=r"))]
11436 || !TARGET_PARTIAL_FLAG_REG_STALL
11437 || (operands[2] == const1_rtx
11439 || TARGET_DOUBLE_WITH_ADD)))
11440 && ix86_match_ccmode (insn, CCGOCmode)
11441 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11443 switch (get_attr_type (insn))
11446 gcc_assert (operands[2] == const1_rtx);
11447 return "add{l}\t%0, %0";
11450 if (REG_P (operands[2]))
11451 return "sal{l}\t{%b2, %0|%0, %b2}";
11452 else if (operands[2] == const1_rtx
11453 && (TARGET_SHIFT1 || optimize_size))
11454 return "sal{l}\t%0";
11456 return "sal{l}\t{%2, %0|%0, %2}";
11459 [(set (attr "type")
11460 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11462 (match_operand 0 "register_operand" ""))
11463 (match_operand 2 "const1_operand" ""))
11464 (const_string "alu")
11466 (const_string "ishift")))
11467 (set_attr "mode" "SI")])
11469 (define_insn "*ashlsi3_cmp_zext"
11470 [(set (reg FLAGS_REG)
11472 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11473 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11475 (set (match_operand:DI 0 "register_operand" "=r")
11476 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11479 || !TARGET_PARTIAL_FLAG_REG_STALL
11480 || (operands[2] == const1_rtx
11482 || TARGET_DOUBLE_WITH_ADD)))
11483 && ix86_match_ccmode (insn, CCGOCmode)
11484 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11486 switch (get_attr_type (insn))
11489 gcc_assert (operands[2] == const1_rtx);
11490 return "add{l}\t%k0, %k0";
11493 if (REG_P (operands[2]))
11494 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11495 else if (operands[2] == const1_rtx
11496 && (TARGET_SHIFT1 || optimize_size))
11497 return "sal{l}\t%k0";
11499 return "sal{l}\t{%2, %k0|%k0, %2}";
11502 [(set (attr "type")
11503 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11505 (match_operand 2 "const1_operand" ""))
11506 (const_string "alu")
11508 (const_string "ishift")))
11509 (set_attr "mode" "SI")])
11511 (define_expand "ashlhi3"
11512 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11513 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11514 (match_operand:QI 2 "nonmemory_operand" "")))
11515 (clobber (reg:CC FLAGS_REG))]
11516 "TARGET_HIMODE_MATH"
11517 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11519 (define_insn "*ashlhi3_1_lea"
11520 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11521 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11522 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11523 (clobber (reg:CC FLAGS_REG))]
11524 "!TARGET_PARTIAL_REG_STALL
11525 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11527 switch (get_attr_type (insn))
11532 gcc_assert (operands[2] == const1_rtx);
11533 return "add{w}\t%0, %0";
11536 if (REG_P (operands[2]))
11537 return "sal{w}\t{%b2, %0|%0, %b2}";
11538 else if (operands[2] == const1_rtx
11539 && (TARGET_SHIFT1 || optimize_size))
11540 return "sal{w}\t%0";
11542 return "sal{w}\t{%2, %0|%0, %2}";
11545 [(set (attr "type")
11546 (cond [(eq_attr "alternative" "1")
11547 (const_string "lea")
11548 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11550 (match_operand 0 "register_operand" ""))
11551 (match_operand 2 "const1_operand" ""))
11552 (const_string "alu")
11554 (const_string "ishift")))
11555 (set_attr "mode" "HI,SI")])
11557 (define_insn "*ashlhi3_1"
11558 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11559 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11560 (match_operand:QI 2 "nonmemory_operand" "cI")))
11561 (clobber (reg:CC FLAGS_REG))]
11562 "TARGET_PARTIAL_REG_STALL
11563 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11565 switch (get_attr_type (insn))
11568 gcc_assert (operands[2] == const1_rtx);
11569 return "add{w}\t%0, %0";
11572 if (REG_P (operands[2]))
11573 return "sal{w}\t{%b2, %0|%0, %b2}";
11574 else if (operands[2] == const1_rtx
11575 && (TARGET_SHIFT1 || optimize_size))
11576 return "sal{w}\t%0";
11578 return "sal{w}\t{%2, %0|%0, %2}";
11581 [(set (attr "type")
11582 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11584 (match_operand 0 "register_operand" ""))
11585 (match_operand 2 "const1_operand" ""))
11586 (const_string "alu")
11588 (const_string "ishift")))
11589 (set_attr "mode" "HI")])
11591 ;; This pattern can't accept a variable shift count, since shifts by
11592 ;; zero don't affect the flags. We assume that shifts by constant
11593 ;; zero are optimized away.
11594 (define_insn "*ashlhi3_cmp"
11595 [(set (reg FLAGS_REG)
11597 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11598 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11600 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11601 (ashift:HI (match_dup 1) (match_dup 2)))]
11603 || !TARGET_PARTIAL_FLAG_REG_STALL
11604 || (operands[2] == const1_rtx
11606 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11607 && ix86_match_ccmode (insn, CCGOCmode)
11608 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11610 switch (get_attr_type (insn))
11613 gcc_assert (operands[2] == const1_rtx);
11614 return "add{w}\t%0, %0";
11617 if (REG_P (operands[2]))
11618 return "sal{w}\t{%b2, %0|%0, %b2}";
11619 else if (operands[2] == const1_rtx
11620 && (TARGET_SHIFT1 || optimize_size))
11621 return "sal{w}\t%0";
11623 return "sal{w}\t{%2, %0|%0, %2}";
11626 [(set (attr "type")
11627 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11629 (match_operand 0 "register_operand" ""))
11630 (match_operand 2 "const1_operand" ""))
11631 (const_string "alu")
11633 (const_string "ishift")))
11634 (set_attr "mode" "HI")])
11636 (define_insn "*ashlhi3_cconly"
11637 [(set (reg FLAGS_REG)
11639 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11640 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11642 (clobber (match_scratch:HI 0 "=r"))]
11644 || !TARGET_PARTIAL_FLAG_REG_STALL
11645 || (operands[2] == const1_rtx
11647 || TARGET_DOUBLE_WITH_ADD)))
11648 && ix86_match_ccmode (insn, CCGOCmode)
11649 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11651 switch (get_attr_type (insn))
11654 gcc_assert (operands[2] == const1_rtx);
11655 return "add{w}\t%0, %0";
11658 if (REG_P (operands[2]))
11659 return "sal{w}\t{%b2, %0|%0, %b2}";
11660 else if (operands[2] == const1_rtx
11661 && (TARGET_SHIFT1 || optimize_size))
11662 return "sal{w}\t%0";
11664 return "sal{w}\t{%2, %0|%0, %2}";
11667 [(set (attr "type")
11668 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11670 (match_operand 0 "register_operand" ""))
11671 (match_operand 2 "const1_operand" ""))
11672 (const_string "alu")
11674 (const_string "ishift")))
11675 (set_attr "mode" "HI")])
11677 (define_expand "ashlqi3"
11678 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11679 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11680 (match_operand:QI 2 "nonmemory_operand" "")))
11681 (clobber (reg:CC FLAGS_REG))]
11682 "TARGET_QIMODE_MATH"
11683 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11685 ;; %%% Potential partial reg stall on alternative 2. What to do?
11687 (define_insn "*ashlqi3_1_lea"
11688 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11689 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11690 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11691 (clobber (reg:CC FLAGS_REG))]
11692 "!TARGET_PARTIAL_REG_STALL
11693 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11695 switch (get_attr_type (insn))
11700 gcc_assert (operands[2] == const1_rtx);
11701 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11702 return "add{l}\t%k0, %k0";
11704 return "add{b}\t%0, %0";
11707 if (REG_P (operands[2]))
11709 if (get_attr_mode (insn) == MODE_SI)
11710 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11712 return "sal{b}\t{%b2, %0|%0, %b2}";
11714 else if (operands[2] == const1_rtx
11715 && (TARGET_SHIFT1 || optimize_size))
11717 if (get_attr_mode (insn) == MODE_SI)
11718 return "sal{l}\t%0";
11720 return "sal{b}\t%0";
11724 if (get_attr_mode (insn) == MODE_SI)
11725 return "sal{l}\t{%2, %k0|%k0, %2}";
11727 return "sal{b}\t{%2, %0|%0, %2}";
11731 [(set (attr "type")
11732 (cond [(eq_attr "alternative" "2")
11733 (const_string "lea")
11734 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11736 (match_operand 0 "register_operand" ""))
11737 (match_operand 2 "const1_operand" ""))
11738 (const_string "alu")
11740 (const_string "ishift")))
11741 (set_attr "mode" "QI,SI,SI")])
11743 (define_insn "*ashlqi3_1"
11744 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11745 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11746 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11747 (clobber (reg:CC FLAGS_REG))]
11748 "TARGET_PARTIAL_REG_STALL
11749 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11751 switch (get_attr_type (insn))
11754 gcc_assert (operands[2] == const1_rtx);
11755 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11756 return "add{l}\t%k0, %k0";
11758 return "add{b}\t%0, %0";
11761 if (REG_P (operands[2]))
11763 if (get_attr_mode (insn) == MODE_SI)
11764 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11766 return "sal{b}\t{%b2, %0|%0, %b2}";
11768 else if (operands[2] == const1_rtx
11769 && (TARGET_SHIFT1 || optimize_size))
11771 if (get_attr_mode (insn) == MODE_SI)
11772 return "sal{l}\t%0";
11774 return "sal{b}\t%0";
11778 if (get_attr_mode (insn) == MODE_SI)
11779 return "sal{l}\t{%2, %k0|%k0, %2}";
11781 return "sal{b}\t{%2, %0|%0, %2}";
11785 [(set (attr "type")
11786 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11788 (match_operand 0 "register_operand" ""))
11789 (match_operand 2 "const1_operand" ""))
11790 (const_string "alu")
11792 (const_string "ishift")))
11793 (set_attr "mode" "QI,SI")])
11795 ;; This pattern can't accept a variable shift count, since shifts by
11796 ;; zero don't affect the flags. We assume that shifts by constant
11797 ;; zero are optimized away.
11798 (define_insn "*ashlqi3_cmp"
11799 [(set (reg FLAGS_REG)
11801 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11802 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11804 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11805 (ashift:QI (match_dup 1) (match_dup 2)))]
11807 || !TARGET_PARTIAL_FLAG_REG_STALL
11808 || (operands[2] == const1_rtx
11810 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11811 && ix86_match_ccmode (insn, CCGOCmode)
11812 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11814 switch (get_attr_type (insn))
11817 gcc_assert (operands[2] == const1_rtx);
11818 return "add{b}\t%0, %0";
11821 if (REG_P (operands[2]))
11822 return "sal{b}\t{%b2, %0|%0, %b2}";
11823 else if (operands[2] == const1_rtx
11824 && (TARGET_SHIFT1 || optimize_size))
11825 return "sal{b}\t%0";
11827 return "sal{b}\t{%2, %0|%0, %2}";
11830 [(set (attr "type")
11831 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11833 (match_operand 0 "register_operand" ""))
11834 (match_operand 2 "const1_operand" ""))
11835 (const_string "alu")
11837 (const_string "ishift")))
11838 (set_attr "mode" "QI")])
11840 (define_insn "*ashlqi3_cconly"
11841 [(set (reg FLAGS_REG)
11843 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11844 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11846 (clobber (match_scratch:QI 0 "=q"))]
11848 || !TARGET_PARTIAL_FLAG_REG_STALL
11849 || (operands[2] == const1_rtx
11851 || TARGET_DOUBLE_WITH_ADD)))
11852 && ix86_match_ccmode (insn, CCGOCmode)
11853 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11855 switch (get_attr_type (insn))
11858 gcc_assert (operands[2] == const1_rtx);
11859 return "add{b}\t%0, %0";
11862 if (REG_P (operands[2]))
11863 return "sal{b}\t{%b2, %0|%0, %b2}";
11864 else if (operands[2] == const1_rtx
11865 && (TARGET_SHIFT1 || optimize_size))
11866 return "sal{b}\t%0";
11868 return "sal{b}\t{%2, %0|%0, %2}";
11871 [(set (attr "type")
11872 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11874 (match_operand 0 "register_operand" ""))
11875 (match_operand 2 "const1_operand" ""))
11876 (const_string "alu")
11878 (const_string "ishift")))
11879 (set_attr "mode" "QI")])
11881 ;; See comment above `ashldi3' about how this works.
11883 (define_expand "ashrti3"
11884 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11885 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11886 (match_operand:QI 2 "nonmemory_operand" "")))
11887 (clobber (reg:CC FLAGS_REG))])]
11890 if (! immediate_operand (operands[2], QImode))
11892 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11895 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11899 (define_insn "ashrti3_1"
11900 [(set (match_operand:TI 0 "register_operand" "=r")
11901 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11902 (match_operand:QI 2 "register_operand" "c")))
11903 (clobber (match_scratch:DI 3 "=&r"))
11904 (clobber (reg:CC FLAGS_REG))]
11907 [(set_attr "type" "multi")])
11909 (define_insn "*ashrti3_2"
11910 [(set (match_operand:TI 0 "register_operand" "=r")
11911 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11912 (match_operand:QI 2 "immediate_operand" "O")))
11913 (clobber (reg:CC FLAGS_REG))]
11916 [(set_attr "type" "multi")])
11919 [(set (match_operand:TI 0 "register_operand" "")
11920 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11921 (match_operand:QI 2 "register_operand" "")))
11922 (clobber (match_scratch:DI 3 ""))
11923 (clobber (reg:CC FLAGS_REG))]
11924 "TARGET_64BIT && reload_completed"
11926 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11929 [(set (match_operand:TI 0 "register_operand" "")
11930 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11931 (match_operand:QI 2 "immediate_operand" "")))
11932 (clobber (reg:CC FLAGS_REG))]
11933 "TARGET_64BIT && reload_completed"
11935 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11937 (define_insn "x86_64_shrd"
11938 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11939 (ior:DI (ashiftrt:DI (match_dup 0)
11940 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11941 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11942 (minus:QI (const_int 64) (match_dup 2)))))
11943 (clobber (reg:CC FLAGS_REG))]
11946 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11947 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11948 [(set_attr "type" "ishift")
11949 (set_attr "prefix_0f" "1")
11950 (set_attr "mode" "DI")
11951 (set_attr "athlon_decode" "vector")
11952 (set_attr "amdfam10_decode" "vector")])
11954 (define_expand "ashrdi3"
11955 [(set (match_operand:DI 0 "shiftdi_operand" "")
11956 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11957 (match_operand:QI 2 "nonmemory_operand" "")))]
11959 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11961 (define_insn "*ashrdi3_63_rex64"
11962 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11963 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11964 (match_operand:DI 2 "const_int_operand" "i,i")))
11965 (clobber (reg:CC FLAGS_REG))]
11966 "TARGET_64BIT && INTVAL (operands[2]) == 63
11967 && (TARGET_USE_CLTD || optimize_size)
11968 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11971 sar{q}\t{%2, %0|%0, %2}"
11972 [(set_attr "type" "imovx,ishift")
11973 (set_attr "prefix_0f" "0,*")
11974 (set_attr "length_immediate" "0,*")
11975 (set_attr "modrm" "0,1")
11976 (set_attr "mode" "DI")])
11978 (define_insn "*ashrdi3_1_one_bit_rex64"
11979 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11980 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11981 (match_operand:QI 2 "const1_operand" "")))
11982 (clobber (reg:CC FLAGS_REG))]
11984 && (TARGET_SHIFT1 || optimize_size)
11985 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11987 [(set_attr "type" "ishift")
11988 (set (attr "length")
11989 (if_then_else (match_operand:DI 0 "register_operand" "")
11991 (const_string "*")))])
11993 (define_insn "*ashrdi3_1_rex64"
11994 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11995 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11996 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11997 (clobber (reg:CC FLAGS_REG))]
11998 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12000 sar{q}\t{%2, %0|%0, %2}
12001 sar{q}\t{%b2, %0|%0, %b2}"
12002 [(set_attr "type" "ishift")
12003 (set_attr "mode" "DI")])
12005 ;; This pattern can't accept a variable shift count, since shifts by
12006 ;; zero don't affect the flags. We assume that shifts by constant
12007 ;; zero are optimized away.
12008 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12009 [(set (reg FLAGS_REG)
12011 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12012 (match_operand:QI 2 "const1_operand" ""))
12014 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12015 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12017 && (TARGET_SHIFT1 || optimize_size)
12018 && ix86_match_ccmode (insn, CCGOCmode)
12019 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12021 [(set_attr "type" "ishift")
12022 (set (attr "length")
12023 (if_then_else (match_operand:DI 0 "register_operand" "")
12025 (const_string "*")))])
12027 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12028 [(set (reg FLAGS_REG)
12030 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12031 (match_operand:QI 2 "const1_operand" ""))
12033 (clobber (match_scratch:DI 0 "=r"))]
12035 && (TARGET_SHIFT1 || optimize_size)
12036 && ix86_match_ccmode (insn, CCGOCmode)
12037 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12039 [(set_attr "type" "ishift")
12040 (set_attr "length" "2")])
12042 ;; This pattern can't accept a variable shift count, since shifts by
12043 ;; zero don't affect the flags. We assume that shifts by constant
12044 ;; zero are optimized away.
12045 (define_insn "*ashrdi3_cmp_rex64"
12046 [(set (reg FLAGS_REG)
12048 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12049 (match_operand:QI 2 "const_int_operand" "n"))
12051 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12052 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12054 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12055 && ix86_match_ccmode (insn, CCGOCmode)
12056 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12057 "sar{q}\t{%2, %0|%0, %2}"
12058 [(set_attr "type" "ishift")
12059 (set_attr "mode" "DI")])
12061 (define_insn "*ashrdi3_cconly_rex64"
12062 [(set (reg FLAGS_REG)
12064 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12065 (match_operand:QI 2 "const_int_operand" "n"))
12067 (clobber (match_scratch:DI 0 "=r"))]
12069 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12070 && ix86_match_ccmode (insn, CCGOCmode)
12071 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12072 "sar{q}\t{%2, %0|%0, %2}"
12073 [(set_attr "type" "ishift")
12074 (set_attr "mode" "DI")])
12076 (define_insn "*ashrdi3_1"
12077 [(set (match_operand:DI 0 "register_operand" "=r")
12078 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12079 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12080 (clobber (reg:CC FLAGS_REG))]
12083 [(set_attr "type" "multi")])
12085 ;; By default we don't ask for a scratch register, because when DImode
12086 ;; values are manipulated, registers are already at a premium. But if
12087 ;; we have one handy, we won't turn it away.
12089 [(match_scratch:SI 3 "r")
12090 (parallel [(set (match_operand:DI 0 "register_operand" "")
12091 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12092 (match_operand:QI 2 "nonmemory_operand" "")))
12093 (clobber (reg:CC FLAGS_REG))])
12095 "!TARGET_64BIT && TARGET_CMOVE"
12097 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12100 [(set (match_operand:DI 0 "register_operand" "")
12101 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12102 (match_operand:QI 2 "nonmemory_operand" "")))
12103 (clobber (reg:CC FLAGS_REG))]
12104 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12105 ? epilogue_completed : reload_completed)"
12107 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12109 (define_insn "x86_shrd_1"
12110 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12111 (ior:SI (ashiftrt:SI (match_dup 0)
12112 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12113 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12114 (minus:QI (const_int 32) (match_dup 2)))))
12115 (clobber (reg:CC FLAGS_REG))]
12118 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12119 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12120 [(set_attr "type" "ishift")
12121 (set_attr "prefix_0f" "1")
12122 (set_attr "pent_pair" "np")
12123 (set_attr "mode" "SI")])
12125 (define_expand "x86_shift_adj_3"
12126 [(use (match_operand:SI 0 "register_operand" ""))
12127 (use (match_operand:SI 1 "register_operand" ""))
12128 (use (match_operand:QI 2 "register_operand" ""))]
12131 rtx label = gen_label_rtx ();
12134 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12136 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12137 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12138 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12139 gen_rtx_LABEL_REF (VOIDmode, label),
12141 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12142 JUMP_LABEL (tmp) = label;
12144 emit_move_insn (operands[0], operands[1]);
12145 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12147 emit_label (label);
12148 LABEL_NUSES (label) = 1;
12153 (define_insn "ashrsi3_31"
12154 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12155 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12156 (match_operand:SI 2 "const_int_operand" "i,i")))
12157 (clobber (reg:CC FLAGS_REG))]
12158 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12159 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12162 sar{l}\t{%2, %0|%0, %2}"
12163 [(set_attr "type" "imovx,ishift")
12164 (set_attr "prefix_0f" "0,*")
12165 (set_attr "length_immediate" "0,*")
12166 (set_attr "modrm" "0,1")
12167 (set_attr "mode" "SI")])
12169 (define_insn "*ashrsi3_31_zext"
12170 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12171 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12172 (match_operand:SI 2 "const_int_operand" "i,i"))))
12173 (clobber (reg:CC FLAGS_REG))]
12174 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12175 && INTVAL (operands[2]) == 31
12176 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12179 sar{l}\t{%2, %k0|%k0, %2}"
12180 [(set_attr "type" "imovx,ishift")
12181 (set_attr "prefix_0f" "0,*")
12182 (set_attr "length_immediate" "0,*")
12183 (set_attr "modrm" "0,1")
12184 (set_attr "mode" "SI")])
12186 (define_expand "ashrsi3"
12187 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12188 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12189 (match_operand:QI 2 "nonmemory_operand" "")))
12190 (clobber (reg:CC FLAGS_REG))]
12192 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12194 (define_insn "*ashrsi3_1_one_bit"
12195 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12196 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12197 (match_operand:QI 2 "const1_operand" "")))
12198 (clobber (reg:CC FLAGS_REG))]
12199 "(TARGET_SHIFT1 || optimize_size)
12200 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12202 [(set_attr "type" "ishift")
12203 (set (attr "length")
12204 (if_then_else (match_operand:SI 0 "register_operand" "")
12206 (const_string "*")))])
12208 (define_insn "*ashrsi3_1_one_bit_zext"
12209 [(set (match_operand:DI 0 "register_operand" "=r")
12210 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12211 (match_operand:QI 2 "const1_operand" ""))))
12212 (clobber (reg:CC FLAGS_REG))]
12214 && (TARGET_SHIFT1 || optimize_size)
12215 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12217 [(set_attr "type" "ishift")
12218 (set_attr "length" "2")])
12220 (define_insn "*ashrsi3_1"
12221 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12222 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12223 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12224 (clobber (reg:CC FLAGS_REG))]
12225 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12227 sar{l}\t{%2, %0|%0, %2}
12228 sar{l}\t{%b2, %0|%0, %b2}"
12229 [(set_attr "type" "ishift")
12230 (set_attr "mode" "SI")])
12232 (define_insn "*ashrsi3_1_zext"
12233 [(set (match_operand:DI 0 "register_operand" "=r,r")
12234 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12235 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12236 (clobber (reg:CC FLAGS_REG))]
12237 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12239 sar{l}\t{%2, %k0|%k0, %2}
12240 sar{l}\t{%b2, %k0|%k0, %b2}"
12241 [(set_attr "type" "ishift")
12242 (set_attr "mode" "SI")])
12244 ;; This pattern can't accept a variable shift count, since shifts by
12245 ;; zero don't affect the flags. We assume that shifts by constant
12246 ;; zero are optimized away.
12247 (define_insn "*ashrsi3_one_bit_cmp"
12248 [(set (reg FLAGS_REG)
12250 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12251 (match_operand:QI 2 "const1_operand" ""))
12253 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12254 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12255 "(TARGET_SHIFT1 || optimize_size)
12256 && ix86_match_ccmode (insn, CCGOCmode)
12257 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12259 [(set_attr "type" "ishift")
12260 (set (attr "length")
12261 (if_then_else (match_operand:SI 0 "register_operand" "")
12263 (const_string "*")))])
12265 (define_insn "*ashrsi3_one_bit_cconly"
12266 [(set (reg FLAGS_REG)
12268 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12269 (match_operand:QI 2 "const1_operand" ""))
12271 (clobber (match_scratch:SI 0 "=r"))]
12272 "(TARGET_SHIFT1 || optimize_size)
12273 && ix86_match_ccmode (insn, CCGOCmode)
12274 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12276 [(set_attr "type" "ishift")
12277 (set_attr "length" "2")])
12279 (define_insn "*ashrsi3_one_bit_cmp_zext"
12280 [(set (reg FLAGS_REG)
12282 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12283 (match_operand:QI 2 "const1_operand" ""))
12285 (set (match_operand:DI 0 "register_operand" "=r")
12286 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12288 && (TARGET_SHIFT1 || optimize_size)
12289 && ix86_match_ccmode (insn, CCmode)
12290 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12292 [(set_attr "type" "ishift")
12293 (set_attr "length" "2")])
12295 ;; This pattern can't accept a variable shift count, since shifts by
12296 ;; zero don't affect the flags. We assume that shifts by constant
12297 ;; zero are optimized away.
12298 (define_insn "*ashrsi3_cmp"
12299 [(set (reg FLAGS_REG)
12301 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12302 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12304 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12305 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12306 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12307 && ix86_match_ccmode (insn, CCGOCmode)
12308 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12309 "sar{l}\t{%2, %0|%0, %2}"
12310 [(set_attr "type" "ishift")
12311 (set_attr "mode" "SI")])
12313 (define_insn "*ashrsi3_cconly"
12314 [(set (reg FLAGS_REG)
12316 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12317 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12319 (clobber (match_scratch:SI 0 "=r"))]
12320 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12321 && ix86_match_ccmode (insn, CCGOCmode)
12322 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12323 "sar{l}\t{%2, %0|%0, %2}"
12324 [(set_attr "type" "ishift")
12325 (set_attr "mode" "SI")])
12327 (define_insn "*ashrsi3_cmp_zext"
12328 [(set (reg FLAGS_REG)
12330 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12331 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12333 (set (match_operand:DI 0 "register_operand" "=r")
12334 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12336 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12337 && ix86_match_ccmode (insn, CCGOCmode)
12338 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12339 "sar{l}\t{%2, %k0|%k0, %2}"
12340 [(set_attr "type" "ishift")
12341 (set_attr "mode" "SI")])
12343 (define_expand "ashrhi3"
12344 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12345 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12346 (match_operand:QI 2 "nonmemory_operand" "")))
12347 (clobber (reg:CC FLAGS_REG))]
12348 "TARGET_HIMODE_MATH"
12349 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12351 (define_insn "*ashrhi3_1_one_bit"
12352 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12353 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12354 (match_operand:QI 2 "const1_operand" "")))
12355 (clobber (reg:CC FLAGS_REG))]
12356 "(TARGET_SHIFT1 || optimize_size)
12357 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12359 [(set_attr "type" "ishift")
12360 (set (attr "length")
12361 (if_then_else (match_operand 0 "register_operand" "")
12363 (const_string "*")))])
12365 (define_insn "*ashrhi3_1"
12366 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12367 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12368 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12369 (clobber (reg:CC FLAGS_REG))]
12370 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12372 sar{w}\t{%2, %0|%0, %2}
12373 sar{w}\t{%b2, %0|%0, %b2}"
12374 [(set_attr "type" "ishift")
12375 (set_attr "mode" "HI")])
12377 ;; This pattern can't accept a variable shift count, since shifts by
12378 ;; zero don't affect the flags. We assume that shifts by constant
12379 ;; zero are optimized away.
12380 (define_insn "*ashrhi3_one_bit_cmp"
12381 [(set (reg FLAGS_REG)
12383 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12384 (match_operand:QI 2 "const1_operand" ""))
12386 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12387 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12388 "(TARGET_SHIFT1 || optimize_size)
12389 && ix86_match_ccmode (insn, CCGOCmode)
12390 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12392 [(set_attr "type" "ishift")
12393 (set (attr "length")
12394 (if_then_else (match_operand 0 "register_operand" "")
12396 (const_string "*")))])
12398 (define_insn "*ashrhi3_one_bit_cconly"
12399 [(set (reg FLAGS_REG)
12401 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12402 (match_operand:QI 2 "const1_operand" ""))
12404 (clobber (match_scratch:HI 0 "=r"))]
12405 "(TARGET_SHIFT1 || optimize_size)
12406 && ix86_match_ccmode (insn, CCGOCmode)
12407 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12409 [(set_attr "type" "ishift")
12410 (set_attr "length" "2")])
12412 ;; This pattern can't accept a variable shift count, since shifts by
12413 ;; zero don't affect the flags. We assume that shifts by constant
12414 ;; zero are optimized away.
12415 (define_insn "*ashrhi3_cmp"
12416 [(set (reg FLAGS_REG)
12418 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12419 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12421 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12422 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12423 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12424 && ix86_match_ccmode (insn, CCGOCmode)
12425 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12426 "sar{w}\t{%2, %0|%0, %2}"
12427 [(set_attr "type" "ishift")
12428 (set_attr "mode" "HI")])
12430 (define_insn "*ashrhi3_cconly"
12431 [(set (reg FLAGS_REG)
12433 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12434 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12436 (clobber (match_scratch:HI 0 "=r"))]
12437 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12438 && ix86_match_ccmode (insn, CCGOCmode)
12439 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12440 "sar{w}\t{%2, %0|%0, %2}"
12441 [(set_attr "type" "ishift")
12442 (set_attr "mode" "HI")])
12444 (define_expand "ashrqi3"
12445 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12446 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12447 (match_operand:QI 2 "nonmemory_operand" "")))
12448 (clobber (reg:CC FLAGS_REG))]
12449 "TARGET_QIMODE_MATH"
12450 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12452 (define_insn "*ashrqi3_1_one_bit"
12453 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12454 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12455 (match_operand:QI 2 "const1_operand" "")))
12456 (clobber (reg:CC FLAGS_REG))]
12457 "(TARGET_SHIFT1 || optimize_size)
12458 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12460 [(set_attr "type" "ishift")
12461 (set (attr "length")
12462 (if_then_else (match_operand 0 "register_operand" "")
12464 (const_string "*")))])
12466 (define_insn "*ashrqi3_1_one_bit_slp"
12467 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12468 (ashiftrt:QI (match_dup 0)
12469 (match_operand:QI 1 "const1_operand" "")))
12470 (clobber (reg:CC FLAGS_REG))]
12471 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12472 && (TARGET_SHIFT1 || optimize_size)
12473 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12475 [(set_attr "type" "ishift1")
12476 (set (attr "length")
12477 (if_then_else (match_operand 0 "register_operand" "")
12479 (const_string "*")))])
12481 (define_insn "*ashrqi3_1"
12482 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12483 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12484 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12485 (clobber (reg:CC FLAGS_REG))]
12486 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12488 sar{b}\t{%2, %0|%0, %2}
12489 sar{b}\t{%b2, %0|%0, %b2}"
12490 [(set_attr "type" "ishift")
12491 (set_attr "mode" "QI")])
12493 (define_insn "*ashrqi3_1_slp"
12494 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12495 (ashiftrt:QI (match_dup 0)
12496 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12497 (clobber (reg:CC FLAGS_REG))]
12498 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12499 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12501 sar{b}\t{%1, %0|%0, %1}
12502 sar{b}\t{%b1, %0|%0, %b1}"
12503 [(set_attr "type" "ishift1")
12504 (set_attr "mode" "QI")])
12506 ;; This pattern can't accept a variable shift count, since shifts by
12507 ;; zero don't affect the flags. We assume that shifts by constant
12508 ;; zero are optimized away.
12509 (define_insn "*ashrqi3_one_bit_cmp"
12510 [(set (reg FLAGS_REG)
12512 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12513 (match_operand:QI 2 "const1_operand" "I"))
12515 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12516 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12517 "(TARGET_SHIFT1 || optimize_size)
12518 && ix86_match_ccmode (insn, CCGOCmode)
12519 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12521 [(set_attr "type" "ishift")
12522 (set (attr "length")
12523 (if_then_else (match_operand 0 "register_operand" "")
12525 (const_string "*")))])
12527 (define_insn "*ashrqi3_one_bit_cconly"
12528 [(set (reg FLAGS_REG)
12530 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12531 (match_operand:QI 2 "const1_operand" "I"))
12533 (clobber (match_scratch:QI 0 "=q"))]
12534 "(TARGET_SHIFT1 || optimize_size)
12535 && ix86_match_ccmode (insn, CCGOCmode)
12536 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12538 [(set_attr "type" "ishift")
12539 (set_attr "length" "2")])
12541 ;; This pattern can't accept a variable shift count, since shifts by
12542 ;; zero don't affect the flags. We assume that shifts by constant
12543 ;; zero are optimized away.
12544 (define_insn "*ashrqi3_cmp"
12545 [(set (reg FLAGS_REG)
12547 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12548 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12550 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12551 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12552 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12553 && ix86_match_ccmode (insn, CCGOCmode)
12554 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12555 "sar{b}\t{%2, %0|%0, %2}"
12556 [(set_attr "type" "ishift")
12557 (set_attr "mode" "QI")])
12559 (define_insn "*ashrqi3_cconly"
12560 [(set (reg FLAGS_REG)
12562 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12563 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12565 (clobber (match_scratch:QI 0 "=q"))]
12566 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12567 && ix86_match_ccmode (insn, CCGOCmode)
12568 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12569 "sar{b}\t{%2, %0|%0, %2}"
12570 [(set_attr "type" "ishift")
12571 (set_attr "mode" "QI")])
12574 ;; Logical shift instructions
12576 ;; See comment above `ashldi3' about how this works.
12578 (define_expand "lshrti3"
12579 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12580 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12581 (match_operand:QI 2 "nonmemory_operand" "")))
12582 (clobber (reg:CC FLAGS_REG))])]
12585 if (! immediate_operand (operands[2], QImode))
12587 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12590 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12594 (define_insn "lshrti3_1"
12595 [(set (match_operand:TI 0 "register_operand" "=r")
12596 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12597 (match_operand:QI 2 "register_operand" "c")))
12598 (clobber (match_scratch:DI 3 "=&r"))
12599 (clobber (reg:CC FLAGS_REG))]
12602 [(set_attr "type" "multi")])
12604 ;; This pattern must be defined before *lshrti3_2 to prevent
12605 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12607 (define_insn "sse2_lshrti3"
12608 [(set (match_operand:TI 0 "register_operand" "=x")
12609 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12610 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12613 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12614 return "psrldq\t{%2, %0|%0, %2}";
12616 [(set_attr "type" "sseishft")
12617 (set_attr "prefix_data16" "1")
12618 (set_attr "mode" "TI")])
12620 (define_insn "*lshrti3_2"
12621 [(set (match_operand:TI 0 "register_operand" "=r")
12622 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12623 (match_operand:QI 2 "immediate_operand" "O")))
12624 (clobber (reg:CC FLAGS_REG))]
12627 [(set_attr "type" "multi")])
12630 [(set (match_operand:TI 0 "register_operand" "")
12631 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12632 (match_operand:QI 2 "register_operand" "")))
12633 (clobber (match_scratch:DI 3 ""))
12634 (clobber (reg:CC FLAGS_REG))]
12635 "TARGET_64BIT && reload_completed"
12637 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12640 [(set (match_operand:TI 0 "register_operand" "")
12641 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12642 (match_operand:QI 2 "immediate_operand" "")))
12643 (clobber (reg:CC FLAGS_REG))]
12644 "TARGET_64BIT && reload_completed"
12646 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12648 (define_expand "lshrdi3"
12649 [(set (match_operand:DI 0 "shiftdi_operand" "")
12650 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12651 (match_operand:QI 2 "nonmemory_operand" "")))]
12653 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12655 (define_insn "*lshrdi3_1_one_bit_rex64"
12656 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12657 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12658 (match_operand:QI 2 "const1_operand" "")))
12659 (clobber (reg:CC FLAGS_REG))]
12661 && (TARGET_SHIFT1 || optimize_size)
12662 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12664 [(set_attr "type" "ishift")
12665 (set (attr "length")
12666 (if_then_else (match_operand:DI 0 "register_operand" "")
12668 (const_string "*")))])
12670 (define_insn "*lshrdi3_1_rex64"
12671 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12672 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12673 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12674 (clobber (reg:CC FLAGS_REG))]
12675 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12677 shr{q}\t{%2, %0|%0, %2}
12678 shr{q}\t{%b2, %0|%0, %b2}"
12679 [(set_attr "type" "ishift")
12680 (set_attr "mode" "DI")])
12682 ;; This pattern can't accept a variable shift count, since shifts by
12683 ;; zero don't affect the flags. We assume that shifts by constant
12684 ;; zero are optimized away.
12685 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12686 [(set (reg FLAGS_REG)
12688 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12689 (match_operand:QI 2 "const1_operand" ""))
12691 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12692 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12694 && (TARGET_SHIFT1 || optimize_size)
12695 && ix86_match_ccmode (insn, CCGOCmode)
12696 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12698 [(set_attr "type" "ishift")
12699 (set (attr "length")
12700 (if_then_else (match_operand:DI 0 "register_operand" "")
12702 (const_string "*")))])
12704 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12705 [(set (reg FLAGS_REG)
12707 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12708 (match_operand:QI 2 "const1_operand" ""))
12710 (clobber (match_scratch:DI 0 "=r"))]
12712 && (TARGET_SHIFT1 || optimize_size)
12713 && ix86_match_ccmode (insn, CCGOCmode)
12714 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12716 [(set_attr "type" "ishift")
12717 (set_attr "length" "2")])
12719 ;; This pattern can't accept a variable shift count, since shifts by
12720 ;; zero don't affect the flags. We assume that shifts by constant
12721 ;; zero are optimized away.
12722 (define_insn "*lshrdi3_cmp_rex64"
12723 [(set (reg FLAGS_REG)
12725 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12726 (match_operand:QI 2 "const_int_operand" "e"))
12728 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12729 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12731 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12732 && ix86_match_ccmode (insn, CCGOCmode)
12733 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12734 "shr{q}\t{%2, %0|%0, %2}"
12735 [(set_attr "type" "ishift")
12736 (set_attr "mode" "DI")])
12738 (define_insn "*lshrdi3_cconly_rex64"
12739 [(set (reg FLAGS_REG)
12741 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12742 (match_operand:QI 2 "const_int_operand" "e"))
12744 (clobber (match_scratch:DI 0 "=r"))]
12746 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12747 && ix86_match_ccmode (insn, CCGOCmode)
12748 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12749 "shr{q}\t{%2, %0|%0, %2}"
12750 [(set_attr "type" "ishift")
12751 (set_attr "mode" "DI")])
12753 (define_insn "*lshrdi3_1"
12754 [(set (match_operand:DI 0 "register_operand" "=r")
12755 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12756 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12757 (clobber (reg:CC FLAGS_REG))]
12760 [(set_attr "type" "multi")])
12762 ;; By default we don't ask for a scratch register, because when DImode
12763 ;; values are manipulated, registers are already at a premium. But if
12764 ;; we have one handy, we won't turn it away.
12766 [(match_scratch:SI 3 "r")
12767 (parallel [(set (match_operand:DI 0 "register_operand" "")
12768 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12769 (match_operand:QI 2 "nonmemory_operand" "")))
12770 (clobber (reg:CC FLAGS_REG))])
12772 "!TARGET_64BIT && TARGET_CMOVE"
12774 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12777 [(set (match_operand:DI 0 "register_operand" "")
12778 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12779 (match_operand:QI 2 "nonmemory_operand" "")))
12780 (clobber (reg:CC FLAGS_REG))]
12781 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12782 ? epilogue_completed : reload_completed)"
12784 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12786 (define_expand "lshrsi3"
12787 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12788 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12789 (match_operand:QI 2 "nonmemory_operand" "")))
12790 (clobber (reg:CC FLAGS_REG))]
12792 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12794 (define_insn "*lshrsi3_1_one_bit"
12795 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12796 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12797 (match_operand:QI 2 "const1_operand" "")))
12798 (clobber (reg:CC FLAGS_REG))]
12799 "(TARGET_SHIFT1 || optimize_size)
12800 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12802 [(set_attr "type" "ishift")
12803 (set (attr "length")
12804 (if_then_else (match_operand:SI 0 "register_operand" "")
12806 (const_string "*")))])
12808 (define_insn "*lshrsi3_1_one_bit_zext"
12809 [(set (match_operand:DI 0 "register_operand" "=r")
12810 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12811 (match_operand:QI 2 "const1_operand" "")))
12812 (clobber (reg:CC FLAGS_REG))]
12814 && (TARGET_SHIFT1 || optimize_size)
12815 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12817 [(set_attr "type" "ishift")
12818 (set_attr "length" "2")])
12820 (define_insn "*lshrsi3_1"
12821 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12822 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12823 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12824 (clobber (reg:CC FLAGS_REG))]
12825 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12827 shr{l}\t{%2, %0|%0, %2}
12828 shr{l}\t{%b2, %0|%0, %b2}"
12829 [(set_attr "type" "ishift")
12830 (set_attr "mode" "SI")])
12832 (define_insn "*lshrsi3_1_zext"
12833 [(set (match_operand:DI 0 "register_operand" "=r,r")
12835 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12836 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12837 (clobber (reg:CC FLAGS_REG))]
12838 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12840 shr{l}\t{%2, %k0|%k0, %2}
12841 shr{l}\t{%b2, %k0|%k0, %b2}"
12842 [(set_attr "type" "ishift")
12843 (set_attr "mode" "SI")])
12845 ;; This pattern can't accept a variable shift count, since shifts by
12846 ;; zero don't affect the flags. We assume that shifts by constant
12847 ;; zero are optimized away.
12848 (define_insn "*lshrsi3_one_bit_cmp"
12849 [(set (reg FLAGS_REG)
12851 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12852 (match_operand:QI 2 "const1_operand" ""))
12854 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12855 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12856 "(TARGET_SHIFT1 || optimize_size)
12857 && ix86_match_ccmode (insn, CCGOCmode)
12858 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12860 [(set_attr "type" "ishift")
12861 (set (attr "length")
12862 (if_then_else (match_operand:SI 0 "register_operand" "")
12864 (const_string "*")))])
12866 (define_insn "*lshrsi3_one_bit_cconly"
12867 [(set (reg FLAGS_REG)
12869 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12870 (match_operand:QI 2 "const1_operand" ""))
12872 (clobber (match_scratch:SI 0 "=r"))]
12873 "(TARGET_SHIFT1 || optimize_size)
12874 && ix86_match_ccmode (insn, CCGOCmode)
12875 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12877 [(set_attr "type" "ishift")
12878 (set_attr "length" "2")])
12880 (define_insn "*lshrsi3_cmp_one_bit_zext"
12881 [(set (reg FLAGS_REG)
12883 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12884 (match_operand:QI 2 "const1_operand" ""))
12886 (set (match_operand:DI 0 "register_operand" "=r")
12887 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12889 && (TARGET_SHIFT1 || optimize_size)
12890 && ix86_match_ccmode (insn, CCGOCmode)
12891 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12893 [(set_attr "type" "ishift")
12894 (set_attr "length" "2")])
12896 ;; This pattern can't accept a variable shift count, since shifts by
12897 ;; zero don't affect the flags. We assume that shifts by constant
12898 ;; zero are optimized away.
12899 (define_insn "*lshrsi3_cmp"
12900 [(set (reg FLAGS_REG)
12902 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12903 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12905 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12906 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12907 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12908 && ix86_match_ccmode (insn, CCGOCmode)
12909 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12910 "shr{l}\t{%2, %0|%0, %2}"
12911 [(set_attr "type" "ishift")
12912 (set_attr "mode" "SI")])
12914 (define_insn "*lshrsi3_cconly"
12915 [(set (reg FLAGS_REG)
12917 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12918 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12920 (clobber (match_scratch:SI 0 "=r"))]
12921 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12922 && ix86_match_ccmode (insn, CCGOCmode)
12923 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12924 "shr{l}\t{%2, %0|%0, %2}"
12925 [(set_attr "type" "ishift")
12926 (set_attr "mode" "SI")])
12928 (define_insn "*lshrsi3_cmp_zext"
12929 [(set (reg FLAGS_REG)
12931 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12932 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12934 (set (match_operand:DI 0 "register_operand" "=r")
12935 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12937 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12938 && ix86_match_ccmode (insn, CCGOCmode)
12939 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12940 "shr{l}\t{%2, %k0|%k0, %2}"
12941 [(set_attr "type" "ishift")
12942 (set_attr "mode" "SI")])
12944 (define_expand "lshrhi3"
12945 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12946 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12947 (match_operand:QI 2 "nonmemory_operand" "")))
12948 (clobber (reg:CC FLAGS_REG))]
12949 "TARGET_HIMODE_MATH"
12950 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12952 (define_insn "*lshrhi3_1_one_bit"
12953 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12954 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12955 (match_operand:QI 2 "const1_operand" "")))
12956 (clobber (reg:CC FLAGS_REG))]
12957 "(TARGET_SHIFT1 || optimize_size)
12958 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12960 [(set_attr "type" "ishift")
12961 (set (attr "length")
12962 (if_then_else (match_operand 0 "register_operand" "")
12964 (const_string "*")))])
12966 (define_insn "*lshrhi3_1"
12967 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12968 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12969 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12970 (clobber (reg:CC FLAGS_REG))]
12971 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12973 shr{w}\t{%2, %0|%0, %2}
12974 shr{w}\t{%b2, %0|%0, %b2}"
12975 [(set_attr "type" "ishift")
12976 (set_attr "mode" "HI")])
12978 ;; This pattern can't accept a variable shift count, since shifts by
12979 ;; zero don't affect the flags. We assume that shifts by constant
12980 ;; zero are optimized away.
12981 (define_insn "*lshrhi3_one_bit_cmp"
12982 [(set (reg FLAGS_REG)
12984 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12985 (match_operand:QI 2 "const1_operand" ""))
12987 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12988 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12989 "(TARGET_SHIFT1 || optimize_size)
12990 && ix86_match_ccmode (insn, CCGOCmode)
12991 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12993 [(set_attr "type" "ishift")
12994 (set (attr "length")
12995 (if_then_else (match_operand:SI 0 "register_operand" "")
12997 (const_string "*")))])
12999 (define_insn "*lshrhi3_one_bit_cconly"
13000 [(set (reg FLAGS_REG)
13002 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13003 (match_operand:QI 2 "const1_operand" ""))
13005 (clobber (match_scratch:HI 0 "=r"))]
13006 "(TARGET_SHIFT1 || optimize_size)
13007 && ix86_match_ccmode (insn, CCGOCmode)
13008 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13010 [(set_attr "type" "ishift")
13011 (set_attr "length" "2")])
13013 ;; This pattern can't accept a variable shift count, since shifts by
13014 ;; zero don't affect the flags. We assume that shifts by constant
13015 ;; zero are optimized away.
13016 (define_insn "*lshrhi3_cmp"
13017 [(set (reg FLAGS_REG)
13019 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13020 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13022 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13023 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13024 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13025 && ix86_match_ccmode (insn, CCGOCmode)
13026 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13027 "shr{w}\t{%2, %0|%0, %2}"
13028 [(set_attr "type" "ishift")
13029 (set_attr "mode" "HI")])
13031 (define_insn "*lshrhi3_cconly"
13032 [(set (reg FLAGS_REG)
13034 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13035 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13037 (clobber (match_scratch:HI 0 "=r"))]
13038 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13039 && ix86_match_ccmode (insn, CCGOCmode)
13040 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13041 "shr{w}\t{%2, %0|%0, %2}"
13042 [(set_attr "type" "ishift")
13043 (set_attr "mode" "HI")])
13045 (define_expand "lshrqi3"
13046 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13047 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13048 (match_operand:QI 2 "nonmemory_operand" "")))
13049 (clobber (reg:CC FLAGS_REG))]
13050 "TARGET_QIMODE_MATH"
13051 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13053 (define_insn "*lshrqi3_1_one_bit"
13054 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13055 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13056 (match_operand:QI 2 "const1_operand" "")))
13057 (clobber (reg:CC FLAGS_REG))]
13058 "(TARGET_SHIFT1 || optimize_size)
13059 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13061 [(set_attr "type" "ishift")
13062 (set (attr "length")
13063 (if_then_else (match_operand 0 "register_operand" "")
13065 (const_string "*")))])
13067 (define_insn "*lshrqi3_1_one_bit_slp"
13068 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13069 (lshiftrt:QI (match_dup 0)
13070 (match_operand:QI 1 "const1_operand" "")))
13071 (clobber (reg:CC FLAGS_REG))]
13072 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13073 && (TARGET_SHIFT1 || optimize_size)"
13075 [(set_attr "type" "ishift1")
13076 (set (attr "length")
13077 (if_then_else (match_operand 0 "register_operand" "")
13079 (const_string "*")))])
13081 (define_insn "*lshrqi3_1"
13082 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13083 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13084 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13085 (clobber (reg:CC FLAGS_REG))]
13086 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13088 shr{b}\t{%2, %0|%0, %2}
13089 shr{b}\t{%b2, %0|%0, %b2}"
13090 [(set_attr "type" "ishift")
13091 (set_attr "mode" "QI")])
13093 (define_insn "*lshrqi3_1_slp"
13094 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13095 (lshiftrt:QI (match_dup 0)
13096 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13097 (clobber (reg:CC FLAGS_REG))]
13098 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13099 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13101 shr{b}\t{%1, %0|%0, %1}
13102 shr{b}\t{%b1, %0|%0, %b1}"
13103 [(set_attr "type" "ishift1")
13104 (set_attr "mode" "QI")])
13106 ;; This pattern can't accept a variable shift count, since shifts by
13107 ;; zero don't affect the flags. We assume that shifts by constant
13108 ;; zero are optimized away.
13109 (define_insn "*lshrqi2_one_bit_cmp"
13110 [(set (reg FLAGS_REG)
13112 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13113 (match_operand:QI 2 "const1_operand" ""))
13115 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13116 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13117 "(TARGET_SHIFT1 || optimize_size)
13118 && ix86_match_ccmode (insn, CCGOCmode)
13119 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13121 [(set_attr "type" "ishift")
13122 (set (attr "length")
13123 (if_then_else (match_operand:SI 0 "register_operand" "")
13125 (const_string "*")))])
13127 (define_insn "*lshrqi2_one_bit_cconly"
13128 [(set (reg FLAGS_REG)
13130 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13131 (match_operand:QI 2 "const1_operand" ""))
13133 (clobber (match_scratch:QI 0 "=q"))]
13134 "(TARGET_SHIFT1 || optimize_size)
13135 && ix86_match_ccmode (insn, CCGOCmode)
13136 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13138 [(set_attr "type" "ishift")
13139 (set_attr "length" "2")])
13141 ;; This pattern can't accept a variable shift count, since shifts by
13142 ;; zero don't affect the flags. We assume that shifts by constant
13143 ;; zero are optimized away.
13144 (define_insn "*lshrqi2_cmp"
13145 [(set (reg FLAGS_REG)
13147 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13148 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13150 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13151 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13152 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13153 && ix86_match_ccmode (insn, CCGOCmode)
13154 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13155 "shr{b}\t{%2, %0|%0, %2}"
13156 [(set_attr "type" "ishift")
13157 (set_attr "mode" "QI")])
13159 (define_insn "*lshrqi2_cconly"
13160 [(set (reg FLAGS_REG)
13162 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13163 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13165 (clobber (match_scratch:QI 0 "=q"))]
13166 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13167 && ix86_match_ccmode (insn, CCGOCmode)
13168 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13169 "shr{b}\t{%2, %0|%0, %2}"
13170 [(set_attr "type" "ishift")
13171 (set_attr "mode" "QI")])
13173 ;; Rotate instructions
13175 (define_expand "rotldi3"
13176 [(set (match_operand:DI 0 "shiftdi_operand" "")
13177 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13178 (match_operand:QI 2 "nonmemory_operand" "")))
13179 (clobber (reg:CC FLAGS_REG))]
13184 ix86_expand_binary_operator (ROTATE, DImode, operands);
13187 if (!const_1_to_31_operand (operands[2], VOIDmode))
13189 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13193 ;; Implement rotation using two double-precision shift instructions
13194 ;; and a scratch register.
13195 (define_insn_and_split "ix86_rotldi3"
13196 [(set (match_operand:DI 0 "register_operand" "=r")
13197 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13198 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13199 (clobber (reg:CC FLAGS_REG))
13200 (clobber (match_scratch:SI 3 "=&r"))]
13203 "&& reload_completed"
13204 [(set (match_dup 3) (match_dup 4))
13206 [(set (match_dup 4)
13207 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13208 (lshiftrt:SI (match_dup 5)
13209 (minus:QI (const_int 32) (match_dup 2)))))
13210 (clobber (reg:CC FLAGS_REG))])
13212 [(set (match_dup 5)
13213 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13214 (lshiftrt:SI (match_dup 3)
13215 (minus:QI (const_int 32) (match_dup 2)))))
13216 (clobber (reg:CC FLAGS_REG))])]
13217 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13219 (define_insn "*rotlsi3_1_one_bit_rex64"
13220 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13221 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13222 (match_operand:QI 2 "const1_operand" "")))
13223 (clobber (reg:CC FLAGS_REG))]
13225 && (TARGET_SHIFT1 || optimize_size)
13226 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13228 [(set_attr "type" "rotate")
13229 (set (attr "length")
13230 (if_then_else (match_operand:DI 0 "register_operand" "")
13232 (const_string "*")))])
13234 (define_insn "*rotldi3_1_rex64"
13235 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13236 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13237 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13238 (clobber (reg:CC FLAGS_REG))]
13239 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13241 rol{q}\t{%2, %0|%0, %2}
13242 rol{q}\t{%b2, %0|%0, %b2}"
13243 [(set_attr "type" "rotate")
13244 (set_attr "mode" "DI")])
13246 (define_expand "rotlsi3"
13247 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13248 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13249 (match_operand:QI 2 "nonmemory_operand" "")))
13250 (clobber (reg:CC FLAGS_REG))]
13252 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13254 (define_insn "*rotlsi3_1_one_bit"
13255 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13256 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13257 (match_operand:QI 2 "const1_operand" "")))
13258 (clobber (reg:CC FLAGS_REG))]
13259 "(TARGET_SHIFT1 || optimize_size)
13260 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13262 [(set_attr "type" "rotate")
13263 (set (attr "length")
13264 (if_then_else (match_operand:SI 0 "register_operand" "")
13266 (const_string "*")))])
13268 (define_insn "*rotlsi3_1_one_bit_zext"
13269 [(set (match_operand:DI 0 "register_operand" "=r")
13271 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13272 (match_operand:QI 2 "const1_operand" ""))))
13273 (clobber (reg:CC FLAGS_REG))]
13275 && (TARGET_SHIFT1 || optimize_size)
13276 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13278 [(set_attr "type" "rotate")
13279 (set_attr "length" "2")])
13281 (define_insn "*rotlsi3_1"
13282 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13283 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13284 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13285 (clobber (reg:CC FLAGS_REG))]
13286 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13288 rol{l}\t{%2, %0|%0, %2}
13289 rol{l}\t{%b2, %0|%0, %b2}"
13290 [(set_attr "type" "rotate")
13291 (set_attr "mode" "SI")])
13293 (define_insn "*rotlsi3_1_zext"
13294 [(set (match_operand:DI 0 "register_operand" "=r,r")
13296 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13297 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13298 (clobber (reg:CC FLAGS_REG))]
13299 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13301 rol{l}\t{%2, %k0|%k0, %2}
13302 rol{l}\t{%b2, %k0|%k0, %b2}"
13303 [(set_attr "type" "rotate")
13304 (set_attr "mode" "SI")])
13306 (define_expand "rotlhi3"
13307 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13308 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13309 (match_operand:QI 2 "nonmemory_operand" "")))
13310 (clobber (reg:CC FLAGS_REG))]
13311 "TARGET_HIMODE_MATH"
13312 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13314 (define_insn "*rotlhi3_1_one_bit"
13315 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13316 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13317 (match_operand:QI 2 "const1_operand" "")))
13318 (clobber (reg:CC FLAGS_REG))]
13319 "(TARGET_SHIFT1 || optimize_size)
13320 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13322 [(set_attr "type" "rotate")
13323 (set (attr "length")
13324 (if_then_else (match_operand 0 "register_operand" "")
13326 (const_string "*")))])
13328 (define_insn "*rotlhi3_1"
13329 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13330 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13331 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13332 (clobber (reg:CC FLAGS_REG))]
13333 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13335 rol{w}\t{%2, %0|%0, %2}
13336 rol{w}\t{%b2, %0|%0, %b2}"
13337 [(set_attr "type" "rotate")
13338 (set_attr "mode" "HI")])
13341 [(set (match_operand:HI 0 "register_operand" "")
13342 (rotate:HI (match_dup 0) (const_int 8)))
13343 (clobber (reg:CC FLAGS_REG))]
13345 [(parallel [(set (strict_low_part (match_dup 0))
13346 (bswap:HI (match_dup 0)))
13347 (clobber (reg:CC FLAGS_REG))])]
13350 (define_expand "rotlqi3"
13351 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13352 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13353 (match_operand:QI 2 "nonmemory_operand" "")))
13354 (clobber (reg:CC FLAGS_REG))]
13355 "TARGET_QIMODE_MATH"
13356 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13358 (define_insn "*rotlqi3_1_one_bit_slp"
13359 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13360 (rotate:QI (match_dup 0)
13361 (match_operand:QI 1 "const1_operand" "")))
13362 (clobber (reg:CC FLAGS_REG))]
13363 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13364 && (TARGET_SHIFT1 || optimize_size)"
13366 [(set_attr "type" "rotate1")
13367 (set (attr "length")
13368 (if_then_else (match_operand 0 "register_operand" "")
13370 (const_string "*")))])
13372 (define_insn "*rotlqi3_1_one_bit"
13373 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13374 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13375 (match_operand:QI 2 "const1_operand" "")))
13376 (clobber (reg:CC FLAGS_REG))]
13377 "(TARGET_SHIFT1 || optimize_size)
13378 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13380 [(set_attr "type" "rotate")
13381 (set (attr "length")
13382 (if_then_else (match_operand 0 "register_operand" "")
13384 (const_string "*")))])
13386 (define_insn "*rotlqi3_1_slp"
13387 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13388 (rotate:QI (match_dup 0)
13389 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13390 (clobber (reg:CC FLAGS_REG))]
13391 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13392 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13394 rol{b}\t{%1, %0|%0, %1}
13395 rol{b}\t{%b1, %0|%0, %b1}"
13396 [(set_attr "type" "rotate1")
13397 (set_attr "mode" "QI")])
13399 (define_insn "*rotlqi3_1"
13400 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13401 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13402 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13403 (clobber (reg:CC FLAGS_REG))]
13404 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13406 rol{b}\t{%2, %0|%0, %2}
13407 rol{b}\t{%b2, %0|%0, %b2}"
13408 [(set_attr "type" "rotate")
13409 (set_attr "mode" "QI")])
13411 (define_expand "rotrdi3"
13412 [(set (match_operand:DI 0 "shiftdi_operand" "")
13413 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13414 (match_operand:QI 2 "nonmemory_operand" "")))
13415 (clobber (reg:CC FLAGS_REG))]
13420 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13423 if (!const_1_to_31_operand (operands[2], VOIDmode))
13425 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13429 ;; Implement rotation using two double-precision shift instructions
13430 ;; and a scratch register.
13431 (define_insn_and_split "ix86_rotrdi3"
13432 [(set (match_operand:DI 0 "register_operand" "=r")
13433 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13434 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13435 (clobber (reg:CC FLAGS_REG))
13436 (clobber (match_scratch:SI 3 "=&r"))]
13439 "&& reload_completed"
13440 [(set (match_dup 3) (match_dup 4))
13442 [(set (match_dup 4)
13443 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13444 (ashift:SI (match_dup 5)
13445 (minus:QI (const_int 32) (match_dup 2)))))
13446 (clobber (reg:CC FLAGS_REG))])
13448 [(set (match_dup 5)
13449 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13450 (ashift:SI (match_dup 3)
13451 (minus:QI (const_int 32) (match_dup 2)))))
13452 (clobber (reg:CC FLAGS_REG))])]
13453 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13455 (define_insn "*rotrdi3_1_one_bit_rex64"
13456 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13457 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13458 (match_operand:QI 2 "const1_operand" "")))
13459 (clobber (reg:CC FLAGS_REG))]
13461 && (TARGET_SHIFT1 || optimize_size)
13462 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13464 [(set_attr "type" "rotate")
13465 (set (attr "length")
13466 (if_then_else (match_operand:DI 0 "register_operand" "")
13468 (const_string "*")))])
13470 (define_insn "*rotrdi3_1_rex64"
13471 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13472 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13473 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13474 (clobber (reg:CC FLAGS_REG))]
13475 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13477 ror{q}\t{%2, %0|%0, %2}
13478 ror{q}\t{%b2, %0|%0, %b2}"
13479 [(set_attr "type" "rotate")
13480 (set_attr "mode" "DI")])
13482 (define_expand "rotrsi3"
13483 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13484 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13485 (match_operand:QI 2 "nonmemory_operand" "")))
13486 (clobber (reg:CC FLAGS_REG))]
13488 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13490 (define_insn "*rotrsi3_1_one_bit"
13491 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13492 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13493 (match_operand:QI 2 "const1_operand" "")))
13494 (clobber (reg:CC FLAGS_REG))]
13495 "(TARGET_SHIFT1 || optimize_size)
13496 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13498 [(set_attr "type" "rotate")
13499 (set (attr "length")
13500 (if_then_else (match_operand:SI 0 "register_operand" "")
13502 (const_string "*")))])
13504 (define_insn "*rotrsi3_1_one_bit_zext"
13505 [(set (match_operand:DI 0 "register_operand" "=r")
13507 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13508 (match_operand:QI 2 "const1_operand" ""))))
13509 (clobber (reg:CC FLAGS_REG))]
13511 && (TARGET_SHIFT1 || optimize_size)
13512 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13514 [(set_attr "type" "rotate")
13515 (set (attr "length")
13516 (if_then_else (match_operand:SI 0 "register_operand" "")
13518 (const_string "*")))])
13520 (define_insn "*rotrsi3_1"
13521 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13522 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13523 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13524 (clobber (reg:CC FLAGS_REG))]
13525 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13527 ror{l}\t{%2, %0|%0, %2}
13528 ror{l}\t{%b2, %0|%0, %b2}"
13529 [(set_attr "type" "rotate")
13530 (set_attr "mode" "SI")])
13532 (define_insn "*rotrsi3_1_zext"
13533 [(set (match_operand:DI 0 "register_operand" "=r,r")
13535 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13536 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13537 (clobber (reg:CC FLAGS_REG))]
13538 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13540 ror{l}\t{%2, %k0|%k0, %2}
13541 ror{l}\t{%b2, %k0|%k0, %b2}"
13542 [(set_attr "type" "rotate")
13543 (set_attr "mode" "SI")])
13545 (define_expand "rotrhi3"
13546 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13547 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13548 (match_operand:QI 2 "nonmemory_operand" "")))
13549 (clobber (reg:CC FLAGS_REG))]
13550 "TARGET_HIMODE_MATH"
13551 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13553 (define_insn "*rotrhi3_one_bit"
13554 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13555 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13556 (match_operand:QI 2 "const1_operand" "")))
13557 (clobber (reg:CC FLAGS_REG))]
13558 "(TARGET_SHIFT1 || optimize_size)
13559 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13561 [(set_attr "type" "rotate")
13562 (set (attr "length")
13563 (if_then_else (match_operand 0 "register_operand" "")
13565 (const_string "*")))])
13567 (define_insn "*rotrhi3_1"
13568 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13569 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13570 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13571 (clobber (reg:CC FLAGS_REG))]
13572 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13574 ror{w}\t{%2, %0|%0, %2}
13575 ror{w}\t{%b2, %0|%0, %b2}"
13576 [(set_attr "type" "rotate")
13577 (set_attr "mode" "HI")])
13580 [(set (match_operand:HI 0 "register_operand" "")
13581 (rotatert:HI (match_dup 0) (const_int 8)))
13582 (clobber (reg:CC FLAGS_REG))]
13584 [(parallel [(set (strict_low_part (match_dup 0))
13585 (bswap:HI (match_dup 0)))
13586 (clobber (reg:CC FLAGS_REG))])]
13589 (define_expand "rotrqi3"
13590 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13591 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13592 (match_operand:QI 2 "nonmemory_operand" "")))
13593 (clobber (reg:CC FLAGS_REG))]
13594 "TARGET_QIMODE_MATH"
13595 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13597 (define_insn "*rotrqi3_1_one_bit"
13598 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13599 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13600 (match_operand:QI 2 "const1_operand" "")))
13601 (clobber (reg:CC FLAGS_REG))]
13602 "(TARGET_SHIFT1 || optimize_size)
13603 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13605 [(set_attr "type" "rotate")
13606 (set (attr "length")
13607 (if_then_else (match_operand 0 "register_operand" "")
13609 (const_string "*")))])
13611 (define_insn "*rotrqi3_1_one_bit_slp"
13612 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13613 (rotatert:QI (match_dup 0)
13614 (match_operand:QI 1 "const1_operand" "")))
13615 (clobber (reg:CC FLAGS_REG))]
13616 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13617 && (TARGET_SHIFT1 || optimize_size)"
13619 [(set_attr "type" "rotate1")
13620 (set (attr "length")
13621 (if_then_else (match_operand 0 "register_operand" "")
13623 (const_string "*")))])
13625 (define_insn "*rotrqi3_1"
13626 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13627 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13628 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13629 (clobber (reg:CC FLAGS_REG))]
13630 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13632 ror{b}\t{%2, %0|%0, %2}
13633 ror{b}\t{%b2, %0|%0, %b2}"
13634 [(set_attr "type" "rotate")
13635 (set_attr "mode" "QI")])
13637 (define_insn "*rotrqi3_1_slp"
13638 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13639 (rotatert:QI (match_dup 0)
13640 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13641 (clobber (reg:CC FLAGS_REG))]
13642 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13643 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13645 ror{b}\t{%1, %0|%0, %1}
13646 ror{b}\t{%b1, %0|%0, %b1}"
13647 [(set_attr "type" "rotate1")
13648 (set_attr "mode" "QI")])
13650 ;; Bit set / bit test instructions
13652 (define_expand "extv"
13653 [(set (match_operand:SI 0 "register_operand" "")
13654 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13655 (match_operand:SI 2 "const8_operand" "")
13656 (match_operand:SI 3 "const8_operand" "")))]
13659 /* Handle extractions from %ah et al. */
13660 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13663 /* From mips.md: extract_bit_field doesn't verify that our source
13664 matches the predicate, so check it again here. */
13665 if (! ext_register_operand (operands[1], VOIDmode))
13669 (define_expand "extzv"
13670 [(set (match_operand:SI 0 "register_operand" "")
13671 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13672 (match_operand:SI 2 "const8_operand" "")
13673 (match_operand:SI 3 "const8_operand" "")))]
13676 /* Handle extractions from %ah et al. */
13677 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13680 /* From mips.md: extract_bit_field doesn't verify that our source
13681 matches the predicate, so check it again here. */
13682 if (! ext_register_operand (operands[1], VOIDmode))
13686 (define_expand "insv"
13687 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13688 (match_operand 1 "const8_operand" "")
13689 (match_operand 2 "const8_operand" ""))
13690 (match_operand 3 "register_operand" ""))]
13693 /* Handle insertions to %ah et al. */
13694 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13697 /* From mips.md: insert_bit_field doesn't verify that our source
13698 matches the predicate, so check it again here. */
13699 if (! ext_register_operand (operands[0], VOIDmode))
13703 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13705 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13710 ;; %%% bts, btr, btc, bt.
13711 ;; In general these instructions are *slow* when applied to memory,
13712 ;; since they enforce atomic operation. When applied to registers,
13713 ;; it depends on the cpu implementation. They're never faster than
13714 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13715 ;; no point. But in 64-bit, we can't hold the relevant immediates
13716 ;; within the instruction itself, so operating on bits in the high
13717 ;; 32-bits of a register becomes easier.
13719 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13720 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13721 ;; negdf respectively, so they can never be disabled entirely.
13723 (define_insn "*btsq"
13724 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13726 (match_operand:DI 1 "const_0_to_63_operand" ""))
13728 (clobber (reg:CC FLAGS_REG))]
13729 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13731 [(set_attr "type" "alu1")])
13733 (define_insn "*btrq"
13734 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13736 (match_operand:DI 1 "const_0_to_63_operand" ""))
13738 (clobber (reg:CC FLAGS_REG))]
13739 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13741 [(set_attr "type" "alu1")])
13743 (define_insn "*btcq"
13744 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13746 (match_operand:DI 1 "const_0_to_63_operand" ""))
13747 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13748 (clobber (reg:CC FLAGS_REG))]
13749 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13751 [(set_attr "type" "alu1")])
13753 ;; Allow Nocona to avoid these instructions if a register is available.
13756 [(match_scratch:DI 2 "r")
13757 (parallel [(set (zero_extract:DI
13758 (match_operand:DI 0 "register_operand" "")
13760 (match_operand:DI 1 "const_0_to_63_operand" ""))
13762 (clobber (reg:CC FLAGS_REG))])]
13763 "TARGET_64BIT && !TARGET_USE_BT"
13766 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13769 if (HOST_BITS_PER_WIDE_INT >= 64)
13770 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13771 else if (i < HOST_BITS_PER_WIDE_INT)
13772 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13774 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13776 op1 = immed_double_const (lo, hi, DImode);
13779 emit_move_insn (operands[2], op1);
13783 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13788 [(match_scratch:DI 2 "r")
13789 (parallel [(set (zero_extract:DI
13790 (match_operand:DI 0 "register_operand" "")
13792 (match_operand:DI 1 "const_0_to_63_operand" ""))
13794 (clobber (reg:CC FLAGS_REG))])]
13795 "TARGET_64BIT && !TARGET_USE_BT"
13798 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13801 if (HOST_BITS_PER_WIDE_INT >= 64)
13802 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13803 else if (i < HOST_BITS_PER_WIDE_INT)
13804 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13806 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13808 op1 = immed_double_const (~lo, ~hi, DImode);
13811 emit_move_insn (operands[2], op1);
13815 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13820 [(match_scratch:DI 2 "r")
13821 (parallel [(set (zero_extract:DI
13822 (match_operand:DI 0 "register_operand" "")
13824 (match_operand:DI 1 "const_0_to_63_operand" ""))
13825 (not:DI (zero_extract:DI
13826 (match_dup 0) (const_int 1) (match_dup 1))))
13827 (clobber (reg:CC FLAGS_REG))])]
13828 "TARGET_64BIT && !TARGET_USE_BT"
13831 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13834 if (HOST_BITS_PER_WIDE_INT >= 64)
13835 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13836 else if (i < HOST_BITS_PER_WIDE_INT)
13837 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13839 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13841 op1 = immed_double_const (lo, hi, DImode);
13844 emit_move_insn (operands[2], op1);
13848 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13852 ;; Store-flag instructions.
13854 ;; For all sCOND expanders, also expand the compare or test insn that
13855 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13857 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13858 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13859 ;; way, which can later delete the movzx if only QImode is needed.
13861 (define_expand "s<code>"
13862 [(set (match_operand:QI 0 "register_operand" "")
13863 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13865 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13867 (define_expand "s<code>"
13868 [(set (match_operand:QI 0 "register_operand" "")
13869 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13870 "TARGET_80387 || TARGET_SSE"
13871 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13873 (define_insn "*setcc_1"
13874 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13875 (match_operator:QI 1 "ix86_comparison_operator"
13876 [(reg FLAGS_REG) (const_int 0)]))]
13879 [(set_attr "type" "setcc")
13880 (set_attr "mode" "QI")])
13882 (define_insn "*setcc_2"
13883 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13884 (match_operator:QI 1 "ix86_comparison_operator"
13885 [(reg FLAGS_REG) (const_int 0)]))]
13888 [(set_attr "type" "setcc")
13889 (set_attr "mode" "QI")])
13891 ;; In general it is not safe to assume too much about CCmode registers,
13892 ;; so simplify-rtx stops when it sees a second one. Under certain
13893 ;; conditions this is safe on x86, so help combine not create
13900 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13901 (ne:QI (match_operator 1 "ix86_comparison_operator"
13902 [(reg FLAGS_REG) (const_int 0)])
13905 [(set (match_dup 0) (match_dup 1))]
13907 PUT_MODE (operands[1], QImode);
13911 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13912 (ne:QI (match_operator 1 "ix86_comparison_operator"
13913 [(reg FLAGS_REG) (const_int 0)])
13916 [(set (match_dup 0) (match_dup 1))]
13918 PUT_MODE (operands[1], QImode);
13922 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13923 (eq:QI (match_operator 1 "ix86_comparison_operator"
13924 [(reg FLAGS_REG) (const_int 0)])
13927 [(set (match_dup 0) (match_dup 1))]
13929 rtx new_op1 = copy_rtx (operands[1]);
13930 operands[1] = new_op1;
13931 PUT_MODE (new_op1, QImode);
13932 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13933 GET_MODE (XEXP (new_op1, 0))));
13935 /* Make sure that (a) the CCmode we have for the flags is strong
13936 enough for the reversed compare or (b) we have a valid FP compare. */
13937 if (! ix86_comparison_operator (new_op1, VOIDmode))
13942 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13943 (eq:QI (match_operator 1 "ix86_comparison_operator"
13944 [(reg FLAGS_REG) (const_int 0)])
13947 [(set (match_dup 0) (match_dup 1))]
13949 rtx new_op1 = copy_rtx (operands[1]);
13950 operands[1] = new_op1;
13951 PUT_MODE (new_op1, QImode);
13952 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13953 GET_MODE (XEXP (new_op1, 0))));
13955 /* Make sure that (a) the CCmode we have for the flags is strong
13956 enough for the reversed compare or (b) we have a valid FP compare. */
13957 if (! ix86_comparison_operator (new_op1, VOIDmode))
13961 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13962 ;; subsequent logical operations are used to imitate conditional moves.
13963 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13966 (define_insn "*sse_setcc<mode>"
13967 [(set (match_operand:MODEF 0 "register_operand" "=x")
13968 (match_operator:MODEF 1 "sse_comparison_operator"
13969 [(match_operand:MODEF 2 "register_operand" "0")
13970 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13971 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13972 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13973 [(set_attr "type" "ssecmp")
13974 (set_attr "mode" "<MODE>")])
13976 (define_insn "*sse5_setcc<mode>"
13977 [(set (match_operand:MODEF 0 "register_operand" "=x")
13978 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13979 [(match_operand:MODEF 2 "register_operand" "x")
13980 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13982 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13983 [(set_attr "type" "sse4arg")
13984 (set_attr "mode" "<MODE>")])
13987 ;; Basic conditional jump instructions.
13988 ;; We ignore the overflow flag for signed branch instructions.
13990 ;; For all bCOND expanders, also expand the compare or test insn that
13991 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13993 (define_expand "b<code>"
13995 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13997 (label_ref (match_operand 0 ""))
14000 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14002 (define_expand "b<code>"
14004 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14006 (label_ref (match_operand 0 ""))
14008 "TARGET_80387 || TARGET_SSE_MATH"
14009 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14011 (define_insn "*jcc_1"
14013 (if_then_else (match_operator 1 "ix86_comparison_operator"
14014 [(reg FLAGS_REG) (const_int 0)])
14015 (label_ref (match_operand 0 "" ""))
14019 [(set_attr "type" "ibr")
14020 (set_attr "modrm" "0")
14021 (set (attr "length")
14022 (if_then_else (and (ge (minus (match_dup 0) (pc))
14024 (lt (minus (match_dup 0) (pc))
14029 (define_insn "*jcc_2"
14031 (if_then_else (match_operator 1 "ix86_comparison_operator"
14032 [(reg FLAGS_REG) (const_int 0)])
14034 (label_ref (match_operand 0 "" ""))))]
14037 [(set_attr "type" "ibr")
14038 (set_attr "modrm" "0")
14039 (set (attr "length")
14040 (if_then_else (and (ge (minus (match_dup 0) (pc))
14042 (lt (minus (match_dup 0) (pc))
14047 ;; In general it is not safe to assume too much about CCmode registers,
14048 ;; so simplify-rtx stops when it sees a second one. Under certain
14049 ;; conditions this is safe on x86, so help combine not create
14057 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14058 [(reg FLAGS_REG) (const_int 0)])
14060 (label_ref (match_operand 1 "" ""))
14064 (if_then_else (match_dup 0)
14065 (label_ref (match_dup 1))
14068 PUT_MODE (operands[0], VOIDmode);
14073 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14074 [(reg FLAGS_REG) (const_int 0)])
14076 (label_ref (match_operand 1 "" ""))
14080 (if_then_else (match_dup 0)
14081 (label_ref (match_dup 1))
14084 rtx new_op0 = copy_rtx (operands[0]);
14085 operands[0] = new_op0;
14086 PUT_MODE (new_op0, VOIDmode);
14087 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14088 GET_MODE (XEXP (new_op0, 0))));
14090 /* Make sure that (a) the CCmode we have for the flags is strong
14091 enough for the reversed compare or (b) we have a valid FP compare. */
14092 if (! ix86_comparison_operator (new_op0, VOIDmode))
14096 ;; Define combination compare-and-branch fp compare instructions to use
14097 ;; during early optimization. Splitting the operation apart early makes
14098 ;; for bad code when we want to reverse the operation.
14100 (define_insn "*fp_jcc_1_mixed"
14102 (if_then_else (match_operator 0 "comparison_operator"
14103 [(match_operand 1 "register_operand" "f,x")
14104 (match_operand 2 "nonimmediate_operand" "f,xm")])
14105 (label_ref (match_operand 3 "" ""))
14107 (clobber (reg:CCFP FPSR_REG))
14108 (clobber (reg:CCFP FLAGS_REG))]
14109 "TARGET_MIX_SSE_I387
14110 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14111 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14112 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14115 (define_insn "*fp_jcc_1_sse"
14117 (if_then_else (match_operator 0 "comparison_operator"
14118 [(match_operand 1 "register_operand" "x")
14119 (match_operand 2 "nonimmediate_operand" "xm")])
14120 (label_ref (match_operand 3 "" ""))
14122 (clobber (reg:CCFP FPSR_REG))
14123 (clobber (reg:CCFP FLAGS_REG))]
14125 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14126 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14127 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14130 (define_insn "*fp_jcc_1_387"
14132 (if_then_else (match_operator 0 "comparison_operator"
14133 [(match_operand 1 "register_operand" "f")
14134 (match_operand 2 "register_operand" "f")])
14135 (label_ref (match_operand 3 "" ""))
14137 (clobber (reg:CCFP FPSR_REG))
14138 (clobber (reg:CCFP FLAGS_REG))]
14139 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14141 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14142 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14145 (define_insn "*fp_jcc_2_mixed"
14147 (if_then_else (match_operator 0 "comparison_operator"
14148 [(match_operand 1 "register_operand" "f,x")
14149 (match_operand 2 "nonimmediate_operand" "f,xm")])
14151 (label_ref (match_operand 3 "" ""))))
14152 (clobber (reg:CCFP FPSR_REG))
14153 (clobber (reg:CCFP FLAGS_REG))]
14154 "TARGET_MIX_SSE_I387
14155 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14156 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14157 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14160 (define_insn "*fp_jcc_2_sse"
14162 (if_then_else (match_operator 0 "comparison_operator"
14163 [(match_operand 1 "register_operand" "x")
14164 (match_operand 2 "nonimmediate_operand" "xm")])
14166 (label_ref (match_operand 3 "" ""))))
14167 (clobber (reg:CCFP FPSR_REG))
14168 (clobber (reg:CCFP FLAGS_REG))]
14170 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14171 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14172 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14175 (define_insn "*fp_jcc_2_387"
14177 (if_then_else (match_operator 0 "comparison_operator"
14178 [(match_operand 1 "register_operand" "f")
14179 (match_operand 2 "register_operand" "f")])
14181 (label_ref (match_operand 3 "" ""))))
14182 (clobber (reg:CCFP FPSR_REG))
14183 (clobber (reg:CCFP FLAGS_REG))]
14184 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14186 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14187 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14190 (define_insn "*fp_jcc_3_387"
14192 (if_then_else (match_operator 0 "comparison_operator"
14193 [(match_operand 1 "register_operand" "f")
14194 (match_operand 2 "nonimmediate_operand" "fm")])
14195 (label_ref (match_operand 3 "" ""))
14197 (clobber (reg:CCFP FPSR_REG))
14198 (clobber (reg:CCFP FLAGS_REG))
14199 (clobber (match_scratch:HI 4 "=a"))]
14201 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14202 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14203 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14204 && SELECT_CC_MODE (GET_CODE (operands[0]),
14205 operands[1], operands[2]) == CCFPmode
14206 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14209 (define_insn "*fp_jcc_4_387"
14211 (if_then_else (match_operator 0 "comparison_operator"
14212 [(match_operand 1 "register_operand" "f")
14213 (match_operand 2 "nonimmediate_operand" "fm")])
14215 (label_ref (match_operand 3 "" ""))))
14216 (clobber (reg:CCFP FPSR_REG))
14217 (clobber (reg:CCFP FLAGS_REG))
14218 (clobber (match_scratch:HI 4 "=a"))]
14220 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14221 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14222 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14223 && SELECT_CC_MODE (GET_CODE (operands[0]),
14224 operands[1], operands[2]) == CCFPmode
14225 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14228 (define_insn "*fp_jcc_5_387"
14230 (if_then_else (match_operator 0 "comparison_operator"
14231 [(match_operand 1 "register_operand" "f")
14232 (match_operand 2 "register_operand" "f")])
14233 (label_ref (match_operand 3 "" ""))
14235 (clobber (reg:CCFP FPSR_REG))
14236 (clobber (reg:CCFP FLAGS_REG))
14237 (clobber (match_scratch:HI 4 "=a"))]
14238 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14239 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14240 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14243 (define_insn "*fp_jcc_6_387"
14245 (if_then_else (match_operator 0 "comparison_operator"
14246 [(match_operand 1 "register_operand" "f")
14247 (match_operand 2 "register_operand" "f")])
14249 (label_ref (match_operand 3 "" ""))))
14250 (clobber (reg:CCFP FPSR_REG))
14251 (clobber (reg:CCFP FLAGS_REG))
14252 (clobber (match_scratch:HI 4 "=a"))]
14253 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14254 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14255 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14258 (define_insn "*fp_jcc_7_387"
14260 (if_then_else (match_operator 0 "comparison_operator"
14261 [(match_operand 1 "register_operand" "f")
14262 (match_operand 2 "const0_operand" "X")])
14263 (label_ref (match_operand 3 "" ""))
14265 (clobber (reg:CCFP FPSR_REG))
14266 (clobber (reg:CCFP FLAGS_REG))
14267 (clobber (match_scratch:HI 4 "=a"))]
14268 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14269 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14270 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14271 && SELECT_CC_MODE (GET_CODE (operands[0]),
14272 operands[1], operands[2]) == CCFPmode
14273 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14276 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14277 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14278 ;; with a precedence over other operators and is always put in the first
14279 ;; place. Swap condition and operands to match ficom instruction.
14281 (define_insn "*fp_jcc_8<mode>_387"
14283 (if_then_else (match_operator 0 "comparison_operator"
14284 [(match_operator 1 "float_operator"
14285 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14286 (match_operand 3 "register_operand" "f,f")])
14287 (label_ref (match_operand 4 "" ""))
14289 (clobber (reg:CCFP FPSR_REG))
14290 (clobber (reg:CCFP FLAGS_REG))
14291 (clobber (match_scratch:HI 5 "=a,a"))]
14292 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14293 && TARGET_USE_<MODE>MODE_FIOP
14294 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14295 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14296 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14297 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14302 (if_then_else (match_operator 0 "comparison_operator"
14303 [(match_operand 1 "register_operand" "")
14304 (match_operand 2 "nonimmediate_operand" "")])
14305 (match_operand 3 "" "")
14306 (match_operand 4 "" "")))
14307 (clobber (reg:CCFP FPSR_REG))
14308 (clobber (reg:CCFP FLAGS_REG))]
14312 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14313 operands[3], operands[4], NULL_RTX, NULL_RTX);
14319 (if_then_else (match_operator 0 "comparison_operator"
14320 [(match_operand 1 "register_operand" "")
14321 (match_operand 2 "general_operand" "")])
14322 (match_operand 3 "" "")
14323 (match_operand 4 "" "")))
14324 (clobber (reg:CCFP FPSR_REG))
14325 (clobber (reg:CCFP FLAGS_REG))
14326 (clobber (match_scratch:HI 5 "=a"))]
14330 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14331 operands[3], operands[4], operands[5], NULL_RTX);
14337 (if_then_else (match_operator 0 "comparison_operator"
14338 [(match_operator 1 "float_operator"
14339 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14340 (match_operand 3 "register_operand" "")])
14341 (match_operand 4 "" "")
14342 (match_operand 5 "" "")))
14343 (clobber (reg:CCFP FPSR_REG))
14344 (clobber (reg:CCFP FLAGS_REG))
14345 (clobber (match_scratch:HI 6 "=a"))]
14349 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14350 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14351 operands[3], operands[7],
14352 operands[4], operands[5], operands[6], NULL_RTX);
14356 ;; %%% Kill this when reload knows how to do it.
14359 (if_then_else (match_operator 0 "comparison_operator"
14360 [(match_operator 1 "float_operator"
14361 [(match_operand:X87MODEI12 2 "register_operand" "")])
14362 (match_operand 3 "register_operand" "")])
14363 (match_operand 4 "" "")
14364 (match_operand 5 "" "")))
14365 (clobber (reg:CCFP FPSR_REG))
14366 (clobber (reg:CCFP FLAGS_REG))
14367 (clobber (match_scratch:HI 6 "=a"))]
14371 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14372 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14373 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14374 operands[3], operands[7],
14375 operands[4], operands[5], operands[6], operands[2]);
14379 ;; Unconditional and other jump instructions
14381 (define_insn "jump"
14383 (label_ref (match_operand 0 "" "")))]
14386 [(set_attr "type" "ibr")
14387 (set (attr "length")
14388 (if_then_else (and (ge (minus (match_dup 0) (pc))
14390 (lt (minus (match_dup 0) (pc))
14394 (set_attr "modrm" "0")])
14396 (define_expand "indirect_jump"
14397 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14401 (define_insn "*indirect_jump"
14402 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14405 [(set_attr "type" "ibr")
14406 (set_attr "length_immediate" "0")])
14408 (define_insn "*indirect_jump_rtx64"
14409 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14412 [(set_attr "type" "ibr")
14413 (set_attr "length_immediate" "0")])
14415 (define_expand "tablejump"
14416 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14417 (use (label_ref (match_operand 1 "" "")))])]
14420 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14421 relative. Convert the relative address to an absolute address. */
14425 enum rtx_code code;
14427 /* We can't use @GOTOFF for text labels on VxWorks;
14428 see gotoff_operand. */
14429 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14433 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14435 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14439 op1 = pic_offset_table_rtx;
14444 op0 = pic_offset_table_rtx;
14448 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14453 (define_insn "*tablejump_1"
14454 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14455 (use (label_ref (match_operand 1 "" "")))]
14458 [(set_attr "type" "ibr")
14459 (set_attr "length_immediate" "0")])
14461 (define_insn "*tablejump_1_rtx64"
14462 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14463 (use (label_ref (match_operand 1 "" "")))]
14466 [(set_attr "type" "ibr")
14467 (set_attr "length_immediate" "0")])
14469 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14472 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14473 (set (match_operand:QI 1 "register_operand" "")
14474 (match_operator:QI 2 "ix86_comparison_operator"
14475 [(reg FLAGS_REG) (const_int 0)]))
14476 (set (match_operand 3 "q_regs_operand" "")
14477 (zero_extend (match_dup 1)))]
14478 "(peep2_reg_dead_p (3, operands[1])
14479 || operands_match_p (operands[1], operands[3]))
14480 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14481 [(set (match_dup 4) (match_dup 0))
14482 (set (strict_low_part (match_dup 5))
14485 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14486 operands[5] = gen_lowpart (QImode, operands[3]);
14487 ix86_expand_clear (operands[3]);
14490 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14493 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14494 (set (match_operand:QI 1 "register_operand" "")
14495 (match_operator:QI 2 "ix86_comparison_operator"
14496 [(reg FLAGS_REG) (const_int 0)]))
14497 (parallel [(set (match_operand 3 "q_regs_operand" "")
14498 (zero_extend (match_dup 1)))
14499 (clobber (reg:CC FLAGS_REG))])]
14500 "(peep2_reg_dead_p (3, operands[1])
14501 || operands_match_p (operands[1], operands[3]))
14502 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14503 [(set (match_dup 4) (match_dup 0))
14504 (set (strict_low_part (match_dup 5))
14507 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14508 operands[5] = gen_lowpart (QImode, operands[3]);
14509 ix86_expand_clear (operands[3]);
14512 ;; Call instructions.
14514 ;; The predicates normally associated with named expanders are not properly
14515 ;; checked for calls. This is a bug in the generic code, but it isn't that
14516 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14518 ;; Call subroutine returning no value.
14520 (define_expand "call_pop"
14521 [(parallel [(call (match_operand:QI 0 "" "")
14522 (match_operand:SI 1 "" ""))
14523 (set (reg:SI SP_REG)
14524 (plus:SI (reg:SI SP_REG)
14525 (match_operand:SI 3 "" "")))])]
14528 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14532 (define_insn "*call_pop_0"
14533 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14534 (match_operand:SI 1 "" ""))
14535 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14536 (match_operand:SI 2 "immediate_operand" "")))]
14539 if (SIBLING_CALL_P (insn))
14542 return "call\t%P0";
14544 [(set_attr "type" "call")])
14546 (define_insn "*call_pop_1"
14547 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14548 (match_operand:SI 1 "" ""))
14549 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14550 (match_operand:SI 2 "immediate_operand" "i")))]
14553 if (constant_call_address_operand (operands[0], Pmode))
14555 if (SIBLING_CALL_P (insn))
14558 return "call\t%P0";
14560 if (SIBLING_CALL_P (insn))
14563 return "call\t%A0";
14565 [(set_attr "type" "call")])
14567 (define_expand "call"
14568 [(call (match_operand:QI 0 "" "")
14569 (match_operand 1 "" ""))
14570 (use (match_operand 2 "" ""))]
14573 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14577 (define_expand "sibcall"
14578 [(call (match_operand:QI 0 "" "")
14579 (match_operand 1 "" ""))
14580 (use (match_operand 2 "" ""))]
14583 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14587 (define_insn "*call_0"
14588 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14589 (match_operand 1 "" ""))]
14592 if (SIBLING_CALL_P (insn))
14595 return "call\t%P0";
14597 [(set_attr "type" "call")])
14599 (define_insn "*call_1"
14600 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14601 (match_operand 1 "" ""))]
14602 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14604 if (constant_call_address_operand (operands[0], Pmode))
14605 return "call\t%P0";
14606 return "call\t%A0";
14608 [(set_attr "type" "call")])
14610 (define_insn "*sibcall_1"
14611 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14612 (match_operand 1 "" ""))]
14613 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14615 if (constant_call_address_operand (operands[0], Pmode))
14619 [(set_attr "type" "call")])
14621 (define_insn "*call_1_rex64"
14622 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14623 (match_operand 1 "" ""))]
14624 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14625 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14627 if (constant_call_address_operand (operands[0], Pmode))
14628 return "call\t%P0";
14629 return "call\t%A0";
14631 [(set_attr "type" "call")])
14633 (define_insn "*call_1_rex64_large"
14634 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14635 (match_operand 1 "" ""))]
14636 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14638 [(set_attr "type" "call")])
14640 (define_insn "*sibcall_1_rex64"
14641 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14642 (match_operand 1 "" ""))]
14643 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14645 [(set_attr "type" "call")])
14647 (define_insn "*sibcall_1_rex64_v"
14648 [(call (mem:QI (reg:DI R11_REG))
14649 (match_operand 0 "" ""))]
14650 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14652 [(set_attr "type" "call")])
14655 ;; Call subroutine, returning value in operand 0
14657 (define_expand "call_value_pop"
14658 [(parallel [(set (match_operand 0 "" "")
14659 (call (match_operand:QI 1 "" "")
14660 (match_operand:SI 2 "" "")))
14661 (set (reg:SI SP_REG)
14662 (plus:SI (reg:SI SP_REG)
14663 (match_operand:SI 4 "" "")))])]
14666 ix86_expand_call (operands[0], operands[1], operands[2],
14667 operands[3], operands[4], 0);
14671 (define_expand "call_value"
14672 [(set (match_operand 0 "" "")
14673 (call (match_operand:QI 1 "" "")
14674 (match_operand:SI 2 "" "")))
14675 (use (match_operand:SI 3 "" ""))]
14676 ;; Operand 2 not used on the i386.
14679 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14683 (define_expand "sibcall_value"
14684 [(set (match_operand 0 "" "")
14685 (call (match_operand:QI 1 "" "")
14686 (match_operand:SI 2 "" "")))
14687 (use (match_operand:SI 3 "" ""))]
14688 ;; Operand 2 not used on the i386.
14691 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14695 ;; Call subroutine returning any type.
14697 (define_expand "untyped_call"
14698 [(parallel [(call (match_operand 0 "" "")
14700 (match_operand 1 "" "")
14701 (match_operand 2 "" "")])]
14706 /* In order to give reg-stack an easier job in validating two
14707 coprocessor registers as containing a possible return value,
14708 simply pretend the untyped call returns a complex long double
14711 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14712 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14713 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14716 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14718 rtx set = XVECEXP (operands[2], 0, i);
14719 emit_move_insn (SET_DEST (set), SET_SRC (set));
14722 /* The optimizer does not know that the call sets the function value
14723 registers we stored in the result block. We avoid problems by
14724 claiming that all hard registers are used and clobbered at this
14726 emit_insn (gen_blockage ());
14731 ;; Prologue and epilogue instructions
14733 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14734 ;; all of memory. This blocks insns from being moved across this point.
14736 (define_insn "blockage"
14737 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14740 [(set_attr "length" "0")])
14742 ;; As USE insns aren't meaningful after reload, this is used instead
14743 ;; to prevent deleting instructions setting registers for PIC code
14744 (define_insn "prologue_use"
14745 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14748 [(set_attr "length" "0")])
14750 ;; Insn emitted into the body of a function to return from a function.
14751 ;; This is only done if the function's epilogue is known to be simple.
14752 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14754 (define_expand "return"
14756 "ix86_can_use_return_insn_p ()"
14758 if (crtl->args.pops_args)
14760 rtx popc = GEN_INT (crtl->args.pops_args);
14761 emit_jump_insn (gen_return_pop_internal (popc));
14766 (define_insn "return_internal"
14770 [(set_attr "length" "1")
14771 (set_attr "length_immediate" "0")
14772 (set_attr "modrm" "0")])
14774 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14775 ;; instruction Athlon and K8 have.
14777 (define_insn "return_internal_long"
14779 (unspec [(const_int 0)] UNSPEC_REP)]
14782 [(set_attr "length" "1")
14783 (set_attr "length_immediate" "0")
14784 (set_attr "prefix_rep" "1")
14785 (set_attr "modrm" "0")])
14787 (define_insn "return_pop_internal"
14789 (use (match_operand:SI 0 "const_int_operand" ""))]
14792 [(set_attr "length" "3")
14793 (set_attr "length_immediate" "2")
14794 (set_attr "modrm" "0")])
14796 (define_insn "return_indirect_internal"
14798 (use (match_operand:SI 0 "register_operand" "r"))]
14801 [(set_attr "type" "ibr")
14802 (set_attr "length_immediate" "0")])
14808 [(set_attr "length" "1")
14809 (set_attr "length_immediate" "0")
14810 (set_attr "modrm" "0")])
14812 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14813 ;; branch prediction penalty for the third jump in a 16-byte
14816 (define_insn "align"
14817 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14820 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14821 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14823 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14824 The align insn is used to avoid 3 jump instructions in the row to improve
14825 branch prediction and the benefits hardly outweigh the cost of extra 8
14826 nops on the average inserted by full alignment pseudo operation. */
14830 [(set_attr "length" "16")])
14832 (define_expand "prologue"
14835 "ix86_expand_prologue (); DONE;")
14837 (define_insn "set_got"
14838 [(set (match_operand:SI 0 "register_operand" "=r")
14839 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14840 (clobber (reg:CC FLAGS_REG))]
14842 { return output_set_got (operands[0], NULL_RTX); }
14843 [(set_attr "type" "multi")
14844 (set_attr "length" "12")])
14846 (define_insn "set_got_labelled"
14847 [(set (match_operand:SI 0 "register_operand" "=r")
14848 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14850 (clobber (reg:CC FLAGS_REG))]
14852 { return output_set_got (operands[0], operands[1]); }
14853 [(set_attr "type" "multi")
14854 (set_attr "length" "12")])
14856 (define_insn "set_got_rex64"
14857 [(set (match_operand:DI 0 "register_operand" "=r")
14858 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14860 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14861 [(set_attr "type" "lea")
14862 (set_attr "length" "6")])
14864 (define_insn "set_rip_rex64"
14865 [(set (match_operand:DI 0 "register_operand" "=r")
14866 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14868 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14869 [(set_attr "type" "lea")
14870 (set_attr "length" "6")])
14872 (define_insn "set_got_offset_rex64"
14873 [(set (match_operand:DI 0 "register_operand" "=r")
14874 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14876 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14877 [(set_attr "type" "imov")
14878 (set_attr "length" "11")])
14880 (define_expand "epilogue"
14883 "ix86_expand_epilogue (1); DONE;")
14885 (define_expand "sibcall_epilogue"
14888 "ix86_expand_epilogue (0); DONE;")
14890 (define_expand "eh_return"
14891 [(use (match_operand 0 "register_operand" ""))]
14894 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14896 /* Tricky bit: we write the address of the handler to which we will
14897 be returning into someone else's stack frame, one word below the
14898 stack address we wish to restore. */
14899 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14900 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14901 tmp = gen_rtx_MEM (Pmode, tmp);
14902 emit_move_insn (tmp, ra);
14904 if (Pmode == SImode)
14905 emit_jump_insn (gen_eh_return_si (sa));
14907 emit_jump_insn (gen_eh_return_di (sa));
14912 (define_insn_and_split "eh_return_si"
14914 (unspec [(match_operand:SI 0 "register_operand" "c")]
14915 UNSPEC_EH_RETURN))]
14920 "ix86_expand_epilogue (2); DONE;")
14922 (define_insn_and_split "eh_return_di"
14924 (unspec [(match_operand:DI 0 "register_operand" "c")]
14925 UNSPEC_EH_RETURN))]
14930 "ix86_expand_epilogue (2); DONE;")
14932 (define_insn "leave"
14933 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14934 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14935 (clobber (mem:BLK (scratch)))]
14938 [(set_attr "type" "leave")])
14940 (define_insn "leave_rex64"
14941 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14942 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14943 (clobber (mem:BLK (scratch)))]
14946 [(set_attr "type" "leave")])
14948 (define_expand "ffssi2"
14950 [(set (match_operand:SI 0 "register_operand" "")
14951 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14952 (clobber (match_scratch:SI 2 ""))
14953 (clobber (reg:CC FLAGS_REG))])]
14958 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14963 (define_expand "ffs_cmove"
14964 [(set (match_dup 2) (const_int -1))
14965 (parallel [(set (reg:CCZ FLAGS_REG)
14966 (compare:CCZ (match_operand:SI 1 "register_operand" "")
14968 (set (match_operand:SI 0 "nonimmediate_operand" "")
14969 (ctz:SI (match_dup 1)))])
14970 (set (match_dup 0) (if_then_else:SI
14971 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14974 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14975 (clobber (reg:CC FLAGS_REG))])]
14977 "operands[2] = gen_reg_rtx (SImode);")
14979 (define_insn_and_split "*ffs_no_cmove"
14980 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14981 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14982 (clobber (match_scratch:SI 2 "=&q"))
14983 (clobber (reg:CC FLAGS_REG))]
14986 "&& reload_completed"
14987 [(parallel [(set (reg:CCZ FLAGS_REG)
14988 (compare:CCZ (match_dup 1) (const_int 0)))
14989 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14990 (set (strict_low_part (match_dup 3))
14991 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14992 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14993 (clobber (reg:CC FLAGS_REG))])
14994 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14995 (clobber (reg:CC FLAGS_REG))])
14996 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14997 (clobber (reg:CC FLAGS_REG))])]
14999 operands[3] = gen_lowpart (QImode, operands[2]);
15000 ix86_expand_clear (operands[2]);
15003 (define_insn "*ffssi_1"
15004 [(set (reg:CCZ FLAGS_REG)
15005 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15007 (set (match_operand:SI 0 "register_operand" "=r")
15008 (ctz:SI (match_dup 1)))]
15010 "bsf{l}\t{%1, %0|%0, %1}"
15011 [(set_attr "prefix_0f" "1")])
15013 (define_expand "ffsdi2"
15014 [(set (match_dup 2) (const_int -1))
15015 (parallel [(set (reg:CCZ FLAGS_REG)
15016 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15018 (set (match_operand:DI 0 "nonimmediate_operand" "")
15019 (ctz:DI (match_dup 1)))])
15020 (set (match_dup 0) (if_then_else:DI
15021 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15024 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15025 (clobber (reg:CC FLAGS_REG))])]
15027 "operands[2] = gen_reg_rtx (DImode);")
15029 (define_insn "*ffsdi_1"
15030 [(set (reg:CCZ FLAGS_REG)
15031 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15033 (set (match_operand:DI 0 "register_operand" "=r")
15034 (ctz:DI (match_dup 1)))]
15036 "bsf{q}\t{%1, %0|%0, %1}"
15037 [(set_attr "prefix_0f" "1")])
15039 (define_insn "ctzsi2"
15040 [(set (match_operand:SI 0 "register_operand" "=r")
15041 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15042 (clobber (reg:CC FLAGS_REG))]
15044 "bsf{l}\t{%1, %0|%0, %1}"
15045 [(set_attr "prefix_0f" "1")])
15047 (define_insn "ctzdi2"
15048 [(set (match_operand:DI 0 "register_operand" "=r")
15049 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15050 (clobber (reg:CC FLAGS_REG))]
15052 "bsf{q}\t{%1, %0|%0, %1}"
15053 [(set_attr "prefix_0f" "1")])
15055 (define_expand "clzsi2"
15057 [(set (match_operand:SI 0 "register_operand" "")
15058 (minus:SI (const_int 31)
15059 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15060 (clobber (reg:CC FLAGS_REG))])
15062 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15063 (clobber (reg:CC FLAGS_REG))])]
15068 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15073 (define_insn "clzsi2_abm"
15074 [(set (match_operand:SI 0 "register_operand" "=r")
15075 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15076 (clobber (reg:CC FLAGS_REG))]
15078 "lzcnt{l}\t{%1, %0|%0, %1}"
15079 [(set_attr "prefix_rep" "1")
15080 (set_attr "type" "bitmanip")
15081 (set_attr "mode" "SI")])
15083 (define_insn "*bsr"
15084 [(set (match_operand:SI 0 "register_operand" "=r")
15085 (minus:SI (const_int 31)
15086 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15087 (clobber (reg:CC FLAGS_REG))]
15089 "bsr{l}\t{%1, %0|%0, %1}"
15090 [(set_attr "prefix_0f" "1")
15091 (set_attr "mode" "SI")])
15093 (define_insn "popcountsi2"
15094 [(set (match_operand:SI 0 "register_operand" "=r")
15095 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15096 (clobber (reg:CC FLAGS_REG))]
15098 "popcnt{l}\t{%1, %0|%0, %1}"
15099 [(set_attr "prefix_rep" "1")
15100 (set_attr "type" "bitmanip")
15101 (set_attr "mode" "SI")])
15103 (define_insn "*popcountsi2_cmp"
15104 [(set (reg FLAGS_REG)
15106 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15108 (set (match_operand:SI 0 "register_operand" "=r")
15109 (popcount:SI (match_dup 1)))]
15110 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15111 "popcnt{l}\t{%1, %0|%0, %1}"
15112 [(set_attr "prefix_rep" "1")
15113 (set_attr "type" "bitmanip")
15114 (set_attr "mode" "SI")])
15116 (define_insn "*popcountsi2_cmp_zext"
15117 [(set (reg FLAGS_REG)
15119 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15121 (set (match_operand:DI 0 "register_operand" "=r")
15122 (zero_extend:DI(popcount:SI (match_dup 1))))]
15123 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15124 "popcnt{l}\t{%1, %0|%0, %1}"
15125 [(set_attr "prefix_rep" "1")
15126 (set_attr "type" "bitmanip")
15127 (set_attr "mode" "SI")])
15129 (define_expand "bswapsi2"
15130 [(set (match_operand:SI 0 "register_operand" "")
15131 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15136 rtx x = operands[0];
15138 emit_move_insn (x, operands[1]);
15139 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15140 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15141 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15146 (define_insn "*bswapsi_1"
15147 [(set (match_operand:SI 0 "register_operand" "=r")
15148 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15151 [(set_attr "prefix_0f" "1")
15152 (set_attr "length" "2")])
15154 (define_insn "*bswaphi_lowpart_1"
15155 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15156 (bswap:HI (match_dup 0)))
15157 (clobber (reg:CC FLAGS_REG))]
15158 "TARGET_USE_XCHGB || optimize_size"
15160 xchg{b}\t{%h0, %b0|%b0, %h0}
15161 rol{w}\t{$8, %0|%0, 8}"
15162 [(set_attr "length" "2,4")
15163 (set_attr "mode" "QI,HI")])
15165 (define_insn "bswaphi_lowpart"
15166 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15167 (bswap:HI (match_dup 0)))
15168 (clobber (reg:CC FLAGS_REG))]
15170 "rol{w}\t{$8, %0|%0, 8}"
15171 [(set_attr "length" "4")
15172 (set_attr "mode" "HI")])
15174 (define_insn "bswapdi2"
15175 [(set (match_operand:DI 0 "register_operand" "=r")
15176 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15179 [(set_attr "prefix_0f" "1")
15180 (set_attr "length" "3")])
15182 (define_expand "clzdi2"
15184 [(set (match_operand:DI 0 "register_operand" "")
15185 (minus:DI (const_int 63)
15186 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15187 (clobber (reg:CC FLAGS_REG))])
15189 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15190 (clobber (reg:CC FLAGS_REG))])]
15195 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15200 (define_insn "clzdi2_abm"
15201 [(set (match_operand:DI 0 "register_operand" "=r")
15202 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15203 (clobber (reg:CC FLAGS_REG))]
15204 "TARGET_64BIT && TARGET_ABM"
15205 "lzcnt{q}\t{%1, %0|%0, %1}"
15206 [(set_attr "prefix_rep" "1")
15207 (set_attr "type" "bitmanip")
15208 (set_attr "mode" "DI")])
15210 (define_insn "*bsr_rex64"
15211 [(set (match_operand:DI 0 "register_operand" "=r")
15212 (minus:DI (const_int 63)
15213 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15214 (clobber (reg:CC FLAGS_REG))]
15216 "bsr{q}\t{%1, %0|%0, %1}"
15217 [(set_attr "prefix_0f" "1")
15218 (set_attr "mode" "DI")])
15220 (define_insn "popcountdi2"
15221 [(set (match_operand:DI 0 "register_operand" "=r")
15222 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15223 (clobber (reg:CC FLAGS_REG))]
15224 "TARGET_64BIT && TARGET_POPCNT"
15225 "popcnt{q}\t{%1, %0|%0, %1}"
15226 [(set_attr "prefix_rep" "1")
15227 (set_attr "type" "bitmanip")
15228 (set_attr "mode" "DI")])
15230 (define_insn "*popcountdi2_cmp"
15231 [(set (reg FLAGS_REG)
15233 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15235 (set (match_operand:DI 0 "register_operand" "=r")
15236 (popcount:DI (match_dup 1)))]
15237 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15238 "popcnt{q}\t{%1, %0|%0, %1}"
15239 [(set_attr "prefix_rep" "1")
15240 (set_attr "type" "bitmanip")
15241 (set_attr "mode" "DI")])
15243 (define_expand "clzhi2"
15245 [(set (match_operand:HI 0 "register_operand" "")
15246 (minus:HI (const_int 15)
15247 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15248 (clobber (reg:CC FLAGS_REG))])
15250 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15251 (clobber (reg:CC FLAGS_REG))])]
15256 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15261 (define_insn "clzhi2_abm"
15262 [(set (match_operand:HI 0 "register_operand" "=r")
15263 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15264 (clobber (reg:CC FLAGS_REG))]
15266 "lzcnt{w}\t{%1, %0|%0, %1}"
15267 [(set_attr "prefix_rep" "1")
15268 (set_attr "type" "bitmanip")
15269 (set_attr "mode" "HI")])
15271 (define_insn "*bsrhi"
15272 [(set (match_operand:HI 0 "register_operand" "=r")
15273 (minus:HI (const_int 15)
15274 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15275 (clobber (reg:CC FLAGS_REG))]
15277 "bsr{w}\t{%1, %0|%0, %1}"
15278 [(set_attr "prefix_0f" "1")
15279 (set_attr "mode" "HI")])
15281 (define_insn "popcounthi2"
15282 [(set (match_operand:HI 0 "register_operand" "=r")
15283 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15284 (clobber (reg:CC FLAGS_REG))]
15286 "popcnt{w}\t{%1, %0|%0, %1}"
15287 [(set_attr "prefix_rep" "1")
15288 (set_attr "type" "bitmanip")
15289 (set_attr "mode" "HI")])
15291 (define_insn "*popcounthi2_cmp"
15292 [(set (reg FLAGS_REG)
15294 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15296 (set (match_operand:HI 0 "register_operand" "=r")
15297 (popcount:HI (match_dup 1)))]
15298 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15299 "popcnt{w}\t{%1, %0|%0, %1}"
15300 [(set_attr "prefix_rep" "1")
15301 (set_attr "type" "bitmanip")
15302 (set_attr "mode" "HI")])
15304 (define_expand "paritydi2"
15305 [(set (match_operand:DI 0 "register_operand" "")
15306 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15309 rtx scratch = gen_reg_rtx (QImode);
15312 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15313 NULL_RTX, operands[1]));
15315 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15316 gen_rtx_REG (CCmode, FLAGS_REG),
15318 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15321 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15324 rtx tmp = gen_reg_rtx (SImode);
15326 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15327 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15332 (define_insn_and_split "paritydi2_cmp"
15333 [(set (reg:CC FLAGS_REG)
15334 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15335 (clobber (match_scratch:DI 0 "=r"))
15336 (clobber (match_scratch:SI 1 "=&r"))
15337 (clobber (match_scratch:HI 2 "=Q"))]
15340 "&& reload_completed"
15342 [(set (match_dup 1)
15343 (xor:SI (match_dup 1) (match_dup 4)))
15344 (clobber (reg:CC FLAGS_REG))])
15346 [(set (reg:CC FLAGS_REG)
15347 (parity:CC (match_dup 1)))
15348 (clobber (match_dup 1))
15349 (clobber (match_dup 2))])]
15351 operands[4] = gen_lowpart (SImode, operands[3]);
15355 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15356 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15359 operands[1] = gen_highpart (SImode, operands[3]);
15362 (define_expand "paritysi2"
15363 [(set (match_operand:SI 0 "register_operand" "")
15364 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15367 rtx scratch = gen_reg_rtx (QImode);
15370 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15372 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15373 gen_rtx_REG (CCmode, FLAGS_REG),
15375 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15377 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15381 (define_insn_and_split "paritysi2_cmp"
15382 [(set (reg:CC FLAGS_REG)
15383 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15384 (clobber (match_scratch:SI 0 "=r"))
15385 (clobber (match_scratch:HI 1 "=&Q"))]
15388 "&& reload_completed"
15390 [(set (match_dup 1)
15391 (xor:HI (match_dup 1) (match_dup 3)))
15392 (clobber (reg:CC FLAGS_REG))])
15394 [(set (reg:CC FLAGS_REG)
15395 (parity:CC (match_dup 1)))
15396 (clobber (match_dup 1))])]
15398 operands[3] = gen_lowpart (HImode, operands[2]);
15400 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15401 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15404 (define_insn "*parityhi2_cmp"
15405 [(set (reg:CC FLAGS_REG)
15406 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15407 (clobber (match_scratch:HI 0 "=Q"))]
15409 "xor{b}\t{%h0, %b0|%b0, %h0}"
15410 [(set_attr "length" "2")
15411 (set_attr "mode" "HI")])
15413 (define_insn "*parityqi2_cmp"
15414 [(set (reg:CC FLAGS_REG)
15415 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15418 [(set_attr "length" "2")
15419 (set_attr "mode" "QI")])
15421 ;; Thread-local storage patterns for ELF.
15423 ;; Note that these code sequences must appear exactly as shown
15424 ;; in order to allow linker relaxation.
15426 (define_insn "*tls_global_dynamic_32_gnu"
15427 [(set (match_operand:SI 0 "register_operand" "=a")
15428 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15429 (match_operand:SI 2 "tls_symbolic_operand" "")
15430 (match_operand:SI 3 "call_insn_operand" "")]
15432 (clobber (match_scratch:SI 4 "=d"))
15433 (clobber (match_scratch:SI 5 "=c"))
15434 (clobber (reg:CC FLAGS_REG))]
15435 "!TARGET_64BIT && TARGET_GNU_TLS"
15436 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15437 [(set_attr "type" "multi")
15438 (set_attr "length" "12")])
15440 (define_insn "*tls_global_dynamic_32_sun"
15441 [(set (match_operand:SI 0 "register_operand" "=a")
15442 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15443 (match_operand:SI 2 "tls_symbolic_operand" "")
15444 (match_operand:SI 3 "call_insn_operand" "")]
15446 (clobber (match_scratch:SI 4 "=d"))
15447 (clobber (match_scratch:SI 5 "=c"))
15448 (clobber (reg:CC FLAGS_REG))]
15449 "!TARGET_64BIT && TARGET_SUN_TLS"
15450 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15451 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15452 [(set_attr "type" "multi")
15453 (set_attr "length" "14")])
15455 (define_expand "tls_global_dynamic_32"
15456 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15459 (match_operand:SI 1 "tls_symbolic_operand" "")
15462 (clobber (match_scratch:SI 4 ""))
15463 (clobber (match_scratch:SI 5 ""))
15464 (clobber (reg:CC FLAGS_REG))])]
15468 operands[2] = pic_offset_table_rtx;
15471 operands[2] = gen_reg_rtx (Pmode);
15472 emit_insn (gen_set_got (operands[2]));
15474 if (TARGET_GNU2_TLS)
15476 emit_insn (gen_tls_dynamic_gnu2_32
15477 (operands[0], operands[1], operands[2]));
15480 operands[3] = ix86_tls_get_addr ();
15483 (define_insn "*tls_global_dynamic_64"
15484 [(set (match_operand:DI 0 "register_operand" "=a")
15485 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15486 (match_operand:DI 3 "" "")))
15487 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15490 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15491 [(set_attr "type" "multi")
15492 (set_attr "length" "16")])
15494 (define_expand "tls_global_dynamic_64"
15495 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15496 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15497 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15501 if (TARGET_GNU2_TLS)
15503 emit_insn (gen_tls_dynamic_gnu2_64
15504 (operands[0], operands[1]));
15507 operands[2] = ix86_tls_get_addr ();
15510 (define_insn "*tls_local_dynamic_base_32_gnu"
15511 [(set (match_operand:SI 0 "register_operand" "=a")
15512 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15513 (match_operand:SI 2 "call_insn_operand" "")]
15514 UNSPEC_TLS_LD_BASE))
15515 (clobber (match_scratch:SI 3 "=d"))
15516 (clobber (match_scratch:SI 4 "=c"))
15517 (clobber (reg:CC FLAGS_REG))]
15518 "!TARGET_64BIT && TARGET_GNU_TLS"
15519 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15520 [(set_attr "type" "multi")
15521 (set_attr "length" "11")])
15523 (define_insn "*tls_local_dynamic_base_32_sun"
15524 [(set (match_operand:SI 0 "register_operand" "=a")
15525 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15526 (match_operand:SI 2 "call_insn_operand" "")]
15527 UNSPEC_TLS_LD_BASE))
15528 (clobber (match_scratch:SI 3 "=d"))
15529 (clobber (match_scratch:SI 4 "=c"))
15530 (clobber (reg:CC FLAGS_REG))]
15531 "!TARGET_64BIT && TARGET_SUN_TLS"
15532 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15533 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15534 [(set_attr "type" "multi")
15535 (set_attr "length" "13")])
15537 (define_expand "tls_local_dynamic_base_32"
15538 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15539 (unspec:SI [(match_dup 1) (match_dup 2)]
15540 UNSPEC_TLS_LD_BASE))
15541 (clobber (match_scratch:SI 3 ""))
15542 (clobber (match_scratch:SI 4 ""))
15543 (clobber (reg:CC FLAGS_REG))])]
15547 operands[1] = pic_offset_table_rtx;
15550 operands[1] = gen_reg_rtx (Pmode);
15551 emit_insn (gen_set_got (operands[1]));
15553 if (TARGET_GNU2_TLS)
15555 emit_insn (gen_tls_dynamic_gnu2_32
15556 (operands[0], ix86_tls_module_base (), operands[1]));
15559 operands[2] = ix86_tls_get_addr ();
15562 (define_insn "*tls_local_dynamic_base_64"
15563 [(set (match_operand:DI 0 "register_operand" "=a")
15564 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15565 (match_operand:DI 2 "" "")))
15566 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15568 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15569 [(set_attr "type" "multi")
15570 (set_attr "length" "12")])
15572 (define_expand "tls_local_dynamic_base_64"
15573 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15574 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15575 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15578 if (TARGET_GNU2_TLS)
15580 emit_insn (gen_tls_dynamic_gnu2_64
15581 (operands[0], ix86_tls_module_base ()));
15584 operands[1] = ix86_tls_get_addr ();
15587 ;; Local dynamic of a single variable is a lose. Show combine how
15588 ;; to convert that back to global dynamic.
15590 (define_insn_and_split "*tls_local_dynamic_32_once"
15591 [(set (match_operand:SI 0 "register_operand" "=a")
15592 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15593 (match_operand:SI 2 "call_insn_operand" "")]
15594 UNSPEC_TLS_LD_BASE)
15595 (const:SI (unspec:SI
15596 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15598 (clobber (match_scratch:SI 4 "=d"))
15599 (clobber (match_scratch:SI 5 "=c"))
15600 (clobber (reg:CC FLAGS_REG))]
15604 [(parallel [(set (match_dup 0)
15605 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15607 (clobber (match_dup 4))
15608 (clobber (match_dup 5))
15609 (clobber (reg:CC FLAGS_REG))])]
15612 ;; Load and add the thread base pointer from %gs:0.
15614 (define_insn "*load_tp_si"
15615 [(set (match_operand:SI 0 "register_operand" "=r")
15616 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15618 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15619 [(set_attr "type" "imov")
15620 (set_attr "modrm" "0")
15621 (set_attr "length" "7")
15622 (set_attr "memory" "load")
15623 (set_attr "imm_disp" "false")])
15625 (define_insn "*add_tp_si"
15626 [(set (match_operand:SI 0 "register_operand" "=r")
15627 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15628 (match_operand:SI 1 "register_operand" "0")))
15629 (clobber (reg:CC FLAGS_REG))]
15631 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15632 [(set_attr "type" "alu")
15633 (set_attr "modrm" "0")
15634 (set_attr "length" "7")
15635 (set_attr "memory" "load")
15636 (set_attr "imm_disp" "false")])
15638 (define_insn "*load_tp_di"
15639 [(set (match_operand:DI 0 "register_operand" "=r")
15640 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15642 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15643 [(set_attr "type" "imov")
15644 (set_attr "modrm" "0")
15645 (set_attr "length" "7")
15646 (set_attr "memory" "load")
15647 (set_attr "imm_disp" "false")])
15649 (define_insn "*add_tp_di"
15650 [(set (match_operand:DI 0 "register_operand" "=r")
15651 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15652 (match_operand:DI 1 "register_operand" "0")))
15653 (clobber (reg:CC FLAGS_REG))]
15655 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15656 [(set_attr "type" "alu")
15657 (set_attr "modrm" "0")
15658 (set_attr "length" "7")
15659 (set_attr "memory" "load")
15660 (set_attr "imm_disp" "false")])
15662 ;; GNU2 TLS patterns can be split.
15664 (define_expand "tls_dynamic_gnu2_32"
15665 [(set (match_dup 3)
15666 (plus:SI (match_operand:SI 2 "register_operand" "")
15668 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15671 [(set (match_operand:SI 0 "register_operand" "")
15672 (unspec:SI [(match_dup 1) (match_dup 3)
15673 (match_dup 2) (reg:SI SP_REG)]
15675 (clobber (reg:CC FLAGS_REG))])]
15676 "!TARGET_64BIT && TARGET_GNU2_TLS"
15678 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15679 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15682 (define_insn "*tls_dynamic_lea_32"
15683 [(set (match_operand:SI 0 "register_operand" "=r")
15684 (plus:SI (match_operand:SI 1 "register_operand" "b")
15686 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15687 UNSPEC_TLSDESC))))]
15688 "!TARGET_64BIT && TARGET_GNU2_TLS"
15689 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15690 [(set_attr "type" "lea")
15691 (set_attr "mode" "SI")
15692 (set_attr "length" "6")
15693 (set_attr "length_address" "4")])
15695 (define_insn "*tls_dynamic_call_32"
15696 [(set (match_operand:SI 0 "register_operand" "=a")
15697 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15698 (match_operand:SI 2 "register_operand" "0")
15699 ;; we have to make sure %ebx still points to the GOT
15700 (match_operand:SI 3 "register_operand" "b")
15703 (clobber (reg:CC FLAGS_REG))]
15704 "!TARGET_64BIT && TARGET_GNU2_TLS"
15705 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15706 [(set_attr "type" "call")
15707 (set_attr "length" "2")
15708 (set_attr "length_address" "0")])
15710 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15711 [(set (match_operand:SI 0 "register_operand" "=&a")
15713 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15714 (match_operand:SI 4 "" "")
15715 (match_operand:SI 2 "register_operand" "b")
15718 (const:SI (unspec:SI
15719 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15721 (clobber (reg:CC FLAGS_REG))]
15722 "!TARGET_64BIT && TARGET_GNU2_TLS"
15725 [(set (match_dup 0) (match_dup 5))]
15727 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15728 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15731 (define_expand "tls_dynamic_gnu2_64"
15732 [(set (match_dup 2)
15733 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15736 [(set (match_operand:DI 0 "register_operand" "")
15737 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15739 (clobber (reg:CC FLAGS_REG))])]
15740 "TARGET_64BIT && TARGET_GNU2_TLS"
15742 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15743 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15746 (define_insn "*tls_dynamic_lea_64"
15747 [(set (match_operand:DI 0 "register_operand" "=r")
15748 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15750 "TARGET_64BIT && TARGET_GNU2_TLS"
15751 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15752 [(set_attr "type" "lea")
15753 (set_attr "mode" "DI")
15754 (set_attr "length" "7")
15755 (set_attr "length_address" "4")])
15757 (define_insn "*tls_dynamic_call_64"
15758 [(set (match_operand:DI 0 "register_operand" "=a")
15759 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15760 (match_operand:DI 2 "register_operand" "0")
15763 (clobber (reg:CC FLAGS_REG))]
15764 "TARGET_64BIT && TARGET_GNU2_TLS"
15765 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15766 [(set_attr "type" "call")
15767 (set_attr "length" "2")
15768 (set_attr "length_address" "0")])
15770 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15771 [(set (match_operand:DI 0 "register_operand" "=&a")
15773 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15774 (match_operand:DI 3 "" "")
15777 (const:DI (unspec:DI
15778 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15780 (clobber (reg:CC FLAGS_REG))]
15781 "TARGET_64BIT && TARGET_GNU2_TLS"
15784 [(set (match_dup 0) (match_dup 4))]
15786 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15787 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15792 ;; These patterns match the binary 387 instructions for addM3, subM3,
15793 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15794 ;; SFmode. The first is the normal insn, the second the same insn but
15795 ;; with one operand a conversion, and the third the same insn but with
15796 ;; the other operand a conversion. The conversion may be SFmode or
15797 ;; SImode if the target mode DFmode, but only SImode if the target mode
15800 ;; Gcc is slightly more smart about handling normal two address instructions
15801 ;; so use special patterns for add and mull.
15803 (define_insn "*fop_sf_comm_mixed"
15804 [(set (match_operand:SF 0 "register_operand" "=f,x")
15805 (match_operator:SF 3 "binary_fp_operator"
15806 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15807 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15808 "TARGET_MIX_SSE_I387
15809 && COMMUTATIVE_ARITH_P (operands[3])
15810 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15811 "* return output_387_binary_op (insn, operands);"
15812 [(set (attr "type")
15813 (if_then_else (eq_attr "alternative" "1")
15814 (if_then_else (match_operand:SF 3 "mult_operator" "")
15815 (const_string "ssemul")
15816 (const_string "sseadd"))
15817 (if_then_else (match_operand:SF 3 "mult_operator" "")
15818 (const_string "fmul")
15819 (const_string "fop"))))
15820 (set_attr "mode" "SF")])
15822 (define_insn "*fop_sf_comm_sse"
15823 [(set (match_operand:SF 0 "register_operand" "=x")
15824 (match_operator:SF 3 "binary_fp_operator"
15825 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15826 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15828 && COMMUTATIVE_ARITH_P (operands[3])
15829 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15830 "* return output_387_binary_op (insn, operands);"
15831 [(set (attr "type")
15832 (if_then_else (match_operand:SF 3 "mult_operator" "")
15833 (const_string "ssemul")
15834 (const_string "sseadd")))
15835 (set_attr "mode" "SF")])
15837 (define_insn "*fop_sf_comm_i387"
15838 [(set (match_operand:SF 0 "register_operand" "=f")
15839 (match_operator:SF 3 "binary_fp_operator"
15840 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15841 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15843 && COMMUTATIVE_ARITH_P (operands[3])
15844 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15845 "* return output_387_binary_op (insn, operands);"
15846 [(set (attr "type")
15847 (if_then_else (match_operand:SF 3 "mult_operator" "")
15848 (const_string "fmul")
15849 (const_string "fop")))
15850 (set_attr "mode" "SF")])
15852 (define_insn "*fop_sf_1_mixed"
15853 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15854 (match_operator:SF 3 "binary_fp_operator"
15855 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15856 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15857 "TARGET_MIX_SSE_I387
15858 && !COMMUTATIVE_ARITH_P (operands[3])
15859 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15860 "* return output_387_binary_op (insn, operands);"
15861 [(set (attr "type")
15862 (cond [(and (eq_attr "alternative" "2")
15863 (match_operand:SF 3 "mult_operator" ""))
15864 (const_string "ssemul")
15865 (and (eq_attr "alternative" "2")
15866 (match_operand:SF 3 "div_operator" ""))
15867 (const_string "ssediv")
15868 (eq_attr "alternative" "2")
15869 (const_string "sseadd")
15870 (match_operand:SF 3 "mult_operator" "")
15871 (const_string "fmul")
15872 (match_operand:SF 3 "div_operator" "")
15873 (const_string "fdiv")
15875 (const_string "fop")))
15876 (set_attr "mode" "SF")])
15878 (define_insn "*rcpsf2_sse"
15879 [(set (match_operand:SF 0 "register_operand" "=x")
15880 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15883 "rcpss\t{%1, %0|%0, %1}"
15884 [(set_attr "type" "sse")
15885 (set_attr "mode" "SF")])
15887 (define_insn "*fop_sf_1_sse"
15888 [(set (match_operand:SF 0 "register_operand" "=x")
15889 (match_operator:SF 3 "binary_fp_operator"
15890 [(match_operand:SF 1 "register_operand" "0")
15891 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15893 && !COMMUTATIVE_ARITH_P (operands[3])"
15894 "* return output_387_binary_op (insn, operands);"
15895 [(set (attr "type")
15896 (cond [(match_operand:SF 3 "mult_operator" "")
15897 (const_string "ssemul")
15898 (match_operand:SF 3 "div_operator" "")
15899 (const_string "ssediv")
15901 (const_string "sseadd")))
15902 (set_attr "mode" "SF")])
15904 ;; This pattern is not fully shadowed by the pattern above.
15905 (define_insn "*fop_sf_1_i387"
15906 [(set (match_operand:SF 0 "register_operand" "=f,f")
15907 (match_operator:SF 3 "binary_fp_operator"
15908 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15909 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15910 "TARGET_80387 && !TARGET_SSE_MATH
15911 && !COMMUTATIVE_ARITH_P (operands[3])
15912 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15913 "* return output_387_binary_op (insn, operands);"
15914 [(set (attr "type")
15915 (cond [(match_operand:SF 3 "mult_operator" "")
15916 (const_string "fmul")
15917 (match_operand:SF 3 "div_operator" "")
15918 (const_string "fdiv")
15920 (const_string "fop")))
15921 (set_attr "mode" "SF")])
15923 ;; ??? Add SSE splitters for these!
15924 (define_insn "*fop_sf_2<mode>_i387"
15925 [(set (match_operand:SF 0 "register_operand" "=f,f")
15926 (match_operator:SF 3 "binary_fp_operator"
15927 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15928 (match_operand:SF 2 "register_operand" "0,0")]))]
15929 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15930 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15931 [(set (attr "type")
15932 (cond [(match_operand:SF 3 "mult_operator" "")
15933 (const_string "fmul")
15934 (match_operand:SF 3 "div_operator" "")
15935 (const_string "fdiv")
15937 (const_string "fop")))
15938 (set_attr "fp_int_src" "true")
15939 (set_attr "mode" "<MODE>")])
15941 (define_insn "*fop_sf_3<mode>_i387"
15942 [(set (match_operand:SF 0 "register_operand" "=f,f")
15943 (match_operator:SF 3 "binary_fp_operator"
15944 [(match_operand:SF 1 "register_operand" "0,0")
15945 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15946 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15947 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15948 [(set (attr "type")
15949 (cond [(match_operand:SF 3 "mult_operator" "")
15950 (const_string "fmul")
15951 (match_operand:SF 3 "div_operator" "")
15952 (const_string "fdiv")
15954 (const_string "fop")))
15955 (set_attr "fp_int_src" "true")
15956 (set_attr "mode" "<MODE>")])
15958 (define_insn "*fop_df_comm_mixed"
15959 [(set (match_operand:DF 0 "register_operand" "=f,x")
15960 (match_operator:DF 3 "binary_fp_operator"
15961 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15962 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15963 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15964 && COMMUTATIVE_ARITH_P (operands[3])
15965 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15966 "* return output_387_binary_op (insn, operands);"
15967 [(set (attr "type")
15968 (if_then_else (eq_attr "alternative" "1")
15969 (if_then_else (match_operand:DF 3 "mult_operator" "")
15970 (const_string "ssemul")
15971 (const_string "sseadd"))
15972 (if_then_else (match_operand:DF 3 "mult_operator" "")
15973 (const_string "fmul")
15974 (const_string "fop"))))
15975 (set_attr "mode" "DF")])
15977 (define_insn "*fop_df_comm_sse"
15978 [(set (match_operand:DF 0 "register_operand" "=x")
15979 (match_operator:DF 3 "binary_fp_operator"
15980 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15981 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15982 "TARGET_SSE2 && TARGET_SSE_MATH
15983 && COMMUTATIVE_ARITH_P (operands[3])
15984 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15985 "* return output_387_binary_op (insn, operands);"
15986 [(set (attr "type")
15987 (if_then_else (match_operand:DF 3 "mult_operator" "")
15988 (const_string "ssemul")
15989 (const_string "sseadd")))
15990 (set_attr "mode" "DF")])
15992 (define_insn "*fop_df_comm_i387"
15993 [(set (match_operand:DF 0 "register_operand" "=f")
15994 (match_operator:DF 3 "binary_fp_operator"
15995 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15996 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15998 && COMMUTATIVE_ARITH_P (operands[3])
15999 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16000 "* return output_387_binary_op (insn, operands);"
16001 [(set (attr "type")
16002 (if_then_else (match_operand:DF 3 "mult_operator" "")
16003 (const_string "fmul")
16004 (const_string "fop")))
16005 (set_attr "mode" "DF")])
16007 (define_insn "*fop_df_1_mixed"
16008 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16009 (match_operator:DF 3 "binary_fp_operator"
16010 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16011 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16012 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16013 && !COMMUTATIVE_ARITH_P (operands[3])
16014 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16015 "* return output_387_binary_op (insn, operands);"
16016 [(set (attr "type")
16017 (cond [(and (eq_attr "alternative" "2")
16018 (match_operand:DF 3 "mult_operator" ""))
16019 (const_string "ssemul")
16020 (and (eq_attr "alternative" "2")
16021 (match_operand:DF 3 "div_operator" ""))
16022 (const_string "ssediv")
16023 (eq_attr "alternative" "2")
16024 (const_string "sseadd")
16025 (match_operand:DF 3 "mult_operator" "")
16026 (const_string "fmul")
16027 (match_operand:DF 3 "div_operator" "")
16028 (const_string "fdiv")
16030 (const_string "fop")))
16031 (set_attr "mode" "DF")])
16033 (define_insn "*fop_df_1_sse"
16034 [(set (match_operand:DF 0 "register_operand" "=x")
16035 (match_operator:DF 3 "binary_fp_operator"
16036 [(match_operand:DF 1 "register_operand" "0")
16037 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16038 "TARGET_SSE2 && TARGET_SSE_MATH
16039 && !COMMUTATIVE_ARITH_P (operands[3])"
16040 "* return output_387_binary_op (insn, operands);"
16041 [(set_attr "mode" "DF")
16043 (cond [(match_operand:DF 3 "mult_operator" "")
16044 (const_string "ssemul")
16045 (match_operand:DF 3 "div_operator" "")
16046 (const_string "ssediv")
16048 (const_string "sseadd")))])
16050 ;; This pattern is not fully shadowed by the pattern above.
16051 (define_insn "*fop_df_1_i387"
16052 [(set (match_operand:DF 0 "register_operand" "=f,f")
16053 (match_operator:DF 3 "binary_fp_operator"
16054 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16055 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16056 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16057 && !COMMUTATIVE_ARITH_P (operands[3])
16058 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16059 "* return output_387_binary_op (insn, operands);"
16060 [(set (attr "type")
16061 (cond [(match_operand:DF 3 "mult_operator" "")
16062 (const_string "fmul")
16063 (match_operand:DF 3 "div_operator" "")
16064 (const_string "fdiv")
16066 (const_string "fop")))
16067 (set_attr "mode" "DF")])
16069 ;; ??? Add SSE splitters for these!
16070 (define_insn "*fop_df_2<mode>_i387"
16071 [(set (match_operand:DF 0 "register_operand" "=f,f")
16072 (match_operator:DF 3 "binary_fp_operator"
16073 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16074 (match_operand:DF 2 "register_operand" "0,0")]))]
16075 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16076 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16077 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16078 [(set (attr "type")
16079 (cond [(match_operand:DF 3 "mult_operator" "")
16080 (const_string "fmul")
16081 (match_operand:DF 3 "div_operator" "")
16082 (const_string "fdiv")
16084 (const_string "fop")))
16085 (set_attr "fp_int_src" "true")
16086 (set_attr "mode" "<MODE>")])
16088 (define_insn "*fop_df_3<mode>_i387"
16089 [(set (match_operand:DF 0 "register_operand" "=f,f")
16090 (match_operator:DF 3 "binary_fp_operator"
16091 [(match_operand:DF 1 "register_operand" "0,0")
16092 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16093 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16094 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16095 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16096 [(set (attr "type")
16097 (cond [(match_operand:DF 3 "mult_operator" "")
16098 (const_string "fmul")
16099 (match_operand:DF 3 "div_operator" "")
16100 (const_string "fdiv")
16102 (const_string "fop")))
16103 (set_attr "fp_int_src" "true")
16104 (set_attr "mode" "<MODE>")])
16106 (define_insn "*fop_df_4_i387"
16107 [(set (match_operand:DF 0 "register_operand" "=f,f")
16108 (match_operator:DF 3 "binary_fp_operator"
16109 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16110 (match_operand:DF 2 "register_operand" "0,f")]))]
16111 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16112 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16113 "* return output_387_binary_op (insn, operands);"
16114 [(set (attr "type")
16115 (cond [(match_operand:DF 3 "mult_operator" "")
16116 (const_string "fmul")
16117 (match_operand:DF 3 "div_operator" "")
16118 (const_string "fdiv")
16120 (const_string "fop")))
16121 (set_attr "mode" "SF")])
16123 (define_insn "*fop_df_5_i387"
16124 [(set (match_operand:DF 0 "register_operand" "=f,f")
16125 (match_operator:DF 3 "binary_fp_operator"
16126 [(match_operand:DF 1 "register_operand" "0,f")
16128 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16129 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16130 "* return output_387_binary_op (insn, operands);"
16131 [(set (attr "type")
16132 (cond [(match_operand:DF 3 "mult_operator" "")
16133 (const_string "fmul")
16134 (match_operand:DF 3 "div_operator" "")
16135 (const_string "fdiv")
16137 (const_string "fop")))
16138 (set_attr "mode" "SF")])
16140 (define_insn "*fop_df_6_i387"
16141 [(set (match_operand:DF 0 "register_operand" "=f,f")
16142 (match_operator:DF 3 "binary_fp_operator"
16144 (match_operand:SF 1 "register_operand" "0,f"))
16146 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16147 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16148 "* return output_387_binary_op (insn, operands);"
16149 [(set (attr "type")
16150 (cond [(match_operand:DF 3 "mult_operator" "")
16151 (const_string "fmul")
16152 (match_operand:DF 3 "div_operator" "")
16153 (const_string "fdiv")
16155 (const_string "fop")))
16156 (set_attr "mode" "SF")])
16158 (define_insn "*fop_xf_comm_i387"
16159 [(set (match_operand:XF 0 "register_operand" "=f")
16160 (match_operator:XF 3 "binary_fp_operator"
16161 [(match_operand:XF 1 "register_operand" "%0")
16162 (match_operand:XF 2 "register_operand" "f")]))]
16164 && COMMUTATIVE_ARITH_P (operands[3])"
16165 "* return output_387_binary_op (insn, operands);"
16166 [(set (attr "type")
16167 (if_then_else (match_operand:XF 3 "mult_operator" "")
16168 (const_string "fmul")
16169 (const_string "fop")))
16170 (set_attr "mode" "XF")])
16172 (define_insn "*fop_xf_1_i387"
16173 [(set (match_operand:XF 0 "register_operand" "=f,f")
16174 (match_operator:XF 3 "binary_fp_operator"
16175 [(match_operand:XF 1 "register_operand" "0,f")
16176 (match_operand:XF 2 "register_operand" "f,0")]))]
16178 && !COMMUTATIVE_ARITH_P (operands[3])"
16179 "* return output_387_binary_op (insn, operands);"
16180 [(set (attr "type")
16181 (cond [(match_operand:XF 3 "mult_operator" "")
16182 (const_string "fmul")
16183 (match_operand:XF 3 "div_operator" "")
16184 (const_string "fdiv")
16186 (const_string "fop")))
16187 (set_attr "mode" "XF")])
16189 (define_insn "*fop_xf_2<mode>_i387"
16190 [(set (match_operand:XF 0 "register_operand" "=f,f")
16191 (match_operator:XF 3 "binary_fp_operator"
16192 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16193 (match_operand:XF 2 "register_operand" "0,0")]))]
16194 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16195 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16196 [(set (attr "type")
16197 (cond [(match_operand:XF 3 "mult_operator" "")
16198 (const_string "fmul")
16199 (match_operand:XF 3 "div_operator" "")
16200 (const_string "fdiv")
16202 (const_string "fop")))
16203 (set_attr "fp_int_src" "true")
16204 (set_attr "mode" "<MODE>")])
16206 (define_insn "*fop_xf_3<mode>_i387"
16207 [(set (match_operand:XF 0 "register_operand" "=f,f")
16208 (match_operator:XF 3 "binary_fp_operator"
16209 [(match_operand:XF 1 "register_operand" "0,0")
16210 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16211 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16212 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16213 [(set (attr "type")
16214 (cond [(match_operand:XF 3 "mult_operator" "")
16215 (const_string "fmul")
16216 (match_operand:XF 3 "div_operator" "")
16217 (const_string "fdiv")
16219 (const_string "fop")))
16220 (set_attr "fp_int_src" "true")
16221 (set_attr "mode" "<MODE>")])
16223 (define_insn "*fop_xf_4_i387"
16224 [(set (match_operand:XF 0 "register_operand" "=f,f")
16225 (match_operator:XF 3 "binary_fp_operator"
16227 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16228 (match_operand:XF 2 "register_operand" "0,f")]))]
16230 "* return output_387_binary_op (insn, operands);"
16231 [(set (attr "type")
16232 (cond [(match_operand:XF 3 "mult_operator" "")
16233 (const_string "fmul")
16234 (match_operand:XF 3 "div_operator" "")
16235 (const_string "fdiv")
16237 (const_string "fop")))
16238 (set_attr "mode" "SF")])
16240 (define_insn "*fop_xf_5_i387"
16241 [(set (match_operand:XF 0 "register_operand" "=f,f")
16242 (match_operator:XF 3 "binary_fp_operator"
16243 [(match_operand:XF 1 "register_operand" "0,f")
16245 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16247 "* return output_387_binary_op (insn, operands);"
16248 [(set (attr "type")
16249 (cond [(match_operand:XF 3 "mult_operator" "")
16250 (const_string "fmul")
16251 (match_operand:XF 3 "div_operator" "")
16252 (const_string "fdiv")
16254 (const_string "fop")))
16255 (set_attr "mode" "SF")])
16257 (define_insn "*fop_xf_6_i387"
16258 [(set (match_operand:XF 0 "register_operand" "=f,f")
16259 (match_operator:XF 3 "binary_fp_operator"
16261 (match_operand:MODEF 1 "register_operand" "0,f"))
16263 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16265 "* return output_387_binary_op (insn, operands);"
16266 [(set (attr "type")
16267 (cond [(match_operand:XF 3 "mult_operator" "")
16268 (const_string "fmul")
16269 (match_operand:XF 3 "div_operator" "")
16270 (const_string "fdiv")
16272 (const_string "fop")))
16273 (set_attr "mode" "SF")])
16276 [(set (match_operand 0 "register_operand" "")
16277 (match_operator 3 "binary_fp_operator"
16278 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16279 (match_operand 2 "register_operand" "")]))]
16281 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16284 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16285 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16286 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16287 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16288 GET_MODE (operands[3]),
16291 ix86_free_from_memory (GET_MODE (operands[1]));
16296 [(set (match_operand 0 "register_operand" "")
16297 (match_operator 3 "binary_fp_operator"
16298 [(match_operand 1 "register_operand" "")
16299 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16301 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16304 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16305 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16306 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16307 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16308 GET_MODE (operands[3]),
16311 ix86_free_from_memory (GET_MODE (operands[2]));
16315 ;; FPU special functions.
16317 ;; This pattern implements a no-op XFmode truncation for
16318 ;; all fancy i386 XFmode math functions.
16320 (define_insn "truncxf<mode>2_i387_noop_unspec"
16321 [(set (match_operand:MODEF 0 "register_operand" "=f")
16322 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16323 UNSPEC_TRUNC_NOOP))]
16324 "TARGET_USE_FANCY_MATH_387"
16325 "* return output_387_reg_move (insn, operands);"
16326 [(set_attr "type" "fmov")
16327 (set_attr "mode" "<MODE>")])
16329 (define_insn "sqrtxf2"
16330 [(set (match_operand:XF 0 "register_operand" "=f")
16331 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16332 "TARGET_USE_FANCY_MATH_387"
16334 [(set_attr "type" "fpspc")
16335 (set_attr "mode" "XF")
16336 (set_attr "athlon_decode" "direct")
16337 (set_attr "amdfam10_decode" "direct")])
16339 (define_insn "sqrt_extend<mode>xf2_i387"
16340 [(set (match_operand:XF 0 "register_operand" "=f")
16343 (match_operand:MODEF 1 "register_operand" "0"))))]
16344 "TARGET_USE_FANCY_MATH_387"
16346 [(set_attr "type" "fpspc")
16347 (set_attr "mode" "XF")
16348 (set_attr "athlon_decode" "direct")
16349 (set_attr "amdfam10_decode" "direct")])
16351 (define_insn "*rsqrtsf2_sse"
16352 [(set (match_operand:SF 0 "register_operand" "=x")
16353 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16356 "rsqrtss\t{%1, %0|%0, %1}"
16357 [(set_attr "type" "sse")
16358 (set_attr "mode" "SF")])
16360 (define_expand "rsqrtsf2"
16361 [(set (match_operand:SF 0 "register_operand" "")
16362 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16366 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16370 (define_insn "*sqrt<mode>2_sse"
16371 [(set (match_operand:MODEF 0 "register_operand" "=x")
16373 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16374 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16375 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16376 [(set_attr "type" "sse")
16377 (set_attr "mode" "<MODE>")
16378 (set_attr "athlon_decode" "*")
16379 (set_attr "amdfam10_decode" "*")])
16381 (define_expand "sqrt<mode>2"
16382 [(set (match_operand:MODEF 0 "register_operand" "")
16384 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16385 "TARGET_USE_FANCY_MATH_387
16386 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16388 if (<MODE>mode == SFmode
16389 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16390 && flag_finite_math_only && !flag_trapping_math
16391 && flag_unsafe_math_optimizations)
16393 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16397 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16399 rtx op0 = gen_reg_rtx (XFmode);
16400 rtx op1 = force_reg (<MODE>mode, operands[1]);
16402 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16403 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16408 (define_insn "fpremxf4_i387"
16409 [(set (match_operand:XF 0 "register_operand" "=f")
16410 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16411 (match_operand:XF 3 "register_operand" "1")]
16413 (set (match_operand:XF 1 "register_operand" "=u")
16414 (unspec:XF [(match_dup 2) (match_dup 3)]
16416 (set (reg:CCFP FPSR_REG)
16417 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16419 "TARGET_USE_FANCY_MATH_387"
16421 [(set_attr "type" "fpspc")
16422 (set_attr "mode" "XF")])
16424 (define_expand "fmodxf3"
16425 [(use (match_operand:XF 0 "register_operand" ""))
16426 (use (match_operand:XF 1 "general_operand" ""))
16427 (use (match_operand:XF 2 "general_operand" ""))]
16428 "TARGET_USE_FANCY_MATH_387"
16430 rtx label = gen_label_rtx ();
16432 rtx op1 = gen_reg_rtx (XFmode);
16433 rtx op2 = gen_reg_rtx (XFmode);
16435 emit_move_insn (op1, operands[1]);
16436 emit_move_insn (op2, operands[2]);
16438 emit_label (label);
16439 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16440 ix86_emit_fp_unordered_jump (label);
16441 LABEL_NUSES (label) = 1;
16443 emit_move_insn (operands[0], op1);
16447 (define_expand "fmod<mode>3"
16448 [(use (match_operand:MODEF 0 "register_operand" ""))
16449 (use (match_operand:MODEF 1 "general_operand" ""))
16450 (use (match_operand:MODEF 2 "general_operand" ""))]
16451 "TARGET_USE_FANCY_MATH_387"
16453 rtx label = gen_label_rtx ();
16455 rtx op1 = gen_reg_rtx (XFmode);
16456 rtx op2 = gen_reg_rtx (XFmode);
16458 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16459 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16461 emit_label (label);
16462 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16463 ix86_emit_fp_unordered_jump (label);
16464 LABEL_NUSES (label) = 1;
16466 /* Truncate the result properly for strict SSE math. */
16467 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16468 && !TARGET_MIX_SSE_I387)
16469 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16471 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16476 (define_insn "fprem1xf4_i387"
16477 [(set (match_operand:XF 0 "register_operand" "=f")
16478 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16479 (match_operand:XF 3 "register_operand" "1")]
16481 (set (match_operand:XF 1 "register_operand" "=u")
16482 (unspec:XF [(match_dup 2) (match_dup 3)]
16484 (set (reg:CCFP FPSR_REG)
16485 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16487 "TARGET_USE_FANCY_MATH_387"
16489 [(set_attr "type" "fpspc")
16490 (set_attr "mode" "XF")])
16492 (define_expand "remainderxf3"
16493 [(use (match_operand:XF 0 "register_operand" ""))
16494 (use (match_operand:XF 1 "general_operand" ""))
16495 (use (match_operand:XF 2 "general_operand" ""))]
16496 "TARGET_USE_FANCY_MATH_387"
16498 rtx label = gen_label_rtx ();
16500 rtx op1 = gen_reg_rtx (XFmode);
16501 rtx op2 = gen_reg_rtx (XFmode);
16503 emit_move_insn (op1, operands[1]);
16504 emit_move_insn (op2, operands[2]);
16506 emit_label (label);
16507 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16508 ix86_emit_fp_unordered_jump (label);
16509 LABEL_NUSES (label) = 1;
16511 emit_move_insn (operands[0], op1);
16515 (define_expand "remainder<mode>3"
16516 [(use (match_operand:MODEF 0 "register_operand" ""))
16517 (use (match_operand:MODEF 1 "general_operand" ""))
16518 (use (match_operand:MODEF 2 "general_operand" ""))]
16519 "TARGET_USE_FANCY_MATH_387"
16521 rtx label = gen_label_rtx ();
16523 rtx op1 = gen_reg_rtx (XFmode);
16524 rtx op2 = gen_reg_rtx (XFmode);
16526 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16527 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16529 emit_label (label);
16531 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16532 ix86_emit_fp_unordered_jump (label);
16533 LABEL_NUSES (label) = 1;
16535 /* Truncate the result properly for strict SSE math. */
16536 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16537 && !TARGET_MIX_SSE_I387)
16538 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16540 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16545 (define_insn "*sinxf2_i387"
16546 [(set (match_operand:XF 0 "register_operand" "=f")
16547 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16548 "TARGET_USE_FANCY_MATH_387
16549 && flag_unsafe_math_optimizations"
16551 [(set_attr "type" "fpspc")
16552 (set_attr "mode" "XF")])
16554 (define_insn "*sin_extend<mode>xf2_i387"
16555 [(set (match_operand:XF 0 "register_operand" "=f")
16556 (unspec:XF [(float_extend:XF
16557 (match_operand:MODEF 1 "register_operand" "0"))]
16559 "TARGET_USE_FANCY_MATH_387
16560 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16561 || TARGET_MIX_SSE_I387)
16562 && flag_unsafe_math_optimizations"
16564 [(set_attr "type" "fpspc")
16565 (set_attr "mode" "XF")])
16567 (define_insn "*cosxf2_i387"
16568 [(set (match_operand:XF 0 "register_operand" "=f")
16569 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16570 "TARGET_USE_FANCY_MATH_387
16571 && flag_unsafe_math_optimizations"
16573 [(set_attr "type" "fpspc")
16574 (set_attr "mode" "XF")])
16576 (define_insn "*cos_extend<mode>xf2_i387"
16577 [(set (match_operand:XF 0 "register_operand" "=f")
16578 (unspec:XF [(float_extend:XF
16579 (match_operand:MODEF 1 "register_operand" "0"))]
16581 "TARGET_USE_FANCY_MATH_387
16582 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16583 || TARGET_MIX_SSE_I387)
16584 && flag_unsafe_math_optimizations"
16586 [(set_attr "type" "fpspc")
16587 (set_attr "mode" "XF")])
16589 ;; When sincos pattern is defined, sin and cos builtin functions will be
16590 ;; expanded to sincos pattern with one of its outputs left unused.
16591 ;; CSE pass will figure out if two sincos patterns can be combined,
16592 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16593 ;; depending on the unused output.
16595 (define_insn "sincosxf3"
16596 [(set (match_operand:XF 0 "register_operand" "=f")
16597 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16598 UNSPEC_SINCOS_COS))
16599 (set (match_operand:XF 1 "register_operand" "=u")
16600 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16601 "TARGET_USE_FANCY_MATH_387
16602 && flag_unsafe_math_optimizations"
16604 [(set_attr "type" "fpspc")
16605 (set_attr "mode" "XF")])
16608 [(set (match_operand:XF 0 "register_operand" "")
16609 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16610 UNSPEC_SINCOS_COS))
16611 (set (match_operand:XF 1 "register_operand" "")
16612 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16613 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16614 && !(reload_completed || reload_in_progress)"
16615 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16619 [(set (match_operand:XF 0 "register_operand" "")
16620 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16621 UNSPEC_SINCOS_COS))
16622 (set (match_operand:XF 1 "register_operand" "")
16623 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16624 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16625 && !(reload_completed || reload_in_progress)"
16626 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16629 (define_insn "sincos_extend<mode>xf3_i387"
16630 [(set (match_operand:XF 0 "register_operand" "=f")
16631 (unspec:XF [(float_extend:XF
16632 (match_operand:MODEF 2 "register_operand" "0"))]
16633 UNSPEC_SINCOS_COS))
16634 (set (match_operand:XF 1 "register_operand" "=u")
16635 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16636 "TARGET_USE_FANCY_MATH_387
16637 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16638 || TARGET_MIX_SSE_I387)
16639 && flag_unsafe_math_optimizations"
16641 [(set_attr "type" "fpspc")
16642 (set_attr "mode" "XF")])
16645 [(set (match_operand:XF 0 "register_operand" "")
16646 (unspec:XF [(float_extend:XF
16647 (match_operand:MODEF 2 "register_operand" ""))]
16648 UNSPEC_SINCOS_COS))
16649 (set (match_operand:XF 1 "register_operand" "")
16650 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16651 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16652 && !(reload_completed || reload_in_progress)"
16653 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16657 [(set (match_operand:XF 0 "register_operand" "")
16658 (unspec:XF [(float_extend:XF
16659 (match_operand:MODEF 2 "register_operand" ""))]
16660 UNSPEC_SINCOS_COS))
16661 (set (match_operand:XF 1 "register_operand" "")
16662 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16663 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16664 && !(reload_completed || reload_in_progress)"
16665 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16668 (define_expand "sincos<mode>3"
16669 [(use (match_operand:MODEF 0 "register_operand" ""))
16670 (use (match_operand:MODEF 1 "register_operand" ""))
16671 (use (match_operand:MODEF 2 "register_operand" ""))]
16672 "TARGET_USE_FANCY_MATH_387
16673 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16674 || TARGET_MIX_SSE_I387)
16675 && flag_unsafe_math_optimizations"
16677 rtx op0 = gen_reg_rtx (XFmode);
16678 rtx op1 = gen_reg_rtx (XFmode);
16680 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16682 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16686 (define_insn "fptanxf4_i387"
16687 [(set (match_operand:XF 0 "register_operand" "=f")
16688 (match_operand:XF 3 "const_double_operand" "F"))
16689 (set (match_operand:XF 1 "register_operand" "=u")
16690 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16692 "TARGET_USE_FANCY_MATH_387
16693 && flag_unsafe_math_optimizations
16694 && standard_80387_constant_p (operands[3]) == 2"
16696 [(set_attr "type" "fpspc")
16697 (set_attr "mode" "XF")])
16699 (define_insn "fptan_extend<mode>xf4_i387"
16700 [(set (match_operand:MODEF 0 "register_operand" "=f")
16701 (match_operand:MODEF 3 "const_double_operand" "F"))
16702 (set (match_operand:XF 1 "register_operand" "=u")
16703 (unspec:XF [(float_extend:XF
16704 (match_operand:MODEF 2 "register_operand" "0"))]
16706 "TARGET_USE_FANCY_MATH_387
16707 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16708 || TARGET_MIX_SSE_I387)
16709 && flag_unsafe_math_optimizations
16710 && standard_80387_constant_p (operands[3]) == 2"
16712 [(set_attr "type" "fpspc")
16713 (set_attr "mode" "XF")])
16715 (define_expand "tanxf2"
16716 [(use (match_operand:XF 0 "register_operand" ""))
16717 (use (match_operand:XF 1 "register_operand" ""))]
16718 "TARGET_USE_FANCY_MATH_387
16719 && flag_unsafe_math_optimizations"
16721 rtx one = gen_reg_rtx (XFmode);
16722 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16724 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16728 (define_expand "tan<mode>2"
16729 [(use (match_operand:MODEF 0 "register_operand" ""))
16730 (use (match_operand:MODEF 1 "register_operand" ""))]
16731 "TARGET_USE_FANCY_MATH_387
16732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16733 || TARGET_MIX_SSE_I387)
16734 && flag_unsafe_math_optimizations"
16736 rtx op0 = gen_reg_rtx (XFmode);
16738 rtx one = gen_reg_rtx (<MODE>mode);
16739 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16741 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16742 operands[1], op2));
16743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16747 (define_insn "*fpatanxf3_i387"
16748 [(set (match_operand:XF 0 "register_operand" "=f")
16749 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16750 (match_operand:XF 2 "register_operand" "u")]
16752 (clobber (match_scratch:XF 3 "=2"))]
16753 "TARGET_USE_FANCY_MATH_387
16754 && flag_unsafe_math_optimizations"
16756 [(set_attr "type" "fpspc")
16757 (set_attr "mode" "XF")])
16759 (define_insn "fpatan_extend<mode>xf3_i387"
16760 [(set (match_operand:XF 0 "register_operand" "=f")
16761 (unspec:XF [(float_extend:XF
16762 (match_operand:MODEF 1 "register_operand" "0"))
16764 (match_operand:MODEF 2 "register_operand" "u"))]
16766 (clobber (match_scratch:XF 3 "=2"))]
16767 "TARGET_USE_FANCY_MATH_387
16768 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16769 || TARGET_MIX_SSE_I387)
16770 && flag_unsafe_math_optimizations"
16772 [(set_attr "type" "fpspc")
16773 (set_attr "mode" "XF")])
16775 (define_expand "atan2xf3"
16776 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16777 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16778 (match_operand:XF 1 "register_operand" "")]
16780 (clobber (match_scratch:XF 3 ""))])]
16781 "TARGET_USE_FANCY_MATH_387
16782 && flag_unsafe_math_optimizations"
16785 (define_expand "atan2<mode>3"
16786 [(use (match_operand:MODEF 0 "register_operand" ""))
16787 (use (match_operand:MODEF 1 "register_operand" ""))
16788 (use (match_operand:MODEF 2 "register_operand" ""))]
16789 "TARGET_USE_FANCY_MATH_387
16790 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16791 || TARGET_MIX_SSE_I387)
16792 && flag_unsafe_math_optimizations"
16794 rtx op0 = gen_reg_rtx (XFmode);
16796 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16797 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16801 (define_expand "atanxf2"
16802 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16803 (unspec:XF [(match_dup 2)
16804 (match_operand:XF 1 "register_operand" "")]
16806 (clobber (match_scratch:XF 3 ""))])]
16807 "TARGET_USE_FANCY_MATH_387
16808 && flag_unsafe_math_optimizations"
16810 operands[2] = gen_reg_rtx (XFmode);
16811 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16814 (define_expand "atan<mode>2"
16815 [(use (match_operand:MODEF 0 "register_operand" ""))
16816 (use (match_operand:MODEF 1 "register_operand" ""))]
16817 "TARGET_USE_FANCY_MATH_387
16818 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16819 || TARGET_MIX_SSE_I387)
16820 && flag_unsafe_math_optimizations"
16822 rtx op0 = gen_reg_rtx (XFmode);
16824 rtx op2 = gen_reg_rtx (<MODE>mode);
16825 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16827 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16828 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16832 (define_expand "asinxf2"
16833 [(set (match_dup 2)
16834 (mult:XF (match_operand:XF 1 "register_operand" "")
16836 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16837 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16838 (parallel [(set (match_operand:XF 0 "register_operand" "")
16839 (unspec:XF [(match_dup 5) (match_dup 1)]
16841 (clobber (match_scratch:XF 6 ""))])]
16842 "TARGET_USE_FANCY_MATH_387
16843 && flag_unsafe_math_optimizations && !optimize_size"
16847 for (i = 2; i < 6; i++)
16848 operands[i] = gen_reg_rtx (XFmode);
16850 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16853 (define_expand "asin<mode>2"
16854 [(use (match_operand:MODEF 0 "register_operand" ""))
16855 (use (match_operand:MODEF 1 "general_operand" ""))]
16856 "TARGET_USE_FANCY_MATH_387
16857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16858 || TARGET_MIX_SSE_I387)
16859 && flag_unsafe_math_optimizations && !optimize_size"
16861 rtx op0 = gen_reg_rtx (XFmode);
16862 rtx op1 = gen_reg_rtx (XFmode);
16864 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16865 emit_insn (gen_asinxf2 (op0, op1));
16866 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16870 (define_expand "acosxf2"
16871 [(set (match_dup 2)
16872 (mult:XF (match_operand:XF 1 "register_operand" "")
16874 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16875 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16876 (parallel [(set (match_operand:XF 0 "register_operand" "")
16877 (unspec:XF [(match_dup 1) (match_dup 5)]
16879 (clobber (match_scratch:XF 6 ""))])]
16880 "TARGET_USE_FANCY_MATH_387
16881 && flag_unsafe_math_optimizations && !optimize_size"
16885 for (i = 2; i < 6; i++)
16886 operands[i] = gen_reg_rtx (XFmode);
16888 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16891 (define_expand "acos<mode>2"
16892 [(use (match_operand:MODEF 0 "register_operand" ""))
16893 (use (match_operand:MODEF 1 "general_operand" ""))]
16894 "TARGET_USE_FANCY_MATH_387
16895 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16896 || TARGET_MIX_SSE_I387)
16897 && flag_unsafe_math_optimizations && !optimize_size"
16899 rtx op0 = gen_reg_rtx (XFmode);
16900 rtx op1 = gen_reg_rtx (XFmode);
16902 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16903 emit_insn (gen_acosxf2 (op0, op1));
16904 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16908 (define_insn "fyl2xxf3_i387"
16909 [(set (match_operand:XF 0 "register_operand" "=f")
16910 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16911 (match_operand:XF 2 "register_operand" "u")]
16913 (clobber (match_scratch:XF 3 "=2"))]
16914 "TARGET_USE_FANCY_MATH_387
16915 && flag_unsafe_math_optimizations"
16917 [(set_attr "type" "fpspc")
16918 (set_attr "mode" "XF")])
16920 (define_insn "fyl2x_extend<mode>xf3_i387"
16921 [(set (match_operand:XF 0 "register_operand" "=f")
16922 (unspec:XF [(float_extend:XF
16923 (match_operand:MODEF 1 "register_operand" "0"))
16924 (match_operand:XF 2 "register_operand" "u")]
16926 (clobber (match_scratch:XF 3 "=2"))]
16927 "TARGET_USE_FANCY_MATH_387
16928 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16929 || TARGET_MIX_SSE_I387)
16930 && flag_unsafe_math_optimizations"
16932 [(set_attr "type" "fpspc")
16933 (set_attr "mode" "XF")])
16935 (define_expand "logxf2"
16936 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16937 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16938 (match_dup 2)] UNSPEC_FYL2X))
16939 (clobber (match_scratch:XF 3 ""))])]
16940 "TARGET_USE_FANCY_MATH_387
16941 && flag_unsafe_math_optimizations"
16943 operands[2] = gen_reg_rtx (XFmode);
16944 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16947 (define_expand "log<mode>2"
16948 [(use (match_operand:MODEF 0 "register_operand" ""))
16949 (use (match_operand:MODEF 1 "register_operand" ""))]
16950 "TARGET_USE_FANCY_MATH_387
16951 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16952 || TARGET_MIX_SSE_I387)
16953 && flag_unsafe_math_optimizations"
16955 rtx op0 = gen_reg_rtx (XFmode);
16957 rtx op2 = gen_reg_rtx (XFmode);
16958 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16960 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16961 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16965 (define_expand "log10xf2"
16966 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16967 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16968 (match_dup 2)] UNSPEC_FYL2X))
16969 (clobber (match_scratch:XF 3 ""))])]
16970 "TARGET_USE_FANCY_MATH_387
16971 && flag_unsafe_math_optimizations"
16973 operands[2] = gen_reg_rtx (XFmode);
16974 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16977 (define_expand "log10<mode>2"
16978 [(use (match_operand:MODEF 0 "register_operand" ""))
16979 (use (match_operand:MODEF 1 "register_operand" ""))]
16980 "TARGET_USE_FANCY_MATH_387
16981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16982 || TARGET_MIX_SSE_I387)
16983 && flag_unsafe_math_optimizations"
16985 rtx op0 = gen_reg_rtx (XFmode);
16987 rtx op2 = gen_reg_rtx (XFmode);
16988 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16990 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16991 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16995 (define_expand "log2xf2"
16996 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16997 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16998 (match_dup 2)] UNSPEC_FYL2X))
16999 (clobber (match_scratch:XF 3 ""))])]
17000 "TARGET_USE_FANCY_MATH_387
17001 && flag_unsafe_math_optimizations"
17003 operands[2] = gen_reg_rtx (XFmode);
17004 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17007 (define_expand "log2<mode>2"
17008 [(use (match_operand:MODEF 0 "register_operand" ""))
17009 (use (match_operand:MODEF 1 "register_operand" ""))]
17010 "TARGET_USE_FANCY_MATH_387
17011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17012 || TARGET_MIX_SSE_I387)
17013 && flag_unsafe_math_optimizations"
17015 rtx op0 = gen_reg_rtx (XFmode);
17017 rtx op2 = gen_reg_rtx (XFmode);
17018 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17020 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17021 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17025 (define_insn "fyl2xp1xf3_i387"
17026 [(set (match_operand:XF 0 "register_operand" "=f")
17027 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17028 (match_operand:XF 2 "register_operand" "u")]
17030 (clobber (match_scratch:XF 3 "=2"))]
17031 "TARGET_USE_FANCY_MATH_387
17032 && flag_unsafe_math_optimizations"
17034 [(set_attr "type" "fpspc")
17035 (set_attr "mode" "XF")])
17037 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17038 [(set (match_operand:XF 0 "register_operand" "=f")
17039 (unspec:XF [(float_extend:XF
17040 (match_operand:MODEF 1 "register_operand" "0"))
17041 (match_operand:XF 2 "register_operand" "u")]
17043 (clobber (match_scratch:XF 3 "=2"))]
17044 "TARGET_USE_FANCY_MATH_387
17045 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17046 || TARGET_MIX_SSE_I387)
17047 && flag_unsafe_math_optimizations"
17049 [(set_attr "type" "fpspc")
17050 (set_attr "mode" "XF")])
17052 (define_expand "log1pxf2"
17053 [(use (match_operand:XF 0 "register_operand" ""))
17054 (use (match_operand:XF 1 "register_operand" ""))]
17055 "TARGET_USE_FANCY_MATH_387
17056 && flag_unsafe_math_optimizations && !optimize_size"
17058 ix86_emit_i387_log1p (operands[0], operands[1]);
17062 (define_expand "log1p<mode>2"
17063 [(use (match_operand:MODEF 0 "register_operand" ""))
17064 (use (match_operand:MODEF 1 "register_operand" ""))]
17065 "TARGET_USE_FANCY_MATH_387
17066 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17067 || TARGET_MIX_SSE_I387)
17068 && flag_unsafe_math_optimizations && !optimize_size"
17070 rtx op0 = gen_reg_rtx (XFmode);
17072 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17074 ix86_emit_i387_log1p (op0, operands[1]);
17075 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17079 (define_insn "fxtractxf3_i387"
17080 [(set (match_operand:XF 0 "register_operand" "=f")
17081 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17082 UNSPEC_XTRACT_FRACT))
17083 (set (match_operand:XF 1 "register_operand" "=u")
17084 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17085 "TARGET_USE_FANCY_MATH_387
17086 && flag_unsafe_math_optimizations"
17088 [(set_attr "type" "fpspc")
17089 (set_attr "mode" "XF")])
17091 (define_insn "fxtract_extend<mode>xf3_i387"
17092 [(set (match_operand:XF 0 "register_operand" "=f")
17093 (unspec:XF [(float_extend:XF
17094 (match_operand:MODEF 2 "register_operand" "0"))]
17095 UNSPEC_XTRACT_FRACT))
17096 (set (match_operand:XF 1 "register_operand" "=u")
17097 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17098 "TARGET_USE_FANCY_MATH_387
17099 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17100 || TARGET_MIX_SSE_I387)
17101 && flag_unsafe_math_optimizations"
17103 [(set_attr "type" "fpspc")
17104 (set_attr "mode" "XF")])
17106 (define_expand "logbxf2"
17107 [(parallel [(set (match_dup 2)
17108 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17109 UNSPEC_XTRACT_FRACT))
17110 (set (match_operand:XF 0 "register_operand" "")
17111 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17112 "TARGET_USE_FANCY_MATH_387
17113 && flag_unsafe_math_optimizations"
17115 operands[2] = gen_reg_rtx (XFmode);
17118 (define_expand "logb<mode>2"
17119 [(use (match_operand:MODEF 0 "register_operand" ""))
17120 (use (match_operand:MODEF 1 "register_operand" ""))]
17121 "TARGET_USE_FANCY_MATH_387
17122 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17123 || TARGET_MIX_SSE_I387)
17124 && flag_unsafe_math_optimizations"
17126 rtx op0 = gen_reg_rtx (XFmode);
17127 rtx op1 = gen_reg_rtx (XFmode);
17129 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17130 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17134 (define_expand "ilogbxf2"
17135 [(use (match_operand:SI 0 "register_operand" ""))
17136 (use (match_operand:XF 1 "register_operand" ""))]
17137 "TARGET_USE_FANCY_MATH_387
17138 && flag_unsafe_math_optimizations && !optimize_size"
17140 rtx op0 = gen_reg_rtx (XFmode);
17141 rtx op1 = gen_reg_rtx (XFmode);
17143 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17144 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17148 (define_expand "ilogb<mode>2"
17149 [(use (match_operand:SI 0 "register_operand" ""))
17150 (use (match_operand:MODEF 1 "register_operand" ""))]
17151 "TARGET_USE_FANCY_MATH_387
17152 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17153 || TARGET_MIX_SSE_I387)
17154 && flag_unsafe_math_optimizations && !optimize_size"
17156 rtx op0 = gen_reg_rtx (XFmode);
17157 rtx op1 = gen_reg_rtx (XFmode);
17159 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17160 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17164 (define_insn "*f2xm1xf2_i387"
17165 [(set (match_operand:XF 0 "register_operand" "=f")
17166 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17168 "TARGET_USE_FANCY_MATH_387
17169 && flag_unsafe_math_optimizations"
17171 [(set_attr "type" "fpspc")
17172 (set_attr "mode" "XF")])
17174 (define_insn "*fscalexf4_i387"
17175 [(set (match_operand:XF 0 "register_operand" "=f")
17176 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17177 (match_operand:XF 3 "register_operand" "1")]
17178 UNSPEC_FSCALE_FRACT))
17179 (set (match_operand:XF 1 "register_operand" "=u")
17180 (unspec:XF [(match_dup 2) (match_dup 3)]
17181 UNSPEC_FSCALE_EXP))]
17182 "TARGET_USE_FANCY_MATH_387
17183 && flag_unsafe_math_optimizations"
17185 [(set_attr "type" "fpspc")
17186 (set_attr "mode" "XF")])
17188 (define_expand "expNcorexf3"
17189 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17190 (match_operand:XF 2 "register_operand" "")))
17191 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17192 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17193 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17194 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17195 (parallel [(set (match_operand:XF 0 "register_operand" "")
17196 (unspec:XF [(match_dup 8) (match_dup 4)]
17197 UNSPEC_FSCALE_FRACT))
17199 (unspec:XF [(match_dup 8) (match_dup 4)]
17200 UNSPEC_FSCALE_EXP))])]
17201 "TARGET_USE_FANCY_MATH_387
17202 && flag_unsafe_math_optimizations && !optimize_size"
17206 for (i = 3; i < 10; i++)
17207 operands[i] = gen_reg_rtx (XFmode);
17209 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17212 (define_expand "expxf2"
17213 [(use (match_operand:XF 0 "register_operand" ""))
17214 (use (match_operand:XF 1 "register_operand" ""))]
17215 "TARGET_USE_FANCY_MATH_387
17216 && flag_unsafe_math_optimizations && !optimize_size"
17218 rtx op2 = gen_reg_rtx (XFmode);
17219 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17221 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17225 (define_expand "exp<mode>2"
17226 [(use (match_operand:MODEF 0 "register_operand" ""))
17227 (use (match_operand:MODEF 1 "general_operand" ""))]
17228 "TARGET_USE_FANCY_MATH_387
17229 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17230 || TARGET_MIX_SSE_I387)
17231 && flag_unsafe_math_optimizations && !optimize_size"
17233 rtx op0 = gen_reg_rtx (XFmode);
17234 rtx op1 = gen_reg_rtx (XFmode);
17236 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17237 emit_insn (gen_expxf2 (op0, op1));
17238 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17242 (define_expand "exp10xf2"
17243 [(use (match_operand:XF 0 "register_operand" ""))
17244 (use (match_operand:XF 1 "register_operand" ""))]
17245 "TARGET_USE_FANCY_MATH_387
17246 && flag_unsafe_math_optimizations && !optimize_size"
17248 rtx op2 = gen_reg_rtx (XFmode);
17249 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17251 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17255 (define_expand "exp10<mode>2"
17256 [(use (match_operand:MODEF 0 "register_operand" ""))
17257 (use (match_operand:MODEF 1 "general_operand" ""))]
17258 "TARGET_USE_FANCY_MATH_387
17259 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17260 || TARGET_MIX_SSE_I387)
17261 && flag_unsafe_math_optimizations && !optimize_size"
17263 rtx op0 = gen_reg_rtx (XFmode);
17264 rtx op1 = gen_reg_rtx (XFmode);
17266 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17267 emit_insn (gen_exp10xf2 (op0, op1));
17268 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17272 (define_expand "exp2xf2"
17273 [(use (match_operand:XF 0 "register_operand" ""))
17274 (use (match_operand:XF 1 "register_operand" ""))]
17275 "TARGET_USE_FANCY_MATH_387
17276 && flag_unsafe_math_optimizations && !optimize_size"
17278 rtx op2 = gen_reg_rtx (XFmode);
17279 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17281 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17285 (define_expand "exp2<mode>2"
17286 [(use (match_operand:MODEF 0 "register_operand" ""))
17287 (use (match_operand:MODEF 1 "general_operand" ""))]
17288 "TARGET_USE_FANCY_MATH_387
17289 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17290 || TARGET_MIX_SSE_I387)
17291 && flag_unsafe_math_optimizations && !optimize_size"
17293 rtx op0 = gen_reg_rtx (XFmode);
17294 rtx op1 = gen_reg_rtx (XFmode);
17296 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17297 emit_insn (gen_exp2xf2 (op0, op1));
17298 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17302 (define_expand "expm1xf2"
17303 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17305 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17306 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17307 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17308 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17309 (parallel [(set (match_dup 7)
17310 (unspec:XF [(match_dup 6) (match_dup 4)]
17311 UNSPEC_FSCALE_FRACT))
17313 (unspec:XF [(match_dup 6) (match_dup 4)]
17314 UNSPEC_FSCALE_EXP))])
17315 (parallel [(set (match_dup 10)
17316 (unspec:XF [(match_dup 9) (match_dup 8)]
17317 UNSPEC_FSCALE_FRACT))
17318 (set (match_dup 11)
17319 (unspec:XF [(match_dup 9) (match_dup 8)]
17320 UNSPEC_FSCALE_EXP))])
17321 (set (match_dup 12) (minus:XF (match_dup 10)
17322 (float_extend:XF (match_dup 13))))
17323 (set (match_operand:XF 0 "register_operand" "")
17324 (plus:XF (match_dup 12) (match_dup 7)))]
17325 "TARGET_USE_FANCY_MATH_387
17326 && flag_unsafe_math_optimizations && !optimize_size"
17330 for (i = 2; i < 13; i++)
17331 operands[i] = gen_reg_rtx (XFmode);
17334 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17336 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17339 (define_expand "expm1<mode>2"
17340 [(use (match_operand:MODEF 0 "register_operand" ""))
17341 (use (match_operand:MODEF 1 "general_operand" ""))]
17342 "TARGET_USE_FANCY_MATH_387
17343 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17344 || TARGET_MIX_SSE_I387)
17345 && flag_unsafe_math_optimizations && !optimize_size"
17347 rtx op0 = gen_reg_rtx (XFmode);
17348 rtx op1 = gen_reg_rtx (XFmode);
17350 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17351 emit_insn (gen_expm1xf2 (op0, op1));
17352 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17356 (define_expand "ldexpxf3"
17357 [(set (match_dup 3)
17358 (float:XF (match_operand:SI 2 "register_operand" "")))
17359 (parallel [(set (match_operand:XF 0 " register_operand" "")
17360 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17362 UNSPEC_FSCALE_FRACT))
17364 (unspec:XF [(match_dup 1) (match_dup 3)]
17365 UNSPEC_FSCALE_EXP))])]
17366 "TARGET_USE_FANCY_MATH_387
17367 && flag_unsafe_math_optimizations && !optimize_size"
17369 operands[3] = gen_reg_rtx (XFmode);
17370 operands[4] = gen_reg_rtx (XFmode);
17373 (define_expand "ldexp<mode>3"
17374 [(use (match_operand:MODEF 0 "register_operand" ""))
17375 (use (match_operand:MODEF 1 "general_operand" ""))
17376 (use (match_operand:SI 2 "register_operand" ""))]
17377 "TARGET_USE_FANCY_MATH_387
17378 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17379 || TARGET_MIX_SSE_I387)
17380 && flag_unsafe_math_optimizations && !optimize_size"
17382 rtx op0 = gen_reg_rtx (XFmode);
17383 rtx op1 = gen_reg_rtx (XFmode);
17385 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17386 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17387 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17391 (define_expand "scalbxf3"
17392 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17393 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17394 (match_operand:XF 2 "register_operand" "")]
17395 UNSPEC_FSCALE_FRACT))
17397 (unspec:XF [(match_dup 1) (match_dup 2)]
17398 UNSPEC_FSCALE_EXP))])]
17399 "TARGET_USE_FANCY_MATH_387
17400 && flag_unsafe_math_optimizations && !optimize_size"
17402 operands[3] = gen_reg_rtx (XFmode);
17405 (define_expand "scalb<mode>3"
17406 [(use (match_operand:MODEF 0 "register_operand" ""))
17407 (use (match_operand:MODEF 1 "general_operand" ""))
17408 (use (match_operand:MODEF 2 "register_operand" ""))]
17409 "TARGET_USE_FANCY_MATH_387
17410 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17411 || TARGET_MIX_SSE_I387)
17412 && flag_unsafe_math_optimizations && !optimize_size"
17414 rtx op0 = gen_reg_rtx (XFmode);
17415 rtx op1 = gen_reg_rtx (XFmode);
17416 rtx op2 = gen_reg_rtx (XFmode);
17418 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17419 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17420 emit_insn (gen_scalbxf3 (op0, op1, op2));
17421 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17426 (define_insn "sse4_1_round<mode>2"
17427 [(set (match_operand:MODEF 0 "register_operand" "=x")
17428 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17429 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17432 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17433 [(set_attr "type" "ssecvt")
17434 (set_attr "prefix_extra" "1")
17435 (set_attr "mode" "<MODE>")])
17437 (define_insn "rintxf2"
17438 [(set (match_operand:XF 0 "register_operand" "=f")
17439 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17441 "TARGET_USE_FANCY_MATH_387
17442 && flag_unsafe_math_optimizations"
17444 [(set_attr "type" "fpspc")
17445 (set_attr "mode" "XF")])
17447 (define_expand "rint<mode>2"
17448 [(use (match_operand:MODEF 0 "register_operand" ""))
17449 (use (match_operand:MODEF 1 "register_operand" ""))]
17450 "(TARGET_USE_FANCY_MATH_387
17451 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17452 || TARGET_MIX_SSE_I387)
17453 && flag_unsafe_math_optimizations)
17454 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17455 && !flag_trapping_math
17456 && (TARGET_ROUND || !optimize_size))"
17458 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17459 && !flag_trapping_math
17460 && (TARGET_ROUND || !optimize_size))
17463 emit_insn (gen_sse4_1_round<mode>2
17464 (operands[0], operands[1], GEN_INT (0x04)));
17466 ix86_expand_rint (operand0, operand1);
17470 rtx op0 = gen_reg_rtx (XFmode);
17471 rtx op1 = gen_reg_rtx (XFmode);
17473 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17474 emit_insn (gen_rintxf2 (op0, op1));
17476 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17481 (define_expand "round<mode>2"
17482 [(match_operand:MODEF 0 "register_operand" "")
17483 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17484 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17485 && !flag_trapping_math && !flag_rounding_math
17488 if (TARGET_64BIT || (<MODE>mode != DFmode))
17489 ix86_expand_round (operand0, operand1);
17491 ix86_expand_rounddf_32 (operand0, operand1);
17495 (define_insn_and_split "*fistdi2_1"
17496 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17497 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17499 "TARGET_USE_FANCY_MATH_387
17500 && !(reload_completed || reload_in_progress)"
17505 if (memory_operand (operands[0], VOIDmode))
17506 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17509 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17510 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17515 [(set_attr "type" "fpspc")
17516 (set_attr "mode" "DI")])
17518 (define_insn "fistdi2"
17519 [(set (match_operand:DI 0 "memory_operand" "=m")
17520 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17522 (clobber (match_scratch:XF 2 "=&1f"))]
17523 "TARGET_USE_FANCY_MATH_387"
17524 "* return output_fix_trunc (insn, operands, 0);"
17525 [(set_attr "type" "fpspc")
17526 (set_attr "mode" "DI")])
17528 (define_insn "fistdi2_with_temp"
17529 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17530 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17532 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17533 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17534 "TARGET_USE_FANCY_MATH_387"
17536 [(set_attr "type" "fpspc")
17537 (set_attr "mode" "DI")])
17540 [(set (match_operand:DI 0 "register_operand" "")
17541 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17543 (clobber (match_operand:DI 2 "memory_operand" ""))
17544 (clobber (match_scratch 3 ""))]
17546 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17547 (clobber (match_dup 3))])
17548 (set (match_dup 0) (match_dup 2))]
17552 [(set (match_operand:DI 0 "memory_operand" "")
17553 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17555 (clobber (match_operand:DI 2 "memory_operand" ""))
17556 (clobber (match_scratch 3 ""))]
17558 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17559 (clobber (match_dup 3))])]
17562 (define_insn_and_split "*fist<mode>2_1"
17563 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17564 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17566 "TARGET_USE_FANCY_MATH_387
17567 && !(reload_completed || reload_in_progress)"
17572 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17573 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17577 [(set_attr "type" "fpspc")
17578 (set_attr "mode" "<MODE>")])
17580 (define_insn "fist<mode>2"
17581 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17582 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17584 "TARGET_USE_FANCY_MATH_387"
17585 "* return output_fix_trunc (insn, operands, 0);"
17586 [(set_attr "type" "fpspc")
17587 (set_attr "mode" "<MODE>")])
17589 (define_insn "fist<mode>2_with_temp"
17590 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17591 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17593 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17594 "TARGET_USE_FANCY_MATH_387"
17596 [(set_attr "type" "fpspc")
17597 (set_attr "mode" "<MODE>")])
17600 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17601 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17603 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17605 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17606 (set (match_dup 0) (match_dup 2))]
17610 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17611 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17613 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17615 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17618 (define_expand "lrintxf<mode>2"
17619 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17620 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17622 "TARGET_USE_FANCY_MATH_387"
17625 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17626 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17627 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17628 UNSPEC_FIX_NOTRUNC))]
17629 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17630 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17633 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17634 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17635 (match_operand:MODEF 1 "register_operand" "")]
17636 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17637 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17638 && !flag_trapping_math && !flag_rounding_math
17641 ix86_expand_lround (operand0, operand1);
17645 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17646 (define_insn_and_split "frndintxf2_floor"
17647 [(set (match_operand:XF 0 "register_operand" "")
17648 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17649 UNSPEC_FRNDINT_FLOOR))
17650 (clobber (reg:CC FLAGS_REG))]
17651 "TARGET_USE_FANCY_MATH_387
17652 && flag_unsafe_math_optimizations
17653 && !(reload_completed || reload_in_progress)"
17658 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17660 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17661 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17663 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17664 operands[2], operands[3]));
17667 [(set_attr "type" "frndint")
17668 (set_attr "i387_cw" "floor")
17669 (set_attr "mode" "XF")])
17671 (define_insn "frndintxf2_floor_i387"
17672 [(set (match_operand:XF 0 "register_operand" "=f")
17673 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17674 UNSPEC_FRNDINT_FLOOR))
17675 (use (match_operand:HI 2 "memory_operand" "m"))
17676 (use (match_operand:HI 3 "memory_operand" "m"))]
17677 "TARGET_USE_FANCY_MATH_387
17678 && flag_unsafe_math_optimizations"
17679 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17680 [(set_attr "type" "frndint")
17681 (set_attr "i387_cw" "floor")
17682 (set_attr "mode" "XF")])
17684 (define_expand "floorxf2"
17685 [(use (match_operand:XF 0 "register_operand" ""))
17686 (use (match_operand:XF 1 "register_operand" ""))]
17687 "TARGET_USE_FANCY_MATH_387
17688 && flag_unsafe_math_optimizations && !optimize_size"
17690 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17694 (define_expand "floor<mode>2"
17695 [(use (match_operand:MODEF 0 "register_operand" ""))
17696 (use (match_operand:MODEF 1 "register_operand" ""))]
17697 "(TARGET_USE_FANCY_MATH_387
17698 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17699 || TARGET_MIX_SSE_I387)
17700 && flag_unsafe_math_optimizations && !optimize_size)
17701 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17702 && !flag_trapping_math
17703 && (TARGET_ROUND || !optimize_size))"
17705 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17706 && !flag_trapping_math
17707 && (TARGET_ROUND || !optimize_size))
17710 emit_insn (gen_sse4_1_round<mode>2
17711 (operands[0], operands[1], GEN_INT (0x01)));
17712 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17713 ix86_expand_floorceil (operand0, operand1, true);
17715 ix86_expand_floorceildf_32 (operand0, operand1, true);
17719 rtx op0 = gen_reg_rtx (XFmode);
17720 rtx op1 = gen_reg_rtx (XFmode);
17722 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17723 emit_insn (gen_frndintxf2_floor (op0, op1));
17725 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17730 (define_insn_and_split "*fist<mode>2_floor_1"
17731 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17732 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17733 UNSPEC_FIST_FLOOR))
17734 (clobber (reg:CC FLAGS_REG))]
17735 "TARGET_USE_FANCY_MATH_387
17736 && flag_unsafe_math_optimizations
17737 && !(reload_completed || reload_in_progress)"
17742 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17744 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17745 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17746 if (memory_operand (operands[0], VOIDmode))
17747 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17748 operands[2], operands[3]));
17751 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17752 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17753 operands[2], operands[3],
17758 [(set_attr "type" "fistp")
17759 (set_attr "i387_cw" "floor")
17760 (set_attr "mode" "<MODE>")])
17762 (define_insn "fistdi2_floor"
17763 [(set (match_operand:DI 0 "memory_operand" "=m")
17764 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17765 UNSPEC_FIST_FLOOR))
17766 (use (match_operand:HI 2 "memory_operand" "m"))
17767 (use (match_operand:HI 3 "memory_operand" "m"))
17768 (clobber (match_scratch:XF 4 "=&1f"))]
17769 "TARGET_USE_FANCY_MATH_387
17770 && flag_unsafe_math_optimizations"
17771 "* return output_fix_trunc (insn, operands, 0);"
17772 [(set_attr "type" "fistp")
17773 (set_attr "i387_cw" "floor")
17774 (set_attr "mode" "DI")])
17776 (define_insn "fistdi2_floor_with_temp"
17777 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17778 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17779 UNSPEC_FIST_FLOOR))
17780 (use (match_operand:HI 2 "memory_operand" "m,m"))
17781 (use (match_operand:HI 3 "memory_operand" "m,m"))
17782 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17783 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17784 "TARGET_USE_FANCY_MATH_387
17785 && flag_unsafe_math_optimizations"
17787 [(set_attr "type" "fistp")
17788 (set_attr "i387_cw" "floor")
17789 (set_attr "mode" "DI")])
17792 [(set (match_operand:DI 0 "register_operand" "")
17793 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17794 UNSPEC_FIST_FLOOR))
17795 (use (match_operand:HI 2 "memory_operand" ""))
17796 (use (match_operand:HI 3 "memory_operand" ""))
17797 (clobber (match_operand:DI 4 "memory_operand" ""))
17798 (clobber (match_scratch 5 ""))]
17800 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17801 (use (match_dup 2))
17802 (use (match_dup 3))
17803 (clobber (match_dup 5))])
17804 (set (match_dup 0) (match_dup 4))]
17808 [(set (match_operand:DI 0 "memory_operand" "")
17809 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17810 UNSPEC_FIST_FLOOR))
17811 (use (match_operand:HI 2 "memory_operand" ""))
17812 (use (match_operand:HI 3 "memory_operand" ""))
17813 (clobber (match_operand:DI 4 "memory_operand" ""))
17814 (clobber (match_scratch 5 ""))]
17816 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17817 (use (match_dup 2))
17818 (use (match_dup 3))
17819 (clobber (match_dup 5))])]
17822 (define_insn "fist<mode>2_floor"
17823 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17824 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17825 UNSPEC_FIST_FLOOR))
17826 (use (match_operand:HI 2 "memory_operand" "m"))
17827 (use (match_operand:HI 3 "memory_operand" "m"))]
17828 "TARGET_USE_FANCY_MATH_387
17829 && flag_unsafe_math_optimizations"
17830 "* return output_fix_trunc (insn, operands, 0);"
17831 [(set_attr "type" "fistp")
17832 (set_attr "i387_cw" "floor")
17833 (set_attr "mode" "<MODE>")])
17835 (define_insn "fist<mode>2_floor_with_temp"
17836 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17837 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17838 UNSPEC_FIST_FLOOR))
17839 (use (match_operand:HI 2 "memory_operand" "m,m"))
17840 (use (match_operand:HI 3 "memory_operand" "m,m"))
17841 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17842 "TARGET_USE_FANCY_MATH_387
17843 && flag_unsafe_math_optimizations"
17845 [(set_attr "type" "fistp")
17846 (set_attr "i387_cw" "floor")
17847 (set_attr "mode" "<MODE>")])
17850 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17851 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17852 UNSPEC_FIST_FLOOR))
17853 (use (match_operand:HI 2 "memory_operand" ""))
17854 (use (match_operand:HI 3 "memory_operand" ""))
17855 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17857 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17858 UNSPEC_FIST_FLOOR))
17859 (use (match_dup 2))
17860 (use (match_dup 3))])
17861 (set (match_dup 0) (match_dup 4))]
17865 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17866 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17867 UNSPEC_FIST_FLOOR))
17868 (use (match_operand:HI 2 "memory_operand" ""))
17869 (use (match_operand:HI 3 "memory_operand" ""))
17870 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17872 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17873 UNSPEC_FIST_FLOOR))
17874 (use (match_dup 2))
17875 (use (match_dup 3))])]
17878 (define_expand "lfloorxf<mode>2"
17879 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17880 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17881 UNSPEC_FIST_FLOOR))
17882 (clobber (reg:CC FLAGS_REG))])]
17883 "TARGET_USE_FANCY_MATH_387
17884 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17885 && flag_unsafe_math_optimizations"
17888 (define_expand "lfloor<mode>di2"
17889 [(match_operand:DI 0 "nonimmediate_operand" "")
17890 (match_operand:MODEF 1 "register_operand" "")]
17891 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17892 && !flag_trapping_math
17895 ix86_expand_lfloorceil (operand0, operand1, true);
17899 (define_expand "lfloor<mode>si2"
17900 [(match_operand:SI 0 "nonimmediate_operand" "")
17901 (match_operand:MODEF 1 "register_operand" "")]
17902 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17903 && !flag_trapping_math
17904 && (!optimize_size || !TARGET_64BIT)"
17906 ix86_expand_lfloorceil (operand0, operand1, true);
17910 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17911 (define_insn_and_split "frndintxf2_ceil"
17912 [(set (match_operand:XF 0 "register_operand" "")
17913 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17914 UNSPEC_FRNDINT_CEIL))
17915 (clobber (reg:CC FLAGS_REG))]
17916 "TARGET_USE_FANCY_MATH_387
17917 && flag_unsafe_math_optimizations
17918 && !(reload_completed || reload_in_progress)"
17923 ix86_optimize_mode_switching[I387_CEIL] = 1;
17925 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17926 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17928 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17929 operands[2], operands[3]));
17932 [(set_attr "type" "frndint")
17933 (set_attr "i387_cw" "ceil")
17934 (set_attr "mode" "XF")])
17936 (define_insn "frndintxf2_ceil_i387"
17937 [(set (match_operand:XF 0 "register_operand" "=f")
17938 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17939 UNSPEC_FRNDINT_CEIL))
17940 (use (match_operand:HI 2 "memory_operand" "m"))
17941 (use (match_operand:HI 3 "memory_operand" "m"))]
17942 "TARGET_USE_FANCY_MATH_387
17943 && flag_unsafe_math_optimizations"
17944 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17945 [(set_attr "type" "frndint")
17946 (set_attr "i387_cw" "ceil")
17947 (set_attr "mode" "XF")])
17949 (define_expand "ceilxf2"
17950 [(use (match_operand:XF 0 "register_operand" ""))
17951 (use (match_operand:XF 1 "register_operand" ""))]
17952 "TARGET_USE_FANCY_MATH_387
17953 && flag_unsafe_math_optimizations && !optimize_size"
17955 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17959 (define_expand "ceil<mode>2"
17960 [(use (match_operand:MODEF 0 "register_operand" ""))
17961 (use (match_operand:MODEF 1 "register_operand" ""))]
17962 "(TARGET_USE_FANCY_MATH_387
17963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17964 || TARGET_MIX_SSE_I387)
17965 && flag_unsafe_math_optimizations && !optimize_size)
17966 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17967 && !flag_trapping_math
17968 && (TARGET_ROUND || !optimize_size))"
17970 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17971 && !flag_trapping_math
17972 && (TARGET_ROUND || !optimize_size))
17975 emit_insn (gen_sse4_1_round<mode>2
17976 (operands[0], operands[1], GEN_INT (0x02)));
17977 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17978 ix86_expand_floorceil (operand0, operand1, false);
17980 ix86_expand_floorceildf_32 (operand0, operand1, false);
17984 rtx op0 = gen_reg_rtx (XFmode);
17985 rtx op1 = gen_reg_rtx (XFmode);
17987 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17988 emit_insn (gen_frndintxf2_ceil (op0, op1));
17990 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17995 (define_insn_and_split "*fist<mode>2_ceil_1"
17996 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17997 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17999 (clobber (reg:CC FLAGS_REG))]
18000 "TARGET_USE_FANCY_MATH_387
18001 && flag_unsafe_math_optimizations
18002 && !(reload_completed || reload_in_progress)"
18007 ix86_optimize_mode_switching[I387_CEIL] = 1;
18009 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18010 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18011 if (memory_operand (operands[0], VOIDmode))
18012 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18013 operands[2], operands[3]));
18016 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18017 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18018 operands[2], operands[3],
18023 [(set_attr "type" "fistp")
18024 (set_attr "i387_cw" "ceil")
18025 (set_attr "mode" "<MODE>")])
18027 (define_insn "fistdi2_ceil"
18028 [(set (match_operand:DI 0 "memory_operand" "=m")
18029 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18031 (use (match_operand:HI 2 "memory_operand" "m"))
18032 (use (match_operand:HI 3 "memory_operand" "m"))
18033 (clobber (match_scratch:XF 4 "=&1f"))]
18034 "TARGET_USE_FANCY_MATH_387
18035 && flag_unsafe_math_optimizations"
18036 "* return output_fix_trunc (insn, operands, 0);"
18037 [(set_attr "type" "fistp")
18038 (set_attr "i387_cw" "ceil")
18039 (set_attr "mode" "DI")])
18041 (define_insn "fistdi2_ceil_with_temp"
18042 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18043 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18045 (use (match_operand:HI 2 "memory_operand" "m,m"))
18046 (use (match_operand:HI 3 "memory_operand" "m,m"))
18047 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18048 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18049 "TARGET_USE_FANCY_MATH_387
18050 && flag_unsafe_math_optimizations"
18052 [(set_attr "type" "fistp")
18053 (set_attr "i387_cw" "ceil")
18054 (set_attr "mode" "DI")])
18057 [(set (match_operand:DI 0 "register_operand" "")
18058 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18060 (use (match_operand:HI 2 "memory_operand" ""))
18061 (use (match_operand:HI 3 "memory_operand" ""))
18062 (clobber (match_operand:DI 4 "memory_operand" ""))
18063 (clobber (match_scratch 5 ""))]
18065 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18066 (use (match_dup 2))
18067 (use (match_dup 3))
18068 (clobber (match_dup 5))])
18069 (set (match_dup 0) (match_dup 4))]
18073 [(set (match_operand:DI 0 "memory_operand" "")
18074 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18076 (use (match_operand:HI 2 "memory_operand" ""))
18077 (use (match_operand:HI 3 "memory_operand" ""))
18078 (clobber (match_operand:DI 4 "memory_operand" ""))
18079 (clobber (match_scratch 5 ""))]
18081 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18082 (use (match_dup 2))
18083 (use (match_dup 3))
18084 (clobber (match_dup 5))])]
18087 (define_insn "fist<mode>2_ceil"
18088 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18089 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18091 (use (match_operand:HI 2 "memory_operand" "m"))
18092 (use (match_operand:HI 3 "memory_operand" "m"))]
18093 "TARGET_USE_FANCY_MATH_387
18094 && flag_unsafe_math_optimizations"
18095 "* return output_fix_trunc (insn, operands, 0);"
18096 [(set_attr "type" "fistp")
18097 (set_attr "i387_cw" "ceil")
18098 (set_attr "mode" "<MODE>")])
18100 (define_insn "fist<mode>2_ceil_with_temp"
18101 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18102 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18104 (use (match_operand:HI 2 "memory_operand" "m,m"))
18105 (use (match_operand:HI 3 "memory_operand" "m,m"))
18106 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18107 "TARGET_USE_FANCY_MATH_387
18108 && flag_unsafe_math_optimizations"
18110 [(set_attr "type" "fistp")
18111 (set_attr "i387_cw" "ceil")
18112 (set_attr "mode" "<MODE>")])
18115 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18116 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18118 (use (match_operand:HI 2 "memory_operand" ""))
18119 (use (match_operand:HI 3 "memory_operand" ""))
18120 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18122 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18124 (use (match_dup 2))
18125 (use (match_dup 3))])
18126 (set (match_dup 0) (match_dup 4))]
18130 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18131 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18133 (use (match_operand:HI 2 "memory_operand" ""))
18134 (use (match_operand:HI 3 "memory_operand" ""))
18135 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18137 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18139 (use (match_dup 2))
18140 (use (match_dup 3))])]
18143 (define_expand "lceilxf<mode>2"
18144 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18145 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18147 (clobber (reg:CC FLAGS_REG))])]
18148 "TARGET_USE_FANCY_MATH_387
18149 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18150 && flag_unsafe_math_optimizations"
18153 (define_expand "lceil<mode>di2"
18154 [(match_operand:DI 0 "nonimmediate_operand" "")
18155 (match_operand:MODEF 1 "register_operand" "")]
18156 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18157 && !flag_trapping_math"
18159 ix86_expand_lfloorceil (operand0, operand1, false);
18163 (define_expand "lceil<mode>si2"
18164 [(match_operand:SI 0 "nonimmediate_operand" "")
18165 (match_operand:MODEF 1 "register_operand" "")]
18166 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18167 && !flag_trapping_math"
18169 ix86_expand_lfloorceil (operand0, operand1, false);
18173 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18174 (define_insn_and_split "frndintxf2_trunc"
18175 [(set (match_operand:XF 0 "register_operand" "")
18176 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18177 UNSPEC_FRNDINT_TRUNC))
18178 (clobber (reg:CC FLAGS_REG))]
18179 "TARGET_USE_FANCY_MATH_387
18180 && flag_unsafe_math_optimizations
18181 && !(reload_completed || reload_in_progress)"
18186 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18188 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18189 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18191 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18192 operands[2], operands[3]));
18195 [(set_attr "type" "frndint")
18196 (set_attr "i387_cw" "trunc")
18197 (set_attr "mode" "XF")])
18199 (define_insn "frndintxf2_trunc_i387"
18200 [(set (match_operand:XF 0 "register_operand" "=f")
18201 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18202 UNSPEC_FRNDINT_TRUNC))
18203 (use (match_operand:HI 2 "memory_operand" "m"))
18204 (use (match_operand:HI 3 "memory_operand" "m"))]
18205 "TARGET_USE_FANCY_MATH_387
18206 && flag_unsafe_math_optimizations"
18207 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18208 [(set_attr "type" "frndint")
18209 (set_attr "i387_cw" "trunc")
18210 (set_attr "mode" "XF")])
18212 (define_expand "btruncxf2"
18213 [(use (match_operand:XF 0 "register_operand" ""))
18214 (use (match_operand:XF 1 "register_operand" ""))]
18215 "TARGET_USE_FANCY_MATH_387
18216 && flag_unsafe_math_optimizations && !optimize_size"
18218 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18222 (define_expand "btrunc<mode>2"
18223 [(use (match_operand:MODEF 0 "register_operand" ""))
18224 (use (match_operand:MODEF 1 "register_operand" ""))]
18225 "(TARGET_USE_FANCY_MATH_387
18226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18227 || TARGET_MIX_SSE_I387)
18228 && flag_unsafe_math_optimizations && !optimize_size)
18229 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18230 && !flag_trapping_math
18231 && (TARGET_ROUND || !optimize_size))"
18233 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18234 && !flag_trapping_math
18235 && (TARGET_ROUND || !optimize_size))
18238 emit_insn (gen_sse4_1_round<mode>2
18239 (operands[0], operands[1], GEN_INT (0x03)));
18240 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18241 ix86_expand_trunc (operand0, operand1);
18243 ix86_expand_truncdf_32 (operand0, operand1);
18247 rtx op0 = gen_reg_rtx (XFmode);
18248 rtx op1 = gen_reg_rtx (XFmode);
18250 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18251 emit_insn (gen_frndintxf2_trunc (op0, op1));
18253 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18258 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18259 (define_insn_and_split "frndintxf2_mask_pm"
18260 [(set (match_operand:XF 0 "register_operand" "")
18261 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18262 UNSPEC_FRNDINT_MASK_PM))
18263 (clobber (reg:CC FLAGS_REG))]
18264 "TARGET_USE_FANCY_MATH_387
18265 && flag_unsafe_math_optimizations
18266 && !(reload_completed || reload_in_progress)"
18271 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18273 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18274 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18276 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18277 operands[2], operands[3]));
18280 [(set_attr "type" "frndint")
18281 (set_attr "i387_cw" "mask_pm")
18282 (set_attr "mode" "XF")])
18284 (define_insn "frndintxf2_mask_pm_i387"
18285 [(set (match_operand:XF 0 "register_operand" "=f")
18286 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18287 UNSPEC_FRNDINT_MASK_PM))
18288 (use (match_operand:HI 2 "memory_operand" "m"))
18289 (use (match_operand:HI 3 "memory_operand" "m"))]
18290 "TARGET_USE_FANCY_MATH_387
18291 && flag_unsafe_math_optimizations"
18292 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18293 [(set_attr "type" "frndint")
18294 (set_attr "i387_cw" "mask_pm")
18295 (set_attr "mode" "XF")])
18297 (define_expand "nearbyintxf2"
18298 [(use (match_operand:XF 0 "register_operand" ""))
18299 (use (match_operand:XF 1 "register_operand" ""))]
18300 "TARGET_USE_FANCY_MATH_387
18301 && flag_unsafe_math_optimizations"
18303 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18308 (define_expand "nearbyint<mode>2"
18309 [(use (match_operand:MODEF 0 "register_operand" ""))
18310 (use (match_operand:MODEF 1 "register_operand" ""))]
18311 "TARGET_USE_FANCY_MATH_387
18312 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18313 || TARGET_MIX_SSE_I387)
18314 && flag_unsafe_math_optimizations"
18316 rtx op0 = gen_reg_rtx (XFmode);
18317 rtx op1 = gen_reg_rtx (XFmode);
18319 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18320 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18322 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18326 (define_insn "fxam<mode>2_i387"
18327 [(set (match_operand:HI 0 "register_operand" "=a")
18329 [(match_operand:X87MODEF 1 "register_operand" "f")]
18331 "TARGET_USE_FANCY_MATH_387"
18332 "fxam\n\tfnstsw\t%0"
18333 [(set_attr "type" "multi")
18334 (set_attr "unit" "i387")
18335 (set_attr "mode" "<MODE>")])
18337 (define_expand "isinf<mode>2"
18338 [(use (match_operand:SI 0 "register_operand" ""))
18339 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18340 "TARGET_USE_FANCY_MATH_387
18341 && TARGET_C99_FUNCTIONS
18342 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18344 rtx mask = GEN_INT (0x45);
18345 rtx val = GEN_INT (0x05);
18349 rtx scratch = gen_reg_rtx (HImode);
18350 rtx res = gen_reg_rtx (QImode);
18352 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18353 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18354 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18355 cond = gen_rtx_fmt_ee (EQ, QImode,
18356 gen_rtx_REG (CCmode, FLAGS_REG),
18358 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18359 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18363 (define_expand "signbit<mode>2"
18364 [(use (match_operand:SI 0 "register_operand" ""))
18365 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18366 "TARGET_USE_FANCY_MATH_387
18367 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18369 rtx mask = GEN_INT (0x0200);
18371 rtx scratch = gen_reg_rtx (HImode);
18373 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18374 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18378 ;; Block operation instructions
18380 (define_expand "movmemsi"
18381 [(use (match_operand:BLK 0 "memory_operand" ""))
18382 (use (match_operand:BLK 1 "memory_operand" ""))
18383 (use (match_operand:SI 2 "nonmemory_operand" ""))
18384 (use (match_operand:SI 3 "const_int_operand" ""))
18385 (use (match_operand:SI 4 "const_int_operand" ""))
18386 (use (match_operand:SI 5 "const_int_operand" ""))]
18389 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18390 operands[4], operands[5]))
18396 (define_expand "movmemdi"
18397 [(use (match_operand:BLK 0 "memory_operand" ""))
18398 (use (match_operand:BLK 1 "memory_operand" ""))
18399 (use (match_operand:DI 2 "nonmemory_operand" ""))
18400 (use (match_operand:DI 3 "const_int_operand" ""))
18401 (use (match_operand:SI 4 "const_int_operand" ""))
18402 (use (match_operand:SI 5 "const_int_operand" ""))]
18405 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18406 operands[4], operands[5]))
18412 ;; Most CPUs don't like single string operations
18413 ;; Handle this case here to simplify previous expander.
18415 (define_expand "strmov"
18416 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18417 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18418 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18419 (clobber (reg:CC FLAGS_REG))])
18420 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18421 (clobber (reg:CC FLAGS_REG))])]
18424 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18426 /* If .md ever supports :P for Pmode, these can be directly
18427 in the pattern above. */
18428 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18429 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18431 /* Can't use this if the user has appropriated esi or edi. */
18432 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18433 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18435 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18436 operands[2], operands[3],
18437 operands[5], operands[6]));
18441 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18444 (define_expand "strmov_singleop"
18445 [(parallel [(set (match_operand 1 "memory_operand" "")
18446 (match_operand 3 "memory_operand" ""))
18447 (set (match_operand 0 "register_operand" "")
18448 (match_operand 4 "" ""))
18449 (set (match_operand 2 "register_operand" "")
18450 (match_operand 5 "" ""))])]
18451 "TARGET_SINGLE_STRINGOP || optimize_size"
18454 (define_insn "*strmovdi_rex_1"
18455 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18456 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18457 (set (match_operand:DI 0 "register_operand" "=D")
18458 (plus:DI (match_dup 2)
18460 (set (match_operand:DI 1 "register_operand" "=S")
18461 (plus:DI (match_dup 3)
18463 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18465 [(set_attr "type" "str")
18466 (set_attr "mode" "DI")
18467 (set_attr "memory" "both")])
18469 (define_insn "*strmovsi_1"
18470 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18471 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18472 (set (match_operand:SI 0 "register_operand" "=D")
18473 (plus:SI (match_dup 2)
18475 (set (match_operand:SI 1 "register_operand" "=S")
18476 (plus:SI (match_dup 3)
18478 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18480 [(set_attr "type" "str")
18481 (set_attr "mode" "SI")
18482 (set_attr "memory" "both")])
18484 (define_insn "*strmovsi_rex_1"
18485 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18486 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18487 (set (match_operand:DI 0 "register_operand" "=D")
18488 (plus:DI (match_dup 2)
18490 (set (match_operand:DI 1 "register_operand" "=S")
18491 (plus:DI (match_dup 3)
18493 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18495 [(set_attr "type" "str")
18496 (set_attr "mode" "SI")
18497 (set_attr "memory" "both")])
18499 (define_insn "*strmovhi_1"
18500 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18501 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18502 (set (match_operand:SI 0 "register_operand" "=D")
18503 (plus:SI (match_dup 2)
18505 (set (match_operand:SI 1 "register_operand" "=S")
18506 (plus:SI (match_dup 3)
18508 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18510 [(set_attr "type" "str")
18511 (set_attr "memory" "both")
18512 (set_attr "mode" "HI")])
18514 (define_insn "*strmovhi_rex_1"
18515 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18516 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18517 (set (match_operand:DI 0 "register_operand" "=D")
18518 (plus:DI (match_dup 2)
18520 (set (match_operand:DI 1 "register_operand" "=S")
18521 (plus:DI (match_dup 3)
18523 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18525 [(set_attr "type" "str")
18526 (set_attr "memory" "both")
18527 (set_attr "mode" "HI")])
18529 (define_insn "*strmovqi_1"
18530 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18531 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18532 (set (match_operand:SI 0 "register_operand" "=D")
18533 (plus:SI (match_dup 2)
18535 (set (match_operand:SI 1 "register_operand" "=S")
18536 (plus:SI (match_dup 3)
18538 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18540 [(set_attr "type" "str")
18541 (set_attr "memory" "both")
18542 (set_attr "mode" "QI")])
18544 (define_insn "*strmovqi_rex_1"
18545 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18546 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18547 (set (match_operand:DI 0 "register_operand" "=D")
18548 (plus:DI (match_dup 2)
18550 (set (match_operand:DI 1 "register_operand" "=S")
18551 (plus:DI (match_dup 3)
18553 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18555 [(set_attr "type" "str")
18556 (set_attr "memory" "both")
18557 (set_attr "mode" "QI")])
18559 (define_expand "rep_mov"
18560 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18561 (set (match_operand 0 "register_operand" "")
18562 (match_operand 5 "" ""))
18563 (set (match_operand 2 "register_operand" "")
18564 (match_operand 6 "" ""))
18565 (set (match_operand 1 "memory_operand" "")
18566 (match_operand 3 "memory_operand" ""))
18567 (use (match_dup 4))])]
18571 (define_insn "*rep_movdi_rex64"
18572 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18573 (set (match_operand:DI 0 "register_operand" "=D")
18574 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18576 (match_operand:DI 3 "register_operand" "0")))
18577 (set (match_operand:DI 1 "register_operand" "=S")
18578 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18579 (match_operand:DI 4 "register_operand" "1")))
18580 (set (mem:BLK (match_dup 3))
18581 (mem:BLK (match_dup 4)))
18582 (use (match_dup 5))]
18585 [(set_attr "type" "str")
18586 (set_attr "prefix_rep" "1")
18587 (set_attr "memory" "both")
18588 (set_attr "mode" "DI")])
18590 (define_insn "*rep_movsi"
18591 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18592 (set (match_operand:SI 0 "register_operand" "=D")
18593 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18595 (match_operand:SI 3 "register_operand" "0")))
18596 (set (match_operand:SI 1 "register_operand" "=S")
18597 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18598 (match_operand:SI 4 "register_operand" "1")))
18599 (set (mem:BLK (match_dup 3))
18600 (mem:BLK (match_dup 4)))
18601 (use (match_dup 5))]
18604 [(set_attr "type" "str")
18605 (set_attr "prefix_rep" "1")
18606 (set_attr "memory" "both")
18607 (set_attr "mode" "SI")])
18609 (define_insn "*rep_movsi_rex64"
18610 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18611 (set (match_operand:DI 0 "register_operand" "=D")
18612 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18614 (match_operand:DI 3 "register_operand" "0")))
18615 (set (match_operand:DI 1 "register_operand" "=S")
18616 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18617 (match_operand:DI 4 "register_operand" "1")))
18618 (set (mem:BLK (match_dup 3))
18619 (mem:BLK (match_dup 4)))
18620 (use (match_dup 5))]
18623 [(set_attr "type" "str")
18624 (set_attr "prefix_rep" "1")
18625 (set_attr "memory" "both")
18626 (set_attr "mode" "SI")])
18628 (define_insn "*rep_movqi"
18629 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18630 (set (match_operand:SI 0 "register_operand" "=D")
18631 (plus:SI (match_operand:SI 3 "register_operand" "0")
18632 (match_operand:SI 5 "register_operand" "2")))
18633 (set (match_operand:SI 1 "register_operand" "=S")
18634 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18635 (set (mem:BLK (match_dup 3))
18636 (mem:BLK (match_dup 4)))
18637 (use (match_dup 5))]
18640 [(set_attr "type" "str")
18641 (set_attr "prefix_rep" "1")
18642 (set_attr "memory" "both")
18643 (set_attr "mode" "SI")])
18645 (define_insn "*rep_movqi_rex64"
18646 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18647 (set (match_operand:DI 0 "register_operand" "=D")
18648 (plus:DI (match_operand:DI 3 "register_operand" "0")
18649 (match_operand:DI 5 "register_operand" "2")))
18650 (set (match_operand:DI 1 "register_operand" "=S")
18651 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18652 (set (mem:BLK (match_dup 3))
18653 (mem:BLK (match_dup 4)))
18654 (use (match_dup 5))]
18657 [(set_attr "type" "str")
18658 (set_attr "prefix_rep" "1")
18659 (set_attr "memory" "both")
18660 (set_attr "mode" "SI")])
18662 (define_expand "setmemsi"
18663 [(use (match_operand:BLK 0 "memory_operand" ""))
18664 (use (match_operand:SI 1 "nonmemory_operand" ""))
18665 (use (match_operand 2 "const_int_operand" ""))
18666 (use (match_operand 3 "const_int_operand" ""))
18667 (use (match_operand:SI 4 "const_int_operand" ""))
18668 (use (match_operand:SI 5 "const_int_operand" ""))]
18671 if (ix86_expand_setmem (operands[0], operands[1],
18672 operands[2], operands[3],
18673 operands[4], operands[5]))
18679 (define_expand "setmemdi"
18680 [(use (match_operand:BLK 0 "memory_operand" ""))
18681 (use (match_operand:DI 1 "nonmemory_operand" ""))
18682 (use (match_operand 2 "const_int_operand" ""))
18683 (use (match_operand 3 "const_int_operand" ""))
18684 (use (match_operand 4 "const_int_operand" ""))
18685 (use (match_operand 5 "const_int_operand" ""))]
18688 if (ix86_expand_setmem (operands[0], operands[1],
18689 operands[2], operands[3],
18690 operands[4], operands[5]))
18696 ;; Most CPUs don't like single string operations
18697 ;; Handle this case here to simplify previous expander.
18699 (define_expand "strset"
18700 [(set (match_operand 1 "memory_operand" "")
18701 (match_operand 2 "register_operand" ""))
18702 (parallel [(set (match_operand 0 "register_operand" "")
18704 (clobber (reg:CC FLAGS_REG))])]
18707 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18708 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18710 /* If .md ever supports :P for Pmode, this can be directly
18711 in the pattern above. */
18712 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18713 GEN_INT (GET_MODE_SIZE (GET_MODE
18715 if (TARGET_SINGLE_STRINGOP || optimize_size)
18717 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18723 (define_expand "strset_singleop"
18724 [(parallel [(set (match_operand 1 "memory_operand" "")
18725 (match_operand 2 "register_operand" ""))
18726 (set (match_operand 0 "register_operand" "")
18727 (match_operand 3 "" ""))])]
18728 "TARGET_SINGLE_STRINGOP || optimize_size"
18731 (define_insn "*strsetdi_rex_1"
18732 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18733 (match_operand:DI 2 "register_operand" "a"))
18734 (set (match_operand:DI 0 "register_operand" "=D")
18735 (plus:DI (match_dup 1)
18737 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18739 [(set_attr "type" "str")
18740 (set_attr "memory" "store")
18741 (set_attr "mode" "DI")])
18743 (define_insn "*strsetsi_1"
18744 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18745 (match_operand:SI 2 "register_operand" "a"))
18746 (set (match_operand:SI 0 "register_operand" "=D")
18747 (plus:SI (match_dup 1)
18749 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18751 [(set_attr "type" "str")
18752 (set_attr "memory" "store")
18753 (set_attr "mode" "SI")])
18755 (define_insn "*strsetsi_rex_1"
18756 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18757 (match_operand:SI 2 "register_operand" "a"))
18758 (set (match_operand:DI 0 "register_operand" "=D")
18759 (plus:DI (match_dup 1)
18761 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18763 [(set_attr "type" "str")
18764 (set_attr "memory" "store")
18765 (set_attr "mode" "SI")])
18767 (define_insn "*strsethi_1"
18768 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18769 (match_operand:HI 2 "register_operand" "a"))
18770 (set (match_operand:SI 0 "register_operand" "=D")
18771 (plus:SI (match_dup 1)
18773 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18775 [(set_attr "type" "str")
18776 (set_attr "memory" "store")
18777 (set_attr "mode" "HI")])
18779 (define_insn "*strsethi_rex_1"
18780 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18781 (match_operand:HI 2 "register_operand" "a"))
18782 (set (match_operand:DI 0 "register_operand" "=D")
18783 (plus:DI (match_dup 1)
18785 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18787 [(set_attr "type" "str")
18788 (set_attr "memory" "store")
18789 (set_attr "mode" "HI")])
18791 (define_insn "*strsetqi_1"
18792 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18793 (match_operand:QI 2 "register_operand" "a"))
18794 (set (match_operand:SI 0 "register_operand" "=D")
18795 (plus:SI (match_dup 1)
18797 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18799 [(set_attr "type" "str")
18800 (set_attr "memory" "store")
18801 (set_attr "mode" "QI")])
18803 (define_insn "*strsetqi_rex_1"
18804 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18805 (match_operand:QI 2 "register_operand" "a"))
18806 (set (match_operand:DI 0 "register_operand" "=D")
18807 (plus:DI (match_dup 1)
18809 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18811 [(set_attr "type" "str")
18812 (set_attr "memory" "store")
18813 (set_attr "mode" "QI")])
18815 (define_expand "rep_stos"
18816 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18817 (set (match_operand 0 "register_operand" "")
18818 (match_operand 4 "" ""))
18819 (set (match_operand 2 "memory_operand" "") (const_int 0))
18820 (use (match_operand 3 "register_operand" ""))
18821 (use (match_dup 1))])]
18825 (define_insn "*rep_stosdi_rex64"
18826 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18827 (set (match_operand:DI 0 "register_operand" "=D")
18828 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18830 (match_operand:DI 3 "register_operand" "0")))
18831 (set (mem:BLK (match_dup 3))
18833 (use (match_operand:DI 2 "register_operand" "a"))
18834 (use (match_dup 4))]
18837 [(set_attr "type" "str")
18838 (set_attr "prefix_rep" "1")
18839 (set_attr "memory" "store")
18840 (set_attr "mode" "DI")])
18842 (define_insn "*rep_stossi"
18843 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18844 (set (match_operand:SI 0 "register_operand" "=D")
18845 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18847 (match_operand:SI 3 "register_operand" "0")))
18848 (set (mem:BLK (match_dup 3))
18850 (use (match_operand:SI 2 "register_operand" "a"))
18851 (use (match_dup 4))]
18854 [(set_attr "type" "str")
18855 (set_attr "prefix_rep" "1")
18856 (set_attr "memory" "store")
18857 (set_attr "mode" "SI")])
18859 (define_insn "*rep_stossi_rex64"
18860 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18861 (set (match_operand:DI 0 "register_operand" "=D")
18862 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18864 (match_operand:DI 3 "register_operand" "0")))
18865 (set (mem:BLK (match_dup 3))
18867 (use (match_operand:SI 2 "register_operand" "a"))
18868 (use (match_dup 4))]
18871 [(set_attr "type" "str")
18872 (set_attr "prefix_rep" "1")
18873 (set_attr "memory" "store")
18874 (set_attr "mode" "SI")])
18876 (define_insn "*rep_stosqi"
18877 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18878 (set (match_operand:SI 0 "register_operand" "=D")
18879 (plus:SI (match_operand:SI 3 "register_operand" "0")
18880 (match_operand:SI 4 "register_operand" "1")))
18881 (set (mem:BLK (match_dup 3))
18883 (use (match_operand:QI 2 "register_operand" "a"))
18884 (use (match_dup 4))]
18887 [(set_attr "type" "str")
18888 (set_attr "prefix_rep" "1")
18889 (set_attr "memory" "store")
18890 (set_attr "mode" "QI")])
18892 (define_insn "*rep_stosqi_rex64"
18893 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18894 (set (match_operand:DI 0 "register_operand" "=D")
18895 (plus:DI (match_operand:DI 3 "register_operand" "0")
18896 (match_operand:DI 4 "register_operand" "1")))
18897 (set (mem:BLK (match_dup 3))
18899 (use (match_operand:QI 2 "register_operand" "a"))
18900 (use (match_dup 4))]
18903 [(set_attr "type" "str")
18904 (set_attr "prefix_rep" "1")
18905 (set_attr "memory" "store")
18906 (set_attr "mode" "QI")])
18908 (define_expand "cmpstrnsi"
18909 [(set (match_operand:SI 0 "register_operand" "")
18910 (compare:SI (match_operand:BLK 1 "general_operand" "")
18911 (match_operand:BLK 2 "general_operand" "")))
18912 (use (match_operand 3 "general_operand" ""))
18913 (use (match_operand 4 "immediate_operand" ""))]
18914 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18916 rtx addr1, addr2, out, outlow, count, countreg, align;
18918 /* Can't use this if the user has appropriated esi or edi. */
18919 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18924 out = gen_reg_rtx (SImode);
18926 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18927 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18928 if (addr1 != XEXP (operands[1], 0))
18929 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18930 if (addr2 != XEXP (operands[2], 0))
18931 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18933 count = operands[3];
18934 countreg = ix86_zero_extend_to_Pmode (count);
18936 /* %%% Iff we are testing strict equality, we can use known alignment
18937 to good advantage. This may be possible with combine, particularly
18938 once cc0 is dead. */
18939 align = operands[4];
18941 if (CONST_INT_P (count))
18943 if (INTVAL (count) == 0)
18945 emit_move_insn (operands[0], const0_rtx);
18948 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18949 operands[1], operands[2]));
18954 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18956 emit_insn (gen_cmpsi_1 (countreg, countreg));
18957 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18958 operands[1], operands[2]));
18961 outlow = gen_lowpart (QImode, out);
18962 emit_insn (gen_cmpintqi (outlow));
18963 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18965 if (operands[0] != out)
18966 emit_move_insn (operands[0], out);
18971 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18973 (define_expand "cmpintqi"
18974 [(set (match_dup 1)
18975 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18977 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18978 (parallel [(set (match_operand:QI 0 "register_operand" "")
18979 (minus:QI (match_dup 1)
18981 (clobber (reg:CC FLAGS_REG))])]
18983 "operands[1] = gen_reg_rtx (QImode);
18984 operands[2] = gen_reg_rtx (QImode);")
18986 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18987 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18989 (define_expand "cmpstrnqi_nz_1"
18990 [(parallel [(set (reg:CC FLAGS_REG)
18991 (compare:CC (match_operand 4 "memory_operand" "")
18992 (match_operand 5 "memory_operand" "")))
18993 (use (match_operand 2 "register_operand" ""))
18994 (use (match_operand:SI 3 "immediate_operand" ""))
18995 (clobber (match_operand 0 "register_operand" ""))
18996 (clobber (match_operand 1 "register_operand" ""))
18997 (clobber (match_dup 2))])]
19001 (define_insn "*cmpstrnqi_nz_1"
19002 [(set (reg:CC FLAGS_REG)
19003 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19004 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19005 (use (match_operand:SI 6 "register_operand" "2"))
19006 (use (match_operand:SI 3 "immediate_operand" "i"))
19007 (clobber (match_operand:SI 0 "register_operand" "=S"))
19008 (clobber (match_operand:SI 1 "register_operand" "=D"))
19009 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19012 [(set_attr "type" "str")
19013 (set_attr "mode" "QI")
19014 (set_attr "prefix_rep" "1")])
19016 (define_insn "*cmpstrnqi_nz_rex_1"
19017 [(set (reg:CC FLAGS_REG)
19018 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19019 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19020 (use (match_operand:DI 6 "register_operand" "2"))
19021 (use (match_operand:SI 3 "immediate_operand" "i"))
19022 (clobber (match_operand:DI 0 "register_operand" "=S"))
19023 (clobber (match_operand:DI 1 "register_operand" "=D"))
19024 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19027 [(set_attr "type" "str")
19028 (set_attr "mode" "QI")
19029 (set_attr "prefix_rep" "1")])
19031 ;; The same, but the count is not known to not be zero.
19033 (define_expand "cmpstrnqi_1"
19034 [(parallel [(set (reg:CC FLAGS_REG)
19035 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19037 (compare:CC (match_operand 4 "memory_operand" "")
19038 (match_operand 5 "memory_operand" ""))
19040 (use (match_operand:SI 3 "immediate_operand" ""))
19041 (use (reg:CC FLAGS_REG))
19042 (clobber (match_operand 0 "register_operand" ""))
19043 (clobber (match_operand 1 "register_operand" ""))
19044 (clobber (match_dup 2))])]
19048 (define_insn "*cmpstrnqi_1"
19049 [(set (reg:CC FLAGS_REG)
19050 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19052 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19053 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19055 (use (match_operand:SI 3 "immediate_operand" "i"))
19056 (use (reg:CC FLAGS_REG))
19057 (clobber (match_operand:SI 0 "register_operand" "=S"))
19058 (clobber (match_operand:SI 1 "register_operand" "=D"))
19059 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19062 [(set_attr "type" "str")
19063 (set_attr "mode" "QI")
19064 (set_attr "prefix_rep" "1")])
19066 (define_insn "*cmpstrnqi_rex_1"
19067 [(set (reg:CC FLAGS_REG)
19068 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19070 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19071 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19073 (use (match_operand:SI 3 "immediate_operand" "i"))
19074 (use (reg:CC FLAGS_REG))
19075 (clobber (match_operand:DI 0 "register_operand" "=S"))
19076 (clobber (match_operand:DI 1 "register_operand" "=D"))
19077 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19080 [(set_attr "type" "str")
19081 (set_attr "mode" "QI")
19082 (set_attr "prefix_rep" "1")])
19084 (define_expand "strlensi"
19085 [(set (match_operand:SI 0 "register_operand" "")
19086 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19087 (match_operand:QI 2 "immediate_operand" "")
19088 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19091 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19097 (define_expand "strlendi"
19098 [(set (match_operand:DI 0 "register_operand" "")
19099 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19100 (match_operand:QI 2 "immediate_operand" "")
19101 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19104 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19110 (define_expand "strlenqi_1"
19111 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19112 (clobber (match_operand 1 "register_operand" ""))
19113 (clobber (reg:CC FLAGS_REG))])]
19117 (define_insn "*strlenqi_1"
19118 [(set (match_operand:SI 0 "register_operand" "=&c")
19119 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19120 (match_operand:QI 2 "register_operand" "a")
19121 (match_operand:SI 3 "immediate_operand" "i")
19122 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19123 (clobber (match_operand:SI 1 "register_operand" "=D"))
19124 (clobber (reg:CC FLAGS_REG))]
19127 [(set_attr "type" "str")
19128 (set_attr "mode" "QI")
19129 (set_attr "prefix_rep" "1")])
19131 (define_insn "*strlenqi_rex_1"
19132 [(set (match_operand:DI 0 "register_operand" "=&c")
19133 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19134 (match_operand:QI 2 "register_operand" "a")
19135 (match_operand:DI 3 "immediate_operand" "i")
19136 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19137 (clobber (match_operand:DI 1 "register_operand" "=D"))
19138 (clobber (reg:CC FLAGS_REG))]
19141 [(set_attr "type" "str")
19142 (set_attr "mode" "QI")
19143 (set_attr "prefix_rep" "1")])
19145 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19146 ;; handled in combine, but it is not currently up to the task.
19147 ;; When used for their truth value, the cmpstrn* expanders generate
19156 ;; The intermediate three instructions are unnecessary.
19158 ;; This one handles cmpstrn*_nz_1...
19161 (set (reg:CC FLAGS_REG)
19162 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19163 (mem:BLK (match_operand 5 "register_operand" ""))))
19164 (use (match_operand 6 "register_operand" ""))
19165 (use (match_operand:SI 3 "immediate_operand" ""))
19166 (clobber (match_operand 0 "register_operand" ""))
19167 (clobber (match_operand 1 "register_operand" ""))
19168 (clobber (match_operand 2 "register_operand" ""))])
19169 (set (match_operand:QI 7 "register_operand" "")
19170 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19171 (set (match_operand:QI 8 "register_operand" "")
19172 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19173 (set (reg FLAGS_REG)
19174 (compare (match_dup 7) (match_dup 8)))
19176 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19178 (set (reg:CC FLAGS_REG)
19179 (compare:CC (mem:BLK (match_dup 4))
19180 (mem:BLK (match_dup 5))))
19181 (use (match_dup 6))
19182 (use (match_dup 3))
19183 (clobber (match_dup 0))
19184 (clobber (match_dup 1))
19185 (clobber (match_dup 2))])]
19188 ;; ...and this one handles cmpstrn*_1.
19191 (set (reg:CC FLAGS_REG)
19192 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19194 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19195 (mem:BLK (match_operand 5 "register_operand" "")))
19197 (use (match_operand:SI 3 "immediate_operand" ""))
19198 (use (reg:CC FLAGS_REG))
19199 (clobber (match_operand 0 "register_operand" ""))
19200 (clobber (match_operand 1 "register_operand" ""))
19201 (clobber (match_operand 2 "register_operand" ""))])
19202 (set (match_operand:QI 7 "register_operand" "")
19203 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19204 (set (match_operand:QI 8 "register_operand" "")
19205 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19206 (set (reg FLAGS_REG)
19207 (compare (match_dup 7) (match_dup 8)))
19209 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19211 (set (reg:CC FLAGS_REG)
19212 (if_then_else:CC (ne (match_dup 6)
19214 (compare:CC (mem:BLK (match_dup 4))
19215 (mem:BLK (match_dup 5)))
19217 (use (match_dup 3))
19218 (use (reg:CC FLAGS_REG))
19219 (clobber (match_dup 0))
19220 (clobber (match_dup 1))
19221 (clobber (match_dup 2))])]
19226 ;; Conditional move instructions.
19228 (define_expand "movdicc"
19229 [(set (match_operand:DI 0 "register_operand" "")
19230 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19231 (match_operand:DI 2 "general_operand" "")
19232 (match_operand:DI 3 "general_operand" "")))]
19234 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19236 (define_insn "x86_movdicc_0_m1_rex64"
19237 [(set (match_operand:DI 0 "register_operand" "=r")
19238 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19241 (clobber (reg:CC FLAGS_REG))]
19244 ; Since we don't have the proper number of operands for an alu insn,
19245 ; fill in all the blanks.
19246 [(set_attr "type" "alu")
19247 (set_attr "pent_pair" "pu")
19248 (set_attr "memory" "none")
19249 (set_attr "imm_disp" "false")
19250 (set_attr "mode" "DI")
19251 (set_attr "length_immediate" "0")])
19253 (define_insn "*x86_movdicc_0_m1_se"
19254 [(set (match_operand:DI 0 "register_operand" "=r")
19255 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19258 (clobber (reg:CC FLAGS_REG))]
19261 [(set_attr "type" "alu")
19262 (set_attr "pent_pair" "pu")
19263 (set_attr "memory" "none")
19264 (set_attr "imm_disp" "false")
19265 (set_attr "mode" "DI")
19266 (set_attr "length_immediate" "0")])
19268 (define_insn "*movdicc_c_rex64"
19269 [(set (match_operand:DI 0 "register_operand" "=r,r")
19270 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19271 [(reg FLAGS_REG) (const_int 0)])
19272 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19273 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19274 "TARGET_64BIT && TARGET_CMOVE
19275 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19277 cmov%O2%C1\t{%2, %0|%0, %2}
19278 cmov%O2%c1\t{%3, %0|%0, %3}"
19279 [(set_attr "type" "icmov")
19280 (set_attr "mode" "DI")])
19282 (define_expand "movsicc"
19283 [(set (match_operand:SI 0 "register_operand" "")
19284 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19285 (match_operand:SI 2 "general_operand" "")
19286 (match_operand:SI 3 "general_operand" "")))]
19288 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19290 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19291 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19292 ;; So just document what we're doing explicitly.
19294 (define_insn "x86_movsicc_0_m1"
19295 [(set (match_operand:SI 0 "register_operand" "=r")
19296 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19299 (clobber (reg:CC FLAGS_REG))]
19302 ; Since we don't have the proper number of operands for an alu insn,
19303 ; fill in all the blanks.
19304 [(set_attr "type" "alu")
19305 (set_attr "pent_pair" "pu")
19306 (set_attr "memory" "none")
19307 (set_attr "imm_disp" "false")
19308 (set_attr "mode" "SI")
19309 (set_attr "length_immediate" "0")])
19311 (define_insn "*x86_movsicc_0_m1_se"
19312 [(set (match_operand:SI 0 "register_operand" "=r")
19313 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19316 (clobber (reg:CC FLAGS_REG))]
19319 [(set_attr "type" "alu")
19320 (set_attr "pent_pair" "pu")
19321 (set_attr "memory" "none")
19322 (set_attr "imm_disp" "false")
19323 (set_attr "mode" "SI")
19324 (set_attr "length_immediate" "0")])
19326 (define_insn "*movsicc_noc"
19327 [(set (match_operand:SI 0 "register_operand" "=r,r")
19328 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19329 [(reg FLAGS_REG) (const_int 0)])
19330 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19331 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19333 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19335 cmov%O2%C1\t{%2, %0|%0, %2}
19336 cmov%O2%c1\t{%3, %0|%0, %3}"
19337 [(set_attr "type" "icmov")
19338 (set_attr "mode" "SI")])
19340 (define_expand "movhicc"
19341 [(set (match_operand:HI 0 "register_operand" "")
19342 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19343 (match_operand:HI 2 "general_operand" "")
19344 (match_operand:HI 3 "general_operand" "")))]
19345 "TARGET_HIMODE_MATH"
19346 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19348 (define_insn "*movhicc_noc"
19349 [(set (match_operand:HI 0 "register_operand" "=r,r")
19350 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19351 [(reg FLAGS_REG) (const_int 0)])
19352 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19353 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19355 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19357 cmov%O2%C1\t{%2, %0|%0, %2}
19358 cmov%O2%c1\t{%3, %0|%0, %3}"
19359 [(set_attr "type" "icmov")
19360 (set_attr "mode" "HI")])
19362 (define_expand "movqicc"
19363 [(set (match_operand:QI 0 "register_operand" "")
19364 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19365 (match_operand:QI 2 "general_operand" "")
19366 (match_operand:QI 3 "general_operand" "")))]
19367 "TARGET_QIMODE_MATH"
19368 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19370 (define_insn_and_split "*movqicc_noc"
19371 [(set (match_operand:QI 0 "register_operand" "=r,r")
19372 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19373 [(match_operand 4 "flags_reg_operand" "")
19375 (match_operand:QI 2 "register_operand" "r,0")
19376 (match_operand:QI 3 "register_operand" "0,r")))]
19377 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19379 "&& reload_completed"
19380 [(set (match_dup 0)
19381 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19384 "operands[0] = gen_lowpart (SImode, operands[0]);
19385 operands[2] = gen_lowpart (SImode, operands[2]);
19386 operands[3] = gen_lowpart (SImode, operands[3]);"
19387 [(set_attr "type" "icmov")
19388 (set_attr "mode" "SI")])
19390 (define_expand "mov<mode>cc"
19391 [(set (match_operand:X87MODEF 0 "register_operand" "")
19392 (if_then_else:X87MODEF
19393 (match_operand 1 "comparison_operator" "")
19394 (match_operand:X87MODEF 2 "register_operand" "")
19395 (match_operand:X87MODEF 3 "register_operand" "")))]
19396 "(TARGET_80387 && TARGET_CMOVE)
19397 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19398 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19400 (define_insn "*movsfcc_1_387"
19401 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19402 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19403 [(reg FLAGS_REG) (const_int 0)])
19404 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19405 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19406 "TARGET_80387 && TARGET_CMOVE
19407 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19409 fcmov%F1\t{%2, %0|%0, %2}
19410 fcmov%f1\t{%3, %0|%0, %3}
19411 cmov%O2%C1\t{%2, %0|%0, %2}
19412 cmov%O2%c1\t{%3, %0|%0, %3}"
19413 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19414 (set_attr "mode" "SF,SF,SI,SI")])
19416 (define_insn "*movdfcc_1"
19417 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19418 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19419 [(reg FLAGS_REG) (const_int 0)])
19420 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19421 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19422 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19423 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19425 fcmov%F1\t{%2, %0|%0, %2}
19426 fcmov%f1\t{%3, %0|%0, %3}
19429 [(set_attr "type" "fcmov,fcmov,multi,multi")
19430 (set_attr "mode" "DF")])
19432 (define_insn "*movdfcc_1_rex64"
19433 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19434 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19435 [(reg FLAGS_REG) (const_int 0)])
19436 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19437 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19438 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19439 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19441 fcmov%F1\t{%2, %0|%0, %2}
19442 fcmov%f1\t{%3, %0|%0, %3}
19443 cmov%O2%C1\t{%2, %0|%0, %2}
19444 cmov%O2%c1\t{%3, %0|%0, %3}"
19445 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19446 (set_attr "mode" "DF")])
19449 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19450 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19451 [(match_operand 4 "flags_reg_operand" "")
19453 (match_operand:DF 2 "nonimmediate_operand" "")
19454 (match_operand:DF 3 "nonimmediate_operand" "")))]
19455 "!TARGET_64BIT && reload_completed"
19456 [(set (match_dup 2)
19457 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19461 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19464 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19465 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19467 (define_insn "*movxfcc_1"
19468 [(set (match_operand:XF 0 "register_operand" "=f,f")
19469 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19470 [(reg FLAGS_REG) (const_int 0)])
19471 (match_operand:XF 2 "register_operand" "f,0")
19472 (match_operand:XF 3 "register_operand" "0,f")))]
19473 "TARGET_80387 && TARGET_CMOVE"
19475 fcmov%F1\t{%2, %0|%0, %2}
19476 fcmov%f1\t{%3, %0|%0, %3}"
19477 [(set_attr "type" "fcmov")
19478 (set_attr "mode" "XF")])
19480 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19481 ;; the scalar versions to have only XMM registers as operands.
19483 ;; SSE5 conditional move
19484 (define_insn "*sse5_pcmov_<mode>"
19485 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19486 (if_then_else:MODEF
19487 (match_operand:MODEF 1 "register_operand" "x,0")
19488 (match_operand:MODEF 2 "register_operand" "0,x")
19489 (match_operand:MODEF 3 "register_operand" "x,x")))]
19490 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19491 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19492 [(set_attr "type" "sse4arg")])
19494 ;; These versions of the min/max patterns are intentionally ignorant of
19495 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19496 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19497 ;; are undefined in this condition, we're certain this is correct.
19499 (define_insn "<code><mode>3"
19500 [(set (match_operand:MODEF 0 "register_operand" "=x")
19502 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19503 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19504 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19505 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19506 [(set_attr "type" "sseadd")
19507 (set_attr "mode" "<MODE>")])
19509 ;; These versions of the min/max patterns implement exactly the operations
19510 ;; min = (op1 < op2 ? op1 : op2)
19511 ;; max = (!(op1 < op2) ? op1 : op2)
19512 ;; Their operands are not commutative, and thus they may be used in the
19513 ;; presence of -0.0 and NaN.
19515 (define_insn "*ieee_smin<mode>3"
19516 [(set (match_operand:MODEF 0 "register_operand" "=x")
19518 [(match_operand:MODEF 1 "register_operand" "0")
19519 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19521 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19522 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19523 [(set_attr "type" "sseadd")
19524 (set_attr "mode" "<MODE>")])
19526 (define_insn "*ieee_smax<mode>3"
19527 [(set (match_operand:MODEF 0 "register_operand" "=x")
19529 [(match_operand:MODEF 1 "register_operand" "0")
19530 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19532 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19533 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19534 [(set_attr "type" "sseadd")
19535 (set_attr "mode" "<MODE>")])
19537 ;; Make two stack loads independent:
19539 ;; fld %st(0) -> fld bb
19540 ;; fmul bb fmul %st(1), %st
19542 ;; Actually we only match the last two instructions for simplicity.
19544 [(set (match_operand 0 "fp_register_operand" "")
19545 (match_operand 1 "fp_register_operand" ""))
19547 (match_operator 2 "binary_fp_operator"
19549 (match_operand 3 "memory_operand" "")]))]
19550 "REGNO (operands[0]) != REGNO (operands[1])"
19551 [(set (match_dup 0) (match_dup 3))
19552 (set (match_dup 0) (match_dup 4))]
19554 ;; The % modifier is not operational anymore in peephole2's, so we have to
19555 ;; swap the operands manually in the case of addition and multiplication.
19556 "if (COMMUTATIVE_ARITH_P (operands[2]))
19557 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19558 operands[0], operands[1]);
19560 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19561 operands[1], operands[0]);")
19563 ;; Conditional addition patterns
19564 (define_expand "addqicc"
19565 [(match_operand:QI 0 "register_operand" "")
19566 (match_operand 1 "comparison_operator" "")
19567 (match_operand:QI 2 "register_operand" "")
19568 (match_operand:QI 3 "const_int_operand" "")]
19570 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19572 (define_expand "addhicc"
19573 [(match_operand:HI 0 "register_operand" "")
19574 (match_operand 1 "comparison_operator" "")
19575 (match_operand:HI 2 "register_operand" "")
19576 (match_operand:HI 3 "const_int_operand" "")]
19578 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19580 (define_expand "addsicc"
19581 [(match_operand:SI 0 "register_operand" "")
19582 (match_operand 1 "comparison_operator" "")
19583 (match_operand:SI 2 "register_operand" "")
19584 (match_operand:SI 3 "const_int_operand" "")]
19586 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19588 (define_expand "adddicc"
19589 [(match_operand:DI 0 "register_operand" "")
19590 (match_operand 1 "comparison_operator" "")
19591 (match_operand:DI 2 "register_operand" "")
19592 (match_operand:DI 3 "const_int_operand" "")]
19594 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19597 ;; Misc patterns (?)
19599 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19600 ;; Otherwise there will be nothing to keep
19602 ;; [(set (reg ebp) (reg esp))]
19603 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19604 ;; (clobber (eflags)]
19605 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19607 ;; in proper program order.
19608 (define_insn "pro_epilogue_adjust_stack_1"
19609 [(set (match_operand:SI 0 "register_operand" "=r,r")
19610 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19611 (match_operand:SI 2 "immediate_operand" "i,i")))
19612 (clobber (reg:CC FLAGS_REG))
19613 (clobber (mem:BLK (scratch)))]
19616 switch (get_attr_type (insn))
19619 return "mov{l}\t{%1, %0|%0, %1}";
19622 if (CONST_INT_P (operands[2])
19623 && (INTVAL (operands[2]) == 128
19624 || (INTVAL (operands[2]) < 0
19625 && INTVAL (operands[2]) != -128)))
19627 operands[2] = GEN_INT (-INTVAL (operands[2]));
19628 return "sub{l}\t{%2, %0|%0, %2}";
19630 return "add{l}\t{%2, %0|%0, %2}";
19633 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19634 return "lea{l}\t{%a2, %0|%0, %a2}";
19637 gcc_unreachable ();
19640 [(set (attr "type")
19641 (cond [(eq_attr "alternative" "0")
19642 (const_string "alu")
19643 (match_operand:SI 2 "const0_operand" "")
19644 (const_string "imov")
19646 (const_string "lea")))
19647 (set_attr "mode" "SI")])
19649 (define_insn "pro_epilogue_adjust_stack_rex64"
19650 [(set (match_operand:DI 0 "register_operand" "=r,r")
19651 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19652 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19653 (clobber (reg:CC FLAGS_REG))
19654 (clobber (mem:BLK (scratch)))]
19657 switch (get_attr_type (insn))
19660 return "mov{q}\t{%1, %0|%0, %1}";
19663 if (CONST_INT_P (operands[2])
19664 /* Avoid overflows. */
19665 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19666 && (INTVAL (operands[2]) == 128
19667 || (INTVAL (operands[2]) < 0
19668 && INTVAL (operands[2]) != -128)))
19670 operands[2] = GEN_INT (-INTVAL (operands[2]));
19671 return "sub{q}\t{%2, %0|%0, %2}";
19673 return "add{q}\t{%2, %0|%0, %2}";
19676 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19677 return "lea{q}\t{%a2, %0|%0, %a2}";
19680 gcc_unreachable ();
19683 [(set (attr "type")
19684 (cond [(eq_attr "alternative" "0")
19685 (const_string "alu")
19686 (match_operand:DI 2 "const0_operand" "")
19687 (const_string "imov")
19689 (const_string "lea")))
19690 (set_attr "mode" "DI")])
19692 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19693 [(set (match_operand:DI 0 "register_operand" "=r,r")
19694 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19695 (match_operand:DI 3 "immediate_operand" "i,i")))
19696 (use (match_operand:DI 2 "register_operand" "r,r"))
19697 (clobber (reg:CC FLAGS_REG))
19698 (clobber (mem:BLK (scratch)))]
19701 switch (get_attr_type (insn))
19704 return "add{q}\t{%2, %0|%0, %2}";
19707 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19708 return "lea{q}\t{%a2, %0|%0, %a2}";
19711 gcc_unreachable ();
19714 [(set_attr "type" "alu,lea")
19715 (set_attr "mode" "DI")])
19717 (define_insn "allocate_stack_worker_32"
19718 [(set (match_operand:SI 0 "register_operand" "+a")
19719 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19720 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19721 (clobber (reg:CC FLAGS_REG))]
19722 "!TARGET_64BIT && TARGET_STACK_PROBE"
19724 [(set_attr "type" "multi")
19725 (set_attr "length" "5")])
19727 (define_insn "allocate_stack_worker_64"
19728 [(set (match_operand:DI 0 "register_operand" "=a")
19729 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19730 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19731 (clobber (reg:DI R10_REG))
19732 (clobber (reg:DI R11_REG))
19733 (clobber (reg:CC FLAGS_REG))]
19734 "TARGET_64BIT && TARGET_STACK_PROBE"
19736 [(set_attr "type" "multi")
19737 (set_attr "length" "5")])
19739 (define_expand "allocate_stack"
19740 [(match_operand 0 "register_operand" "")
19741 (match_operand 1 "general_operand" "")]
19742 "TARGET_STACK_PROBE"
19746 #ifndef CHECK_STACK_LIMIT
19747 #define CHECK_STACK_LIMIT 0
19750 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19751 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19753 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19754 stack_pointer_rtx, 0, OPTAB_DIRECT);
19755 if (x != stack_pointer_rtx)
19756 emit_move_insn (stack_pointer_rtx, x);
19760 x = copy_to_mode_reg (Pmode, operands[1]);
19762 x = gen_allocate_stack_worker_64 (x);
19764 x = gen_allocate_stack_worker_32 (x);
19768 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19772 (define_expand "builtin_setjmp_receiver"
19773 [(label_ref (match_operand 0 "" ""))]
19774 "!TARGET_64BIT && flag_pic"
19779 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19780 rtx label_rtx = gen_label_rtx ();
19781 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19782 xops[0] = xops[1] = picreg;
19783 xops[2] = gen_rtx_CONST (SImode,
19784 gen_rtx_MINUS (SImode,
19785 gen_rtx_LABEL_REF (SImode, label_rtx),
19786 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19787 ix86_expand_binary_operator (MINUS, SImode, xops);
19790 emit_insn (gen_set_got (pic_offset_table_rtx));
19794 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19797 [(set (match_operand 0 "register_operand" "")
19798 (match_operator 3 "promotable_binary_operator"
19799 [(match_operand 1 "register_operand" "")
19800 (match_operand 2 "aligned_operand" "")]))
19801 (clobber (reg:CC FLAGS_REG))]
19802 "! TARGET_PARTIAL_REG_STALL && reload_completed
19803 && ((GET_MODE (operands[0]) == HImode
19804 && ((!optimize_size && !TARGET_FAST_PREFIX)
19805 /* ??? next two lines just !satisfies_constraint_K (...) */
19806 || !CONST_INT_P (operands[2])
19807 || satisfies_constraint_K (operands[2])))
19808 || (GET_MODE (operands[0]) == QImode
19809 && (TARGET_PROMOTE_QImode || optimize_size)))"
19810 [(parallel [(set (match_dup 0)
19811 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19812 (clobber (reg:CC FLAGS_REG))])]
19813 "operands[0] = gen_lowpart (SImode, operands[0]);
19814 operands[1] = gen_lowpart (SImode, operands[1]);
19815 if (GET_CODE (operands[3]) != ASHIFT)
19816 operands[2] = gen_lowpart (SImode, operands[2]);
19817 PUT_MODE (operands[3], SImode);")
19819 ; Promote the QImode tests, as i386 has encoding of the AND
19820 ; instruction with 32-bit sign-extended immediate and thus the
19821 ; instruction size is unchanged, except in the %eax case for
19822 ; which it is increased by one byte, hence the ! optimize_size.
19824 [(set (match_operand 0 "flags_reg_operand" "")
19825 (match_operator 2 "compare_operator"
19826 [(and (match_operand 3 "aligned_operand" "")
19827 (match_operand 4 "const_int_operand" ""))
19829 (set (match_operand 1 "register_operand" "")
19830 (and (match_dup 3) (match_dup 4)))]
19831 "! TARGET_PARTIAL_REG_STALL && reload_completed
19833 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19834 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19835 /* Ensure that the operand will remain sign-extended immediate. */
19836 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19837 [(parallel [(set (match_dup 0)
19838 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19841 (and:SI (match_dup 3) (match_dup 4)))])]
19844 = gen_int_mode (INTVAL (operands[4])
19845 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19846 operands[1] = gen_lowpart (SImode, operands[1]);
19847 operands[3] = gen_lowpart (SImode, operands[3]);
19850 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19851 ; the TEST instruction with 32-bit sign-extended immediate and thus
19852 ; the instruction size would at least double, which is not what we
19853 ; want even with ! optimize_size.
19855 [(set (match_operand 0 "flags_reg_operand" "")
19856 (match_operator 1 "compare_operator"
19857 [(and (match_operand:HI 2 "aligned_operand" "")
19858 (match_operand:HI 3 "const_int_operand" ""))
19860 "! TARGET_PARTIAL_REG_STALL && reload_completed
19861 && ! TARGET_FAST_PREFIX
19863 /* Ensure that the operand will remain sign-extended immediate. */
19864 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19865 [(set (match_dup 0)
19866 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19870 = gen_int_mode (INTVAL (operands[3])
19871 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19872 operands[2] = gen_lowpart (SImode, operands[2]);
19876 [(set (match_operand 0 "register_operand" "")
19877 (neg (match_operand 1 "register_operand" "")))
19878 (clobber (reg:CC FLAGS_REG))]
19879 "! TARGET_PARTIAL_REG_STALL && reload_completed
19880 && (GET_MODE (operands[0]) == HImode
19881 || (GET_MODE (operands[0]) == QImode
19882 && (TARGET_PROMOTE_QImode || optimize_size)))"
19883 [(parallel [(set (match_dup 0)
19884 (neg:SI (match_dup 1)))
19885 (clobber (reg:CC FLAGS_REG))])]
19886 "operands[0] = gen_lowpart (SImode, operands[0]);
19887 operands[1] = gen_lowpart (SImode, operands[1]);")
19890 [(set (match_operand 0 "register_operand" "")
19891 (not (match_operand 1 "register_operand" "")))]
19892 "! TARGET_PARTIAL_REG_STALL && reload_completed
19893 && (GET_MODE (operands[0]) == HImode
19894 || (GET_MODE (operands[0]) == QImode
19895 && (TARGET_PROMOTE_QImode || optimize_size)))"
19896 [(set (match_dup 0)
19897 (not:SI (match_dup 1)))]
19898 "operands[0] = gen_lowpart (SImode, operands[0]);
19899 operands[1] = gen_lowpart (SImode, operands[1]);")
19902 [(set (match_operand 0 "register_operand" "")
19903 (if_then_else (match_operator 1 "comparison_operator"
19904 [(reg FLAGS_REG) (const_int 0)])
19905 (match_operand 2 "register_operand" "")
19906 (match_operand 3 "register_operand" "")))]
19907 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19908 && (GET_MODE (operands[0]) == HImode
19909 || (GET_MODE (operands[0]) == QImode
19910 && (TARGET_PROMOTE_QImode || optimize_size)))"
19911 [(set (match_dup 0)
19912 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19913 "operands[0] = gen_lowpart (SImode, operands[0]);
19914 operands[2] = gen_lowpart (SImode, operands[2]);
19915 operands[3] = gen_lowpart (SImode, operands[3]);")
19918 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19919 ;; transform a complex memory operation into two memory to register operations.
19921 ;; Don't push memory operands
19923 [(set (match_operand:SI 0 "push_operand" "")
19924 (match_operand:SI 1 "memory_operand" ""))
19925 (match_scratch:SI 2 "r")]
19926 "!optimize_size && !TARGET_PUSH_MEMORY
19927 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19928 [(set (match_dup 2) (match_dup 1))
19929 (set (match_dup 0) (match_dup 2))]
19933 [(set (match_operand:DI 0 "push_operand" "")
19934 (match_operand:DI 1 "memory_operand" ""))
19935 (match_scratch:DI 2 "r")]
19936 "!optimize_size && !TARGET_PUSH_MEMORY
19937 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19938 [(set (match_dup 2) (match_dup 1))
19939 (set (match_dup 0) (match_dup 2))]
19942 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19945 [(set (match_operand:SF 0 "push_operand" "")
19946 (match_operand:SF 1 "memory_operand" ""))
19947 (match_scratch:SF 2 "r")]
19948 "!optimize_size && !TARGET_PUSH_MEMORY
19949 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19950 [(set (match_dup 2) (match_dup 1))
19951 (set (match_dup 0) (match_dup 2))]
19955 [(set (match_operand:HI 0 "push_operand" "")
19956 (match_operand:HI 1 "memory_operand" ""))
19957 (match_scratch:HI 2 "r")]
19958 "!optimize_size && !TARGET_PUSH_MEMORY
19959 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19960 [(set (match_dup 2) (match_dup 1))
19961 (set (match_dup 0) (match_dup 2))]
19965 [(set (match_operand:QI 0 "push_operand" "")
19966 (match_operand:QI 1 "memory_operand" ""))
19967 (match_scratch:QI 2 "q")]
19968 "!optimize_size && !TARGET_PUSH_MEMORY
19969 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19970 [(set (match_dup 2) (match_dup 1))
19971 (set (match_dup 0) (match_dup 2))]
19974 ;; Don't move an immediate directly to memory when the instruction
19977 [(match_scratch:SI 1 "r")
19978 (set (match_operand:SI 0 "memory_operand" "")
19981 && ! TARGET_USE_MOV0
19982 && TARGET_SPLIT_LONG_MOVES
19983 && get_attr_length (insn) >= ix86_cost->large_insn
19984 && peep2_regno_dead_p (0, FLAGS_REG)"
19985 [(parallel [(set (match_dup 1) (const_int 0))
19986 (clobber (reg:CC FLAGS_REG))])
19987 (set (match_dup 0) (match_dup 1))]
19991 [(match_scratch:HI 1 "r")
19992 (set (match_operand:HI 0 "memory_operand" "")
19995 && ! TARGET_USE_MOV0
19996 && TARGET_SPLIT_LONG_MOVES
19997 && get_attr_length (insn) >= ix86_cost->large_insn
19998 && peep2_regno_dead_p (0, FLAGS_REG)"
19999 [(parallel [(set (match_dup 2) (const_int 0))
20000 (clobber (reg:CC FLAGS_REG))])
20001 (set (match_dup 0) (match_dup 1))]
20002 "operands[2] = gen_lowpart (SImode, operands[1]);")
20005 [(match_scratch:QI 1 "q")
20006 (set (match_operand:QI 0 "memory_operand" "")
20009 && ! TARGET_USE_MOV0
20010 && TARGET_SPLIT_LONG_MOVES
20011 && get_attr_length (insn) >= ix86_cost->large_insn
20012 && peep2_regno_dead_p (0, FLAGS_REG)"
20013 [(parallel [(set (match_dup 2) (const_int 0))
20014 (clobber (reg:CC FLAGS_REG))])
20015 (set (match_dup 0) (match_dup 1))]
20016 "operands[2] = gen_lowpart (SImode, operands[1]);")
20019 [(match_scratch:SI 2 "r")
20020 (set (match_operand:SI 0 "memory_operand" "")
20021 (match_operand:SI 1 "immediate_operand" ""))]
20023 && TARGET_SPLIT_LONG_MOVES
20024 && get_attr_length (insn) >= ix86_cost->large_insn"
20025 [(set (match_dup 2) (match_dup 1))
20026 (set (match_dup 0) (match_dup 2))]
20030 [(match_scratch:HI 2 "r")
20031 (set (match_operand:HI 0 "memory_operand" "")
20032 (match_operand:HI 1 "immediate_operand" ""))]
20034 && TARGET_SPLIT_LONG_MOVES
20035 && get_attr_length (insn) >= ix86_cost->large_insn"
20036 [(set (match_dup 2) (match_dup 1))
20037 (set (match_dup 0) (match_dup 2))]
20041 [(match_scratch:QI 2 "q")
20042 (set (match_operand:QI 0 "memory_operand" "")
20043 (match_operand:QI 1 "immediate_operand" ""))]
20045 && TARGET_SPLIT_LONG_MOVES
20046 && get_attr_length (insn) >= ix86_cost->large_insn"
20047 [(set (match_dup 2) (match_dup 1))
20048 (set (match_dup 0) (match_dup 2))]
20051 ;; Don't compare memory with zero, load and use a test instead.
20053 [(set (match_operand 0 "flags_reg_operand" "")
20054 (match_operator 1 "compare_operator"
20055 [(match_operand:SI 2 "memory_operand" "")
20057 (match_scratch:SI 3 "r")]
20058 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20059 [(set (match_dup 3) (match_dup 2))
20060 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20063 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20064 ;; Don't split NOTs with a displacement operand, because resulting XOR
20065 ;; will not be pairable anyway.
20067 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20068 ;; represented using a modRM byte. The XOR replacement is long decoded,
20069 ;; so this split helps here as well.
20071 ;; Note: Can't do this as a regular split because we can't get proper
20072 ;; lifetime information then.
20075 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20076 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20078 && ((TARGET_NOT_UNPAIRABLE
20079 && (!MEM_P (operands[0])
20080 || !memory_displacement_operand (operands[0], SImode)))
20081 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20082 && peep2_regno_dead_p (0, FLAGS_REG)"
20083 [(parallel [(set (match_dup 0)
20084 (xor:SI (match_dup 1) (const_int -1)))
20085 (clobber (reg:CC FLAGS_REG))])]
20089 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20090 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20092 && ((TARGET_NOT_UNPAIRABLE
20093 && (!MEM_P (operands[0])
20094 || !memory_displacement_operand (operands[0], HImode)))
20095 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20096 && peep2_regno_dead_p (0, FLAGS_REG)"
20097 [(parallel [(set (match_dup 0)
20098 (xor:HI (match_dup 1) (const_int -1)))
20099 (clobber (reg:CC FLAGS_REG))])]
20103 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20104 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20106 && ((TARGET_NOT_UNPAIRABLE
20107 && (!MEM_P (operands[0])
20108 || !memory_displacement_operand (operands[0], QImode)))
20109 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20110 && peep2_regno_dead_p (0, FLAGS_REG)"
20111 [(parallel [(set (match_dup 0)
20112 (xor:QI (match_dup 1) (const_int -1)))
20113 (clobber (reg:CC FLAGS_REG))])]
20116 ;; Non pairable "test imm, reg" instructions can be translated to
20117 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20118 ;; byte opcode instead of two, have a short form for byte operands),
20119 ;; so do it for other CPUs as well. Given that the value was dead,
20120 ;; this should not create any new dependencies. Pass on the sub-word
20121 ;; versions if we're concerned about partial register stalls.
20124 [(set (match_operand 0 "flags_reg_operand" "")
20125 (match_operator 1 "compare_operator"
20126 [(and:SI (match_operand:SI 2 "register_operand" "")
20127 (match_operand:SI 3 "immediate_operand" ""))
20129 "ix86_match_ccmode (insn, CCNOmode)
20130 && (true_regnum (operands[2]) != AX_REG
20131 || satisfies_constraint_K (operands[3]))
20132 && peep2_reg_dead_p (1, operands[2])"
20134 [(set (match_dup 0)
20135 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20138 (and:SI (match_dup 2) (match_dup 3)))])]
20141 ;; We don't need to handle HImode case, because it will be promoted to SImode
20142 ;; on ! TARGET_PARTIAL_REG_STALL
20145 [(set (match_operand 0 "flags_reg_operand" "")
20146 (match_operator 1 "compare_operator"
20147 [(and:QI (match_operand:QI 2 "register_operand" "")
20148 (match_operand:QI 3 "immediate_operand" ""))
20150 "! TARGET_PARTIAL_REG_STALL
20151 && ix86_match_ccmode (insn, CCNOmode)
20152 && true_regnum (operands[2]) != AX_REG
20153 && peep2_reg_dead_p (1, operands[2])"
20155 [(set (match_dup 0)
20156 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20159 (and:QI (match_dup 2) (match_dup 3)))])]
20163 [(set (match_operand 0 "flags_reg_operand" "")
20164 (match_operator 1 "compare_operator"
20167 (match_operand 2 "ext_register_operand" "")
20170 (match_operand 3 "const_int_operand" ""))
20172 "! TARGET_PARTIAL_REG_STALL
20173 && ix86_match_ccmode (insn, CCNOmode)
20174 && true_regnum (operands[2]) != AX_REG
20175 && peep2_reg_dead_p (1, operands[2])"
20176 [(parallel [(set (match_dup 0)
20185 (set (zero_extract:SI (match_dup 2)
20196 ;; Don't do logical operations with memory inputs.
20198 [(match_scratch:SI 2 "r")
20199 (parallel [(set (match_operand:SI 0 "register_operand" "")
20200 (match_operator:SI 3 "arith_or_logical_operator"
20202 (match_operand:SI 1 "memory_operand" "")]))
20203 (clobber (reg:CC FLAGS_REG))])]
20204 "! optimize_size && ! TARGET_READ_MODIFY"
20205 [(set (match_dup 2) (match_dup 1))
20206 (parallel [(set (match_dup 0)
20207 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20208 (clobber (reg:CC FLAGS_REG))])]
20212 [(match_scratch:SI 2 "r")
20213 (parallel [(set (match_operand:SI 0 "register_operand" "")
20214 (match_operator:SI 3 "arith_or_logical_operator"
20215 [(match_operand:SI 1 "memory_operand" "")
20217 (clobber (reg:CC FLAGS_REG))])]
20218 "! optimize_size && ! TARGET_READ_MODIFY"
20219 [(set (match_dup 2) (match_dup 1))
20220 (parallel [(set (match_dup 0)
20221 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20222 (clobber (reg:CC FLAGS_REG))])]
20225 ; Don't do logical operations with memory outputs
20227 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20228 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20229 ; the same decoder scheduling characteristics as the original.
20232 [(match_scratch:SI 2 "r")
20233 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20234 (match_operator:SI 3 "arith_or_logical_operator"
20236 (match_operand:SI 1 "nonmemory_operand" "")]))
20237 (clobber (reg:CC FLAGS_REG))])]
20238 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20239 [(set (match_dup 2) (match_dup 0))
20240 (parallel [(set (match_dup 2)
20241 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20242 (clobber (reg:CC FLAGS_REG))])
20243 (set (match_dup 0) (match_dup 2))]
20247 [(match_scratch:SI 2 "r")
20248 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20249 (match_operator:SI 3 "arith_or_logical_operator"
20250 [(match_operand:SI 1 "nonmemory_operand" "")
20252 (clobber (reg:CC FLAGS_REG))])]
20253 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20254 [(set (match_dup 2) (match_dup 0))
20255 (parallel [(set (match_dup 2)
20256 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20257 (clobber (reg:CC FLAGS_REG))])
20258 (set (match_dup 0) (match_dup 2))]
20261 ;; Attempt to always use XOR for zeroing registers.
20263 [(set (match_operand 0 "register_operand" "")
20264 (match_operand 1 "const0_operand" ""))]
20265 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20266 && (! TARGET_USE_MOV0 || optimize_size)
20267 && GENERAL_REG_P (operands[0])
20268 && peep2_regno_dead_p (0, FLAGS_REG)"
20269 [(parallel [(set (match_dup 0) (const_int 0))
20270 (clobber (reg:CC FLAGS_REG))])]
20272 operands[0] = gen_lowpart (word_mode, operands[0]);
20276 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20278 "(GET_MODE (operands[0]) == QImode
20279 || GET_MODE (operands[0]) == HImode)
20280 && (! TARGET_USE_MOV0 || optimize_size)
20281 && peep2_regno_dead_p (0, FLAGS_REG)"
20282 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20283 (clobber (reg:CC FLAGS_REG))])])
20285 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20287 [(set (match_operand 0 "register_operand" "")
20289 "(GET_MODE (operands[0]) == HImode
20290 || GET_MODE (operands[0]) == SImode
20291 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20292 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20293 && peep2_regno_dead_p (0, FLAGS_REG)"
20294 [(parallel [(set (match_dup 0) (const_int -1))
20295 (clobber (reg:CC FLAGS_REG))])]
20296 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20299 ;; Attempt to convert simple leas to adds. These can be created by
20302 [(set (match_operand:SI 0 "register_operand" "")
20303 (plus:SI (match_dup 0)
20304 (match_operand:SI 1 "nonmemory_operand" "")))]
20305 "peep2_regno_dead_p (0, FLAGS_REG)"
20306 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20307 (clobber (reg:CC FLAGS_REG))])]
20311 [(set (match_operand:SI 0 "register_operand" "")
20312 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20313 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20314 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20315 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20316 (clobber (reg:CC FLAGS_REG))])]
20317 "operands[2] = gen_lowpart (SImode, operands[2]);")
20320 [(set (match_operand:DI 0 "register_operand" "")
20321 (plus:DI (match_dup 0)
20322 (match_operand:DI 1 "x86_64_general_operand" "")))]
20323 "peep2_regno_dead_p (0, FLAGS_REG)"
20324 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20325 (clobber (reg:CC FLAGS_REG))])]
20329 [(set (match_operand:SI 0 "register_operand" "")
20330 (mult:SI (match_dup 0)
20331 (match_operand:SI 1 "const_int_operand" "")))]
20332 "exact_log2 (INTVAL (operands[1])) >= 0
20333 && peep2_regno_dead_p (0, FLAGS_REG)"
20334 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20335 (clobber (reg:CC FLAGS_REG))])]
20336 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20339 [(set (match_operand:DI 0 "register_operand" "")
20340 (mult:DI (match_dup 0)
20341 (match_operand:DI 1 "const_int_operand" "")))]
20342 "exact_log2 (INTVAL (operands[1])) >= 0
20343 && peep2_regno_dead_p (0, FLAGS_REG)"
20344 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20345 (clobber (reg:CC FLAGS_REG))])]
20346 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20349 [(set (match_operand:SI 0 "register_operand" "")
20350 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20351 (match_operand:DI 2 "const_int_operand" "")) 0))]
20352 "exact_log2 (INTVAL (operands[2])) >= 0
20353 && REGNO (operands[0]) == REGNO (operands[1])
20354 && peep2_regno_dead_p (0, FLAGS_REG)"
20355 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20356 (clobber (reg:CC FLAGS_REG))])]
20357 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20359 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20360 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20361 ;; many CPUs it is also faster, since special hardware to avoid esp
20362 ;; dependencies is present.
20364 ;; While some of these conversions may be done using splitters, we use peepholes
20365 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20367 ;; Convert prologue esp subtractions to push.
20368 ;; We need register to push. In order to keep verify_flow_info happy we have
20370 ;; - use scratch and clobber it in order to avoid dependencies
20371 ;; - use already live register
20372 ;; We can't use the second way right now, since there is no reliable way how to
20373 ;; verify that given register is live. First choice will also most likely in
20374 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20375 ;; call clobbered registers are dead. We may want to use base pointer as an
20376 ;; alternative when no register is available later.
20379 [(match_scratch:SI 0 "r")
20380 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20381 (clobber (reg:CC FLAGS_REG))
20382 (clobber (mem:BLK (scratch)))])]
20383 "optimize_size || !TARGET_SUB_ESP_4"
20384 [(clobber (match_dup 0))
20385 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20386 (clobber (mem:BLK (scratch)))])])
20389 [(match_scratch:SI 0 "r")
20390 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20391 (clobber (reg:CC FLAGS_REG))
20392 (clobber (mem:BLK (scratch)))])]
20393 "optimize_size || !TARGET_SUB_ESP_8"
20394 [(clobber (match_dup 0))
20395 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20396 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20397 (clobber (mem:BLK (scratch)))])])
20399 ;; Convert esp subtractions to push.
20401 [(match_scratch:SI 0 "r")
20402 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20403 (clobber (reg:CC FLAGS_REG))])]
20404 "optimize_size || !TARGET_SUB_ESP_4"
20405 [(clobber (match_dup 0))
20406 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20409 [(match_scratch:SI 0 "r")
20410 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20411 (clobber (reg:CC FLAGS_REG))])]
20412 "optimize_size || !TARGET_SUB_ESP_8"
20413 [(clobber (match_dup 0))
20414 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20415 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20417 ;; Convert epilogue deallocator to pop.
20419 [(match_scratch:SI 0 "r")
20420 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20421 (clobber (reg:CC FLAGS_REG))
20422 (clobber (mem:BLK (scratch)))])]
20423 "optimize_size || !TARGET_ADD_ESP_4"
20424 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20425 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20426 (clobber (mem:BLK (scratch)))])]
20429 ;; Two pops case is tricky, since pop causes dependency on destination register.
20430 ;; We use two registers if available.
20432 [(match_scratch:SI 0 "r")
20433 (match_scratch:SI 1 "r")
20434 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20435 (clobber (reg:CC FLAGS_REG))
20436 (clobber (mem:BLK (scratch)))])]
20437 "optimize_size || !TARGET_ADD_ESP_8"
20438 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20439 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20440 (clobber (mem:BLK (scratch)))])
20441 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20442 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20446 [(match_scratch:SI 0 "r")
20447 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20448 (clobber (reg:CC FLAGS_REG))
20449 (clobber (mem:BLK (scratch)))])]
20451 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20452 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20453 (clobber (mem:BLK (scratch)))])
20454 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20455 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20458 ;; Convert esp additions to pop.
20460 [(match_scratch:SI 0 "r")
20461 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20462 (clobber (reg:CC FLAGS_REG))])]
20464 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20465 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20468 ;; Two pops case is tricky, since pop causes dependency on destination register.
20469 ;; We use two registers if available.
20471 [(match_scratch:SI 0 "r")
20472 (match_scratch:SI 1 "r")
20473 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20474 (clobber (reg:CC FLAGS_REG))])]
20476 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20477 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20478 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20479 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20483 [(match_scratch:SI 0 "r")
20484 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20485 (clobber (reg:CC FLAGS_REG))])]
20487 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20488 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20489 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20490 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20493 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20494 ;; required and register dies. Similarly for 128 to plus -128.
20496 [(set (match_operand 0 "flags_reg_operand" "")
20497 (match_operator 1 "compare_operator"
20498 [(match_operand 2 "register_operand" "")
20499 (match_operand 3 "const_int_operand" "")]))]
20500 "(INTVAL (operands[3]) == -1
20501 || INTVAL (operands[3]) == 1
20502 || INTVAL (operands[3]) == 128)
20503 && ix86_match_ccmode (insn, CCGCmode)
20504 && peep2_reg_dead_p (1, operands[2])"
20505 [(parallel [(set (match_dup 0)
20506 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20507 (clobber (match_dup 2))])]
20511 [(match_scratch:DI 0 "r")
20512 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20513 (clobber (reg:CC FLAGS_REG))
20514 (clobber (mem:BLK (scratch)))])]
20515 "optimize_size || !TARGET_SUB_ESP_4"
20516 [(clobber (match_dup 0))
20517 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20518 (clobber (mem:BLK (scratch)))])])
20521 [(match_scratch:DI 0 "r")
20522 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20523 (clobber (reg:CC FLAGS_REG))
20524 (clobber (mem:BLK (scratch)))])]
20525 "optimize_size || !TARGET_SUB_ESP_8"
20526 [(clobber (match_dup 0))
20527 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20528 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20529 (clobber (mem:BLK (scratch)))])])
20531 ;; Convert esp subtractions to push.
20533 [(match_scratch:DI 0 "r")
20534 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20535 (clobber (reg:CC FLAGS_REG))])]
20536 "optimize_size || !TARGET_SUB_ESP_4"
20537 [(clobber (match_dup 0))
20538 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20541 [(match_scratch:DI 0 "r")
20542 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20543 (clobber (reg:CC FLAGS_REG))])]
20544 "optimize_size || !TARGET_SUB_ESP_8"
20545 [(clobber (match_dup 0))
20546 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20547 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20549 ;; Convert epilogue deallocator to pop.
20551 [(match_scratch:DI 0 "r")
20552 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20553 (clobber (reg:CC FLAGS_REG))
20554 (clobber (mem:BLK (scratch)))])]
20555 "optimize_size || !TARGET_ADD_ESP_4"
20556 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20557 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20558 (clobber (mem:BLK (scratch)))])]
20561 ;; Two pops case is tricky, since pop causes dependency on destination register.
20562 ;; We use two registers if available.
20564 [(match_scratch:DI 0 "r")
20565 (match_scratch:DI 1 "r")
20566 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20567 (clobber (reg:CC FLAGS_REG))
20568 (clobber (mem:BLK (scratch)))])]
20569 "optimize_size || !TARGET_ADD_ESP_8"
20570 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20571 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20572 (clobber (mem:BLK (scratch)))])
20573 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20574 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20578 [(match_scratch:DI 0 "r")
20579 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20580 (clobber (reg:CC FLAGS_REG))
20581 (clobber (mem:BLK (scratch)))])]
20583 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20584 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20585 (clobber (mem:BLK (scratch)))])
20586 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20587 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20590 ;; Convert esp additions to pop.
20592 [(match_scratch:DI 0 "r")
20593 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20594 (clobber (reg:CC FLAGS_REG))])]
20596 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20597 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20600 ;; Two pops case is tricky, since pop causes dependency on destination register.
20601 ;; We use two registers if available.
20603 [(match_scratch:DI 0 "r")
20604 (match_scratch:DI 1 "r")
20605 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20606 (clobber (reg:CC FLAGS_REG))])]
20608 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20609 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20610 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20611 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20615 [(match_scratch:DI 0 "r")
20616 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20617 (clobber (reg:CC FLAGS_REG))])]
20619 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20620 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20621 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20622 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20625 ;; Convert imul by three, five and nine into lea
20628 [(set (match_operand:SI 0 "register_operand" "")
20629 (mult:SI (match_operand:SI 1 "register_operand" "")
20630 (match_operand:SI 2 "const_int_operand" "")))
20631 (clobber (reg:CC FLAGS_REG))])]
20632 "INTVAL (operands[2]) == 3
20633 || INTVAL (operands[2]) == 5
20634 || INTVAL (operands[2]) == 9"
20635 [(set (match_dup 0)
20636 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20638 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20642 [(set (match_operand:SI 0 "register_operand" "")
20643 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20644 (match_operand:SI 2 "const_int_operand" "")))
20645 (clobber (reg:CC FLAGS_REG))])]
20647 && (INTVAL (operands[2]) == 3
20648 || INTVAL (operands[2]) == 5
20649 || INTVAL (operands[2]) == 9)"
20650 [(set (match_dup 0) (match_dup 1))
20652 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20654 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20658 [(set (match_operand:DI 0 "register_operand" "")
20659 (mult:DI (match_operand:DI 1 "register_operand" "")
20660 (match_operand:DI 2 "const_int_operand" "")))
20661 (clobber (reg:CC FLAGS_REG))])]
20663 && (INTVAL (operands[2]) == 3
20664 || INTVAL (operands[2]) == 5
20665 || INTVAL (operands[2]) == 9)"
20666 [(set (match_dup 0)
20667 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20669 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20673 [(set (match_operand:DI 0 "register_operand" "")
20674 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20675 (match_operand:DI 2 "const_int_operand" "")))
20676 (clobber (reg:CC FLAGS_REG))])]
20679 && (INTVAL (operands[2]) == 3
20680 || INTVAL (operands[2]) == 5
20681 || INTVAL (operands[2]) == 9)"
20682 [(set (match_dup 0) (match_dup 1))
20684 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20686 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20688 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20689 ;; imul $32bit_imm, reg, reg is direct decoded.
20691 [(match_scratch:DI 3 "r")
20692 (parallel [(set (match_operand:DI 0 "register_operand" "")
20693 (mult:DI (match_operand:DI 1 "memory_operand" "")
20694 (match_operand:DI 2 "immediate_operand" "")))
20695 (clobber (reg:CC FLAGS_REG))])]
20696 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20697 && !satisfies_constraint_K (operands[2])"
20698 [(set (match_dup 3) (match_dup 1))
20699 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20700 (clobber (reg:CC FLAGS_REG))])]
20704 [(match_scratch:SI 3 "r")
20705 (parallel [(set (match_operand:SI 0 "register_operand" "")
20706 (mult:SI (match_operand:SI 1 "memory_operand" "")
20707 (match_operand:SI 2 "immediate_operand" "")))
20708 (clobber (reg:CC FLAGS_REG))])]
20709 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20710 && !satisfies_constraint_K (operands[2])"
20711 [(set (match_dup 3) (match_dup 1))
20712 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20713 (clobber (reg:CC FLAGS_REG))])]
20717 [(match_scratch:SI 3 "r")
20718 (parallel [(set (match_operand:DI 0 "register_operand" "")
20720 (mult:SI (match_operand:SI 1 "memory_operand" "")
20721 (match_operand:SI 2 "immediate_operand" ""))))
20722 (clobber (reg:CC FLAGS_REG))])]
20723 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20724 && !satisfies_constraint_K (operands[2])"
20725 [(set (match_dup 3) (match_dup 1))
20726 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20727 (clobber (reg:CC FLAGS_REG))])]
20730 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20731 ;; Convert it into imul reg, reg
20732 ;; It would be better to force assembler to encode instruction using long
20733 ;; immediate, but there is apparently no way to do so.
20735 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20736 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20737 (match_operand:DI 2 "const_int_operand" "")))
20738 (clobber (reg:CC FLAGS_REG))])
20739 (match_scratch:DI 3 "r")]
20740 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20741 && satisfies_constraint_K (operands[2])"
20742 [(set (match_dup 3) (match_dup 2))
20743 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20744 (clobber (reg:CC FLAGS_REG))])]
20746 if (!rtx_equal_p (operands[0], operands[1]))
20747 emit_move_insn (operands[0], operands[1]);
20751 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20752 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20753 (match_operand:SI 2 "const_int_operand" "")))
20754 (clobber (reg:CC FLAGS_REG))])
20755 (match_scratch:SI 3 "r")]
20756 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20757 && satisfies_constraint_K (operands[2])"
20758 [(set (match_dup 3) (match_dup 2))
20759 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20760 (clobber (reg:CC FLAGS_REG))])]
20762 if (!rtx_equal_p (operands[0], operands[1]))
20763 emit_move_insn (operands[0], operands[1]);
20767 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20768 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20769 (match_operand:HI 2 "immediate_operand" "")))
20770 (clobber (reg:CC FLAGS_REG))])
20771 (match_scratch:HI 3 "r")]
20772 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20773 [(set (match_dup 3) (match_dup 2))
20774 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20775 (clobber (reg:CC FLAGS_REG))])]
20777 if (!rtx_equal_p (operands[0], operands[1]))
20778 emit_move_insn (operands[0], operands[1]);
20781 ;; After splitting up read-modify operations, array accesses with memory
20782 ;; operands might end up in form:
20784 ;; movl 4(%esp), %edx
20786 ;; instead of pre-splitting:
20788 ;; addl 4(%esp), %eax
20790 ;; movl 4(%esp), %edx
20791 ;; leal (%edx,%eax,4), %eax
20794 [(parallel [(set (match_operand 0 "register_operand" "")
20795 (ashift (match_operand 1 "register_operand" "")
20796 (match_operand 2 "const_int_operand" "")))
20797 (clobber (reg:CC FLAGS_REG))])
20798 (set (match_operand 3 "register_operand")
20799 (match_operand 4 "x86_64_general_operand" ""))
20800 (parallel [(set (match_operand 5 "register_operand" "")
20801 (plus (match_operand 6 "register_operand" "")
20802 (match_operand 7 "register_operand" "")))
20803 (clobber (reg:CC FLAGS_REG))])]
20804 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20805 /* Validate MODE for lea. */
20806 && ((!TARGET_PARTIAL_REG_STALL
20807 && (GET_MODE (operands[0]) == QImode
20808 || GET_MODE (operands[0]) == HImode))
20809 || GET_MODE (operands[0]) == SImode
20810 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20811 /* We reorder load and the shift. */
20812 && !rtx_equal_p (operands[1], operands[3])
20813 && !reg_overlap_mentioned_p (operands[0], operands[4])
20814 /* Last PLUS must consist of operand 0 and 3. */
20815 && !rtx_equal_p (operands[0], operands[3])
20816 && (rtx_equal_p (operands[3], operands[6])
20817 || rtx_equal_p (operands[3], operands[7]))
20818 && (rtx_equal_p (operands[0], operands[6])
20819 || rtx_equal_p (operands[0], operands[7]))
20820 /* The intermediate operand 0 must die or be same as output. */
20821 && (rtx_equal_p (operands[0], operands[5])
20822 || peep2_reg_dead_p (3, operands[0]))"
20823 [(set (match_dup 3) (match_dup 4))
20824 (set (match_dup 0) (match_dup 1))]
20826 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20827 int scale = 1 << INTVAL (operands[2]);
20828 rtx index = gen_lowpart (Pmode, operands[1]);
20829 rtx base = gen_lowpart (Pmode, operands[3]);
20830 rtx dest = gen_lowpart (mode, operands[5]);
20832 operands[1] = gen_rtx_PLUS (Pmode, base,
20833 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20835 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20836 operands[0] = dest;
20839 ;; Call-value patterns last so that the wildcard operand does not
20840 ;; disrupt insn-recog's switch tables.
20842 (define_insn "*call_value_pop_0"
20843 [(set (match_operand 0 "" "")
20844 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20845 (match_operand:SI 2 "" "")))
20846 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20847 (match_operand:SI 3 "immediate_operand" "")))]
20850 if (SIBLING_CALL_P (insn))
20853 return "call\t%P1";
20855 [(set_attr "type" "callv")])
20857 (define_insn "*call_value_pop_1"
20858 [(set (match_operand 0 "" "")
20859 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20860 (match_operand:SI 2 "" "")))
20861 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20862 (match_operand:SI 3 "immediate_operand" "i")))]
20865 if (constant_call_address_operand (operands[1], Pmode))
20867 if (SIBLING_CALL_P (insn))
20870 return "call\t%P1";
20872 if (SIBLING_CALL_P (insn))
20875 return "call\t%A1";
20877 [(set_attr "type" "callv")])
20879 (define_insn "*call_value_0"
20880 [(set (match_operand 0 "" "")
20881 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20882 (match_operand:SI 2 "" "")))]
20885 if (SIBLING_CALL_P (insn))
20888 return "call\t%P1";
20890 [(set_attr "type" "callv")])
20892 (define_insn "*call_value_0_rex64"
20893 [(set (match_operand 0 "" "")
20894 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20895 (match_operand:DI 2 "const_int_operand" "")))]
20898 if (SIBLING_CALL_P (insn))
20901 return "call\t%P1";
20903 [(set_attr "type" "callv")])
20905 (define_insn "*call_value_1"
20906 [(set (match_operand 0 "" "")
20907 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20908 (match_operand:SI 2 "" "")))]
20909 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20911 if (constant_call_address_operand (operands[1], Pmode))
20912 return "call\t%P1";
20913 return "call\t%A1";
20915 [(set_attr "type" "callv")])
20917 (define_insn "*sibcall_value_1"
20918 [(set (match_operand 0 "" "")
20919 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20920 (match_operand:SI 2 "" "")))]
20921 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20923 if (constant_call_address_operand (operands[1], Pmode))
20927 [(set_attr "type" "callv")])
20929 (define_insn "*call_value_1_rex64"
20930 [(set (match_operand 0 "" "")
20931 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20932 (match_operand:DI 2 "" "")))]
20933 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20934 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20936 if (constant_call_address_operand (operands[1], Pmode))
20937 return "call\t%P1";
20938 return "call\t%A1";
20940 [(set_attr "type" "callv")])
20942 (define_insn "*call_value_1_rex64_large"
20943 [(set (match_operand 0 "" "")
20944 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20945 (match_operand:DI 2 "" "")))]
20946 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20948 [(set_attr "type" "callv")])
20950 (define_insn "*sibcall_value_1_rex64"
20951 [(set (match_operand 0 "" "")
20952 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20953 (match_operand:DI 2 "" "")))]
20954 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20956 [(set_attr "type" "callv")])
20958 (define_insn "*sibcall_value_1_rex64_v"
20959 [(set (match_operand 0 "" "")
20960 (call (mem:QI (reg:DI R11_REG))
20961 (match_operand:DI 1 "" "")))]
20962 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20964 [(set_attr "type" "callv")])
20966 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20967 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20968 ;; caught for use by garbage collectors and the like. Using an insn that
20969 ;; maps to SIGILL makes it more likely the program will rightfully die.
20970 ;; Keeping with tradition, "6" is in honor of #UD.
20971 (define_insn "trap"
20972 [(trap_if (const_int 1) (const_int 6))]
20974 { return ASM_SHORT "0x0b0f"; }
20975 [(set_attr "length" "2")])
20977 (define_expand "sse_prologue_save"
20978 [(parallel [(set (match_operand:BLK 0 "" "")
20979 (unspec:BLK [(reg:DI 21)
20986 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20987 (use (match_operand:DI 1 "register_operand" ""))
20988 (use (match_operand:DI 2 "immediate_operand" ""))
20989 (use (label_ref:DI (match_operand 3 "" "")))])]
20993 (define_insn "*sse_prologue_save_insn"
20994 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20995 (match_operand:DI 4 "const_int_operand" "n")))
20996 (unspec:BLK [(reg:DI 21)
21003 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21004 (use (match_operand:DI 1 "register_operand" "r"))
21005 (use (match_operand:DI 2 "const_int_operand" "i"))
21006 (use (label_ref:DI (match_operand 3 "" "X")))]
21008 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21009 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21012 operands[0] = gen_rtx_MEM (Pmode,
21013 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21014 output_asm_insn ("jmp\t%A1", operands);
21015 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21017 operands[4] = adjust_address (operands[0], DImode, i*16);
21018 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21019 PUT_MODE (operands[4], TImode);
21020 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21021 output_asm_insn ("rex", operands);
21022 output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
21024 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21025 CODE_LABEL_NUMBER (operands[3]));
21028 [(set_attr "type" "other")
21029 (set_attr "length_immediate" "0")
21030 (set_attr "length_address" "0")
21031 (set_attr "length" "135")
21032 (set_attr "memory" "store")
21033 (set_attr "modrm" "0")
21034 (set_attr "mode" "DI")])
21036 (define_expand "prefetch"
21037 [(prefetch (match_operand 0 "address_operand" "")
21038 (match_operand:SI 1 "const_int_operand" "")
21039 (match_operand:SI 2 "const_int_operand" ""))]
21040 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21042 int rw = INTVAL (operands[1]);
21043 int locality = INTVAL (operands[2]);
21045 gcc_assert (rw == 0 || rw == 1);
21046 gcc_assert (locality >= 0 && locality <= 3);
21047 gcc_assert (GET_MODE (operands[0]) == Pmode
21048 || GET_MODE (operands[0]) == VOIDmode);
21050 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21051 supported by SSE counterpart or the SSE prefetch is not available
21052 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21054 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21055 operands[2] = GEN_INT (3);
21057 operands[1] = const0_rtx;
21060 (define_insn "*prefetch_sse"
21061 [(prefetch (match_operand:SI 0 "address_operand" "p")
21063 (match_operand:SI 1 "const_int_operand" ""))]
21064 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21066 static const char * const patterns[4] = {
21067 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21070 int locality = INTVAL (operands[1]);
21071 gcc_assert (locality >= 0 && locality <= 3);
21073 return patterns[locality];
21075 [(set_attr "type" "sse")
21076 (set_attr "memory" "none")])
21078 (define_insn "*prefetch_sse_rex"
21079 [(prefetch (match_operand:DI 0 "address_operand" "p")
21081 (match_operand:SI 1 "const_int_operand" ""))]
21082 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21084 static const char * const patterns[4] = {
21085 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21088 int locality = INTVAL (operands[1]);
21089 gcc_assert (locality >= 0 && locality <= 3);
21091 return patterns[locality];
21093 [(set_attr "type" "sse")
21094 (set_attr "memory" "none")])
21096 (define_insn "*prefetch_3dnow"
21097 [(prefetch (match_operand:SI 0 "address_operand" "p")
21098 (match_operand:SI 1 "const_int_operand" "n")
21100 "TARGET_3DNOW && !TARGET_64BIT"
21102 if (INTVAL (operands[1]) == 0)
21103 return "prefetch\t%a0";
21105 return "prefetchw\t%a0";
21107 [(set_attr "type" "mmx")
21108 (set_attr "memory" "none")])
21110 (define_insn "*prefetch_3dnow_rex"
21111 [(prefetch (match_operand:DI 0 "address_operand" "p")
21112 (match_operand:SI 1 "const_int_operand" "n")
21114 "TARGET_3DNOW && TARGET_64BIT"
21116 if (INTVAL (operands[1]) == 0)
21117 return "prefetch\t%a0";
21119 return "prefetchw\t%a0";
21121 [(set_attr "type" "mmx")
21122 (set_attr "memory" "none")])
21124 (define_expand "stack_protect_set"
21125 [(match_operand 0 "memory_operand" "")
21126 (match_operand 1 "memory_operand" "")]
21129 #ifdef TARGET_THREAD_SSP_OFFSET
21131 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21132 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21134 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21135 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21138 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21140 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21145 (define_insn "stack_protect_set_si"
21146 [(set (match_operand:SI 0 "memory_operand" "=m")
21147 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21148 (set (match_scratch:SI 2 "=&r") (const_int 0))
21149 (clobber (reg:CC FLAGS_REG))]
21151 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21152 [(set_attr "type" "multi")])
21154 (define_insn "stack_protect_set_di"
21155 [(set (match_operand:DI 0 "memory_operand" "=m")
21156 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21157 (set (match_scratch:DI 2 "=&r") (const_int 0))
21158 (clobber (reg:CC FLAGS_REG))]
21160 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21161 [(set_attr "type" "multi")])
21163 (define_insn "stack_tls_protect_set_si"
21164 [(set (match_operand:SI 0 "memory_operand" "=m")
21165 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21166 (set (match_scratch:SI 2 "=&r") (const_int 0))
21167 (clobber (reg:CC FLAGS_REG))]
21169 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21170 [(set_attr "type" "multi")])
21172 (define_insn "stack_tls_protect_set_di"
21173 [(set (match_operand:DI 0 "memory_operand" "=m")
21174 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21175 (set (match_scratch:DI 2 "=&r") (const_int 0))
21176 (clobber (reg:CC FLAGS_REG))]
21179 /* The kernel uses a different segment register for performance reasons; a
21180 system call would not have to trash the userspace segment register,
21181 which would be expensive */
21182 if (ix86_cmodel != CM_KERNEL)
21183 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21185 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21187 [(set_attr "type" "multi")])
21189 (define_expand "stack_protect_test"
21190 [(match_operand 0 "memory_operand" "")
21191 (match_operand 1 "memory_operand" "")
21192 (match_operand 2 "" "")]
21195 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21196 ix86_compare_op0 = operands[0];
21197 ix86_compare_op1 = operands[1];
21198 ix86_compare_emitted = flags;
21200 #ifdef TARGET_THREAD_SSP_OFFSET
21202 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21203 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21205 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21206 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21209 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21211 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21213 emit_jump_insn (gen_beq (operands[2]));
21217 (define_insn "stack_protect_test_si"
21218 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21219 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21220 (match_operand:SI 2 "memory_operand" "m")]
21222 (clobber (match_scratch:SI 3 "=&r"))]
21224 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21225 [(set_attr "type" "multi")])
21227 (define_insn "stack_protect_test_di"
21228 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21229 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21230 (match_operand:DI 2 "memory_operand" "m")]
21232 (clobber (match_scratch:DI 3 "=&r"))]
21234 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21235 [(set_attr "type" "multi")])
21237 (define_insn "stack_tls_protect_test_si"
21238 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21239 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21240 (match_operand:SI 2 "const_int_operand" "i")]
21241 UNSPEC_SP_TLS_TEST))
21242 (clobber (match_scratch:SI 3 "=r"))]
21244 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21245 [(set_attr "type" "multi")])
21247 (define_insn "stack_tls_protect_test_di"
21248 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21249 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21250 (match_operand:DI 2 "const_int_operand" "i")]
21251 UNSPEC_SP_TLS_TEST))
21252 (clobber (match_scratch:DI 3 "=r"))]
21255 /* The kernel uses a different segment register for performance reasons; a
21256 system call would not have to trash the userspace segment register,
21257 which would be expensive */
21258 if (ix86_cmodel != CM_KERNEL)
21259 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21261 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21263 [(set_attr "type" "multi")])
21265 (define_mode_iterator CRC32MODE [QI HI SI])
21266 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21267 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21269 (define_insn "sse4_2_crc32<mode>"
21270 [(set (match_operand:SI 0 "register_operand" "=r")
21272 [(match_operand:SI 1 "register_operand" "0")
21273 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21276 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21277 [(set_attr "type" "sselog1")
21278 (set_attr "prefix_rep" "1")
21279 (set_attr "prefix_extra" "1")
21280 (set_attr "mode" "SI")])
21282 (define_insn "sse4_2_crc32di"
21283 [(set (match_operand:DI 0 "register_operand" "=r")
21285 [(match_operand:DI 1 "register_operand" "0")
21286 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21288 "TARGET_SSE4_2 && TARGET_64BIT"
21289 "crc32q\t{%2, %0|%0, %2}"
21290 [(set_attr "type" "sselog1")
21291 (set_attr "prefix_rep" "1")
21292 (set_attr "prefix_extra" "1")
21293 (set_attr "mode" "DI")])
21297 (include "sync.md")