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") (umax "maxu") (umin "minu")])
552 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
554 ;; Mapping of parallel logic operators
555 (define_code_iterator plogic [and ior xor])
557 ;; Base name for insn mnemonic.
558 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
560 ;; All single word integer modes.
561 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
563 ;; Instruction suffix for integer modes.
564 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
566 ;; Register class for integer modes.
567 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
569 ;; Immediate operand constraint for integer modes.
570 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
572 ;; General operand predicate for integer modes.
573 (define_mode_attr general_operand
574 [(QI "general_operand")
575 (HI "general_operand")
576 (SI "general_operand")
577 (DI "x86_64_general_operand")])
579 ;; SSE and x87 SFmode and DFmode floating point modes
580 (define_mode_iterator MODEF [SF DF])
582 ;; All x87 floating point modes
583 (define_mode_iterator X87MODEF [SF DF XF])
585 ;; All integer modes handled by x87 fisttp operator.
586 (define_mode_iterator X87MODEI [HI SI DI])
588 ;; All integer modes handled by integer x87 operators.
589 (define_mode_iterator X87MODEI12 [HI SI])
591 ;; All integer modes handled by SSE cvtts?2si* operators.
592 (define_mode_iterator SSEMODEI24 [SI DI])
594 ;; SSE asm suffix for floating point modes
595 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
597 ;; SSE vector mode corresponding to a scalar mode
598 (define_mode_attr ssevecmode
599 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
601 ;; Instruction suffix for REX 64bit operators.
602 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
604 ;; Scheduling descriptions
606 (include "pentium.md")
609 (include "athlon.md")
613 ;; Operand and operator predicates and constraints
615 (include "predicates.md")
616 (include "constraints.md")
619 ;; Compare instructions.
621 ;; All compare insns have expanders that save the operands away without
622 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
623 ;; after the cmp) will actually emit the cmpM.
625 (define_expand "cmpti"
626 [(set (reg:CC FLAGS_REG)
627 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
628 (match_operand:TI 1 "x86_64_general_operand" "")))]
631 if (MEM_P (operands[0]) && MEM_P (operands[1]))
632 operands[0] = force_reg (TImode, operands[0]);
633 ix86_compare_op0 = operands[0];
634 ix86_compare_op1 = operands[1];
638 (define_expand "cmpdi"
639 [(set (reg:CC FLAGS_REG)
640 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
641 (match_operand:DI 1 "x86_64_general_operand" "")))]
644 if (MEM_P (operands[0]) && MEM_P (operands[1]))
645 operands[0] = force_reg (DImode, operands[0]);
646 ix86_compare_op0 = operands[0];
647 ix86_compare_op1 = operands[1];
651 (define_expand "cmpsi"
652 [(set (reg:CC FLAGS_REG)
653 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
654 (match_operand:SI 1 "general_operand" "")))]
657 if (MEM_P (operands[0]) && MEM_P (operands[1]))
658 operands[0] = force_reg (SImode, operands[0]);
659 ix86_compare_op0 = operands[0];
660 ix86_compare_op1 = operands[1];
664 (define_expand "cmphi"
665 [(set (reg:CC FLAGS_REG)
666 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
667 (match_operand:HI 1 "general_operand" "")))]
670 if (MEM_P (operands[0]) && MEM_P (operands[1]))
671 operands[0] = force_reg (HImode, operands[0]);
672 ix86_compare_op0 = operands[0];
673 ix86_compare_op1 = operands[1];
677 (define_expand "cmpqi"
678 [(set (reg:CC FLAGS_REG)
679 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
680 (match_operand:QI 1 "general_operand" "")))]
683 if (MEM_P (operands[0]) && MEM_P (operands[1]))
684 operands[0] = force_reg (QImode, operands[0]);
685 ix86_compare_op0 = operands[0];
686 ix86_compare_op1 = operands[1];
690 (define_insn "cmpdi_ccno_1_rex64"
691 [(set (reg FLAGS_REG)
692 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
693 (match_operand:DI 1 "const0_operand" "n,n")))]
694 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
697 cmp{q}\t{%1, %0|%0, %1}"
698 [(set_attr "type" "test,icmp")
699 (set_attr "length_immediate" "0,1")
700 (set_attr "mode" "DI")])
702 (define_insn "*cmpdi_minus_1_rex64"
703 [(set (reg FLAGS_REG)
704 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
705 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
707 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
708 "cmp{q}\t{%1, %0|%0, %1}"
709 [(set_attr "type" "icmp")
710 (set_attr "mode" "DI")])
712 (define_expand "cmpdi_1_rex64"
713 [(set (reg:CC FLAGS_REG)
714 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
715 (match_operand:DI 1 "general_operand" "")))]
719 (define_insn "cmpdi_1_insn_rex64"
720 [(set (reg FLAGS_REG)
721 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
722 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
723 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
724 "cmp{q}\t{%1, %0|%0, %1}"
725 [(set_attr "type" "icmp")
726 (set_attr "mode" "DI")])
729 (define_insn "*cmpsi_ccno_1"
730 [(set (reg FLAGS_REG)
731 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
732 (match_operand:SI 1 "const0_operand" "n,n")))]
733 "ix86_match_ccmode (insn, CCNOmode)"
736 cmp{l}\t{%1, %0|%0, %1}"
737 [(set_attr "type" "test,icmp")
738 (set_attr "length_immediate" "0,1")
739 (set_attr "mode" "SI")])
741 (define_insn "*cmpsi_minus_1"
742 [(set (reg FLAGS_REG)
743 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
744 (match_operand:SI 1 "general_operand" "ri,mr"))
746 "ix86_match_ccmode (insn, CCGOCmode)"
747 "cmp{l}\t{%1, %0|%0, %1}"
748 [(set_attr "type" "icmp")
749 (set_attr "mode" "SI")])
751 (define_expand "cmpsi_1"
752 [(set (reg:CC FLAGS_REG)
753 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
754 (match_operand:SI 1 "general_operand" "")))]
758 (define_insn "*cmpsi_1_insn"
759 [(set (reg FLAGS_REG)
760 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
761 (match_operand:SI 1 "general_operand" "ri,mr")))]
762 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
763 && ix86_match_ccmode (insn, CCmode)"
764 "cmp{l}\t{%1, %0|%0, %1}"
765 [(set_attr "type" "icmp")
766 (set_attr "mode" "SI")])
768 (define_insn "*cmphi_ccno_1"
769 [(set (reg FLAGS_REG)
770 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
771 (match_operand:HI 1 "const0_operand" "n,n")))]
772 "ix86_match_ccmode (insn, CCNOmode)"
775 cmp{w}\t{%1, %0|%0, %1}"
776 [(set_attr "type" "test,icmp")
777 (set_attr "length_immediate" "0,1")
778 (set_attr "mode" "HI")])
780 (define_insn "*cmphi_minus_1"
781 [(set (reg FLAGS_REG)
782 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
783 (match_operand:HI 1 "general_operand" "ri,mr"))
785 "ix86_match_ccmode (insn, CCGOCmode)"
786 "cmp{w}\t{%1, %0|%0, %1}"
787 [(set_attr "type" "icmp")
788 (set_attr "mode" "HI")])
790 (define_insn "*cmphi_1"
791 [(set (reg FLAGS_REG)
792 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
793 (match_operand:HI 1 "general_operand" "ri,mr")))]
794 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
795 && ix86_match_ccmode (insn, CCmode)"
796 "cmp{w}\t{%1, %0|%0, %1}"
797 [(set_attr "type" "icmp")
798 (set_attr "mode" "HI")])
800 (define_insn "*cmpqi_ccno_1"
801 [(set (reg FLAGS_REG)
802 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
803 (match_operand:QI 1 "const0_operand" "n,n")))]
804 "ix86_match_ccmode (insn, CCNOmode)"
807 cmp{b}\t{$0, %0|%0, 0}"
808 [(set_attr "type" "test,icmp")
809 (set_attr "length_immediate" "0,1")
810 (set_attr "mode" "QI")])
812 (define_insn "*cmpqi_1"
813 [(set (reg FLAGS_REG)
814 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
815 (match_operand:QI 1 "general_operand" "qi,mq")))]
816 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
817 && ix86_match_ccmode (insn, CCmode)"
818 "cmp{b}\t{%1, %0|%0, %1}"
819 [(set_attr "type" "icmp")
820 (set_attr "mode" "QI")])
822 (define_insn "*cmpqi_minus_1"
823 [(set (reg FLAGS_REG)
824 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
825 (match_operand:QI 1 "general_operand" "qi,mq"))
827 "ix86_match_ccmode (insn, CCGOCmode)"
828 "cmp{b}\t{%1, %0|%0, %1}"
829 [(set_attr "type" "icmp")
830 (set_attr "mode" "QI")])
832 (define_insn "*cmpqi_ext_1"
833 [(set (reg FLAGS_REG)
835 (match_operand:QI 0 "general_operand" "Qm")
838 (match_operand 1 "ext_register_operand" "Q")
841 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
842 "cmp{b}\t{%h1, %0|%0, %h1}"
843 [(set_attr "type" "icmp")
844 (set_attr "mode" "QI")])
846 (define_insn "*cmpqi_ext_1_rex64"
847 [(set (reg FLAGS_REG)
849 (match_operand:QI 0 "register_operand" "Q")
852 (match_operand 1 "ext_register_operand" "Q")
855 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
856 "cmp{b}\t{%h1, %0|%0, %h1}"
857 [(set_attr "type" "icmp")
858 (set_attr "mode" "QI")])
860 (define_insn "*cmpqi_ext_2"
861 [(set (reg FLAGS_REG)
865 (match_operand 0 "ext_register_operand" "Q")
868 (match_operand:QI 1 "const0_operand" "n")))]
869 "ix86_match_ccmode (insn, CCNOmode)"
871 [(set_attr "type" "test")
872 (set_attr "length_immediate" "0")
873 (set_attr "mode" "QI")])
875 (define_expand "cmpqi_ext_3"
876 [(set (reg:CC FLAGS_REG)
880 (match_operand 0 "ext_register_operand" "")
883 (match_operand:QI 1 "general_operand" "")))]
887 (define_insn "cmpqi_ext_3_insn"
888 [(set (reg FLAGS_REG)
892 (match_operand 0 "ext_register_operand" "Q")
895 (match_operand:QI 1 "general_operand" "Qmn")))]
896 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
897 "cmp{b}\t{%1, %h0|%h0, %1}"
898 [(set_attr "type" "icmp")
899 (set_attr "mode" "QI")])
901 (define_insn "cmpqi_ext_3_insn_rex64"
902 [(set (reg FLAGS_REG)
906 (match_operand 0 "ext_register_operand" "Q")
909 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
910 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
911 "cmp{b}\t{%1, %h0|%h0, %1}"
912 [(set_attr "type" "icmp")
913 (set_attr "mode" "QI")])
915 (define_insn "*cmpqi_ext_4"
916 [(set (reg FLAGS_REG)
920 (match_operand 0 "ext_register_operand" "Q")
925 (match_operand 1 "ext_register_operand" "Q")
928 "ix86_match_ccmode (insn, CCmode)"
929 "cmp{b}\t{%h1, %h0|%h0, %h1}"
930 [(set_attr "type" "icmp")
931 (set_attr "mode" "QI")])
933 ;; These implement float point compares.
934 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
935 ;; which would allow mix and match FP modes on the compares. Which is what
936 ;; the old patterns did, but with many more of them.
938 (define_expand "cmpxf"
939 [(set (reg:CC FLAGS_REG)
940 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
941 (match_operand:XF 1 "nonmemory_operand" "")))]
944 ix86_compare_op0 = operands[0];
945 ix86_compare_op1 = operands[1];
949 (define_expand "cmp<mode>"
950 [(set (reg:CC FLAGS_REG)
951 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
952 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
953 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
955 ix86_compare_op0 = operands[0];
956 ix86_compare_op1 = operands[1];
960 ;; FP compares, step 1:
961 ;; Set the FP condition codes.
963 ;; CCFPmode compare with exceptions
964 ;; CCFPUmode compare with no exceptions
966 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
967 ;; used to manage the reg stack popping would not be preserved.
969 (define_insn "*cmpfp_0"
970 [(set (match_operand:HI 0 "register_operand" "=a")
973 (match_operand 1 "register_operand" "f")
974 (match_operand 2 "const0_operand" "X"))]
976 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
977 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
978 "* return output_fp_compare (insn, operands, 0, 0);"
979 [(set_attr "type" "multi")
980 (set_attr "unit" "i387")
982 (cond [(match_operand:SF 1 "" "")
984 (match_operand:DF 1 "" "")
987 (const_string "XF")))])
989 (define_insn_and_split "*cmpfp_0_cc"
990 [(set (reg:CCFP FLAGS_REG)
992 (match_operand 1 "register_operand" "f")
993 (match_operand 2 "const0_operand" "X")))
994 (clobber (match_operand:HI 0 "register_operand" "=a"))]
995 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
996 && TARGET_SAHF && !TARGET_CMOVE
997 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
999 "&& reload_completed"
1002 [(compare:CCFP (match_dup 1)(match_dup 2))]
1004 (set (reg:CC FLAGS_REG)
1005 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1007 [(set_attr "type" "multi")
1008 (set_attr "unit" "i387")
1010 (cond [(match_operand:SF 1 "" "")
1012 (match_operand:DF 1 "" "")
1015 (const_string "XF")))])
1017 (define_insn "*cmpfp_xf"
1018 [(set (match_operand:HI 0 "register_operand" "=a")
1021 (match_operand:XF 1 "register_operand" "f")
1022 (match_operand:XF 2 "register_operand" "f"))]
1025 "* return output_fp_compare (insn, operands, 0, 0);"
1026 [(set_attr "type" "multi")
1027 (set_attr "unit" "i387")
1028 (set_attr "mode" "XF")])
1030 (define_insn_and_split "*cmpfp_xf_cc"
1031 [(set (reg:CCFP FLAGS_REG)
1033 (match_operand:XF 1 "register_operand" "f")
1034 (match_operand:XF 2 "register_operand" "f")))
1035 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1037 && TARGET_SAHF && !TARGET_CMOVE"
1039 "&& reload_completed"
1042 [(compare:CCFP (match_dup 1)(match_dup 2))]
1044 (set (reg:CC FLAGS_REG)
1045 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1047 [(set_attr "type" "multi")
1048 (set_attr "unit" "i387")
1049 (set_attr "mode" "XF")])
1051 (define_insn "*cmpfp_<mode>"
1052 [(set (match_operand:HI 0 "register_operand" "=a")
1055 (match_operand:MODEF 1 "register_operand" "f")
1056 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1059 "* return output_fp_compare (insn, operands, 0, 0);"
1060 [(set_attr "type" "multi")
1061 (set_attr "unit" "i387")
1062 (set_attr "mode" "<MODE>")])
1064 (define_insn_and_split "*cmpfp_<mode>_cc"
1065 [(set (reg:CCFP FLAGS_REG)
1067 (match_operand:MODEF 1 "register_operand" "f")
1068 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1069 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1071 && TARGET_SAHF && !TARGET_CMOVE"
1073 "&& reload_completed"
1076 [(compare:CCFP (match_dup 1)(match_dup 2))]
1078 (set (reg:CC FLAGS_REG)
1079 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1081 [(set_attr "type" "multi")
1082 (set_attr "unit" "i387")
1083 (set_attr "mode" "<MODE>")])
1085 (define_insn "*cmpfp_u"
1086 [(set (match_operand:HI 0 "register_operand" "=a")
1089 (match_operand 1 "register_operand" "f")
1090 (match_operand 2 "register_operand" "f"))]
1092 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1093 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1094 "* return output_fp_compare (insn, operands, 0, 1);"
1095 [(set_attr "type" "multi")
1096 (set_attr "unit" "i387")
1098 (cond [(match_operand:SF 1 "" "")
1100 (match_operand:DF 1 "" "")
1103 (const_string "XF")))])
1105 (define_insn_and_split "*cmpfp_u_cc"
1106 [(set (reg:CCFPU FLAGS_REG)
1108 (match_operand 1 "register_operand" "f")
1109 (match_operand 2 "register_operand" "f")))
1110 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1111 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1112 && TARGET_SAHF && !TARGET_CMOVE
1113 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1115 "&& reload_completed"
1118 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1120 (set (reg:CC FLAGS_REG)
1121 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1123 [(set_attr "type" "multi")
1124 (set_attr "unit" "i387")
1126 (cond [(match_operand:SF 1 "" "")
1128 (match_operand:DF 1 "" "")
1131 (const_string "XF")))])
1133 (define_insn "*cmpfp_<mode>"
1134 [(set (match_operand:HI 0 "register_operand" "=a")
1137 (match_operand 1 "register_operand" "f")
1138 (match_operator 3 "float_operator"
1139 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1141 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1142 && TARGET_USE_<MODE>MODE_FIOP
1143 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1144 "* return output_fp_compare (insn, operands, 0, 0);"
1145 [(set_attr "type" "multi")
1146 (set_attr "unit" "i387")
1147 (set_attr "fp_int_src" "true")
1148 (set_attr "mode" "<MODE>")])
1150 (define_insn_and_split "*cmpfp_<mode>_cc"
1151 [(set (reg:CCFP FLAGS_REG)
1153 (match_operand 1 "register_operand" "f")
1154 (match_operator 3 "float_operator"
1155 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1156 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1157 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1158 && TARGET_SAHF && !TARGET_CMOVE
1159 && TARGET_USE_<MODE>MODE_FIOP
1160 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1162 "&& reload_completed"
1167 (match_op_dup 3 [(match_dup 2)]))]
1169 (set (reg:CC FLAGS_REG)
1170 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1172 [(set_attr "type" "multi")
1173 (set_attr "unit" "i387")
1174 (set_attr "fp_int_src" "true")
1175 (set_attr "mode" "<MODE>")])
1177 ;; FP compares, step 2
1178 ;; Move the fpsw to ax.
1180 (define_insn "x86_fnstsw_1"
1181 [(set (match_operand:HI 0 "register_operand" "=a")
1182 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1185 [(set_attr "length" "2")
1186 (set_attr "mode" "SI")
1187 (set_attr "unit" "i387")])
1189 ;; FP compares, step 3
1190 ;; Get ax into flags, general case.
1192 (define_insn "x86_sahf_1"
1193 [(set (reg:CC FLAGS_REG)
1194 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1198 #ifdef HAVE_AS_IX86_SAHF
1201 return ".byte\t0x9e";
1204 [(set_attr "length" "1")
1205 (set_attr "athlon_decode" "vector")
1206 (set_attr "amdfam10_decode" "direct")
1207 (set_attr "mode" "SI")])
1209 ;; Pentium Pro can do steps 1 through 3 in one go.
1210 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1211 (define_insn "*cmpfp_i_mixed"
1212 [(set (reg:CCFP FLAGS_REG)
1213 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1214 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1215 "TARGET_MIX_SSE_I387
1216 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1217 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1218 "* return output_fp_compare (insn, operands, 1, 0);"
1219 [(set_attr "type" "fcmp,ssecomi")
1221 (if_then_else (match_operand:SF 1 "" "")
1223 (const_string "DF")))
1224 (set_attr "athlon_decode" "vector")
1225 (set_attr "amdfam10_decode" "direct")])
1227 (define_insn "*cmpfp_i_sse"
1228 [(set (reg:CCFP FLAGS_REG)
1229 (compare:CCFP (match_operand 0 "register_operand" "x")
1230 (match_operand 1 "nonimmediate_operand" "xm")))]
1232 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1233 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1234 "* return output_fp_compare (insn, operands, 1, 0);"
1235 [(set_attr "type" "ssecomi")
1237 (if_then_else (match_operand:SF 1 "" "")
1239 (const_string "DF")))
1240 (set_attr "athlon_decode" "vector")
1241 (set_attr "amdfam10_decode" "direct")])
1243 (define_insn "*cmpfp_i_i387"
1244 [(set (reg:CCFP FLAGS_REG)
1245 (compare:CCFP (match_operand 0 "register_operand" "f")
1246 (match_operand 1 "register_operand" "f")))]
1247 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1249 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1250 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1251 "* return output_fp_compare (insn, operands, 1, 0);"
1252 [(set_attr "type" "fcmp")
1254 (cond [(match_operand:SF 1 "" "")
1256 (match_operand:DF 1 "" "")
1259 (const_string "XF")))
1260 (set_attr "athlon_decode" "vector")
1261 (set_attr "amdfam10_decode" "direct")])
1263 (define_insn "*cmpfp_iu_mixed"
1264 [(set (reg:CCFPU FLAGS_REG)
1265 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1266 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1267 "TARGET_MIX_SSE_I387
1268 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1269 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1270 "* return output_fp_compare (insn, operands, 1, 1);"
1271 [(set_attr "type" "fcmp,ssecomi")
1273 (if_then_else (match_operand:SF 1 "" "")
1275 (const_string "DF")))
1276 (set_attr "athlon_decode" "vector")
1277 (set_attr "amdfam10_decode" "direct")])
1279 (define_insn "*cmpfp_iu_sse"
1280 [(set (reg:CCFPU FLAGS_REG)
1281 (compare:CCFPU (match_operand 0 "register_operand" "x")
1282 (match_operand 1 "nonimmediate_operand" "xm")))]
1284 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1285 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1286 "* return output_fp_compare (insn, operands, 1, 1);"
1287 [(set_attr "type" "ssecomi")
1289 (if_then_else (match_operand:SF 1 "" "")
1291 (const_string "DF")))
1292 (set_attr "athlon_decode" "vector")
1293 (set_attr "amdfam10_decode" "direct")])
1295 (define_insn "*cmpfp_iu_387"
1296 [(set (reg:CCFPU FLAGS_REG)
1297 (compare:CCFPU (match_operand 0 "register_operand" "f")
1298 (match_operand 1 "register_operand" "f")))]
1299 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1301 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1302 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1303 "* return output_fp_compare (insn, operands, 1, 1);"
1304 [(set_attr "type" "fcmp")
1306 (cond [(match_operand:SF 1 "" "")
1308 (match_operand:DF 1 "" "")
1311 (const_string "XF")))
1312 (set_attr "athlon_decode" "vector")
1313 (set_attr "amdfam10_decode" "direct")])
1315 ;; Move instructions.
1317 ;; General case of fullword move.
1319 (define_expand "movsi"
1320 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1321 (match_operand:SI 1 "general_operand" ""))]
1323 "ix86_expand_move (SImode, operands); DONE;")
1325 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1328 ;; %%% We don't use a post-inc memory reference because x86 is not a
1329 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1330 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1331 ;; targets without our curiosities, and it is just as easy to represent
1332 ;; this differently.
1334 (define_insn "*pushsi2"
1335 [(set (match_operand:SI 0 "push_operand" "=<")
1336 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1339 [(set_attr "type" "push")
1340 (set_attr "mode" "SI")])
1342 ;; For 64BIT abi we always round up to 8 bytes.
1343 (define_insn "*pushsi2_rex64"
1344 [(set (match_operand:SI 0 "push_operand" "=X")
1345 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1348 [(set_attr "type" "push")
1349 (set_attr "mode" "SI")])
1351 (define_insn "*pushsi2_prologue"
1352 [(set (match_operand:SI 0 "push_operand" "=<")
1353 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1354 (clobber (mem:BLK (scratch)))]
1357 [(set_attr "type" "push")
1358 (set_attr "mode" "SI")])
1360 (define_insn "*popsi1_epilogue"
1361 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1362 (mem:SI (reg:SI SP_REG)))
1363 (set (reg:SI SP_REG)
1364 (plus:SI (reg:SI SP_REG) (const_int 4)))
1365 (clobber (mem:BLK (scratch)))]
1368 [(set_attr "type" "pop")
1369 (set_attr "mode" "SI")])
1371 (define_insn "popsi1"
1372 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1373 (mem:SI (reg:SI SP_REG)))
1374 (set (reg:SI SP_REG)
1375 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1378 [(set_attr "type" "pop")
1379 (set_attr "mode" "SI")])
1381 (define_insn "*movsi_xor"
1382 [(set (match_operand:SI 0 "register_operand" "=r")
1383 (match_operand:SI 1 "const0_operand" "i"))
1384 (clobber (reg:CC FLAGS_REG))]
1385 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1387 [(set_attr "type" "alu1")
1388 (set_attr "mode" "SI")
1389 (set_attr "length_immediate" "0")])
1391 (define_insn "*movsi_or"
1392 [(set (match_operand:SI 0 "register_operand" "=r")
1393 (match_operand:SI 1 "immediate_operand" "i"))
1394 (clobber (reg:CC FLAGS_REG))]
1396 && operands[1] == constm1_rtx
1397 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1399 operands[1] = constm1_rtx;
1400 return "or{l}\t{%1, %0|%0, %1}";
1402 [(set_attr "type" "alu1")
1403 (set_attr "mode" "SI")
1404 (set_attr "length_immediate" "1")])
1406 (define_insn "*movsi_1"
1407 [(set (match_operand:SI 0 "nonimmediate_operand"
1408 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1409 (match_operand:SI 1 "general_operand"
1410 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1411 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1413 switch (get_attr_type (insn))
1416 if (get_attr_mode (insn) == MODE_TI)
1417 return "pxor\t%0, %0";
1418 return "xorps\t%0, %0";
1421 switch (get_attr_mode (insn))
1424 return "movdqa\t{%1, %0|%0, %1}";
1426 return "movaps\t{%1, %0|%0, %1}";
1428 return "movd\t{%1, %0|%0, %1}";
1430 return "movss\t{%1, %0|%0, %1}";
1436 return "pxor\t%0, %0";
1439 if (get_attr_mode (insn) == MODE_DI)
1440 return "movq\t{%1, %0|%0, %1}";
1441 return "movd\t{%1, %0|%0, %1}";
1444 return "lea{l}\t{%1, %0|%0, %1}";
1447 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1448 return "mov{l}\t{%1, %0|%0, %1}";
1452 (cond [(eq_attr "alternative" "2")
1453 (const_string "mmxadd")
1454 (eq_attr "alternative" "3,4,5")
1455 (const_string "mmxmov")
1456 (eq_attr "alternative" "6")
1457 (const_string "sselog1")
1458 (eq_attr "alternative" "7,8,9,10,11")
1459 (const_string "ssemov")
1460 (match_operand:DI 1 "pic_32bit_operand" "")
1461 (const_string "lea")
1463 (const_string "imov")))
1465 (cond [(eq_attr "alternative" "2,3")
1467 (eq_attr "alternative" "6,7")
1469 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1470 (const_string "V4SF")
1471 (const_string "TI"))
1472 (and (eq_attr "alternative" "8,9,10,11")
1473 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1476 (const_string "SI")))])
1478 ;; Stores and loads of ax to arbitrary constant address.
1479 ;; We fake an second form of instruction to force reload to load address
1480 ;; into register when rax is not available
1481 (define_insn "*movabssi_1_rex64"
1482 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1483 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1484 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1486 movabs{l}\t{%1, %P0|%P0, %1}
1487 mov{l}\t{%1, %a0|%a0, %1}"
1488 [(set_attr "type" "imov")
1489 (set_attr "modrm" "0,*")
1490 (set_attr "length_address" "8,0")
1491 (set_attr "length_immediate" "0,*")
1492 (set_attr "memory" "store")
1493 (set_attr "mode" "SI")])
1495 (define_insn "*movabssi_2_rex64"
1496 [(set (match_operand:SI 0 "register_operand" "=a,r")
1497 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1498 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1500 movabs{l}\t{%P1, %0|%0, %P1}
1501 mov{l}\t{%a1, %0|%0, %a1}"
1502 [(set_attr "type" "imov")
1503 (set_attr "modrm" "0,*")
1504 (set_attr "length_address" "8,0")
1505 (set_attr "length_immediate" "0")
1506 (set_attr "memory" "load")
1507 (set_attr "mode" "SI")])
1509 (define_insn "*swapsi"
1510 [(set (match_operand:SI 0 "register_operand" "+r")
1511 (match_operand:SI 1 "register_operand" "+r"))
1516 [(set_attr "type" "imov")
1517 (set_attr "mode" "SI")
1518 (set_attr "pent_pair" "np")
1519 (set_attr "athlon_decode" "vector")
1520 (set_attr "amdfam10_decode" "double")])
1522 (define_expand "movhi"
1523 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1524 (match_operand:HI 1 "general_operand" ""))]
1526 "ix86_expand_move (HImode, operands); DONE;")
1528 (define_insn "*pushhi2"
1529 [(set (match_operand:HI 0 "push_operand" "=X")
1530 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1533 [(set_attr "type" "push")
1534 (set_attr "mode" "SI")])
1536 ;; For 64BIT abi we always round up to 8 bytes.
1537 (define_insn "*pushhi2_rex64"
1538 [(set (match_operand:HI 0 "push_operand" "=X")
1539 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1542 [(set_attr "type" "push")
1543 (set_attr "mode" "DI")])
1545 (define_insn "*movhi_1"
1546 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1547 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1548 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1550 switch (get_attr_type (insn))
1553 /* movzwl is faster than movw on p2 due to partial word stalls,
1554 though not as fast as an aligned movl. */
1555 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1557 if (get_attr_mode (insn) == MODE_SI)
1558 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1560 return "mov{w}\t{%1, %0|%0, %1}";
1564 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1565 (const_string "imov")
1566 (and (eq_attr "alternative" "0")
1567 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1569 (eq (symbol_ref "TARGET_HIMODE_MATH")
1571 (const_string "imov")
1572 (and (eq_attr "alternative" "1,2")
1573 (match_operand:HI 1 "aligned_operand" ""))
1574 (const_string "imov")
1575 (and (ne (symbol_ref "TARGET_MOVX")
1577 (eq_attr "alternative" "0,2"))
1578 (const_string "imovx")
1580 (const_string "imov")))
1582 (cond [(eq_attr "type" "imovx")
1584 (and (eq_attr "alternative" "1,2")
1585 (match_operand:HI 1 "aligned_operand" ""))
1587 (and (eq_attr "alternative" "0")
1588 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1590 (eq (symbol_ref "TARGET_HIMODE_MATH")
1594 (const_string "HI")))])
1596 ;; Stores and loads of ax to arbitrary constant address.
1597 ;; We fake an second form of instruction to force reload to load address
1598 ;; into register when rax is not available
1599 (define_insn "*movabshi_1_rex64"
1600 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1601 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1602 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1604 movabs{w}\t{%1, %P0|%P0, %1}
1605 mov{w}\t{%1, %a0|%a0, %1}"
1606 [(set_attr "type" "imov")
1607 (set_attr "modrm" "0,*")
1608 (set_attr "length_address" "8,0")
1609 (set_attr "length_immediate" "0,*")
1610 (set_attr "memory" "store")
1611 (set_attr "mode" "HI")])
1613 (define_insn "*movabshi_2_rex64"
1614 [(set (match_operand:HI 0 "register_operand" "=a,r")
1615 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1616 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1618 movabs{w}\t{%P1, %0|%0, %P1}
1619 mov{w}\t{%a1, %0|%0, %a1}"
1620 [(set_attr "type" "imov")
1621 (set_attr "modrm" "0,*")
1622 (set_attr "length_address" "8,0")
1623 (set_attr "length_immediate" "0")
1624 (set_attr "memory" "load")
1625 (set_attr "mode" "HI")])
1627 (define_insn "*swaphi_1"
1628 [(set (match_operand:HI 0 "register_operand" "+r")
1629 (match_operand:HI 1 "register_operand" "+r"))
1632 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1634 [(set_attr "type" "imov")
1635 (set_attr "mode" "SI")
1636 (set_attr "pent_pair" "np")
1637 (set_attr "athlon_decode" "vector")
1638 (set_attr "amdfam10_decode" "double")])
1640 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1641 (define_insn "*swaphi_2"
1642 [(set (match_operand:HI 0 "register_operand" "+r")
1643 (match_operand:HI 1 "register_operand" "+r"))
1646 "TARGET_PARTIAL_REG_STALL"
1648 [(set_attr "type" "imov")
1649 (set_attr "mode" "HI")
1650 (set_attr "pent_pair" "np")
1651 (set_attr "athlon_decode" "vector")])
1653 (define_expand "movstricthi"
1654 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1655 (match_operand:HI 1 "general_operand" ""))]
1656 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1658 /* Don't generate memory->memory moves, go through a register */
1659 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1660 operands[1] = force_reg (HImode, operands[1]);
1663 (define_insn "*movstricthi_1"
1664 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1665 (match_operand:HI 1 "general_operand" "rn,m"))]
1666 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1667 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1668 "mov{w}\t{%1, %0|%0, %1}"
1669 [(set_attr "type" "imov")
1670 (set_attr "mode" "HI")])
1672 (define_insn "*movstricthi_xor"
1673 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1674 (match_operand:HI 1 "const0_operand" "i"))
1675 (clobber (reg:CC FLAGS_REG))]
1677 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1679 [(set_attr "type" "alu1")
1680 (set_attr "mode" "HI")
1681 (set_attr "length_immediate" "0")])
1683 (define_expand "movqi"
1684 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1685 (match_operand:QI 1 "general_operand" ""))]
1687 "ix86_expand_move (QImode, operands); DONE;")
1689 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1690 ;; "push a byte". But actually we use pushl, which has the effect
1691 ;; of rounding the amount pushed up to a word.
1693 (define_insn "*pushqi2"
1694 [(set (match_operand:QI 0 "push_operand" "=X")
1695 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1698 [(set_attr "type" "push")
1699 (set_attr "mode" "SI")])
1701 ;; For 64BIT abi we always round up to 8 bytes.
1702 (define_insn "*pushqi2_rex64"
1703 [(set (match_operand:QI 0 "push_operand" "=X")
1704 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1707 [(set_attr "type" "push")
1708 (set_attr "mode" "DI")])
1710 ;; Situation is quite tricky about when to choose full sized (SImode) move
1711 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1712 ;; partial register dependency machines (such as AMD Athlon), where QImode
1713 ;; moves issue extra dependency and for partial register stalls machines
1714 ;; that don't use QImode patterns (and QImode move cause stall on the next
1717 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1718 ;; register stall machines with, where we use QImode instructions, since
1719 ;; partial register stall can be caused there. Then we use movzx.
1720 (define_insn "*movqi_1"
1721 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1722 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1723 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1725 switch (get_attr_type (insn))
1728 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1729 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1731 if (get_attr_mode (insn) == MODE_SI)
1732 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1734 return "mov{b}\t{%1, %0|%0, %1}";
1738 (cond [(and (eq_attr "alternative" "5")
1739 (not (match_operand:QI 1 "aligned_operand" "")))
1740 (const_string "imovx")
1741 (ne (symbol_ref "optimize_size") (const_int 0))
1742 (const_string "imov")
1743 (and (eq_attr "alternative" "3")
1744 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1746 (eq (symbol_ref "TARGET_QIMODE_MATH")
1748 (const_string "imov")
1749 (eq_attr "alternative" "3,5")
1750 (const_string "imovx")
1751 (and (ne (symbol_ref "TARGET_MOVX")
1753 (eq_attr "alternative" "2"))
1754 (const_string "imovx")
1756 (const_string "imov")))
1758 (cond [(eq_attr "alternative" "3,4,5")
1760 (eq_attr "alternative" "6")
1762 (eq_attr "type" "imovx")
1764 (and (eq_attr "type" "imov")
1765 (and (eq_attr "alternative" "0,1")
1766 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1768 (and (eq (symbol_ref "optimize_size")
1770 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1773 ;; Avoid partial register stalls when not using QImode arithmetic
1774 (and (eq_attr "type" "imov")
1775 (and (eq_attr "alternative" "0,1")
1776 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1778 (eq (symbol_ref "TARGET_QIMODE_MATH")
1782 (const_string "QI")))])
1784 (define_expand "reload_outqi"
1785 [(parallel [(match_operand:QI 0 "" "=m")
1786 (match_operand:QI 1 "register_operand" "r")
1787 (match_operand:QI 2 "register_operand" "=&q")])]
1791 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1793 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1794 if (! q_regs_operand (op1, QImode))
1796 emit_insn (gen_movqi (op2, op1));
1799 emit_insn (gen_movqi (op0, op1));
1803 (define_insn "*swapqi_1"
1804 [(set (match_operand:QI 0 "register_operand" "+r")
1805 (match_operand:QI 1 "register_operand" "+r"))
1808 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1810 [(set_attr "type" "imov")
1811 (set_attr "mode" "SI")
1812 (set_attr "pent_pair" "np")
1813 (set_attr "athlon_decode" "vector")
1814 (set_attr "amdfam10_decode" "vector")])
1816 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1817 (define_insn "*swapqi_2"
1818 [(set (match_operand:QI 0 "register_operand" "+q")
1819 (match_operand:QI 1 "register_operand" "+q"))
1822 "TARGET_PARTIAL_REG_STALL"
1824 [(set_attr "type" "imov")
1825 (set_attr "mode" "QI")
1826 (set_attr "pent_pair" "np")
1827 (set_attr "athlon_decode" "vector")])
1829 (define_expand "movstrictqi"
1830 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1831 (match_operand:QI 1 "general_operand" ""))]
1832 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1834 /* Don't generate memory->memory moves, go through a register. */
1835 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1836 operands[1] = force_reg (QImode, operands[1]);
1839 (define_insn "*movstrictqi_1"
1840 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1841 (match_operand:QI 1 "general_operand" "*qn,m"))]
1842 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1843 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1844 "mov{b}\t{%1, %0|%0, %1}"
1845 [(set_attr "type" "imov")
1846 (set_attr "mode" "QI")])
1848 (define_insn "*movstrictqi_xor"
1849 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1850 (match_operand:QI 1 "const0_operand" "i"))
1851 (clobber (reg:CC FLAGS_REG))]
1852 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1854 [(set_attr "type" "alu1")
1855 (set_attr "mode" "QI")
1856 (set_attr "length_immediate" "0")])
1858 (define_insn "*movsi_extv_1"
1859 [(set (match_operand:SI 0 "register_operand" "=R")
1860 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1864 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1865 [(set_attr "type" "imovx")
1866 (set_attr "mode" "SI")])
1868 (define_insn "*movhi_extv_1"
1869 [(set (match_operand:HI 0 "register_operand" "=R")
1870 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1874 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1875 [(set_attr "type" "imovx")
1876 (set_attr "mode" "SI")])
1878 (define_insn "*movqi_extv_1"
1879 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1880 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1885 switch (get_attr_type (insn))
1888 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1890 return "mov{b}\t{%h1, %0|%0, %h1}";
1894 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1895 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1896 (ne (symbol_ref "TARGET_MOVX")
1898 (const_string "imovx")
1899 (const_string "imov")))
1901 (if_then_else (eq_attr "type" "imovx")
1903 (const_string "QI")))])
1905 (define_insn "*movqi_extv_1_rex64"
1906 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1907 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1912 switch (get_attr_type (insn))
1915 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1917 return "mov{b}\t{%h1, %0|%0, %h1}";
1921 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1922 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1923 (ne (symbol_ref "TARGET_MOVX")
1925 (const_string "imovx")
1926 (const_string "imov")))
1928 (if_then_else (eq_attr "type" "imovx")
1930 (const_string "QI")))])
1932 ;; Stores and loads of ax to arbitrary constant address.
1933 ;; We fake an second form of instruction to force reload to load address
1934 ;; into register when rax is not available
1935 (define_insn "*movabsqi_1_rex64"
1936 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1937 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1938 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1940 movabs{b}\t{%1, %P0|%P0, %1}
1941 mov{b}\t{%1, %a0|%a0, %1}"
1942 [(set_attr "type" "imov")
1943 (set_attr "modrm" "0,*")
1944 (set_attr "length_address" "8,0")
1945 (set_attr "length_immediate" "0,*")
1946 (set_attr "memory" "store")
1947 (set_attr "mode" "QI")])
1949 (define_insn "*movabsqi_2_rex64"
1950 [(set (match_operand:QI 0 "register_operand" "=a,r")
1951 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1952 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1954 movabs{b}\t{%P1, %0|%0, %P1}
1955 mov{b}\t{%a1, %0|%0, %a1}"
1956 [(set_attr "type" "imov")
1957 (set_attr "modrm" "0,*")
1958 (set_attr "length_address" "8,0")
1959 (set_attr "length_immediate" "0")
1960 (set_attr "memory" "load")
1961 (set_attr "mode" "QI")])
1963 (define_insn "*movdi_extzv_1"
1964 [(set (match_operand:DI 0 "register_operand" "=R")
1965 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1969 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1970 [(set_attr "type" "imovx")
1971 (set_attr "mode" "DI")])
1973 (define_insn "*movsi_extzv_1"
1974 [(set (match_operand:SI 0 "register_operand" "=R")
1975 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1979 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1980 [(set_attr "type" "imovx")
1981 (set_attr "mode" "SI")])
1983 (define_insn "*movqi_extzv_2"
1984 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1985 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1990 switch (get_attr_type (insn))
1993 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1995 return "mov{b}\t{%h1, %0|%0, %h1}";
1999 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2000 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2001 (ne (symbol_ref "TARGET_MOVX")
2003 (const_string "imovx")
2004 (const_string "imov")))
2006 (if_then_else (eq_attr "type" "imovx")
2008 (const_string "QI")))])
2010 (define_insn "*movqi_extzv_2_rex64"
2011 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2012 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2017 switch (get_attr_type (insn))
2020 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2022 return "mov{b}\t{%h1, %0|%0, %h1}";
2026 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2027 (ne (symbol_ref "TARGET_MOVX")
2029 (const_string "imovx")
2030 (const_string "imov")))
2032 (if_then_else (eq_attr "type" "imovx")
2034 (const_string "QI")))])
2036 (define_insn "movsi_insv_1"
2037 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2040 (match_operand:SI 1 "general_operand" "Qmn"))]
2042 "mov{b}\t{%b1, %h0|%h0, %b1}"
2043 [(set_attr "type" "imov")
2044 (set_attr "mode" "QI")])
2046 (define_insn "*movsi_insv_1_rex64"
2047 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2050 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2052 "mov{b}\t{%b1, %h0|%h0, %b1}"
2053 [(set_attr "type" "imov")
2054 (set_attr "mode" "QI")])
2056 (define_insn "movdi_insv_1_rex64"
2057 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2060 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2062 "mov{b}\t{%b1, %h0|%h0, %b1}"
2063 [(set_attr "type" "imov")
2064 (set_attr "mode" "QI")])
2066 (define_insn "*movqi_insv_2"
2067 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2070 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2073 "mov{b}\t{%h1, %h0|%h0, %h1}"
2074 [(set_attr "type" "imov")
2075 (set_attr "mode" "QI")])
2077 (define_expand "movdi"
2078 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2079 (match_operand:DI 1 "general_operand" ""))]
2081 "ix86_expand_move (DImode, operands); DONE;")
2083 (define_insn "*pushdi"
2084 [(set (match_operand:DI 0 "push_operand" "=<")
2085 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2089 (define_insn "*pushdi2_rex64"
2090 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2091 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2096 [(set_attr "type" "push,multi")
2097 (set_attr "mode" "DI")])
2099 ;; Convert impossible pushes of immediate to existing instructions.
2100 ;; First try to get scratch register and go through it. In case this
2101 ;; fails, push sign extended lower part first and then overwrite
2102 ;; upper part by 32bit move.
2104 [(match_scratch:DI 2 "r")
2105 (set (match_operand:DI 0 "push_operand" "")
2106 (match_operand:DI 1 "immediate_operand" ""))]
2107 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2108 && !x86_64_immediate_operand (operands[1], DImode)"
2109 [(set (match_dup 2) (match_dup 1))
2110 (set (match_dup 0) (match_dup 2))]
2113 ;; We need to define this as both peepholer and splitter for case
2114 ;; peephole2 pass is not run.
2115 ;; "&& 1" is needed to keep it from matching the previous pattern.
2117 [(set (match_operand:DI 0 "push_operand" "")
2118 (match_operand:DI 1 "immediate_operand" ""))]
2119 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2120 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2121 [(set (match_dup 0) (match_dup 1))
2122 (set (match_dup 2) (match_dup 3))]
2123 "split_di (operands + 1, 1, operands + 2, operands + 3);
2124 operands[1] = gen_lowpart (DImode, operands[2]);
2125 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2130 [(set (match_operand:DI 0 "push_operand" "")
2131 (match_operand:DI 1 "immediate_operand" ""))]
2132 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2133 ? epilogue_completed : reload_completed)
2134 && !symbolic_operand (operands[1], DImode)
2135 && !x86_64_immediate_operand (operands[1], DImode)"
2136 [(set (match_dup 0) (match_dup 1))
2137 (set (match_dup 2) (match_dup 3))]
2138 "split_di (operands + 1, 1, operands + 2, operands + 3);
2139 operands[1] = gen_lowpart (DImode, operands[2]);
2140 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2144 (define_insn "*pushdi2_prologue_rex64"
2145 [(set (match_operand:DI 0 "push_operand" "=<")
2146 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2147 (clobber (mem:BLK (scratch)))]
2150 [(set_attr "type" "push")
2151 (set_attr "mode" "DI")])
2153 (define_insn "*popdi1_epilogue_rex64"
2154 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2155 (mem:DI (reg:DI SP_REG)))
2156 (set (reg:DI SP_REG)
2157 (plus:DI (reg:DI SP_REG) (const_int 8)))
2158 (clobber (mem:BLK (scratch)))]
2161 [(set_attr "type" "pop")
2162 (set_attr "mode" "DI")])
2164 (define_insn "popdi1"
2165 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2166 (mem:DI (reg:DI SP_REG)))
2167 (set (reg:DI SP_REG)
2168 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2171 [(set_attr "type" "pop")
2172 (set_attr "mode" "DI")])
2174 (define_insn "*movdi_xor_rex64"
2175 [(set (match_operand:DI 0 "register_operand" "=r")
2176 (match_operand:DI 1 "const0_operand" "i"))
2177 (clobber (reg:CC FLAGS_REG))]
2178 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2179 && reload_completed"
2181 [(set_attr "type" "alu1")
2182 (set_attr "mode" "SI")
2183 (set_attr "length_immediate" "0")])
2185 (define_insn "*movdi_or_rex64"
2186 [(set (match_operand:DI 0 "register_operand" "=r")
2187 (match_operand:DI 1 "const_int_operand" "i"))
2188 (clobber (reg:CC FLAGS_REG))]
2189 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2191 && operands[1] == constm1_rtx"
2193 operands[1] = constm1_rtx;
2194 return "or{q}\t{%1, %0|%0, %1}";
2196 [(set_attr "type" "alu1")
2197 (set_attr "mode" "DI")
2198 (set_attr "length_immediate" "1")])
2200 (define_insn "*movdi_2"
2201 [(set (match_operand:DI 0 "nonimmediate_operand"
2202 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2203 (match_operand:DI 1 "general_operand"
2204 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2205 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2210 movq\t{%1, %0|%0, %1}
2211 movq\t{%1, %0|%0, %1}
2213 movq\t{%1, %0|%0, %1}
2214 movdqa\t{%1, %0|%0, %1}
2215 movq\t{%1, %0|%0, %1}
2217 movlps\t{%1, %0|%0, %1}
2218 movaps\t{%1, %0|%0, %1}
2219 movlps\t{%1, %0|%0, %1}"
2220 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2221 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2224 [(set (match_operand:DI 0 "push_operand" "")
2225 (match_operand:DI 1 "general_operand" ""))]
2226 "!TARGET_64BIT && reload_completed
2227 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2229 "ix86_split_long_move (operands); DONE;")
2231 ;; %%% This multiword shite has got to go.
2233 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2234 (match_operand:DI 1 "general_operand" ""))]
2235 "!TARGET_64BIT && reload_completed
2236 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2237 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2239 "ix86_split_long_move (operands); DONE;")
2241 (define_insn "*movdi_1_rex64"
2242 [(set (match_operand:DI 0 "nonimmediate_operand"
2243 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2244 (match_operand:DI 1 "general_operand"
2245 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2246 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2248 switch (get_attr_type (insn))
2251 if (SSE_REG_P (operands[0]))
2252 return "movq2dq\t{%1, %0|%0, %1}";
2254 return "movdq2q\t{%1, %0|%0, %1}";
2257 if (get_attr_mode (insn) == MODE_TI)
2258 return "movdqa\t{%1, %0|%0, %1}";
2262 /* Moves from and into integer register is done using movd
2263 opcode with REX prefix. */
2264 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2265 return "movd\t{%1, %0|%0, %1}";
2266 return "movq\t{%1, %0|%0, %1}";
2270 return "pxor\t%0, %0";
2276 return "lea{q}\t{%a1, %0|%0, %a1}";
2279 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2280 if (get_attr_mode (insn) == MODE_SI)
2281 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2282 else if (which_alternative == 2)
2283 return "movabs{q}\t{%1, %0|%0, %1}";
2285 return "mov{q}\t{%1, %0|%0, %1}";
2289 (cond [(eq_attr "alternative" "5")
2290 (const_string "mmxadd")
2291 (eq_attr "alternative" "6,7,8,9,10")
2292 (const_string "mmxmov")
2293 (eq_attr "alternative" "11")
2294 (const_string "sselog1")
2295 (eq_attr "alternative" "12,13,14,15,16")
2296 (const_string "ssemov")
2297 (eq_attr "alternative" "17,18")
2298 (const_string "ssecvt")
2299 (eq_attr "alternative" "4")
2300 (const_string "multi")
2301 (match_operand:DI 1 "pic_32bit_operand" "")
2302 (const_string "lea")
2304 (const_string "imov")))
2305 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2306 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2307 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2309 ;; Stores and loads of ax to arbitrary constant address.
2310 ;; We fake an second form of instruction to force reload to load address
2311 ;; into register when rax is not available
2312 (define_insn "*movabsdi_1_rex64"
2313 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2314 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2315 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2317 movabs{q}\t{%1, %P0|%P0, %1}
2318 mov{q}\t{%1, %a0|%a0, %1}"
2319 [(set_attr "type" "imov")
2320 (set_attr "modrm" "0,*")
2321 (set_attr "length_address" "8,0")
2322 (set_attr "length_immediate" "0,*")
2323 (set_attr "memory" "store")
2324 (set_attr "mode" "DI")])
2326 (define_insn "*movabsdi_2_rex64"
2327 [(set (match_operand:DI 0 "register_operand" "=a,r")
2328 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2329 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2331 movabs{q}\t{%P1, %0|%0, %P1}
2332 mov{q}\t{%a1, %0|%0, %a1}"
2333 [(set_attr "type" "imov")
2334 (set_attr "modrm" "0,*")
2335 (set_attr "length_address" "8,0")
2336 (set_attr "length_immediate" "0")
2337 (set_attr "memory" "load")
2338 (set_attr "mode" "DI")])
2340 ;; Convert impossible stores of immediate to existing instructions.
2341 ;; First try to get scratch register and go through it. In case this
2342 ;; fails, move by 32bit parts.
2344 [(match_scratch:DI 2 "r")
2345 (set (match_operand:DI 0 "memory_operand" "")
2346 (match_operand:DI 1 "immediate_operand" ""))]
2347 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2348 && !x86_64_immediate_operand (operands[1], DImode)"
2349 [(set (match_dup 2) (match_dup 1))
2350 (set (match_dup 0) (match_dup 2))]
2353 ;; We need to define this as both peepholer and splitter for case
2354 ;; peephole2 pass is not run.
2355 ;; "&& 1" is needed to keep it from matching the previous pattern.
2357 [(set (match_operand:DI 0 "memory_operand" "")
2358 (match_operand:DI 1 "immediate_operand" ""))]
2359 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2360 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2361 [(set (match_dup 2) (match_dup 3))
2362 (set (match_dup 4) (match_dup 5))]
2363 "split_di (operands, 2, operands + 2, operands + 4);")
2366 [(set (match_operand:DI 0 "memory_operand" "")
2367 (match_operand:DI 1 "immediate_operand" ""))]
2368 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2369 ? epilogue_completed : reload_completed)
2370 && !symbolic_operand (operands[1], DImode)
2371 && !x86_64_immediate_operand (operands[1], DImode)"
2372 [(set (match_dup 2) (match_dup 3))
2373 (set (match_dup 4) (match_dup 5))]
2374 "split_di (operands, 2, operands + 2, operands + 4);")
2376 (define_insn "*swapdi_rex64"
2377 [(set (match_operand:DI 0 "register_operand" "+r")
2378 (match_operand:DI 1 "register_operand" "+r"))
2383 [(set_attr "type" "imov")
2384 (set_attr "mode" "DI")
2385 (set_attr "pent_pair" "np")
2386 (set_attr "athlon_decode" "vector")
2387 (set_attr "amdfam10_decode" "double")])
2389 (define_expand "movti"
2390 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2391 (match_operand:TI 1 "nonimmediate_operand" ""))]
2392 "TARGET_SSE || TARGET_64BIT"
2395 ix86_expand_move (TImode, operands);
2396 else if (push_operand (operands[0], TImode))
2397 ix86_expand_push (TImode, operands[1]);
2399 ix86_expand_vector_move (TImode, operands);
2403 (define_insn "*movti_internal"
2404 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2405 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2406 "TARGET_SSE && !TARGET_64BIT
2407 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2409 switch (which_alternative)
2412 if (get_attr_mode (insn) == MODE_V4SF)
2413 return "xorps\t%0, %0";
2415 return "pxor\t%0, %0";
2418 /* TDmode values are passed as TImode on the stack. Moving them
2419 to stack may result in unaligned memory access. */
2420 if (misaligned_operand (operands[0], TImode)
2421 || misaligned_operand (operands[1], TImode))
2423 if (get_attr_mode (insn) == MODE_V4SF)
2424 return "movups\t{%1, %0|%0, %1}";
2426 return "movdqu\t{%1, %0|%0, %1}";
2430 if (get_attr_mode (insn) == MODE_V4SF)
2431 return "movaps\t{%1, %0|%0, %1}";
2433 return "movdqa\t{%1, %0|%0, %1}";
2439 [(set_attr "type" "sselog1,ssemov,ssemov")
2441 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2442 (ne (symbol_ref "optimize_size") (const_int 0)))
2443 (const_string "V4SF")
2444 (and (eq_attr "alternative" "2")
2445 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2447 (const_string "V4SF")]
2448 (const_string "TI")))])
2450 (define_insn "*movti_rex64"
2451 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2452 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2454 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2456 switch (which_alternative)
2462 if (get_attr_mode (insn) == MODE_V4SF)
2463 return "xorps\t%0, %0";
2465 return "pxor\t%0, %0";
2468 /* TDmode values are passed as TImode on the stack. Moving them
2469 to stack may result in unaligned memory access. */
2470 if (misaligned_operand (operands[0], TImode)
2471 || misaligned_operand (operands[1], TImode))
2473 if (get_attr_mode (insn) == MODE_V4SF)
2474 return "movups\t{%1, %0|%0, %1}";
2476 return "movdqu\t{%1, %0|%0, %1}";
2480 if (get_attr_mode (insn) == MODE_V4SF)
2481 return "movaps\t{%1, %0|%0, %1}";
2483 return "movdqa\t{%1, %0|%0, %1}";
2489 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2491 (cond [(eq_attr "alternative" "2,3")
2493 (ne (symbol_ref "optimize_size")
2495 (const_string "V4SF")
2496 (const_string "TI"))
2497 (eq_attr "alternative" "4")
2499 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2501 (ne (symbol_ref "optimize_size")
2503 (const_string "V4SF")
2504 (const_string "TI"))]
2505 (const_string "DI")))])
2508 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2509 (match_operand:TI 1 "general_operand" ""))]
2510 "reload_completed && !SSE_REG_P (operands[0])
2511 && !SSE_REG_P (operands[1])"
2513 "ix86_split_long_move (operands); DONE;")
2515 ;; This expands to what emit_move_complex would generate if we didn't
2516 ;; have a movti pattern. Having this avoids problems with reload on
2517 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2518 ;; to have around all the time.
2519 (define_expand "movcdi"
2520 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2521 (match_operand:CDI 1 "general_operand" ""))]
2524 if (push_operand (operands[0], CDImode))
2525 emit_move_complex_push (CDImode, operands[0], operands[1]);
2527 emit_move_complex_parts (operands[0], operands[1]);
2531 (define_expand "movsf"
2532 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2533 (match_operand:SF 1 "general_operand" ""))]
2535 "ix86_expand_move (SFmode, operands); DONE;")
2537 (define_insn "*pushsf"
2538 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2539 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2542 /* Anything else should be already split before reg-stack. */
2543 gcc_assert (which_alternative == 1);
2544 return "push{l}\t%1";
2546 [(set_attr "type" "multi,push,multi")
2547 (set_attr "unit" "i387,*,*")
2548 (set_attr "mode" "SF,SI,SF")])
2550 (define_insn "*pushsf_rex64"
2551 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2552 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2555 /* Anything else should be already split before reg-stack. */
2556 gcc_assert (which_alternative == 1);
2557 return "push{q}\t%q1";
2559 [(set_attr "type" "multi,push,multi")
2560 (set_attr "unit" "i387,*,*")
2561 (set_attr "mode" "SF,DI,SF")])
2564 [(set (match_operand:SF 0 "push_operand" "")
2565 (match_operand:SF 1 "memory_operand" ""))]
2567 && MEM_P (operands[1])
2568 && (operands[2] = find_constant_src (insn))"
2573 ;; %%% Kill this when call knows how to work this out.
2575 [(set (match_operand:SF 0 "push_operand" "")
2576 (match_operand:SF 1 "any_fp_register_operand" ""))]
2578 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2579 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2582 [(set (match_operand:SF 0 "push_operand" "")
2583 (match_operand:SF 1 "any_fp_register_operand" ""))]
2585 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2586 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2588 (define_insn "*movsf_1"
2589 [(set (match_operand:SF 0 "nonimmediate_operand"
2590 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2591 (match_operand:SF 1 "general_operand"
2592 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2593 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2594 && (reload_in_progress || reload_completed
2595 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2596 || (!TARGET_SSE_MATH && optimize_size
2597 && standard_80387_constant_p (operands[1]))
2598 || GET_CODE (operands[1]) != CONST_DOUBLE
2599 || memory_operand (operands[0], SFmode))"
2601 switch (which_alternative)
2605 return output_387_reg_move (insn, operands);
2608 return standard_80387_constant_opcode (operands[1]);
2612 return "mov{l}\t{%1, %0|%0, %1}";
2614 if (get_attr_mode (insn) == MODE_TI)
2615 return "pxor\t%0, %0";
2617 return "xorps\t%0, %0";
2619 if (get_attr_mode (insn) == MODE_V4SF)
2620 return "movaps\t{%1, %0|%0, %1}";
2622 return "movss\t{%1, %0|%0, %1}";
2624 return "movss\t{%1, %0|%0, %1}";
2627 case 12: case 13: case 14: case 15:
2628 return "movd\t{%1, %0|%0, %1}";
2631 return "movq\t{%1, %0|%0, %1}";
2637 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2639 (cond [(eq_attr "alternative" "3,4,9,10")
2641 (eq_attr "alternative" "5")
2643 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2645 (ne (symbol_ref "TARGET_SSE2")
2647 (eq (symbol_ref "optimize_size")
2650 (const_string "V4SF"))
2651 /* For architectures resolving dependencies on
2652 whole SSE registers use APS move to break dependency
2653 chains, otherwise use short move to avoid extra work.
2655 Do the same for architectures resolving dependencies on
2656 the parts. While in DF mode it is better to always handle
2657 just register parts, the SF mode is different due to lack
2658 of instructions to load just part of the register. It is
2659 better to maintain the whole registers in single format
2660 to avoid problems on using packed logical operations. */
2661 (eq_attr "alternative" "6")
2663 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2665 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2667 (const_string "V4SF")
2668 (const_string "SF"))
2669 (eq_attr "alternative" "11")
2670 (const_string "DI")]
2671 (const_string "SF")))])
2673 (define_insn "*swapsf"
2674 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2675 (match_operand:SF 1 "fp_register_operand" "+f"))
2678 "reload_completed || TARGET_80387"
2680 if (STACK_TOP_P (operands[0]))
2685 [(set_attr "type" "fxch")
2686 (set_attr "mode" "SF")])
2688 (define_expand "movdf"
2689 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2690 (match_operand:DF 1 "general_operand" ""))]
2692 "ix86_expand_move (DFmode, operands); DONE;")
2694 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2695 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2696 ;; On the average, pushdf using integers can be still shorter. Allow this
2697 ;; pattern for optimize_size too.
2699 (define_insn "*pushdf_nointeger"
2700 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2701 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2702 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2704 /* This insn should be already split before reg-stack. */
2707 [(set_attr "type" "multi")
2708 (set_attr "unit" "i387,*,*,*")
2709 (set_attr "mode" "DF,SI,SI,DF")])
2711 (define_insn "*pushdf_integer"
2712 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2713 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2714 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2716 /* This insn should be already split before reg-stack. */
2719 [(set_attr "type" "multi")
2720 (set_attr "unit" "i387,*,*")
2721 (set_attr "mode" "DF,SI,DF")])
2723 ;; %%% Kill this when call knows how to work this out.
2725 [(set (match_operand:DF 0 "push_operand" "")
2726 (match_operand:DF 1 "any_fp_register_operand" ""))]
2727 "!TARGET_64BIT && reload_completed"
2728 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2729 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2733 [(set (match_operand:DF 0 "push_operand" "")
2734 (match_operand:DF 1 "any_fp_register_operand" ""))]
2735 "TARGET_64BIT && reload_completed"
2736 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2737 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2741 [(set (match_operand:DF 0 "push_operand" "")
2742 (match_operand:DF 1 "general_operand" ""))]
2745 "ix86_split_long_move (operands); DONE;")
2747 ;; Moving is usually shorter when only FP registers are used. This separate
2748 ;; movdf pattern avoids the use of integer registers for FP operations
2749 ;; when optimizing for size.
2751 (define_insn "*movdf_nointeger"
2752 [(set (match_operand:DF 0 "nonimmediate_operand"
2753 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2754 (match_operand:DF 1 "general_operand"
2755 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2756 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2757 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2758 && (reload_in_progress || reload_completed
2759 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2760 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2761 && !memory_operand (operands[0], DFmode)
2762 && standard_80387_constant_p (operands[1]))
2763 || GET_CODE (operands[1]) != CONST_DOUBLE
2765 || !TARGET_MEMORY_MISMATCH_STALL
2766 || reload_in_progress || reload_completed)
2767 && memory_operand (operands[0], DFmode)))"
2769 switch (which_alternative)
2773 return output_387_reg_move (insn, operands);
2776 return standard_80387_constant_opcode (operands[1]);
2782 switch (get_attr_mode (insn))
2785 return "xorps\t%0, %0";
2787 return "xorpd\t%0, %0";
2789 return "pxor\t%0, %0";
2796 switch (get_attr_mode (insn))
2799 return "movaps\t{%1, %0|%0, %1}";
2801 return "movapd\t{%1, %0|%0, %1}";
2803 return "movdqa\t{%1, %0|%0, %1}";
2805 return "movq\t{%1, %0|%0, %1}";
2807 return "movsd\t{%1, %0|%0, %1}";
2809 return "movlpd\t{%1, %0|%0, %1}";
2811 return "movlps\t{%1, %0|%0, %1}";
2820 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2822 (cond [(eq_attr "alternative" "0,1,2")
2824 (eq_attr "alternative" "3,4")
2827 /* For SSE1, we have many fewer alternatives. */
2828 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2829 (cond [(eq_attr "alternative" "5,6")
2830 (const_string "V4SF")
2832 (const_string "V2SF"))
2834 /* xorps is one byte shorter. */
2835 (eq_attr "alternative" "5")
2836 (cond [(ne (symbol_ref "optimize_size")
2838 (const_string "V4SF")
2839 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2843 (const_string "V2DF"))
2845 /* For architectures resolving dependencies on
2846 whole SSE registers use APD move to break dependency
2847 chains, otherwise use short move to avoid extra work.
2849 movaps encodes one byte shorter. */
2850 (eq_attr "alternative" "6")
2852 [(ne (symbol_ref "optimize_size")
2854 (const_string "V4SF")
2855 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2857 (const_string "V2DF")
2859 (const_string "DF"))
2860 /* For architectures resolving dependencies on register
2861 parts we may avoid extra work to zero out upper part
2863 (eq_attr "alternative" "7")
2865 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2867 (const_string "V1DF")
2868 (const_string "DF"))
2870 (const_string "DF")))])
2872 (define_insn "*movdf_integer_rex64"
2873 [(set (match_operand:DF 0 "nonimmediate_operand"
2874 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2875 (match_operand:DF 1 "general_operand"
2876 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2877 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2878 && (reload_in_progress || reload_completed
2879 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2880 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2881 && standard_80387_constant_p (operands[1]))
2882 || GET_CODE (operands[1]) != CONST_DOUBLE
2883 || memory_operand (operands[0], DFmode))"
2885 switch (which_alternative)
2889 return output_387_reg_move (insn, operands);
2892 return standard_80387_constant_opcode (operands[1]);
2899 switch (get_attr_mode (insn))
2902 return "xorps\t%0, %0";
2904 return "xorpd\t%0, %0";
2906 return "pxor\t%0, %0";
2913 switch (get_attr_mode (insn))
2916 return "movaps\t{%1, %0|%0, %1}";
2918 return "movapd\t{%1, %0|%0, %1}";
2920 return "movdqa\t{%1, %0|%0, %1}";
2922 return "movq\t{%1, %0|%0, %1}";
2924 return "movsd\t{%1, %0|%0, %1}";
2926 return "movlpd\t{%1, %0|%0, %1}";
2928 return "movlps\t{%1, %0|%0, %1}";
2935 return "movd\t{%1, %0|%0, %1}";
2941 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2943 (cond [(eq_attr "alternative" "0,1,2")
2945 (eq_attr "alternative" "3,4,9,10")
2948 /* For SSE1, we have many fewer alternatives. */
2949 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2950 (cond [(eq_attr "alternative" "5,6")
2951 (const_string "V4SF")
2953 (const_string "V2SF"))
2955 /* xorps is one byte shorter. */
2956 (eq_attr "alternative" "5")
2957 (cond [(ne (symbol_ref "optimize_size")
2959 (const_string "V4SF")
2960 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2964 (const_string "V2DF"))
2966 /* For architectures resolving dependencies on
2967 whole SSE registers use APD move to break dependency
2968 chains, otherwise use short move to avoid extra work.
2970 movaps encodes one byte shorter. */
2971 (eq_attr "alternative" "6")
2973 [(ne (symbol_ref "optimize_size")
2975 (const_string "V4SF")
2976 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2978 (const_string "V2DF")
2980 (const_string "DF"))
2981 /* For architectures resolving dependencies on register
2982 parts we may avoid extra work to zero out upper part
2984 (eq_attr "alternative" "7")
2986 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2988 (const_string "V1DF")
2989 (const_string "DF"))
2991 (const_string "DF")))])
2993 (define_insn "*movdf_integer"
2994 [(set (match_operand:DF 0 "nonimmediate_operand"
2995 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2996 (match_operand:DF 1 "general_operand"
2997 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2998 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2999 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3000 && (reload_in_progress || reload_completed
3001 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3002 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3003 && standard_80387_constant_p (operands[1]))
3004 || GET_CODE (operands[1]) != CONST_DOUBLE
3005 || memory_operand (operands[0], DFmode))"
3007 switch (which_alternative)
3011 return output_387_reg_move (insn, operands);
3014 return standard_80387_constant_opcode (operands[1]);
3021 switch (get_attr_mode (insn))
3024 return "xorps\t%0, %0";
3026 return "xorpd\t%0, %0";
3028 return "pxor\t%0, %0";
3035 switch (get_attr_mode (insn))
3038 return "movaps\t{%1, %0|%0, %1}";
3040 return "movapd\t{%1, %0|%0, %1}";
3042 return "movdqa\t{%1, %0|%0, %1}";
3044 return "movq\t{%1, %0|%0, %1}";
3046 return "movsd\t{%1, %0|%0, %1}";
3048 return "movlpd\t{%1, %0|%0, %1}";
3050 return "movlps\t{%1, %0|%0, %1}";
3059 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3061 (cond [(eq_attr "alternative" "0,1,2")
3063 (eq_attr "alternative" "3,4")
3066 /* For SSE1, we have many fewer alternatives. */
3067 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3068 (cond [(eq_attr "alternative" "5,6")
3069 (const_string "V4SF")
3071 (const_string "V2SF"))
3073 /* xorps is one byte shorter. */
3074 (eq_attr "alternative" "5")
3075 (cond [(ne (symbol_ref "optimize_size")
3077 (const_string "V4SF")
3078 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3082 (const_string "V2DF"))
3084 /* For architectures resolving dependencies on
3085 whole SSE registers use APD move to break dependency
3086 chains, otherwise use short move to avoid extra work.
3088 movaps encodes one byte shorter. */
3089 (eq_attr "alternative" "6")
3091 [(ne (symbol_ref "optimize_size")
3093 (const_string "V4SF")
3094 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3096 (const_string "V2DF")
3098 (const_string "DF"))
3099 /* For architectures resolving dependencies on register
3100 parts we may avoid extra work to zero out upper part
3102 (eq_attr "alternative" "7")
3104 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3106 (const_string "V1DF")
3107 (const_string "DF"))
3109 (const_string "DF")))])
3112 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3113 (match_operand:DF 1 "general_operand" ""))]
3115 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3116 && ! (ANY_FP_REG_P (operands[0]) ||
3117 (GET_CODE (operands[0]) == SUBREG
3118 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3119 && ! (ANY_FP_REG_P (operands[1]) ||
3120 (GET_CODE (operands[1]) == SUBREG
3121 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3123 "ix86_split_long_move (operands); DONE;")
3125 (define_insn "*swapdf"
3126 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3127 (match_operand:DF 1 "fp_register_operand" "+f"))
3130 "reload_completed || TARGET_80387"
3132 if (STACK_TOP_P (operands[0]))
3137 [(set_attr "type" "fxch")
3138 (set_attr "mode" "DF")])
3140 (define_expand "movxf"
3141 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3142 (match_operand:XF 1 "general_operand" ""))]
3144 "ix86_expand_move (XFmode, operands); DONE;")
3146 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3147 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3148 ;; Pushing using integer instructions is longer except for constants
3149 ;; and direct memory references.
3150 ;; (assuming that any given constant is pushed only once, but this ought to be
3151 ;; handled elsewhere).
3153 (define_insn "*pushxf_nointeger"
3154 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3155 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3158 /* This insn should be already split before reg-stack. */
3161 [(set_attr "type" "multi")
3162 (set_attr "unit" "i387,*,*")
3163 (set_attr "mode" "XF,SI,SI")])
3165 (define_insn "*pushxf_integer"
3166 [(set (match_operand:XF 0 "push_operand" "=<,<")
3167 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3170 /* This insn should be already split before reg-stack. */
3173 [(set_attr "type" "multi")
3174 (set_attr "unit" "i387,*")
3175 (set_attr "mode" "XF,SI")])
3178 [(set (match_operand 0 "push_operand" "")
3179 (match_operand 1 "general_operand" ""))]
3181 && (GET_MODE (operands[0]) == XFmode
3182 || GET_MODE (operands[0]) == DFmode)
3183 && !ANY_FP_REG_P (operands[1])"
3185 "ix86_split_long_move (operands); DONE;")
3188 [(set (match_operand:XF 0 "push_operand" "")
3189 (match_operand:XF 1 "any_fp_register_operand" ""))]
3191 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3192 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3193 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3196 [(set (match_operand:XF 0 "push_operand" "")
3197 (match_operand:XF 1 "any_fp_register_operand" ""))]
3199 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3200 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3201 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3203 ;; Do not use integer registers when optimizing for size
3204 (define_insn "*movxf_nointeger"
3205 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3206 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3208 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3209 && (reload_in_progress || reload_completed
3210 || (optimize_size && standard_80387_constant_p (operands[1]))
3211 || GET_CODE (operands[1]) != CONST_DOUBLE
3212 || memory_operand (operands[0], XFmode))"
3214 switch (which_alternative)
3218 return output_387_reg_move (insn, operands);
3221 return standard_80387_constant_opcode (operands[1]);
3229 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3230 (set_attr "mode" "XF,XF,XF,SI,SI")])
3232 (define_insn "*movxf_integer"
3233 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3234 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3236 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3237 && (reload_in_progress || reload_completed
3238 || (optimize_size && standard_80387_constant_p (operands[1]))
3239 || GET_CODE (operands[1]) != CONST_DOUBLE
3240 || memory_operand (operands[0], XFmode))"
3242 switch (which_alternative)
3246 return output_387_reg_move (insn, operands);
3249 return standard_80387_constant_opcode (operands[1]);
3258 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3259 (set_attr "mode" "XF,XF,XF,SI,SI")])
3261 (define_expand "movtf"
3262 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3263 (match_operand:TF 1 "nonimmediate_operand" ""))]
3266 ix86_expand_move (TFmode, operands);
3270 (define_insn "*movtf_internal"
3271 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3272 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3274 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3276 switch (which_alternative)
3280 if (get_attr_mode (insn) == MODE_V4SF)
3281 return "movaps\t{%1, %0|%0, %1}";
3283 return "movdqa\t{%1, %0|%0, %1}";
3285 if (get_attr_mode (insn) == MODE_V4SF)
3286 return "xorps\t%0, %0";
3288 return "pxor\t%0, %0";
3296 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3298 (cond [(eq_attr "alternative" "0,2")
3300 (ne (symbol_ref "optimize_size")
3302 (const_string "V4SF")
3303 (const_string "TI"))
3304 (eq_attr "alternative" "1")
3306 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3308 (ne (symbol_ref "optimize_size")
3310 (const_string "V4SF")
3311 (const_string "TI"))]
3312 (const_string "DI")))])
3315 [(set (match_operand 0 "nonimmediate_operand" "")
3316 (match_operand 1 "general_operand" ""))]
3318 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3319 && GET_MODE (operands[0]) == XFmode
3320 && ! (ANY_FP_REG_P (operands[0]) ||
3321 (GET_CODE (operands[0]) == SUBREG
3322 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3323 && ! (ANY_FP_REG_P (operands[1]) ||
3324 (GET_CODE (operands[1]) == SUBREG
3325 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3327 "ix86_split_long_move (operands); DONE;")
3330 [(set (match_operand 0 "register_operand" "")
3331 (match_operand 1 "memory_operand" ""))]
3333 && MEM_P (operands[1])
3334 && (GET_MODE (operands[0]) == TFmode
3335 || GET_MODE (operands[0]) == XFmode
3336 || GET_MODE (operands[0]) == SFmode
3337 || GET_MODE (operands[0]) == DFmode)
3338 && (operands[2] = find_constant_src (insn))"
3339 [(set (match_dup 0) (match_dup 2))]
3341 rtx c = operands[2];
3342 rtx r = operands[0];
3344 if (GET_CODE (r) == SUBREG)
3349 if (!standard_sse_constant_p (c))
3352 else if (FP_REG_P (r))
3354 if (!standard_80387_constant_p (c))
3357 else if (MMX_REG_P (r))
3362 [(set (match_operand 0 "register_operand" "")
3363 (float_extend (match_operand 1 "memory_operand" "")))]
3365 && MEM_P (operands[1])
3366 && (GET_MODE (operands[0]) == TFmode
3367 || GET_MODE (operands[0]) == XFmode
3368 || GET_MODE (operands[0]) == SFmode
3369 || GET_MODE (operands[0]) == DFmode)
3370 && (operands[2] = find_constant_src (insn))"
3371 [(set (match_dup 0) (match_dup 2))]
3373 rtx c = operands[2];
3374 rtx r = operands[0];
3376 if (GET_CODE (r) == SUBREG)
3381 if (!standard_sse_constant_p (c))
3384 else if (FP_REG_P (r))
3386 if (!standard_80387_constant_p (c))
3389 else if (MMX_REG_P (r))
3393 (define_insn "swapxf"
3394 [(set (match_operand:XF 0 "register_operand" "+f")
3395 (match_operand:XF 1 "register_operand" "+f"))
3400 if (STACK_TOP_P (operands[0]))
3405 [(set_attr "type" "fxch")
3406 (set_attr "mode" "XF")])
3408 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3410 [(set (match_operand:X87MODEF 0 "register_operand" "")
3411 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3412 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3413 && (standard_80387_constant_p (operands[1]) == 8
3414 || standard_80387_constant_p (operands[1]) == 9)"
3415 [(set (match_dup 0)(match_dup 1))
3417 (neg:X87MODEF (match_dup 0)))]
3421 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3422 if (real_isnegzero (&r))
3423 operands[1] = CONST0_RTX (<MODE>mode);
3425 operands[1] = CONST1_RTX (<MODE>mode);
3429 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3430 (match_operand:TF 1 "general_operand" ""))]
3432 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3434 "ix86_split_long_move (operands); DONE;")
3436 ;; Zero extension instructions
3438 (define_expand "zero_extendhisi2"
3439 [(set (match_operand:SI 0 "register_operand" "")
3440 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3443 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3445 operands[1] = force_reg (HImode, operands[1]);
3446 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3451 (define_insn "zero_extendhisi2_and"
3452 [(set (match_operand:SI 0 "register_operand" "=r")
3453 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3454 (clobber (reg:CC FLAGS_REG))]
3455 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3457 [(set_attr "type" "alu1")
3458 (set_attr "mode" "SI")])
3461 [(set (match_operand:SI 0 "register_operand" "")
3462 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3463 (clobber (reg:CC FLAGS_REG))]
3464 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3465 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3466 (clobber (reg:CC FLAGS_REG))])]
3469 (define_insn "*zero_extendhisi2_movzwl"
3470 [(set (match_operand:SI 0 "register_operand" "=r")
3471 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3472 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3473 "movz{wl|x}\t{%1, %0|%0, %1}"
3474 [(set_attr "type" "imovx")
3475 (set_attr "mode" "SI")])
3477 (define_expand "zero_extendqihi2"
3479 [(set (match_operand:HI 0 "register_operand" "")
3480 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3481 (clobber (reg:CC FLAGS_REG))])]
3485 (define_insn "*zero_extendqihi2_and"
3486 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3487 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3488 (clobber (reg:CC FLAGS_REG))]
3489 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3491 [(set_attr "type" "alu1")
3492 (set_attr "mode" "HI")])
3494 (define_insn "*zero_extendqihi2_movzbw_and"
3495 [(set (match_operand:HI 0 "register_operand" "=r,r")
3496 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3497 (clobber (reg:CC FLAGS_REG))]
3498 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3500 [(set_attr "type" "imovx,alu1")
3501 (set_attr "mode" "HI")])
3503 ; zero extend to SImode here to avoid partial register stalls
3504 (define_insn "*zero_extendqihi2_movzbl"
3505 [(set (match_operand:HI 0 "register_operand" "=r")
3506 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3507 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3508 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3509 [(set_attr "type" "imovx")
3510 (set_attr "mode" "SI")])
3512 ;; For the movzbw case strip only the clobber
3514 [(set (match_operand:HI 0 "register_operand" "")
3515 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3516 (clobber (reg:CC FLAGS_REG))]
3518 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3519 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3520 [(set (match_operand:HI 0 "register_operand" "")
3521 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3523 ;; When source and destination does not overlap, clear destination
3524 ;; first and then do the movb
3526 [(set (match_operand:HI 0 "register_operand" "")
3527 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3528 (clobber (reg:CC FLAGS_REG))]
3530 && ANY_QI_REG_P (operands[0])
3531 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3532 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3533 [(set (match_dup 0) (const_int 0))
3534 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3535 "operands[2] = gen_lowpart (QImode, operands[0]);")
3537 ;; Rest is handled by single and.
3539 [(set (match_operand:HI 0 "register_operand" "")
3540 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3541 (clobber (reg:CC FLAGS_REG))]
3543 && true_regnum (operands[0]) == true_regnum (operands[1])"
3544 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3545 (clobber (reg:CC FLAGS_REG))])]
3548 (define_expand "zero_extendqisi2"
3550 [(set (match_operand:SI 0 "register_operand" "")
3551 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3552 (clobber (reg:CC FLAGS_REG))])]
3556 (define_insn "*zero_extendqisi2_and"
3557 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3558 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3559 (clobber (reg:CC FLAGS_REG))]
3560 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3562 [(set_attr "type" "alu1")
3563 (set_attr "mode" "SI")])
3565 (define_insn "*zero_extendqisi2_movzbw_and"
3566 [(set (match_operand:SI 0 "register_operand" "=r,r")
3567 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3568 (clobber (reg:CC FLAGS_REG))]
3569 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3571 [(set_attr "type" "imovx,alu1")
3572 (set_attr "mode" "SI")])
3574 (define_insn "*zero_extendqisi2_movzbw"
3575 [(set (match_operand:SI 0 "register_operand" "=r")
3576 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3577 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3578 "movz{bl|x}\t{%1, %0|%0, %1}"
3579 [(set_attr "type" "imovx")
3580 (set_attr "mode" "SI")])
3582 ;; For the movzbl case strip only the clobber
3584 [(set (match_operand:SI 0 "register_operand" "")
3585 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3586 (clobber (reg:CC FLAGS_REG))]
3588 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3589 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3591 (zero_extend:SI (match_dup 1)))])
3593 ;; When source and destination does not overlap, clear destination
3594 ;; first and then do the movb
3596 [(set (match_operand:SI 0 "register_operand" "")
3597 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3598 (clobber (reg:CC FLAGS_REG))]
3600 && ANY_QI_REG_P (operands[0])
3601 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3602 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3603 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3604 [(set (match_dup 0) (const_int 0))
3605 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3606 "operands[2] = gen_lowpart (QImode, operands[0]);")
3608 ;; Rest is handled by single and.
3610 [(set (match_operand:SI 0 "register_operand" "")
3611 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3612 (clobber (reg:CC FLAGS_REG))]
3614 && true_regnum (operands[0]) == true_regnum (operands[1])"
3615 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3616 (clobber (reg:CC FLAGS_REG))])]
3619 ;; %%% Kill me once multi-word ops are sane.
3620 (define_expand "zero_extendsidi2"
3621 [(set (match_operand:DI 0 "register_operand" "")
3622 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3627 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3632 (define_insn "zero_extendsidi2_32"
3633 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3635 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3636 (clobber (reg:CC FLAGS_REG))]
3642 movd\t{%1, %0|%0, %1}
3643 movd\t{%1, %0|%0, %1}
3644 movd\t{%1, %0|%0, %1}
3645 movd\t{%1, %0|%0, %1}"
3646 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3647 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3649 (define_insn "zero_extendsidi2_rex64"
3650 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3652 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3655 mov\t{%k1, %k0|%k0, %k1}
3657 movd\t{%1, %0|%0, %1}
3658 movd\t{%1, %0|%0, %1}
3659 movd\t{%1, %0|%0, %1}
3660 movd\t{%1, %0|%0, %1}"
3661 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3662 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3665 [(set (match_operand:DI 0 "memory_operand" "")
3666 (zero_extend:DI (match_dup 0)))]
3668 [(set (match_dup 4) (const_int 0))]
3669 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3672 [(set (match_operand:DI 0 "register_operand" "")
3673 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3674 (clobber (reg:CC FLAGS_REG))]
3675 "!TARGET_64BIT && reload_completed
3676 && true_regnum (operands[0]) == true_regnum (operands[1])"
3677 [(set (match_dup 4) (const_int 0))]
3678 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3681 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3682 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3683 (clobber (reg:CC FLAGS_REG))]
3684 "!TARGET_64BIT && reload_completed
3685 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3686 [(set (match_dup 3) (match_dup 1))
3687 (set (match_dup 4) (const_int 0))]
3688 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3690 (define_insn "zero_extendhidi2"
3691 [(set (match_operand:DI 0 "register_operand" "=r")
3692 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3694 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "DI")])
3698 (define_insn "zero_extendqidi2"
3699 [(set (match_operand:DI 0 "register_operand" "=r")
3700 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3702 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3703 [(set_attr "type" "imovx")
3704 (set_attr "mode" "DI")])
3706 ;; Sign extension instructions
3708 (define_expand "extendsidi2"
3709 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3710 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3711 (clobber (reg:CC FLAGS_REG))
3712 (clobber (match_scratch:SI 2 ""))])]
3717 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3722 (define_insn "*extendsidi2_1"
3723 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3724 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3725 (clobber (reg:CC FLAGS_REG))
3726 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3730 (define_insn "extendsidi2_rex64"
3731 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3732 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3736 movs{lq|x}\t{%1,%0|%0, %1}"
3737 [(set_attr "type" "imovx")
3738 (set_attr "mode" "DI")
3739 (set_attr "prefix_0f" "0")
3740 (set_attr "modrm" "0,1")])
3742 (define_insn "extendhidi2"
3743 [(set (match_operand:DI 0 "register_operand" "=r")
3744 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3746 "movs{wq|x}\t{%1,%0|%0, %1}"
3747 [(set_attr "type" "imovx")
3748 (set_attr "mode" "DI")])
3750 (define_insn "extendqidi2"
3751 [(set (match_operand:DI 0 "register_operand" "=r")
3752 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3754 "movs{bq|x}\t{%1,%0|%0, %1}"
3755 [(set_attr "type" "imovx")
3756 (set_attr "mode" "DI")])
3758 ;; Extend to memory case when source register does die.
3760 [(set (match_operand:DI 0 "memory_operand" "")
3761 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3762 (clobber (reg:CC FLAGS_REG))
3763 (clobber (match_operand:SI 2 "register_operand" ""))]
3765 && dead_or_set_p (insn, operands[1])
3766 && !reg_mentioned_p (operands[1], operands[0]))"
3767 [(set (match_dup 3) (match_dup 1))
3768 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3769 (clobber (reg:CC FLAGS_REG))])
3770 (set (match_dup 4) (match_dup 1))]
3771 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3773 ;; Extend to memory case when source register does not die.
3775 [(set (match_operand:DI 0 "memory_operand" "")
3776 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3777 (clobber (reg:CC FLAGS_REG))
3778 (clobber (match_operand:SI 2 "register_operand" ""))]
3782 split_di (&operands[0], 1, &operands[3], &operands[4]);
3784 emit_move_insn (operands[3], operands[1]);
3786 /* Generate a cltd if possible and doing so it profitable. */
3787 if ((optimize_size || TARGET_USE_CLTD)
3788 && true_regnum (operands[1]) == AX_REG
3789 && true_regnum (operands[2]) == DX_REG)
3791 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3795 emit_move_insn (operands[2], operands[1]);
3796 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3798 emit_move_insn (operands[4], operands[2]);
3802 ;; Extend to register case. Optimize case where source and destination
3803 ;; registers match and cases where we can use cltd.
3805 [(set (match_operand:DI 0 "register_operand" "")
3806 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3807 (clobber (reg:CC FLAGS_REG))
3808 (clobber (match_scratch:SI 2 ""))]
3812 split_di (&operands[0], 1, &operands[3], &operands[4]);
3814 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3815 emit_move_insn (operands[3], operands[1]);
3817 /* Generate a cltd if possible and doing so it profitable. */
3818 if ((optimize_size || TARGET_USE_CLTD)
3819 && true_regnum (operands[3]) == AX_REG)
3821 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3825 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3826 emit_move_insn (operands[4], operands[1]);
3828 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3832 (define_insn "extendhisi2"
3833 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3834 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3837 switch (get_attr_prefix_0f (insn))
3840 return "{cwtl|cwde}";
3842 return "movs{wl|x}\t{%1,%0|%0, %1}";
3845 [(set_attr "type" "imovx")
3846 (set_attr "mode" "SI")
3847 (set (attr "prefix_0f")
3848 ;; movsx is short decodable while cwtl is vector decoded.
3849 (if_then_else (and (eq_attr "cpu" "!k6")
3850 (eq_attr "alternative" "0"))
3852 (const_string "1")))
3854 (if_then_else (eq_attr "prefix_0f" "0")
3856 (const_string "1")))])
3858 (define_insn "*extendhisi2_zext"
3859 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3861 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3864 switch (get_attr_prefix_0f (insn))
3867 return "{cwtl|cwde}";
3869 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3872 [(set_attr "type" "imovx")
3873 (set_attr "mode" "SI")
3874 (set (attr "prefix_0f")
3875 ;; movsx is short decodable while cwtl is vector decoded.
3876 (if_then_else (and (eq_attr "cpu" "!k6")
3877 (eq_attr "alternative" "0"))
3879 (const_string "1")))
3881 (if_then_else (eq_attr "prefix_0f" "0")
3883 (const_string "1")))])
3885 (define_insn "extendqihi2"
3886 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3887 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3890 switch (get_attr_prefix_0f (insn))
3893 return "{cbtw|cbw}";
3895 return "movs{bw|x}\t{%1,%0|%0, %1}";
3898 [(set_attr "type" "imovx")
3899 (set_attr "mode" "HI")
3900 (set (attr "prefix_0f")
3901 ;; movsx is short decodable while cwtl is vector decoded.
3902 (if_then_else (and (eq_attr "cpu" "!k6")
3903 (eq_attr "alternative" "0"))
3905 (const_string "1")))
3907 (if_then_else (eq_attr "prefix_0f" "0")
3909 (const_string "1")))])
3911 (define_insn "extendqisi2"
3912 [(set (match_operand:SI 0 "register_operand" "=r")
3913 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3915 "movs{bl|x}\t{%1,%0|%0, %1}"
3916 [(set_attr "type" "imovx")
3917 (set_attr "mode" "SI")])
3919 (define_insn "*extendqisi2_zext"
3920 [(set (match_operand:DI 0 "register_operand" "=r")
3922 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3924 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3925 [(set_attr "type" "imovx")
3926 (set_attr "mode" "SI")])
3928 ;; Conversions between float and double.
3930 ;; These are all no-ops in the model used for the 80387. So just
3933 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3934 (define_insn "*dummy_extendsfdf2"
3935 [(set (match_operand:DF 0 "push_operand" "=<")
3936 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3941 [(set (match_operand:DF 0 "push_operand" "")
3942 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3944 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3945 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3948 [(set (match_operand:DF 0 "push_operand" "")
3949 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3951 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3952 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3954 (define_insn "*dummy_extendsfxf2"
3955 [(set (match_operand:XF 0 "push_operand" "=<")
3956 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3961 [(set (match_operand:XF 0 "push_operand" "")
3962 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3964 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3965 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3966 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3969 [(set (match_operand:XF 0 "push_operand" "")
3970 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3972 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3973 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3974 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3977 [(set (match_operand:XF 0 "push_operand" "")
3978 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3980 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3981 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3982 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3985 [(set (match_operand:XF 0 "push_operand" "")
3986 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3988 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3989 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3990 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3992 (define_expand "extendsfdf2"
3993 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3994 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3995 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3997 /* ??? Needed for compress_float_constant since all fp constants
3998 are LEGITIMATE_CONSTANT_P. */
3999 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4001 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4002 && standard_80387_constant_p (operands[1]) > 0)
4004 operands[1] = simplify_const_unary_operation
4005 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4006 emit_move_insn_1 (operands[0], operands[1]);
4009 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4013 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4015 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4017 We do the conversion post reload to avoid producing of 128bit spills
4018 that might lead to ICE on 32bit target. The sequence unlikely combine
4021 [(set (match_operand:DF 0 "register_operand" "")
4023 (match_operand:SF 1 "nonimmediate_operand" "")))]
4024 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4025 && reload_completed && SSE_REG_P (operands[0])"
4030 (parallel [(const_int 0) (const_int 1)]))))]
4032 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4033 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4034 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4035 Try to avoid move when unpacking can be done in source. */
4036 if (REG_P (operands[1]))
4038 /* If it is unsafe to overwrite upper half of source, we need
4039 to move to destination and unpack there. */
4040 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4041 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4042 && true_regnum (operands[0]) != true_regnum (operands[1]))
4044 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4045 emit_move_insn (tmp, operands[1]);
4048 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4049 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4052 emit_insn (gen_vec_setv4sf_0 (operands[3],
4053 CONST0_RTX (V4SFmode), operands[1]));
4056 (define_insn "*extendsfdf2_mixed"
4057 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4059 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4060 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4062 switch (which_alternative)
4066 return output_387_reg_move (insn, operands);
4069 return "cvtss2sd\t{%1, %0|%0, %1}";
4075 [(set_attr "type" "fmov,fmov,ssecvt")
4076 (set_attr "mode" "SF,XF,DF")])
4078 (define_insn "*extendsfdf2_sse"
4079 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4080 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4081 "TARGET_SSE2 && TARGET_SSE_MATH"
4082 "cvtss2sd\t{%1, %0|%0, %1}"
4083 [(set_attr "type" "ssecvt")
4084 (set_attr "mode" "DF")])
4086 (define_insn "*extendsfdf2_i387"
4087 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4088 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4090 "* return output_387_reg_move (insn, operands);"
4091 [(set_attr "type" "fmov")
4092 (set_attr "mode" "SF,XF")])
4094 (define_expand "extend<mode>xf2"
4095 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4096 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4099 /* ??? Needed for compress_float_constant since all fp constants
4100 are LEGITIMATE_CONSTANT_P. */
4101 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4103 if (standard_80387_constant_p (operands[1]) > 0)
4105 operands[1] = simplify_const_unary_operation
4106 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4107 emit_move_insn_1 (operands[0], operands[1]);
4110 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4114 (define_insn "*extend<mode>xf2_i387"
4115 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4117 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4119 "* return output_387_reg_move (insn, operands);"
4120 [(set_attr "type" "fmov")
4121 (set_attr "mode" "<MODE>,XF")])
4123 ;; %%% This seems bad bad news.
4124 ;; This cannot output into an f-reg because there is no way to be sure
4125 ;; of truncating in that case. Otherwise this is just like a simple move
4126 ;; insn. So we pretend we can output to a reg in order to get better
4127 ;; register preferencing, but we really use a stack slot.
4129 ;; Conversion from DFmode to SFmode.
4131 (define_expand "truncdfsf2"
4132 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4134 (match_operand:DF 1 "nonimmediate_operand" "")))]
4135 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4137 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4139 else if (flag_unsafe_math_optimizations)
4143 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4144 rtx temp = assign_386_stack_local (SFmode, slot);
4145 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4150 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4152 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4154 We do the conversion post reload to avoid producing of 128bit spills
4155 that might lead to ICE on 32bit target. The sequence unlikely combine
4158 [(set (match_operand:SF 0 "register_operand" "")
4160 (match_operand:DF 1 "nonimmediate_operand" "")))]
4161 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4162 && reload_completed && SSE_REG_P (operands[0])"
4165 (float_truncate:V2SF
4169 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4170 operands[3] = CONST0_RTX (V2SFmode);
4171 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4172 /* Use movsd for loading from memory, unpcklpd for registers.
4173 Try to avoid move when unpacking can be done in source, or SSE3
4174 movddup is available. */
4175 if (REG_P (operands[1]))
4178 && true_regnum (operands[0]) != true_regnum (operands[1])
4179 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4180 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4182 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4183 emit_move_insn (tmp, operands[1]);
4186 else if (!TARGET_SSE3)
4187 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4188 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4191 emit_insn (gen_sse2_loadlpd (operands[4],
4192 CONST0_RTX (V2DFmode), operands[1]));
4195 (define_expand "truncdfsf2_with_temp"
4196 [(parallel [(set (match_operand:SF 0 "" "")
4197 (float_truncate:SF (match_operand:DF 1 "" "")))
4198 (clobber (match_operand:SF 2 "" ""))])]
4201 (define_insn "*truncdfsf_fast_mixed"
4202 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4204 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4205 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4207 switch (which_alternative)
4211 return output_387_reg_move (insn, operands);
4213 return "cvtsd2ss\t{%1, %0|%0, %1}";
4218 [(set_attr "type" "fmov,fmov,ssecvt")
4219 (set_attr "mode" "SF")])
4221 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4222 ;; because nothing we do here is unsafe.
4223 (define_insn "*truncdfsf_fast_sse"
4224 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4226 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4227 "TARGET_SSE2 && TARGET_SSE_MATH"
4228 "cvtsd2ss\t{%1, %0|%0, %1}"
4229 [(set_attr "type" "ssecvt")
4230 (set_attr "mode" "SF")])
4232 (define_insn "*truncdfsf_fast_i387"
4233 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4235 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4236 "TARGET_80387 && flag_unsafe_math_optimizations"
4237 "* return output_387_reg_move (insn, operands);"
4238 [(set_attr "type" "fmov")
4239 (set_attr "mode" "SF")])
4241 (define_insn "*truncdfsf_mixed"
4242 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4244 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4245 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4246 "TARGET_MIX_SSE_I387"
4248 switch (which_alternative)
4251 return output_387_reg_move (insn, operands);
4256 return "cvtsd2ss\t{%1, %0|%0, %1}";
4261 [(set_attr "type" "fmov,multi,ssecvt")
4262 (set_attr "unit" "*,i387,*")
4263 (set_attr "mode" "SF")])
4265 (define_insn "*truncdfsf_i387"
4266 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4268 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4269 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4272 switch (which_alternative)
4275 return output_387_reg_move (insn, operands);
4283 [(set_attr "type" "fmov,multi")
4284 (set_attr "unit" "*,i387")
4285 (set_attr "mode" "SF")])
4287 (define_insn "*truncdfsf2_i387_1"
4288 [(set (match_operand:SF 0 "memory_operand" "=m")
4290 (match_operand:DF 1 "register_operand" "f")))]
4292 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4293 && !TARGET_MIX_SSE_I387"
4294 "* return output_387_reg_move (insn, operands);"
4295 [(set_attr "type" "fmov")
4296 (set_attr "mode" "SF")])
4299 [(set (match_operand:SF 0 "register_operand" "")
4301 (match_operand:DF 1 "fp_register_operand" "")))
4302 (clobber (match_operand 2 "" ""))]
4304 [(set (match_dup 2) (match_dup 1))
4305 (set (match_dup 0) (match_dup 2))]
4307 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4310 ;; Conversion from XFmode to {SF,DF}mode
4312 (define_expand "truncxf<mode>2"
4313 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4314 (float_truncate:MODEF
4315 (match_operand:XF 1 "register_operand" "")))
4316 (clobber (match_dup 2))])]
4319 if (flag_unsafe_math_optimizations)
4321 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4322 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4323 if (reg != operands[0])
4324 emit_move_insn (operands[0], reg);
4329 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4330 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4334 (define_insn "*truncxfsf2_mixed"
4335 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4337 (match_operand:XF 1 "register_operand" "f,f")))
4338 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4341 gcc_assert (!which_alternative);
4342 return output_387_reg_move (insn, operands);
4344 [(set_attr "type" "fmov,multi")
4345 (set_attr "unit" "*,i387")
4346 (set_attr "mode" "SF")])
4348 (define_insn "*truncxfdf2_mixed"
4349 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4351 (match_operand:XF 1 "register_operand" "f,f")))
4352 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4355 gcc_assert (!which_alternative);
4356 return output_387_reg_move (insn, operands);
4358 [(set_attr "type" "fmov,multi")
4359 (set_attr "unit" "*,i387")
4360 (set_attr "mode" "DF")])
4362 (define_insn "truncxf<mode>2_i387_noop"
4363 [(set (match_operand:MODEF 0 "register_operand" "=f")
4364 (float_truncate:MODEF
4365 (match_operand:XF 1 "register_operand" "f")))]
4366 "TARGET_80387 && flag_unsafe_math_optimizations"
4367 "* return output_387_reg_move (insn, operands);"
4368 [(set_attr "type" "fmov")
4369 (set_attr "mode" "<MODE>")])
4371 (define_insn "*truncxf<mode>2_i387"
4372 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4373 (float_truncate:MODEF
4374 (match_operand:XF 1 "register_operand" "f")))]
4376 "* return output_387_reg_move (insn, operands);"
4377 [(set_attr "type" "fmov")
4378 (set_attr "mode" "<MODE>")])
4381 [(set (match_operand:MODEF 0 "register_operand" "")
4382 (float_truncate:MODEF
4383 (match_operand:XF 1 "register_operand" "")))
4384 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4385 "TARGET_80387 && reload_completed"
4386 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4387 (set (match_dup 0) (match_dup 2))]
4391 [(set (match_operand:MODEF 0 "memory_operand" "")
4392 (float_truncate:MODEF
4393 (match_operand:XF 1 "register_operand" "")))
4394 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4396 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4399 ;; Signed conversion to DImode.
4401 (define_expand "fix_truncxfdi2"
4402 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4403 (fix:DI (match_operand:XF 1 "register_operand" "")))
4404 (clobber (reg:CC FLAGS_REG))])]
4409 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4414 (define_expand "fix_trunc<mode>di2"
4415 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4416 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4417 (clobber (reg:CC FLAGS_REG))])]
4418 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4421 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4423 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4426 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4428 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4429 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4430 if (out != operands[0])
4431 emit_move_insn (operands[0], out);
4436 ;; Signed conversion to SImode.
4438 (define_expand "fix_truncxfsi2"
4439 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4440 (fix:SI (match_operand:XF 1 "register_operand" "")))
4441 (clobber (reg:CC FLAGS_REG))])]
4446 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4451 (define_expand "fix_trunc<mode>si2"
4452 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4453 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4454 (clobber (reg:CC FLAGS_REG))])]
4455 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4458 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4460 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4463 if (SSE_FLOAT_MODE_P (<MODE>mode))
4465 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4466 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4467 if (out != operands[0])
4468 emit_move_insn (operands[0], out);
4473 ;; Signed conversion to HImode.
4475 (define_expand "fix_trunc<mode>hi2"
4476 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4477 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4478 (clobber (reg:CC FLAGS_REG))])]
4480 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4484 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4489 ;; Unsigned conversion to SImode.
4491 (define_expand "fixuns_trunc<mode>si2"
4493 [(set (match_operand:SI 0 "register_operand" "")
4495 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4497 (clobber (match_scratch:<ssevecmode> 3 ""))
4498 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4499 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4501 enum machine_mode mode = <MODE>mode;
4502 enum machine_mode vecmode = <ssevecmode>mode;
4503 REAL_VALUE_TYPE TWO31r;
4506 real_ldexp (&TWO31r, &dconst1, 31);
4507 two31 = const_double_from_real_value (TWO31r, mode);
4508 two31 = ix86_build_const_vector (mode, true, two31);
4509 operands[2] = force_reg (vecmode, two31);
4512 (define_insn_and_split "*fixuns_trunc<mode>_1"
4513 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4515 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4516 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4517 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4518 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4519 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4521 "&& reload_completed"
4524 ix86_split_convert_uns_si_sse (operands);
4528 ;; Unsigned conversion to HImode.
4529 ;; Without these patterns, we'll try the unsigned SI conversion which
4530 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4532 (define_expand "fixuns_trunc<mode>hi2"
4534 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4535 (set (match_operand:HI 0 "nonimmediate_operand" "")
4536 (subreg:HI (match_dup 2) 0))]
4537 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4538 "operands[2] = gen_reg_rtx (SImode);")
4540 ;; When SSE is available, it is always faster to use it!
4541 (define_insn "fix_trunc<mode>di_sse"
4542 [(set (match_operand:DI 0 "register_operand" "=r,r")
4543 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4544 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4545 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4546 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4547 [(set_attr "type" "sseicvt")
4548 (set_attr "mode" "<MODE>")
4549 (set_attr "athlon_decode" "double,vector")
4550 (set_attr "amdfam10_decode" "double,double")])
4552 (define_insn "fix_trunc<mode>si_sse"
4553 [(set (match_operand:SI 0 "register_operand" "=r,r")
4554 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4555 "SSE_FLOAT_MODE_P (<MODE>mode)
4556 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4557 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4558 [(set_attr "type" "sseicvt")
4559 (set_attr "mode" "<MODE>")
4560 (set_attr "athlon_decode" "double,vector")
4561 (set_attr "amdfam10_decode" "double,double")])
4563 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4565 [(set (match_operand:MODEF 0 "register_operand" "")
4566 (match_operand:MODEF 1 "memory_operand" ""))
4567 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4568 (fix:SSEMODEI24 (match_dup 0)))]
4569 "TARGET_SHORTEN_X87_SSE
4570 && peep2_reg_dead_p (2, operands[0])"
4571 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4574 ;; Avoid vector decoded forms of the instruction.
4576 [(match_scratch:DF 2 "Y2")
4577 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4578 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4579 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4580 [(set (match_dup 2) (match_dup 1))
4581 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4585 [(match_scratch:SF 2 "x")
4586 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4587 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4588 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4589 [(set (match_dup 2) (match_dup 1))
4590 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4593 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4594 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4595 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4596 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4599 && (TARGET_64BIT || <MODE>mode != DImode))
4601 && !(reload_completed || reload_in_progress)"
4606 if (memory_operand (operands[0], VOIDmode))
4607 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4610 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4611 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4617 [(set_attr "type" "fisttp")
4618 (set_attr "mode" "<MODE>")])
4620 (define_insn "fix_trunc<mode>_i387_fisttp"
4621 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4622 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4623 (clobber (match_scratch:XF 2 "=&1f"))]
4624 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4626 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4627 && (TARGET_64BIT || <MODE>mode != DImode))
4628 && TARGET_SSE_MATH)"
4629 "* return output_fix_trunc (insn, operands, 1);"
4630 [(set_attr "type" "fisttp")
4631 (set_attr "mode" "<MODE>")])
4633 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4634 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4635 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4636 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4637 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4638 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4640 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4641 && (TARGET_64BIT || <MODE>mode != DImode))
4642 && TARGET_SSE_MATH)"
4644 [(set_attr "type" "fisttp")
4645 (set_attr "mode" "<MODE>")])
4648 [(set (match_operand:X87MODEI 0 "register_operand" "")
4649 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4650 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4651 (clobber (match_scratch 3 ""))]
4653 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4654 (clobber (match_dup 3))])
4655 (set (match_dup 0) (match_dup 2))]
4659 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4660 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4661 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4662 (clobber (match_scratch 3 ""))]
4664 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4665 (clobber (match_dup 3))])]
4668 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4669 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4670 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4671 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4672 ;; function in i386.c.
4673 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4674 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4675 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4676 (clobber (reg:CC FLAGS_REG))]
4677 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4679 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4680 && (TARGET_64BIT || <MODE>mode != DImode))
4681 && !(reload_completed || reload_in_progress)"
4686 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4688 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4689 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4690 if (memory_operand (operands[0], VOIDmode))
4691 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4692 operands[2], operands[3]));
4695 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4696 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4697 operands[2], operands[3],
4702 [(set_attr "type" "fistp")
4703 (set_attr "i387_cw" "trunc")
4704 (set_attr "mode" "<MODE>")])
4706 (define_insn "fix_truncdi_i387"
4707 [(set (match_operand:DI 0 "memory_operand" "=m")
4708 (fix:DI (match_operand 1 "register_operand" "f")))
4709 (use (match_operand:HI 2 "memory_operand" "m"))
4710 (use (match_operand:HI 3 "memory_operand" "m"))
4711 (clobber (match_scratch:XF 4 "=&1f"))]
4712 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4714 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4715 "* return output_fix_trunc (insn, operands, 0);"
4716 [(set_attr "type" "fistp")
4717 (set_attr "i387_cw" "trunc")
4718 (set_attr "mode" "DI")])
4720 (define_insn "fix_truncdi_i387_with_temp"
4721 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4722 (fix:DI (match_operand 1 "register_operand" "f,f")))
4723 (use (match_operand:HI 2 "memory_operand" "m,m"))
4724 (use (match_operand:HI 3 "memory_operand" "m,m"))
4725 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4726 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4727 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4729 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4731 [(set_attr "type" "fistp")
4732 (set_attr "i387_cw" "trunc")
4733 (set_attr "mode" "DI")])
4736 [(set (match_operand:DI 0 "register_operand" "")
4737 (fix:DI (match_operand 1 "register_operand" "")))
4738 (use (match_operand:HI 2 "memory_operand" ""))
4739 (use (match_operand:HI 3 "memory_operand" ""))
4740 (clobber (match_operand:DI 4 "memory_operand" ""))
4741 (clobber (match_scratch 5 ""))]
4743 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4746 (clobber (match_dup 5))])
4747 (set (match_dup 0) (match_dup 4))]
4751 [(set (match_operand:DI 0 "memory_operand" "")
4752 (fix:DI (match_operand 1 "register_operand" "")))
4753 (use (match_operand:HI 2 "memory_operand" ""))
4754 (use (match_operand:HI 3 "memory_operand" ""))
4755 (clobber (match_operand:DI 4 "memory_operand" ""))
4756 (clobber (match_scratch 5 ""))]
4758 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4761 (clobber (match_dup 5))])]
4764 (define_insn "fix_trunc<mode>_i387"
4765 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4766 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4767 (use (match_operand:HI 2 "memory_operand" "m"))
4768 (use (match_operand:HI 3 "memory_operand" "m"))]
4769 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4771 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4772 "* return output_fix_trunc (insn, operands, 0);"
4773 [(set_attr "type" "fistp")
4774 (set_attr "i387_cw" "trunc")
4775 (set_attr "mode" "<MODE>")])
4777 (define_insn "fix_trunc<mode>_i387_with_temp"
4778 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4779 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4780 (use (match_operand:HI 2 "memory_operand" "m,m"))
4781 (use (match_operand:HI 3 "memory_operand" "m,m"))
4782 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4783 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4785 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4787 [(set_attr "type" "fistp")
4788 (set_attr "i387_cw" "trunc")
4789 (set_attr "mode" "<MODE>")])
4792 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4793 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4794 (use (match_operand:HI 2 "memory_operand" ""))
4795 (use (match_operand:HI 3 "memory_operand" ""))
4796 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4798 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4800 (use (match_dup 3))])
4801 (set (match_dup 0) (match_dup 4))]
4805 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4806 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4807 (use (match_operand:HI 2 "memory_operand" ""))
4808 (use (match_operand:HI 3 "memory_operand" ""))
4809 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4811 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4813 (use (match_dup 3))])]
4816 (define_insn "x86_fnstcw_1"
4817 [(set (match_operand:HI 0 "memory_operand" "=m")
4818 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4821 [(set_attr "length" "2")
4822 (set_attr "mode" "HI")
4823 (set_attr "unit" "i387")])
4825 (define_insn "x86_fldcw_1"
4826 [(set (reg:HI FPCR_REG)
4827 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4830 [(set_attr "length" "2")
4831 (set_attr "mode" "HI")
4832 (set_attr "unit" "i387")
4833 (set_attr "athlon_decode" "vector")
4834 (set_attr "amdfam10_decode" "vector")])
4836 ;; Conversion between fixed point and floating point.
4838 ;; Even though we only accept memory inputs, the backend _really_
4839 ;; wants to be able to do this between registers.
4841 (define_expand "floathi<mode>2"
4842 [(set (match_operand:X87MODEF 0 "register_operand" "")
4843 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4845 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4846 || TARGET_MIX_SSE_I387)"
4849 ;; Pre-reload splitter to add memory clobber to the pattern.
4850 (define_insn_and_split "*floathi<mode>2_1"
4851 [(set (match_operand:X87MODEF 0 "register_operand" "")
4852 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4854 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4855 || TARGET_MIX_SSE_I387)
4856 && !(reload_completed || reload_in_progress)"
4859 [(parallel [(set (match_dup 0)
4860 (float:X87MODEF (match_dup 1)))
4861 (clobber (match_dup 2))])]
4862 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4864 (define_insn "*floathi<mode>2_i387_with_temp"
4865 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4866 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4867 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4870 || TARGET_MIX_SSE_I387)"
4872 [(set_attr "type" "fmov,multi")
4873 (set_attr "mode" "<MODE>")
4874 (set_attr "unit" "*,i387")
4875 (set_attr "fp_int_src" "true")])
4877 (define_insn "*floathi<mode>2_i387"
4878 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4879 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4881 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4882 || TARGET_MIX_SSE_I387)"
4884 [(set_attr "type" "fmov")
4885 (set_attr "mode" "<MODE>")
4886 (set_attr "fp_int_src" "true")])
4889 [(set (match_operand:X87MODEF 0 "register_operand" "")
4890 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4891 (clobber (match_operand:HI 2 "memory_operand" ""))]
4893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4894 || TARGET_MIX_SSE_I387)
4895 && reload_completed"
4896 [(set (match_dup 2) (match_dup 1))
4897 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4901 [(set (match_operand:X87MODEF 0 "register_operand" "")
4902 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4903 (clobber (match_operand:HI 2 "memory_operand" ""))]
4905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4906 || TARGET_MIX_SSE_I387)
4907 && reload_completed"
4908 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4911 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4912 [(set (match_operand:X87MODEF 0 "register_operand" "")
4914 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4916 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4917 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4920 ;; Pre-reload splitter to add memory clobber to the pattern.
4921 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4922 [(set (match_operand:X87MODEF 0 "register_operand" "")
4923 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4925 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4926 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4927 || TARGET_MIX_SSE_I387))
4928 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4929 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4930 && ((<SSEMODEI24:MODE>mode == SImode
4931 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4932 && flag_trapping_math)
4933 || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4934 && !(reload_completed || reload_in_progress)"
4937 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4938 (clobber (match_dup 2))])]
4940 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4942 /* Avoid store forwarding (partial memory) stall penalty
4943 by passing DImode value through XMM registers. */
4944 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4945 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4948 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4955 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4956 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4958 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4959 (clobber (match_operand:SI 2 "memory_operand" "=m,m,m,m,m"))]
4960 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4961 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4963 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4964 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4965 (set_attr "unit" "*,i387,*,*,*")
4966 (set_attr "athlon_decode" "*,*,double,direct,double")
4967 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4968 (set_attr "fp_int_src" "true")])
4970 (define_insn "*floatsi<mode>2_vector_mixed"
4971 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4972 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4973 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4974 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4978 [(set_attr "type" "fmov,sseicvt")
4979 (set_attr "mode" "<MODE>,<ssevecmode>")
4980 (set_attr "unit" "i387,*")
4981 (set_attr "athlon_decode" "*,direct")
4982 (set_attr "amdfam10_decode" "*,double")
4983 (set_attr "fp_int_src" "true")])
4985 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4986 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4988 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4989 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m,m,m"))]
4990 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4991 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4993 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4994 (set_attr "mode" "<MODEF:MODE>")
4995 (set_attr "unit" "*,i387,*,*")
4996 (set_attr "athlon_decode" "*,*,double,direct")
4997 (set_attr "amdfam10_decode" "*,*,vector,double")
4998 (set_attr "fp_int_src" "true")])
5001 [(set (match_operand:MODEF 0 "register_operand" "")
5002 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5003 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5004 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5005 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5006 && TARGET_INTER_UNIT_CONVERSIONS
5008 && (SSE_REG_P (operands[0])
5009 || (GET_CODE (operands[0]) == SUBREG
5010 && SSE_REG_P (operands[0])))"
5011 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5015 [(set (match_operand:MODEF 0 "register_operand" "")
5016 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5017 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5018 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5019 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5020 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5022 && (SSE_REG_P (operands[0])
5023 || (GET_CODE (operands[0]) == SUBREG
5024 && SSE_REG_P (operands[0])))"
5025 [(set (match_dup 2) (match_dup 1))
5026 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5029 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5030 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5032 (match_operand:SSEMODEI24 1 "register_operand" "m,r,m")))]
5033 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5034 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5035 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5038 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5039 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5040 [(set_attr "type" "fmov,sseicvt,sseicvt")
5041 (set_attr "mode" "<MODEF:MODE>")
5042 (set_attr "unit" "i387,*,*")
5043 (set_attr "athlon_decode" "*,double,direct")
5044 (set_attr "amdfam10_decode" "*,vector,double")
5045 (set_attr "fp_int_src" "true")])
5047 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5048 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5050 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5051 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5052 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5053 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5056 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5057 [(set_attr "type" "fmov,sseicvt")
5058 (set_attr "mode" "<MODEF:MODE>")
5059 (set_attr "athlon_decode" "*,direct")
5060 (set_attr "amdfam10_decode" "*,double")
5061 (set_attr "fp_int_src" "true")])
5063 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5064 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5066 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5067 (clobber (match_operand:SI 2 "memory_operand" "=m,m,m"))]
5068 "TARGET_SSE2 && TARGET_SSE_MATH
5069 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5071 [(set_attr "type" "sseicvt")
5072 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5073 (set_attr "athlon_decode" "double,direct,double")
5074 (set_attr "amdfam10_decode" "vector,double,double")
5075 (set_attr "fp_int_src" "true")])
5077 (define_insn "*floatsi<mode>2_vector_sse"
5078 [(set (match_operand:MODEF 0 "register_operand" "=x")
5079 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5080 "TARGET_SSE2 && TARGET_SSE_MATH
5081 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5083 [(set_attr "type" "sseicvt")
5084 (set_attr "mode" "<MODE>")
5085 (set_attr "athlon_decode" "direct")
5086 (set_attr "amdfam10_decode" "double")
5087 (set_attr "fp_int_src" "true")])
5090 [(set (match_operand:MODEF 0 "register_operand" "")
5091 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5092 (clobber (match_operand:SI 2 "memory_operand" ""))]
5093 "TARGET_SSE2 && TARGET_SSE_MATH
5094 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5096 && (SSE_REG_P (operands[0])
5097 || (GET_CODE (operands[0]) == SUBREG
5098 && SSE_REG_P (operands[0])))"
5101 rtx op1 = operands[1];
5103 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5105 if (GET_CODE (op1) == SUBREG)
5106 op1 = SUBREG_REG (op1);
5108 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5110 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5111 emit_insn (gen_sse2_loadld (operands[4],
5112 CONST0_RTX (V4SImode), operands[1]));
5114 /* We can ignore possible trapping value in the
5115 high part of SSE register for non-trapping math. */
5116 else if (SSE_REG_P (op1) && !flag_trapping_math)
5117 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5120 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5121 emit_move_insn (operands[2], operands[1]);
5122 emit_insn (gen_sse2_loadld (operands[4],
5123 CONST0_RTX (V4SImode), operands[2]));
5126 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5131 [(set (match_operand:MODEF 0 "register_operand" "")
5132 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5133 (clobber (match_operand:SI 2 "memory_operand" ""))]
5134 "TARGET_SSE2 && TARGET_SSE_MATH
5135 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5137 && (SSE_REG_P (operands[0])
5138 || (GET_CODE (operands[0]) == SUBREG
5139 && SSE_REG_P (operands[0])))"
5142 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5144 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5146 emit_insn (gen_sse2_loadld (operands[4],
5147 CONST0_RTX (V4SImode), operands[1]));
5149 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5154 [(set (match_operand:MODEF 0 "register_operand" "")
5155 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5156 "TARGET_SSE2 && TARGET_SSE_MATH
5157 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5159 && (SSE_REG_P (operands[0])
5160 || (GET_CODE (operands[0]) == SUBREG
5161 && SSE_REG_P (operands[0])))"
5164 rtx op1 = operands[1];
5166 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5168 if (GET_CODE (op1) == SUBREG)
5169 op1 = SUBREG_REG (op1);
5171 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5173 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5174 emit_insn (gen_sse2_loadld (operands[4],
5175 CONST0_RTX (V4SImode), operands[1]));
5177 /* We can ignore possible trapping value in the
5178 high part of SSE register for non-trapping math. */
5179 else if (SSE_REG_P (op1) && !flag_trapping_math)
5180 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5186 [(set (match_operand:MODEF 0 "register_operand" "")
5187 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5188 "TARGET_SSE2 && TARGET_SSE_MATH
5189 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5191 && (SSE_REG_P (operands[0])
5192 || (GET_CODE (operands[0]) == SUBREG
5193 && SSE_REG_P (operands[0])))"
5196 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5198 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5200 emit_insn (gen_sse2_loadld (operands[4],
5201 CONST0_RTX (V4SImode), operands[1]));
5203 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5207 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5208 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5210 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5211 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m"))]
5212 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5213 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5215 [(set_attr "type" "sseicvt")
5216 (set_attr "mode" "<MODEF:MODE>")
5217 (set_attr "athlon_decode" "double,direct")
5218 (set_attr "amdfam10_decode" "vector,double")
5219 (set_attr "fp_int_src" "true")])
5221 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5222 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5224 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5225 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5226 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5227 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5229 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5230 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5231 [(set_attr "type" "sseicvt")
5232 (set_attr "mode" "<MODEF:MODE>")
5233 (set_attr "athlon_decode" "double,direct")
5234 (set_attr "amdfam10_decode" "vector,double")
5235 (set_attr "fp_int_src" "true")])
5238 [(set (match_operand:MODEF 0 "register_operand" "")
5239 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5240 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5241 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5242 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5243 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5245 && (SSE_REG_P (operands[0])
5246 || (GET_CODE (operands[0]) == SUBREG
5247 && SSE_REG_P (operands[0])))"
5248 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5251 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5252 [(set (match_operand:MODEF 0 "register_operand" "=x")
5254 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5255 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5256 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5257 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5258 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5259 [(set_attr "type" "sseicvt")
5260 (set_attr "mode" "<MODEF:MODE>")
5261 (set_attr "athlon_decode" "direct")
5262 (set_attr "amdfam10_decode" "double")
5263 (set_attr "fp_int_src" "true")])
5266 [(set (match_operand:MODEF 0 "register_operand" "")
5267 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5268 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5269 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5270 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5271 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5273 && (SSE_REG_P (operands[0])
5274 || (GET_CODE (operands[0]) == SUBREG
5275 && SSE_REG_P (operands[0])))"
5276 [(set (match_dup 2) (match_dup 1))
5277 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5281 [(set (match_operand:MODEF 0 "register_operand" "")
5282 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5283 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5284 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5285 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5287 && (SSE_REG_P (operands[0])
5288 || (GET_CODE (operands[0]) == SUBREG
5289 && SSE_REG_P (operands[0])))"
5290 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5293 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5294 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5296 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5297 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,m"))]
5302 [(set_attr "type" "fmov,multi")
5303 (set_attr "mode" "<X87MODEF:MODE>")
5304 (set_attr "unit" "*,i387")
5305 (set_attr "fp_int_src" "true")])
5307 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5308 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5310 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5313 [(set_attr "type" "fmov")
5314 (set_attr "mode" "<X87MODEF:MODE>")
5315 (set_attr "fp_int_src" "true")])
5318 [(set (match_operand:X87MODEF 0 "register_operand" "")
5319 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5320 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5323 && FP_REG_P (operands[0])"
5324 [(set (match_dup 2) (match_dup 1))
5325 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5329 [(set (match_operand:X87MODEF 0 "register_operand" "")
5330 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5331 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5334 && FP_REG_P (operands[0])"
5335 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5338 ;; Avoid store forwarding (partial memory) stall penalty
5339 ;; by passing DImode value through XMM registers. */
5341 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5342 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5344 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5345 (clobber (match_scratch:V4SI 3 "=&x,x"))
5346 (clobber (match_scratch:V4SI 4 "=&x,x"))
5347 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))]
5348 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5349 && !TARGET_64BIT && !optimize_size"
5351 [(set_attr "type" "multi")
5352 (set_attr "mode" "<X87MODEF:MODE>")
5353 (set_attr "unit" "i387")
5354 (set_attr "fp_int_src" "true")])
5357 [(set (match_operand:X87MODEF 0 "register_operand" "")
5358 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5359 (clobber (match_operand:V4SI 3 "register_operand" ""))
5360 (clobber (match_operand:V4SI 4 "register_operand" ""))
5361 (clobber (match_operand:DI 2 "memory_operand" ""))]
5362 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5363 && !TARGET_64BIT && !optimize_size
5365 && FP_REG_P (operands[0])"
5366 [(set (match_dup 2) (match_dup 3))
5367 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5369 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5370 Assemble the 64-bit DImode value in an xmm register. */
5371 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5372 gen_rtx_SUBREG (SImode, operands[1], 0)));
5373 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5374 gen_rtx_SUBREG (SImode, operands[1], 4)));
5375 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5377 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5381 [(set (match_operand:X87MODEF 0 "register_operand" "")
5382 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5383 (clobber (match_operand:V4SI 2 "register_operand" ""))
5384 (clobber (match_operand:V4SI 3 "register_operand" ""))
5385 (clobber (match_operand:DI 4 "memory_operand" ""))]
5386 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5387 && !TARGET_64BIT && !optimize_size
5389 && FP_REG_P (operands[0])"
5390 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5393 ;; Avoid store forwarding (partial memory) stall penalty by extending
5394 ;; SImode value to DImode through XMM register instead of pushing two
5395 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5396 ;; targets benefit from this optimization. Also note that fild
5397 ;; loads from memory only.
5399 (define_insn "*floatunssi<mode>2_1"
5400 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5401 (unsigned_float:X87MODEF
5402 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5403 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5404 (clobber (match_scratch:SI 3 "=X,x"))]
5406 && TARGET_80387 && TARGET_SSE"
5408 [(set_attr "type" "multi")
5409 (set_attr "mode" "<MODE>")])
5412 [(set (match_operand:X87MODEF 0 "register_operand" "")
5413 (unsigned_float:X87MODEF
5414 (match_operand:SI 1 "register_operand" "")))
5415 (clobber (match_operand:DI 2 "memory_operand" ""))
5416 (clobber (match_scratch:SI 3 ""))]
5418 && TARGET_80387 && TARGET_SSE
5419 && reload_completed"
5420 [(set (match_dup 2) (match_dup 1))
5422 (float:X87MODEF (match_dup 2)))]
5423 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5426 [(set (match_operand:X87MODEF 0 "register_operand" "")
5427 (unsigned_float:X87MODEF
5428 (match_operand:SI 1 "memory_operand" "")))
5429 (clobber (match_operand:DI 2 "memory_operand" ""))
5430 (clobber (match_scratch:SI 3 ""))]
5432 && TARGET_80387 && TARGET_SSE
5433 && reload_completed"
5434 [(set (match_dup 2) (match_dup 3))
5436 (float:X87MODEF (match_dup 2)))]
5438 emit_move_insn (operands[3], operands[1]);
5439 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5442 (define_expand "floatunssi<mode>2"
5444 [(set (match_operand:X87MODEF 0 "register_operand" "")
5445 (unsigned_float:X87MODEF
5446 (match_operand:SI 1 "nonimmediate_operand" "")))
5447 (clobber (match_dup 2))
5448 (clobber (match_scratch:SI 3 ""))])]
5450 && ((TARGET_80387 && TARGET_SSE)
5451 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5453 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5455 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5460 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5461 operands[2] = assign_386_stack_local (DImode, slot);
5465 (define_expand "floatunsdisf2"
5466 [(use (match_operand:SF 0 "register_operand" ""))
5467 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5468 "TARGET_64BIT && TARGET_SSE_MATH"
5469 "x86_emit_floatuns (operands); DONE;")
5471 (define_expand "floatunsdidf2"
5472 [(use (match_operand:DF 0 "register_operand" ""))
5473 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5474 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5475 && TARGET_SSE2 && TARGET_SSE_MATH"
5478 x86_emit_floatuns (operands);
5480 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5486 ;; %%% splits for addditi3
5488 (define_expand "addti3"
5489 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5490 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5491 (match_operand:TI 2 "x86_64_general_operand" "")))
5492 (clobber (reg:CC FLAGS_REG))]
5494 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5496 (define_insn "*addti3_1"
5497 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5498 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5499 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5500 (clobber (reg:CC FLAGS_REG))]
5501 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5505 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5506 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5507 (match_operand:TI 2 "x86_64_general_operand" "")))
5508 (clobber (reg:CC FLAGS_REG))]
5509 "TARGET_64BIT && reload_completed"
5510 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5512 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5513 (parallel [(set (match_dup 3)
5514 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5517 (clobber (reg:CC FLAGS_REG))])]
5518 "split_ti (operands+0, 1, operands+0, operands+3);
5519 split_ti (operands+1, 1, operands+1, operands+4);
5520 split_ti (operands+2, 1, operands+2, operands+5);")
5522 ;; %%% splits for addsidi3
5523 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5524 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5525 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5527 (define_expand "adddi3"
5528 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5529 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5530 (match_operand:DI 2 "x86_64_general_operand" "")))
5531 (clobber (reg:CC FLAGS_REG))]
5533 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5535 (define_insn "*adddi3_1"
5536 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5537 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5538 (match_operand:DI 2 "general_operand" "roiF,riF")))
5539 (clobber (reg:CC FLAGS_REG))]
5540 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5544 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5545 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5546 (match_operand:DI 2 "general_operand" "")))
5547 (clobber (reg:CC FLAGS_REG))]
5548 "!TARGET_64BIT && reload_completed"
5549 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5551 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5552 (parallel [(set (match_dup 3)
5553 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5556 (clobber (reg:CC FLAGS_REG))])]
5557 "split_di (operands+0, 1, operands+0, operands+3);
5558 split_di (operands+1, 1, operands+1, operands+4);
5559 split_di (operands+2, 1, operands+2, operands+5);")
5561 (define_insn "adddi3_carry_rex64"
5562 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5563 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5564 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5565 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5566 (clobber (reg:CC FLAGS_REG))]
5567 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5568 "adc{q}\t{%2, %0|%0, %2}"
5569 [(set_attr "type" "alu")
5570 (set_attr "pent_pair" "pu")
5571 (set_attr "mode" "DI")])
5573 (define_insn "*adddi3_cc_rex64"
5574 [(set (reg:CC FLAGS_REG)
5575 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5576 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5578 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5579 (plus:DI (match_dup 1) (match_dup 2)))]
5580 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5581 "add{q}\t{%2, %0|%0, %2}"
5582 [(set_attr "type" "alu")
5583 (set_attr "mode" "DI")])
5585 (define_insn "*<addsub><mode>3_cc_overflow"
5586 [(set (reg:CCC FLAGS_REG)
5589 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5590 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5592 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5593 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5594 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5595 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5596 [(set_attr "type" "alu")
5597 (set_attr "mode" "<MODE>")])
5599 (define_insn "*add<mode>3_cconly_overflow"
5600 [(set (reg:CCC FLAGS_REG)
5602 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5603 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5605 (clobber (match_scratch:SWI 0 "=<r>"))]
5606 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5607 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5608 [(set_attr "type" "alu")
5609 (set_attr "mode" "<MODE>")])
5611 (define_insn "*sub<mode>3_cconly_overflow"
5612 [(set (reg:CCC FLAGS_REG)
5614 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5615 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5618 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5619 [(set_attr "type" "icmp")
5620 (set_attr "mode" "<MODE>")])
5622 (define_insn "*<addsub>si3_zext_cc_overflow"
5623 [(set (reg:CCC FLAGS_REG)
5625 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5626 (match_operand:SI 2 "general_operand" "g"))
5628 (set (match_operand:DI 0 "register_operand" "=r")
5629 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5630 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5631 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5632 [(set_attr "type" "alu")
5633 (set_attr "mode" "SI")])
5635 (define_insn "addqi3_carry"
5636 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5637 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5638 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5639 (match_operand:QI 2 "general_operand" "qi,qm")))
5640 (clobber (reg:CC FLAGS_REG))]
5641 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5642 "adc{b}\t{%2, %0|%0, %2}"
5643 [(set_attr "type" "alu")
5644 (set_attr "pent_pair" "pu")
5645 (set_attr "mode" "QI")])
5647 (define_insn "addhi3_carry"
5648 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5649 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5650 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5651 (match_operand:HI 2 "general_operand" "ri,rm")))
5652 (clobber (reg:CC FLAGS_REG))]
5653 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5654 "adc{w}\t{%2, %0|%0, %2}"
5655 [(set_attr "type" "alu")
5656 (set_attr "pent_pair" "pu")
5657 (set_attr "mode" "HI")])
5659 (define_insn "addsi3_carry"
5660 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5661 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5662 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5663 (match_operand:SI 2 "general_operand" "ri,rm")))
5664 (clobber (reg:CC FLAGS_REG))]
5665 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5666 "adc{l}\t{%2, %0|%0, %2}"
5667 [(set_attr "type" "alu")
5668 (set_attr "pent_pair" "pu")
5669 (set_attr "mode" "SI")])
5671 (define_insn "*addsi3_carry_zext"
5672 [(set (match_operand:DI 0 "register_operand" "=r")
5674 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5675 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5676 (match_operand:SI 2 "general_operand" "g"))))
5677 (clobber (reg:CC FLAGS_REG))]
5678 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5679 "adc{l}\t{%2, %k0|%k0, %2}"
5680 [(set_attr "type" "alu")
5681 (set_attr "pent_pair" "pu")
5682 (set_attr "mode" "SI")])
5684 (define_insn "*addsi3_cc"
5685 [(set (reg:CC FLAGS_REG)
5686 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5687 (match_operand:SI 2 "general_operand" "ri,rm")]
5689 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5690 (plus:SI (match_dup 1) (match_dup 2)))]
5691 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5692 "add{l}\t{%2, %0|%0, %2}"
5693 [(set_attr "type" "alu")
5694 (set_attr "mode" "SI")])
5696 (define_insn "addqi3_cc"
5697 [(set (reg:CC FLAGS_REG)
5698 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5699 (match_operand:QI 2 "general_operand" "qi,qm")]
5701 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5702 (plus:QI (match_dup 1) (match_dup 2)))]
5703 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5704 "add{b}\t{%2, %0|%0, %2}"
5705 [(set_attr "type" "alu")
5706 (set_attr "mode" "QI")])
5708 (define_expand "addsi3"
5709 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5710 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5711 (match_operand:SI 2 "general_operand" "")))
5712 (clobber (reg:CC FLAGS_REG))])]
5714 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5716 (define_insn "*lea_1"
5717 [(set (match_operand:SI 0 "register_operand" "=r")
5718 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5720 "lea{l}\t{%a1, %0|%0, %a1}"
5721 [(set_attr "type" "lea")
5722 (set_attr "mode" "SI")])
5724 (define_insn "*lea_1_rex64"
5725 [(set (match_operand:SI 0 "register_operand" "=r")
5726 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5728 "lea{l}\t{%a1, %0|%0, %a1}"
5729 [(set_attr "type" "lea")
5730 (set_attr "mode" "SI")])
5732 (define_insn "*lea_1_zext"
5733 [(set (match_operand:DI 0 "register_operand" "=r")
5735 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5737 "lea{l}\t{%a1, %k0|%k0, %a1}"
5738 [(set_attr "type" "lea")
5739 (set_attr "mode" "SI")])
5741 (define_insn "*lea_2_rex64"
5742 [(set (match_operand:DI 0 "register_operand" "=r")
5743 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5745 "lea{q}\t{%a1, %0|%0, %a1}"
5746 [(set_attr "type" "lea")
5747 (set_attr "mode" "DI")])
5749 ;; The lea patterns for non-Pmodes needs to be matched by several
5750 ;; insns converted to real lea by splitters.
5752 (define_insn_and_split "*lea_general_1"
5753 [(set (match_operand 0 "register_operand" "=r")
5754 (plus (plus (match_operand 1 "index_register_operand" "l")
5755 (match_operand 2 "register_operand" "r"))
5756 (match_operand 3 "immediate_operand" "i")))]
5757 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5758 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5759 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5760 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5761 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5762 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5763 || GET_MODE (operands[3]) == VOIDmode)"
5765 "&& reload_completed"
5769 operands[0] = gen_lowpart (SImode, operands[0]);
5770 operands[1] = gen_lowpart (Pmode, operands[1]);
5771 operands[2] = gen_lowpart (Pmode, operands[2]);
5772 operands[3] = gen_lowpart (Pmode, operands[3]);
5773 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5775 if (Pmode != SImode)
5776 pat = gen_rtx_SUBREG (SImode, pat, 0);
5777 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5780 [(set_attr "type" "lea")
5781 (set_attr "mode" "SI")])
5783 (define_insn_and_split "*lea_general_1_zext"
5784 [(set (match_operand:DI 0 "register_operand" "=r")
5786 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5787 (match_operand:SI 2 "register_operand" "r"))
5788 (match_operand:SI 3 "immediate_operand" "i"))))]
5791 "&& reload_completed"
5793 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5795 (match_dup 3)) 0)))]
5797 operands[1] = gen_lowpart (Pmode, operands[1]);
5798 operands[2] = gen_lowpart (Pmode, operands[2]);
5799 operands[3] = gen_lowpart (Pmode, operands[3]);
5801 [(set_attr "type" "lea")
5802 (set_attr "mode" "SI")])
5804 (define_insn_and_split "*lea_general_2"
5805 [(set (match_operand 0 "register_operand" "=r")
5806 (plus (mult (match_operand 1 "index_register_operand" "l")
5807 (match_operand 2 "const248_operand" "i"))
5808 (match_operand 3 "nonmemory_operand" "ri")))]
5809 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5810 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5811 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5812 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5813 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5814 || GET_MODE (operands[3]) == VOIDmode)"
5816 "&& reload_completed"
5820 operands[0] = gen_lowpart (SImode, operands[0]);
5821 operands[1] = gen_lowpart (Pmode, operands[1]);
5822 operands[3] = gen_lowpart (Pmode, operands[3]);
5823 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5825 if (Pmode != SImode)
5826 pat = gen_rtx_SUBREG (SImode, pat, 0);
5827 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5830 [(set_attr "type" "lea")
5831 (set_attr "mode" "SI")])
5833 (define_insn_and_split "*lea_general_2_zext"
5834 [(set (match_operand:DI 0 "register_operand" "=r")
5836 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5837 (match_operand:SI 2 "const248_operand" "n"))
5838 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5841 "&& reload_completed"
5843 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5845 (match_dup 3)) 0)))]
5847 operands[1] = gen_lowpart (Pmode, operands[1]);
5848 operands[3] = gen_lowpart (Pmode, operands[3]);
5850 [(set_attr "type" "lea")
5851 (set_attr "mode" "SI")])
5853 (define_insn_and_split "*lea_general_3"
5854 [(set (match_operand 0 "register_operand" "=r")
5855 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5856 (match_operand 2 "const248_operand" "i"))
5857 (match_operand 3 "register_operand" "r"))
5858 (match_operand 4 "immediate_operand" "i")))]
5859 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5860 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5861 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5862 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5863 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5865 "&& reload_completed"
5869 operands[0] = gen_lowpart (SImode, operands[0]);
5870 operands[1] = gen_lowpart (Pmode, operands[1]);
5871 operands[3] = gen_lowpart (Pmode, operands[3]);
5872 operands[4] = gen_lowpart (Pmode, operands[4]);
5873 pat = gen_rtx_PLUS (Pmode,
5874 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5878 if (Pmode != SImode)
5879 pat = gen_rtx_SUBREG (SImode, pat, 0);
5880 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5883 [(set_attr "type" "lea")
5884 (set_attr "mode" "SI")])
5886 (define_insn_and_split "*lea_general_3_zext"
5887 [(set (match_operand:DI 0 "register_operand" "=r")
5889 (plus:SI (plus:SI (mult:SI
5890 (match_operand:SI 1 "index_register_operand" "l")
5891 (match_operand:SI 2 "const248_operand" "n"))
5892 (match_operand:SI 3 "register_operand" "r"))
5893 (match_operand:SI 4 "immediate_operand" "i"))))]
5896 "&& reload_completed"
5898 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5901 (match_dup 4)) 0)))]
5903 operands[1] = gen_lowpart (Pmode, operands[1]);
5904 operands[3] = gen_lowpart (Pmode, operands[3]);
5905 operands[4] = gen_lowpart (Pmode, operands[4]);
5907 [(set_attr "type" "lea")
5908 (set_attr "mode" "SI")])
5910 (define_insn "*adddi_1_rex64"
5911 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5912 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5913 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5914 (clobber (reg:CC FLAGS_REG))]
5915 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5917 switch (get_attr_type (insn))
5920 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5921 return "lea{q}\t{%a2, %0|%0, %a2}";
5924 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5925 if (operands[2] == const1_rtx)
5926 return "inc{q}\t%0";
5929 gcc_assert (operands[2] == constm1_rtx);
5930 return "dec{q}\t%0";
5934 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5936 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5937 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5938 if (CONST_INT_P (operands[2])
5939 /* Avoid overflows. */
5940 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5941 && (INTVAL (operands[2]) == 128
5942 || (INTVAL (operands[2]) < 0
5943 && INTVAL (operands[2]) != -128)))
5945 operands[2] = GEN_INT (-INTVAL (operands[2]));
5946 return "sub{q}\t{%2, %0|%0, %2}";
5948 return "add{q}\t{%2, %0|%0, %2}";
5952 (cond [(eq_attr "alternative" "2")
5953 (const_string "lea")
5954 ; Current assemblers are broken and do not allow @GOTOFF in
5955 ; ought but a memory context.
5956 (match_operand:DI 2 "pic_symbolic_operand" "")
5957 (const_string "lea")
5958 (match_operand:DI 2 "incdec_operand" "")
5959 (const_string "incdec")
5961 (const_string "alu")))
5962 (set_attr "mode" "DI")])
5964 ;; Convert lea to the lea pattern to avoid flags dependency.
5966 [(set (match_operand:DI 0 "register_operand" "")
5967 (plus:DI (match_operand:DI 1 "register_operand" "")
5968 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5969 (clobber (reg:CC FLAGS_REG))]
5970 "TARGET_64BIT && reload_completed
5971 && true_regnum (operands[0]) != true_regnum (operands[1])"
5973 (plus:DI (match_dup 1)
5977 (define_insn "*adddi_2_rex64"
5978 [(set (reg FLAGS_REG)
5980 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5981 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5983 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5984 (plus:DI (match_dup 1) (match_dup 2)))]
5985 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5986 && ix86_binary_operator_ok (PLUS, DImode, operands)
5987 /* Current assemblers are broken and do not allow @GOTOFF in
5988 ought but a memory context. */
5989 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5991 switch (get_attr_type (insn))
5994 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5995 if (operands[2] == const1_rtx)
5996 return "inc{q}\t%0";
5999 gcc_assert (operands[2] == constm1_rtx);
6000 return "dec{q}\t%0";
6004 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6005 /* ???? We ought to handle there the 32bit case too
6006 - do we need new constraint? */
6007 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6008 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6009 if (CONST_INT_P (operands[2])
6010 /* Avoid overflows. */
6011 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6012 && (INTVAL (operands[2]) == 128
6013 || (INTVAL (operands[2]) < 0
6014 && INTVAL (operands[2]) != -128)))
6016 operands[2] = GEN_INT (-INTVAL (operands[2]));
6017 return "sub{q}\t{%2, %0|%0, %2}";
6019 return "add{q}\t{%2, %0|%0, %2}";
6023 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6024 (const_string "incdec")
6025 (const_string "alu")))
6026 (set_attr "mode" "DI")])
6028 (define_insn "*adddi_3_rex64"
6029 [(set (reg FLAGS_REG)
6030 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6031 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6032 (clobber (match_scratch:DI 0 "=r"))]
6034 && ix86_match_ccmode (insn, CCZmode)
6035 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6036 /* Current assemblers are broken and do not allow @GOTOFF in
6037 ought but a memory context. */
6038 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6040 switch (get_attr_type (insn))
6043 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6044 if (operands[2] == const1_rtx)
6045 return "inc{q}\t%0";
6048 gcc_assert (operands[2] == constm1_rtx);
6049 return "dec{q}\t%0";
6053 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6054 /* ???? We ought to handle there the 32bit case too
6055 - do we need new constraint? */
6056 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6057 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6058 if (CONST_INT_P (operands[2])
6059 /* Avoid overflows. */
6060 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6061 && (INTVAL (operands[2]) == 128
6062 || (INTVAL (operands[2]) < 0
6063 && INTVAL (operands[2]) != -128)))
6065 operands[2] = GEN_INT (-INTVAL (operands[2]));
6066 return "sub{q}\t{%2, %0|%0, %2}";
6068 return "add{q}\t{%2, %0|%0, %2}";
6072 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6073 (const_string "incdec")
6074 (const_string "alu")))
6075 (set_attr "mode" "DI")])
6077 ; For comparisons against 1, -1 and 128, we may generate better code
6078 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6079 ; is matched then. We can't accept general immediate, because for
6080 ; case of overflows, the result is messed up.
6081 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6083 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6084 ; only for comparisons not depending on it.
6085 (define_insn "*adddi_4_rex64"
6086 [(set (reg FLAGS_REG)
6087 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6088 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6089 (clobber (match_scratch:DI 0 "=rm"))]
6091 && ix86_match_ccmode (insn, CCGCmode)"
6093 switch (get_attr_type (insn))
6096 if (operands[2] == constm1_rtx)
6097 return "inc{q}\t%0";
6100 gcc_assert (operands[2] == const1_rtx);
6101 return "dec{q}\t%0";
6105 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6106 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6107 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6108 if ((INTVAL (operands[2]) == -128
6109 || (INTVAL (operands[2]) > 0
6110 && INTVAL (operands[2]) != 128))
6111 /* Avoid overflows. */
6112 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6113 return "sub{q}\t{%2, %0|%0, %2}";
6114 operands[2] = GEN_INT (-INTVAL (operands[2]));
6115 return "add{q}\t{%2, %0|%0, %2}";
6119 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6120 (const_string "incdec")
6121 (const_string "alu")))
6122 (set_attr "mode" "DI")])
6124 (define_insn "*adddi_5_rex64"
6125 [(set (reg FLAGS_REG)
6127 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6128 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6130 (clobber (match_scratch:DI 0 "=r"))]
6132 && ix86_match_ccmode (insn, CCGOCmode)
6133 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6134 /* Current assemblers are broken and do not allow @GOTOFF in
6135 ought but a memory context. */
6136 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6138 switch (get_attr_type (insn))
6141 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6142 if (operands[2] == const1_rtx)
6143 return "inc{q}\t%0";
6146 gcc_assert (operands[2] == constm1_rtx);
6147 return "dec{q}\t%0";
6151 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6152 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6153 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6154 if (CONST_INT_P (operands[2])
6155 /* Avoid overflows. */
6156 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6157 && (INTVAL (operands[2]) == 128
6158 || (INTVAL (operands[2]) < 0
6159 && INTVAL (operands[2]) != -128)))
6161 operands[2] = GEN_INT (-INTVAL (operands[2]));
6162 return "sub{q}\t{%2, %0|%0, %2}";
6164 return "add{q}\t{%2, %0|%0, %2}";
6168 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6169 (const_string "incdec")
6170 (const_string "alu")))
6171 (set_attr "mode" "DI")])
6174 (define_insn "*addsi_1"
6175 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6176 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6177 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6178 (clobber (reg:CC FLAGS_REG))]
6179 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6181 switch (get_attr_type (insn))
6184 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6185 return "lea{l}\t{%a2, %0|%0, %a2}";
6188 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6189 if (operands[2] == const1_rtx)
6190 return "inc{l}\t%0";
6193 gcc_assert (operands[2] == constm1_rtx);
6194 return "dec{l}\t%0";
6198 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6200 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6201 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6202 if (CONST_INT_P (operands[2])
6203 && (INTVAL (operands[2]) == 128
6204 || (INTVAL (operands[2]) < 0
6205 && INTVAL (operands[2]) != -128)))
6207 operands[2] = GEN_INT (-INTVAL (operands[2]));
6208 return "sub{l}\t{%2, %0|%0, %2}";
6210 return "add{l}\t{%2, %0|%0, %2}";
6214 (cond [(eq_attr "alternative" "2")
6215 (const_string "lea")
6216 ; Current assemblers are broken and do not allow @GOTOFF in
6217 ; ought but a memory context.
6218 (match_operand:SI 2 "pic_symbolic_operand" "")
6219 (const_string "lea")
6220 (match_operand:SI 2 "incdec_operand" "")
6221 (const_string "incdec")
6223 (const_string "alu")))
6224 (set_attr "mode" "SI")])
6226 ;; Convert lea to the lea pattern to avoid flags dependency.
6228 [(set (match_operand 0 "register_operand" "")
6229 (plus (match_operand 1 "register_operand" "")
6230 (match_operand 2 "nonmemory_operand" "")))
6231 (clobber (reg:CC FLAGS_REG))]
6233 && true_regnum (operands[0]) != true_regnum (operands[1])"
6237 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6238 may confuse gen_lowpart. */
6239 if (GET_MODE (operands[0]) != Pmode)
6241 operands[1] = gen_lowpart (Pmode, operands[1]);
6242 operands[2] = gen_lowpart (Pmode, operands[2]);
6244 operands[0] = gen_lowpart (SImode, operands[0]);
6245 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6246 if (Pmode != SImode)
6247 pat = gen_rtx_SUBREG (SImode, pat, 0);
6248 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6252 ;; It may seem that nonimmediate operand is proper one for operand 1.
6253 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6254 ;; we take care in ix86_binary_operator_ok to not allow two memory
6255 ;; operands so proper swapping will be done in reload. This allow
6256 ;; patterns constructed from addsi_1 to match.
6257 (define_insn "addsi_1_zext"
6258 [(set (match_operand:DI 0 "register_operand" "=r,r")
6260 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6261 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6262 (clobber (reg:CC FLAGS_REG))]
6263 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6265 switch (get_attr_type (insn))
6268 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6269 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6272 if (operands[2] == const1_rtx)
6273 return "inc{l}\t%k0";
6276 gcc_assert (operands[2] == constm1_rtx);
6277 return "dec{l}\t%k0";
6281 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6282 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6283 if (CONST_INT_P (operands[2])
6284 && (INTVAL (operands[2]) == 128
6285 || (INTVAL (operands[2]) < 0
6286 && INTVAL (operands[2]) != -128)))
6288 operands[2] = GEN_INT (-INTVAL (operands[2]));
6289 return "sub{l}\t{%2, %k0|%k0, %2}";
6291 return "add{l}\t{%2, %k0|%k0, %2}";
6295 (cond [(eq_attr "alternative" "1")
6296 (const_string "lea")
6297 ; Current assemblers are broken and do not allow @GOTOFF in
6298 ; ought but a memory context.
6299 (match_operand:SI 2 "pic_symbolic_operand" "")
6300 (const_string "lea")
6301 (match_operand:SI 2 "incdec_operand" "")
6302 (const_string "incdec")
6304 (const_string "alu")))
6305 (set_attr "mode" "SI")])
6307 ;; Convert lea to the lea pattern to avoid flags dependency.
6309 [(set (match_operand:DI 0 "register_operand" "")
6311 (plus:SI (match_operand:SI 1 "register_operand" "")
6312 (match_operand:SI 2 "nonmemory_operand" ""))))
6313 (clobber (reg:CC FLAGS_REG))]
6314 "TARGET_64BIT && reload_completed
6315 && true_regnum (operands[0]) != true_regnum (operands[1])"
6317 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6319 operands[1] = gen_lowpart (Pmode, operands[1]);
6320 operands[2] = gen_lowpart (Pmode, operands[2]);
6323 (define_insn "*addsi_2"
6324 [(set (reg FLAGS_REG)
6326 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6327 (match_operand:SI 2 "general_operand" "rmni,rni"))
6329 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6330 (plus:SI (match_dup 1) (match_dup 2)))]
6331 "ix86_match_ccmode (insn, CCGOCmode)
6332 && ix86_binary_operator_ok (PLUS, SImode, operands)
6333 /* Current assemblers are broken and do not allow @GOTOFF in
6334 ought but a memory context. */
6335 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6337 switch (get_attr_type (insn))
6340 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6341 if (operands[2] == const1_rtx)
6342 return "inc{l}\t%0";
6345 gcc_assert (operands[2] == constm1_rtx);
6346 return "dec{l}\t%0";
6350 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6351 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6352 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6353 if (CONST_INT_P (operands[2])
6354 && (INTVAL (operands[2]) == 128
6355 || (INTVAL (operands[2]) < 0
6356 && INTVAL (operands[2]) != -128)))
6358 operands[2] = GEN_INT (-INTVAL (operands[2]));
6359 return "sub{l}\t{%2, %0|%0, %2}";
6361 return "add{l}\t{%2, %0|%0, %2}";
6365 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6366 (const_string "incdec")
6367 (const_string "alu")))
6368 (set_attr "mode" "SI")])
6370 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6371 (define_insn "*addsi_2_zext"
6372 [(set (reg FLAGS_REG)
6374 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6375 (match_operand:SI 2 "general_operand" "rmni"))
6377 (set (match_operand:DI 0 "register_operand" "=r")
6378 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6379 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6380 && ix86_binary_operator_ok (PLUS, SImode, operands)
6381 /* Current assemblers are broken and do not allow @GOTOFF in
6382 ought but a memory context. */
6383 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6385 switch (get_attr_type (insn))
6388 if (operands[2] == const1_rtx)
6389 return "inc{l}\t%k0";
6392 gcc_assert (operands[2] == constm1_rtx);
6393 return "dec{l}\t%k0";
6397 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6398 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6399 if (CONST_INT_P (operands[2])
6400 && (INTVAL (operands[2]) == 128
6401 || (INTVAL (operands[2]) < 0
6402 && INTVAL (operands[2]) != -128)))
6404 operands[2] = GEN_INT (-INTVAL (operands[2]));
6405 return "sub{l}\t{%2, %k0|%k0, %2}";
6407 return "add{l}\t{%2, %k0|%k0, %2}";
6411 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6412 (const_string "incdec")
6413 (const_string "alu")))
6414 (set_attr "mode" "SI")])
6416 (define_insn "*addsi_3"
6417 [(set (reg FLAGS_REG)
6418 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6419 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6420 (clobber (match_scratch:SI 0 "=r"))]
6421 "ix86_match_ccmode (insn, CCZmode)
6422 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6423 /* Current assemblers are broken and do not allow @GOTOFF in
6424 ought but a memory context. */
6425 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6427 switch (get_attr_type (insn))
6430 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6431 if (operands[2] == const1_rtx)
6432 return "inc{l}\t%0";
6435 gcc_assert (operands[2] == constm1_rtx);
6436 return "dec{l}\t%0";
6440 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6441 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6442 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6443 if (CONST_INT_P (operands[2])
6444 && (INTVAL (operands[2]) == 128
6445 || (INTVAL (operands[2]) < 0
6446 && INTVAL (operands[2]) != -128)))
6448 operands[2] = GEN_INT (-INTVAL (operands[2]));
6449 return "sub{l}\t{%2, %0|%0, %2}";
6451 return "add{l}\t{%2, %0|%0, %2}";
6455 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6456 (const_string "incdec")
6457 (const_string "alu")))
6458 (set_attr "mode" "SI")])
6460 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6461 (define_insn "*addsi_3_zext"
6462 [(set (reg FLAGS_REG)
6463 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6464 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6465 (set (match_operand:DI 0 "register_operand" "=r")
6466 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6467 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6468 && ix86_binary_operator_ok (PLUS, SImode, operands)
6469 /* Current assemblers are broken and do not allow @GOTOFF in
6470 ought but a memory context. */
6471 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6473 switch (get_attr_type (insn))
6476 if (operands[2] == const1_rtx)
6477 return "inc{l}\t%k0";
6480 gcc_assert (operands[2] == constm1_rtx);
6481 return "dec{l}\t%k0";
6485 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6486 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6487 if (CONST_INT_P (operands[2])
6488 && (INTVAL (operands[2]) == 128
6489 || (INTVAL (operands[2]) < 0
6490 && INTVAL (operands[2]) != -128)))
6492 operands[2] = GEN_INT (-INTVAL (operands[2]));
6493 return "sub{l}\t{%2, %k0|%k0, %2}";
6495 return "add{l}\t{%2, %k0|%k0, %2}";
6499 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6500 (const_string "incdec")
6501 (const_string "alu")))
6502 (set_attr "mode" "SI")])
6504 ; For comparisons against 1, -1 and 128, we may generate better code
6505 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6506 ; is matched then. We can't accept general immediate, because for
6507 ; case of overflows, the result is messed up.
6508 ; This pattern also don't hold of 0x80000000, since the value overflows
6510 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6511 ; only for comparisons not depending on it.
6512 (define_insn "*addsi_4"
6513 [(set (reg FLAGS_REG)
6514 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6515 (match_operand:SI 2 "const_int_operand" "n")))
6516 (clobber (match_scratch:SI 0 "=rm"))]
6517 "ix86_match_ccmode (insn, CCGCmode)
6518 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6520 switch (get_attr_type (insn))
6523 if (operands[2] == constm1_rtx)
6524 return "inc{l}\t%0";
6527 gcc_assert (operands[2] == const1_rtx);
6528 return "dec{l}\t%0";
6532 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6533 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6534 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6535 if ((INTVAL (operands[2]) == -128
6536 || (INTVAL (operands[2]) > 0
6537 && INTVAL (operands[2]) != 128)))
6538 return "sub{l}\t{%2, %0|%0, %2}";
6539 operands[2] = GEN_INT (-INTVAL (operands[2]));
6540 return "add{l}\t{%2, %0|%0, %2}";
6544 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6545 (const_string "incdec")
6546 (const_string "alu")))
6547 (set_attr "mode" "SI")])
6549 (define_insn "*addsi_5"
6550 [(set (reg FLAGS_REG)
6552 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6553 (match_operand:SI 2 "general_operand" "rmni"))
6555 (clobber (match_scratch:SI 0 "=r"))]
6556 "ix86_match_ccmode (insn, CCGOCmode)
6557 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6558 /* Current assemblers are broken and do not allow @GOTOFF in
6559 ought but a memory context. */
6560 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6562 switch (get_attr_type (insn))
6565 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6566 if (operands[2] == const1_rtx)
6567 return "inc{l}\t%0";
6570 gcc_assert (operands[2] == constm1_rtx);
6571 return "dec{l}\t%0";
6575 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6576 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6577 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6578 if (CONST_INT_P (operands[2])
6579 && (INTVAL (operands[2]) == 128
6580 || (INTVAL (operands[2]) < 0
6581 && INTVAL (operands[2]) != -128)))
6583 operands[2] = GEN_INT (-INTVAL (operands[2]));
6584 return "sub{l}\t{%2, %0|%0, %2}";
6586 return "add{l}\t{%2, %0|%0, %2}";
6590 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6591 (const_string "incdec")
6592 (const_string "alu")))
6593 (set_attr "mode" "SI")])
6595 (define_expand "addhi3"
6596 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6597 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6598 (match_operand:HI 2 "general_operand" "")))
6599 (clobber (reg:CC FLAGS_REG))])]
6600 "TARGET_HIMODE_MATH"
6601 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6603 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6604 ;; type optimizations enabled by define-splits. This is not important
6605 ;; for PII, and in fact harmful because of partial register stalls.
6607 (define_insn "*addhi_1_lea"
6608 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6609 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6610 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "!TARGET_PARTIAL_REG_STALL
6613 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6615 switch (get_attr_type (insn))
6620 if (operands[2] == const1_rtx)
6621 return "inc{w}\t%0";
6624 gcc_assert (operands[2] == constm1_rtx);
6625 return "dec{w}\t%0";
6629 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6630 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6631 if (CONST_INT_P (operands[2])
6632 && (INTVAL (operands[2]) == 128
6633 || (INTVAL (operands[2]) < 0
6634 && INTVAL (operands[2]) != -128)))
6636 operands[2] = GEN_INT (-INTVAL (operands[2]));
6637 return "sub{w}\t{%2, %0|%0, %2}";
6639 return "add{w}\t{%2, %0|%0, %2}";
6643 (if_then_else (eq_attr "alternative" "2")
6644 (const_string "lea")
6645 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6646 (const_string "incdec")
6647 (const_string "alu"))))
6648 (set_attr "mode" "HI,HI,SI")])
6650 (define_insn "*addhi_1"
6651 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6652 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6653 (match_operand:HI 2 "general_operand" "ri,rm")))
6654 (clobber (reg:CC FLAGS_REG))]
6655 "TARGET_PARTIAL_REG_STALL
6656 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6658 switch (get_attr_type (insn))
6661 if (operands[2] == const1_rtx)
6662 return "inc{w}\t%0";
6665 gcc_assert (operands[2] == constm1_rtx);
6666 return "dec{w}\t%0";
6670 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6671 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6672 if (CONST_INT_P (operands[2])
6673 && (INTVAL (operands[2]) == 128
6674 || (INTVAL (operands[2]) < 0
6675 && INTVAL (operands[2]) != -128)))
6677 operands[2] = GEN_INT (-INTVAL (operands[2]));
6678 return "sub{w}\t{%2, %0|%0, %2}";
6680 return "add{w}\t{%2, %0|%0, %2}";
6684 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6685 (const_string "incdec")
6686 (const_string "alu")))
6687 (set_attr "mode" "HI")])
6689 (define_insn "*addhi_2"
6690 [(set (reg FLAGS_REG)
6692 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6693 (match_operand:HI 2 "general_operand" "rmni,rni"))
6695 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6696 (plus:HI (match_dup 1) (match_dup 2)))]
6697 "ix86_match_ccmode (insn, CCGOCmode)
6698 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6700 switch (get_attr_type (insn))
6703 if (operands[2] == const1_rtx)
6704 return "inc{w}\t%0";
6707 gcc_assert (operands[2] == constm1_rtx);
6708 return "dec{w}\t%0";
6712 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6713 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6714 if (CONST_INT_P (operands[2])
6715 && (INTVAL (operands[2]) == 128
6716 || (INTVAL (operands[2]) < 0
6717 && INTVAL (operands[2]) != -128)))
6719 operands[2] = GEN_INT (-INTVAL (operands[2]));
6720 return "sub{w}\t{%2, %0|%0, %2}";
6722 return "add{w}\t{%2, %0|%0, %2}";
6726 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6727 (const_string "incdec")
6728 (const_string "alu")))
6729 (set_attr "mode" "HI")])
6731 (define_insn "*addhi_3"
6732 [(set (reg FLAGS_REG)
6733 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6734 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6735 (clobber (match_scratch:HI 0 "=r"))]
6736 "ix86_match_ccmode (insn, CCZmode)
6737 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6739 switch (get_attr_type (insn))
6742 if (operands[2] == const1_rtx)
6743 return "inc{w}\t%0";
6746 gcc_assert (operands[2] == constm1_rtx);
6747 return "dec{w}\t%0";
6751 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6752 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6753 if (CONST_INT_P (operands[2])
6754 && (INTVAL (operands[2]) == 128
6755 || (INTVAL (operands[2]) < 0
6756 && INTVAL (operands[2]) != -128)))
6758 operands[2] = GEN_INT (-INTVAL (operands[2]));
6759 return "sub{w}\t{%2, %0|%0, %2}";
6761 return "add{w}\t{%2, %0|%0, %2}";
6765 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6766 (const_string "incdec")
6767 (const_string "alu")))
6768 (set_attr "mode" "HI")])
6770 ; See comments above addsi_4 for details.
6771 (define_insn "*addhi_4"
6772 [(set (reg FLAGS_REG)
6773 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6774 (match_operand:HI 2 "const_int_operand" "n")))
6775 (clobber (match_scratch:HI 0 "=rm"))]
6776 "ix86_match_ccmode (insn, CCGCmode)
6777 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6779 switch (get_attr_type (insn))
6782 if (operands[2] == constm1_rtx)
6783 return "inc{w}\t%0";
6786 gcc_assert (operands[2] == const1_rtx);
6787 return "dec{w}\t%0";
6791 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6792 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6793 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6794 if ((INTVAL (operands[2]) == -128
6795 || (INTVAL (operands[2]) > 0
6796 && INTVAL (operands[2]) != 128)))
6797 return "sub{w}\t{%2, %0|%0, %2}";
6798 operands[2] = GEN_INT (-INTVAL (operands[2]));
6799 return "add{w}\t{%2, %0|%0, %2}";
6803 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6804 (const_string "incdec")
6805 (const_string "alu")))
6806 (set_attr "mode" "SI")])
6809 (define_insn "*addhi_5"
6810 [(set (reg FLAGS_REG)
6812 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6813 (match_operand:HI 2 "general_operand" "rmni"))
6815 (clobber (match_scratch:HI 0 "=r"))]
6816 "ix86_match_ccmode (insn, CCGOCmode)
6817 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6819 switch (get_attr_type (insn))
6822 if (operands[2] == const1_rtx)
6823 return "inc{w}\t%0";
6826 gcc_assert (operands[2] == constm1_rtx);
6827 return "dec{w}\t%0";
6831 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6832 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6833 if (CONST_INT_P (operands[2])
6834 && (INTVAL (operands[2]) == 128
6835 || (INTVAL (operands[2]) < 0
6836 && INTVAL (operands[2]) != -128)))
6838 operands[2] = GEN_INT (-INTVAL (operands[2]));
6839 return "sub{w}\t{%2, %0|%0, %2}";
6841 return "add{w}\t{%2, %0|%0, %2}";
6845 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6846 (const_string "incdec")
6847 (const_string "alu")))
6848 (set_attr "mode" "HI")])
6850 (define_expand "addqi3"
6851 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6852 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6853 (match_operand:QI 2 "general_operand" "")))
6854 (clobber (reg:CC FLAGS_REG))])]
6855 "TARGET_QIMODE_MATH"
6856 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6858 ;; %%% Potential partial reg stall on alternative 2. What to do?
6859 (define_insn "*addqi_1_lea"
6860 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6861 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6862 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6863 (clobber (reg:CC FLAGS_REG))]
6864 "!TARGET_PARTIAL_REG_STALL
6865 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6867 int widen = (which_alternative == 2);
6868 switch (get_attr_type (insn))
6873 if (operands[2] == const1_rtx)
6874 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6877 gcc_assert (operands[2] == constm1_rtx);
6878 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6882 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6883 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6884 if (CONST_INT_P (operands[2])
6885 && (INTVAL (operands[2]) == 128
6886 || (INTVAL (operands[2]) < 0
6887 && INTVAL (operands[2]) != -128)))
6889 operands[2] = GEN_INT (-INTVAL (operands[2]));
6891 return "sub{l}\t{%2, %k0|%k0, %2}";
6893 return "sub{b}\t{%2, %0|%0, %2}";
6896 return "add{l}\t{%k2, %k0|%k0, %k2}";
6898 return "add{b}\t{%2, %0|%0, %2}";
6902 (if_then_else (eq_attr "alternative" "3")
6903 (const_string "lea")
6904 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6905 (const_string "incdec")
6906 (const_string "alu"))))
6907 (set_attr "mode" "QI,QI,SI,SI")])
6909 (define_insn "*addqi_1"
6910 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6911 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6912 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6913 (clobber (reg:CC FLAGS_REG))]
6914 "TARGET_PARTIAL_REG_STALL
6915 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6917 int widen = (which_alternative == 2);
6918 switch (get_attr_type (insn))
6921 if (operands[2] == const1_rtx)
6922 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6925 gcc_assert (operands[2] == constm1_rtx);
6926 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6930 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6931 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6932 if (CONST_INT_P (operands[2])
6933 && (INTVAL (operands[2]) == 128
6934 || (INTVAL (operands[2]) < 0
6935 && INTVAL (operands[2]) != -128)))
6937 operands[2] = GEN_INT (-INTVAL (operands[2]));
6939 return "sub{l}\t{%2, %k0|%k0, %2}";
6941 return "sub{b}\t{%2, %0|%0, %2}";
6944 return "add{l}\t{%k2, %k0|%k0, %k2}";
6946 return "add{b}\t{%2, %0|%0, %2}";
6950 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6951 (const_string "incdec")
6952 (const_string "alu")))
6953 (set_attr "mode" "QI,QI,SI")])
6955 (define_insn "*addqi_1_slp"
6956 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6957 (plus:QI (match_dup 0)
6958 (match_operand:QI 1 "general_operand" "qn,qnm")))
6959 (clobber (reg:CC FLAGS_REG))]
6960 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6961 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6963 switch (get_attr_type (insn))
6966 if (operands[1] == const1_rtx)
6967 return "inc{b}\t%0";
6970 gcc_assert (operands[1] == constm1_rtx);
6971 return "dec{b}\t%0";
6975 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6976 if (CONST_INT_P (operands[1])
6977 && INTVAL (operands[1]) < 0)
6979 operands[1] = GEN_INT (-INTVAL (operands[1]));
6980 return "sub{b}\t{%1, %0|%0, %1}";
6982 return "add{b}\t{%1, %0|%0, %1}";
6986 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6987 (const_string "incdec")
6988 (const_string "alu1")))
6989 (set (attr "memory")
6990 (if_then_else (match_operand 1 "memory_operand" "")
6991 (const_string "load")
6992 (const_string "none")))
6993 (set_attr "mode" "QI")])
6995 (define_insn "*addqi_2"
6996 [(set (reg FLAGS_REG)
6998 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6999 (match_operand:QI 2 "general_operand" "qmni,qni"))
7001 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7002 (plus:QI (match_dup 1) (match_dup 2)))]
7003 "ix86_match_ccmode (insn, CCGOCmode)
7004 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7006 switch (get_attr_type (insn))
7009 if (operands[2] == const1_rtx)
7010 return "inc{b}\t%0";
7013 gcc_assert (operands[2] == constm1_rtx
7014 || (CONST_INT_P (operands[2])
7015 && INTVAL (operands[2]) == 255));
7016 return "dec{b}\t%0";
7020 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7021 if (CONST_INT_P (operands[2])
7022 && INTVAL (operands[2]) < 0)
7024 operands[2] = GEN_INT (-INTVAL (operands[2]));
7025 return "sub{b}\t{%2, %0|%0, %2}";
7027 return "add{b}\t{%2, %0|%0, %2}";
7031 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7032 (const_string "incdec")
7033 (const_string "alu")))
7034 (set_attr "mode" "QI")])
7036 (define_insn "*addqi_3"
7037 [(set (reg FLAGS_REG)
7038 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
7039 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7040 (clobber (match_scratch:QI 0 "=q"))]
7041 "ix86_match_ccmode (insn, CCZmode)
7042 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7044 switch (get_attr_type (insn))
7047 if (operands[2] == const1_rtx)
7048 return "inc{b}\t%0";
7051 gcc_assert (operands[2] == constm1_rtx
7052 || (CONST_INT_P (operands[2])
7053 && INTVAL (operands[2]) == 255));
7054 return "dec{b}\t%0";
7058 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7059 if (CONST_INT_P (operands[2])
7060 && INTVAL (operands[2]) < 0)
7062 operands[2] = GEN_INT (-INTVAL (operands[2]));
7063 return "sub{b}\t{%2, %0|%0, %2}";
7065 return "add{b}\t{%2, %0|%0, %2}";
7069 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7070 (const_string "incdec")
7071 (const_string "alu")))
7072 (set_attr "mode" "QI")])
7074 ; See comments above addsi_4 for details.
7075 (define_insn "*addqi_4"
7076 [(set (reg FLAGS_REG)
7077 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7078 (match_operand:QI 2 "const_int_operand" "n")))
7079 (clobber (match_scratch:QI 0 "=qm"))]
7080 "ix86_match_ccmode (insn, CCGCmode)
7081 && (INTVAL (operands[2]) & 0xff) != 0x80"
7083 switch (get_attr_type (insn))
7086 if (operands[2] == constm1_rtx
7087 || (CONST_INT_P (operands[2])
7088 && INTVAL (operands[2]) == 255))
7089 return "inc{b}\t%0";
7092 gcc_assert (operands[2] == const1_rtx);
7093 return "dec{b}\t%0";
7097 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7098 if (INTVAL (operands[2]) < 0)
7100 operands[2] = GEN_INT (-INTVAL (operands[2]));
7101 return "add{b}\t{%2, %0|%0, %2}";
7103 return "sub{b}\t{%2, %0|%0, %2}";
7107 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7108 (const_string "incdec")
7109 (const_string "alu")))
7110 (set_attr "mode" "QI")])
7113 (define_insn "*addqi_5"
7114 [(set (reg FLAGS_REG)
7116 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7117 (match_operand:QI 2 "general_operand" "qmni"))
7119 (clobber (match_scratch:QI 0 "=q"))]
7120 "ix86_match_ccmode (insn, CCGOCmode)
7121 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7123 switch (get_attr_type (insn))
7126 if (operands[2] == const1_rtx)
7127 return "inc{b}\t%0";
7130 gcc_assert (operands[2] == constm1_rtx
7131 || (CONST_INT_P (operands[2])
7132 && INTVAL (operands[2]) == 255));
7133 return "dec{b}\t%0";
7137 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7138 if (CONST_INT_P (operands[2])
7139 && INTVAL (operands[2]) < 0)
7141 operands[2] = GEN_INT (-INTVAL (operands[2]));
7142 return "sub{b}\t{%2, %0|%0, %2}";
7144 return "add{b}\t{%2, %0|%0, %2}";
7148 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7149 (const_string "incdec")
7150 (const_string "alu")))
7151 (set_attr "mode" "QI")])
7154 (define_insn "addqi_ext_1"
7155 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7160 (match_operand 1 "ext_register_operand" "0")
7163 (match_operand:QI 2 "general_operand" "Qmn")))
7164 (clobber (reg:CC FLAGS_REG))]
7167 switch (get_attr_type (insn))
7170 if (operands[2] == const1_rtx)
7171 return "inc{b}\t%h0";
7174 gcc_assert (operands[2] == constm1_rtx
7175 || (CONST_INT_P (operands[2])
7176 && INTVAL (operands[2]) == 255));
7177 return "dec{b}\t%h0";
7181 return "add{b}\t{%2, %h0|%h0, %2}";
7185 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7186 (const_string "incdec")
7187 (const_string "alu")))
7188 (set_attr "mode" "QI")])
7190 (define_insn "*addqi_ext_1_rex64"
7191 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7196 (match_operand 1 "ext_register_operand" "0")
7199 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7200 (clobber (reg:CC FLAGS_REG))]
7203 switch (get_attr_type (insn))
7206 if (operands[2] == const1_rtx)
7207 return "inc{b}\t%h0";
7210 gcc_assert (operands[2] == constm1_rtx
7211 || (CONST_INT_P (operands[2])
7212 && INTVAL (operands[2]) == 255));
7213 return "dec{b}\t%h0";
7217 return "add{b}\t{%2, %h0|%h0, %2}";
7221 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7222 (const_string "incdec")
7223 (const_string "alu")))
7224 (set_attr "mode" "QI")])
7226 (define_insn "*addqi_ext_2"
7227 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7232 (match_operand 1 "ext_register_operand" "%0")
7236 (match_operand 2 "ext_register_operand" "Q")
7239 (clobber (reg:CC FLAGS_REG))]
7241 "add{b}\t{%h2, %h0|%h0, %h2}"
7242 [(set_attr "type" "alu")
7243 (set_attr "mode" "QI")])
7245 ;; The patterns that match these are at the end of this file.
7247 (define_expand "addxf3"
7248 [(set (match_operand:XF 0 "register_operand" "")
7249 (plus:XF (match_operand:XF 1 "register_operand" "")
7250 (match_operand:XF 2 "register_operand" "")))]
7254 (define_expand "add<mode>3"
7255 [(set (match_operand:MODEF 0 "register_operand" "")
7256 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7257 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7258 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7261 ;; Subtract instructions
7263 ;; %%% splits for subditi3
7265 (define_expand "subti3"
7266 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7267 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7268 (match_operand:TI 2 "x86_64_general_operand" "")))
7269 (clobber (reg:CC FLAGS_REG))])]
7271 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7273 (define_insn "*subti3_1"
7274 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7275 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7276 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7277 (clobber (reg:CC FLAGS_REG))]
7278 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7282 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7283 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7284 (match_operand:TI 2 "x86_64_general_operand" "")))
7285 (clobber (reg:CC FLAGS_REG))]
7286 "TARGET_64BIT && reload_completed"
7287 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7288 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7289 (parallel [(set (match_dup 3)
7290 (minus:DI (match_dup 4)
7291 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7293 (clobber (reg:CC FLAGS_REG))])]
7294 "split_ti (operands+0, 1, operands+0, operands+3);
7295 split_ti (operands+1, 1, operands+1, operands+4);
7296 split_ti (operands+2, 1, operands+2, operands+5);")
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, 1, operands+0, operands+3);
7330 split_di (operands+1, 1, operands+1, operands+4);
7331 split_di (operands+2, 1, operands+2, operands+5);")
7333 (define_insn "subdi3_carry_rex64"
7334 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7335 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7336 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7337 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7338 (clobber (reg:CC FLAGS_REG))]
7339 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7340 "sbb{q}\t{%2, %0|%0, %2}"
7341 [(set_attr "type" "alu")
7342 (set_attr "pent_pair" "pu")
7343 (set_attr "mode" "DI")])
7345 (define_insn "*subdi_1_rex64"
7346 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7347 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7348 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7349 (clobber (reg:CC FLAGS_REG))]
7350 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7351 "sub{q}\t{%2, %0|%0, %2}"
7352 [(set_attr "type" "alu")
7353 (set_attr "mode" "DI")])
7355 (define_insn "*subdi_2_rex64"
7356 [(set (reg FLAGS_REG)
7358 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7359 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7361 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7362 (minus:DI (match_dup 1) (match_dup 2)))]
7363 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7364 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7365 "sub{q}\t{%2, %0|%0, %2}"
7366 [(set_attr "type" "alu")
7367 (set_attr "mode" "DI")])
7369 (define_insn "*subdi_3_rex63"
7370 [(set (reg FLAGS_REG)
7371 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7372 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7373 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7374 (minus:DI (match_dup 1) (match_dup 2)))]
7375 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7376 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7377 "sub{q}\t{%2, %0|%0, %2}"
7378 [(set_attr "type" "alu")
7379 (set_attr "mode" "DI")])
7381 (define_insn "subqi3_carry"
7382 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7383 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7384 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7385 (match_operand:QI 2 "general_operand" "qi,qm"))))
7386 (clobber (reg:CC FLAGS_REG))]
7387 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7388 "sbb{b}\t{%2, %0|%0, %2}"
7389 [(set_attr "type" "alu")
7390 (set_attr "pent_pair" "pu")
7391 (set_attr "mode" "QI")])
7393 (define_insn "subhi3_carry"
7394 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7395 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7396 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7397 (match_operand:HI 2 "general_operand" "ri,rm"))))
7398 (clobber (reg:CC FLAGS_REG))]
7399 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7400 "sbb{w}\t{%2, %0|%0, %2}"
7401 [(set_attr "type" "alu")
7402 (set_attr "pent_pair" "pu")
7403 (set_attr "mode" "HI")])
7405 (define_insn "subsi3_carry"
7406 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7407 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7408 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7409 (match_operand:SI 2 "general_operand" "ri,rm"))))
7410 (clobber (reg:CC FLAGS_REG))]
7411 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7412 "sbb{l}\t{%2, %0|%0, %2}"
7413 [(set_attr "type" "alu")
7414 (set_attr "pent_pair" "pu")
7415 (set_attr "mode" "SI")])
7417 (define_insn "subsi3_carry_zext"
7418 [(set (match_operand:DI 0 "register_operand" "=r")
7420 (minus:SI (match_operand:SI 1 "register_operand" "0")
7421 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7422 (match_operand:SI 2 "general_operand" "g")))))
7423 (clobber (reg:CC FLAGS_REG))]
7424 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7425 "sbb{l}\t{%2, %k0|%k0, %2}"
7426 [(set_attr "type" "alu")
7427 (set_attr "pent_pair" "pu")
7428 (set_attr "mode" "SI")])
7430 (define_expand "subsi3"
7431 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7432 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7433 (match_operand:SI 2 "general_operand" "")))
7434 (clobber (reg:CC FLAGS_REG))])]
7436 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7438 (define_insn "*subsi_1"
7439 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7440 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7441 (match_operand:SI 2 "general_operand" "ri,rm")))
7442 (clobber (reg:CC FLAGS_REG))]
7443 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7444 "sub{l}\t{%2, %0|%0, %2}"
7445 [(set_attr "type" "alu")
7446 (set_attr "mode" "SI")])
7448 (define_insn "*subsi_1_zext"
7449 [(set (match_operand:DI 0 "register_operand" "=r")
7451 (minus:SI (match_operand:SI 1 "register_operand" "0")
7452 (match_operand:SI 2 "general_operand" "g"))))
7453 (clobber (reg:CC FLAGS_REG))]
7454 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7455 "sub{l}\t{%2, %k0|%k0, %2}"
7456 [(set_attr "type" "alu")
7457 (set_attr "mode" "SI")])
7459 (define_insn "*subsi_2"
7460 [(set (reg FLAGS_REG)
7462 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7463 (match_operand:SI 2 "general_operand" "ri,rm"))
7465 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7466 (minus:SI (match_dup 1) (match_dup 2)))]
7467 "ix86_match_ccmode (insn, CCGOCmode)
7468 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7469 "sub{l}\t{%2, %0|%0, %2}"
7470 [(set_attr "type" "alu")
7471 (set_attr "mode" "SI")])
7473 (define_insn "*subsi_2_zext"
7474 [(set (reg FLAGS_REG)
7476 (minus:SI (match_operand:SI 1 "register_operand" "0")
7477 (match_operand:SI 2 "general_operand" "g"))
7479 (set (match_operand:DI 0 "register_operand" "=r")
7481 (minus:SI (match_dup 1)
7483 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7484 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7485 "sub{l}\t{%2, %k0|%k0, %2}"
7486 [(set_attr "type" "alu")
7487 (set_attr "mode" "SI")])
7489 (define_insn "*subsi_3"
7490 [(set (reg FLAGS_REG)
7491 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7492 (match_operand:SI 2 "general_operand" "ri,rm")))
7493 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7494 (minus:SI (match_dup 1) (match_dup 2)))]
7495 "ix86_match_ccmode (insn, CCmode)
7496 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7497 "sub{l}\t{%2, %0|%0, %2}"
7498 [(set_attr "type" "alu")
7499 (set_attr "mode" "SI")])
7501 (define_insn "*subsi_3_zext"
7502 [(set (reg FLAGS_REG)
7503 (compare (match_operand:SI 1 "register_operand" "0")
7504 (match_operand:SI 2 "general_operand" "g")))
7505 (set (match_operand:DI 0 "register_operand" "=r")
7507 (minus:SI (match_dup 1)
7509 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7510 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7511 "sub{l}\t{%2, %1|%1, %2}"
7512 [(set_attr "type" "alu")
7513 (set_attr "mode" "DI")])
7515 (define_expand "subhi3"
7516 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7517 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7518 (match_operand:HI 2 "general_operand" "")))
7519 (clobber (reg:CC FLAGS_REG))])]
7520 "TARGET_HIMODE_MATH"
7521 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7523 (define_insn "*subhi_1"
7524 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7525 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7526 (match_operand:HI 2 "general_operand" "ri,rm")))
7527 (clobber (reg:CC FLAGS_REG))]
7528 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7529 "sub{w}\t{%2, %0|%0, %2}"
7530 [(set_attr "type" "alu")
7531 (set_attr "mode" "HI")])
7533 (define_insn "*subhi_2"
7534 [(set (reg FLAGS_REG)
7536 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7537 (match_operand:HI 2 "general_operand" "ri,rm"))
7539 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7540 (minus:HI (match_dup 1) (match_dup 2)))]
7541 "ix86_match_ccmode (insn, CCGOCmode)
7542 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7543 "sub{w}\t{%2, %0|%0, %2}"
7544 [(set_attr "type" "alu")
7545 (set_attr "mode" "HI")])
7547 (define_insn "*subhi_3"
7548 [(set (reg FLAGS_REG)
7549 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7550 (match_operand:HI 2 "general_operand" "ri,rm")))
7551 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7552 (minus:HI (match_dup 1) (match_dup 2)))]
7553 "ix86_match_ccmode (insn, CCmode)
7554 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7555 "sub{w}\t{%2, %0|%0, %2}"
7556 [(set_attr "type" "alu")
7557 (set_attr "mode" "HI")])
7559 (define_expand "subqi3"
7560 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7561 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7562 (match_operand:QI 2 "general_operand" "")))
7563 (clobber (reg:CC FLAGS_REG))])]
7564 "TARGET_QIMODE_MATH"
7565 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7567 (define_insn "*subqi_1"
7568 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7569 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7570 (match_operand:QI 2 "general_operand" "qn,qmn")))
7571 (clobber (reg:CC FLAGS_REG))]
7572 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7573 "sub{b}\t{%2, %0|%0, %2}"
7574 [(set_attr "type" "alu")
7575 (set_attr "mode" "QI")])
7577 (define_insn "*subqi_1_slp"
7578 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7579 (minus:QI (match_dup 0)
7580 (match_operand:QI 1 "general_operand" "qn,qmn")))
7581 (clobber (reg:CC FLAGS_REG))]
7582 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7583 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7584 "sub{b}\t{%1, %0|%0, %1}"
7585 [(set_attr "type" "alu1")
7586 (set_attr "mode" "QI")])
7588 (define_insn "*subqi_2"
7589 [(set (reg FLAGS_REG)
7591 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7592 (match_operand:QI 2 "general_operand" "qi,qm"))
7594 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7595 (minus:HI (match_dup 1) (match_dup 2)))]
7596 "ix86_match_ccmode (insn, CCGOCmode)
7597 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7598 "sub{b}\t{%2, %0|%0, %2}"
7599 [(set_attr "type" "alu")
7600 (set_attr "mode" "QI")])
7602 (define_insn "*subqi_3"
7603 [(set (reg FLAGS_REG)
7604 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7605 (match_operand:QI 2 "general_operand" "qi,qm")))
7606 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7607 (minus:HI (match_dup 1) (match_dup 2)))]
7608 "ix86_match_ccmode (insn, CCmode)
7609 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7610 "sub{b}\t{%2, %0|%0, %2}"
7611 [(set_attr "type" "alu")
7612 (set_attr "mode" "QI")])
7614 ;; The patterns that match these are at the end of this file.
7616 (define_expand "subxf3"
7617 [(set (match_operand:XF 0 "register_operand" "")
7618 (minus:XF (match_operand:XF 1 "register_operand" "")
7619 (match_operand:XF 2 "register_operand" "")))]
7623 (define_expand "sub<mode>3"
7624 [(set (match_operand:MODEF 0 "register_operand" "")
7625 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7626 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7627 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7630 ;; Multiply instructions
7632 (define_expand "muldi3"
7633 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7634 (mult:DI (match_operand:DI 1 "register_operand" "")
7635 (match_operand:DI 2 "x86_64_general_operand" "")))
7636 (clobber (reg:CC FLAGS_REG))])]
7641 ;; IMUL reg64, reg64, imm8 Direct
7642 ;; IMUL reg64, mem64, imm8 VectorPath
7643 ;; IMUL reg64, reg64, imm32 Direct
7644 ;; IMUL reg64, mem64, imm32 VectorPath
7645 ;; IMUL reg64, reg64 Direct
7646 ;; IMUL reg64, mem64 Direct
7648 (define_insn "*muldi3_1_rex64"
7649 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7650 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7651 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7652 (clobber (reg:CC FLAGS_REG))]
7654 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7656 imul{q}\t{%2, %1, %0|%0, %1, %2}
7657 imul{q}\t{%2, %1, %0|%0, %1, %2}
7658 imul{q}\t{%2, %0|%0, %2}"
7659 [(set_attr "type" "imul")
7660 (set_attr "prefix_0f" "0,0,1")
7661 (set (attr "athlon_decode")
7662 (cond [(eq_attr "cpu" "athlon")
7663 (const_string "vector")
7664 (eq_attr "alternative" "1")
7665 (const_string "vector")
7666 (and (eq_attr "alternative" "2")
7667 (match_operand 1 "memory_operand" ""))
7668 (const_string "vector")]
7669 (const_string "direct")))
7670 (set (attr "amdfam10_decode")
7671 (cond [(and (eq_attr "alternative" "0,1")
7672 (match_operand 1 "memory_operand" ""))
7673 (const_string "vector")]
7674 (const_string "direct")))
7675 (set_attr "mode" "DI")])
7677 (define_expand "mulsi3"
7678 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7679 (mult:SI (match_operand:SI 1 "register_operand" "")
7680 (match_operand:SI 2 "general_operand" "")))
7681 (clobber (reg:CC FLAGS_REG))])]
7686 ;; IMUL reg32, reg32, imm8 Direct
7687 ;; IMUL reg32, mem32, imm8 VectorPath
7688 ;; IMUL reg32, reg32, imm32 Direct
7689 ;; IMUL reg32, mem32, imm32 VectorPath
7690 ;; IMUL reg32, reg32 Direct
7691 ;; IMUL reg32, mem32 Direct
7693 (define_insn "*mulsi3_1"
7694 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7695 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7696 (match_operand:SI 2 "general_operand" "K,i,mr")))
7697 (clobber (reg:CC FLAGS_REG))]
7698 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7700 imul{l}\t{%2, %1, %0|%0, %1, %2}
7701 imul{l}\t{%2, %1, %0|%0, %1, %2}
7702 imul{l}\t{%2, %0|%0, %2}"
7703 [(set_attr "type" "imul")
7704 (set_attr "prefix_0f" "0,0,1")
7705 (set (attr "athlon_decode")
7706 (cond [(eq_attr "cpu" "athlon")
7707 (const_string "vector")
7708 (eq_attr "alternative" "1")
7709 (const_string "vector")
7710 (and (eq_attr "alternative" "2")
7711 (match_operand 1 "memory_operand" ""))
7712 (const_string "vector")]
7713 (const_string "direct")))
7714 (set (attr "amdfam10_decode")
7715 (cond [(and (eq_attr "alternative" "0,1")
7716 (match_operand 1 "memory_operand" ""))
7717 (const_string "vector")]
7718 (const_string "direct")))
7719 (set_attr "mode" "SI")])
7721 (define_insn "*mulsi3_1_zext"
7722 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7724 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7725 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7726 (clobber (reg:CC FLAGS_REG))]
7728 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7730 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7731 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7732 imul{l}\t{%2, %k0|%k0, %2}"
7733 [(set_attr "type" "imul")
7734 (set_attr "prefix_0f" "0,0,1")
7735 (set (attr "athlon_decode")
7736 (cond [(eq_attr "cpu" "athlon")
7737 (const_string "vector")
7738 (eq_attr "alternative" "1")
7739 (const_string "vector")
7740 (and (eq_attr "alternative" "2")
7741 (match_operand 1 "memory_operand" ""))
7742 (const_string "vector")]
7743 (const_string "direct")))
7744 (set (attr "amdfam10_decode")
7745 (cond [(and (eq_attr "alternative" "0,1")
7746 (match_operand 1 "memory_operand" ""))
7747 (const_string "vector")]
7748 (const_string "direct")))
7749 (set_attr "mode" "SI")])
7751 (define_expand "mulhi3"
7752 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7753 (mult:HI (match_operand:HI 1 "register_operand" "")
7754 (match_operand:HI 2 "general_operand" "")))
7755 (clobber (reg:CC FLAGS_REG))])]
7756 "TARGET_HIMODE_MATH"
7760 ;; IMUL reg16, reg16, imm8 VectorPath
7761 ;; IMUL reg16, mem16, imm8 VectorPath
7762 ;; IMUL reg16, reg16, imm16 VectorPath
7763 ;; IMUL reg16, mem16, imm16 VectorPath
7764 ;; IMUL reg16, reg16 Direct
7765 ;; IMUL reg16, mem16 Direct
7766 (define_insn "*mulhi3_1"
7767 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7768 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7769 (match_operand:HI 2 "general_operand" "K,i,mr")))
7770 (clobber (reg:CC FLAGS_REG))]
7771 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7773 imul{w}\t{%2, %1, %0|%0, %1, %2}
7774 imul{w}\t{%2, %1, %0|%0, %1, %2}
7775 imul{w}\t{%2, %0|%0, %2}"
7776 [(set_attr "type" "imul")
7777 (set_attr "prefix_0f" "0,0,1")
7778 (set (attr "athlon_decode")
7779 (cond [(eq_attr "cpu" "athlon")
7780 (const_string "vector")
7781 (eq_attr "alternative" "1,2")
7782 (const_string "vector")]
7783 (const_string "direct")))
7784 (set (attr "amdfam10_decode")
7785 (cond [(eq_attr "alternative" "0,1")
7786 (const_string "vector")]
7787 (const_string "direct")))
7788 (set_attr "mode" "HI")])
7790 (define_expand "mulqi3"
7791 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7792 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7793 (match_operand:QI 2 "register_operand" "")))
7794 (clobber (reg:CC FLAGS_REG))])]
7795 "TARGET_QIMODE_MATH"
7802 (define_insn "*mulqi3_1"
7803 [(set (match_operand:QI 0 "register_operand" "=a")
7804 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7805 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7806 (clobber (reg:CC FLAGS_REG))]
7808 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7810 [(set_attr "type" "imul")
7811 (set_attr "length_immediate" "0")
7812 (set (attr "athlon_decode")
7813 (if_then_else (eq_attr "cpu" "athlon")
7814 (const_string "vector")
7815 (const_string "direct")))
7816 (set_attr "amdfam10_decode" "direct")
7817 (set_attr "mode" "QI")])
7819 (define_expand "umulqihi3"
7820 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7821 (mult:HI (zero_extend:HI
7822 (match_operand:QI 1 "nonimmediate_operand" ""))
7824 (match_operand:QI 2 "register_operand" ""))))
7825 (clobber (reg:CC FLAGS_REG))])]
7826 "TARGET_QIMODE_MATH"
7829 (define_insn "*umulqihi3_1"
7830 [(set (match_operand:HI 0 "register_operand" "=a")
7831 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7832 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7833 (clobber (reg:CC FLAGS_REG))]
7835 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7837 [(set_attr "type" "imul")
7838 (set_attr "length_immediate" "0")
7839 (set (attr "athlon_decode")
7840 (if_then_else (eq_attr "cpu" "athlon")
7841 (const_string "vector")
7842 (const_string "direct")))
7843 (set_attr "amdfam10_decode" "direct")
7844 (set_attr "mode" "QI")])
7846 (define_expand "mulqihi3"
7847 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7848 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7849 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7850 (clobber (reg:CC FLAGS_REG))])]
7851 "TARGET_QIMODE_MATH"
7854 (define_insn "*mulqihi3_insn"
7855 [(set (match_operand:HI 0 "register_operand" "=a")
7856 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7857 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7858 (clobber (reg:CC FLAGS_REG))]
7860 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7862 [(set_attr "type" "imul")
7863 (set_attr "length_immediate" "0")
7864 (set (attr "athlon_decode")
7865 (if_then_else (eq_attr "cpu" "athlon")
7866 (const_string "vector")
7867 (const_string "direct")))
7868 (set_attr "amdfam10_decode" "direct")
7869 (set_attr "mode" "QI")])
7871 (define_expand "umulditi3"
7872 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7873 (mult:TI (zero_extend:TI
7874 (match_operand:DI 1 "nonimmediate_operand" ""))
7876 (match_operand:DI 2 "register_operand" ""))))
7877 (clobber (reg:CC FLAGS_REG))])]
7881 (define_insn "*umulditi3_insn"
7882 [(set (match_operand:TI 0 "register_operand" "=A")
7883 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7884 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7885 (clobber (reg:CC FLAGS_REG))]
7887 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7889 [(set_attr "type" "imul")
7890 (set_attr "length_immediate" "0")
7891 (set (attr "athlon_decode")
7892 (if_then_else (eq_attr "cpu" "athlon")
7893 (const_string "vector")
7894 (const_string "double")))
7895 (set_attr "amdfam10_decode" "double")
7896 (set_attr "mode" "DI")])
7898 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7899 (define_expand "umulsidi3"
7900 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7901 (mult:DI (zero_extend:DI
7902 (match_operand:SI 1 "nonimmediate_operand" ""))
7904 (match_operand:SI 2 "register_operand" ""))))
7905 (clobber (reg:CC FLAGS_REG))])]
7909 (define_insn "*umulsidi3_insn"
7910 [(set (match_operand:DI 0 "register_operand" "=A")
7911 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7912 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7913 (clobber (reg:CC FLAGS_REG))]
7915 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7917 [(set_attr "type" "imul")
7918 (set_attr "length_immediate" "0")
7919 (set (attr "athlon_decode")
7920 (if_then_else (eq_attr "cpu" "athlon")
7921 (const_string "vector")
7922 (const_string "double")))
7923 (set_attr "amdfam10_decode" "double")
7924 (set_attr "mode" "SI")])
7926 (define_expand "mulditi3"
7927 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7928 (mult:TI (sign_extend:TI
7929 (match_operand:DI 1 "nonimmediate_operand" ""))
7931 (match_operand:DI 2 "register_operand" ""))))
7932 (clobber (reg:CC FLAGS_REG))])]
7936 (define_insn "*mulditi3_insn"
7937 [(set (match_operand:TI 0 "register_operand" "=A")
7938 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7939 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7940 (clobber (reg:CC FLAGS_REG))]
7942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7944 [(set_attr "type" "imul")
7945 (set_attr "length_immediate" "0")
7946 (set (attr "athlon_decode")
7947 (if_then_else (eq_attr "cpu" "athlon")
7948 (const_string "vector")
7949 (const_string "double")))
7950 (set_attr "amdfam10_decode" "double")
7951 (set_attr "mode" "DI")])
7953 (define_expand "mulsidi3"
7954 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7955 (mult:DI (sign_extend:DI
7956 (match_operand:SI 1 "nonimmediate_operand" ""))
7958 (match_operand:SI 2 "register_operand" ""))))
7959 (clobber (reg:CC FLAGS_REG))])]
7963 (define_insn "*mulsidi3_insn"
7964 [(set (match_operand:DI 0 "register_operand" "=A")
7965 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7966 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7967 (clobber (reg:CC FLAGS_REG))]
7969 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7971 [(set_attr "type" "imul")
7972 (set_attr "length_immediate" "0")
7973 (set (attr "athlon_decode")
7974 (if_then_else (eq_attr "cpu" "athlon")
7975 (const_string "vector")
7976 (const_string "double")))
7977 (set_attr "amdfam10_decode" "double")
7978 (set_attr "mode" "SI")])
7980 (define_expand "umuldi3_highpart"
7981 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7984 (mult:TI (zero_extend:TI
7985 (match_operand:DI 1 "nonimmediate_operand" ""))
7987 (match_operand:DI 2 "register_operand" "")))
7989 (clobber (match_scratch:DI 3 ""))
7990 (clobber (reg:CC FLAGS_REG))])]
7994 (define_insn "*umuldi3_highpart_rex64"
7995 [(set (match_operand:DI 0 "register_operand" "=d")
7998 (mult:TI (zero_extend:TI
7999 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8001 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8003 (clobber (match_scratch:DI 3 "=1"))
8004 (clobber (reg:CC FLAGS_REG))]
8006 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8008 [(set_attr "type" "imul")
8009 (set_attr "length_immediate" "0")
8010 (set (attr "athlon_decode")
8011 (if_then_else (eq_attr "cpu" "athlon")
8012 (const_string "vector")
8013 (const_string "double")))
8014 (set_attr "amdfam10_decode" "double")
8015 (set_attr "mode" "DI")])
8017 (define_expand "umulsi3_highpart"
8018 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8021 (mult:DI (zero_extend:DI
8022 (match_operand:SI 1 "nonimmediate_operand" ""))
8024 (match_operand:SI 2 "register_operand" "")))
8026 (clobber (match_scratch:SI 3 ""))
8027 (clobber (reg:CC FLAGS_REG))])]
8031 (define_insn "*umulsi3_highpart_insn"
8032 [(set (match_operand:SI 0 "register_operand" "=d")
8035 (mult:DI (zero_extend:DI
8036 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8038 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8040 (clobber (match_scratch:SI 3 "=1"))
8041 (clobber (reg:CC FLAGS_REG))]
8042 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8044 [(set_attr "type" "imul")
8045 (set_attr "length_immediate" "0")
8046 (set (attr "athlon_decode")
8047 (if_then_else (eq_attr "cpu" "athlon")
8048 (const_string "vector")
8049 (const_string "double")))
8050 (set_attr "amdfam10_decode" "double")
8051 (set_attr "mode" "SI")])
8053 (define_insn "*umulsi3_highpart_zext"
8054 [(set (match_operand:DI 0 "register_operand" "=d")
8055 (zero_extend:DI (truncate:SI
8057 (mult:DI (zero_extend:DI
8058 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8060 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8062 (clobber (match_scratch:SI 3 "=1"))
8063 (clobber (reg:CC FLAGS_REG))]
8065 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8067 [(set_attr "type" "imul")
8068 (set_attr "length_immediate" "0")
8069 (set (attr "athlon_decode")
8070 (if_then_else (eq_attr "cpu" "athlon")
8071 (const_string "vector")
8072 (const_string "double")))
8073 (set_attr "amdfam10_decode" "double")
8074 (set_attr "mode" "SI")])
8076 (define_expand "smuldi3_highpart"
8077 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8080 (mult:TI (sign_extend:TI
8081 (match_operand:DI 1 "nonimmediate_operand" ""))
8083 (match_operand:DI 2 "register_operand" "")))
8085 (clobber (match_scratch:DI 3 ""))
8086 (clobber (reg:CC FLAGS_REG))])]
8090 (define_insn "*smuldi3_highpart_rex64"
8091 [(set (match_operand:DI 0 "register_operand" "=d")
8094 (mult:TI (sign_extend:TI
8095 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8097 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8099 (clobber (match_scratch:DI 3 "=1"))
8100 (clobber (reg:CC FLAGS_REG))]
8102 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8104 [(set_attr "type" "imul")
8105 (set (attr "athlon_decode")
8106 (if_then_else (eq_attr "cpu" "athlon")
8107 (const_string "vector")
8108 (const_string "double")))
8109 (set_attr "amdfam10_decode" "double")
8110 (set_attr "mode" "DI")])
8112 (define_expand "smulsi3_highpart"
8113 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8116 (mult:DI (sign_extend:DI
8117 (match_operand:SI 1 "nonimmediate_operand" ""))
8119 (match_operand:SI 2 "register_operand" "")))
8121 (clobber (match_scratch:SI 3 ""))
8122 (clobber (reg:CC FLAGS_REG))])]
8126 (define_insn "*smulsi3_highpart_insn"
8127 [(set (match_operand:SI 0 "register_operand" "=d")
8130 (mult:DI (sign_extend:DI
8131 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8133 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8135 (clobber (match_scratch:SI 3 "=1"))
8136 (clobber (reg:CC FLAGS_REG))]
8137 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8139 [(set_attr "type" "imul")
8140 (set (attr "athlon_decode")
8141 (if_then_else (eq_attr "cpu" "athlon")
8142 (const_string "vector")
8143 (const_string "double")))
8144 (set_attr "amdfam10_decode" "double")
8145 (set_attr "mode" "SI")])
8147 (define_insn "*smulsi3_highpart_zext"
8148 [(set (match_operand:DI 0 "register_operand" "=d")
8149 (zero_extend:DI (truncate:SI
8151 (mult:DI (sign_extend:DI
8152 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8154 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8156 (clobber (match_scratch:SI 3 "=1"))
8157 (clobber (reg:CC FLAGS_REG))]
8159 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8161 [(set_attr "type" "imul")
8162 (set (attr "athlon_decode")
8163 (if_then_else (eq_attr "cpu" "athlon")
8164 (const_string "vector")
8165 (const_string "double")))
8166 (set_attr "amdfam10_decode" "double")
8167 (set_attr "mode" "SI")])
8169 ;; The patterns that match these are at the end of this file.
8171 (define_expand "mulxf3"
8172 [(set (match_operand:XF 0 "register_operand" "")
8173 (mult:XF (match_operand:XF 1 "register_operand" "")
8174 (match_operand:XF 2 "register_operand" "")))]
8178 (define_expand "mul<mode>3"
8179 [(set (match_operand:MODEF 0 "register_operand" "")
8180 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8181 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8182 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8185 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8188 ;; Divide instructions
8190 (define_insn "divqi3"
8191 [(set (match_operand:QI 0 "register_operand" "=a")
8192 (div:QI (match_operand:HI 1 "register_operand" "0")
8193 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8194 (clobber (reg:CC FLAGS_REG))]
8195 "TARGET_QIMODE_MATH"
8197 [(set_attr "type" "idiv")
8198 (set_attr "mode" "QI")])
8200 (define_insn "udivqi3"
8201 [(set (match_operand:QI 0 "register_operand" "=a")
8202 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8203 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8204 (clobber (reg:CC FLAGS_REG))]
8205 "TARGET_QIMODE_MATH"
8207 [(set_attr "type" "idiv")
8208 (set_attr "mode" "QI")])
8210 ;; The patterns that match these are at the end of this file.
8212 (define_expand "divxf3"
8213 [(set (match_operand:XF 0 "register_operand" "")
8214 (div:XF (match_operand:XF 1 "register_operand" "")
8215 (match_operand:XF 2 "register_operand" "")))]
8219 (define_expand "divdf3"
8220 [(set (match_operand:DF 0 "register_operand" "")
8221 (div:DF (match_operand:DF 1 "register_operand" "")
8222 (match_operand:DF 2 "nonimmediate_operand" "")))]
8223 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8226 (define_expand "divsf3"
8227 [(set (match_operand:SF 0 "register_operand" "")
8228 (div:SF (match_operand:SF 1 "register_operand" "")
8229 (match_operand:SF 2 "nonimmediate_operand" "")))]
8230 "TARGET_80387 || TARGET_SSE_MATH"
8232 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8233 && flag_finite_math_only && !flag_trapping_math
8234 && flag_unsafe_math_optimizations)
8236 ix86_emit_swdivsf (operands[0], operands[1],
8237 operands[2], SFmode);
8242 ;; Remainder instructions.
8244 (define_expand "divmoddi4"
8245 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8246 (div:DI (match_operand:DI 1 "register_operand" "")
8247 (match_operand:DI 2 "nonimmediate_operand" "")))
8248 (set (match_operand:DI 3 "register_operand" "")
8249 (mod:DI (match_dup 1) (match_dup 2)))
8250 (clobber (reg:CC FLAGS_REG))])]
8254 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8255 ;; Penalize eax case slightly because it results in worse scheduling
8257 (define_insn "*divmoddi4_nocltd_rex64"
8258 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8259 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8260 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8261 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8262 (mod:DI (match_dup 2) (match_dup 3)))
8263 (clobber (reg:CC FLAGS_REG))]
8264 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8266 [(set_attr "type" "multi")])
8268 (define_insn "*divmoddi4_cltd_rex64"
8269 [(set (match_operand:DI 0 "register_operand" "=a")
8270 (div:DI (match_operand:DI 2 "register_operand" "a")
8271 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8272 (set (match_operand:DI 1 "register_operand" "=&d")
8273 (mod:DI (match_dup 2) (match_dup 3)))
8274 (clobber (reg:CC FLAGS_REG))]
8275 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8277 [(set_attr "type" "multi")])
8279 (define_insn "*divmoddi_noext_rex64"
8280 [(set (match_operand:DI 0 "register_operand" "=a")
8281 (div:DI (match_operand:DI 1 "register_operand" "0")
8282 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8283 (set (match_operand:DI 3 "register_operand" "=d")
8284 (mod:DI (match_dup 1) (match_dup 2)))
8285 (use (match_operand:DI 4 "register_operand" "3"))
8286 (clobber (reg:CC FLAGS_REG))]
8289 [(set_attr "type" "idiv")
8290 (set_attr "mode" "DI")])
8293 [(set (match_operand:DI 0 "register_operand" "")
8294 (div:DI (match_operand:DI 1 "register_operand" "")
8295 (match_operand:DI 2 "nonimmediate_operand" "")))
8296 (set (match_operand:DI 3 "register_operand" "")
8297 (mod:DI (match_dup 1) (match_dup 2)))
8298 (clobber (reg:CC FLAGS_REG))]
8299 "TARGET_64BIT && reload_completed"
8300 [(parallel [(set (match_dup 3)
8301 (ashiftrt:DI (match_dup 4) (const_int 63)))
8302 (clobber (reg:CC FLAGS_REG))])
8303 (parallel [(set (match_dup 0)
8304 (div:DI (reg:DI 0) (match_dup 2)))
8306 (mod:DI (reg:DI 0) (match_dup 2)))
8308 (clobber (reg:CC FLAGS_REG))])]
8310 /* Avoid use of cltd in favor of a mov+shift. */
8311 if (!TARGET_USE_CLTD && !optimize_size)
8313 if (true_regnum (operands[1]))
8314 emit_move_insn (operands[0], operands[1]);
8316 emit_move_insn (operands[3], operands[1]);
8317 operands[4] = operands[3];
8321 gcc_assert (!true_regnum (operands[1]));
8322 operands[4] = operands[1];
8327 (define_expand "divmodsi4"
8328 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8329 (div:SI (match_operand:SI 1 "register_operand" "")
8330 (match_operand:SI 2 "nonimmediate_operand" "")))
8331 (set (match_operand:SI 3 "register_operand" "")
8332 (mod:SI (match_dup 1) (match_dup 2)))
8333 (clobber (reg:CC FLAGS_REG))])]
8337 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8338 ;; Penalize eax case slightly because it results in worse scheduling
8340 (define_insn "*divmodsi4_nocltd"
8341 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8342 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8343 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8344 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8345 (mod:SI (match_dup 2) (match_dup 3)))
8346 (clobber (reg:CC FLAGS_REG))]
8347 "!optimize_size && !TARGET_USE_CLTD"
8349 [(set_attr "type" "multi")])
8351 (define_insn "*divmodsi4_cltd"
8352 [(set (match_operand:SI 0 "register_operand" "=a")
8353 (div:SI (match_operand:SI 2 "register_operand" "a")
8354 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8355 (set (match_operand:SI 1 "register_operand" "=&d")
8356 (mod:SI (match_dup 2) (match_dup 3)))
8357 (clobber (reg:CC FLAGS_REG))]
8358 "optimize_size || TARGET_USE_CLTD"
8360 [(set_attr "type" "multi")])
8362 (define_insn "*divmodsi_noext"
8363 [(set (match_operand:SI 0 "register_operand" "=a")
8364 (div:SI (match_operand:SI 1 "register_operand" "0")
8365 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8366 (set (match_operand:SI 3 "register_operand" "=d")
8367 (mod:SI (match_dup 1) (match_dup 2)))
8368 (use (match_operand:SI 4 "register_operand" "3"))
8369 (clobber (reg:CC FLAGS_REG))]
8372 [(set_attr "type" "idiv")
8373 (set_attr "mode" "SI")])
8376 [(set (match_operand:SI 0 "register_operand" "")
8377 (div:SI (match_operand:SI 1 "register_operand" "")
8378 (match_operand:SI 2 "nonimmediate_operand" "")))
8379 (set (match_operand:SI 3 "register_operand" "")
8380 (mod:SI (match_dup 1) (match_dup 2)))
8381 (clobber (reg:CC FLAGS_REG))]
8383 [(parallel [(set (match_dup 3)
8384 (ashiftrt:SI (match_dup 4) (const_int 31)))
8385 (clobber (reg:CC FLAGS_REG))])
8386 (parallel [(set (match_dup 0)
8387 (div:SI (reg:SI 0) (match_dup 2)))
8389 (mod:SI (reg:SI 0) (match_dup 2)))
8391 (clobber (reg:CC FLAGS_REG))])]
8393 /* Avoid use of cltd in favor of a mov+shift. */
8394 if (!TARGET_USE_CLTD && !optimize_size)
8396 if (true_regnum (operands[1]))
8397 emit_move_insn (operands[0], operands[1]);
8399 emit_move_insn (operands[3], operands[1]);
8400 operands[4] = operands[3];
8404 gcc_assert (!true_regnum (operands[1]));
8405 operands[4] = operands[1];
8409 (define_insn "divmodhi4"
8410 [(set (match_operand:HI 0 "register_operand" "=a")
8411 (div:HI (match_operand:HI 1 "register_operand" "0")
8412 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8413 (set (match_operand:HI 3 "register_operand" "=&d")
8414 (mod:HI (match_dup 1) (match_dup 2)))
8415 (clobber (reg:CC FLAGS_REG))]
8416 "TARGET_HIMODE_MATH"
8418 [(set_attr "type" "multi")
8419 (set_attr "length_immediate" "0")
8420 (set_attr "mode" "SI")])
8422 (define_insn "udivmoddi4"
8423 [(set (match_operand:DI 0 "register_operand" "=a")
8424 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8425 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8426 (set (match_operand:DI 3 "register_operand" "=&d")
8427 (umod:DI (match_dup 1) (match_dup 2)))
8428 (clobber (reg:CC FLAGS_REG))]
8430 "xor{q}\t%3, %3\;div{q}\t%2"
8431 [(set_attr "type" "multi")
8432 (set_attr "length_immediate" "0")
8433 (set_attr "mode" "DI")])
8435 (define_insn "*udivmoddi4_noext"
8436 [(set (match_operand:DI 0 "register_operand" "=a")
8437 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8438 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8439 (set (match_operand:DI 3 "register_operand" "=d")
8440 (umod:DI (match_dup 1) (match_dup 2)))
8442 (clobber (reg:CC FLAGS_REG))]
8445 [(set_attr "type" "idiv")
8446 (set_attr "mode" "DI")])
8449 [(set (match_operand:DI 0 "register_operand" "")
8450 (udiv:DI (match_operand:DI 1 "register_operand" "")
8451 (match_operand:DI 2 "nonimmediate_operand" "")))
8452 (set (match_operand:DI 3 "register_operand" "")
8453 (umod:DI (match_dup 1) (match_dup 2)))
8454 (clobber (reg:CC FLAGS_REG))]
8455 "TARGET_64BIT && reload_completed"
8456 [(set (match_dup 3) (const_int 0))
8457 (parallel [(set (match_dup 0)
8458 (udiv:DI (match_dup 1) (match_dup 2)))
8460 (umod:DI (match_dup 1) (match_dup 2)))
8462 (clobber (reg:CC FLAGS_REG))])]
8465 (define_insn "udivmodsi4"
8466 [(set (match_operand:SI 0 "register_operand" "=a")
8467 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8468 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8469 (set (match_operand:SI 3 "register_operand" "=&d")
8470 (umod:SI (match_dup 1) (match_dup 2)))
8471 (clobber (reg:CC FLAGS_REG))]
8473 "xor{l}\t%3, %3\;div{l}\t%2"
8474 [(set_attr "type" "multi")
8475 (set_attr "length_immediate" "0")
8476 (set_attr "mode" "SI")])
8478 (define_insn "*udivmodsi4_noext"
8479 [(set (match_operand:SI 0 "register_operand" "=a")
8480 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8481 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8482 (set (match_operand:SI 3 "register_operand" "=d")
8483 (umod:SI (match_dup 1) (match_dup 2)))
8485 (clobber (reg:CC FLAGS_REG))]
8488 [(set_attr "type" "idiv")
8489 (set_attr "mode" "SI")])
8492 [(set (match_operand:SI 0 "register_operand" "")
8493 (udiv:SI (match_operand:SI 1 "register_operand" "")
8494 (match_operand:SI 2 "nonimmediate_operand" "")))
8495 (set (match_operand:SI 3 "register_operand" "")
8496 (umod:SI (match_dup 1) (match_dup 2)))
8497 (clobber (reg:CC FLAGS_REG))]
8499 [(set (match_dup 3) (const_int 0))
8500 (parallel [(set (match_dup 0)
8501 (udiv:SI (match_dup 1) (match_dup 2)))
8503 (umod:SI (match_dup 1) (match_dup 2)))
8505 (clobber (reg:CC FLAGS_REG))])]
8508 (define_expand "udivmodhi4"
8509 [(set (match_dup 4) (const_int 0))
8510 (parallel [(set (match_operand:HI 0 "register_operand" "")
8511 (udiv:HI (match_operand:HI 1 "register_operand" "")
8512 (match_operand:HI 2 "nonimmediate_operand" "")))
8513 (set (match_operand:HI 3 "register_operand" "")
8514 (umod:HI (match_dup 1) (match_dup 2)))
8516 (clobber (reg:CC FLAGS_REG))])]
8517 "TARGET_HIMODE_MATH"
8518 "operands[4] = gen_reg_rtx (HImode);")
8520 (define_insn "*udivmodhi_noext"
8521 [(set (match_operand:HI 0 "register_operand" "=a")
8522 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8523 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8524 (set (match_operand:HI 3 "register_operand" "=d")
8525 (umod:HI (match_dup 1) (match_dup 2)))
8526 (use (match_operand:HI 4 "register_operand" "3"))
8527 (clobber (reg:CC FLAGS_REG))]
8530 [(set_attr "type" "idiv")
8531 (set_attr "mode" "HI")])
8533 ;; We cannot use div/idiv for double division, because it causes
8534 ;; "division by zero" on the overflow and that's not what we expect
8535 ;; from truncate. Because true (non truncating) double division is
8536 ;; never generated, we can't create this insn anyway.
8539 ; [(set (match_operand:SI 0 "register_operand" "=a")
8541 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8543 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8544 ; (set (match_operand:SI 3 "register_operand" "=d")
8546 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8547 ; (clobber (reg:CC FLAGS_REG))]
8549 ; "div{l}\t{%2, %0|%0, %2}"
8550 ; [(set_attr "type" "idiv")])
8552 ;;- Logical AND instructions
8554 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8555 ;; Note that this excludes ah.
8557 (define_insn "*testdi_1_rex64"
8558 [(set (reg FLAGS_REG)
8560 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8561 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8563 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8564 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8566 test{l}\t{%k1, %k0|%k0, %k1}
8567 test{l}\t{%k1, %k0|%k0, %k1}
8568 test{q}\t{%1, %0|%0, %1}
8569 test{q}\t{%1, %0|%0, %1}
8570 test{q}\t{%1, %0|%0, %1}"
8571 [(set_attr "type" "test")
8572 (set_attr "modrm" "0,1,0,1,1")
8573 (set_attr "mode" "SI,SI,DI,DI,DI")
8574 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8576 (define_insn "testsi_1"
8577 [(set (reg FLAGS_REG)
8579 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8580 (match_operand:SI 1 "general_operand" "in,in,rin"))
8582 "ix86_match_ccmode (insn, CCNOmode)
8583 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8584 "test{l}\t{%1, %0|%0, %1}"
8585 [(set_attr "type" "test")
8586 (set_attr "modrm" "0,1,1")
8587 (set_attr "mode" "SI")
8588 (set_attr "pent_pair" "uv,np,uv")])
8590 (define_expand "testsi_ccno_1"
8591 [(set (reg:CCNO FLAGS_REG)
8593 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8594 (match_operand:SI 1 "nonmemory_operand" ""))
8599 (define_insn "*testhi_1"
8600 [(set (reg FLAGS_REG)
8601 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8602 (match_operand:HI 1 "general_operand" "n,n,rn"))
8604 "ix86_match_ccmode (insn, CCNOmode)
8605 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8606 "test{w}\t{%1, %0|%0, %1}"
8607 [(set_attr "type" "test")
8608 (set_attr "modrm" "0,1,1")
8609 (set_attr "mode" "HI")
8610 (set_attr "pent_pair" "uv,np,uv")])
8612 (define_expand "testqi_ccz_1"
8613 [(set (reg:CCZ FLAGS_REG)
8614 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8615 (match_operand:QI 1 "nonmemory_operand" ""))
8620 (define_insn "*testqi_1_maybe_si"
8621 [(set (reg FLAGS_REG)
8624 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8625 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8627 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8628 && ix86_match_ccmode (insn,
8629 CONST_INT_P (operands[1])
8630 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8632 if (which_alternative == 3)
8634 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8635 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8636 return "test{l}\t{%1, %k0|%k0, %1}";
8638 return "test{b}\t{%1, %0|%0, %1}";
8640 [(set_attr "type" "test")
8641 (set_attr "modrm" "0,1,1,1")
8642 (set_attr "mode" "QI,QI,QI,SI")
8643 (set_attr "pent_pair" "uv,np,uv,np")])
8645 (define_insn "*testqi_1"
8646 [(set (reg FLAGS_REG)
8649 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8650 (match_operand:QI 1 "general_operand" "n,n,qn"))
8652 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8653 && ix86_match_ccmode (insn, CCNOmode)"
8654 "test{b}\t{%1, %0|%0, %1}"
8655 [(set_attr "type" "test")
8656 (set_attr "modrm" "0,1,1")
8657 (set_attr "mode" "QI")
8658 (set_attr "pent_pair" "uv,np,uv")])
8660 (define_expand "testqi_ext_ccno_0"
8661 [(set (reg:CCNO FLAGS_REG)
8665 (match_operand 0 "ext_register_operand" "")
8668 (match_operand 1 "const_int_operand" ""))
8673 (define_insn "*testqi_ext_0"
8674 [(set (reg FLAGS_REG)
8678 (match_operand 0 "ext_register_operand" "Q")
8681 (match_operand 1 "const_int_operand" "n"))
8683 "ix86_match_ccmode (insn, CCNOmode)"
8684 "test{b}\t{%1, %h0|%h0, %1}"
8685 [(set_attr "type" "test")
8686 (set_attr "mode" "QI")
8687 (set_attr "length_immediate" "1")
8688 (set_attr "pent_pair" "np")])
8690 (define_insn "*testqi_ext_1"
8691 [(set (reg FLAGS_REG)
8695 (match_operand 0 "ext_register_operand" "Q")
8699 (match_operand:QI 1 "general_operand" "Qm")))
8701 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8702 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8703 "test{b}\t{%1, %h0|%h0, %1}"
8704 [(set_attr "type" "test")
8705 (set_attr "mode" "QI")])
8707 (define_insn "*testqi_ext_1_rex64"
8708 [(set (reg FLAGS_REG)
8712 (match_operand 0 "ext_register_operand" "Q")
8716 (match_operand:QI 1 "register_operand" "Q")))
8718 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8719 "test{b}\t{%1, %h0|%h0, %1}"
8720 [(set_attr "type" "test")
8721 (set_attr "mode" "QI")])
8723 (define_insn "*testqi_ext_2"
8724 [(set (reg FLAGS_REG)
8728 (match_operand 0 "ext_register_operand" "Q")
8732 (match_operand 1 "ext_register_operand" "Q")
8736 "ix86_match_ccmode (insn, CCNOmode)"
8737 "test{b}\t{%h1, %h0|%h0, %h1}"
8738 [(set_attr "type" "test")
8739 (set_attr "mode" "QI")])
8741 ;; Combine likes to form bit extractions for some tests. Humor it.
8742 (define_insn "*testqi_ext_3"
8743 [(set (reg FLAGS_REG)
8744 (compare (zero_extract:SI
8745 (match_operand 0 "nonimmediate_operand" "rm")
8746 (match_operand:SI 1 "const_int_operand" "")
8747 (match_operand:SI 2 "const_int_operand" ""))
8749 "ix86_match_ccmode (insn, CCNOmode)
8750 && INTVAL (operands[1]) > 0
8751 && INTVAL (operands[2]) >= 0
8752 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8753 && (GET_MODE (operands[0]) == SImode
8754 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8755 || GET_MODE (operands[0]) == HImode
8756 || GET_MODE (operands[0]) == QImode)"
8759 (define_insn "*testqi_ext_3_rex64"
8760 [(set (reg FLAGS_REG)
8761 (compare (zero_extract:DI
8762 (match_operand 0 "nonimmediate_operand" "rm")
8763 (match_operand:DI 1 "const_int_operand" "")
8764 (match_operand:DI 2 "const_int_operand" ""))
8767 && ix86_match_ccmode (insn, CCNOmode)
8768 && INTVAL (operands[1]) > 0
8769 && INTVAL (operands[2]) >= 0
8770 /* Ensure that resulting mask is zero or sign extended operand. */
8771 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8772 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8773 && INTVAL (operands[1]) > 32))
8774 && (GET_MODE (operands[0]) == SImode
8775 || GET_MODE (operands[0]) == DImode
8776 || GET_MODE (operands[0]) == HImode
8777 || GET_MODE (operands[0]) == QImode)"
8781 [(set (match_operand 0 "flags_reg_operand" "")
8782 (match_operator 1 "compare_operator"
8784 (match_operand 2 "nonimmediate_operand" "")
8785 (match_operand 3 "const_int_operand" "")
8786 (match_operand 4 "const_int_operand" ""))
8788 "ix86_match_ccmode (insn, CCNOmode)"
8789 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8791 rtx val = operands[2];
8792 HOST_WIDE_INT len = INTVAL (operands[3]);
8793 HOST_WIDE_INT pos = INTVAL (operands[4]);
8795 enum machine_mode mode, submode;
8797 mode = GET_MODE (val);
8800 /* ??? Combine likes to put non-volatile mem extractions in QImode
8801 no matter the size of the test. So find a mode that works. */
8802 if (! MEM_VOLATILE_P (val))
8804 mode = smallest_mode_for_size (pos + len, MODE_INT);
8805 val = adjust_address (val, mode, 0);
8808 else if (GET_CODE (val) == SUBREG
8809 && (submode = GET_MODE (SUBREG_REG (val)),
8810 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8811 && pos + len <= GET_MODE_BITSIZE (submode))
8813 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8815 val = SUBREG_REG (val);
8817 else if (mode == HImode && pos + len <= 8)
8819 /* Small HImode tests can be converted to QImode. */
8821 val = gen_lowpart (QImode, val);
8824 if (len == HOST_BITS_PER_WIDE_INT)
8827 mask = ((HOST_WIDE_INT)1 << len) - 1;
8830 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8833 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8834 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8835 ;; this is relatively important trick.
8836 ;; Do the conversion only post-reload to avoid limiting of the register class
8839 [(set (match_operand 0 "flags_reg_operand" "")
8840 (match_operator 1 "compare_operator"
8841 [(and (match_operand 2 "register_operand" "")
8842 (match_operand 3 "const_int_operand" ""))
8845 && QI_REG_P (operands[2])
8846 && GET_MODE (operands[2]) != QImode
8847 && ((ix86_match_ccmode (insn, CCZmode)
8848 && !(INTVAL (operands[3]) & ~(255 << 8)))
8849 || (ix86_match_ccmode (insn, CCNOmode)
8850 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8853 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8856 "operands[2] = gen_lowpart (SImode, operands[2]);
8857 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8860 [(set (match_operand 0 "flags_reg_operand" "")
8861 (match_operator 1 "compare_operator"
8862 [(and (match_operand 2 "nonimmediate_operand" "")
8863 (match_operand 3 "const_int_operand" ""))
8866 && GET_MODE (operands[2]) != QImode
8867 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8868 && ((ix86_match_ccmode (insn, CCZmode)
8869 && !(INTVAL (operands[3]) & ~255))
8870 || (ix86_match_ccmode (insn, CCNOmode)
8871 && !(INTVAL (operands[3]) & ~127)))"
8873 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8875 "operands[2] = gen_lowpart (QImode, operands[2]);
8876 operands[3] = gen_lowpart (QImode, operands[3]);")
8879 ;; %%% This used to optimize known byte-wide and operations to memory,
8880 ;; and sometimes to QImode registers. If this is considered useful,
8881 ;; it should be done with splitters.
8883 (define_expand "anddi3"
8884 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8885 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8886 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8887 (clobber (reg:CC FLAGS_REG))]
8889 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8891 (define_insn "*anddi_1_rex64"
8892 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8893 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8894 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8895 (clobber (reg:CC FLAGS_REG))]
8896 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8898 switch (get_attr_type (insn))
8902 enum machine_mode mode;
8904 gcc_assert (CONST_INT_P (operands[2]));
8905 if (INTVAL (operands[2]) == 0xff)
8909 gcc_assert (INTVAL (operands[2]) == 0xffff);
8913 operands[1] = gen_lowpart (mode, operands[1]);
8915 return "movz{bq|x}\t{%1,%0|%0, %1}";
8917 return "movz{wq|x}\t{%1,%0|%0, %1}";
8921 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8922 if (get_attr_mode (insn) == MODE_SI)
8923 return "and{l}\t{%k2, %k0|%k0, %k2}";
8925 return "and{q}\t{%2, %0|%0, %2}";
8928 [(set_attr "type" "alu,alu,alu,imovx")
8929 (set_attr "length_immediate" "*,*,*,0")
8930 (set_attr "mode" "SI,DI,DI,DI")])
8932 (define_insn "*anddi_2"
8933 [(set (reg FLAGS_REG)
8934 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8935 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8937 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8938 (and:DI (match_dup 1) (match_dup 2)))]
8939 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8940 && ix86_binary_operator_ok (AND, DImode, operands)"
8942 and{l}\t{%k2, %k0|%k0, %k2}
8943 and{q}\t{%2, %0|%0, %2}
8944 and{q}\t{%2, %0|%0, %2}"
8945 [(set_attr "type" "alu")
8946 (set_attr "mode" "SI,DI,DI")])
8948 (define_expand "andsi3"
8949 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8950 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8951 (match_operand:SI 2 "general_operand" "")))
8952 (clobber (reg:CC FLAGS_REG))]
8954 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8956 (define_insn "*andsi_1"
8957 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8958 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8959 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8960 (clobber (reg:CC FLAGS_REG))]
8961 "ix86_binary_operator_ok (AND, SImode, operands)"
8963 switch (get_attr_type (insn))
8967 enum machine_mode mode;
8969 gcc_assert (CONST_INT_P (operands[2]));
8970 if (INTVAL (operands[2]) == 0xff)
8974 gcc_assert (INTVAL (operands[2]) == 0xffff);
8978 operands[1] = gen_lowpart (mode, operands[1]);
8980 return "movz{bl|x}\t{%1,%0|%0, %1}";
8982 return "movz{wl|x}\t{%1,%0|%0, %1}";
8986 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8987 return "and{l}\t{%2, %0|%0, %2}";
8990 [(set_attr "type" "alu,alu,imovx")
8991 (set_attr "length_immediate" "*,*,0")
8992 (set_attr "mode" "SI")])
8995 [(set (match_operand 0 "register_operand" "")
8997 (const_int -65536)))
8998 (clobber (reg:CC FLAGS_REG))]
8999 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9000 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9001 "operands[1] = gen_lowpart (HImode, operands[0]);")
9004 [(set (match_operand 0 "ext_register_operand" "")
9007 (clobber (reg:CC FLAGS_REG))]
9008 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9009 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9010 "operands[1] = gen_lowpart (QImode, operands[0]);")
9013 [(set (match_operand 0 "ext_register_operand" "")
9015 (const_int -65281)))
9016 (clobber (reg:CC FLAGS_REG))]
9017 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9018 [(parallel [(set (zero_extract:SI (match_dup 0)
9022 (zero_extract:SI (match_dup 0)
9025 (zero_extract:SI (match_dup 0)
9028 (clobber (reg:CC FLAGS_REG))])]
9029 "operands[0] = gen_lowpart (SImode, operands[0]);")
9031 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9032 (define_insn "*andsi_1_zext"
9033 [(set (match_operand:DI 0 "register_operand" "=r")
9035 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9036 (match_operand:SI 2 "general_operand" "g"))))
9037 (clobber (reg:CC FLAGS_REG))]
9038 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9039 "and{l}\t{%2, %k0|%k0, %2}"
9040 [(set_attr "type" "alu")
9041 (set_attr "mode" "SI")])
9043 (define_insn "*andsi_2"
9044 [(set (reg FLAGS_REG)
9045 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9046 (match_operand:SI 2 "general_operand" "g,ri"))
9048 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9049 (and:SI (match_dup 1) (match_dup 2)))]
9050 "ix86_match_ccmode (insn, CCNOmode)
9051 && ix86_binary_operator_ok (AND, SImode, operands)"
9052 "and{l}\t{%2, %0|%0, %2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "mode" "SI")])
9056 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9057 (define_insn "*andsi_2_zext"
9058 [(set (reg FLAGS_REG)
9059 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9060 (match_operand:SI 2 "general_operand" "g"))
9062 (set (match_operand:DI 0 "register_operand" "=r")
9063 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9064 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9065 && ix86_binary_operator_ok (AND, SImode, operands)"
9066 "and{l}\t{%2, %k0|%k0, %2}"
9067 [(set_attr "type" "alu")
9068 (set_attr "mode" "SI")])
9070 (define_expand "andhi3"
9071 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9072 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9073 (match_operand:HI 2 "general_operand" "")))
9074 (clobber (reg:CC FLAGS_REG))]
9075 "TARGET_HIMODE_MATH"
9076 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9078 (define_insn "*andhi_1"
9079 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9080 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9081 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9082 (clobber (reg:CC FLAGS_REG))]
9083 "ix86_binary_operator_ok (AND, HImode, operands)"
9085 switch (get_attr_type (insn))
9088 gcc_assert (CONST_INT_P (operands[2]));
9089 gcc_assert (INTVAL (operands[2]) == 0xff);
9090 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9093 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9095 return "and{w}\t{%2, %0|%0, %2}";
9098 [(set_attr "type" "alu,alu,imovx")
9099 (set_attr "length_immediate" "*,*,0")
9100 (set_attr "mode" "HI,HI,SI")])
9102 (define_insn "*andhi_2"
9103 [(set (reg FLAGS_REG)
9104 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9105 (match_operand:HI 2 "general_operand" "g,ri"))
9107 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9108 (and:HI (match_dup 1) (match_dup 2)))]
9109 "ix86_match_ccmode (insn, CCNOmode)
9110 && ix86_binary_operator_ok (AND, HImode, operands)"
9111 "and{w}\t{%2, %0|%0, %2}"
9112 [(set_attr "type" "alu")
9113 (set_attr "mode" "HI")])
9115 (define_expand "andqi3"
9116 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9117 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9118 (match_operand:QI 2 "general_operand" "")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "TARGET_QIMODE_MATH"
9121 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9123 ;; %%% Potential partial reg stall on alternative 2. What to do?
9124 (define_insn "*andqi_1"
9125 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9126 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9127 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9128 (clobber (reg:CC FLAGS_REG))]
9129 "ix86_binary_operator_ok (AND, QImode, operands)"
9131 and{b}\t{%2, %0|%0, %2}
9132 and{b}\t{%2, %0|%0, %2}
9133 and{l}\t{%k2, %k0|%k0, %k2}"
9134 [(set_attr "type" "alu")
9135 (set_attr "mode" "QI,QI,SI")])
9137 (define_insn "*andqi_1_slp"
9138 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9139 (and:QI (match_dup 0)
9140 (match_operand:QI 1 "general_operand" "qi,qmi")))
9141 (clobber (reg:CC FLAGS_REG))]
9142 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9143 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9144 "and{b}\t{%1, %0|%0, %1}"
9145 [(set_attr "type" "alu1")
9146 (set_attr "mode" "QI")])
9148 (define_insn "*andqi_2_maybe_si"
9149 [(set (reg FLAGS_REG)
9151 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9152 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9154 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9155 (and:QI (match_dup 1) (match_dup 2)))]
9156 "ix86_binary_operator_ok (AND, QImode, operands)
9157 && ix86_match_ccmode (insn,
9158 CONST_INT_P (operands[2])
9159 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9161 if (which_alternative == 2)
9163 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9164 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9165 return "and{l}\t{%2, %k0|%k0, %2}";
9167 return "and{b}\t{%2, %0|%0, %2}";
9169 [(set_attr "type" "alu")
9170 (set_attr "mode" "QI,QI,SI")])
9172 (define_insn "*andqi_2"
9173 [(set (reg FLAGS_REG)
9175 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9176 (match_operand:QI 2 "general_operand" "qim,qi"))
9178 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9179 (and:QI (match_dup 1) (match_dup 2)))]
9180 "ix86_match_ccmode (insn, CCNOmode)
9181 && ix86_binary_operator_ok (AND, QImode, operands)"
9182 "and{b}\t{%2, %0|%0, %2}"
9183 [(set_attr "type" "alu")
9184 (set_attr "mode" "QI")])
9186 (define_insn "*andqi_2_slp"
9187 [(set (reg FLAGS_REG)
9189 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9190 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9192 (set (strict_low_part (match_dup 0))
9193 (and:QI (match_dup 0) (match_dup 1)))]
9194 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9195 && ix86_match_ccmode (insn, CCNOmode)
9196 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9197 "and{b}\t{%1, %0|%0, %1}"
9198 [(set_attr "type" "alu1")
9199 (set_attr "mode" "QI")])
9201 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9202 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9203 ;; for a QImode operand, which of course failed.
9205 (define_insn "andqi_ext_0"
9206 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9211 (match_operand 1 "ext_register_operand" "0")
9214 (match_operand 2 "const_int_operand" "n")))
9215 (clobber (reg:CC FLAGS_REG))]
9217 "and{b}\t{%2, %h0|%h0, %2}"
9218 [(set_attr "type" "alu")
9219 (set_attr "length_immediate" "1")
9220 (set_attr "mode" "QI")])
9222 ;; Generated by peephole translating test to and. This shows up
9223 ;; often in fp comparisons.
9225 (define_insn "*andqi_ext_0_cc"
9226 [(set (reg FLAGS_REG)
9230 (match_operand 1 "ext_register_operand" "0")
9233 (match_operand 2 "const_int_operand" "n"))
9235 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9244 "ix86_match_ccmode (insn, CCNOmode)"
9245 "and{b}\t{%2, %h0|%h0, %2}"
9246 [(set_attr "type" "alu")
9247 (set_attr "length_immediate" "1")
9248 (set_attr "mode" "QI")])
9250 (define_insn "*andqi_ext_1"
9251 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9256 (match_operand 1 "ext_register_operand" "0")
9260 (match_operand:QI 2 "general_operand" "Qm"))))
9261 (clobber (reg:CC FLAGS_REG))]
9263 "and{b}\t{%2, %h0|%h0, %2}"
9264 [(set_attr "type" "alu")
9265 (set_attr "length_immediate" "0")
9266 (set_attr "mode" "QI")])
9268 (define_insn "*andqi_ext_1_rex64"
9269 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9274 (match_operand 1 "ext_register_operand" "0")
9278 (match_operand 2 "ext_register_operand" "Q"))))
9279 (clobber (reg:CC FLAGS_REG))]
9281 "and{b}\t{%2, %h0|%h0, %2}"
9282 [(set_attr "type" "alu")
9283 (set_attr "length_immediate" "0")
9284 (set_attr "mode" "QI")])
9286 (define_insn "*andqi_ext_2"
9287 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9292 (match_operand 1 "ext_register_operand" "%0")
9296 (match_operand 2 "ext_register_operand" "Q")
9299 (clobber (reg:CC FLAGS_REG))]
9301 "and{b}\t{%h2, %h0|%h0, %h2}"
9302 [(set_attr "type" "alu")
9303 (set_attr "length_immediate" "0")
9304 (set_attr "mode" "QI")])
9306 ;; Convert wide AND instructions with immediate operand to shorter QImode
9307 ;; equivalents when possible.
9308 ;; Don't do the splitting with memory operands, since it introduces risk
9309 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9310 ;; for size, but that can (should?) be handled by generic code instead.
9312 [(set (match_operand 0 "register_operand" "")
9313 (and (match_operand 1 "register_operand" "")
9314 (match_operand 2 "const_int_operand" "")))
9315 (clobber (reg:CC FLAGS_REG))]
9317 && QI_REG_P (operands[0])
9318 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9319 && !(~INTVAL (operands[2]) & ~(255 << 8))
9320 && GET_MODE (operands[0]) != QImode"
9321 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9322 (and:SI (zero_extract:SI (match_dup 1)
9323 (const_int 8) (const_int 8))
9325 (clobber (reg:CC FLAGS_REG))])]
9326 "operands[0] = gen_lowpart (SImode, operands[0]);
9327 operands[1] = gen_lowpart (SImode, operands[1]);
9328 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9330 ;; Since AND can be encoded with sign extended immediate, this is only
9331 ;; profitable when 7th bit is not set.
9333 [(set (match_operand 0 "register_operand" "")
9334 (and (match_operand 1 "general_operand" "")
9335 (match_operand 2 "const_int_operand" "")))
9336 (clobber (reg:CC FLAGS_REG))]
9338 && ANY_QI_REG_P (operands[0])
9339 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9340 && !(~INTVAL (operands[2]) & ~255)
9341 && !(INTVAL (operands[2]) & 128)
9342 && GET_MODE (operands[0]) != QImode"
9343 [(parallel [(set (strict_low_part (match_dup 0))
9344 (and:QI (match_dup 1)
9346 (clobber (reg:CC FLAGS_REG))])]
9347 "operands[0] = gen_lowpart (QImode, operands[0]);
9348 operands[1] = gen_lowpart (QImode, operands[1]);
9349 operands[2] = gen_lowpart (QImode, operands[2]);")
9351 ;; Logical inclusive OR instructions
9353 ;; %%% This used to optimize known byte-wide and operations to memory.
9354 ;; If this is considered useful, it should be done with splitters.
9356 (define_expand "iordi3"
9357 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9358 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9359 (match_operand:DI 2 "x86_64_general_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))]
9362 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9364 (define_insn "*iordi_1_rex64"
9365 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9366 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9367 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9368 (clobber (reg:CC FLAGS_REG))]
9370 && ix86_binary_operator_ok (IOR, DImode, operands)"
9371 "or{q}\t{%2, %0|%0, %2}"
9372 [(set_attr "type" "alu")
9373 (set_attr "mode" "DI")])
9375 (define_insn "*iordi_2_rex64"
9376 [(set (reg FLAGS_REG)
9377 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9378 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9380 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9381 (ior:DI (match_dup 1) (match_dup 2)))]
9383 && ix86_match_ccmode (insn, CCNOmode)
9384 && ix86_binary_operator_ok (IOR, DImode, operands)"
9385 "or{q}\t{%2, %0|%0, %2}"
9386 [(set_attr "type" "alu")
9387 (set_attr "mode" "DI")])
9389 (define_insn "*iordi_3_rex64"
9390 [(set (reg FLAGS_REG)
9391 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9392 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9394 (clobber (match_scratch:DI 0 "=r"))]
9396 && ix86_match_ccmode (insn, CCNOmode)
9397 && ix86_binary_operator_ok (IOR, DImode, operands)"
9398 "or{q}\t{%2, %0|%0, %2}"
9399 [(set_attr "type" "alu")
9400 (set_attr "mode" "DI")])
9403 (define_expand "iorsi3"
9404 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9405 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9406 (match_operand:SI 2 "general_operand" "")))
9407 (clobber (reg:CC FLAGS_REG))]
9409 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9411 (define_insn "*iorsi_1"
9412 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9413 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9414 (match_operand:SI 2 "general_operand" "ri,g")))
9415 (clobber (reg:CC FLAGS_REG))]
9416 "ix86_binary_operator_ok (IOR, SImode, operands)"
9417 "or{l}\t{%2, %0|%0, %2}"
9418 [(set_attr "type" "alu")
9419 (set_attr "mode" "SI")])
9421 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9422 (define_insn "*iorsi_1_zext"
9423 [(set (match_operand:DI 0 "register_operand" "=r")
9425 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9426 (match_operand:SI 2 "general_operand" "g"))))
9427 (clobber (reg:CC FLAGS_REG))]
9428 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9429 "or{l}\t{%2, %k0|%k0, %2}"
9430 [(set_attr "type" "alu")
9431 (set_attr "mode" "SI")])
9433 (define_insn "*iorsi_1_zext_imm"
9434 [(set (match_operand:DI 0 "register_operand" "=r")
9435 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9436 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9437 (clobber (reg:CC FLAGS_REG))]
9439 "or{l}\t{%2, %k0|%k0, %2}"
9440 [(set_attr "type" "alu")
9441 (set_attr "mode" "SI")])
9443 (define_insn "*iorsi_2"
9444 [(set (reg FLAGS_REG)
9445 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9446 (match_operand:SI 2 "general_operand" "g,ri"))
9448 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9449 (ior:SI (match_dup 1) (match_dup 2)))]
9450 "ix86_match_ccmode (insn, CCNOmode)
9451 && ix86_binary_operator_ok (IOR, SImode, operands)"
9452 "or{l}\t{%2, %0|%0, %2}"
9453 [(set_attr "type" "alu")
9454 (set_attr "mode" "SI")])
9456 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9457 ;; ??? Special case for immediate operand is missing - it is tricky.
9458 (define_insn "*iorsi_2_zext"
9459 [(set (reg FLAGS_REG)
9460 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9461 (match_operand:SI 2 "general_operand" "g"))
9463 (set (match_operand:DI 0 "register_operand" "=r")
9464 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9465 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9466 && ix86_binary_operator_ok (IOR, SImode, operands)"
9467 "or{l}\t{%2, %k0|%k0, %2}"
9468 [(set_attr "type" "alu")
9469 (set_attr "mode" "SI")])
9471 (define_insn "*iorsi_2_zext_imm"
9472 [(set (reg FLAGS_REG)
9473 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9474 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9476 (set (match_operand:DI 0 "register_operand" "=r")
9477 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9478 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9479 && ix86_binary_operator_ok (IOR, SImode, operands)"
9480 "or{l}\t{%2, %k0|%k0, %2}"
9481 [(set_attr "type" "alu")
9482 (set_attr "mode" "SI")])
9484 (define_insn "*iorsi_3"
9485 [(set (reg FLAGS_REG)
9486 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9487 (match_operand:SI 2 "general_operand" "g"))
9489 (clobber (match_scratch:SI 0 "=r"))]
9490 "ix86_match_ccmode (insn, CCNOmode)
9491 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9492 "or{l}\t{%2, %0|%0, %2}"
9493 [(set_attr "type" "alu")
9494 (set_attr "mode" "SI")])
9496 (define_expand "iorhi3"
9497 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9498 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9499 (match_operand:HI 2 "general_operand" "")))
9500 (clobber (reg:CC FLAGS_REG))]
9501 "TARGET_HIMODE_MATH"
9502 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9504 (define_insn "*iorhi_1"
9505 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9506 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9507 (match_operand:HI 2 "general_operand" "g,ri")))
9508 (clobber (reg:CC FLAGS_REG))]
9509 "ix86_binary_operator_ok (IOR, HImode, operands)"
9510 "or{w}\t{%2, %0|%0, %2}"
9511 [(set_attr "type" "alu")
9512 (set_attr "mode" "HI")])
9514 (define_insn "*iorhi_2"
9515 [(set (reg FLAGS_REG)
9516 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9517 (match_operand:HI 2 "general_operand" "g,ri"))
9519 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9520 (ior:HI (match_dup 1) (match_dup 2)))]
9521 "ix86_match_ccmode (insn, CCNOmode)
9522 && ix86_binary_operator_ok (IOR, HImode, operands)"
9523 "or{w}\t{%2, %0|%0, %2}"
9524 [(set_attr "type" "alu")
9525 (set_attr "mode" "HI")])
9527 (define_insn "*iorhi_3"
9528 [(set (reg FLAGS_REG)
9529 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9530 (match_operand:HI 2 "general_operand" "g"))
9532 (clobber (match_scratch:HI 0 "=r"))]
9533 "ix86_match_ccmode (insn, CCNOmode)
9534 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9535 "or{w}\t{%2, %0|%0, %2}"
9536 [(set_attr "type" "alu")
9537 (set_attr "mode" "HI")])
9539 (define_expand "iorqi3"
9540 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9541 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9542 (match_operand:QI 2 "general_operand" "")))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "TARGET_QIMODE_MATH"
9545 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9547 ;; %%% Potential partial reg stall on alternative 2. What to do?
9548 (define_insn "*iorqi_1"
9549 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9550 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9551 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9552 (clobber (reg:CC FLAGS_REG))]
9553 "ix86_binary_operator_ok (IOR, QImode, operands)"
9555 or{b}\t{%2, %0|%0, %2}
9556 or{b}\t{%2, %0|%0, %2}
9557 or{l}\t{%k2, %k0|%k0, %k2}"
9558 [(set_attr "type" "alu")
9559 (set_attr "mode" "QI,QI,SI")])
9561 (define_insn "*iorqi_1_slp"
9562 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9563 (ior:QI (match_dup 0)
9564 (match_operand:QI 1 "general_operand" "qmi,qi")))
9565 (clobber (reg:CC FLAGS_REG))]
9566 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9567 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9568 "or{b}\t{%1, %0|%0, %1}"
9569 [(set_attr "type" "alu1")
9570 (set_attr "mode" "QI")])
9572 (define_insn "*iorqi_2"
9573 [(set (reg FLAGS_REG)
9574 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9575 (match_operand:QI 2 "general_operand" "qim,qi"))
9577 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9578 (ior:QI (match_dup 1) (match_dup 2)))]
9579 "ix86_match_ccmode (insn, CCNOmode)
9580 && ix86_binary_operator_ok (IOR, QImode, operands)"
9581 "or{b}\t{%2, %0|%0, %2}"
9582 [(set_attr "type" "alu")
9583 (set_attr "mode" "QI")])
9585 (define_insn "*iorqi_2_slp"
9586 [(set (reg FLAGS_REG)
9587 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9588 (match_operand:QI 1 "general_operand" "qim,qi"))
9590 (set (strict_low_part (match_dup 0))
9591 (ior:QI (match_dup 0) (match_dup 1)))]
9592 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9593 && ix86_match_ccmode (insn, CCNOmode)
9594 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9595 "or{b}\t{%1, %0|%0, %1}"
9596 [(set_attr "type" "alu1")
9597 (set_attr "mode" "QI")])
9599 (define_insn "*iorqi_3"
9600 [(set (reg FLAGS_REG)
9601 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9602 (match_operand:QI 2 "general_operand" "qim"))
9604 (clobber (match_scratch:QI 0 "=q"))]
9605 "ix86_match_ccmode (insn, CCNOmode)
9606 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9607 "or{b}\t{%2, %0|%0, %2}"
9608 [(set_attr "type" "alu")
9609 (set_attr "mode" "QI")])
9611 (define_insn "iorqi_ext_0"
9612 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9617 (match_operand 1 "ext_register_operand" "0")
9620 (match_operand 2 "const_int_operand" "n")))
9621 (clobber (reg:CC FLAGS_REG))]
9622 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9623 "or{b}\t{%2, %h0|%h0, %2}"
9624 [(set_attr "type" "alu")
9625 (set_attr "length_immediate" "1")
9626 (set_attr "mode" "QI")])
9628 (define_insn "*iorqi_ext_1"
9629 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9634 (match_operand 1 "ext_register_operand" "0")
9638 (match_operand:QI 2 "general_operand" "Qm"))))
9639 (clobber (reg:CC FLAGS_REG))]
9641 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9642 "or{b}\t{%2, %h0|%h0, %2}"
9643 [(set_attr "type" "alu")
9644 (set_attr "length_immediate" "0")
9645 (set_attr "mode" "QI")])
9647 (define_insn "*iorqi_ext_1_rex64"
9648 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9653 (match_operand 1 "ext_register_operand" "0")
9657 (match_operand 2 "ext_register_operand" "Q"))))
9658 (clobber (reg:CC FLAGS_REG))]
9660 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9661 "or{b}\t{%2, %h0|%h0, %2}"
9662 [(set_attr "type" "alu")
9663 (set_attr "length_immediate" "0")
9664 (set_attr "mode" "QI")])
9666 (define_insn "*iorqi_ext_2"
9667 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9671 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9674 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9677 (clobber (reg:CC FLAGS_REG))]
9678 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9679 "ior{b}\t{%h2, %h0|%h0, %h2}"
9680 [(set_attr "type" "alu")
9681 (set_attr "length_immediate" "0")
9682 (set_attr "mode" "QI")])
9685 [(set (match_operand 0 "register_operand" "")
9686 (ior (match_operand 1 "register_operand" "")
9687 (match_operand 2 "const_int_operand" "")))
9688 (clobber (reg:CC FLAGS_REG))]
9690 && QI_REG_P (operands[0])
9691 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9692 && !(INTVAL (operands[2]) & ~(255 << 8))
9693 && GET_MODE (operands[0]) != QImode"
9694 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9695 (ior:SI (zero_extract:SI (match_dup 1)
9696 (const_int 8) (const_int 8))
9698 (clobber (reg:CC FLAGS_REG))])]
9699 "operands[0] = gen_lowpart (SImode, operands[0]);
9700 operands[1] = gen_lowpart (SImode, operands[1]);
9701 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9703 ;; Since OR can be encoded with sign extended immediate, this is only
9704 ;; profitable when 7th bit is set.
9706 [(set (match_operand 0 "register_operand" "")
9707 (ior (match_operand 1 "general_operand" "")
9708 (match_operand 2 "const_int_operand" "")))
9709 (clobber (reg:CC FLAGS_REG))]
9711 && ANY_QI_REG_P (operands[0])
9712 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9713 && !(INTVAL (operands[2]) & ~255)
9714 && (INTVAL (operands[2]) & 128)
9715 && GET_MODE (operands[0]) != QImode"
9716 [(parallel [(set (strict_low_part (match_dup 0))
9717 (ior:QI (match_dup 1)
9719 (clobber (reg:CC FLAGS_REG))])]
9720 "operands[0] = gen_lowpart (QImode, operands[0]);
9721 operands[1] = gen_lowpart (QImode, operands[1]);
9722 operands[2] = gen_lowpart (QImode, operands[2]);")
9724 ;; Logical XOR instructions
9726 ;; %%% This used to optimize known byte-wide and operations to memory.
9727 ;; If this is considered useful, it should be done with splitters.
9729 (define_expand "xordi3"
9730 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9731 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9732 (match_operand:DI 2 "x86_64_general_operand" "")))
9733 (clobber (reg:CC FLAGS_REG))]
9735 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9737 (define_insn "*xordi_1_rex64"
9738 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9739 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9740 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9741 (clobber (reg:CC FLAGS_REG))]
9743 && ix86_binary_operator_ok (XOR, DImode, operands)"
9745 xor{q}\t{%2, %0|%0, %2}
9746 xor{q}\t{%2, %0|%0, %2}"
9747 [(set_attr "type" "alu")
9748 (set_attr "mode" "DI,DI")])
9750 (define_insn "*xordi_2_rex64"
9751 [(set (reg FLAGS_REG)
9752 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9753 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9755 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9756 (xor:DI (match_dup 1) (match_dup 2)))]
9758 && ix86_match_ccmode (insn, CCNOmode)
9759 && ix86_binary_operator_ok (XOR, DImode, operands)"
9761 xor{q}\t{%2, %0|%0, %2}
9762 xor{q}\t{%2, %0|%0, %2}"
9763 [(set_attr "type" "alu")
9764 (set_attr "mode" "DI,DI")])
9766 (define_insn "*xordi_3_rex64"
9767 [(set (reg FLAGS_REG)
9768 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9769 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9771 (clobber (match_scratch:DI 0 "=r"))]
9773 && ix86_match_ccmode (insn, CCNOmode)
9774 && ix86_binary_operator_ok (XOR, DImode, operands)"
9775 "xor{q}\t{%2, %0|%0, %2}"
9776 [(set_attr "type" "alu")
9777 (set_attr "mode" "DI")])
9779 (define_expand "xorsi3"
9780 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9781 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9782 (match_operand:SI 2 "general_operand" "")))
9783 (clobber (reg:CC FLAGS_REG))]
9785 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9787 (define_insn "*xorsi_1"
9788 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9789 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9790 (match_operand:SI 2 "general_operand" "ri,rm")))
9791 (clobber (reg:CC FLAGS_REG))]
9792 "ix86_binary_operator_ok (XOR, SImode, operands)"
9793 "xor{l}\t{%2, %0|%0, %2}"
9794 [(set_attr "type" "alu")
9795 (set_attr "mode" "SI")])
9797 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9798 ;; Add speccase for immediates
9799 (define_insn "*xorsi_1_zext"
9800 [(set (match_operand:DI 0 "register_operand" "=r")
9802 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9803 (match_operand:SI 2 "general_operand" "g"))))
9804 (clobber (reg:CC FLAGS_REG))]
9805 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9806 "xor{l}\t{%2, %k0|%k0, %2}"
9807 [(set_attr "type" "alu")
9808 (set_attr "mode" "SI")])
9810 (define_insn "*xorsi_1_zext_imm"
9811 [(set (match_operand:DI 0 "register_operand" "=r")
9812 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9813 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9814 (clobber (reg:CC FLAGS_REG))]
9815 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9816 "xor{l}\t{%2, %k0|%k0, %2}"
9817 [(set_attr "type" "alu")
9818 (set_attr "mode" "SI")])
9820 (define_insn "*xorsi_2"
9821 [(set (reg FLAGS_REG)
9822 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9823 (match_operand:SI 2 "general_operand" "g,ri"))
9825 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9826 (xor:SI (match_dup 1) (match_dup 2)))]
9827 "ix86_match_ccmode (insn, CCNOmode)
9828 && ix86_binary_operator_ok (XOR, SImode, operands)"
9829 "xor{l}\t{%2, %0|%0, %2}"
9830 [(set_attr "type" "alu")
9831 (set_attr "mode" "SI")])
9833 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9834 ;; ??? Special case for immediate operand is missing - it is tricky.
9835 (define_insn "*xorsi_2_zext"
9836 [(set (reg FLAGS_REG)
9837 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9838 (match_operand:SI 2 "general_operand" "g"))
9840 (set (match_operand:DI 0 "register_operand" "=r")
9841 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9842 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9843 && ix86_binary_operator_ok (XOR, SImode, operands)"
9844 "xor{l}\t{%2, %k0|%k0, %2}"
9845 [(set_attr "type" "alu")
9846 (set_attr "mode" "SI")])
9848 (define_insn "*xorsi_2_zext_imm"
9849 [(set (reg FLAGS_REG)
9850 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9851 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9853 (set (match_operand:DI 0 "register_operand" "=r")
9854 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9855 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9856 && ix86_binary_operator_ok (XOR, SImode, operands)"
9857 "xor{l}\t{%2, %k0|%k0, %2}"
9858 [(set_attr "type" "alu")
9859 (set_attr "mode" "SI")])
9861 (define_insn "*xorsi_3"
9862 [(set (reg FLAGS_REG)
9863 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9864 (match_operand:SI 2 "general_operand" "g"))
9866 (clobber (match_scratch:SI 0 "=r"))]
9867 "ix86_match_ccmode (insn, CCNOmode)
9868 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9869 "xor{l}\t{%2, %0|%0, %2}"
9870 [(set_attr "type" "alu")
9871 (set_attr "mode" "SI")])
9873 (define_expand "xorhi3"
9874 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9875 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9876 (match_operand:HI 2 "general_operand" "")))
9877 (clobber (reg:CC FLAGS_REG))]
9878 "TARGET_HIMODE_MATH"
9879 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9881 (define_insn "*xorhi_1"
9882 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9883 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9884 (match_operand:HI 2 "general_operand" "g,ri")))
9885 (clobber (reg:CC FLAGS_REG))]
9886 "ix86_binary_operator_ok (XOR, HImode, operands)"
9887 "xor{w}\t{%2, %0|%0, %2}"
9888 [(set_attr "type" "alu")
9889 (set_attr "mode" "HI")])
9891 (define_insn "*xorhi_2"
9892 [(set (reg FLAGS_REG)
9893 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9894 (match_operand:HI 2 "general_operand" "g,ri"))
9896 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9897 (xor:HI (match_dup 1) (match_dup 2)))]
9898 "ix86_match_ccmode (insn, CCNOmode)
9899 && ix86_binary_operator_ok (XOR, HImode, operands)"
9900 "xor{w}\t{%2, %0|%0, %2}"
9901 [(set_attr "type" "alu")
9902 (set_attr "mode" "HI")])
9904 (define_insn "*xorhi_3"
9905 [(set (reg FLAGS_REG)
9906 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9907 (match_operand:HI 2 "general_operand" "g"))
9909 (clobber (match_scratch:HI 0 "=r"))]
9910 "ix86_match_ccmode (insn, CCNOmode)
9911 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9912 "xor{w}\t{%2, %0|%0, %2}"
9913 [(set_attr "type" "alu")
9914 (set_attr "mode" "HI")])
9916 (define_expand "xorqi3"
9917 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9918 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9919 (match_operand:QI 2 "general_operand" "")))
9920 (clobber (reg:CC FLAGS_REG))]
9921 "TARGET_QIMODE_MATH"
9922 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9924 ;; %%% Potential partial reg stall on alternative 2. What to do?
9925 (define_insn "*xorqi_1"
9926 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9927 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9928 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9929 (clobber (reg:CC FLAGS_REG))]
9930 "ix86_binary_operator_ok (XOR, QImode, operands)"
9932 xor{b}\t{%2, %0|%0, %2}
9933 xor{b}\t{%2, %0|%0, %2}
9934 xor{l}\t{%k2, %k0|%k0, %k2}"
9935 [(set_attr "type" "alu")
9936 (set_attr "mode" "QI,QI,SI")])
9938 (define_insn "*xorqi_1_slp"
9939 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9940 (xor:QI (match_dup 0)
9941 (match_operand:QI 1 "general_operand" "qi,qmi")))
9942 (clobber (reg:CC FLAGS_REG))]
9943 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9944 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9945 "xor{b}\t{%1, %0|%0, %1}"
9946 [(set_attr "type" "alu1")
9947 (set_attr "mode" "QI")])
9949 (define_insn "xorqi_ext_0"
9950 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9955 (match_operand 1 "ext_register_operand" "0")
9958 (match_operand 2 "const_int_operand" "n")))
9959 (clobber (reg:CC FLAGS_REG))]
9960 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9961 "xor{b}\t{%2, %h0|%h0, %2}"
9962 [(set_attr "type" "alu")
9963 (set_attr "length_immediate" "1")
9964 (set_attr "mode" "QI")])
9966 (define_insn "*xorqi_ext_1"
9967 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9972 (match_operand 1 "ext_register_operand" "0")
9976 (match_operand:QI 2 "general_operand" "Qm"))))
9977 (clobber (reg:CC FLAGS_REG))]
9979 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9980 "xor{b}\t{%2, %h0|%h0, %2}"
9981 [(set_attr "type" "alu")
9982 (set_attr "length_immediate" "0")
9983 (set_attr "mode" "QI")])
9985 (define_insn "*xorqi_ext_1_rex64"
9986 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9991 (match_operand 1 "ext_register_operand" "0")
9995 (match_operand 2 "ext_register_operand" "Q"))))
9996 (clobber (reg:CC FLAGS_REG))]
9998 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9999 "xor{b}\t{%2, %h0|%h0, %2}"
10000 [(set_attr "type" "alu")
10001 (set_attr "length_immediate" "0")
10002 (set_attr "mode" "QI")])
10004 (define_insn "*xorqi_ext_2"
10005 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10009 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10012 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10015 (clobber (reg:CC FLAGS_REG))]
10016 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
10017 "xor{b}\t{%h2, %h0|%h0, %h2}"
10018 [(set_attr "type" "alu")
10019 (set_attr "length_immediate" "0")
10020 (set_attr "mode" "QI")])
10022 (define_insn "*xorqi_cc_1"
10023 [(set (reg FLAGS_REG)
10025 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10026 (match_operand:QI 2 "general_operand" "qim,qi"))
10028 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10029 (xor:QI (match_dup 1) (match_dup 2)))]
10030 "ix86_match_ccmode (insn, CCNOmode)
10031 && ix86_binary_operator_ok (XOR, QImode, operands)"
10032 "xor{b}\t{%2, %0|%0, %2}"
10033 [(set_attr "type" "alu")
10034 (set_attr "mode" "QI")])
10036 (define_insn "*xorqi_2_slp"
10037 [(set (reg FLAGS_REG)
10038 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10039 (match_operand:QI 1 "general_operand" "qim,qi"))
10041 (set (strict_low_part (match_dup 0))
10042 (xor:QI (match_dup 0) (match_dup 1)))]
10043 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10044 && ix86_match_ccmode (insn, CCNOmode)
10045 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10046 "xor{b}\t{%1, %0|%0, %1}"
10047 [(set_attr "type" "alu1")
10048 (set_attr "mode" "QI")])
10050 (define_insn "*xorqi_cc_2"
10051 [(set (reg FLAGS_REG)
10053 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10054 (match_operand:QI 2 "general_operand" "qim"))
10056 (clobber (match_scratch:QI 0 "=q"))]
10057 "ix86_match_ccmode (insn, CCNOmode)
10058 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10059 "xor{b}\t{%2, %0|%0, %2}"
10060 [(set_attr "type" "alu")
10061 (set_attr "mode" "QI")])
10063 (define_insn "*xorqi_cc_ext_1"
10064 [(set (reg FLAGS_REG)
10068 (match_operand 1 "ext_register_operand" "0")
10071 (match_operand:QI 2 "general_operand" "qmn"))
10073 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10077 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10079 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10080 "xor{b}\t{%2, %h0|%h0, %2}"
10081 [(set_attr "type" "alu")
10082 (set_attr "mode" "QI")])
10084 (define_insn "*xorqi_cc_ext_1_rex64"
10085 [(set (reg FLAGS_REG)
10089 (match_operand 1 "ext_register_operand" "0")
10092 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10094 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10098 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10100 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10101 "xor{b}\t{%2, %h0|%h0, %2}"
10102 [(set_attr "type" "alu")
10103 (set_attr "mode" "QI")])
10105 (define_expand "xorqi_cc_ext_1"
10107 (set (reg:CCNO FLAGS_REG)
10111 (match_operand 1 "ext_register_operand" "")
10114 (match_operand:QI 2 "general_operand" ""))
10116 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10120 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10126 [(set (match_operand 0 "register_operand" "")
10127 (xor (match_operand 1 "register_operand" "")
10128 (match_operand 2 "const_int_operand" "")))
10129 (clobber (reg:CC FLAGS_REG))]
10131 && QI_REG_P (operands[0])
10132 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10133 && !(INTVAL (operands[2]) & ~(255 << 8))
10134 && GET_MODE (operands[0]) != QImode"
10135 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10136 (xor:SI (zero_extract:SI (match_dup 1)
10137 (const_int 8) (const_int 8))
10139 (clobber (reg:CC FLAGS_REG))])]
10140 "operands[0] = gen_lowpart (SImode, operands[0]);
10141 operands[1] = gen_lowpart (SImode, operands[1]);
10142 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10144 ;; Since XOR can be encoded with sign extended immediate, this is only
10145 ;; profitable when 7th bit is set.
10147 [(set (match_operand 0 "register_operand" "")
10148 (xor (match_operand 1 "general_operand" "")
10149 (match_operand 2 "const_int_operand" "")))
10150 (clobber (reg:CC FLAGS_REG))]
10152 && ANY_QI_REG_P (operands[0])
10153 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10154 && !(INTVAL (operands[2]) & ~255)
10155 && (INTVAL (operands[2]) & 128)
10156 && GET_MODE (operands[0]) != QImode"
10157 [(parallel [(set (strict_low_part (match_dup 0))
10158 (xor:QI (match_dup 1)
10160 (clobber (reg:CC FLAGS_REG))])]
10161 "operands[0] = gen_lowpart (QImode, operands[0]);
10162 operands[1] = gen_lowpart (QImode, operands[1]);
10163 operands[2] = gen_lowpart (QImode, operands[2]);")
10165 ;; Negation instructions
10167 (define_expand "negti2"
10168 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10169 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10170 (clobber (reg:CC FLAGS_REG))])]
10172 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10174 (define_insn "*negti2_1"
10175 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10176 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10177 (clobber (reg:CC FLAGS_REG))]
10179 && ix86_unary_operator_ok (NEG, TImode, operands)"
10183 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10184 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10185 (clobber (reg:CC FLAGS_REG))]
10186 "TARGET_64BIT && reload_completed"
10188 [(set (reg:CCZ FLAGS_REG)
10189 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10190 (set (match_dup 0) (neg:DI (match_dup 2)))])
10192 [(set (match_dup 1)
10193 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10196 (clobber (reg:CC FLAGS_REG))])
10198 [(set (match_dup 1)
10199 (neg:DI (match_dup 1)))
10200 (clobber (reg:CC FLAGS_REG))])]
10201 "split_ti (operands+1, 1, operands+2, operands+3);
10202 split_ti (operands+0, 1, operands+0, operands+1);")
10204 (define_expand "negdi2"
10205 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10206 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10207 (clobber (reg:CC FLAGS_REG))])]
10209 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10211 (define_insn "*negdi2_1"
10212 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10213 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10214 (clobber (reg:CC FLAGS_REG))]
10216 && ix86_unary_operator_ok (NEG, DImode, operands)"
10220 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10221 (neg:DI (match_operand:DI 1 "general_operand" "")))
10222 (clobber (reg:CC FLAGS_REG))]
10223 "!TARGET_64BIT && reload_completed"
10225 [(set (reg:CCZ FLAGS_REG)
10226 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10227 (set (match_dup 0) (neg:SI (match_dup 2)))])
10229 [(set (match_dup 1)
10230 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10233 (clobber (reg:CC FLAGS_REG))])
10235 [(set (match_dup 1)
10236 (neg:SI (match_dup 1)))
10237 (clobber (reg:CC FLAGS_REG))])]
10238 "split_di (operands+1, 1, operands+2, operands+3);
10239 split_di (operands+0, 1, operands+0, operands+1);")
10241 (define_insn "*negdi2_1_rex64"
10242 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10243 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10244 (clobber (reg:CC FLAGS_REG))]
10245 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10247 [(set_attr "type" "negnot")
10248 (set_attr "mode" "DI")])
10250 ;; The problem with neg is that it does not perform (compare x 0),
10251 ;; it really performs (compare 0 x), which leaves us with the zero
10252 ;; flag being the only useful item.
10254 (define_insn "*negdi2_cmpz_rex64"
10255 [(set (reg:CCZ FLAGS_REG)
10256 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10258 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10259 (neg:DI (match_dup 1)))]
10260 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10262 [(set_attr "type" "negnot")
10263 (set_attr "mode" "DI")])
10266 (define_expand "negsi2"
10267 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10268 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10269 (clobber (reg:CC FLAGS_REG))])]
10271 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10273 (define_insn "*negsi2_1"
10274 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10275 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10276 (clobber (reg:CC FLAGS_REG))]
10277 "ix86_unary_operator_ok (NEG, SImode, operands)"
10279 [(set_attr "type" "negnot")
10280 (set_attr "mode" "SI")])
10282 ;; Combine is quite creative about this pattern.
10283 (define_insn "*negsi2_1_zext"
10284 [(set (match_operand:DI 0 "register_operand" "=r")
10285 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10288 (clobber (reg:CC FLAGS_REG))]
10289 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10291 [(set_attr "type" "negnot")
10292 (set_attr "mode" "SI")])
10294 ;; The problem with neg is that it does not perform (compare x 0),
10295 ;; it really performs (compare 0 x), which leaves us with the zero
10296 ;; flag being the only useful item.
10298 (define_insn "*negsi2_cmpz"
10299 [(set (reg:CCZ FLAGS_REG)
10300 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10302 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10303 (neg:SI (match_dup 1)))]
10304 "ix86_unary_operator_ok (NEG, SImode, operands)"
10306 [(set_attr "type" "negnot")
10307 (set_attr "mode" "SI")])
10309 (define_insn "*negsi2_cmpz_zext"
10310 [(set (reg:CCZ FLAGS_REG)
10311 (compare:CCZ (lshiftrt:DI
10313 (match_operand:DI 1 "register_operand" "0")
10317 (set (match_operand:DI 0 "register_operand" "=r")
10318 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10321 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10323 [(set_attr "type" "negnot")
10324 (set_attr "mode" "SI")])
10326 (define_expand "neghi2"
10327 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10328 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10329 (clobber (reg:CC FLAGS_REG))])]
10330 "TARGET_HIMODE_MATH"
10331 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10333 (define_insn "*neghi2_1"
10334 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10335 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10336 (clobber (reg:CC FLAGS_REG))]
10337 "ix86_unary_operator_ok (NEG, HImode, operands)"
10339 [(set_attr "type" "negnot")
10340 (set_attr "mode" "HI")])
10342 (define_insn "*neghi2_cmpz"
10343 [(set (reg:CCZ FLAGS_REG)
10344 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10346 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10347 (neg:HI (match_dup 1)))]
10348 "ix86_unary_operator_ok (NEG, HImode, operands)"
10350 [(set_attr "type" "negnot")
10351 (set_attr "mode" "HI")])
10353 (define_expand "negqi2"
10354 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10355 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10356 (clobber (reg:CC FLAGS_REG))])]
10357 "TARGET_QIMODE_MATH"
10358 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10360 (define_insn "*negqi2_1"
10361 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10362 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10363 (clobber (reg:CC FLAGS_REG))]
10364 "ix86_unary_operator_ok (NEG, QImode, operands)"
10366 [(set_attr "type" "negnot")
10367 (set_attr "mode" "QI")])
10369 (define_insn "*negqi2_cmpz"
10370 [(set (reg:CCZ FLAGS_REG)
10371 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10373 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10374 (neg:QI (match_dup 1)))]
10375 "ix86_unary_operator_ok (NEG, QImode, operands)"
10377 [(set_attr "type" "negnot")
10378 (set_attr "mode" "QI")])
10380 ;; Changing of sign for FP values is doable using integer unit too.
10382 (define_expand "neg<mode>2"
10383 [(set (match_operand:X87MODEF 0 "register_operand" "")
10384 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10385 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10386 "ix86_expand_fp_absneg_operator (NEG, <MODE>mode, operands); DONE;")
10388 (define_expand "abs<mode>2"
10389 [(set (match_operand:X87MODEF 0 "register_operand" "")
10390 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10391 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10392 "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10394 (define_insn "*absneg<mode>2_mixed"
10395 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10396 (match_operator:MODEF 3 "absneg_operator"
10397 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10398 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10399 (clobber (reg:CC FLAGS_REG))]
10400 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10403 (define_insn "*absneg<mode>2_sse"
10404 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10405 (match_operator:MODEF 3 "absneg_operator"
10406 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10407 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10408 (clobber (reg:CC FLAGS_REG))]
10409 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10412 (define_insn "*absneg<mode>2_i387"
10413 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10414 (match_operator:X87MODEF 3 "absneg_operator"
10415 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10416 (use (match_operand 2 "" ""))
10417 (clobber (reg:CC FLAGS_REG))]
10418 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10421 (define_expand "negtf2"
10422 [(set (match_operand:TF 0 "register_operand" "")
10423 (neg:TF (match_operand:TF 1 "register_operand" "")))]
10425 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10427 (define_expand "abstf2"
10428 [(set (match_operand:TF 0 "register_operand" "")
10429 (abs:TF (match_operand:TF 1 "register_operand" "")))]
10431 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10433 (define_insn "*absnegtf2_sse"
10434 [(set (match_operand:TF 0 "register_operand" "=x,x")
10435 (match_operator:TF 3 "absneg_operator"
10436 [(match_operand:TF 1 "register_operand" "0,x")]))
10437 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10438 (clobber (reg:CC FLAGS_REG))]
10442 ;; Splitters for fp abs and neg.
10445 [(set (match_operand 0 "fp_register_operand" "")
10446 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10447 (use (match_operand 2 "" ""))
10448 (clobber (reg:CC FLAGS_REG))]
10450 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10453 [(set (match_operand 0 "register_operand" "")
10454 (match_operator 3 "absneg_operator"
10455 [(match_operand 1 "register_operand" "")]))
10456 (use (match_operand 2 "nonimmediate_operand" ""))
10457 (clobber (reg:CC FLAGS_REG))]
10458 "reload_completed && SSE_REG_P (operands[0])"
10459 [(set (match_dup 0) (match_dup 3))]
10461 enum machine_mode mode = GET_MODE (operands[0]);
10462 enum machine_mode vmode = GET_MODE (operands[2]);
10465 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10466 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10467 if (operands_match_p (operands[0], operands[2]))
10470 operands[1] = operands[2];
10473 if (GET_CODE (operands[3]) == ABS)
10474 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10476 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10481 [(set (match_operand:SF 0 "register_operand" "")
10482 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10483 (use (match_operand:V4SF 2 "" ""))
10484 (clobber (reg:CC FLAGS_REG))]
10486 [(parallel [(set (match_dup 0) (match_dup 1))
10487 (clobber (reg:CC FLAGS_REG))])]
10490 operands[0] = gen_lowpart (SImode, operands[0]);
10491 if (GET_CODE (operands[1]) == ABS)
10493 tmp = gen_int_mode (0x7fffffff, SImode);
10494 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10498 tmp = gen_int_mode (0x80000000, SImode);
10499 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10505 [(set (match_operand:DF 0 "register_operand" "")
10506 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10507 (use (match_operand 2 "" ""))
10508 (clobber (reg:CC FLAGS_REG))]
10510 [(parallel [(set (match_dup 0) (match_dup 1))
10511 (clobber (reg:CC FLAGS_REG))])]
10516 tmp = gen_lowpart (DImode, operands[0]);
10517 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10520 if (GET_CODE (operands[1]) == ABS)
10523 tmp = gen_rtx_NOT (DImode, tmp);
10527 operands[0] = gen_highpart (SImode, operands[0]);
10528 if (GET_CODE (operands[1]) == ABS)
10530 tmp = gen_int_mode (0x7fffffff, SImode);
10531 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10535 tmp = gen_int_mode (0x80000000, SImode);
10536 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10543 [(set (match_operand:XF 0 "register_operand" "")
10544 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10545 (use (match_operand 2 "" ""))
10546 (clobber (reg:CC FLAGS_REG))]
10548 [(parallel [(set (match_dup 0) (match_dup 1))
10549 (clobber (reg:CC FLAGS_REG))])]
10552 operands[0] = gen_rtx_REG (SImode,
10553 true_regnum (operands[0])
10554 + (TARGET_64BIT ? 1 : 2));
10555 if (GET_CODE (operands[1]) == ABS)
10557 tmp = GEN_INT (0x7fff);
10558 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10562 tmp = GEN_INT (0x8000);
10563 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10568 ;; Conditionalize these after reload. If they match before reload, we
10569 ;; lose the clobber and ability to use integer instructions.
10571 (define_insn "*neg<mode>2_1"
10572 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10573 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10575 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10577 [(set_attr "type" "fsgn")
10578 (set_attr "mode" "<MODE>")])
10580 (define_insn "*abs<mode>2_1"
10581 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10582 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10584 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10586 [(set_attr "type" "fsgn")
10587 (set_attr "mode" "<MODE>")])
10589 (define_insn "*negextendsfdf2"
10590 [(set (match_operand:DF 0 "register_operand" "=f")
10591 (neg:DF (float_extend:DF
10592 (match_operand:SF 1 "register_operand" "0"))))]
10593 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10595 [(set_attr "type" "fsgn")
10596 (set_attr "mode" "DF")])
10598 (define_insn "*negextenddfxf2"
10599 [(set (match_operand:XF 0 "register_operand" "=f")
10600 (neg:XF (float_extend:XF
10601 (match_operand:DF 1 "register_operand" "0"))))]
10604 [(set_attr "type" "fsgn")
10605 (set_attr "mode" "XF")])
10607 (define_insn "*negextendsfxf2"
10608 [(set (match_operand:XF 0 "register_operand" "=f")
10609 (neg:XF (float_extend:XF
10610 (match_operand:SF 1 "register_operand" "0"))))]
10613 [(set_attr "type" "fsgn")
10614 (set_attr "mode" "XF")])
10616 (define_insn "*absextendsfdf2"
10617 [(set (match_operand:DF 0 "register_operand" "=f")
10618 (abs:DF (float_extend:DF
10619 (match_operand:SF 1 "register_operand" "0"))))]
10620 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10622 [(set_attr "type" "fsgn")
10623 (set_attr "mode" "DF")])
10625 (define_insn "*absextenddfxf2"
10626 [(set (match_operand:XF 0 "register_operand" "=f")
10627 (abs:XF (float_extend:XF
10628 (match_operand:DF 1 "register_operand" "0"))))]
10631 [(set_attr "type" "fsgn")
10632 (set_attr "mode" "XF")])
10634 (define_insn "*absextendsfxf2"
10635 [(set (match_operand:XF 0 "register_operand" "=f")
10636 (abs:XF (float_extend:XF
10637 (match_operand:SF 1 "register_operand" "0"))))]
10640 [(set_attr "type" "fsgn")
10641 (set_attr "mode" "XF")])
10643 ;; Copysign instructions
10645 (define_mode_iterator CSGNMODE [SF DF TF])
10646 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10648 (define_expand "copysign<mode>3"
10649 [(match_operand:CSGNMODE 0 "register_operand" "")
10650 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10651 (match_operand:CSGNMODE 2 "register_operand" "")]
10652 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10653 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10655 ix86_expand_copysign (operands);
10659 (define_insn_and_split "copysign<mode>3_const"
10660 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10662 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10663 (match_operand:CSGNMODE 2 "register_operand" "0")
10664 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10666 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10667 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10669 "&& reload_completed"
10672 ix86_split_copysign_const (operands);
10676 (define_insn "copysign<mode>3_var"
10677 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10679 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10680 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10681 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10682 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10684 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10685 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10686 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10690 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10692 [(match_operand:CSGNMODE 2 "register_operand" "")
10693 (match_operand:CSGNMODE 3 "register_operand" "")
10694 (match_operand:<CSGNVMODE> 4 "" "")
10695 (match_operand:<CSGNVMODE> 5 "" "")]
10697 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10698 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10699 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10700 && reload_completed"
10703 ix86_split_copysign_var (operands);
10707 ;; One complement instructions
10709 (define_expand "one_cmpldi2"
10710 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10711 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10713 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10715 (define_insn "*one_cmpldi2_1_rex64"
10716 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10717 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10718 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10720 [(set_attr "type" "negnot")
10721 (set_attr "mode" "DI")])
10723 (define_insn "*one_cmpldi2_2_rex64"
10724 [(set (reg FLAGS_REG)
10725 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10727 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10728 (not:DI (match_dup 1)))]
10729 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10730 && ix86_unary_operator_ok (NOT, DImode, operands)"
10732 [(set_attr "type" "alu1")
10733 (set_attr "mode" "DI")])
10736 [(set (match_operand 0 "flags_reg_operand" "")
10737 (match_operator 2 "compare_operator"
10738 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10740 (set (match_operand:DI 1 "nonimmediate_operand" "")
10741 (not:DI (match_dup 3)))]
10742 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10743 [(parallel [(set (match_dup 0)
10745 [(xor:DI (match_dup 3) (const_int -1))
10748 (xor:DI (match_dup 3) (const_int -1)))])]
10751 (define_expand "one_cmplsi2"
10752 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10753 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10755 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10757 (define_insn "*one_cmplsi2_1"
10758 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10759 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10760 "ix86_unary_operator_ok (NOT, SImode, operands)"
10762 [(set_attr "type" "negnot")
10763 (set_attr "mode" "SI")])
10765 ;; ??? Currently never generated - xor is used instead.
10766 (define_insn "*one_cmplsi2_1_zext"
10767 [(set (match_operand:DI 0 "register_operand" "=r")
10768 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10769 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10771 [(set_attr "type" "negnot")
10772 (set_attr "mode" "SI")])
10774 (define_insn "*one_cmplsi2_2"
10775 [(set (reg FLAGS_REG)
10776 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10778 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10779 (not:SI (match_dup 1)))]
10780 "ix86_match_ccmode (insn, CCNOmode)
10781 && ix86_unary_operator_ok (NOT, SImode, operands)"
10783 [(set_attr "type" "alu1")
10784 (set_attr "mode" "SI")])
10787 [(set (match_operand 0 "flags_reg_operand" "")
10788 (match_operator 2 "compare_operator"
10789 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10791 (set (match_operand:SI 1 "nonimmediate_operand" "")
10792 (not:SI (match_dup 3)))]
10793 "ix86_match_ccmode (insn, CCNOmode)"
10794 [(parallel [(set (match_dup 0)
10795 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10798 (xor:SI (match_dup 3) (const_int -1)))])]
10801 ;; ??? Currently never generated - xor is used instead.
10802 (define_insn "*one_cmplsi2_2_zext"
10803 [(set (reg FLAGS_REG)
10804 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10806 (set (match_operand:DI 0 "register_operand" "=r")
10807 (zero_extend:DI (not:SI (match_dup 1))))]
10808 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10809 && ix86_unary_operator_ok (NOT, SImode, operands)"
10811 [(set_attr "type" "alu1")
10812 (set_attr "mode" "SI")])
10815 [(set (match_operand 0 "flags_reg_operand" "")
10816 (match_operator 2 "compare_operator"
10817 [(not:SI (match_operand:SI 3 "register_operand" ""))
10819 (set (match_operand:DI 1 "register_operand" "")
10820 (zero_extend:DI (not:SI (match_dup 3))))]
10821 "ix86_match_ccmode (insn, CCNOmode)"
10822 [(parallel [(set (match_dup 0)
10823 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10826 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10829 (define_expand "one_cmplhi2"
10830 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10831 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10832 "TARGET_HIMODE_MATH"
10833 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10835 (define_insn "*one_cmplhi2_1"
10836 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10837 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10838 "ix86_unary_operator_ok (NOT, HImode, operands)"
10840 [(set_attr "type" "negnot")
10841 (set_attr "mode" "HI")])
10843 (define_insn "*one_cmplhi2_2"
10844 [(set (reg FLAGS_REG)
10845 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10847 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10848 (not:HI (match_dup 1)))]
10849 "ix86_match_ccmode (insn, CCNOmode)
10850 && ix86_unary_operator_ok (NEG, HImode, operands)"
10852 [(set_attr "type" "alu1")
10853 (set_attr "mode" "HI")])
10856 [(set (match_operand 0 "flags_reg_operand" "")
10857 (match_operator 2 "compare_operator"
10858 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10860 (set (match_operand:HI 1 "nonimmediate_operand" "")
10861 (not:HI (match_dup 3)))]
10862 "ix86_match_ccmode (insn, CCNOmode)"
10863 [(parallel [(set (match_dup 0)
10864 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10867 (xor:HI (match_dup 3) (const_int -1)))])]
10870 ;; %%% Potential partial reg stall on alternative 1. What to do?
10871 (define_expand "one_cmplqi2"
10872 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10873 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10874 "TARGET_QIMODE_MATH"
10875 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10877 (define_insn "*one_cmplqi2_1"
10878 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10879 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10880 "ix86_unary_operator_ok (NOT, QImode, operands)"
10884 [(set_attr "type" "negnot")
10885 (set_attr "mode" "QI,SI")])
10887 (define_insn "*one_cmplqi2_2"
10888 [(set (reg FLAGS_REG)
10889 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10891 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10892 (not:QI (match_dup 1)))]
10893 "ix86_match_ccmode (insn, CCNOmode)
10894 && ix86_unary_operator_ok (NOT, QImode, operands)"
10896 [(set_attr "type" "alu1")
10897 (set_attr "mode" "QI")])
10900 [(set (match_operand 0 "flags_reg_operand" "")
10901 (match_operator 2 "compare_operator"
10902 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10904 (set (match_operand:QI 1 "nonimmediate_operand" "")
10905 (not:QI (match_dup 3)))]
10906 "ix86_match_ccmode (insn, CCNOmode)"
10907 [(parallel [(set (match_dup 0)
10908 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10911 (xor:QI (match_dup 3) (const_int -1)))])]
10914 ;; Arithmetic shift instructions
10916 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10917 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10918 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10919 ;; from the assembler input.
10921 ;; This instruction shifts the target reg/mem as usual, but instead of
10922 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10923 ;; is a left shift double, bits are taken from the high order bits of
10924 ;; reg, else if the insn is a shift right double, bits are taken from the
10925 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10926 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10928 ;; Since sh[lr]d does not change the `reg' operand, that is done
10929 ;; separately, making all shifts emit pairs of shift double and normal
10930 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10931 ;; support a 63 bit shift, each shift where the count is in a reg expands
10932 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10934 ;; If the shift count is a constant, we need never emit more than one
10935 ;; shift pair, instead using moves and sign extension for counts greater
10938 (define_expand "ashlti3"
10939 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10940 (ashift:TI (match_operand:TI 1 "register_operand" "")
10941 (match_operand:QI 2 "nonmemory_operand" "")))
10942 (clobber (reg:CC FLAGS_REG))])]
10945 if (! immediate_operand (operands[2], QImode))
10947 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10950 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10954 (define_insn "ashlti3_1"
10955 [(set (match_operand:TI 0 "register_operand" "=r")
10956 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10957 (match_operand:QI 2 "register_operand" "c")))
10958 (clobber (match_scratch:DI 3 "=&r"))
10959 (clobber (reg:CC FLAGS_REG))]
10962 [(set_attr "type" "multi")])
10964 ;; This pattern must be defined before *ashlti3_2 to prevent
10965 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10967 (define_insn "sse2_ashlti3"
10968 [(set (match_operand:TI 0 "register_operand" "=x")
10969 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10970 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10973 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10974 return "pslldq\t{%2, %0|%0, %2}";
10976 [(set_attr "type" "sseishft")
10977 (set_attr "prefix_data16" "1")
10978 (set_attr "mode" "TI")])
10980 (define_insn "*ashlti3_2"
10981 [(set (match_operand:TI 0 "register_operand" "=r")
10982 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10983 (match_operand:QI 2 "immediate_operand" "O")))
10984 (clobber (reg:CC FLAGS_REG))]
10987 [(set_attr "type" "multi")])
10990 [(set (match_operand:TI 0 "register_operand" "")
10991 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10992 (match_operand:QI 2 "register_operand" "")))
10993 (clobber (match_scratch:DI 3 ""))
10994 (clobber (reg:CC FLAGS_REG))]
10995 "TARGET_64BIT && reload_completed"
10997 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11000 [(set (match_operand:TI 0 "register_operand" "")
11001 (ashift:TI (match_operand:TI 1 "register_operand" "")
11002 (match_operand:QI 2 "immediate_operand" "")))
11003 (clobber (reg:CC FLAGS_REG))]
11004 "TARGET_64BIT && reload_completed"
11006 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11008 (define_insn "x86_64_shld"
11009 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11010 (ior:DI (ashift:DI (match_dup 0)
11011 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11012 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
11013 (minus:QI (const_int 64) (match_dup 2)))))
11014 (clobber (reg:CC FLAGS_REG))]
11017 shld{q}\t{%2, %1, %0|%0, %1, %2}
11018 shld{q}\t{%s2%1, %0|%0, %1, %2}"
11019 [(set_attr "type" "ishift")
11020 (set_attr "prefix_0f" "1")
11021 (set_attr "mode" "DI")
11022 (set_attr "athlon_decode" "vector")
11023 (set_attr "amdfam10_decode" "vector")])
11025 (define_expand "x86_64_shift_adj"
11026 [(set (reg:CCZ FLAGS_REG)
11027 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11030 (set (match_operand:DI 0 "register_operand" "")
11031 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11032 (match_operand:DI 1 "register_operand" "")
11035 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11036 (match_operand:DI 3 "register_operand" "r")
11041 (define_expand "ashldi3"
11042 [(set (match_operand:DI 0 "shiftdi_operand" "")
11043 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11044 (match_operand:QI 2 "nonmemory_operand" "")))]
11046 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11048 (define_insn "*ashldi3_1_rex64"
11049 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11050 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11051 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11052 (clobber (reg:CC FLAGS_REG))]
11053 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11055 switch (get_attr_type (insn))
11058 gcc_assert (operands[2] == const1_rtx);
11059 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11060 return "add{q}\t%0, %0";
11063 gcc_assert (CONST_INT_P (operands[2]));
11064 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11065 operands[1] = gen_rtx_MULT (DImode, operands[1],
11066 GEN_INT (1 << INTVAL (operands[2])));
11067 return "lea{q}\t{%a1, %0|%0, %a1}";
11070 if (REG_P (operands[2]))
11071 return "sal{q}\t{%b2, %0|%0, %b2}";
11072 else if (operands[2] == const1_rtx
11073 && (TARGET_SHIFT1 || optimize_size))
11074 return "sal{q}\t%0";
11076 return "sal{q}\t{%2, %0|%0, %2}";
11079 [(set (attr "type")
11080 (cond [(eq_attr "alternative" "1")
11081 (const_string "lea")
11082 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11084 (match_operand 0 "register_operand" ""))
11085 (match_operand 2 "const1_operand" ""))
11086 (const_string "alu")
11088 (const_string "ishift")))
11089 (set_attr "mode" "DI")])
11091 ;; Convert lea to the lea pattern to avoid flags dependency.
11093 [(set (match_operand:DI 0 "register_operand" "")
11094 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11095 (match_operand:QI 2 "immediate_operand" "")))
11096 (clobber (reg:CC FLAGS_REG))]
11097 "TARGET_64BIT && reload_completed
11098 && true_regnum (operands[0]) != true_regnum (operands[1])"
11099 [(set (match_dup 0)
11100 (mult:DI (match_dup 1)
11102 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11104 ;; This pattern can't accept a variable shift count, since shifts by
11105 ;; zero don't affect the flags. We assume that shifts by constant
11106 ;; zero are optimized away.
11107 (define_insn "*ashldi3_cmp_rex64"
11108 [(set (reg FLAGS_REG)
11110 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11111 (match_operand:QI 2 "immediate_operand" "e"))
11113 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11114 (ashift:DI (match_dup 1) (match_dup 2)))]
11117 || !TARGET_PARTIAL_FLAG_REG_STALL
11118 || (operands[2] == const1_rtx
11120 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11121 && ix86_match_ccmode (insn, CCGOCmode)
11122 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11124 switch (get_attr_type (insn))
11127 gcc_assert (operands[2] == const1_rtx);
11128 return "add{q}\t%0, %0";
11131 if (REG_P (operands[2]))
11132 return "sal{q}\t{%b2, %0|%0, %b2}";
11133 else if (operands[2] == const1_rtx
11134 && (TARGET_SHIFT1 || optimize_size))
11135 return "sal{q}\t%0";
11137 return "sal{q}\t{%2, %0|%0, %2}";
11140 [(set (attr "type")
11141 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11143 (match_operand 0 "register_operand" ""))
11144 (match_operand 2 "const1_operand" ""))
11145 (const_string "alu")
11147 (const_string "ishift")))
11148 (set_attr "mode" "DI")])
11150 (define_insn "*ashldi3_cconly_rex64"
11151 [(set (reg FLAGS_REG)
11153 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11154 (match_operand:QI 2 "immediate_operand" "e"))
11156 (clobber (match_scratch:DI 0 "=r"))]
11159 || !TARGET_PARTIAL_FLAG_REG_STALL
11160 || (operands[2] == const1_rtx
11162 || TARGET_DOUBLE_WITH_ADD)))
11163 && ix86_match_ccmode (insn, CCGOCmode)
11164 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11166 switch (get_attr_type (insn))
11169 gcc_assert (operands[2] == const1_rtx);
11170 return "add{q}\t%0, %0";
11173 if (REG_P (operands[2]))
11174 return "sal{q}\t{%b2, %0|%0, %b2}";
11175 else if (operands[2] == const1_rtx
11176 && (TARGET_SHIFT1 || optimize_size))
11177 return "sal{q}\t%0";
11179 return "sal{q}\t{%2, %0|%0, %2}";
11182 [(set (attr "type")
11183 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11185 (match_operand 0 "register_operand" ""))
11186 (match_operand 2 "const1_operand" ""))
11187 (const_string "alu")
11189 (const_string "ishift")))
11190 (set_attr "mode" "DI")])
11192 (define_insn "*ashldi3_1"
11193 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11194 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11195 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11196 (clobber (reg:CC FLAGS_REG))]
11199 [(set_attr "type" "multi")])
11201 ;; By default we don't ask for a scratch register, because when DImode
11202 ;; values are manipulated, registers are already at a premium. But if
11203 ;; we have one handy, we won't turn it away.
11205 [(match_scratch:SI 3 "r")
11206 (parallel [(set (match_operand:DI 0 "register_operand" "")
11207 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11208 (match_operand:QI 2 "nonmemory_operand" "")))
11209 (clobber (reg:CC FLAGS_REG))])
11211 "!TARGET_64BIT && TARGET_CMOVE"
11213 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11216 [(set (match_operand:DI 0 "register_operand" "")
11217 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11218 (match_operand:QI 2 "nonmemory_operand" "")))
11219 (clobber (reg:CC FLAGS_REG))]
11220 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11221 ? epilogue_completed : reload_completed)"
11223 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11225 (define_insn "x86_shld_1"
11226 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11227 (ior:SI (ashift:SI (match_dup 0)
11228 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11229 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11230 (minus:QI (const_int 32) (match_dup 2)))))
11231 (clobber (reg:CC FLAGS_REG))]
11234 shld{l}\t{%2, %1, %0|%0, %1, %2}
11235 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11236 [(set_attr "type" "ishift")
11237 (set_attr "prefix_0f" "1")
11238 (set_attr "mode" "SI")
11239 (set_attr "pent_pair" "np")
11240 (set_attr "athlon_decode" "vector")
11241 (set_attr "amdfam10_decode" "vector")])
11243 (define_expand "x86_shift_adj_1"
11244 [(set (reg:CCZ FLAGS_REG)
11245 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11248 (set (match_operand:SI 0 "register_operand" "")
11249 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11250 (match_operand:SI 1 "register_operand" "")
11253 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11254 (match_operand:SI 3 "register_operand" "r")
11259 (define_expand "x86_shift_adj_2"
11260 [(use (match_operand:SI 0 "register_operand" ""))
11261 (use (match_operand:SI 1 "register_operand" ""))
11262 (use (match_operand:QI 2 "register_operand" ""))]
11265 rtx label = gen_label_rtx ();
11268 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11270 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11271 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11272 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11273 gen_rtx_LABEL_REF (VOIDmode, label),
11275 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11276 JUMP_LABEL (tmp) = label;
11278 emit_move_insn (operands[0], operands[1]);
11279 ix86_expand_clear (operands[1]);
11281 emit_label (label);
11282 LABEL_NUSES (label) = 1;
11287 (define_expand "ashlsi3"
11288 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11289 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11290 (match_operand:QI 2 "nonmemory_operand" "")))
11291 (clobber (reg:CC FLAGS_REG))]
11293 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11295 (define_insn "*ashlsi3_1"
11296 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11297 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11298 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11299 (clobber (reg:CC FLAGS_REG))]
11300 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11302 switch (get_attr_type (insn))
11305 gcc_assert (operands[2] == const1_rtx);
11306 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11307 return "add{l}\t%0, %0";
11313 if (REG_P (operands[2]))
11314 return "sal{l}\t{%b2, %0|%0, %b2}";
11315 else if (operands[2] == const1_rtx
11316 && (TARGET_SHIFT1 || optimize_size))
11317 return "sal{l}\t%0";
11319 return "sal{l}\t{%2, %0|%0, %2}";
11322 [(set (attr "type")
11323 (cond [(eq_attr "alternative" "1")
11324 (const_string "lea")
11325 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11327 (match_operand 0 "register_operand" ""))
11328 (match_operand 2 "const1_operand" ""))
11329 (const_string "alu")
11331 (const_string "ishift")))
11332 (set_attr "mode" "SI")])
11334 ;; Convert lea to the lea pattern to avoid flags dependency.
11336 [(set (match_operand 0 "register_operand" "")
11337 (ashift (match_operand 1 "index_register_operand" "")
11338 (match_operand:QI 2 "const_int_operand" "")))
11339 (clobber (reg:CC FLAGS_REG))]
11341 && true_regnum (operands[0]) != true_regnum (operands[1])
11342 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11346 enum machine_mode mode = GET_MODE (operands[0]);
11348 if (GET_MODE_SIZE (mode) < 4)
11349 operands[0] = gen_lowpart (SImode, operands[0]);
11351 operands[1] = gen_lowpart (Pmode, operands[1]);
11352 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11354 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11355 if (Pmode != SImode)
11356 pat = gen_rtx_SUBREG (SImode, pat, 0);
11357 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11361 ;; Rare case of shifting RSP is handled by generating move and shift
11363 [(set (match_operand 0 "register_operand" "")
11364 (ashift (match_operand 1 "register_operand" "")
11365 (match_operand:QI 2 "const_int_operand" "")))
11366 (clobber (reg:CC FLAGS_REG))]
11368 && true_regnum (operands[0]) != true_regnum (operands[1])"
11372 emit_move_insn (operands[0], operands[1]);
11373 pat = gen_rtx_SET (VOIDmode, operands[0],
11374 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11375 operands[0], operands[2]));
11376 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11377 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11381 (define_insn "*ashlsi3_1_zext"
11382 [(set (match_operand:DI 0 "register_operand" "=r,r")
11383 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11384 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11385 (clobber (reg:CC FLAGS_REG))]
11386 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11388 switch (get_attr_type (insn))
11391 gcc_assert (operands[2] == const1_rtx);
11392 return "add{l}\t%k0, %k0";
11398 if (REG_P (operands[2]))
11399 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11400 else if (operands[2] == const1_rtx
11401 && (TARGET_SHIFT1 || optimize_size))
11402 return "sal{l}\t%k0";
11404 return "sal{l}\t{%2, %k0|%k0, %2}";
11407 [(set (attr "type")
11408 (cond [(eq_attr "alternative" "1")
11409 (const_string "lea")
11410 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11412 (match_operand 2 "const1_operand" ""))
11413 (const_string "alu")
11415 (const_string "ishift")))
11416 (set_attr "mode" "SI")])
11418 ;; Convert lea to the lea pattern to avoid flags dependency.
11420 [(set (match_operand:DI 0 "register_operand" "")
11421 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11422 (match_operand:QI 2 "const_int_operand" ""))))
11423 (clobber (reg:CC FLAGS_REG))]
11424 "TARGET_64BIT && reload_completed
11425 && true_regnum (operands[0]) != true_regnum (operands[1])"
11426 [(set (match_dup 0) (zero_extend:DI
11427 (subreg:SI (mult:SI (match_dup 1)
11428 (match_dup 2)) 0)))]
11430 operands[1] = gen_lowpart (Pmode, operands[1]);
11431 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11434 ;; This pattern can't accept a variable shift count, since shifts by
11435 ;; zero don't affect the flags. We assume that shifts by constant
11436 ;; zero are optimized away.
11437 (define_insn "*ashlsi3_cmp"
11438 [(set (reg FLAGS_REG)
11440 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11441 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11443 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11444 (ashift:SI (match_dup 1) (match_dup 2)))]
11446 || !TARGET_PARTIAL_FLAG_REG_STALL
11447 || (operands[2] == const1_rtx
11449 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11450 && ix86_match_ccmode (insn, CCGOCmode)
11451 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11453 switch (get_attr_type (insn))
11456 gcc_assert (operands[2] == const1_rtx);
11457 return "add{l}\t%0, %0";
11460 if (REG_P (operands[2]))
11461 return "sal{l}\t{%b2, %0|%0, %b2}";
11462 else if (operands[2] == const1_rtx
11463 && (TARGET_SHIFT1 || optimize_size))
11464 return "sal{l}\t%0";
11466 return "sal{l}\t{%2, %0|%0, %2}";
11469 [(set (attr "type")
11470 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11472 (match_operand 0 "register_operand" ""))
11473 (match_operand 2 "const1_operand" ""))
11474 (const_string "alu")
11476 (const_string "ishift")))
11477 (set_attr "mode" "SI")])
11479 (define_insn "*ashlsi3_cconly"
11480 [(set (reg FLAGS_REG)
11482 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11483 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11485 (clobber (match_scratch:SI 0 "=r"))]
11487 || !TARGET_PARTIAL_FLAG_REG_STALL
11488 || (operands[2] == const1_rtx
11490 || TARGET_DOUBLE_WITH_ADD)))
11491 && ix86_match_ccmode (insn, CCGOCmode)
11492 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11494 switch (get_attr_type (insn))
11497 gcc_assert (operands[2] == const1_rtx);
11498 return "add{l}\t%0, %0";
11501 if (REG_P (operands[2]))
11502 return "sal{l}\t{%b2, %0|%0, %b2}";
11503 else if (operands[2] == const1_rtx
11504 && (TARGET_SHIFT1 || optimize_size))
11505 return "sal{l}\t%0";
11507 return "sal{l}\t{%2, %0|%0, %2}";
11510 [(set (attr "type")
11511 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11513 (match_operand 0 "register_operand" ""))
11514 (match_operand 2 "const1_operand" ""))
11515 (const_string "alu")
11517 (const_string "ishift")))
11518 (set_attr "mode" "SI")])
11520 (define_insn "*ashlsi3_cmp_zext"
11521 [(set (reg FLAGS_REG)
11523 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11524 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11526 (set (match_operand:DI 0 "register_operand" "=r")
11527 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11530 || !TARGET_PARTIAL_FLAG_REG_STALL
11531 || (operands[2] == const1_rtx
11533 || TARGET_DOUBLE_WITH_ADD)))
11534 && ix86_match_ccmode (insn, CCGOCmode)
11535 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11537 switch (get_attr_type (insn))
11540 gcc_assert (operands[2] == const1_rtx);
11541 return "add{l}\t%k0, %k0";
11544 if (REG_P (operands[2]))
11545 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11546 else if (operands[2] == const1_rtx
11547 && (TARGET_SHIFT1 || optimize_size))
11548 return "sal{l}\t%k0";
11550 return "sal{l}\t{%2, %k0|%k0, %2}";
11553 [(set (attr "type")
11554 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11556 (match_operand 2 "const1_operand" ""))
11557 (const_string "alu")
11559 (const_string "ishift")))
11560 (set_attr "mode" "SI")])
11562 (define_expand "ashlhi3"
11563 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11564 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11565 (match_operand:QI 2 "nonmemory_operand" "")))
11566 (clobber (reg:CC FLAGS_REG))]
11567 "TARGET_HIMODE_MATH"
11568 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11570 (define_insn "*ashlhi3_1_lea"
11571 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11572 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11573 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11574 (clobber (reg:CC FLAGS_REG))]
11575 "!TARGET_PARTIAL_REG_STALL
11576 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11578 switch (get_attr_type (insn))
11583 gcc_assert (operands[2] == const1_rtx);
11584 return "add{w}\t%0, %0";
11587 if (REG_P (operands[2]))
11588 return "sal{w}\t{%b2, %0|%0, %b2}";
11589 else if (operands[2] == const1_rtx
11590 && (TARGET_SHIFT1 || optimize_size))
11591 return "sal{w}\t%0";
11593 return "sal{w}\t{%2, %0|%0, %2}";
11596 [(set (attr "type")
11597 (cond [(eq_attr "alternative" "1")
11598 (const_string "lea")
11599 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11601 (match_operand 0 "register_operand" ""))
11602 (match_operand 2 "const1_operand" ""))
11603 (const_string "alu")
11605 (const_string "ishift")))
11606 (set_attr "mode" "HI,SI")])
11608 (define_insn "*ashlhi3_1"
11609 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11610 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11611 (match_operand:QI 2 "nonmemory_operand" "cI")))
11612 (clobber (reg:CC FLAGS_REG))]
11613 "TARGET_PARTIAL_REG_STALL
11614 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11616 switch (get_attr_type (insn))
11619 gcc_assert (operands[2] == const1_rtx);
11620 return "add{w}\t%0, %0";
11623 if (REG_P (operands[2]))
11624 return "sal{w}\t{%b2, %0|%0, %b2}";
11625 else if (operands[2] == const1_rtx
11626 && (TARGET_SHIFT1 || optimize_size))
11627 return "sal{w}\t%0";
11629 return "sal{w}\t{%2, %0|%0, %2}";
11632 [(set (attr "type")
11633 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11635 (match_operand 0 "register_operand" ""))
11636 (match_operand 2 "const1_operand" ""))
11637 (const_string "alu")
11639 (const_string "ishift")))
11640 (set_attr "mode" "HI")])
11642 ;; This pattern can't accept a variable shift count, since shifts by
11643 ;; zero don't affect the flags. We assume that shifts by constant
11644 ;; zero are optimized away.
11645 (define_insn "*ashlhi3_cmp"
11646 [(set (reg FLAGS_REG)
11648 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11649 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11651 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11652 (ashift:HI (match_dup 1) (match_dup 2)))]
11654 || !TARGET_PARTIAL_FLAG_REG_STALL
11655 || (operands[2] == const1_rtx
11657 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11658 && ix86_match_ccmode (insn, CCGOCmode)
11659 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11661 switch (get_attr_type (insn))
11664 gcc_assert (operands[2] == const1_rtx);
11665 return "add{w}\t%0, %0";
11668 if (REG_P (operands[2]))
11669 return "sal{w}\t{%b2, %0|%0, %b2}";
11670 else if (operands[2] == const1_rtx
11671 && (TARGET_SHIFT1 || optimize_size))
11672 return "sal{w}\t%0";
11674 return "sal{w}\t{%2, %0|%0, %2}";
11677 [(set (attr "type")
11678 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11680 (match_operand 0 "register_operand" ""))
11681 (match_operand 2 "const1_operand" ""))
11682 (const_string "alu")
11684 (const_string "ishift")))
11685 (set_attr "mode" "HI")])
11687 (define_insn "*ashlhi3_cconly"
11688 [(set (reg FLAGS_REG)
11690 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11691 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11693 (clobber (match_scratch:HI 0 "=r"))]
11695 || !TARGET_PARTIAL_FLAG_REG_STALL
11696 || (operands[2] == const1_rtx
11698 || TARGET_DOUBLE_WITH_ADD)))
11699 && ix86_match_ccmode (insn, CCGOCmode)
11700 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11702 switch (get_attr_type (insn))
11705 gcc_assert (operands[2] == const1_rtx);
11706 return "add{w}\t%0, %0";
11709 if (REG_P (operands[2]))
11710 return "sal{w}\t{%b2, %0|%0, %b2}";
11711 else if (operands[2] == const1_rtx
11712 && (TARGET_SHIFT1 || optimize_size))
11713 return "sal{w}\t%0";
11715 return "sal{w}\t{%2, %0|%0, %2}";
11718 [(set (attr "type")
11719 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11721 (match_operand 0 "register_operand" ""))
11722 (match_operand 2 "const1_operand" ""))
11723 (const_string "alu")
11725 (const_string "ishift")))
11726 (set_attr "mode" "HI")])
11728 (define_expand "ashlqi3"
11729 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11730 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11731 (match_operand:QI 2 "nonmemory_operand" "")))
11732 (clobber (reg:CC FLAGS_REG))]
11733 "TARGET_QIMODE_MATH"
11734 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11736 ;; %%% Potential partial reg stall on alternative 2. What to do?
11738 (define_insn "*ashlqi3_1_lea"
11739 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11740 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11741 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11742 (clobber (reg:CC FLAGS_REG))]
11743 "!TARGET_PARTIAL_REG_STALL
11744 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11746 switch (get_attr_type (insn))
11751 gcc_assert (operands[2] == const1_rtx);
11752 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11753 return "add{l}\t%k0, %k0";
11755 return "add{b}\t%0, %0";
11758 if (REG_P (operands[2]))
11760 if (get_attr_mode (insn) == MODE_SI)
11761 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11763 return "sal{b}\t{%b2, %0|%0, %b2}";
11765 else if (operands[2] == const1_rtx
11766 && (TARGET_SHIFT1 || optimize_size))
11768 if (get_attr_mode (insn) == MODE_SI)
11769 return "sal{l}\t%0";
11771 return "sal{b}\t%0";
11775 if (get_attr_mode (insn) == MODE_SI)
11776 return "sal{l}\t{%2, %k0|%k0, %2}";
11778 return "sal{b}\t{%2, %0|%0, %2}";
11782 [(set (attr "type")
11783 (cond [(eq_attr "alternative" "2")
11784 (const_string "lea")
11785 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11787 (match_operand 0 "register_operand" ""))
11788 (match_operand 2 "const1_operand" ""))
11789 (const_string "alu")
11791 (const_string "ishift")))
11792 (set_attr "mode" "QI,SI,SI")])
11794 (define_insn "*ashlqi3_1"
11795 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11796 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11797 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11798 (clobber (reg:CC FLAGS_REG))]
11799 "TARGET_PARTIAL_REG_STALL
11800 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11802 switch (get_attr_type (insn))
11805 gcc_assert (operands[2] == const1_rtx);
11806 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11807 return "add{l}\t%k0, %k0";
11809 return "add{b}\t%0, %0";
11812 if (REG_P (operands[2]))
11814 if (get_attr_mode (insn) == MODE_SI)
11815 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11817 return "sal{b}\t{%b2, %0|%0, %b2}";
11819 else if (operands[2] == const1_rtx
11820 && (TARGET_SHIFT1 || optimize_size))
11822 if (get_attr_mode (insn) == MODE_SI)
11823 return "sal{l}\t%0";
11825 return "sal{b}\t%0";
11829 if (get_attr_mode (insn) == MODE_SI)
11830 return "sal{l}\t{%2, %k0|%k0, %2}";
11832 return "sal{b}\t{%2, %0|%0, %2}";
11836 [(set (attr "type")
11837 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11839 (match_operand 0 "register_operand" ""))
11840 (match_operand 2 "const1_operand" ""))
11841 (const_string "alu")
11843 (const_string "ishift")))
11844 (set_attr "mode" "QI,SI")])
11846 ;; This pattern can't accept a variable shift count, since shifts by
11847 ;; zero don't affect the flags. We assume that shifts by constant
11848 ;; zero are optimized away.
11849 (define_insn "*ashlqi3_cmp"
11850 [(set (reg FLAGS_REG)
11852 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11853 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11855 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11856 (ashift:QI (match_dup 1) (match_dup 2)))]
11858 || !TARGET_PARTIAL_FLAG_REG_STALL
11859 || (operands[2] == const1_rtx
11861 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11862 && ix86_match_ccmode (insn, CCGOCmode)
11863 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11865 switch (get_attr_type (insn))
11868 gcc_assert (operands[2] == const1_rtx);
11869 return "add{b}\t%0, %0";
11872 if (REG_P (operands[2]))
11873 return "sal{b}\t{%b2, %0|%0, %b2}";
11874 else if (operands[2] == const1_rtx
11875 && (TARGET_SHIFT1 || optimize_size))
11876 return "sal{b}\t%0";
11878 return "sal{b}\t{%2, %0|%0, %2}";
11881 [(set (attr "type")
11882 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11884 (match_operand 0 "register_operand" ""))
11885 (match_operand 2 "const1_operand" ""))
11886 (const_string "alu")
11888 (const_string "ishift")))
11889 (set_attr "mode" "QI")])
11891 (define_insn "*ashlqi3_cconly"
11892 [(set (reg FLAGS_REG)
11894 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11895 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11897 (clobber (match_scratch:QI 0 "=q"))]
11899 || !TARGET_PARTIAL_FLAG_REG_STALL
11900 || (operands[2] == const1_rtx
11902 || TARGET_DOUBLE_WITH_ADD)))
11903 && ix86_match_ccmode (insn, CCGOCmode)
11904 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11906 switch (get_attr_type (insn))
11909 gcc_assert (operands[2] == const1_rtx);
11910 return "add{b}\t%0, %0";
11913 if (REG_P (operands[2]))
11914 return "sal{b}\t{%b2, %0|%0, %b2}";
11915 else if (operands[2] == const1_rtx
11916 && (TARGET_SHIFT1 || optimize_size))
11917 return "sal{b}\t%0";
11919 return "sal{b}\t{%2, %0|%0, %2}";
11922 [(set (attr "type")
11923 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11925 (match_operand 0 "register_operand" ""))
11926 (match_operand 2 "const1_operand" ""))
11927 (const_string "alu")
11929 (const_string "ishift")))
11930 (set_attr "mode" "QI")])
11932 ;; See comment above `ashldi3' about how this works.
11934 (define_expand "ashrti3"
11935 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11936 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11937 (match_operand:QI 2 "nonmemory_operand" "")))
11938 (clobber (reg:CC FLAGS_REG))])]
11941 if (! immediate_operand (operands[2], QImode))
11943 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11946 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11950 (define_insn "ashrti3_1"
11951 [(set (match_operand:TI 0 "register_operand" "=r")
11952 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11953 (match_operand:QI 2 "register_operand" "c")))
11954 (clobber (match_scratch:DI 3 "=&r"))
11955 (clobber (reg:CC FLAGS_REG))]
11958 [(set_attr "type" "multi")])
11960 (define_insn "*ashrti3_2"
11961 [(set (match_operand:TI 0 "register_operand" "=r")
11962 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11963 (match_operand:QI 2 "immediate_operand" "O")))
11964 (clobber (reg:CC FLAGS_REG))]
11967 [(set_attr "type" "multi")])
11970 [(set (match_operand:TI 0 "register_operand" "")
11971 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11972 (match_operand:QI 2 "register_operand" "")))
11973 (clobber (match_scratch:DI 3 ""))
11974 (clobber (reg:CC FLAGS_REG))]
11975 "TARGET_64BIT && reload_completed"
11977 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11980 [(set (match_operand:TI 0 "register_operand" "")
11981 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11982 (match_operand:QI 2 "immediate_operand" "")))
11983 (clobber (reg:CC FLAGS_REG))]
11984 "TARGET_64BIT && reload_completed"
11986 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11988 (define_insn "x86_64_shrd"
11989 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11990 (ior:DI (ashiftrt:DI (match_dup 0)
11991 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11992 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11993 (minus:QI (const_int 64) (match_dup 2)))))
11994 (clobber (reg:CC FLAGS_REG))]
11997 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11998 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11999 [(set_attr "type" "ishift")
12000 (set_attr "prefix_0f" "1")
12001 (set_attr "mode" "DI")
12002 (set_attr "athlon_decode" "vector")
12003 (set_attr "amdfam10_decode" "vector")])
12005 (define_expand "ashrdi3"
12006 [(set (match_operand:DI 0 "shiftdi_operand" "")
12007 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12008 (match_operand:QI 2 "nonmemory_operand" "")))]
12010 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12012 (define_insn "*ashrdi3_63_rex64"
12013 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12014 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12015 (match_operand:DI 2 "const_int_operand" "i,i")))
12016 (clobber (reg:CC FLAGS_REG))]
12017 "TARGET_64BIT && INTVAL (operands[2]) == 63
12018 && (TARGET_USE_CLTD || optimize_size)
12019 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12022 sar{q}\t{%2, %0|%0, %2}"
12023 [(set_attr "type" "imovx,ishift")
12024 (set_attr "prefix_0f" "0,*")
12025 (set_attr "length_immediate" "0,*")
12026 (set_attr "modrm" "0,1")
12027 (set_attr "mode" "DI")])
12029 (define_insn "*ashrdi3_1_one_bit_rex64"
12030 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12031 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12032 (match_operand:QI 2 "const1_operand" "")))
12033 (clobber (reg:CC FLAGS_REG))]
12035 && (TARGET_SHIFT1 || optimize_size)
12036 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12038 [(set_attr "type" "ishift")
12039 (set (attr "length")
12040 (if_then_else (match_operand:DI 0 "register_operand" "")
12042 (const_string "*")))])
12044 (define_insn "*ashrdi3_1_rex64"
12045 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12046 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12047 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12048 (clobber (reg:CC FLAGS_REG))]
12049 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12051 sar{q}\t{%2, %0|%0, %2}
12052 sar{q}\t{%b2, %0|%0, %b2}"
12053 [(set_attr "type" "ishift")
12054 (set_attr "mode" "DI")])
12056 ;; This pattern can't accept a variable shift count, since shifts by
12057 ;; zero don't affect the flags. We assume that shifts by constant
12058 ;; zero are optimized away.
12059 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12060 [(set (reg FLAGS_REG)
12062 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12063 (match_operand:QI 2 "const1_operand" ""))
12065 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12066 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12068 && (TARGET_SHIFT1 || optimize_size)
12069 && ix86_match_ccmode (insn, CCGOCmode)
12070 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12072 [(set_attr "type" "ishift")
12073 (set (attr "length")
12074 (if_then_else (match_operand:DI 0 "register_operand" "")
12076 (const_string "*")))])
12078 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12079 [(set (reg FLAGS_REG)
12081 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12082 (match_operand:QI 2 "const1_operand" ""))
12084 (clobber (match_scratch:DI 0 "=r"))]
12086 && (TARGET_SHIFT1 || optimize_size)
12087 && ix86_match_ccmode (insn, CCGOCmode)
12088 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12090 [(set_attr "type" "ishift")
12091 (set_attr "length" "2")])
12093 ;; This pattern can't accept a variable shift count, since shifts by
12094 ;; zero don't affect the flags. We assume that shifts by constant
12095 ;; zero are optimized away.
12096 (define_insn "*ashrdi3_cmp_rex64"
12097 [(set (reg FLAGS_REG)
12099 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12100 (match_operand:QI 2 "const_int_operand" "n"))
12102 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12103 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12105 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12106 && ix86_match_ccmode (insn, CCGOCmode)
12107 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12108 "sar{q}\t{%2, %0|%0, %2}"
12109 [(set_attr "type" "ishift")
12110 (set_attr "mode" "DI")])
12112 (define_insn "*ashrdi3_cconly_rex64"
12113 [(set (reg FLAGS_REG)
12115 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12116 (match_operand:QI 2 "const_int_operand" "n"))
12118 (clobber (match_scratch:DI 0 "=r"))]
12120 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12121 && ix86_match_ccmode (insn, CCGOCmode)
12122 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12123 "sar{q}\t{%2, %0|%0, %2}"
12124 [(set_attr "type" "ishift")
12125 (set_attr "mode" "DI")])
12127 (define_insn "*ashrdi3_1"
12128 [(set (match_operand:DI 0 "register_operand" "=r")
12129 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12130 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12131 (clobber (reg:CC FLAGS_REG))]
12134 [(set_attr "type" "multi")])
12136 ;; By default we don't ask for a scratch register, because when DImode
12137 ;; values are manipulated, registers are already at a premium. But if
12138 ;; we have one handy, we won't turn it away.
12140 [(match_scratch:SI 3 "r")
12141 (parallel [(set (match_operand:DI 0 "register_operand" "")
12142 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12143 (match_operand:QI 2 "nonmemory_operand" "")))
12144 (clobber (reg:CC FLAGS_REG))])
12146 "!TARGET_64BIT && TARGET_CMOVE"
12148 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12151 [(set (match_operand:DI 0 "register_operand" "")
12152 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12153 (match_operand:QI 2 "nonmemory_operand" "")))
12154 (clobber (reg:CC FLAGS_REG))]
12155 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12156 ? epilogue_completed : reload_completed)"
12158 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12160 (define_insn "x86_shrd_1"
12161 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12162 (ior:SI (ashiftrt:SI (match_dup 0)
12163 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12164 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12165 (minus:QI (const_int 32) (match_dup 2)))))
12166 (clobber (reg:CC FLAGS_REG))]
12169 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12170 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12171 [(set_attr "type" "ishift")
12172 (set_attr "prefix_0f" "1")
12173 (set_attr "pent_pair" "np")
12174 (set_attr "mode" "SI")])
12176 (define_expand "x86_shift_adj_3"
12177 [(use (match_operand:SI 0 "register_operand" ""))
12178 (use (match_operand:SI 1 "register_operand" ""))
12179 (use (match_operand:QI 2 "register_operand" ""))]
12182 rtx label = gen_label_rtx ();
12185 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12187 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12188 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12189 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12190 gen_rtx_LABEL_REF (VOIDmode, label),
12192 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12193 JUMP_LABEL (tmp) = label;
12195 emit_move_insn (operands[0], operands[1]);
12196 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12198 emit_label (label);
12199 LABEL_NUSES (label) = 1;
12204 (define_insn "ashrsi3_31"
12205 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12206 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12207 (match_operand:SI 2 "const_int_operand" "i,i")))
12208 (clobber (reg:CC FLAGS_REG))]
12209 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12210 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12213 sar{l}\t{%2, %0|%0, %2}"
12214 [(set_attr "type" "imovx,ishift")
12215 (set_attr "prefix_0f" "0,*")
12216 (set_attr "length_immediate" "0,*")
12217 (set_attr "modrm" "0,1")
12218 (set_attr "mode" "SI")])
12220 (define_insn "*ashrsi3_31_zext"
12221 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12222 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12223 (match_operand:SI 2 "const_int_operand" "i,i"))))
12224 (clobber (reg:CC FLAGS_REG))]
12225 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12226 && INTVAL (operands[2]) == 31
12227 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12230 sar{l}\t{%2, %k0|%k0, %2}"
12231 [(set_attr "type" "imovx,ishift")
12232 (set_attr "prefix_0f" "0,*")
12233 (set_attr "length_immediate" "0,*")
12234 (set_attr "modrm" "0,1")
12235 (set_attr "mode" "SI")])
12237 (define_expand "ashrsi3"
12238 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12239 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12240 (match_operand:QI 2 "nonmemory_operand" "")))
12241 (clobber (reg:CC FLAGS_REG))]
12243 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12245 (define_insn "*ashrsi3_1_one_bit"
12246 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12247 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12248 (match_operand:QI 2 "const1_operand" "")))
12249 (clobber (reg:CC FLAGS_REG))]
12250 "(TARGET_SHIFT1 || optimize_size)
12251 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12253 [(set_attr "type" "ishift")
12254 (set (attr "length")
12255 (if_then_else (match_operand:SI 0 "register_operand" "")
12257 (const_string "*")))])
12259 (define_insn "*ashrsi3_1_one_bit_zext"
12260 [(set (match_operand:DI 0 "register_operand" "=r")
12261 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12262 (match_operand:QI 2 "const1_operand" ""))))
12263 (clobber (reg:CC FLAGS_REG))]
12265 && (TARGET_SHIFT1 || optimize_size)
12266 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12268 [(set_attr "type" "ishift")
12269 (set_attr "length" "2")])
12271 (define_insn "*ashrsi3_1"
12272 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12273 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12274 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12275 (clobber (reg:CC FLAGS_REG))]
12276 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12278 sar{l}\t{%2, %0|%0, %2}
12279 sar{l}\t{%b2, %0|%0, %b2}"
12280 [(set_attr "type" "ishift")
12281 (set_attr "mode" "SI")])
12283 (define_insn "*ashrsi3_1_zext"
12284 [(set (match_operand:DI 0 "register_operand" "=r,r")
12285 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12286 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12287 (clobber (reg:CC FLAGS_REG))]
12288 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12290 sar{l}\t{%2, %k0|%k0, %2}
12291 sar{l}\t{%b2, %k0|%k0, %b2}"
12292 [(set_attr "type" "ishift")
12293 (set_attr "mode" "SI")])
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_one_bit_cmp"
12299 [(set (reg FLAGS_REG)
12301 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12302 (match_operand:QI 2 "const1_operand" ""))
12304 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12305 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12306 "(TARGET_SHIFT1 || optimize_size)
12307 && ix86_match_ccmode (insn, CCGOCmode)
12308 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12310 [(set_attr "type" "ishift")
12311 (set (attr "length")
12312 (if_then_else (match_operand:SI 0 "register_operand" "")
12314 (const_string "*")))])
12316 (define_insn "*ashrsi3_one_bit_cconly"
12317 [(set (reg FLAGS_REG)
12319 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12320 (match_operand:QI 2 "const1_operand" ""))
12322 (clobber (match_scratch:SI 0 "=r"))]
12323 "(TARGET_SHIFT1 || optimize_size)
12324 && ix86_match_ccmode (insn, CCGOCmode)
12325 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12327 [(set_attr "type" "ishift")
12328 (set_attr "length" "2")])
12330 (define_insn "*ashrsi3_one_bit_cmp_zext"
12331 [(set (reg FLAGS_REG)
12333 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12334 (match_operand:QI 2 "const1_operand" ""))
12336 (set (match_operand:DI 0 "register_operand" "=r")
12337 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12339 && (TARGET_SHIFT1 || optimize_size)
12340 && ix86_match_ccmode (insn, CCmode)
12341 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12343 [(set_attr "type" "ishift")
12344 (set_attr "length" "2")])
12346 ;; This pattern can't accept a variable shift count, since shifts by
12347 ;; zero don't affect the flags. We assume that shifts by constant
12348 ;; zero are optimized away.
12349 (define_insn "*ashrsi3_cmp"
12350 [(set (reg FLAGS_REG)
12352 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12353 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12355 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12356 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12357 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12358 && ix86_match_ccmode (insn, CCGOCmode)
12359 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12360 "sar{l}\t{%2, %0|%0, %2}"
12361 [(set_attr "type" "ishift")
12362 (set_attr "mode" "SI")])
12364 (define_insn "*ashrsi3_cconly"
12365 [(set (reg FLAGS_REG)
12367 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12370 (clobber (match_scratch:SI 0 "=r"))]
12371 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12372 && ix86_match_ccmode (insn, CCGOCmode)
12373 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12374 "sar{l}\t{%2, %0|%0, %2}"
12375 [(set_attr "type" "ishift")
12376 (set_attr "mode" "SI")])
12378 (define_insn "*ashrsi3_cmp_zext"
12379 [(set (reg FLAGS_REG)
12381 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12382 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12384 (set (match_operand:DI 0 "register_operand" "=r")
12385 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12387 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12388 && ix86_match_ccmode (insn, CCGOCmode)
12389 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12390 "sar{l}\t{%2, %k0|%k0, %2}"
12391 [(set_attr "type" "ishift")
12392 (set_attr "mode" "SI")])
12394 (define_expand "ashrhi3"
12395 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12396 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12397 (match_operand:QI 2 "nonmemory_operand" "")))
12398 (clobber (reg:CC FLAGS_REG))]
12399 "TARGET_HIMODE_MATH"
12400 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12402 (define_insn "*ashrhi3_1_one_bit"
12403 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12404 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12405 (match_operand:QI 2 "const1_operand" "")))
12406 (clobber (reg:CC FLAGS_REG))]
12407 "(TARGET_SHIFT1 || optimize_size)
12408 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12410 [(set_attr "type" "ishift")
12411 (set (attr "length")
12412 (if_then_else (match_operand 0 "register_operand" "")
12414 (const_string "*")))])
12416 (define_insn "*ashrhi3_1"
12417 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12418 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12419 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12420 (clobber (reg:CC FLAGS_REG))]
12421 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12423 sar{w}\t{%2, %0|%0, %2}
12424 sar{w}\t{%b2, %0|%0, %b2}"
12425 [(set_attr "type" "ishift")
12426 (set_attr "mode" "HI")])
12428 ;; This pattern can't accept a variable shift count, since shifts by
12429 ;; zero don't affect the flags. We assume that shifts by constant
12430 ;; zero are optimized away.
12431 (define_insn "*ashrhi3_one_bit_cmp"
12432 [(set (reg FLAGS_REG)
12434 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12435 (match_operand:QI 2 "const1_operand" ""))
12437 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12438 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12439 "(TARGET_SHIFT1 || optimize_size)
12440 && ix86_match_ccmode (insn, CCGOCmode)
12441 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12443 [(set_attr "type" "ishift")
12444 (set (attr "length")
12445 (if_then_else (match_operand 0 "register_operand" "")
12447 (const_string "*")))])
12449 (define_insn "*ashrhi3_one_bit_cconly"
12450 [(set (reg FLAGS_REG)
12452 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12453 (match_operand:QI 2 "const1_operand" ""))
12455 (clobber (match_scratch:HI 0 "=r"))]
12456 "(TARGET_SHIFT1 || optimize_size)
12457 && ix86_match_ccmode (insn, CCGOCmode)
12458 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12460 [(set_attr "type" "ishift")
12461 (set_attr "length" "2")])
12463 ;; This pattern can't accept a variable shift count, since shifts by
12464 ;; zero don't affect the flags. We assume that shifts by constant
12465 ;; zero are optimized away.
12466 (define_insn "*ashrhi3_cmp"
12467 [(set (reg FLAGS_REG)
12469 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12470 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12472 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12473 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12474 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12475 && ix86_match_ccmode (insn, CCGOCmode)
12476 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12477 "sar{w}\t{%2, %0|%0, %2}"
12478 [(set_attr "type" "ishift")
12479 (set_attr "mode" "HI")])
12481 (define_insn "*ashrhi3_cconly"
12482 [(set (reg FLAGS_REG)
12484 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12485 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12487 (clobber (match_scratch:HI 0 "=r"))]
12488 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12489 && ix86_match_ccmode (insn, CCGOCmode)
12490 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12491 "sar{w}\t{%2, %0|%0, %2}"
12492 [(set_attr "type" "ishift")
12493 (set_attr "mode" "HI")])
12495 (define_expand "ashrqi3"
12496 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12497 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12498 (match_operand:QI 2 "nonmemory_operand" "")))
12499 (clobber (reg:CC FLAGS_REG))]
12500 "TARGET_QIMODE_MATH"
12501 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12503 (define_insn "*ashrqi3_1_one_bit"
12504 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12505 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12506 (match_operand:QI 2 "const1_operand" "")))
12507 (clobber (reg:CC FLAGS_REG))]
12508 "(TARGET_SHIFT1 || optimize_size)
12509 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12511 [(set_attr "type" "ishift")
12512 (set (attr "length")
12513 (if_then_else (match_operand 0 "register_operand" "")
12515 (const_string "*")))])
12517 (define_insn "*ashrqi3_1_one_bit_slp"
12518 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12519 (ashiftrt:QI (match_dup 0)
12520 (match_operand:QI 1 "const1_operand" "")))
12521 (clobber (reg:CC FLAGS_REG))]
12522 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12523 && (TARGET_SHIFT1 || optimize_size)
12524 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12526 [(set_attr "type" "ishift1")
12527 (set (attr "length")
12528 (if_then_else (match_operand 0 "register_operand" "")
12530 (const_string "*")))])
12532 (define_insn "*ashrqi3_1"
12533 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12534 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12535 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12536 (clobber (reg:CC FLAGS_REG))]
12537 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12539 sar{b}\t{%2, %0|%0, %2}
12540 sar{b}\t{%b2, %0|%0, %b2}"
12541 [(set_attr "type" "ishift")
12542 (set_attr "mode" "QI")])
12544 (define_insn "*ashrqi3_1_slp"
12545 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12546 (ashiftrt:QI (match_dup 0)
12547 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12548 (clobber (reg:CC FLAGS_REG))]
12549 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12550 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12552 sar{b}\t{%1, %0|%0, %1}
12553 sar{b}\t{%b1, %0|%0, %b1}"
12554 [(set_attr "type" "ishift1")
12555 (set_attr "mode" "QI")])
12557 ;; This pattern can't accept a variable shift count, since shifts by
12558 ;; zero don't affect the flags. We assume that shifts by constant
12559 ;; zero are optimized away.
12560 (define_insn "*ashrqi3_one_bit_cmp"
12561 [(set (reg FLAGS_REG)
12563 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12564 (match_operand:QI 2 "const1_operand" "I"))
12566 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12567 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12568 "(TARGET_SHIFT1 || optimize_size)
12569 && ix86_match_ccmode (insn, CCGOCmode)
12570 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12572 [(set_attr "type" "ishift")
12573 (set (attr "length")
12574 (if_then_else (match_operand 0 "register_operand" "")
12576 (const_string "*")))])
12578 (define_insn "*ashrqi3_one_bit_cconly"
12579 [(set (reg FLAGS_REG)
12581 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12582 (match_operand:QI 2 "const1_operand" "I"))
12584 (clobber (match_scratch:QI 0 "=q"))]
12585 "(TARGET_SHIFT1 || optimize_size)
12586 && ix86_match_ccmode (insn, CCGOCmode)
12587 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12589 [(set_attr "type" "ishift")
12590 (set_attr "length" "2")])
12592 ;; This pattern can't accept a variable shift count, since shifts by
12593 ;; zero don't affect the flags. We assume that shifts by constant
12594 ;; zero are optimized away.
12595 (define_insn "*ashrqi3_cmp"
12596 [(set (reg FLAGS_REG)
12598 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12599 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12601 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12602 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12603 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12604 && ix86_match_ccmode (insn, CCGOCmode)
12605 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12606 "sar{b}\t{%2, %0|%0, %2}"
12607 [(set_attr "type" "ishift")
12608 (set_attr "mode" "QI")])
12610 (define_insn "*ashrqi3_cconly"
12611 [(set (reg FLAGS_REG)
12613 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12614 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12616 (clobber (match_scratch:QI 0 "=q"))]
12617 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12618 && ix86_match_ccmode (insn, CCGOCmode)
12619 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12620 "sar{b}\t{%2, %0|%0, %2}"
12621 [(set_attr "type" "ishift")
12622 (set_attr "mode" "QI")])
12625 ;; Logical shift instructions
12627 ;; See comment above `ashldi3' about how this works.
12629 (define_expand "lshrti3"
12630 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12631 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12632 (match_operand:QI 2 "nonmemory_operand" "")))
12633 (clobber (reg:CC FLAGS_REG))])]
12636 if (! immediate_operand (operands[2], QImode))
12638 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12641 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12645 (define_insn "lshrti3_1"
12646 [(set (match_operand:TI 0 "register_operand" "=r")
12647 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12648 (match_operand:QI 2 "register_operand" "c")))
12649 (clobber (match_scratch:DI 3 "=&r"))
12650 (clobber (reg:CC FLAGS_REG))]
12653 [(set_attr "type" "multi")])
12655 ;; This pattern must be defined before *lshrti3_2 to prevent
12656 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12658 (define_insn "sse2_lshrti3"
12659 [(set (match_operand:TI 0 "register_operand" "=x")
12660 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12661 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12664 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12665 return "psrldq\t{%2, %0|%0, %2}";
12667 [(set_attr "type" "sseishft")
12668 (set_attr "prefix_data16" "1")
12669 (set_attr "mode" "TI")])
12671 (define_insn "*lshrti3_2"
12672 [(set (match_operand:TI 0 "register_operand" "=r")
12673 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12674 (match_operand:QI 2 "immediate_operand" "O")))
12675 (clobber (reg:CC FLAGS_REG))]
12678 [(set_attr "type" "multi")])
12681 [(set (match_operand:TI 0 "register_operand" "")
12682 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12683 (match_operand:QI 2 "register_operand" "")))
12684 (clobber (match_scratch:DI 3 ""))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "TARGET_64BIT && reload_completed"
12688 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12691 [(set (match_operand:TI 0 "register_operand" "")
12692 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12693 (match_operand:QI 2 "immediate_operand" "")))
12694 (clobber (reg:CC FLAGS_REG))]
12695 "TARGET_64BIT && reload_completed"
12697 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12699 (define_expand "lshrdi3"
12700 [(set (match_operand:DI 0 "shiftdi_operand" "")
12701 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12702 (match_operand:QI 2 "nonmemory_operand" "")))]
12704 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12706 (define_insn "*lshrdi3_1_one_bit_rex64"
12707 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12708 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12709 (match_operand:QI 2 "const1_operand" "")))
12710 (clobber (reg:CC FLAGS_REG))]
12712 && (TARGET_SHIFT1 || optimize_size)
12713 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12715 [(set_attr "type" "ishift")
12716 (set (attr "length")
12717 (if_then_else (match_operand:DI 0 "register_operand" "")
12719 (const_string "*")))])
12721 (define_insn "*lshrdi3_1_rex64"
12722 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12723 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12724 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12725 (clobber (reg:CC FLAGS_REG))]
12726 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12728 shr{q}\t{%2, %0|%0, %2}
12729 shr{q}\t{%b2, %0|%0, %b2}"
12730 [(set_attr "type" "ishift")
12731 (set_attr "mode" "DI")])
12733 ;; This pattern can't accept a variable shift count, since shifts by
12734 ;; zero don't affect the flags. We assume that shifts by constant
12735 ;; zero are optimized away.
12736 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12737 [(set (reg FLAGS_REG)
12739 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12740 (match_operand:QI 2 "const1_operand" ""))
12742 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12743 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12745 && (TARGET_SHIFT1 || optimize_size)
12746 && ix86_match_ccmode (insn, CCGOCmode)
12747 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12749 [(set_attr "type" "ishift")
12750 (set (attr "length")
12751 (if_then_else (match_operand:DI 0 "register_operand" "")
12753 (const_string "*")))])
12755 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12756 [(set (reg FLAGS_REG)
12758 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12759 (match_operand:QI 2 "const1_operand" ""))
12761 (clobber (match_scratch:DI 0 "=r"))]
12763 && (TARGET_SHIFT1 || optimize_size)
12764 && ix86_match_ccmode (insn, CCGOCmode)
12765 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12767 [(set_attr "type" "ishift")
12768 (set_attr "length" "2")])
12770 ;; This pattern can't accept a variable shift count, since shifts by
12771 ;; zero don't affect the flags. We assume that shifts by constant
12772 ;; zero are optimized away.
12773 (define_insn "*lshrdi3_cmp_rex64"
12774 [(set (reg FLAGS_REG)
12776 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12777 (match_operand:QI 2 "const_int_operand" "e"))
12779 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12780 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12782 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12783 && ix86_match_ccmode (insn, CCGOCmode)
12784 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12785 "shr{q}\t{%2, %0|%0, %2}"
12786 [(set_attr "type" "ishift")
12787 (set_attr "mode" "DI")])
12789 (define_insn "*lshrdi3_cconly_rex64"
12790 [(set (reg FLAGS_REG)
12792 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12793 (match_operand:QI 2 "const_int_operand" "e"))
12795 (clobber (match_scratch:DI 0 "=r"))]
12797 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12798 && ix86_match_ccmode (insn, CCGOCmode)
12799 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12800 "shr{q}\t{%2, %0|%0, %2}"
12801 [(set_attr "type" "ishift")
12802 (set_attr "mode" "DI")])
12804 (define_insn "*lshrdi3_1"
12805 [(set (match_operand:DI 0 "register_operand" "=r")
12806 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12807 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12808 (clobber (reg:CC FLAGS_REG))]
12811 [(set_attr "type" "multi")])
12813 ;; By default we don't ask for a scratch register, because when DImode
12814 ;; values are manipulated, registers are already at a premium. But if
12815 ;; we have one handy, we won't turn it away.
12817 [(match_scratch:SI 3 "r")
12818 (parallel [(set (match_operand:DI 0 "register_operand" "")
12819 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12820 (match_operand:QI 2 "nonmemory_operand" "")))
12821 (clobber (reg:CC FLAGS_REG))])
12823 "!TARGET_64BIT && TARGET_CMOVE"
12825 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12828 [(set (match_operand:DI 0 "register_operand" "")
12829 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12830 (match_operand:QI 2 "nonmemory_operand" "")))
12831 (clobber (reg:CC FLAGS_REG))]
12832 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12833 ? epilogue_completed : reload_completed)"
12835 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12837 (define_expand "lshrsi3"
12838 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12839 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12840 (match_operand:QI 2 "nonmemory_operand" "")))
12841 (clobber (reg:CC FLAGS_REG))]
12843 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12845 (define_insn "*lshrsi3_1_one_bit"
12846 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12847 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12848 (match_operand:QI 2 "const1_operand" "")))
12849 (clobber (reg:CC FLAGS_REG))]
12850 "(TARGET_SHIFT1 || optimize_size)
12851 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12853 [(set_attr "type" "ishift")
12854 (set (attr "length")
12855 (if_then_else (match_operand:SI 0 "register_operand" "")
12857 (const_string "*")))])
12859 (define_insn "*lshrsi3_1_one_bit_zext"
12860 [(set (match_operand:DI 0 "register_operand" "=r")
12861 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12862 (match_operand:QI 2 "const1_operand" "")))
12863 (clobber (reg:CC FLAGS_REG))]
12865 && (TARGET_SHIFT1 || optimize_size)
12866 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12868 [(set_attr "type" "ishift")
12869 (set_attr "length" "2")])
12871 (define_insn "*lshrsi3_1"
12872 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12873 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12874 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12875 (clobber (reg:CC FLAGS_REG))]
12876 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12878 shr{l}\t{%2, %0|%0, %2}
12879 shr{l}\t{%b2, %0|%0, %b2}"
12880 [(set_attr "type" "ishift")
12881 (set_attr "mode" "SI")])
12883 (define_insn "*lshrsi3_1_zext"
12884 [(set (match_operand:DI 0 "register_operand" "=r,r")
12886 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12887 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12888 (clobber (reg:CC FLAGS_REG))]
12889 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12891 shr{l}\t{%2, %k0|%k0, %2}
12892 shr{l}\t{%b2, %k0|%k0, %b2}"
12893 [(set_attr "type" "ishift")
12894 (set_attr "mode" "SI")])
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_one_bit_cmp"
12900 [(set (reg FLAGS_REG)
12902 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12903 (match_operand:QI 2 "const1_operand" ""))
12905 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12906 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12907 "(TARGET_SHIFT1 || optimize_size)
12908 && ix86_match_ccmode (insn, CCGOCmode)
12909 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12911 [(set_attr "type" "ishift")
12912 (set (attr "length")
12913 (if_then_else (match_operand:SI 0 "register_operand" "")
12915 (const_string "*")))])
12917 (define_insn "*lshrsi3_one_bit_cconly"
12918 [(set (reg FLAGS_REG)
12920 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12921 (match_operand:QI 2 "const1_operand" ""))
12923 (clobber (match_scratch:SI 0 "=r"))]
12924 "(TARGET_SHIFT1 || optimize_size)
12925 && ix86_match_ccmode (insn, CCGOCmode)
12926 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12928 [(set_attr "type" "ishift")
12929 (set_attr "length" "2")])
12931 (define_insn "*lshrsi3_cmp_one_bit_zext"
12932 [(set (reg FLAGS_REG)
12934 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12935 (match_operand:QI 2 "const1_operand" ""))
12937 (set (match_operand:DI 0 "register_operand" "=r")
12938 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12940 && (TARGET_SHIFT1 || optimize_size)
12941 && ix86_match_ccmode (insn, CCGOCmode)
12942 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12944 [(set_attr "type" "ishift")
12945 (set_attr "length" "2")])
12947 ;; This pattern can't accept a variable shift count, since shifts by
12948 ;; zero don't affect the flags. We assume that shifts by constant
12949 ;; zero are optimized away.
12950 (define_insn "*lshrsi3_cmp"
12951 [(set (reg FLAGS_REG)
12953 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12954 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12956 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12957 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12958 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12959 && ix86_match_ccmode (insn, CCGOCmode)
12960 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12961 "shr{l}\t{%2, %0|%0, %2}"
12962 [(set_attr "type" "ishift")
12963 (set_attr "mode" "SI")])
12965 (define_insn "*lshrsi3_cconly"
12966 [(set (reg FLAGS_REG)
12968 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12969 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12971 (clobber (match_scratch:SI 0 "=r"))]
12972 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12973 && ix86_match_ccmode (insn, CCGOCmode)
12974 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12975 "shr{l}\t{%2, %0|%0, %2}"
12976 [(set_attr "type" "ishift")
12977 (set_attr "mode" "SI")])
12979 (define_insn "*lshrsi3_cmp_zext"
12980 [(set (reg FLAGS_REG)
12982 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12983 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12985 (set (match_operand:DI 0 "register_operand" "=r")
12986 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12988 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12989 && ix86_match_ccmode (insn, CCGOCmode)
12990 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12991 "shr{l}\t{%2, %k0|%k0, %2}"
12992 [(set_attr "type" "ishift")
12993 (set_attr "mode" "SI")])
12995 (define_expand "lshrhi3"
12996 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12997 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12998 (match_operand:QI 2 "nonmemory_operand" "")))
12999 (clobber (reg:CC FLAGS_REG))]
13000 "TARGET_HIMODE_MATH"
13001 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13003 (define_insn "*lshrhi3_1_one_bit"
13004 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13005 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13006 (match_operand:QI 2 "const1_operand" "")))
13007 (clobber (reg:CC FLAGS_REG))]
13008 "(TARGET_SHIFT1 || optimize_size)
13009 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13011 [(set_attr "type" "ishift")
13012 (set (attr "length")
13013 (if_then_else (match_operand 0 "register_operand" "")
13015 (const_string "*")))])
13017 (define_insn "*lshrhi3_1"
13018 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13019 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13020 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13021 (clobber (reg:CC FLAGS_REG))]
13022 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13024 shr{w}\t{%2, %0|%0, %2}
13025 shr{w}\t{%b2, %0|%0, %b2}"
13026 [(set_attr "type" "ishift")
13027 (set_attr "mode" "HI")])
13029 ;; This pattern can't accept a variable shift count, since shifts by
13030 ;; zero don't affect the flags. We assume that shifts by constant
13031 ;; zero are optimized away.
13032 (define_insn "*lshrhi3_one_bit_cmp"
13033 [(set (reg FLAGS_REG)
13035 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13036 (match_operand:QI 2 "const1_operand" ""))
13038 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13039 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13040 "(TARGET_SHIFT1 || optimize_size)
13041 && ix86_match_ccmode (insn, CCGOCmode)
13042 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13044 [(set_attr "type" "ishift")
13045 (set (attr "length")
13046 (if_then_else (match_operand:SI 0 "register_operand" "")
13048 (const_string "*")))])
13050 (define_insn "*lshrhi3_one_bit_cconly"
13051 [(set (reg FLAGS_REG)
13053 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13054 (match_operand:QI 2 "const1_operand" ""))
13056 (clobber (match_scratch:HI 0 "=r"))]
13057 "(TARGET_SHIFT1 || optimize_size)
13058 && ix86_match_ccmode (insn, CCGOCmode)
13059 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13061 [(set_attr "type" "ishift")
13062 (set_attr "length" "2")])
13064 ;; This pattern can't accept a variable shift count, since shifts by
13065 ;; zero don't affect the flags. We assume that shifts by constant
13066 ;; zero are optimized away.
13067 (define_insn "*lshrhi3_cmp"
13068 [(set (reg FLAGS_REG)
13070 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13071 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13073 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13074 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13075 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13076 && ix86_match_ccmode (insn, CCGOCmode)
13077 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13078 "shr{w}\t{%2, %0|%0, %2}"
13079 [(set_attr "type" "ishift")
13080 (set_attr "mode" "HI")])
13082 (define_insn "*lshrhi3_cconly"
13083 [(set (reg FLAGS_REG)
13085 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13086 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13088 (clobber (match_scratch:HI 0 "=r"))]
13089 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13090 && ix86_match_ccmode (insn, CCGOCmode)
13091 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13092 "shr{w}\t{%2, %0|%0, %2}"
13093 [(set_attr "type" "ishift")
13094 (set_attr "mode" "HI")])
13096 (define_expand "lshrqi3"
13097 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13098 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13099 (match_operand:QI 2 "nonmemory_operand" "")))
13100 (clobber (reg:CC FLAGS_REG))]
13101 "TARGET_QIMODE_MATH"
13102 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13104 (define_insn "*lshrqi3_1_one_bit"
13105 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13106 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13107 (match_operand:QI 2 "const1_operand" "")))
13108 (clobber (reg:CC FLAGS_REG))]
13109 "(TARGET_SHIFT1 || optimize_size)
13110 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13112 [(set_attr "type" "ishift")
13113 (set (attr "length")
13114 (if_then_else (match_operand 0 "register_operand" "")
13116 (const_string "*")))])
13118 (define_insn "*lshrqi3_1_one_bit_slp"
13119 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13120 (lshiftrt:QI (match_dup 0)
13121 (match_operand:QI 1 "const1_operand" "")))
13122 (clobber (reg:CC FLAGS_REG))]
13123 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13124 && (TARGET_SHIFT1 || optimize_size)"
13126 [(set_attr "type" "ishift1")
13127 (set (attr "length")
13128 (if_then_else (match_operand 0 "register_operand" "")
13130 (const_string "*")))])
13132 (define_insn "*lshrqi3_1"
13133 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13134 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13135 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13136 (clobber (reg:CC FLAGS_REG))]
13137 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13139 shr{b}\t{%2, %0|%0, %2}
13140 shr{b}\t{%b2, %0|%0, %b2}"
13141 [(set_attr "type" "ishift")
13142 (set_attr "mode" "QI")])
13144 (define_insn "*lshrqi3_1_slp"
13145 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13146 (lshiftrt:QI (match_dup 0)
13147 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13148 (clobber (reg:CC FLAGS_REG))]
13149 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13150 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13152 shr{b}\t{%1, %0|%0, %1}
13153 shr{b}\t{%b1, %0|%0, %b1}"
13154 [(set_attr "type" "ishift1")
13155 (set_attr "mode" "QI")])
13157 ;; This pattern can't accept a variable shift count, since shifts by
13158 ;; zero don't affect the flags. We assume that shifts by constant
13159 ;; zero are optimized away.
13160 (define_insn "*lshrqi2_one_bit_cmp"
13161 [(set (reg FLAGS_REG)
13163 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13164 (match_operand:QI 2 "const1_operand" ""))
13166 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13167 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13168 "(TARGET_SHIFT1 || optimize_size)
13169 && ix86_match_ccmode (insn, CCGOCmode)
13170 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13172 [(set_attr "type" "ishift")
13173 (set (attr "length")
13174 (if_then_else (match_operand:SI 0 "register_operand" "")
13176 (const_string "*")))])
13178 (define_insn "*lshrqi2_one_bit_cconly"
13179 [(set (reg FLAGS_REG)
13181 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13182 (match_operand:QI 2 "const1_operand" ""))
13184 (clobber (match_scratch:QI 0 "=q"))]
13185 "(TARGET_SHIFT1 || optimize_size)
13186 && ix86_match_ccmode (insn, CCGOCmode)
13187 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13189 [(set_attr "type" "ishift")
13190 (set_attr "length" "2")])
13192 ;; This pattern can't accept a variable shift count, since shifts by
13193 ;; zero don't affect the flags. We assume that shifts by constant
13194 ;; zero are optimized away.
13195 (define_insn "*lshrqi2_cmp"
13196 [(set (reg FLAGS_REG)
13198 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13199 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13201 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13202 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13203 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13204 && ix86_match_ccmode (insn, CCGOCmode)
13205 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13206 "shr{b}\t{%2, %0|%0, %2}"
13207 [(set_attr "type" "ishift")
13208 (set_attr "mode" "QI")])
13210 (define_insn "*lshrqi2_cconly"
13211 [(set (reg FLAGS_REG)
13213 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13214 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13216 (clobber (match_scratch:QI 0 "=q"))]
13217 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13218 && ix86_match_ccmode (insn, CCGOCmode)
13219 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13220 "shr{b}\t{%2, %0|%0, %2}"
13221 [(set_attr "type" "ishift")
13222 (set_attr "mode" "QI")])
13224 ;; Rotate instructions
13226 (define_expand "rotldi3"
13227 [(set (match_operand:DI 0 "shiftdi_operand" "")
13228 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13229 (match_operand:QI 2 "nonmemory_operand" "")))
13230 (clobber (reg:CC FLAGS_REG))]
13235 ix86_expand_binary_operator (ROTATE, DImode, operands);
13238 if (!const_1_to_31_operand (operands[2], VOIDmode))
13240 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13244 ;; Implement rotation using two double-precision shift instructions
13245 ;; and a scratch register.
13246 (define_insn_and_split "ix86_rotldi3"
13247 [(set (match_operand:DI 0 "register_operand" "=r")
13248 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13249 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13250 (clobber (reg:CC FLAGS_REG))
13251 (clobber (match_scratch:SI 3 "=&r"))]
13254 "&& reload_completed"
13255 [(set (match_dup 3) (match_dup 4))
13257 [(set (match_dup 4)
13258 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13259 (lshiftrt:SI (match_dup 5)
13260 (minus:QI (const_int 32) (match_dup 2)))))
13261 (clobber (reg:CC FLAGS_REG))])
13263 [(set (match_dup 5)
13264 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13265 (lshiftrt:SI (match_dup 3)
13266 (minus:QI (const_int 32) (match_dup 2)))))
13267 (clobber (reg:CC FLAGS_REG))])]
13268 "split_di (operands, 1, operands + 4, operands + 5);")
13270 (define_insn "*rotlsi3_1_one_bit_rex64"
13271 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13272 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13273 (match_operand:QI 2 "const1_operand" "")))
13274 (clobber (reg:CC FLAGS_REG))]
13276 && (TARGET_SHIFT1 || optimize_size)
13277 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13279 [(set_attr "type" "rotate")
13280 (set (attr "length")
13281 (if_then_else (match_operand:DI 0 "register_operand" "")
13283 (const_string "*")))])
13285 (define_insn "*rotldi3_1_rex64"
13286 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13287 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13288 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13289 (clobber (reg:CC FLAGS_REG))]
13290 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13292 rol{q}\t{%2, %0|%0, %2}
13293 rol{q}\t{%b2, %0|%0, %b2}"
13294 [(set_attr "type" "rotate")
13295 (set_attr "mode" "DI")])
13297 (define_expand "rotlsi3"
13298 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13299 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13300 (match_operand:QI 2 "nonmemory_operand" "")))
13301 (clobber (reg:CC FLAGS_REG))]
13303 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13305 (define_insn "*rotlsi3_1_one_bit"
13306 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13307 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13308 (match_operand:QI 2 "const1_operand" "")))
13309 (clobber (reg:CC FLAGS_REG))]
13310 "(TARGET_SHIFT1 || optimize_size)
13311 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13313 [(set_attr "type" "rotate")
13314 (set (attr "length")
13315 (if_then_else (match_operand:SI 0 "register_operand" "")
13317 (const_string "*")))])
13319 (define_insn "*rotlsi3_1_one_bit_zext"
13320 [(set (match_operand:DI 0 "register_operand" "=r")
13322 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13323 (match_operand:QI 2 "const1_operand" ""))))
13324 (clobber (reg:CC FLAGS_REG))]
13326 && (TARGET_SHIFT1 || optimize_size)
13327 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13329 [(set_attr "type" "rotate")
13330 (set_attr "length" "2")])
13332 (define_insn "*rotlsi3_1"
13333 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13334 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13335 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13336 (clobber (reg:CC FLAGS_REG))]
13337 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13339 rol{l}\t{%2, %0|%0, %2}
13340 rol{l}\t{%b2, %0|%0, %b2}"
13341 [(set_attr "type" "rotate")
13342 (set_attr "mode" "SI")])
13344 (define_insn "*rotlsi3_1_zext"
13345 [(set (match_operand:DI 0 "register_operand" "=r,r")
13347 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13348 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13349 (clobber (reg:CC FLAGS_REG))]
13350 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13352 rol{l}\t{%2, %k0|%k0, %2}
13353 rol{l}\t{%b2, %k0|%k0, %b2}"
13354 [(set_attr "type" "rotate")
13355 (set_attr "mode" "SI")])
13357 (define_expand "rotlhi3"
13358 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13359 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13360 (match_operand:QI 2 "nonmemory_operand" "")))
13361 (clobber (reg:CC FLAGS_REG))]
13362 "TARGET_HIMODE_MATH"
13363 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13365 (define_insn "*rotlhi3_1_one_bit"
13366 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13367 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13368 (match_operand:QI 2 "const1_operand" "")))
13369 (clobber (reg:CC FLAGS_REG))]
13370 "(TARGET_SHIFT1 || optimize_size)
13371 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13373 [(set_attr "type" "rotate")
13374 (set (attr "length")
13375 (if_then_else (match_operand 0 "register_operand" "")
13377 (const_string "*")))])
13379 (define_insn "*rotlhi3_1"
13380 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13381 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13382 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13383 (clobber (reg:CC FLAGS_REG))]
13384 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13386 rol{w}\t{%2, %0|%0, %2}
13387 rol{w}\t{%b2, %0|%0, %b2}"
13388 [(set_attr "type" "rotate")
13389 (set_attr "mode" "HI")])
13392 [(set (match_operand:HI 0 "register_operand" "")
13393 (rotate:HI (match_dup 0) (const_int 8)))
13394 (clobber (reg:CC FLAGS_REG))]
13396 [(parallel [(set (strict_low_part (match_dup 0))
13397 (bswap:HI (match_dup 0)))
13398 (clobber (reg:CC FLAGS_REG))])]
13401 (define_expand "rotlqi3"
13402 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13403 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13404 (match_operand:QI 2 "nonmemory_operand" "")))
13405 (clobber (reg:CC FLAGS_REG))]
13406 "TARGET_QIMODE_MATH"
13407 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13409 (define_insn "*rotlqi3_1_one_bit_slp"
13410 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13411 (rotate:QI (match_dup 0)
13412 (match_operand:QI 1 "const1_operand" "")))
13413 (clobber (reg:CC FLAGS_REG))]
13414 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13415 && (TARGET_SHIFT1 || optimize_size)"
13417 [(set_attr "type" "rotate1")
13418 (set (attr "length")
13419 (if_then_else (match_operand 0 "register_operand" "")
13421 (const_string "*")))])
13423 (define_insn "*rotlqi3_1_one_bit"
13424 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13425 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13426 (match_operand:QI 2 "const1_operand" "")))
13427 (clobber (reg:CC FLAGS_REG))]
13428 "(TARGET_SHIFT1 || optimize_size)
13429 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13431 [(set_attr "type" "rotate")
13432 (set (attr "length")
13433 (if_then_else (match_operand 0 "register_operand" "")
13435 (const_string "*")))])
13437 (define_insn "*rotlqi3_1_slp"
13438 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13439 (rotate:QI (match_dup 0)
13440 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13441 (clobber (reg:CC FLAGS_REG))]
13442 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13443 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13445 rol{b}\t{%1, %0|%0, %1}
13446 rol{b}\t{%b1, %0|%0, %b1}"
13447 [(set_attr "type" "rotate1")
13448 (set_attr "mode" "QI")])
13450 (define_insn "*rotlqi3_1"
13451 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13452 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13453 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13454 (clobber (reg:CC FLAGS_REG))]
13455 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13457 rol{b}\t{%2, %0|%0, %2}
13458 rol{b}\t{%b2, %0|%0, %b2}"
13459 [(set_attr "type" "rotate")
13460 (set_attr "mode" "QI")])
13462 (define_expand "rotrdi3"
13463 [(set (match_operand:DI 0 "shiftdi_operand" "")
13464 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13465 (match_operand:QI 2 "nonmemory_operand" "")))
13466 (clobber (reg:CC FLAGS_REG))]
13471 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13474 if (!const_1_to_31_operand (operands[2], VOIDmode))
13476 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13480 ;; Implement rotation using two double-precision shift instructions
13481 ;; and a scratch register.
13482 (define_insn_and_split "ix86_rotrdi3"
13483 [(set (match_operand:DI 0 "register_operand" "=r")
13484 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13485 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13486 (clobber (reg:CC FLAGS_REG))
13487 (clobber (match_scratch:SI 3 "=&r"))]
13490 "&& reload_completed"
13491 [(set (match_dup 3) (match_dup 4))
13493 [(set (match_dup 4)
13494 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13495 (ashift:SI (match_dup 5)
13496 (minus:QI (const_int 32) (match_dup 2)))))
13497 (clobber (reg:CC FLAGS_REG))])
13499 [(set (match_dup 5)
13500 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13501 (ashift:SI (match_dup 3)
13502 (minus:QI (const_int 32) (match_dup 2)))))
13503 (clobber (reg:CC FLAGS_REG))])]
13504 "split_di (operands, 1, operands + 4, operands + 5);")
13506 (define_insn "*rotrdi3_1_one_bit_rex64"
13507 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13508 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13509 (match_operand:QI 2 "const1_operand" "")))
13510 (clobber (reg:CC FLAGS_REG))]
13512 && (TARGET_SHIFT1 || optimize_size)
13513 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13515 [(set_attr "type" "rotate")
13516 (set (attr "length")
13517 (if_then_else (match_operand:DI 0 "register_operand" "")
13519 (const_string "*")))])
13521 (define_insn "*rotrdi3_1_rex64"
13522 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13523 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13524 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13525 (clobber (reg:CC FLAGS_REG))]
13526 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13528 ror{q}\t{%2, %0|%0, %2}
13529 ror{q}\t{%b2, %0|%0, %b2}"
13530 [(set_attr "type" "rotate")
13531 (set_attr "mode" "DI")])
13533 (define_expand "rotrsi3"
13534 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13535 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13536 (match_operand:QI 2 "nonmemory_operand" "")))
13537 (clobber (reg:CC FLAGS_REG))]
13539 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13541 (define_insn "*rotrsi3_1_one_bit"
13542 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13543 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13544 (match_operand:QI 2 "const1_operand" "")))
13545 (clobber (reg:CC FLAGS_REG))]
13546 "(TARGET_SHIFT1 || optimize_size)
13547 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13549 [(set_attr "type" "rotate")
13550 (set (attr "length")
13551 (if_then_else (match_operand:SI 0 "register_operand" "")
13553 (const_string "*")))])
13555 (define_insn "*rotrsi3_1_one_bit_zext"
13556 [(set (match_operand:DI 0 "register_operand" "=r")
13558 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13559 (match_operand:QI 2 "const1_operand" ""))))
13560 (clobber (reg:CC FLAGS_REG))]
13562 && (TARGET_SHIFT1 || optimize_size)
13563 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13565 [(set_attr "type" "rotate")
13566 (set (attr "length")
13567 (if_then_else (match_operand:SI 0 "register_operand" "")
13569 (const_string "*")))])
13571 (define_insn "*rotrsi3_1"
13572 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13573 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13574 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13575 (clobber (reg:CC FLAGS_REG))]
13576 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13578 ror{l}\t{%2, %0|%0, %2}
13579 ror{l}\t{%b2, %0|%0, %b2}"
13580 [(set_attr "type" "rotate")
13581 (set_attr "mode" "SI")])
13583 (define_insn "*rotrsi3_1_zext"
13584 [(set (match_operand:DI 0 "register_operand" "=r,r")
13586 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13587 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13588 (clobber (reg:CC FLAGS_REG))]
13589 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13591 ror{l}\t{%2, %k0|%k0, %2}
13592 ror{l}\t{%b2, %k0|%k0, %b2}"
13593 [(set_attr "type" "rotate")
13594 (set_attr "mode" "SI")])
13596 (define_expand "rotrhi3"
13597 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13598 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13599 (match_operand:QI 2 "nonmemory_operand" "")))
13600 (clobber (reg:CC FLAGS_REG))]
13601 "TARGET_HIMODE_MATH"
13602 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13604 (define_insn "*rotrhi3_one_bit"
13605 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13606 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13607 (match_operand:QI 2 "const1_operand" "")))
13608 (clobber (reg:CC FLAGS_REG))]
13609 "(TARGET_SHIFT1 || optimize_size)
13610 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13612 [(set_attr "type" "rotate")
13613 (set (attr "length")
13614 (if_then_else (match_operand 0 "register_operand" "")
13616 (const_string "*")))])
13618 (define_insn "*rotrhi3_1"
13619 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13620 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13621 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13622 (clobber (reg:CC FLAGS_REG))]
13623 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13625 ror{w}\t{%2, %0|%0, %2}
13626 ror{w}\t{%b2, %0|%0, %b2}"
13627 [(set_attr "type" "rotate")
13628 (set_attr "mode" "HI")])
13631 [(set (match_operand:HI 0 "register_operand" "")
13632 (rotatert:HI (match_dup 0) (const_int 8)))
13633 (clobber (reg:CC FLAGS_REG))]
13635 [(parallel [(set (strict_low_part (match_dup 0))
13636 (bswap:HI (match_dup 0)))
13637 (clobber (reg:CC FLAGS_REG))])]
13640 (define_expand "rotrqi3"
13641 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13642 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13643 (match_operand:QI 2 "nonmemory_operand" "")))
13644 (clobber (reg:CC FLAGS_REG))]
13645 "TARGET_QIMODE_MATH"
13646 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13648 (define_insn "*rotrqi3_1_one_bit"
13649 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13650 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13651 (match_operand:QI 2 "const1_operand" "")))
13652 (clobber (reg:CC FLAGS_REG))]
13653 "(TARGET_SHIFT1 || optimize_size)
13654 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13656 [(set_attr "type" "rotate")
13657 (set (attr "length")
13658 (if_then_else (match_operand 0 "register_operand" "")
13660 (const_string "*")))])
13662 (define_insn "*rotrqi3_1_one_bit_slp"
13663 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13664 (rotatert:QI (match_dup 0)
13665 (match_operand:QI 1 "const1_operand" "")))
13666 (clobber (reg:CC FLAGS_REG))]
13667 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13668 && (TARGET_SHIFT1 || optimize_size)"
13670 [(set_attr "type" "rotate1")
13671 (set (attr "length")
13672 (if_then_else (match_operand 0 "register_operand" "")
13674 (const_string "*")))])
13676 (define_insn "*rotrqi3_1"
13677 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13678 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13679 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13680 (clobber (reg:CC FLAGS_REG))]
13681 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13683 ror{b}\t{%2, %0|%0, %2}
13684 ror{b}\t{%b2, %0|%0, %b2}"
13685 [(set_attr "type" "rotate")
13686 (set_attr "mode" "QI")])
13688 (define_insn "*rotrqi3_1_slp"
13689 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13690 (rotatert:QI (match_dup 0)
13691 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13692 (clobber (reg:CC FLAGS_REG))]
13693 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13694 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13696 ror{b}\t{%1, %0|%0, %1}
13697 ror{b}\t{%b1, %0|%0, %b1}"
13698 [(set_attr "type" "rotate1")
13699 (set_attr "mode" "QI")])
13701 ;; Bit set / bit test instructions
13703 (define_expand "extv"
13704 [(set (match_operand:SI 0 "register_operand" "")
13705 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13706 (match_operand:SI 2 "const8_operand" "")
13707 (match_operand:SI 3 "const8_operand" "")))]
13710 /* Handle extractions from %ah et al. */
13711 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13714 /* From mips.md: extract_bit_field doesn't verify that our source
13715 matches the predicate, so check it again here. */
13716 if (! ext_register_operand (operands[1], VOIDmode))
13720 (define_expand "extzv"
13721 [(set (match_operand:SI 0 "register_operand" "")
13722 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13723 (match_operand:SI 2 "const8_operand" "")
13724 (match_operand:SI 3 "const8_operand" "")))]
13727 /* Handle extractions from %ah et al. */
13728 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13731 /* From mips.md: extract_bit_field doesn't verify that our source
13732 matches the predicate, so check it again here. */
13733 if (! ext_register_operand (operands[1], VOIDmode))
13737 (define_expand "insv"
13738 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13739 (match_operand 1 "const8_operand" "")
13740 (match_operand 2 "const8_operand" ""))
13741 (match_operand 3 "register_operand" ""))]
13744 /* Handle insertions to %ah et al. */
13745 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13748 /* From mips.md: insert_bit_field doesn't verify that our source
13749 matches the predicate, so check it again here. */
13750 if (! ext_register_operand (operands[0], VOIDmode))
13754 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13756 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13761 ;; %%% bts, btr, btc, bt.
13762 ;; In general these instructions are *slow* when applied to memory,
13763 ;; since they enforce atomic operation. When applied to registers,
13764 ;; it depends on the cpu implementation. They're never faster than
13765 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13766 ;; no point. But in 64-bit, we can't hold the relevant immediates
13767 ;; within the instruction itself, so operating on bits in the high
13768 ;; 32-bits of a register becomes easier.
13770 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13771 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13772 ;; negdf respectively, so they can never be disabled entirely.
13774 (define_insn "*btsq"
13775 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13777 (match_operand:DI 1 "const_0_to_63_operand" ""))
13779 (clobber (reg:CC FLAGS_REG))]
13780 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13782 [(set_attr "type" "alu1")])
13784 (define_insn "*btrq"
13785 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13787 (match_operand:DI 1 "const_0_to_63_operand" ""))
13789 (clobber (reg:CC FLAGS_REG))]
13790 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13792 [(set_attr "type" "alu1")])
13794 (define_insn "*btcq"
13795 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13797 (match_operand:DI 1 "const_0_to_63_operand" ""))
13798 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13799 (clobber (reg:CC FLAGS_REG))]
13800 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13802 [(set_attr "type" "alu1")])
13804 ;; Allow Nocona to avoid these instructions if a register is available.
13807 [(match_scratch:DI 2 "r")
13808 (parallel [(set (zero_extract:DI
13809 (match_operand:DI 0 "register_operand" "")
13811 (match_operand:DI 1 "const_0_to_63_operand" ""))
13813 (clobber (reg:CC FLAGS_REG))])]
13814 "TARGET_64BIT && !TARGET_USE_BT"
13817 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13820 if (HOST_BITS_PER_WIDE_INT >= 64)
13821 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13822 else if (i < HOST_BITS_PER_WIDE_INT)
13823 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13825 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13827 op1 = immed_double_const (lo, hi, DImode);
13830 emit_move_insn (operands[2], op1);
13834 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13839 [(match_scratch:DI 2 "r")
13840 (parallel [(set (zero_extract:DI
13841 (match_operand:DI 0 "register_operand" "")
13843 (match_operand:DI 1 "const_0_to_63_operand" ""))
13845 (clobber (reg:CC FLAGS_REG))])]
13846 "TARGET_64BIT && !TARGET_USE_BT"
13849 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13852 if (HOST_BITS_PER_WIDE_INT >= 64)
13853 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13854 else if (i < HOST_BITS_PER_WIDE_INT)
13855 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13857 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13859 op1 = immed_double_const (~lo, ~hi, DImode);
13862 emit_move_insn (operands[2], op1);
13866 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13871 [(match_scratch:DI 2 "r")
13872 (parallel [(set (zero_extract:DI
13873 (match_operand:DI 0 "register_operand" "")
13875 (match_operand:DI 1 "const_0_to_63_operand" ""))
13876 (not:DI (zero_extract:DI
13877 (match_dup 0) (const_int 1) (match_dup 1))))
13878 (clobber (reg:CC FLAGS_REG))])]
13879 "TARGET_64BIT && !TARGET_USE_BT"
13882 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13885 if (HOST_BITS_PER_WIDE_INT >= 64)
13886 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13887 else if (i < HOST_BITS_PER_WIDE_INT)
13888 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13890 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13892 op1 = immed_double_const (lo, hi, DImode);
13895 emit_move_insn (operands[2], op1);
13899 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13903 ;; Store-flag instructions.
13905 ;; For all sCOND expanders, also expand the compare or test insn that
13906 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13908 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13909 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13910 ;; way, which can later delete the movzx if only QImode is needed.
13912 (define_expand "s<code>"
13913 [(set (match_operand:QI 0 "register_operand" "")
13914 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13916 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13918 (define_expand "s<code>"
13919 [(set (match_operand:QI 0 "register_operand" "")
13920 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13921 "TARGET_80387 || TARGET_SSE"
13922 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13924 (define_insn "*setcc_1"
13925 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13926 (match_operator:QI 1 "ix86_comparison_operator"
13927 [(reg FLAGS_REG) (const_int 0)]))]
13930 [(set_attr "type" "setcc")
13931 (set_attr "mode" "QI")])
13933 (define_insn "*setcc_2"
13934 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13935 (match_operator:QI 1 "ix86_comparison_operator"
13936 [(reg FLAGS_REG) (const_int 0)]))]
13939 [(set_attr "type" "setcc")
13940 (set_attr "mode" "QI")])
13942 ;; In general it is not safe to assume too much about CCmode registers,
13943 ;; so simplify-rtx stops when it sees a second one. Under certain
13944 ;; conditions this is safe on x86, so help combine not create
13951 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13952 (ne:QI (match_operator 1 "ix86_comparison_operator"
13953 [(reg FLAGS_REG) (const_int 0)])
13956 [(set (match_dup 0) (match_dup 1))]
13958 PUT_MODE (operands[1], QImode);
13962 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13963 (ne:QI (match_operator 1 "ix86_comparison_operator"
13964 [(reg FLAGS_REG) (const_int 0)])
13967 [(set (match_dup 0) (match_dup 1))]
13969 PUT_MODE (operands[1], QImode);
13973 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13974 (eq:QI (match_operator 1 "ix86_comparison_operator"
13975 [(reg FLAGS_REG) (const_int 0)])
13978 [(set (match_dup 0) (match_dup 1))]
13980 rtx new_op1 = copy_rtx (operands[1]);
13981 operands[1] = new_op1;
13982 PUT_MODE (new_op1, QImode);
13983 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13984 GET_MODE (XEXP (new_op1, 0))));
13986 /* Make sure that (a) the CCmode we have for the flags is strong
13987 enough for the reversed compare or (b) we have a valid FP compare. */
13988 if (! ix86_comparison_operator (new_op1, VOIDmode))
13993 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13994 (eq:QI (match_operator 1 "ix86_comparison_operator"
13995 [(reg FLAGS_REG) (const_int 0)])
13998 [(set (match_dup 0) (match_dup 1))]
14000 rtx new_op1 = copy_rtx (operands[1]);
14001 operands[1] = new_op1;
14002 PUT_MODE (new_op1, QImode);
14003 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14004 GET_MODE (XEXP (new_op1, 0))));
14006 /* Make sure that (a) the CCmode we have for the flags is strong
14007 enough for the reversed compare or (b) we have a valid FP compare. */
14008 if (! ix86_comparison_operator (new_op1, VOIDmode))
14012 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14013 ;; subsequent logical operations are used to imitate conditional moves.
14014 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14017 (define_insn "*sse_setcc<mode>"
14018 [(set (match_operand:MODEF 0 "register_operand" "=x")
14019 (match_operator:MODEF 1 "sse_comparison_operator"
14020 [(match_operand:MODEF 2 "register_operand" "0")
14021 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14022 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14023 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14024 [(set_attr "type" "ssecmp")
14025 (set_attr "mode" "<MODE>")])
14027 (define_insn "*sse5_setcc<mode>"
14028 [(set (match_operand:MODEF 0 "register_operand" "=x")
14029 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14030 [(match_operand:MODEF 2 "register_operand" "x")
14031 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14033 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14034 [(set_attr "type" "sse4arg")
14035 (set_attr "mode" "<MODE>")])
14038 ;; Basic conditional jump instructions.
14039 ;; We ignore the overflow flag for signed branch instructions.
14041 ;; For all bCOND expanders, also expand the compare or test insn that
14042 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14044 (define_expand "b<code>"
14046 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14048 (label_ref (match_operand 0 ""))
14051 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14053 (define_expand "b<code>"
14055 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14057 (label_ref (match_operand 0 ""))
14059 "TARGET_80387 || TARGET_SSE_MATH"
14060 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14062 (define_insn "*jcc_1"
14064 (if_then_else (match_operator 1 "ix86_comparison_operator"
14065 [(reg FLAGS_REG) (const_int 0)])
14066 (label_ref (match_operand 0 "" ""))
14070 [(set_attr "type" "ibr")
14071 (set_attr "modrm" "0")
14072 (set (attr "length")
14073 (if_then_else (and (ge (minus (match_dup 0) (pc))
14075 (lt (minus (match_dup 0) (pc))
14080 (define_insn "*jcc_2"
14082 (if_then_else (match_operator 1 "ix86_comparison_operator"
14083 [(reg FLAGS_REG) (const_int 0)])
14085 (label_ref (match_operand 0 "" ""))))]
14088 [(set_attr "type" "ibr")
14089 (set_attr "modrm" "0")
14090 (set (attr "length")
14091 (if_then_else (and (ge (minus (match_dup 0) (pc))
14093 (lt (minus (match_dup 0) (pc))
14098 ;; In general it is not safe to assume too much about CCmode registers,
14099 ;; so simplify-rtx stops when it sees a second one. Under certain
14100 ;; conditions this is safe on x86, so help combine not create
14108 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14109 [(reg FLAGS_REG) (const_int 0)])
14111 (label_ref (match_operand 1 "" ""))
14115 (if_then_else (match_dup 0)
14116 (label_ref (match_dup 1))
14119 PUT_MODE (operands[0], VOIDmode);
14124 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14125 [(reg FLAGS_REG) (const_int 0)])
14127 (label_ref (match_operand 1 "" ""))
14131 (if_then_else (match_dup 0)
14132 (label_ref (match_dup 1))
14135 rtx new_op0 = copy_rtx (operands[0]);
14136 operands[0] = new_op0;
14137 PUT_MODE (new_op0, VOIDmode);
14138 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14139 GET_MODE (XEXP (new_op0, 0))));
14141 /* Make sure that (a) the CCmode we have for the flags is strong
14142 enough for the reversed compare or (b) we have a valid FP compare. */
14143 if (! ix86_comparison_operator (new_op0, VOIDmode))
14147 ;; Define combination compare-and-branch fp compare instructions to use
14148 ;; during early optimization. Splitting the operation apart early makes
14149 ;; for bad code when we want to reverse the operation.
14151 (define_insn "*fp_jcc_1_mixed"
14153 (if_then_else (match_operator 0 "comparison_operator"
14154 [(match_operand 1 "register_operand" "f,x")
14155 (match_operand 2 "nonimmediate_operand" "f,xm")])
14156 (label_ref (match_operand 3 "" ""))
14158 (clobber (reg:CCFP FPSR_REG))
14159 (clobber (reg:CCFP FLAGS_REG))]
14160 "TARGET_MIX_SSE_I387
14161 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14162 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14163 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14166 (define_insn "*fp_jcc_1_sse"
14168 (if_then_else (match_operator 0 "comparison_operator"
14169 [(match_operand 1 "register_operand" "x")
14170 (match_operand 2 "nonimmediate_operand" "xm")])
14171 (label_ref (match_operand 3 "" ""))
14173 (clobber (reg:CCFP FPSR_REG))
14174 (clobber (reg:CCFP FLAGS_REG))]
14176 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14177 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14178 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14181 (define_insn "*fp_jcc_1_387"
14183 (if_then_else (match_operator 0 "comparison_operator"
14184 [(match_operand 1 "register_operand" "f")
14185 (match_operand 2 "register_operand" "f")])
14186 (label_ref (match_operand 3 "" ""))
14188 (clobber (reg:CCFP FPSR_REG))
14189 (clobber (reg:CCFP FLAGS_REG))]
14190 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14192 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14193 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14196 (define_insn "*fp_jcc_2_mixed"
14198 (if_then_else (match_operator 0 "comparison_operator"
14199 [(match_operand 1 "register_operand" "f,x")
14200 (match_operand 2 "nonimmediate_operand" "f,xm")])
14202 (label_ref (match_operand 3 "" ""))))
14203 (clobber (reg:CCFP FPSR_REG))
14204 (clobber (reg:CCFP FLAGS_REG))]
14205 "TARGET_MIX_SSE_I387
14206 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14207 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14208 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14211 (define_insn "*fp_jcc_2_sse"
14213 (if_then_else (match_operator 0 "comparison_operator"
14214 [(match_operand 1 "register_operand" "x")
14215 (match_operand 2 "nonimmediate_operand" "xm")])
14217 (label_ref (match_operand 3 "" ""))))
14218 (clobber (reg:CCFP FPSR_REG))
14219 (clobber (reg:CCFP FLAGS_REG))]
14221 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14222 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14223 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14226 (define_insn "*fp_jcc_2_387"
14228 (if_then_else (match_operator 0 "comparison_operator"
14229 [(match_operand 1 "register_operand" "f")
14230 (match_operand 2 "register_operand" "f")])
14232 (label_ref (match_operand 3 "" ""))))
14233 (clobber (reg:CCFP FPSR_REG))
14234 (clobber (reg:CCFP FLAGS_REG))]
14235 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14237 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14238 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14241 (define_insn "*fp_jcc_3_387"
14243 (if_then_else (match_operator 0 "comparison_operator"
14244 [(match_operand 1 "register_operand" "f")
14245 (match_operand 2 "nonimmediate_operand" "fm")])
14246 (label_ref (match_operand 3 "" ""))
14248 (clobber (reg:CCFP FPSR_REG))
14249 (clobber (reg:CCFP FLAGS_REG))
14250 (clobber (match_scratch:HI 4 "=a"))]
14252 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14253 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14254 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14255 && SELECT_CC_MODE (GET_CODE (operands[0]),
14256 operands[1], operands[2]) == CCFPmode
14257 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14260 (define_insn "*fp_jcc_4_387"
14262 (if_then_else (match_operator 0 "comparison_operator"
14263 [(match_operand 1 "register_operand" "f")
14264 (match_operand 2 "nonimmediate_operand" "fm")])
14266 (label_ref (match_operand 3 "" ""))))
14267 (clobber (reg:CCFP FPSR_REG))
14268 (clobber (reg:CCFP FLAGS_REG))
14269 (clobber (match_scratch:HI 4 "=a"))]
14271 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14272 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14273 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14274 && SELECT_CC_MODE (GET_CODE (operands[0]),
14275 operands[1], operands[2]) == CCFPmode
14276 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14279 (define_insn "*fp_jcc_5_387"
14281 (if_then_else (match_operator 0 "comparison_operator"
14282 [(match_operand 1 "register_operand" "f")
14283 (match_operand 2 "register_operand" "f")])
14284 (label_ref (match_operand 3 "" ""))
14286 (clobber (reg:CCFP FPSR_REG))
14287 (clobber (reg:CCFP FLAGS_REG))
14288 (clobber (match_scratch:HI 4 "=a"))]
14289 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14290 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14291 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14294 (define_insn "*fp_jcc_6_387"
14296 (if_then_else (match_operator 0 "comparison_operator"
14297 [(match_operand 1 "register_operand" "f")
14298 (match_operand 2 "register_operand" "f")])
14300 (label_ref (match_operand 3 "" ""))))
14301 (clobber (reg:CCFP FPSR_REG))
14302 (clobber (reg:CCFP FLAGS_REG))
14303 (clobber (match_scratch:HI 4 "=a"))]
14304 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14305 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14306 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14309 (define_insn "*fp_jcc_7_387"
14311 (if_then_else (match_operator 0 "comparison_operator"
14312 [(match_operand 1 "register_operand" "f")
14313 (match_operand 2 "const0_operand" "X")])
14314 (label_ref (match_operand 3 "" ""))
14316 (clobber (reg:CCFP FPSR_REG))
14317 (clobber (reg:CCFP FLAGS_REG))
14318 (clobber (match_scratch:HI 4 "=a"))]
14319 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14320 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14321 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14322 && SELECT_CC_MODE (GET_CODE (operands[0]),
14323 operands[1], operands[2]) == CCFPmode
14324 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14327 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14328 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14329 ;; with a precedence over other operators and is always put in the first
14330 ;; place. Swap condition and operands to match ficom instruction.
14332 (define_insn "*fp_jcc_8<mode>_387"
14334 (if_then_else (match_operator 0 "comparison_operator"
14335 [(match_operator 1 "float_operator"
14336 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14337 (match_operand 3 "register_operand" "f,f")])
14338 (label_ref (match_operand 4 "" ""))
14340 (clobber (reg:CCFP FPSR_REG))
14341 (clobber (reg:CCFP FLAGS_REG))
14342 (clobber (match_scratch:HI 5 "=a,a"))]
14343 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14344 && TARGET_USE_<MODE>MODE_FIOP
14345 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14346 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14347 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14348 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14353 (if_then_else (match_operator 0 "comparison_operator"
14354 [(match_operand 1 "register_operand" "")
14355 (match_operand 2 "nonimmediate_operand" "")])
14356 (match_operand 3 "" "")
14357 (match_operand 4 "" "")))
14358 (clobber (reg:CCFP FPSR_REG))
14359 (clobber (reg:CCFP FLAGS_REG))]
14363 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14364 operands[3], operands[4], NULL_RTX, NULL_RTX);
14370 (if_then_else (match_operator 0 "comparison_operator"
14371 [(match_operand 1 "register_operand" "")
14372 (match_operand 2 "general_operand" "")])
14373 (match_operand 3 "" "")
14374 (match_operand 4 "" "")))
14375 (clobber (reg:CCFP FPSR_REG))
14376 (clobber (reg:CCFP FLAGS_REG))
14377 (clobber (match_scratch:HI 5 "=a"))]
14381 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14382 operands[3], operands[4], operands[5], NULL_RTX);
14388 (if_then_else (match_operator 0 "comparison_operator"
14389 [(match_operator 1 "float_operator"
14390 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14391 (match_operand 3 "register_operand" "")])
14392 (match_operand 4 "" "")
14393 (match_operand 5 "" "")))
14394 (clobber (reg:CCFP FPSR_REG))
14395 (clobber (reg:CCFP FLAGS_REG))
14396 (clobber (match_scratch:HI 6 "=a"))]
14400 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14401 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14402 operands[3], operands[7],
14403 operands[4], operands[5], operands[6], NULL_RTX);
14407 ;; %%% Kill this when reload knows how to do it.
14410 (if_then_else (match_operator 0 "comparison_operator"
14411 [(match_operator 1 "float_operator"
14412 [(match_operand:X87MODEI12 2 "register_operand" "")])
14413 (match_operand 3 "register_operand" "")])
14414 (match_operand 4 "" "")
14415 (match_operand 5 "" "")))
14416 (clobber (reg:CCFP FPSR_REG))
14417 (clobber (reg:CCFP FLAGS_REG))
14418 (clobber (match_scratch:HI 6 "=a"))]
14422 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14423 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14424 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14425 operands[3], operands[7],
14426 operands[4], operands[5], operands[6], operands[2]);
14430 ;; Unconditional and other jump instructions
14432 (define_insn "jump"
14434 (label_ref (match_operand 0 "" "")))]
14437 [(set_attr "type" "ibr")
14438 (set (attr "length")
14439 (if_then_else (and (ge (minus (match_dup 0) (pc))
14441 (lt (minus (match_dup 0) (pc))
14445 (set_attr "modrm" "0")])
14447 (define_expand "indirect_jump"
14448 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14452 (define_insn "*indirect_jump"
14453 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14456 [(set_attr "type" "ibr")
14457 (set_attr "length_immediate" "0")])
14459 (define_insn "*indirect_jump_rtx64"
14460 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14463 [(set_attr "type" "ibr")
14464 (set_attr "length_immediate" "0")])
14466 (define_expand "tablejump"
14467 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14468 (use (label_ref (match_operand 1 "" "")))])]
14471 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14472 relative. Convert the relative address to an absolute address. */
14476 enum rtx_code code;
14478 /* We can't use @GOTOFF for text labels on VxWorks;
14479 see gotoff_operand. */
14480 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14484 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14486 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14490 op1 = pic_offset_table_rtx;
14495 op0 = pic_offset_table_rtx;
14499 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14504 (define_insn "*tablejump_1"
14505 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14506 (use (label_ref (match_operand 1 "" "")))]
14509 [(set_attr "type" "ibr")
14510 (set_attr "length_immediate" "0")])
14512 (define_insn "*tablejump_1_rtx64"
14513 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14514 (use (label_ref (match_operand 1 "" "")))]
14517 [(set_attr "type" "ibr")
14518 (set_attr "length_immediate" "0")])
14520 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14523 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14524 (set (match_operand:QI 1 "register_operand" "")
14525 (match_operator:QI 2 "ix86_comparison_operator"
14526 [(reg FLAGS_REG) (const_int 0)]))
14527 (set (match_operand 3 "q_regs_operand" "")
14528 (zero_extend (match_dup 1)))]
14529 "(peep2_reg_dead_p (3, operands[1])
14530 || operands_match_p (operands[1], operands[3]))
14531 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14532 [(set (match_dup 4) (match_dup 0))
14533 (set (strict_low_part (match_dup 5))
14536 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14537 operands[5] = gen_lowpart (QImode, operands[3]);
14538 ix86_expand_clear (operands[3]);
14541 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14544 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14545 (set (match_operand:QI 1 "register_operand" "")
14546 (match_operator:QI 2 "ix86_comparison_operator"
14547 [(reg FLAGS_REG) (const_int 0)]))
14548 (parallel [(set (match_operand 3 "q_regs_operand" "")
14549 (zero_extend (match_dup 1)))
14550 (clobber (reg:CC FLAGS_REG))])]
14551 "(peep2_reg_dead_p (3, operands[1])
14552 || operands_match_p (operands[1], operands[3]))
14553 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14554 [(set (match_dup 4) (match_dup 0))
14555 (set (strict_low_part (match_dup 5))
14558 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14559 operands[5] = gen_lowpart (QImode, operands[3]);
14560 ix86_expand_clear (operands[3]);
14563 ;; Call instructions.
14565 ;; The predicates normally associated with named expanders are not properly
14566 ;; checked for calls. This is a bug in the generic code, but it isn't that
14567 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14569 ;; Call subroutine returning no value.
14571 (define_expand "call_pop"
14572 [(parallel [(call (match_operand:QI 0 "" "")
14573 (match_operand:SI 1 "" ""))
14574 (set (reg:SI SP_REG)
14575 (plus:SI (reg:SI SP_REG)
14576 (match_operand:SI 3 "" "")))])]
14579 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14583 (define_insn "*call_pop_0"
14584 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14585 (match_operand:SI 1 "" ""))
14586 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14587 (match_operand:SI 2 "immediate_operand" "")))]
14590 if (SIBLING_CALL_P (insn))
14593 return "call\t%P0";
14595 [(set_attr "type" "call")])
14597 (define_insn "*call_pop_1"
14598 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14599 (match_operand:SI 1 "" ""))
14600 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14601 (match_operand:SI 2 "immediate_operand" "i")))]
14604 if (constant_call_address_operand (operands[0], Pmode))
14606 if (SIBLING_CALL_P (insn))
14609 return "call\t%P0";
14611 if (SIBLING_CALL_P (insn))
14614 return "call\t%A0";
14616 [(set_attr "type" "call")])
14618 (define_expand "call"
14619 [(call (match_operand:QI 0 "" "")
14620 (match_operand 1 "" ""))
14621 (use (match_operand 2 "" ""))]
14624 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14628 (define_expand "sibcall"
14629 [(call (match_operand:QI 0 "" "")
14630 (match_operand 1 "" ""))
14631 (use (match_operand 2 "" ""))]
14634 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14638 (define_insn "*call_0"
14639 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14640 (match_operand 1 "" ""))]
14643 if (SIBLING_CALL_P (insn))
14646 return "call\t%P0";
14648 [(set_attr "type" "call")])
14650 (define_insn "*call_1"
14651 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14652 (match_operand 1 "" ""))]
14653 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14655 if (constant_call_address_operand (operands[0], Pmode))
14656 return "call\t%P0";
14657 return "call\t%A0";
14659 [(set_attr "type" "call")])
14661 (define_insn "*sibcall_1"
14662 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14663 (match_operand 1 "" ""))]
14664 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14666 if (constant_call_address_operand (operands[0], Pmode))
14670 [(set_attr "type" "call")])
14672 (define_insn "*call_1_rex64"
14673 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14674 (match_operand 1 "" ""))]
14675 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14676 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14678 if (constant_call_address_operand (operands[0], Pmode))
14679 return "call\t%P0";
14680 return "call\t%A0";
14682 [(set_attr "type" "call")])
14684 (define_insn "*call_1_rex64_large"
14685 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14686 (match_operand 1 "" ""))]
14687 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14689 [(set_attr "type" "call")])
14691 (define_insn "*sibcall_1_rex64"
14692 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14693 (match_operand 1 "" ""))]
14694 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14696 [(set_attr "type" "call")])
14698 (define_insn "*sibcall_1_rex64_v"
14699 [(call (mem:QI (reg:DI R11_REG))
14700 (match_operand 0 "" ""))]
14701 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14703 [(set_attr "type" "call")])
14706 ;; Call subroutine, returning value in operand 0
14708 (define_expand "call_value_pop"
14709 [(parallel [(set (match_operand 0 "" "")
14710 (call (match_operand:QI 1 "" "")
14711 (match_operand:SI 2 "" "")))
14712 (set (reg:SI SP_REG)
14713 (plus:SI (reg:SI SP_REG)
14714 (match_operand:SI 4 "" "")))])]
14717 ix86_expand_call (operands[0], operands[1], operands[2],
14718 operands[3], operands[4], 0);
14722 (define_expand "call_value"
14723 [(set (match_operand 0 "" "")
14724 (call (match_operand:QI 1 "" "")
14725 (match_operand:SI 2 "" "")))
14726 (use (match_operand:SI 3 "" ""))]
14727 ;; Operand 2 not used on the i386.
14730 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14734 (define_expand "sibcall_value"
14735 [(set (match_operand 0 "" "")
14736 (call (match_operand:QI 1 "" "")
14737 (match_operand:SI 2 "" "")))
14738 (use (match_operand:SI 3 "" ""))]
14739 ;; Operand 2 not used on the i386.
14742 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14746 ;; Call subroutine returning any type.
14748 (define_expand "untyped_call"
14749 [(parallel [(call (match_operand 0 "" "")
14751 (match_operand 1 "" "")
14752 (match_operand 2 "" "")])]
14757 /* In order to give reg-stack an easier job in validating two
14758 coprocessor registers as containing a possible return value,
14759 simply pretend the untyped call returns a complex long double
14762 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14763 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14764 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14767 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14769 rtx set = XVECEXP (operands[2], 0, i);
14770 emit_move_insn (SET_DEST (set), SET_SRC (set));
14773 /* The optimizer does not know that the call sets the function value
14774 registers we stored in the result block. We avoid problems by
14775 claiming that all hard registers are used and clobbered at this
14777 emit_insn (gen_blockage ());
14782 ;; Prologue and epilogue instructions
14784 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14785 ;; all of memory. This blocks insns from being moved across this point.
14787 (define_insn "blockage"
14788 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14791 [(set_attr "length" "0")])
14793 ;; As USE insns aren't meaningful after reload, this is used instead
14794 ;; to prevent deleting instructions setting registers for PIC code
14795 (define_insn "prologue_use"
14796 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14799 [(set_attr "length" "0")])
14801 ;; Insn emitted into the body of a function to return from a function.
14802 ;; This is only done if the function's epilogue is known to be simple.
14803 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14805 (define_expand "return"
14807 "ix86_can_use_return_insn_p ()"
14809 if (current_function_pops_args)
14811 rtx popc = GEN_INT (current_function_pops_args);
14812 emit_jump_insn (gen_return_pop_internal (popc));
14817 (define_insn "return_internal"
14821 [(set_attr "length" "1")
14822 (set_attr "length_immediate" "0")
14823 (set_attr "modrm" "0")])
14825 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14826 ;; instruction Athlon and K8 have.
14828 (define_insn "return_internal_long"
14830 (unspec [(const_int 0)] UNSPEC_REP)]
14833 [(set_attr "length" "1")
14834 (set_attr "length_immediate" "0")
14835 (set_attr "prefix_rep" "1")
14836 (set_attr "modrm" "0")])
14838 (define_insn "return_pop_internal"
14840 (use (match_operand:SI 0 "const_int_operand" ""))]
14843 [(set_attr "length" "3")
14844 (set_attr "length_immediate" "2")
14845 (set_attr "modrm" "0")])
14847 (define_insn "return_indirect_internal"
14849 (use (match_operand:SI 0 "register_operand" "r"))]
14852 [(set_attr "type" "ibr")
14853 (set_attr "length_immediate" "0")])
14859 [(set_attr "length" "1")
14860 (set_attr "length_immediate" "0")
14861 (set_attr "modrm" "0")])
14863 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14864 ;; branch prediction penalty for the third jump in a 16-byte
14867 (define_insn "align"
14868 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14871 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14872 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14874 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14875 The align insn is used to avoid 3 jump instructions in the row to improve
14876 branch prediction and the benefits hardly outweigh the cost of extra 8
14877 nops on the average inserted by full alignment pseudo operation. */
14881 [(set_attr "length" "16")])
14883 (define_expand "prologue"
14886 "ix86_expand_prologue (); DONE;")
14888 (define_insn "set_got"
14889 [(set (match_operand:SI 0 "register_operand" "=r")
14890 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14891 (clobber (reg:CC FLAGS_REG))]
14893 { return output_set_got (operands[0], NULL_RTX); }
14894 [(set_attr "type" "multi")
14895 (set_attr "length" "12")])
14897 (define_insn "set_got_labelled"
14898 [(set (match_operand:SI 0 "register_operand" "=r")
14899 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14901 (clobber (reg:CC FLAGS_REG))]
14903 { return output_set_got (operands[0], operands[1]); }
14904 [(set_attr "type" "multi")
14905 (set_attr "length" "12")])
14907 (define_insn "set_got_rex64"
14908 [(set (match_operand:DI 0 "register_operand" "=r")
14909 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14911 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14912 [(set_attr "type" "lea")
14913 (set_attr "length" "6")])
14915 (define_insn "set_rip_rex64"
14916 [(set (match_operand:DI 0 "register_operand" "=r")
14917 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14919 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14920 [(set_attr "type" "lea")
14921 (set_attr "length" "6")])
14923 (define_insn "set_got_offset_rex64"
14924 [(set (match_operand:DI 0 "register_operand" "=r")
14925 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14927 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14928 [(set_attr "type" "imov")
14929 (set_attr "length" "11")])
14931 (define_expand "epilogue"
14934 "ix86_expand_epilogue (1); DONE;")
14936 (define_expand "sibcall_epilogue"
14939 "ix86_expand_epilogue (0); DONE;")
14941 (define_expand "eh_return"
14942 [(use (match_operand 0 "register_operand" ""))]
14945 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14947 /* Tricky bit: we write the address of the handler to which we will
14948 be returning into someone else's stack frame, one word below the
14949 stack address we wish to restore. */
14950 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14951 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14952 tmp = gen_rtx_MEM (Pmode, tmp);
14953 emit_move_insn (tmp, ra);
14955 if (Pmode == SImode)
14956 emit_jump_insn (gen_eh_return_si (sa));
14958 emit_jump_insn (gen_eh_return_di (sa));
14963 (define_insn_and_split "eh_return_si"
14965 (unspec [(match_operand:SI 0 "register_operand" "c")]
14966 UNSPEC_EH_RETURN))]
14971 "ix86_expand_epilogue (2); DONE;")
14973 (define_insn_and_split "eh_return_di"
14975 (unspec [(match_operand:DI 0 "register_operand" "c")]
14976 UNSPEC_EH_RETURN))]
14981 "ix86_expand_epilogue (2); DONE;")
14983 (define_insn "leave"
14984 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14985 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14986 (clobber (mem:BLK (scratch)))]
14989 [(set_attr "type" "leave")])
14991 (define_insn "leave_rex64"
14992 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14993 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14994 (clobber (mem:BLK (scratch)))]
14997 [(set_attr "type" "leave")])
14999 (define_expand "ffssi2"
15001 [(set (match_operand:SI 0 "register_operand" "")
15002 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15003 (clobber (match_scratch:SI 2 ""))
15004 (clobber (reg:CC FLAGS_REG))])]
15009 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15014 (define_expand "ffs_cmove"
15015 [(set (match_dup 2) (const_int -1))
15016 (parallel [(set (reg:CCZ FLAGS_REG)
15017 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15019 (set (match_operand:SI 0 "nonimmediate_operand" "")
15020 (ctz:SI (match_dup 1)))])
15021 (set (match_dup 0) (if_then_else:SI
15022 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15025 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15026 (clobber (reg:CC FLAGS_REG))])]
15028 "operands[2] = gen_reg_rtx (SImode);")
15030 (define_insn_and_split "*ffs_no_cmove"
15031 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15032 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15033 (clobber (match_scratch:SI 2 "=&q"))
15034 (clobber (reg:CC FLAGS_REG))]
15037 "&& reload_completed"
15038 [(parallel [(set (reg:CCZ FLAGS_REG)
15039 (compare:CCZ (match_dup 1) (const_int 0)))
15040 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15041 (set (strict_low_part (match_dup 3))
15042 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15043 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15044 (clobber (reg:CC FLAGS_REG))])
15045 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15046 (clobber (reg:CC FLAGS_REG))])
15047 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15048 (clobber (reg:CC FLAGS_REG))])]
15050 operands[3] = gen_lowpart (QImode, operands[2]);
15051 ix86_expand_clear (operands[2]);
15054 (define_insn "*ffssi_1"
15055 [(set (reg:CCZ FLAGS_REG)
15056 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15058 (set (match_operand:SI 0 "register_operand" "=r")
15059 (ctz:SI (match_dup 1)))]
15061 "bsf{l}\t{%1, %0|%0, %1}"
15062 [(set_attr "prefix_0f" "1")])
15064 (define_expand "ffsdi2"
15065 [(set (match_dup 2) (const_int -1))
15066 (parallel [(set (reg:CCZ FLAGS_REG)
15067 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15069 (set (match_operand:DI 0 "nonimmediate_operand" "")
15070 (ctz:DI (match_dup 1)))])
15071 (set (match_dup 0) (if_then_else:DI
15072 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15075 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15076 (clobber (reg:CC FLAGS_REG))])]
15078 "operands[2] = gen_reg_rtx (DImode);")
15080 (define_insn "*ffsdi_1"
15081 [(set (reg:CCZ FLAGS_REG)
15082 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15084 (set (match_operand:DI 0 "register_operand" "=r")
15085 (ctz:DI (match_dup 1)))]
15087 "bsf{q}\t{%1, %0|%0, %1}"
15088 [(set_attr "prefix_0f" "1")])
15090 (define_insn "ctzsi2"
15091 [(set (match_operand:SI 0 "register_operand" "=r")
15092 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15093 (clobber (reg:CC FLAGS_REG))]
15095 "bsf{l}\t{%1, %0|%0, %1}"
15096 [(set_attr "prefix_0f" "1")])
15098 (define_insn "ctzdi2"
15099 [(set (match_operand:DI 0 "register_operand" "=r")
15100 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15101 (clobber (reg:CC FLAGS_REG))]
15103 "bsf{q}\t{%1, %0|%0, %1}"
15104 [(set_attr "prefix_0f" "1")])
15106 (define_expand "clzsi2"
15108 [(set (match_operand:SI 0 "register_operand" "")
15109 (minus:SI (const_int 31)
15110 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15111 (clobber (reg:CC FLAGS_REG))])
15113 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15114 (clobber (reg:CC FLAGS_REG))])]
15119 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15124 (define_insn "clzsi2_abm"
15125 [(set (match_operand:SI 0 "register_operand" "=r")
15126 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15127 (clobber (reg:CC FLAGS_REG))]
15129 "lzcnt{l}\t{%1, %0|%0, %1}"
15130 [(set_attr "prefix_rep" "1")
15131 (set_attr "type" "bitmanip")
15132 (set_attr "mode" "SI")])
15134 (define_insn "*bsr"
15135 [(set (match_operand:SI 0 "register_operand" "=r")
15136 (minus:SI (const_int 31)
15137 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15138 (clobber (reg:CC FLAGS_REG))]
15140 "bsr{l}\t{%1, %0|%0, %1}"
15141 [(set_attr "prefix_0f" "1")
15142 (set_attr "mode" "SI")])
15144 (define_insn "popcountsi2"
15145 [(set (match_operand:SI 0 "register_operand" "=r")
15146 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15147 (clobber (reg:CC FLAGS_REG))]
15149 "popcnt{l}\t{%1, %0|%0, %1}"
15150 [(set_attr "prefix_rep" "1")
15151 (set_attr "type" "bitmanip")
15152 (set_attr "mode" "SI")])
15154 (define_insn "*popcountsi2_cmp"
15155 [(set (reg FLAGS_REG)
15157 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15159 (set (match_operand:SI 0 "register_operand" "=r")
15160 (popcount:SI (match_dup 1)))]
15161 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15162 "popcnt{l}\t{%1, %0|%0, %1}"
15163 [(set_attr "prefix_rep" "1")
15164 (set_attr "type" "bitmanip")
15165 (set_attr "mode" "SI")])
15167 (define_insn "*popcountsi2_cmp_zext"
15168 [(set (reg FLAGS_REG)
15170 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15172 (set (match_operand:DI 0 "register_operand" "=r")
15173 (zero_extend:DI(popcount:SI (match_dup 1))))]
15174 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15175 "popcnt{l}\t{%1, %0|%0, %1}"
15176 [(set_attr "prefix_rep" "1")
15177 (set_attr "type" "bitmanip")
15178 (set_attr "mode" "SI")])
15180 (define_expand "bswapsi2"
15181 [(set (match_operand:SI 0 "register_operand" "")
15182 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15187 rtx x = operands[0];
15189 emit_move_insn (x, operands[1]);
15190 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15191 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15192 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15197 (define_insn "*bswapsi_1"
15198 [(set (match_operand:SI 0 "register_operand" "=r")
15199 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15202 [(set_attr "prefix_0f" "1")
15203 (set_attr "length" "2")])
15205 (define_insn "*bswaphi_lowpart_1"
15206 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15207 (bswap:HI (match_dup 0)))
15208 (clobber (reg:CC FLAGS_REG))]
15209 "TARGET_USE_XCHGB || optimize_size"
15211 xchg{b}\t{%h0, %b0|%b0, %h0}
15212 rol{w}\t{$8, %0|%0, 8}"
15213 [(set_attr "length" "2,4")
15214 (set_attr "mode" "QI,HI")])
15216 (define_insn "bswaphi_lowpart"
15217 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15218 (bswap:HI (match_dup 0)))
15219 (clobber (reg:CC FLAGS_REG))]
15221 "rol{w}\t{$8, %0|%0, 8}"
15222 [(set_attr "length" "4")
15223 (set_attr "mode" "HI")])
15225 (define_insn "bswapdi2"
15226 [(set (match_operand:DI 0 "register_operand" "=r")
15227 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15230 [(set_attr "prefix_0f" "1")
15231 (set_attr "length" "3")])
15233 (define_expand "clzdi2"
15235 [(set (match_operand:DI 0 "register_operand" "")
15236 (minus:DI (const_int 63)
15237 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15238 (clobber (reg:CC FLAGS_REG))])
15240 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15241 (clobber (reg:CC FLAGS_REG))])]
15246 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15251 (define_insn "clzdi2_abm"
15252 [(set (match_operand:DI 0 "register_operand" "=r")
15253 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15254 (clobber (reg:CC FLAGS_REG))]
15255 "TARGET_64BIT && TARGET_ABM"
15256 "lzcnt{q}\t{%1, %0|%0, %1}"
15257 [(set_attr "prefix_rep" "1")
15258 (set_attr "type" "bitmanip")
15259 (set_attr "mode" "DI")])
15261 (define_insn "*bsr_rex64"
15262 [(set (match_operand:DI 0 "register_operand" "=r")
15263 (minus:DI (const_int 63)
15264 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15265 (clobber (reg:CC FLAGS_REG))]
15267 "bsr{q}\t{%1, %0|%0, %1}"
15268 [(set_attr "prefix_0f" "1")
15269 (set_attr "mode" "DI")])
15271 (define_insn "popcountdi2"
15272 [(set (match_operand:DI 0 "register_operand" "=r")
15273 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15274 (clobber (reg:CC FLAGS_REG))]
15275 "TARGET_64BIT && TARGET_POPCNT"
15276 "popcnt{q}\t{%1, %0|%0, %1}"
15277 [(set_attr "prefix_rep" "1")
15278 (set_attr "type" "bitmanip")
15279 (set_attr "mode" "DI")])
15281 (define_insn "*popcountdi2_cmp"
15282 [(set (reg FLAGS_REG)
15284 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15286 (set (match_operand:DI 0 "register_operand" "=r")
15287 (popcount:DI (match_dup 1)))]
15288 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15289 "popcnt{q}\t{%1, %0|%0, %1}"
15290 [(set_attr "prefix_rep" "1")
15291 (set_attr "type" "bitmanip")
15292 (set_attr "mode" "DI")])
15294 (define_expand "clzhi2"
15296 [(set (match_operand:HI 0 "register_operand" "")
15297 (minus:HI (const_int 15)
15298 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15299 (clobber (reg:CC FLAGS_REG))])
15301 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15302 (clobber (reg:CC FLAGS_REG))])]
15307 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15312 (define_insn "clzhi2_abm"
15313 [(set (match_operand:HI 0 "register_operand" "=r")
15314 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15315 (clobber (reg:CC FLAGS_REG))]
15317 "lzcnt{w}\t{%1, %0|%0, %1}"
15318 [(set_attr "prefix_rep" "1")
15319 (set_attr "type" "bitmanip")
15320 (set_attr "mode" "HI")])
15322 (define_insn "*bsrhi"
15323 [(set (match_operand:HI 0 "register_operand" "=r")
15324 (minus:HI (const_int 15)
15325 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15326 (clobber (reg:CC FLAGS_REG))]
15328 "bsr{w}\t{%1, %0|%0, %1}"
15329 [(set_attr "prefix_0f" "1")
15330 (set_attr "mode" "HI")])
15332 (define_insn "popcounthi2"
15333 [(set (match_operand:HI 0 "register_operand" "=r")
15334 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15335 (clobber (reg:CC FLAGS_REG))]
15337 "popcnt{w}\t{%1, %0|%0, %1}"
15338 [(set_attr "prefix_rep" "1")
15339 (set_attr "type" "bitmanip")
15340 (set_attr "mode" "HI")])
15342 (define_insn "*popcounthi2_cmp"
15343 [(set (reg FLAGS_REG)
15345 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15347 (set (match_operand:HI 0 "register_operand" "=r")
15348 (popcount:HI (match_dup 1)))]
15349 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15350 "popcnt{w}\t{%1, %0|%0, %1}"
15351 [(set_attr "prefix_rep" "1")
15352 (set_attr "type" "bitmanip")
15353 (set_attr "mode" "HI")])
15355 (define_expand "paritydi2"
15356 [(set (match_operand:DI 0 "register_operand" "")
15357 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15360 rtx scratch = gen_reg_rtx (QImode);
15363 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15364 NULL_RTX, operands[1]));
15366 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15367 gen_rtx_REG (CCmode, FLAGS_REG),
15369 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15372 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15375 rtx tmp = gen_reg_rtx (SImode);
15377 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15378 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15383 (define_insn_and_split "paritydi2_cmp"
15384 [(set (reg:CC FLAGS_REG)
15385 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15386 (clobber (match_scratch:DI 0 "=r"))
15387 (clobber (match_scratch:SI 1 "=&r"))
15388 (clobber (match_scratch:HI 2 "=Q"))]
15391 "&& reload_completed"
15393 [(set (match_dup 1)
15394 (xor:SI (match_dup 1) (match_dup 4)))
15395 (clobber (reg:CC FLAGS_REG))])
15397 [(set (reg:CC FLAGS_REG)
15398 (parity:CC (match_dup 1)))
15399 (clobber (match_dup 1))
15400 (clobber (match_dup 2))])]
15402 operands[4] = gen_lowpart (SImode, operands[3]);
15406 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15407 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15410 operands[1] = gen_highpart (SImode, operands[3]);
15413 (define_expand "paritysi2"
15414 [(set (match_operand:SI 0 "register_operand" "")
15415 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15418 rtx scratch = gen_reg_rtx (QImode);
15421 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15423 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15424 gen_rtx_REG (CCmode, FLAGS_REG),
15426 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15428 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15432 (define_insn_and_split "paritysi2_cmp"
15433 [(set (reg:CC FLAGS_REG)
15434 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15435 (clobber (match_scratch:SI 0 "=r"))
15436 (clobber (match_scratch:HI 1 "=&Q"))]
15439 "&& reload_completed"
15441 [(set (match_dup 1)
15442 (xor:HI (match_dup 1) (match_dup 3)))
15443 (clobber (reg:CC FLAGS_REG))])
15445 [(set (reg:CC FLAGS_REG)
15446 (parity:CC (match_dup 1)))
15447 (clobber (match_dup 1))])]
15449 operands[3] = gen_lowpart (HImode, operands[2]);
15451 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15452 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15455 (define_insn "*parityhi2_cmp"
15456 [(set (reg:CC FLAGS_REG)
15457 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15458 (clobber (match_scratch:HI 0 "=Q"))]
15460 "xor{b}\t{%h0, %b0|%b0, %h0}"
15461 [(set_attr "length" "2")
15462 (set_attr "mode" "HI")])
15464 (define_insn "*parityqi2_cmp"
15465 [(set (reg:CC FLAGS_REG)
15466 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15469 [(set_attr "length" "2")
15470 (set_attr "mode" "QI")])
15472 ;; Thread-local storage patterns for ELF.
15474 ;; Note that these code sequences must appear exactly as shown
15475 ;; in order to allow linker relaxation.
15477 (define_insn "*tls_global_dynamic_32_gnu"
15478 [(set (match_operand:SI 0 "register_operand" "=a")
15479 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15480 (match_operand:SI 2 "tls_symbolic_operand" "")
15481 (match_operand:SI 3 "call_insn_operand" "")]
15483 (clobber (match_scratch:SI 4 "=d"))
15484 (clobber (match_scratch:SI 5 "=c"))
15485 (clobber (reg:CC FLAGS_REG))]
15486 "!TARGET_64BIT && TARGET_GNU_TLS"
15487 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15488 [(set_attr "type" "multi")
15489 (set_attr "length" "12")])
15491 (define_insn "*tls_global_dynamic_32_sun"
15492 [(set (match_operand:SI 0 "register_operand" "=a")
15493 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15494 (match_operand:SI 2 "tls_symbolic_operand" "")
15495 (match_operand:SI 3 "call_insn_operand" "")]
15497 (clobber (match_scratch:SI 4 "=d"))
15498 (clobber (match_scratch:SI 5 "=c"))
15499 (clobber (reg:CC FLAGS_REG))]
15500 "!TARGET_64BIT && TARGET_SUN_TLS"
15501 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15502 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15503 [(set_attr "type" "multi")
15504 (set_attr "length" "14")])
15506 (define_expand "tls_global_dynamic_32"
15507 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15510 (match_operand:SI 1 "tls_symbolic_operand" "")
15513 (clobber (match_scratch:SI 4 ""))
15514 (clobber (match_scratch:SI 5 ""))
15515 (clobber (reg:CC FLAGS_REG))])]
15519 operands[2] = pic_offset_table_rtx;
15522 operands[2] = gen_reg_rtx (Pmode);
15523 emit_insn (gen_set_got (operands[2]));
15525 if (TARGET_GNU2_TLS)
15527 emit_insn (gen_tls_dynamic_gnu2_32
15528 (operands[0], operands[1], operands[2]));
15531 operands[3] = ix86_tls_get_addr ();
15534 (define_insn "*tls_global_dynamic_64"
15535 [(set (match_operand:DI 0 "register_operand" "=a")
15536 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15537 (match_operand:DI 3 "" "")))
15538 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15541 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15542 [(set_attr "type" "multi")
15543 (set_attr "length" "16")])
15545 (define_expand "tls_global_dynamic_64"
15546 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15547 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15548 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15552 if (TARGET_GNU2_TLS)
15554 emit_insn (gen_tls_dynamic_gnu2_64
15555 (operands[0], operands[1]));
15558 operands[2] = ix86_tls_get_addr ();
15561 (define_insn "*tls_local_dynamic_base_32_gnu"
15562 [(set (match_operand:SI 0 "register_operand" "=a")
15563 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15564 (match_operand:SI 2 "call_insn_operand" "")]
15565 UNSPEC_TLS_LD_BASE))
15566 (clobber (match_scratch:SI 3 "=d"))
15567 (clobber (match_scratch:SI 4 "=c"))
15568 (clobber (reg:CC FLAGS_REG))]
15569 "!TARGET_64BIT && TARGET_GNU_TLS"
15570 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15571 [(set_attr "type" "multi")
15572 (set_attr "length" "11")])
15574 (define_insn "*tls_local_dynamic_base_32_sun"
15575 [(set (match_operand:SI 0 "register_operand" "=a")
15576 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15577 (match_operand:SI 2 "call_insn_operand" "")]
15578 UNSPEC_TLS_LD_BASE))
15579 (clobber (match_scratch:SI 3 "=d"))
15580 (clobber (match_scratch:SI 4 "=c"))
15581 (clobber (reg:CC FLAGS_REG))]
15582 "!TARGET_64BIT && TARGET_SUN_TLS"
15583 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15584 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15585 [(set_attr "type" "multi")
15586 (set_attr "length" "13")])
15588 (define_expand "tls_local_dynamic_base_32"
15589 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15590 (unspec:SI [(match_dup 1) (match_dup 2)]
15591 UNSPEC_TLS_LD_BASE))
15592 (clobber (match_scratch:SI 3 ""))
15593 (clobber (match_scratch:SI 4 ""))
15594 (clobber (reg:CC FLAGS_REG))])]
15598 operands[1] = pic_offset_table_rtx;
15601 operands[1] = gen_reg_rtx (Pmode);
15602 emit_insn (gen_set_got (operands[1]));
15604 if (TARGET_GNU2_TLS)
15606 emit_insn (gen_tls_dynamic_gnu2_32
15607 (operands[0], ix86_tls_module_base (), operands[1]));
15610 operands[2] = ix86_tls_get_addr ();
15613 (define_insn "*tls_local_dynamic_base_64"
15614 [(set (match_operand:DI 0 "register_operand" "=a")
15615 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15616 (match_operand:DI 2 "" "")))
15617 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15619 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15620 [(set_attr "type" "multi")
15621 (set_attr "length" "12")])
15623 (define_expand "tls_local_dynamic_base_64"
15624 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15625 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15626 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15629 if (TARGET_GNU2_TLS)
15631 emit_insn (gen_tls_dynamic_gnu2_64
15632 (operands[0], ix86_tls_module_base ()));
15635 operands[1] = ix86_tls_get_addr ();
15638 ;; Local dynamic of a single variable is a lose. Show combine how
15639 ;; to convert that back to global dynamic.
15641 (define_insn_and_split "*tls_local_dynamic_32_once"
15642 [(set (match_operand:SI 0 "register_operand" "=a")
15643 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15644 (match_operand:SI 2 "call_insn_operand" "")]
15645 UNSPEC_TLS_LD_BASE)
15646 (const:SI (unspec:SI
15647 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15649 (clobber (match_scratch:SI 4 "=d"))
15650 (clobber (match_scratch:SI 5 "=c"))
15651 (clobber (reg:CC FLAGS_REG))]
15655 [(parallel [(set (match_dup 0)
15656 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15658 (clobber (match_dup 4))
15659 (clobber (match_dup 5))
15660 (clobber (reg:CC FLAGS_REG))])]
15663 ;; Load and add the thread base pointer from %gs:0.
15665 (define_insn "*load_tp_si"
15666 [(set (match_operand:SI 0 "register_operand" "=r")
15667 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15669 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15670 [(set_attr "type" "imov")
15671 (set_attr "modrm" "0")
15672 (set_attr "length" "7")
15673 (set_attr "memory" "load")
15674 (set_attr "imm_disp" "false")])
15676 (define_insn "*add_tp_si"
15677 [(set (match_operand:SI 0 "register_operand" "=r")
15678 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15679 (match_operand:SI 1 "register_operand" "0")))
15680 (clobber (reg:CC FLAGS_REG))]
15682 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15683 [(set_attr "type" "alu")
15684 (set_attr "modrm" "0")
15685 (set_attr "length" "7")
15686 (set_attr "memory" "load")
15687 (set_attr "imm_disp" "false")])
15689 (define_insn "*load_tp_di"
15690 [(set (match_operand:DI 0 "register_operand" "=r")
15691 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15693 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15694 [(set_attr "type" "imov")
15695 (set_attr "modrm" "0")
15696 (set_attr "length" "7")
15697 (set_attr "memory" "load")
15698 (set_attr "imm_disp" "false")])
15700 (define_insn "*add_tp_di"
15701 [(set (match_operand:DI 0 "register_operand" "=r")
15702 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15703 (match_operand:DI 1 "register_operand" "0")))
15704 (clobber (reg:CC FLAGS_REG))]
15706 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15707 [(set_attr "type" "alu")
15708 (set_attr "modrm" "0")
15709 (set_attr "length" "7")
15710 (set_attr "memory" "load")
15711 (set_attr "imm_disp" "false")])
15713 ;; GNU2 TLS patterns can be split.
15715 (define_expand "tls_dynamic_gnu2_32"
15716 [(set (match_dup 3)
15717 (plus:SI (match_operand:SI 2 "register_operand" "")
15719 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15722 [(set (match_operand:SI 0 "register_operand" "")
15723 (unspec:SI [(match_dup 1) (match_dup 3)
15724 (match_dup 2) (reg:SI SP_REG)]
15726 (clobber (reg:CC FLAGS_REG))])]
15727 "!TARGET_64BIT && TARGET_GNU2_TLS"
15729 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15730 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15733 (define_insn "*tls_dynamic_lea_32"
15734 [(set (match_operand:SI 0 "register_operand" "=r")
15735 (plus:SI (match_operand:SI 1 "register_operand" "b")
15737 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15738 UNSPEC_TLSDESC))))]
15739 "!TARGET_64BIT && TARGET_GNU2_TLS"
15740 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15741 [(set_attr "type" "lea")
15742 (set_attr "mode" "SI")
15743 (set_attr "length" "6")
15744 (set_attr "length_address" "4")])
15746 (define_insn "*tls_dynamic_call_32"
15747 [(set (match_operand:SI 0 "register_operand" "=a")
15748 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15749 (match_operand:SI 2 "register_operand" "0")
15750 ;; we have to make sure %ebx still points to the GOT
15751 (match_operand:SI 3 "register_operand" "b")
15754 (clobber (reg:CC FLAGS_REG))]
15755 "!TARGET_64BIT && TARGET_GNU2_TLS"
15756 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15757 [(set_attr "type" "call")
15758 (set_attr "length" "2")
15759 (set_attr "length_address" "0")])
15761 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15762 [(set (match_operand:SI 0 "register_operand" "=&a")
15764 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15765 (match_operand:SI 4 "" "")
15766 (match_operand:SI 2 "register_operand" "b")
15769 (const:SI (unspec:SI
15770 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15772 (clobber (reg:CC FLAGS_REG))]
15773 "!TARGET_64BIT && TARGET_GNU2_TLS"
15776 [(set (match_dup 0) (match_dup 5))]
15778 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15779 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15782 (define_expand "tls_dynamic_gnu2_64"
15783 [(set (match_dup 2)
15784 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15787 [(set (match_operand:DI 0 "register_operand" "")
15788 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15790 (clobber (reg:CC FLAGS_REG))])]
15791 "TARGET_64BIT && TARGET_GNU2_TLS"
15793 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15794 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15797 (define_insn "*tls_dynamic_lea_64"
15798 [(set (match_operand:DI 0 "register_operand" "=r")
15799 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15801 "TARGET_64BIT && TARGET_GNU2_TLS"
15802 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15803 [(set_attr "type" "lea")
15804 (set_attr "mode" "DI")
15805 (set_attr "length" "7")
15806 (set_attr "length_address" "4")])
15808 (define_insn "*tls_dynamic_call_64"
15809 [(set (match_operand:DI 0 "register_operand" "=a")
15810 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15811 (match_operand:DI 2 "register_operand" "0")
15814 (clobber (reg:CC FLAGS_REG))]
15815 "TARGET_64BIT && TARGET_GNU2_TLS"
15816 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15817 [(set_attr "type" "call")
15818 (set_attr "length" "2")
15819 (set_attr "length_address" "0")])
15821 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15822 [(set (match_operand:DI 0 "register_operand" "=&a")
15824 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15825 (match_operand:DI 3 "" "")
15828 (const:DI (unspec:DI
15829 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15831 (clobber (reg:CC FLAGS_REG))]
15832 "TARGET_64BIT && TARGET_GNU2_TLS"
15835 [(set (match_dup 0) (match_dup 4))]
15837 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15838 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15843 ;; These patterns match the binary 387 instructions for addM3, subM3,
15844 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15845 ;; SFmode. The first is the normal insn, the second the same insn but
15846 ;; with one operand a conversion, and the third the same insn but with
15847 ;; the other operand a conversion. The conversion may be SFmode or
15848 ;; SImode if the target mode DFmode, but only SImode if the target mode
15851 ;; Gcc is slightly more smart about handling normal two address instructions
15852 ;; so use special patterns for add and mull.
15854 (define_insn "*fop_sf_comm_mixed"
15855 [(set (match_operand:SF 0 "register_operand" "=f,x")
15856 (match_operator:SF 3 "binary_fp_operator"
15857 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15858 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15859 "TARGET_MIX_SSE_I387
15860 && COMMUTATIVE_ARITH_P (operands[3])
15861 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15862 "* return output_387_binary_op (insn, operands);"
15863 [(set (attr "type")
15864 (if_then_else (eq_attr "alternative" "1")
15865 (if_then_else (match_operand:SF 3 "mult_operator" "")
15866 (const_string "ssemul")
15867 (const_string "sseadd"))
15868 (if_then_else (match_operand:SF 3 "mult_operator" "")
15869 (const_string "fmul")
15870 (const_string "fop"))))
15871 (set_attr "mode" "SF")])
15873 (define_insn "*fop_sf_comm_sse"
15874 [(set (match_operand:SF 0 "register_operand" "=x")
15875 (match_operator:SF 3 "binary_fp_operator"
15876 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15877 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15879 && COMMUTATIVE_ARITH_P (operands[3])
15880 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15881 "* return output_387_binary_op (insn, operands);"
15882 [(set (attr "type")
15883 (if_then_else (match_operand:SF 3 "mult_operator" "")
15884 (const_string "ssemul")
15885 (const_string "sseadd")))
15886 (set_attr "mode" "SF")])
15888 (define_insn "*fop_sf_comm_i387"
15889 [(set (match_operand:SF 0 "register_operand" "=f")
15890 (match_operator:SF 3 "binary_fp_operator"
15891 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15892 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15894 && COMMUTATIVE_ARITH_P (operands[3])
15895 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15896 "* return output_387_binary_op (insn, operands);"
15897 [(set (attr "type")
15898 (if_then_else (match_operand:SF 3 "mult_operator" "")
15899 (const_string "fmul")
15900 (const_string "fop")))
15901 (set_attr "mode" "SF")])
15903 (define_insn "*fop_sf_1_mixed"
15904 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15905 (match_operator:SF 3 "binary_fp_operator"
15906 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15907 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15908 "TARGET_MIX_SSE_I387
15909 && !COMMUTATIVE_ARITH_P (operands[3])
15910 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15911 "* return output_387_binary_op (insn, operands);"
15912 [(set (attr "type")
15913 (cond [(and (eq_attr "alternative" "2")
15914 (match_operand:SF 3 "mult_operator" ""))
15915 (const_string "ssemul")
15916 (and (eq_attr "alternative" "2")
15917 (match_operand:SF 3 "div_operator" ""))
15918 (const_string "ssediv")
15919 (eq_attr "alternative" "2")
15920 (const_string "sseadd")
15921 (match_operand:SF 3 "mult_operator" "")
15922 (const_string "fmul")
15923 (match_operand:SF 3 "div_operator" "")
15924 (const_string "fdiv")
15926 (const_string "fop")))
15927 (set_attr "mode" "SF")])
15929 (define_insn "*rcpsf2_sse"
15930 [(set (match_operand:SF 0 "register_operand" "=x")
15931 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15934 "rcpss\t{%1, %0|%0, %1}"
15935 [(set_attr "type" "sse")
15936 (set_attr "mode" "SF")])
15938 (define_insn "*fop_sf_1_sse"
15939 [(set (match_operand:SF 0 "register_operand" "=x")
15940 (match_operator:SF 3 "binary_fp_operator"
15941 [(match_operand:SF 1 "register_operand" "0")
15942 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15944 && !COMMUTATIVE_ARITH_P (operands[3])"
15945 "* return output_387_binary_op (insn, operands);"
15946 [(set (attr "type")
15947 (cond [(match_operand:SF 3 "mult_operator" "")
15948 (const_string "ssemul")
15949 (match_operand:SF 3 "div_operator" "")
15950 (const_string "ssediv")
15952 (const_string "sseadd")))
15953 (set_attr "mode" "SF")])
15955 ;; This pattern is not fully shadowed by the pattern above.
15956 (define_insn "*fop_sf_1_i387"
15957 [(set (match_operand:SF 0 "register_operand" "=f,f")
15958 (match_operator:SF 3 "binary_fp_operator"
15959 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15960 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15961 "TARGET_80387 && !TARGET_SSE_MATH
15962 && !COMMUTATIVE_ARITH_P (operands[3])
15963 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15964 "* return output_387_binary_op (insn, operands);"
15965 [(set (attr "type")
15966 (cond [(match_operand:SF 3 "mult_operator" "")
15967 (const_string "fmul")
15968 (match_operand:SF 3 "div_operator" "")
15969 (const_string "fdiv")
15971 (const_string "fop")))
15972 (set_attr "mode" "SF")])
15974 ;; ??? Add SSE splitters for these!
15975 (define_insn "*fop_sf_2<mode>_i387"
15976 [(set (match_operand:SF 0 "register_operand" "=f,f")
15977 (match_operator:SF 3 "binary_fp_operator"
15978 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15979 (match_operand:SF 2 "register_operand" "0,0")]))]
15980 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15981 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15982 [(set (attr "type")
15983 (cond [(match_operand:SF 3 "mult_operator" "")
15984 (const_string "fmul")
15985 (match_operand:SF 3 "div_operator" "")
15986 (const_string "fdiv")
15988 (const_string "fop")))
15989 (set_attr "fp_int_src" "true")
15990 (set_attr "mode" "<MODE>")])
15992 (define_insn "*fop_sf_3<mode>_i387"
15993 [(set (match_operand:SF 0 "register_operand" "=f,f")
15994 (match_operator:SF 3 "binary_fp_operator"
15995 [(match_operand:SF 1 "register_operand" "0,0")
15996 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15997 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15998 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15999 [(set (attr "type")
16000 (cond [(match_operand:SF 3 "mult_operator" "")
16001 (const_string "fmul")
16002 (match_operand:SF 3 "div_operator" "")
16003 (const_string "fdiv")
16005 (const_string "fop")))
16006 (set_attr "fp_int_src" "true")
16007 (set_attr "mode" "<MODE>")])
16009 (define_insn "*fop_df_comm_mixed"
16010 [(set (match_operand:DF 0 "register_operand" "=f,x")
16011 (match_operator:DF 3 "binary_fp_operator"
16012 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16013 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16014 "TARGET_SSE2 && TARGET_MIX_SSE_I387
16015 && COMMUTATIVE_ARITH_P (operands[3])
16016 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16017 "* return output_387_binary_op (insn, operands);"
16018 [(set (attr "type")
16019 (if_then_else (eq_attr "alternative" "1")
16020 (if_then_else (match_operand:DF 3 "mult_operator" "")
16021 (const_string "ssemul")
16022 (const_string "sseadd"))
16023 (if_then_else (match_operand:DF 3 "mult_operator" "")
16024 (const_string "fmul")
16025 (const_string "fop"))))
16026 (set_attr "mode" "DF")])
16028 (define_insn "*fop_df_comm_sse"
16029 [(set (match_operand:DF 0 "register_operand" "=x")
16030 (match_operator:DF 3 "binary_fp_operator"
16031 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16032 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16033 "TARGET_SSE2 && TARGET_SSE_MATH
16034 && COMMUTATIVE_ARITH_P (operands[3])
16035 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16036 "* return output_387_binary_op (insn, operands);"
16037 [(set (attr "type")
16038 (if_then_else (match_operand:DF 3 "mult_operator" "")
16039 (const_string "ssemul")
16040 (const_string "sseadd")))
16041 (set_attr "mode" "DF")])
16043 (define_insn "*fop_df_comm_i387"
16044 [(set (match_operand:DF 0 "register_operand" "=f")
16045 (match_operator:DF 3 "binary_fp_operator"
16046 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16047 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16049 && COMMUTATIVE_ARITH_P (operands[3])
16050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16051 "* return output_387_binary_op (insn, operands);"
16052 [(set (attr "type")
16053 (if_then_else (match_operand:DF 3 "mult_operator" "")
16054 (const_string "fmul")
16055 (const_string "fop")))
16056 (set_attr "mode" "DF")])
16058 (define_insn "*fop_df_1_mixed"
16059 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16060 (match_operator:DF 3 "binary_fp_operator"
16061 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16062 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16063 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16064 && !COMMUTATIVE_ARITH_P (operands[3])
16065 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16066 "* return output_387_binary_op (insn, operands);"
16067 [(set (attr "type")
16068 (cond [(and (eq_attr "alternative" "2")
16069 (match_operand:DF 3 "mult_operator" ""))
16070 (const_string "ssemul")
16071 (and (eq_attr "alternative" "2")
16072 (match_operand:DF 3 "div_operator" ""))
16073 (const_string "ssediv")
16074 (eq_attr "alternative" "2")
16075 (const_string "sseadd")
16076 (match_operand:DF 3 "mult_operator" "")
16077 (const_string "fmul")
16078 (match_operand:DF 3 "div_operator" "")
16079 (const_string "fdiv")
16081 (const_string "fop")))
16082 (set_attr "mode" "DF")])
16084 (define_insn "*fop_df_1_sse"
16085 [(set (match_operand:DF 0 "register_operand" "=x")
16086 (match_operator:DF 3 "binary_fp_operator"
16087 [(match_operand:DF 1 "register_operand" "0")
16088 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16089 "TARGET_SSE2 && TARGET_SSE_MATH
16090 && !COMMUTATIVE_ARITH_P (operands[3])"
16091 "* return output_387_binary_op (insn, operands);"
16092 [(set_attr "mode" "DF")
16094 (cond [(match_operand:DF 3 "mult_operator" "")
16095 (const_string "ssemul")
16096 (match_operand:DF 3 "div_operator" "")
16097 (const_string "ssediv")
16099 (const_string "sseadd")))])
16101 ;; This pattern is not fully shadowed by the pattern above.
16102 (define_insn "*fop_df_1_i387"
16103 [(set (match_operand:DF 0 "register_operand" "=f,f")
16104 (match_operator:DF 3 "binary_fp_operator"
16105 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16106 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16107 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16108 && !COMMUTATIVE_ARITH_P (operands[3])
16109 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16110 "* return output_387_binary_op (insn, operands);"
16111 [(set (attr "type")
16112 (cond [(match_operand:DF 3 "mult_operator" "")
16113 (const_string "fmul")
16114 (match_operand:DF 3 "div_operator" "")
16115 (const_string "fdiv")
16117 (const_string "fop")))
16118 (set_attr "mode" "DF")])
16120 ;; ??? Add SSE splitters for these!
16121 (define_insn "*fop_df_2<mode>_i387"
16122 [(set (match_operand:DF 0 "register_operand" "=f,f")
16123 (match_operator:DF 3 "binary_fp_operator"
16124 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16125 (match_operand:DF 2 "register_operand" "0,0")]))]
16126 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16127 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16128 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16129 [(set (attr "type")
16130 (cond [(match_operand:DF 3 "mult_operator" "")
16131 (const_string "fmul")
16132 (match_operand:DF 3 "div_operator" "")
16133 (const_string "fdiv")
16135 (const_string "fop")))
16136 (set_attr "fp_int_src" "true")
16137 (set_attr "mode" "<MODE>")])
16139 (define_insn "*fop_df_3<mode>_i387"
16140 [(set (match_operand:DF 0 "register_operand" "=f,f")
16141 (match_operator:DF 3 "binary_fp_operator"
16142 [(match_operand:DF 1 "register_operand" "0,0")
16143 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16144 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16145 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16146 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16147 [(set (attr "type")
16148 (cond [(match_operand:DF 3 "mult_operator" "")
16149 (const_string "fmul")
16150 (match_operand:DF 3 "div_operator" "")
16151 (const_string "fdiv")
16153 (const_string "fop")))
16154 (set_attr "fp_int_src" "true")
16155 (set_attr "mode" "<MODE>")])
16157 (define_insn "*fop_df_4_i387"
16158 [(set (match_operand:DF 0 "register_operand" "=f,f")
16159 (match_operator:DF 3 "binary_fp_operator"
16160 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16161 (match_operand:DF 2 "register_operand" "0,f")]))]
16162 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16163 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16164 "* return output_387_binary_op (insn, operands);"
16165 [(set (attr "type")
16166 (cond [(match_operand:DF 3 "mult_operator" "")
16167 (const_string "fmul")
16168 (match_operand:DF 3 "div_operator" "")
16169 (const_string "fdiv")
16171 (const_string "fop")))
16172 (set_attr "mode" "SF")])
16174 (define_insn "*fop_df_5_i387"
16175 [(set (match_operand:DF 0 "register_operand" "=f,f")
16176 (match_operator:DF 3 "binary_fp_operator"
16177 [(match_operand:DF 1 "register_operand" "0,f")
16179 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16180 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16181 "* return output_387_binary_op (insn, operands);"
16182 [(set (attr "type")
16183 (cond [(match_operand:DF 3 "mult_operator" "")
16184 (const_string "fmul")
16185 (match_operand:DF 3 "div_operator" "")
16186 (const_string "fdiv")
16188 (const_string "fop")))
16189 (set_attr "mode" "SF")])
16191 (define_insn "*fop_df_6_i387"
16192 [(set (match_operand:DF 0 "register_operand" "=f,f")
16193 (match_operator:DF 3 "binary_fp_operator"
16195 (match_operand:SF 1 "register_operand" "0,f"))
16197 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16198 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16199 "* return output_387_binary_op (insn, operands);"
16200 [(set (attr "type")
16201 (cond [(match_operand:DF 3 "mult_operator" "")
16202 (const_string "fmul")
16203 (match_operand:DF 3 "div_operator" "")
16204 (const_string "fdiv")
16206 (const_string "fop")))
16207 (set_attr "mode" "SF")])
16209 (define_insn "*fop_xf_comm_i387"
16210 [(set (match_operand:XF 0 "register_operand" "=f")
16211 (match_operator:XF 3 "binary_fp_operator"
16212 [(match_operand:XF 1 "register_operand" "%0")
16213 (match_operand:XF 2 "register_operand" "f")]))]
16215 && COMMUTATIVE_ARITH_P (operands[3])"
16216 "* return output_387_binary_op (insn, operands);"
16217 [(set (attr "type")
16218 (if_then_else (match_operand:XF 3 "mult_operator" "")
16219 (const_string "fmul")
16220 (const_string "fop")))
16221 (set_attr "mode" "XF")])
16223 (define_insn "*fop_xf_1_i387"
16224 [(set (match_operand:XF 0 "register_operand" "=f,f")
16225 (match_operator:XF 3 "binary_fp_operator"
16226 [(match_operand:XF 1 "register_operand" "0,f")
16227 (match_operand:XF 2 "register_operand" "f,0")]))]
16229 && !COMMUTATIVE_ARITH_P (operands[3])"
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" "XF")])
16240 (define_insn "*fop_xf_2<mode>_i387"
16241 [(set (match_operand:XF 0 "register_operand" "=f,f")
16242 (match_operator:XF 3 "binary_fp_operator"
16243 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16244 (match_operand:XF 2 "register_operand" "0,0")]))]
16245 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16246 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16247 [(set (attr "type")
16248 (cond [(match_operand:XF 3 "mult_operator" "")
16249 (const_string "fmul")
16250 (match_operand:XF 3 "div_operator" "")
16251 (const_string "fdiv")
16253 (const_string "fop")))
16254 (set_attr "fp_int_src" "true")
16255 (set_attr "mode" "<MODE>")])
16257 (define_insn "*fop_xf_3<mode>_i387"
16258 [(set (match_operand:XF 0 "register_operand" "=f,f")
16259 (match_operator:XF 3 "binary_fp_operator"
16260 [(match_operand:XF 1 "register_operand" "0,0")
16261 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16262 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16263 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16264 [(set (attr "type")
16265 (cond [(match_operand:XF 3 "mult_operator" "")
16266 (const_string "fmul")
16267 (match_operand:XF 3 "div_operator" "")
16268 (const_string "fdiv")
16270 (const_string "fop")))
16271 (set_attr "fp_int_src" "true")
16272 (set_attr "mode" "<MODE>")])
16274 (define_insn "*fop_xf_4_i387"
16275 [(set (match_operand:XF 0 "register_operand" "=f,f")
16276 (match_operator:XF 3 "binary_fp_operator"
16278 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16279 (match_operand:XF 2 "register_operand" "0,f")]))]
16281 "* return output_387_binary_op (insn, operands);"
16282 [(set (attr "type")
16283 (cond [(match_operand:XF 3 "mult_operator" "")
16284 (const_string "fmul")
16285 (match_operand:XF 3 "div_operator" "")
16286 (const_string "fdiv")
16288 (const_string "fop")))
16289 (set_attr "mode" "SF")])
16291 (define_insn "*fop_xf_5_i387"
16292 [(set (match_operand:XF 0 "register_operand" "=f,f")
16293 (match_operator:XF 3 "binary_fp_operator"
16294 [(match_operand:XF 1 "register_operand" "0,f")
16296 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16298 "* return output_387_binary_op (insn, operands);"
16299 [(set (attr "type")
16300 (cond [(match_operand:XF 3 "mult_operator" "")
16301 (const_string "fmul")
16302 (match_operand:XF 3 "div_operator" "")
16303 (const_string "fdiv")
16305 (const_string "fop")))
16306 (set_attr "mode" "SF")])
16308 (define_insn "*fop_xf_6_i387"
16309 [(set (match_operand:XF 0 "register_operand" "=f,f")
16310 (match_operator:XF 3 "binary_fp_operator"
16312 (match_operand:MODEF 1 "register_operand" "0,f"))
16314 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16316 "* return output_387_binary_op (insn, operands);"
16317 [(set (attr "type")
16318 (cond [(match_operand:XF 3 "mult_operator" "")
16319 (const_string "fmul")
16320 (match_operand:XF 3 "div_operator" "")
16321 (const_string "fdiv")
16323 (const_string "fop")))
16324 (set_attr "mode" "SF")])
16327 [(set (match_operand 0 "register_operand" "")
16328 (match_operator 3 "binary_fp_operator"
16329 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16330 (match_operand 2 "register_operand" "")]))]
16332 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16335 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16336 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16337 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16338 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16339 GET_MODE (operands[3]),
16342 ix86_free_from_memory (GET_MODE (operands[1]));
16347 [(set (match_operand 0 "register_operand" "")
16348 (match_operator 3 "binary_fp_operator"
16349 [(match_operand 1 "register_operand" "")
16350 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16352 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16355 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16356 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16357 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16358 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16359 GET_MODE (operands[3]),
16362 ix86_free_from_memory (GET_MODE (operands[2]));
16366 ;; FPU special functions.
16368 ;; This pattern implements a no-op XFmode truncation for
16369 ;; all fancy i386 XFmode math functions.
16371 (define_insn "truncxf<mode>2_i387_noop_unspec"
16372 [(set (match_operand:MODEF 0 "register_operand" "=f")
16373 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16374 UNSPEC_TRUNC_NOOP))]
16375 "TARGET_USE_FANCY_MATH_387"
16376 "* return output_387_reg_move (insn, operands);"
16377 [(set_attr "type" "fmov")
16378 (set_attr "mode" "<MODE>")])
16380 (define_insn "sqrtxf2"
16381 [(set (match_operand:XF 0 "register_operand" "=f")
16382 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16383 "TARGET_USE_FANCY_MATH_387"
16385 [(set_attr "type" "fpspc")
16386 (set_attr "mode" "XF")
16387 (set_attr "athlon_decode" "direct")
16388 (set_attr "amdfam10_decode" "direct")])
16390 (define_insn "sqrt_extend<mode>xf2_i387"
16391 [(set (match_operand:XF 0 "register_operand" "=f")
16394 (match_operand:MODEF 1 "register_operand" "0"))))]
16395 "TARGET_USE_FANCY_MATH_387"
16397 [(set_attr "type" "fpspc")
16398 (set_attr "mode" "XF")
16399 (set_attr "athlon_decode" "direct")
16400 (set_attr "amdfam10_decode" "direct")])
16402 (define_insn "*rsqrtsf2_sse"
16403 [(set (match_operand:SF 0 "register_operand" "=x")
16404 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16407 "rsqrtss\t{%1, %0|%0, %1}"
16408 [(set_attr "type" "sse")
16409 (set_attr "mode" "SF")])
16411 (define_expand "rsqrtsf2"
16412 [(set (match_operand:SF 0 "register_operand" "")
16413 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16417 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16421 (define_insn "*sqrt<mode>2_sse"
16422 [(set (match_operand:MODEF 0 "register_operand" "=x")
16424 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16425 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16426 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16427 [(set_attr "type" "sse")
16428 (set_attr "mode" "<MODE>")
16429 (set_attr "athlon_decode" "*")
16430 (set_attr "amdfam10_decode" "*")])
16432 (define_expand "sqrt<mode>2"
16433 [(set (match_operand:MODEF 0 "register_operand" "")
16435 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16436 "TARGET_USE_FANCY_MATH_387
16437 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16439 if (<MODE>mode == SFmode
16440 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16441 && flag_finite_math_only && !flag_trapping_math
16442 && flag_unsafe_math_optimizations)
16444 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16448 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16450 rtx op0 = gen_reg_rtx (XFmode);
16451 rtx op1 = force_reg (<MODE>mode, operands[1]);
16453 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16454 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16459 (define_insn "fpremxf4_i387"
16460 [(set (match_operand:XF 0 "register_operand" "=f")
16461 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16462 (match_operand:XF 3 "register_operand" "1")]
16464 (set (match_operand:XF 1 "register_operand" "=u")
16465 (unspec:XF [(match_dup 2) (match_dup 3)]
16467 (set (reg:CCFP FPSR_REG)
16468 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16470 "TARGET_USE_FANCY_MATH_387"
16472 [(set_attr "type" "fpspc")
16473 (set_attr "mode" "XF")])
16475 (define_expand "fmodxf3"
16476 [(use (match_operand:XF 0 "register_operand" ""))
16477 (use (match_operand:XF 1 "register_operand" ""))
16478 (use (match_operand:XF 2 "register_operand" ""))]
16479 "TARGET_USE_FANCY_MATH_387"
16481 rtx label = gen_label_rtx ();
16485 if (rtx_equal_p (operands[1], operands[2]))
16487 op2 = gen_reg_rtx (XFmode);
16488 emit_move_insn (op2, operands[2]);
16493 emit_label (label);
16494 emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16495 ix86_emit_fp_unordered_jump (label);
16496 LABEL_NUSES (label) = 1;
16498 emit_move_insn (operands[0], operands[1]);
16502 (define_expand "fmod<mode>3"
16503 [(use (match_operand:MODEF 0 "register_operand" ""))
16504 (use (match_operand:MODEF 1 "general_operand" ""))
16505 (use (match_operand:MODEF 2 "general_operand" ""))]
16506 "TARGET_USE_FANCY_MATH_387"
16508 rtx label = gen_label_rtx ();
16510 rtx op1 = gen_reg_rtx (XFmode);
16511 rtx op2 = gen_reg_rtx (XFmode);
16513 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16514 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16516 emit_label (label);
16517 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16518 ix86_emit_fp_unordered_jump (label);
16519 LABEL_NUSES (label) = 1;
16521 /* Truncate the result properly for strict SSE math. */
16522 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16523 && !TARGET_MIX_SSE_I387)
16524 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16526 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16531 (define_insn "fprem1xf4_i387"
16532 [(set (match_operand:XF 0 "register_operand" "=f")
16533 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16534 (match_operand:XF 3 "register_operand" "1")]
16536 (set (match_operand:XF 1 "register_operand" "=u")
16537 (unspec:XF [(match_dup 2) (match_dup 3)]
16539 (set (reg:CCFP FPSR_REG)
16540 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16542 "TARGET_USE_FANCY_MATH_387"
16544 [(set_attr "type" "fpspc")
16545 (set_attr "mode" "XF")])
16547 (define_expand "remainderxf3"
16548 [(use (match_operand:XF 0 "register_operand" ""))
16549 (use (match_operand:XF 1 "register_operand" ""))
16550 (use (match_operand:XF 2 "register_operand" ""))]
16551 "TARGET_USE_FANCY_MATH_387"
16553 rtx label = gen_label_rtx ();
16557 if (rtx_equal_p (operands[1], operands[2]))
16559 op2 = gen_reg_rtx (XFmode);
16560 emit_move_insn (op2, operands[2]);
16565 emit_label (label);
16566 emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16567 ix86_emit_fp_unordered_jump (label);
16568 LABEL_NUSES (label) = 1;
16570 emit_move_insn (operands[0], operands[1]);
16574 (define_expand "remainder<mode>3"
16575 [(use (match_operand:MODEF 0 "register_operand" ""))
16576 (use (match_operand:MODEF 1 "general_operand" ""))
16577 (use (match_operand:MODEF 2 "general_operand" ""))]
16578 "TARGET_USE_FANCY_MATH_387"
16580 rtx label = gen_label_rtx ();
16582 rtx op1 = gen_reg_rtx (XFmode);
16583 rtx op2 = gen_reg_rtx (XFmode);
16585 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16586 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16588 emit_label (label);
16590 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16591 ix86_emit_fp_unordered_jump (label);
16592 LABEL_NUSES (label) = 1;
16594 /* Truncate the result properly for strict SSE math. */
16595 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16596 && !TARGET_MIX_SSE_I387)
16597 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16599 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16604 (define_insn "*sinxf2_i387"
16605 [(set (match_operand:XF 0 "register_operand" "=f")
16606 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16607 "TARGET_USE_FANCY_MATH_387
16608 && flag_unsafe_math_optimizations"
16610 [(set_attr "type" "fpspc")
16611 (set_attr "mode" "XF")])
16613 (define_insn "*sin_extend<mode>xf2_i387"
16614 [(set (match_operand:XF 0 "register_operand" "=f")
16615 (unspec:XF [(float_extend:XF
16616 (match_operand:MODEF 1 "register_operand" "0"))]
16618 "TARGET_USE_FANCY_MATH_387
16619 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16620 || TARGET_MIX_SSE_I387)
16621 && flag_unsafe_math_optimizations"
16623 [(set_attr "type" "fpspc")
16624 (set_attr "mode" "XF")])
16626 (define_insn "*cosxf2_i387"
16627 [(set (match_operand:XF 0 "register_operand" "=f")
16628 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16629 "TARGET_USE_FANCY_MATH_387
16630 && flag_unsafe_math_optimizations"
16632 [(set_attr "type" "fpspc")
16633 (set_attr "mode" "XF")])
16635 (define_insn "*cos_extend<mode>xf2_i387"
16636 [(set (match_operand:XF 0 "register_operand" "=f")
16637 (unspec:XF [(float_extend:XF
16638 (match_operand:MODEF 1 "register_operand" "0"))]
16640 "TARGET_USE_FANCY_MATH_387
16641 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16642 || TARGET_MIX_SSE_I387)
16643 && flag_unsafe_math_optimizations"
16645 [(set_attr "type" "fpspc")
16646 (set_attr "mode" "XF")])
16648 ;; When sincos pattern is defined, sin and cos builtin functions will be
16649 ;; expanded to sincos pattern with one of its outputs left unused.
16650 ;; CSE pass will figure out if two sincos patterns can be combined,
16651 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16652 ;; depending on the unused output.
16654 (define_insn "sincosxf3"
16655 [(set (match_operand:XF 0 "register_operand" "=f")
16656 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16657 UNSPEC_SINCOS_COS))
16658 (set (match_operand:XF 1 "register_operand" "=u")
16659 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16660 "TARGET_USE_FANCY_MATH_387
16661 && flag_unsafe_math_optimizations"
16663 [(set_attr "type" "fpspc")
16664 (set_attr "mode" "XF")])
16667 [(set (match_operand:XF 0 "register_operand" "")
16668 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16669 UNSPEC_SINCOS_COS))
16670 (set (match_operand:XF 1 "register_operand" "")
16671 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16672 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16673 && !(reload_completed || reload_in_progress)"
16674 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16678 [(set (match_operand:XF 0 "register_operand" "")
16679 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16680 UNSPEC_SINCOS_COS))
16681 (set (match_operand:XF 1 "register_operand" "")
16682 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16683 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16684 && !(reload_completed || reload_in_progress)"
16685 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16688 (define_insn "sincos_extend<mode>xf3_i387"
16689 [(set (match_operand:XF 0 "register_operand" "=f")
16690 (unspec:XF [(float_extend:XF
16691 (match_operand:MODEF 2 "register_operand" "0"))]
16692 UNSPEC_SINCOS_COS))
16693 (set (match_operand:XF 1 "register_operand" "=u")
16694 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16695 "TARGET_USE_FANCY_MATH_387
16696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16697 || TARGET_MIX_SSE_I387)
16698 && flag_unsafe_math_optimizations"
16700 [(set_attr "type" "fpspc")
16701 (set_attr "mode" "XF")])
16704 [(set (match_operand:XF 0 "register_operand" "")
16705 (unspec:XF [(float_extend:XF
16706 (match_operand:MODEF 2 "register_operand" ""))]
16707 UNSPEC_SINCOS_COS))
16708 (set (match_operand:XF 1 "register_operand" "")
16709 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16710 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16711 && !(reload_completed || reload_in_progress)"
16712 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16716 [(set (match_operand:XF 0 "register_operand" "")
16717 (unspec:XF [(float_extend:XF
16718 (match_operand:MODEF 2 "register_operand" ""))]
16719 UNSPEC_SINCOS_COS))
16720 (set (match_operand:XF 1 "register_operand" "")
16721 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16722 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16723 && !(reload_completed || reload_in_progress)"
16724 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16727 (define_expand "sincos<mode>3"
16728 [(use (match_operand:MODEF 0 "register_operand" ""))
16729 (use (match_operand:MODEF 1 "register_operand" ""))
16730 (use (match_operand:MODEF 2 "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);
16737 rtx op1 = gen_reg_rtx (XFmode);
16739 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16740 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16741 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16745 (define_insn "fptanxf4_i387"
16746 [(set (match_operand:XF 0 "register_operand" "=f")
16747 (match_operand:XF 3 "const_double_operand" "F"))
16748 (set (match_operand:XF 1 "register_operand" "=u")
16749 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16751 "TARGET_USE_FANCY_MATH_387
16752 && flag_unsafe_math_optimizations
16753 && standard_80387_constant_p (operands[3]) == 2"
16755 [(set_attr "type" "fpspc")
16756 (set_attr "mode" "XF")])
16758 (define_insn "fptan_extend<mode>xf4_i387"
16759 [(set (match_operand:MODEF 0 "register_operand" "=f")
16760 (match_operand:MODEF 3 "const_double_operand" "F"))
16761 (set (match_operand:XF 1 "register_operand" "=u")
16762 (unspec:XF [(float_extend:XF
16763 (match_operand:MODEF 2 "register_operand" "0"))]
16765 "TARGET_USE_FANCY_MATH_387
16766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16767 || TARGET_MIX_SSE_I387)
16768 && flag_unsafe_math_optimizations
16769 && standard_80387_constant_p (operands[3]) == 2"
16771 [(set_attr "type" "fpspc")
16772 (set_attr "mode" "XF")])
16774 (define_expand "tanxf2"
16775 [(use (match_operand:XF 0 "register_operand" ""))
16776 (use (match_operand:XF 1 "register_operand" ""))]
16777 "TARGET_USE_FANCY_MATH_387
16778 && flag_unsafe_math_optimizations"
16780 rtx one = gen_reg_rtx (XFmode);
16781 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16783 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16787 (define_expand "tan<mode>2"
16788 [(use (match_operand:MODEF 0 "register_operand" ""))
16789 (use (match_operand:MODEF 1 "register_operand" ""))]
16790 "TARGET_USE_FANCY_MATH_387
16791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16792 || TARGET_MIX_SSE_I387)
16793 && flag_unsafe_math_optimizations"
16795 rtx op0 = gen_reg_rtx (XFmode);
16797 rtx one = gen_reg_rtx (<MODE>mode);
16798 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16800 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16801 operands[1], op2));
16802 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16806 (define_insn "*fpatanxf3_i387"
16807 [(set (match_operand:XF 0 "register_operand" "=f")
16808 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16809 (match_operand:XF 2 "register_operand" "u")]
16811 (clobber (match_scratch:XF 3 "=2"))]
16812 "TARGET_USE_FANCY_MATH_387
16813 && flag_unsafe_math_optimizations"
16815 [(set_attr "type" "fpspc")
16816 (set_attr "mode" "XF")])
16818 (define_insn "fpatan_extend<mode>xf3_i387"
16819 [(set (match_operand:XF 0 "register_operand" "=f")
16820 (unspec:XF [(float_extend:XF
16821 (match_operand:MODEF 1 "register_operand" "0"))
16823 (match_operand:MODEF 2 "register_operand" "u"))]
16825 (clobber (match_scratch:XF 3 "=2"))]
16826 "TARGET_USE_FANCY_MATH_387
16827 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16828 || TARGET_MIX_SSE_I387)
16829 && flag_unsafe_math_optimizations"
16831 [(set_attr "type" "fpspc")
16832 (set_attr "mode" "XF")])
16834 (define_expand "atan2xf3"
16835 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16836 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16837 (match_operand:XF 1 "register_operand" "")]
16839 (clobber (match_scratch:XF 3 ""))])]
16840 "TARGET_USE_FANCY_MATH_387
16841 && flag_unsafe_math_optimizations"
16844 (define_expand "atan2<mode>3"
16845 [(use (match_operand:MODEF 0 "register_operand" ""))
16846 (use (match_operand:MODEF 1 "register_operand" ""))
16847 (use (match_operand:MODEF 2 "register_operand" ""))]
16848 "TARGET_USE_FANCY_MATH_387
16849 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16850 || TARGET_MIX_SSE_I387)
16851 && flag_unsafe_math_optimizations"
16853 rtx op0 = gen_reg_rtx (XFmode);
16855 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16856 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16860 (define_expand "atanxf2"
16861 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16862 (unspec:XF [(match_dup 2)
16863 (match_operand:XF 1 "register_operand" "")]
16865 (clobber (match_scratch:XF 3 ""))])]
16866 "TARGET_USE_FANCY_MATH_387
16867 && flag_unsafe_math_optimizations"
16869 operands[2] = gen_reg_rtx (XFmode);
16870 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16873 (define_expand "atan<mode>2"
16874 [(use (match_operand:MODEF 0 "register_operand" ""))
16875 (use (match_operand:MODEF 1 "register_operand" ""))]
16876 "TARGET_USE_FANCY_MATH_387
16877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16878 || TARGET_MIX_SSE_I387)
16879 && flag_unsafe_math_optimizations"
16881 rtx op0 = gen_reg_rtx (XFmode);
16883 rtx op2 = gen_reg_rtx (<MODE>mode);
16884 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16886 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16887 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16891 (define_expand "asinxf2"
16892 [(set (match_dup 2)
16893 (mult:XF (match_operand:XF 1 "register_operand" "")
16895 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16896 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16897 (parallel [(set (match_operand:XF 0 "register_operand" "")
16898 (unspec:XF [(match_dup 5) (match_dup 1)]
16900 (clobber (match_scratch:XF 6 ""))])]
16901 "TARGET_USE_FANCY_MATH_387
16902 && flag_unsafe_math_optimizations && !optimize_size"
16906 for (i = 2; i < 6; i++)
16907 operands[i] = gen_reg_rtx (XFmode);
16909 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16912 (define_expand "asin<mode>2"
16913 [(use (match_operand:MODEF 0 "register_operand" ""))
16914 (use (match_operand:MODEF 1 "general_operand" ""))]
16915 "TARGET_USE_FANCY_MATH_387
16916 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16917 || TARGET_MIX_SSE_I387)
16918 && flag_unsafe_math_optimizations && !optimize_size"
16920 rtx op0 = gen_reg_rtx (XFmode);
16921 rtx op1 = gen_reg_rtx (XFmode);
16923 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16924 emit_insn (gen_asinxf2 (op0, op1));
16925 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16929 (define_expand "acosxf2"
16930 [(set (match_dup 2)
16931 (mult:XF (match_operand:XF 1 "register_operand" "")
16933 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16934 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16935 (parallel [(set (match_operand:XF 0 "register_operand" "")
16936 (unspec:XF [(match_dup 1) (match_dup 5)]
16938 (clobber (match_scratch:XF 6 ""))])]
16939 "TARGET_USE_FANCY_MATH_387
16940 && flag_unsafe_math_optimizations && !optimize_size"
16944 for (i = 2; i < 6; i++)
16945 operands[i] = gen_reg_rtx (XFmode);
16947 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16950 (define_expand "acos<mode>2"
16951 [(use (match_operand:MODEF 0 "register_operand" ""))
16952 (use (match_operand:MODEF 1 "general_operand" ""))]
16953 "TARGET_USE_FANCY_MATH_387
16954 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16955 || TARGET_MIX_SSE_I387)
16956 && flag_unsafe_math_optimizations && !optimize_size"
16958 rtx op0 = gen_reg_rtx (XFmode);
16959 rtx op1 = gen_reg_rtx (XFmode);
16961 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16962 emit_insn (gen_acosxf2 (op0, op1));
16963 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16967 (define_insn "fyl2xxf3_i387"
16968 [(set (match_operand:XF 0 "register_operand" "=f")
16969 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16970 (match_operand:XF 2 "register_operand" "u")]
16972 (clobber (match_scratch:XF 3 "=2"))]
16973 "TARGET_USE_FANCY_MATH_387
16974 && flag_unsafe_math_optimizations"
16976 [(set_attr "type" "fpspc")
16977 (set_attr "mode" "XF")])
16979 (define_insn "fyl2x_extend<mode>xf3_i387"
16980 [(set (match_operand:XF 0 "register_operand" "=f")
16981 (unspec:XF [(float_extend:XF
16982 (match_operand:MODEF 1 "register_operand" "0"))
16983 (match_operand:XF 2 "register_operand" "u")]
16985 (clobber (match_scratch:XF 3 "=2"))]
16986 "TARGET_USE_FANCY_MATH_387
16987 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16988 || TARGET_MIX_SSE_I387)
16989 && flag_unsafe_math_optimizations"
16991 [(set_attr "type" "fpspc")
16992 (set_attr "mode" "XF")])
16994 (define_expand "logxf2"
16995 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16996 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16997 (match_dup 2)] UNSPEC_FYL2X))
16998 (clobber (match_scratch:XF 3 ""))])]
16999 "TARGET_USE_FANCY_MATH_387
17000 && flag_unsafe_math_optimizations"
17002 operands[2] = gen_reg_rtx (XFmode);
17003 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17006 (define_expand "log<mode>2"
17007 [(use (match_operand:MODEF 0 "register_operand" ""))
17008 (use (match_operand:MODEF 1 "register_operand" ""))]
17009 "TARGET_USE_FANCY_MATH_387
17010 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17011 || TARGET_MIX_SSE_I387)
17012 && flag_unsafe_math_optimizations"
17014 rtx op0 = gen_reg_rtx (XFmode);
17016 rtx op2 = gen_reg_rtx (XFmode);
17017 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17019 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17020 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17024 (define_expand "log10xf2"
17025 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17026 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17027 (match_dup 2)] UNSPEC_FYL2X))
17028 (clobber (match_scratch:XF 3 ""))])]
17029 "TARGET_USE_FANCY_MATH_387
17030 && flag_unsafe_math_optimizations"
17032 operands[2] = gen_reg_rtx (XFmode);
17033 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17036 (define_expand "log10<mode>2"
17037 [(use (match_operand:MODEF 0 "register_operand" ""))
17038 (use (match_operand:MODEF 1 "register_operand" ""))]
17039 "TARGET_USE_FANCY_MATH_387
17040 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17041 || TARGET_MIX_SSE_I387)
17042 && flag_unsafe_math_optimizations"
17044 rtx op0 = gen_reg_rtx (XFmode);
17046 rtx op2 = gen_reg_rtx (XFmode);
17047 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17049 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17054 (define_expand "log2xf2"
17055 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17056 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17057 (match_dup 2)] UNSPEC_FYL2X))
17058 (clobber (match_scratch:XF 3 ""))])]
17059 "TARGET_USE_FANCY_MATH_387
17060 && flag_unsafe_math_optimizations"
17062 operands[2] = gen_reg_rtx (XFmode);
17063 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17066 (define_expand "log2<mode>2"
17067 [(use (match_operand:MODEF 0 "register_operand" ""))
17068 (use (match_operand:MODEF 1 "register_operand" ""))]
17069 "TARGET_USE_FANCY_MATH_387
17070 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17071 || TARGET_MIX_SSE_I387)
17072 && flag_unsafe_math_optimizations"
17074 rtx op0 = gen_reg_rtx (XFmode);
17076 rtx op2 = gen_reg_rtx (XFmode);
17077 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17079 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17080 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17084 (define_insn "fyl2xp1xf3_i387"
17085 [(set (match_operand:XF 0 "register_operand" "=f")
17086 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17087 (match_operand:XF 2 "register_operand" "u")]
17089 (clobber (match_scratch:XF 3 "=2"))]
17090 "TARGET_USE_FANCY_MATH_387
17091 && flag_unsafe_math_optimizations"
17093 [(set_attr "type" "fpspc")
17094 (set_attr "mode" "XF")])
17096 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17097 [(set (match_operand:XF 0 "register_operand" "=f")
17098 (unspec:XF [(float_extend:XF
17099 (match_operand:MODEF 1 "register_operand" "0"))
17100 (match_operand:XF 2 "register_operand" "u")]
17102 (clobber (match_scratch:XF 3 "=2"))]
17103 "TARGET_USE_FANCY_MATH_387
17104 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17105 || TARGET_MIX_SSE_I387)
17106 && flag_unsafe_math_optimizations"
17108 [(set_attr "type" "fpspc")
17109 (set_attr "mode" "XF")])
17111 (define_expand "log1pxf2"
17112 [(use (match_operand:XF 0 "register_operand" ""))
17113 (use (match_operand:XF 1 "register_operand" ""))]
17114 "TARGET_USE_FANCY_MATH_387
17115 && flag_unsafe_math_optimizations && !optimize_size"
17117 ix86_emit_i387_log1p (operands[0], operands[1]);
17121 (define_expand "log1p<mode>2"
17122 [(use (match_operand:MODEF 0 "register_operand" ""))
17123 (use (match_operand:MODEF 1 "register_operand" ""))]
17124 "TARGET_USE_FANCY_MATH_387
17125 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17126 || TARGET_MIX_SSE_I387)
17127 && flag_unsafe_math_optimizations && !optimize_size"
17129 rtx op0 = gen_reg_rtx (XFmode);
17131 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17133 ix86_emit_i387_log1p (op0, operands[1]);
17134 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17138 (define_insn "fxtractxf3_i387"
17139 [(set (match_operand:XF 0 "register_operand" "=f")
17140 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17141 UNSPEC_XTRACT_FRACT))
17142 (set (match_operand:XF 1 "register_operand" "=u")
17143 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17144 "TARGET_USE_FANCY_MATH_387
17145 && flag_unsafe_math_optimizations"
17147 [(set_attr "type" "fpspc")
17148 (set_attr "mode" "XF")])
17150 (define_insn "fxtract_extend<mode>xf3_i387"
17151 [(set (match_operand:XF 0 "register_operand" "=f")
17152 (unspec:XF [(float_extend:XF
17153 (match_operand:MODEF 2 "register_operand" "0"))]
17154 UNSPEC_XTRACT_FRACT))
17155 (set (match_operand:XF 1 "register_operand" "=u")
17156 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17157 "TARGET_USE_FANCY_MATH_387
17158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17159 || TARGET_MIX_SSE_I387)
17160 && flag_unsafe_math_optimizations"
17162 [(set_attr "type" "fpspc")
17163 (set_attr "mode" "XF")])
17165 (define_expand "logbxf2"
17166 [(parallel [(set (match_dup 2)
17167 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17168 UNSPEC_XTRACT_FRACT))
17169 (set (match_operand:XF 0 "register_operand" "")
17170 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17171 "TARGET_USE_FANCY_MATH_387
17172 && flag_unsafe_math_optimizations"
17174 operands[2] = gen_reg_rtx (XFmode);
17177 (define_expand "logb<mode>2"
17178 [(use (match_operand:MODEF 0 "register_operand" ""))
17179 (use (match_operand:MODEF 1 "register_operand" ""))]
17180 "TARGET_USE_FANCY_MATH_387
17181 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17182 || TARGET_MIX_SSE_I387)
17183 && flag_unsafe_math_optimizations"
17185 rtx op0 = gen_reg_rtx (XFmode);
17186 rtx op1 = gen_reg_rtx (XFmode);
17188 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17189 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17193 (define_expand "ilogbxf2"
17194 [(use (match_operand:SI 0 "register_operand" ""))
17195 (use (match_operand:XF 1 "register_operand" ""))]
17196 "TARGET_USE_FANCY_MATH_387
17197 && flag_unsafe_math_optimizations && !optimize_size"
17199 rtx op0 = gen_reg_rtx (XFmode);
17200 rtx op1 = gen_reg_rtx (XFmode);
17202 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17203 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17207 (define_expand "ilogb<mode>2"
17208 [(use (match_operand:SI 0 "register_operand" ""))
17209 (use (match_operand:MODEF 1 "register_operand" ""))]
17210 "TARGET_USE_FANCY_MATH_387
17211 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17212 || TARGET_MIX_SSE_I387)
17213 && flag_unsafe_math_optimizations && !optimize_size"
17215 rtx op0 = gen_reg_rtx (XFmode);
17216 rtx op1 = gen_reg_rtx (XFmode);
17218 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17219 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17223 (define_insn "*f2xm1xf2_i387"
17224 [(set (match_operand:XF 0 "register_operand" "=f")
17225 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17227 "TARGET_USE_FANCY_MATH_387
17228 && flag_unsafe_math_optimizations"
17230 [(set_attr "type" "fpspc")
17231 (set_attr "mode" "XF")])
17233 (define_insn "*fscalexf4_i387"
17234 [(set (match_operand:XF 0 "register_operand" "=f")
17235 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17236 (match_operand:XF 3 "register_operand" "1")]
17237 UNSPEC_FSCALE_FRACT))
17238 (set (match_operand:XF 1 "register_operand" "=u")
17239 (unspec:XF [(match_dup 2) (match_dup 3)]
17240 UNSPEC_FSCALE_EXP))]
17241 "TARGET_USE_FANCY_MATH_387
17242 && flag_unsafe_math_optimizations"
17244 [(set_attr "type" "fpspc")
17245 (set_attr "mode" "XF")])
17247 (define_expand "expNcorexf3"
17248 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17249 (match_operand:XF 2 "register_operand" "")))
17250 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17251 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17252 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17253 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17254 (parallel [(set (match_operand:XF 0 "register_operand" "")
17255 (unspec:XF [(match_dup 8) (match_dup 4)]
17256 UNSPEC_FSCALE_FRACT))
17258 (unspec:XF [(match_dup 8) (match_dup 4)]
17259 UNSPEC_FSCALE_EXP))])]
17260 "TARGET_USE_FANCY_MATH_387
17261 && flag_unsafe_math_optimizations && !optimize_size"
17265 for (i = 3; i < 10; i++)
17266 operands[i] = gen_reg_rtx (XFmode);
17268 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17271 (define_expand "expxf2"
17272 [(use (match_operand:XF 0 "register_operand" ""))
17273 (use (match_operand:XF 1 "register_operand" ""))]
17274 "TARGET_USE_FANCY_MATH_387
17275 && flag_unsafe_math_optimizations && !optimize_size"
17277 rtx op2 = gen_reg_rtx (XFmode);
17278 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17280 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17284 (define_expand "exp<mode>2"
17285 [(use (match_operand:MODEF 0 "register_operand" ""))
17286 (use (match_operand:MODEF 1 "general_operand" ""))]
17287 "TARGET_USE_FANCY_MATH_387
17288 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17289 || TARGET_MIX_SSE_I387)
17290 && flag_unsafe_math_optimizations && !optimize_size"
17292 rtx op0 = gen_reg_rtx (XFmode);
17293 rtx op1 = gen_reg_rtx (XFmode);
17295 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17296 emit_insn (gen_expxf2 (op0, op1));
17297 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17301 (define_expand "exp10xf2"
17302 [(use (match_operand:XF 0 "register_operand" ""))
17303 (use (match_operand:XF 1 "register_operand" ""))]
17304 "TARGET_USE_FANCY_MATH_387
17305 && flag_unsafe_math_optimizations && !optimize_size"
17307 rtx op2 = gen_reg_rtx (XFmode);
17308 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17310 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17314 (define_expand "exp10<mode>2"
17315 [(use (match_operand:MODEF 0 "register_operand" ""))
17316 (use (match_operand:MODEF 1 "general_operand" ""))]
17317 "TARGET_USE_FANCY_MATH_387
17318 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17319 || TARGET_MIX_SSE_I387)
17320 && flag_unsafe_math_optimizations && !optimize_size"
17322 rtx op0 = gen_reg_rtx (XFmode);
17323 rtx op1 = gen_reg_rtx (XFmode);
17325 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17326 emit_insn (gen_exp10xf2 (op0, op1));
17327 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17331 (define_expand "exp2xf2"
17332 [(use (match_operand:XF 0 "register_operand" ""))
17333 (use (match_operand:XF 1 "register_operand" ""))]
17334 "TARGET_USE_FANCY_MATH_387
17335 && flag_unsafe_math_optimizations && !optimize_size"
17337 rtx op2 = gen_reg_rtx (XFmode);
17338 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17340 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17344 (define_expand "exp2<mode>2"
17345 [(use (match_operand:MODEF 0 "register_operand" ""))
17346 (use (match_operand:MODEF 1 "general_operand" ""))]
17347 "TARGET_USE_FANCY_MATH_387
17348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17349 || TARGET_MIX_SSE_I387)
17350 && flag_unsafe_math_optimizations && !optimize_size"
17352 rtx op0 = gen_reg_rtx (XFmode);
17353 rtx op1 = gen_reg_rtx (XFmode);
17355 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17356 emit_insn (gen_exp2xf2 (op0, op1));
17357 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17361 (define_expand "expm1xf2"
17362 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17364 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17365 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17366 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17367 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17368 (parallel [(set (match_dup 7)
17369 (unspec:XF [(match_dup 6) (match_dup 4)]
17370 UNSPEC_FSCALE_FRACT))
17372 (unspec:XF [(match_dup 6) (match_dup 4)]
17373 UNSPEC_FSCALE_EXP))])
17374 (parallel [(set (match_dup 10)
17375 (unspec:XF [(match_dup 9) (match_dup 8)]
17376 UNSPEC_FSCALE_FRACT))
17377 (set (match_dup 11)
17378 (unspec:XF [(match_dup 9) (match_dup 8)]
17379 UNSPEC_FSCALE_EXP))])
17380 (set (match_dup 12) (minus:XF (match_dup 10)
17381 (float_extend:XF (match_dup 13))))
17382 (set (match_operand:XF 0 "register_operand" "")
17383 (plus:XF (match_dup 12) (match_dup 7)))]
17384 "TARGET_USE_FANCY_MATH_387
17385 && flag_unsafe_math_optimizations && !optimize_size"
17389 for (i = 2; i < 13; i++)
17390 operands[i] = gen_reg_rtx (XFmode);
17393 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17395 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17398 (define_expand "expm1<mode>2"
17399 [(use (match_operand:MODEF 0 "register_operand" ""))
17400 (use (match_operand:MODEF 1 "general_operand" ""))]
17401 "TARGET_USE_FANCY_MATH_387
17402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17403 || TARGET_MIX_SSE_I387)
17404 && flag_unsafe_math_optimizations && !optimize_size"
17406 rtx op0 = gen_reg_rtx (XFmode);
17407 rtx op1 = gen_reg_rtx (XFmode);
17409 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17410 emit_insn (gen_expm1xf2 (op0, op1));
17411 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17415 (define_expand "ldexpxf3"
17416 [(set (match_dup 3)
17417 (float:XF (match_operand:SI 2 "register_operand" "")))
17418 (parallel [(set (match_operand:XF 0 " register_operand" "")
17419 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17421 UNSPEC_FSCALE_FRACT))
17423 (unspec:XF [(match_dup 1) (match_dup 3)]
17424 UNSPEC_FSCALE_EXP))])]
17425 "TARGET_USE_FANCY_MATH_387
17426 && flag_unsafe_math_optimizations && !optimize_size"
17428 operands[3] = gen_reg_rtx (XFmode);
17429 operands[4] = gen_reg_rtx (XFmode);
17432 (define_expand "ldexp<mode>3"
17433 [(use (match_operand:MODEF 0 "register_operand" ""))
17434 (use (match_operand:MODEF 1 "general_operand" ""))
17435 (use (match_operand:SI 2 "register_operand" ""))]
17436 "TARGET_USE_FANCY_MATH_387
17437 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17438 || TARGET_MIX_SSE_I387)
17439 && flag_unsafe_math_optimizations && !optimize_size"
17441 rtx op0 = gen_reg_rtx (XFmode);
17442 rtx op1 = gen_reg_rtx (XFmode);
17444 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17445 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17446 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17450 (define_expand "scalbxf3"
17451 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17452 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17453 (match_operand:XF 2 "register_operand" "")]
17454 UNSPEC_FSCALE_FRACT))
17456 (unspec:XF [(match_dup 1) (match_dup 2)]
17457 UNSPEC_FSCALE_EXP))])]
17458 "TARGET_USE_FANCY_MATH_387
17459 && flag_unsafe_math_optimizations && !optimize_size"
17461 operands[3] = gen_reg_rtx (XFmode);
17464 (define_expand "scalb<mode>3"
17465 [(use (match_operand:MODEF 0 "register_operand" ""))
17466 (use (match_operand:MODEF 1 "general_operand" ""))
17467 (use (match_operand:MODEF 2 "register_operand" ""))]
17468 "TARGET_USE_FANCY_MATH_387
17469 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17470 || TARGET_MIX_SSE_I387)
17471 && flag_unsafe_math_optimizations && !optimize_size"
17473 rtx op0 = gen_reg_rtx (XFmode);
17474 rtx op1 = gen_reg_rtx (XFmode);
17475 rtx op2 = gen_reg_rtx (XFmode);
17477 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17478 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17479 emit_insn (gen_scalbxf3 (op0, op1, op2));
17480 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17485 (define_insn "sse4_1_round<mode>2"
17486 [(set (match_operand:MODEF 0 "register_operand" "=x")
17487 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17488 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17491 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17492 [(set_attr "type" "ssecvt")
17493 (set_attr "prefix_extra" "1")
17494 (set_attr "mode" "<MODE>")])
17496 (define_insn "rintxf2"
17497 [(set (match_operand:XF 0 "register_operand" "=f")
17498 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17500 "TARGET_USE_FANCY_MATH_387
17501 && flag_unsafe_math_optimizations"
17503 [(set_attr "type" "fpspc")
17504 (set_attr "mode" "XF")])
17506 (define_expand "rint<mode>2"
17507 [(use (match_operand:MODEF 0 "register_operand" ""))
17508 (use (match_operand:MODEF 1 "register_operand" ""))]
17509 "(TARGET_USE_FANCY_MATH_387
17510 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17511 || TARGET_MIX_SSE_I387)
17512 && flag_unsafe_math_optimizations)
17513 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17514 && !flag_trapping_math
17515 && (TARGET_ROUND || !optimize_size))"
17517 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17518 && !flag_trapping_math
17519 && (TARGET_ROUND || !optimize_size))
17522 emit_insn (gen_sse4_1_round<mode>2
17523 (operands[0], operands[1], GEN_INT (0x04)));
17525 ix86_expand_rint (operand0, operand1);
17529 rtx op0 = gen_reg_rtx (XFmode);
17530 rtx op1 = gen_reg_rtx (XFmode);
17532 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17533 emit_insn (gen_rintxf2 (op0, op1));
17535 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17540 (define_expand "round<mode>2"
17541 [(match_operand:MODEF 0 "register_operand" "")
17542 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17543 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17544 && !flag_trapping_math && !flag_rounding_math
17547 if (TARGET_64BIT || (<MODE>mode != DFmode))
17548 ix86_expand_round (operand0, operand1);
17550 ix86_expand_rounddf_32 (operand0, operand1);
17554 (define_insn_and_split "*fistdi2_1"
17555 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17556 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17558 "TARGET_USE_FANCY_MATH_387
17559 && !(reload_completed || reload_in_progress)"
17564 if (memory_operand (operands[0], VOIDmode))
17565 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17568 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17569 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17574 [(set_attr "type" "fpspc")
17575 (set_attr "mode" "DI")])
17577 (define_insn "fistdi2"
17578 [(set (match_operand:DI 0 "memory_operand" "=m")
17579 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17581 (clobber (match_scratch:XF 2 "=&1f"))]
17582 "TARGET_USE_FANCY_MATH_387"
17583 "* return output_fix_trunc (insn, operands, 0);"
17584 [(set_attr "type" "fpspc")
17585 (set_attr "mode" "DI")])
17587 (define_insn "fistdi2_with_temp"
17588 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17589 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17591 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17592 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17593 "TARGET_USE_FANCY_MATH_387"
17595 [(set_attr "type" "fpspc")
17596 (set_attr "mode" "DI")])
17599 [(set (match_operand:DI 0 "register_operand" "")
17600 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17602 (clobber (match_operand:DI 2 "memory_operand" ""))
17603 (clobber (match_scratch 3 ""))]
17605 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17606 (clobber (match_dup 3))])
17607 (set (match_dup 0) (match_dup 2))]
17611 [(set (match_operand:DI 0 "memory_operand" "")
17612 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17614 (clobber (match_operand:DI 2 "memory_operand" ""))
17615 (clobber (match_scratch 3 ""))]
17617 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17618 (clobber (match_dup 3))])]
17621 (define_insn_and_split "*fist<mode>2_1"
17622 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17623 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17625 "TARGET_USE_FANCY_MATH_387
17626 && !(reload_completed || reload_in_progress)"
17631 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17632 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17636 [(set_attr "type" "fpspc")
17637 (set_attr "mode" "<MODE>")])
17639 (define_insn "fist<mode>2"
17640 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17641 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17643 "TARGET_USE_FANCY_MATH_387"
17644 "* return output_fix_trunc (insn, operands, 0);"
17645 [(set_attr "type" "fpspc")
17646 (set_attr "mode" "<MODE>")])
17648 (define_insn "fist<mode>2_with_temp"
17649 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17650 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17652 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17653 "TARGET_USE_FANCY_MATH_387"
17655 [(set_attr "type" "fpspc")
17656 (set_attr "mode" "<MODE>")])
17659 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17660 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17662 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17664 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17665 (set (match_dup 0) (match_dup 2))]
17669 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17670 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17672 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17674 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17677 (define_expand "lrintxf<mode>2"
17678 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17679 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17681 "TARGET_USE_FANCY_MATH_387"
17684 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17685 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17686 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17687 UNSPEC_FIX_NOTRUNC))]
17688 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17689 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17692 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17693 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17694 (match_operand:MODEF 1 "register_operand" "")]
17695 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17696 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17697 && !flag_trapping_math && !flag_rounding_math
17700 ix86_expand_lround (operand0, operand1);
17704 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17705 (define_insn_and_split "frndintxf2_floor"
17706 [(set (match_operand:XF 0 "register_operand" "")
17707 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17708 UNSPEC_FRNDINT_FLOOR))
17709 (clobber (reg:CC FLAGS_REG))]
17710 "TARGET_USE_FANCY_MATH_387
17711 && flag_unsafe_math_optimizations
17712 && !(reload_completed || reload_in_progress)"
17717 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17719 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17720 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17722 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17723 operands[2], operands[3]));
17726 [(set_attr "type" "frndint")
17727 (set_attr "i387_cw" "floor")
17728 (set_attr "mode" "XF")])
17730 (define_insn "frndintxf2_floor_i387"
17731 [(set (match_operand:XF 0 "register_operand" "=f")
17732 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17733 UNSPEC_FRNDINT_FLOOR))
17734 (use (match_operand:HI 2 "memory_operand" "m"))
17735 (use (match_operand:HI 3 "memory_operand" "m"))]
17736 "TARGET_USE_FANCY_MATH_387
17737 && flag_unsafe_math_optimizations"
17738 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17739 [(set_attr "type" "frndint")
17740 (set_attr "i387_cw" "floor")
17741 (set_attr "mode" "XF")])
17743 (define_expand "floorxf2"
17744 [(use (match_operand:XF 0 "register_operand" ""))
17745 (use (match_operand:XF 1 "register_operand" ""))]
17746 "TARGET_USE_FANCY_MATH_387
17747 && flag_unsafe_math_optimizations && !optimize_size"
17749 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17753 (define_expand "floor<mode>2"
17754 [(use (match_operand:MODEF 0 "register_operand" ""))
17755 (use (match_operand:MODEF 1 "register_operand" ""))]
17756 "(TARGET_USE_FANCY_MATH_387
17757 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17758 || TARGET_MIX_SSE_I387)
17759 && flag_unsafe_math_optimizations && !optimize_size)
17760 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17761 && !flag_trapping_math
17762 && (TARGET_ROUND || !optimize_size))"
17764 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17765 && !flag_trapping_math
17766 && (TARGET_ROUND || !optimize_size))
17769 emit_insn (gen_sse4_1_round<mode>2
17770 (operands[0], operands[1], GEN_INT (0x01)));
17771 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17772 ix86_expand_floorceil (operand0, operand1, true);
17774 ix86_expand_floorceildf_32 (operand0, operand1, true);
17778 rtx op0 = gen_reg_rtx (XFmode);
17779 rtx op1 = gen_reg_rtx (XFmode);
17781 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17782 emit_insn (gen_frndintxf2_floor (op0, op1));
17784 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17789 (define_insn_and_split "*fist<mode>2_floor_1"
17790 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17791 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17792 UNSPEC_FIST_FLOOR))
17793 (clobber (reg:CC FLAGS_REG))]
17794 "TARGET_USE_FANCY_MATH_387
17795 && flag_unsafe_math_optimizations
17796 && !(reload_completed || reload_in_progress)"
17801 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17803 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17804 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17805 if (memory_operand (operands[0], VOIDmode))
17806 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17807 operands[2], operands[3]));
17810 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17811 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17812 operands[2], operands[3],
17817 [(set_attr "type" "fistp")
17818 (set_attr "i387_cw" "floor")
17819 (set_attr "mode" "<MODE>")])
17821 (define_insn "fistdi2_floor"
17822 [(set (match_operand:DI 0 "memory_operand" "=m")
17823 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17824 UNSPEC_FIST_FLOOR))
17825 (use (match_operand:HI 2 "memory_operand" "m"))
17826 (use (match_operand:HI 3 "memory_operand" "m"))
17827 (clobber (match_scratch:XF 4 "=&1f"))]
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" "DI")])
17835 (define_insn "fistdi2_floor_with_temp"
17836 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17837 (unspec:DI [(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:DI 4 "memory_operand" "=m,m"))
17842 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17843 "TARGET_USE_FANCY_MATH_387
17844 && flag_unsafe_math_optimizations"
17846 [(set_attr "type" "fistp")
17847 (set_attr "i387_cw" "floor")
17848 (set_attr "mode" "DI")])
17851 [(set (match_operand:DI 0 "register_operand" "")
17852 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17853 UNSPEC_FIST_FLOOR))
17854 (use (match_operand:HI 2 "memory_operand" ""))
17855 (use (match_operand:HI 3 "memory_operand" ""))
17856 (clobber (match_operand:DI 4 "memory_operand" ""))
17857 (clobber (match_scratch 5 ""))]
17859 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17860 (use (match_dup 2))
17861 (use (match_dup 3))
17862 (clobber (match_dup 5))])
17863 (set (match_dup 0) (match_dup 4))]
17867 [(set (match_operand:DI 0 "memory_operand" "")
17868 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17869 UNSPEC_FIST_FLOOR))
17870 (use (match_operand:HI 2 "memory_operand" ""))
17871 (use (match_operand:HI 3 "memory_operand" ""))
17872 (clobber (match_operand:DI 4 "memory_operand" ""))
17873 (clobber (match_scratch 5 ""))]
17875 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17876 (use (match_dup 2))
17877 (use (match_dup 3))
17878 (clobber (match_dup 5))])]
17881 (define_insn "fist<mode>2_floor"
17882 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17883 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17884 UNSPEC_FIST_FLOOR))
17885 (use (match_operand:HI 2 "memory_operand" "m"))
17886 (use (match_operand:HI 3 "memory_operand" "m"))]
17887 "TARGET_USE_FANCY_MATH_387
17888 && flag_unsafe_math_optimizations"
17889 "* return output_fix_trunc (insn, operands, 0);"
17890 [(set_attr "type" "fistp")
17891 (set_attr "i387_cw" "floor")
17892 (set_attr "mode" "<MODE>")])
17894 (define_insn "fist<mode>2_floor_with_temp"
17895 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17896 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17897 UNSPEC_FIST_FLOOR))
17898 (use (match_operand:HI 2 "memory_operand" "m,m"))
17899 (use (match_operand:HI 3 "memory_operand" "m,m"))
17900 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17901 "TARGET_USE_FANCY_MATH_387
17902 && flag_unsafe_math_optimizations"
17904 [(set_attr "type" "fistp")
17905 (set_attr "i387_cw" "floor")
17906 (set_attr "mode" "<MODE>")])
17909 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17910 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17911 UNSPEC_FIST_FLOOR))
17912 (use (match_operand:HI 2 "memory_operand" ""))
17913 (use (match_operand:HI 3 "memory_operand" ""))
17914 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17916 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17917 UNSPEC_FIST_FLOOR))
17918 (use (match_dup 2))
17919 (use (match_dup 3))])
17920 (set (match_dup 0) (match_dup 4))]
17924 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17925 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17926 UNSPEC_FIST_FLOOR))
17927 (use (match_operand:HI 2 "memory_operand" ""))
17928 (use (match_operand:HI 3 "memory_operand" ""))
17929 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17931 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17932 UNSPEC_FIST_FLOOR))
17933 (use (match_dup 2))
17934 (use (match_dup 3))])]
17937 (define_expand "lfloorxf<mode>2"
17938 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17939 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17940 UNSPEC_FIST_FLOOR))
17941 (clobber (reg:CC FLAGS_REG))])]
17942 "TARGET_USE_FANCY_MATH_387
17943 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17944 && flag_unsafe_math_optimizations"
17947 (define_expand "lfloor<mode>di2"
17948 [(match_operand:DI 0 "nonimmediate_operand" "")
17949 (match_operand:MODEF 1 "register_operand" "")]
17950 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17951 && !flag_trapping_math
17954 ix86_expand_lfloorceil (operand0, operand1, true);
17958 (define_expand "lfloor<mode>si2"
17959 [(match_operand:SI 0 "nonimmediate_operand" "")
17960 (match_operand:MODEF 1 "register_operand" "")]
17961 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17962 && !flag_trapping_math
17963 && (!optimize_size || !TARGET_64BIT)"
17965 ix86_expand_lfloorceil (operand0, operand1, true);
17969 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17970 (define_insn_and_split "frndintxf2_ceil"
17971 [(set (match_operand:XF 0 "register_operand" "")
17972 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17973 UNSPEC_FRNDINT_CEIL))
17974 (clobber (reg:CC FLAGS_REG))]
17975 "TARGET_USE_FANCY_MATH_387
17976 && flag_unsafe_math_optimizations
17977 && !(reload_completed || reload_in_progress)"
17982 ix86_optimize_mode_switching[I387_CEIL] = 1;
17984 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17985 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17987 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17988 operands[2], operands[3]));
17991 [(set_attr "type" "frndint")
17992 (set_attr "i387_cw" "ceil")
17993 (set_attr "mode" "XF")])
17995 (define_insn "frndintxf2_ceil_i387"
17996 [(set (match_operand:XF 0 "register_operand" "=f")
17997 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17998 UNSPEC_FRNDINT_CEIL))
17999 (use (match_operand:HI 2 "memory_operand" "m"))
18000 (use (match_operand:HI 3 "memory_operand" "m"))]
18001 "TARGET_USE_FANCY_MATH_387
18002 && flag_unsafe_math_optimizations"
18003 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18004 [(set_attr "type" "frndint")
18005 (set_attr "i387_cw" "ceil")
18006 (set_attr "mode" "XF")])
18008 (define_expand "ceilxf2"
18009 [(use (match_operand:XF 0 "register_operand" ""))
18010 (use (match_operand:XF 1 "register_operand" ""))]
18011 "TARGET_USE_FANCY_MATH_387
18012 && flag_unsafe_math_optimizations && !optimize_size"
18014 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18018 (define_expand "ceil<mode>2"
18019 [(use (match_operand:MODEF 0 "register_operand" ""))
18020 (use (match_operand:MODEF 1 "register_operand" ""))]
18021 "(TARGET_USE_FANCY_MATH_387
18022 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18023 || TARGET_MIX_SSE_I387)
18024 && flag_unsafe_math_optimizations && !optimize_size)
18025 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18026 && !flag_trapping_math
18027 && (TARGET_ROUND || !optimize_size))"
18029 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18030 && !flag_trapping_math
18031 && (TARGET_ROUND || !optimize_size))
18034 emit_insn (gen_sse4_1_round<mode>2
18035 (operands[0], operands[1], GEN_INT (0x02)));
18036 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18037 ix86_expand_floorceil (operand0, operand1, false);
18039 ix86_expand_floorceildf_32 (operand0, operand1, false);
18043 rtx op0 = gen_reg_rtx (XFmode);
18044 rtx op1 = gen_reg_rtx (XFmode);
18046 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18047 emit_insn (gen_frndintxf2_ceil (op0, op1));
18049 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18054 (define_insn_and_split "*fist<mode>2_ceil_1"
18055 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18056 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18058 (clobber (reg:CC FLAGS_REG))]
18059 "TARGET_USE_FANCY_MATH_387
18060 && flag_unsafe_math_optimizations
18061 && !(reload_completed || reload_in_progress)"
18066 ix86_optimize_mode_switching[I387_CEIL] = 1;
18068 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18069 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18070 if (memory_operand (operands[0], VOIDmode))
18071 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18072 operands[2], operands[3]));
18075 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18076 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18077 operands[2], operands[3],
18082 [(set_attr "type" "fistp")
18083 (set_attr "i387_cw" "ceil")
18084 (set_attr "mode" "<MODE>")])
18086 (define_insn "fistdi2_ceil"
18087 [(set (match_operand:DI 0 "memory_operand" "=m")
18088 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18090 (use (match_operand:HI 2 "memory_operand" "m"))
18091 (use (match_operand:HI 3 "memory_operand" "m"))
18092 (clobber (match_scratch:XF 4 "=&1f"))]
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" "DI")])
18100 (define_insn "fistdi2_ceil_with_temp"
18101 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18102 (unspec:DI [(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:DI 4 "memory_operand" "=m,m"))
18107 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18108 "TARGET_USE_FANCY_MATH_387
18109 && flag_unsafe_math_optimizations"
18111 [(set_attr "type" "fistp")
18112 (set_attr "i387_cw" "ceil")
18113 (set_attr "mode" "DI")])
18116 [(set (match_operand:DI 0 "register_operand" "")
18117 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18119 (use (match_operand:HI 2 "memory_operand" ""))
18120 (use (match_operand:HI 3 "memory_operand" ""))
18121 (clobber (match_operand:DI 4 "memory_operand" ""))
18122 (clobber (match_scratch 5 ""))]
18124 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18125 (use (match_dup 2))
18126 (use (match_dup 3))
18127 (clobber (match_dup 5))])
18128 (set (match_dup 0) (match_dup 4))]
18132 [(set (match_operand:DI 0 "memory_operand" "")
18133 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18135 (use (match_operand:HI 2 "memory_operand" ""))
18136 (use (match_operand:HI 3 "memory_operand" ""))
18137 (clobber (match_operand:DI 4 "memory_operand" ""))
18138 (clobber (match_scratch 5 ""))]
18140 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18141 (use (match_dup 2))
18142 (use (match_dup 3))
18143 (clobber (match_dup 5))])]
18146 (define_insn "fist<mode>2_ceil"
18147 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18148 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18150 (use (match_operand:HI 2 "memory_operand" "m"))
18151 (use (match_operand:HI 3 "memory_operand" "m"))]
18152 "TARGET_USE_FANCY_MATH_387
18153 && flag_unsafe_math_optimizations"
18154 "* return output_fix_trunc (insn, operands, 0);"
18155 [(set_attr "type" "fistp")
18156 (set_attr "i387_cw" "ceil")
18157 (set_attr "mode" "<MODE>")])
18159 (define_insn "fist<mode>2_ceil_with_temp"
18160 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18161 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18163 (use (match_operand:HI 2 "memory_operand" "m,m"))
18164 (use (match_operand:HI 3 "memory_operand" "m,m"))
18165 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18166 "TARGET_USE_FANCY_MATH_387
18167 && flag_unsafe_math_optimizations"
18169 [(set_attr "type" "fistp")
18170 (set_attr "i387_cw" "ceil")
18171 (set_attr "mode" "<MODE>")])
18174 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18175 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18177 (use (match_operand:HI 2 "memory_operand" ""))
18178 (use (match_operand:HI 3 "memory_operand" ""))
18179 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18181 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18183 (use (match_dup 2))
18184 (use (match_dup 3))])
18185 (set (match_dup 0) (match_dup 4))]
18189 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18190 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18192 (use (match_operand:HI 2 "memory_operand" ""))
18193 (use (match_operand:HI 3 "memory_operand" ""))
18194 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18196 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18198 (use (match_dup 2))
18199 (use (match_dup 3))])]
18202 (define_expand "lceilxf<mode>2"
18203 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18204 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18206 (clobber (reg:CC FLAGS_REG))])]
18207 "TARGET_USE_FANCY_MATH_387
18208 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18209 && flag_unsafe_math_optimizations"
18212 (define_expand "lceil<mode>di2"
18213 [(match_operand:DI 0 "nonimmediate_operand" "")
18214 (match_operand:MODEF 1 "register_operand" "")]
18215 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18216 && !flag_trapping_math"
18218 ix86_expand_lfloorceil (operand0, operand1, false);
18222 (define_expand "lceil<mode>si2"
18223 [(match_operand:SI 0 "nonimmediate_operand" "")
18224 (match_operand:MODEF 1 "register_operand" "")]
18225 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18226 && !flag_trapping_math"
18228 ix86_expand_lfloorceil (operand0, operand1, false);
18232 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18233 (define_insn_and_split "frndintxf2_trunc"
18234 [(set (match_operand:XF 0 "register_operand" "")
18235 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18236 UNSPEC_FRNDINT_TRUNC))
18237 (clobber (reg:CC FLAGS_REG))]
18238 "TARGET_USE_FANCY_MATH_387
18239 && flag_unsafe_math_optimizations
18240 && !(reload_completed || reload_in_progress)"
18245 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18247 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18248 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18250 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18251 operands[2], operands[3]));
18254 [(set_attr "type" "frndint")
18255 (set_attr "i387_cw" "trunc")
18256 (set_attr "mode" "XF")])
18258 (define_insn "frndintxf2_trunc_i387"
18259 [(set (match_operand:XF 0 "register_operand" "=f")
18260 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18261 UNSPEC_FRNDINT_TRUNC))
18262 (use (match_operand:HI 2 "memory_operand" "m"))
18263 (use (match_operand:HI 3 "memory_operand" "m"))]
18264 "TARGET_USE_FANCY_MATH_387
18265 && flag_unsafe_math_optimizations"
18266 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18267 [(set_attr "type" "frndint")
18268 (set_attr "i387_cw" "trunc")
18269 (set_attr "mode" "XF")])
18271 (define_expand "btruncxf2"
18272 [(use (match_operand:XF 0 "register_operand" ""))
18273 (use (match_operand:XF 1 "register_operand" ""))]
18274 "TARGET_USE_FANCY_MATH_387
18275 && flag_unsafe_math_optimizations && !optimize_size"
18277 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18281 (define_expand "btrunc<mode>2"
18282 [(use (match_operand:MODEF 0 "register_operand" ""))
18283 (use (match_operand:MODEF 1 "register_operand" ""))]
18284 "(TARGET_USE_FANCY_MATH_387
18285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18286 || TARGET_MIX_SSE_I387)
18287 && flag_unsafe_math_optimizations && !optimize_size)
18288 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18289 && !flag_trapping_math
18290 && (TARGET_ROUND || !optimize_size))"
18292 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18293 && !flag_trapping_math
18294 && (TARGET_ROUND || !optimize_size))
18297 emit_insn (gen_sse4_1_round<mode>2
18298 (operands[0], operands[1], GEN_INT (0x03)));
18299 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18300 ix86_expand_trunc (operand0, operand1);
18302 ix86_expand_truncdf_32 (operand0, operand1);
18306 rtx op0 = gen_reg_rtx (XFmode);
18307 rtx op1 = gen_reg_rtx (XFmode);
18309 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18310 emit_insn (gen_frndintxf2_trunc (op0, op1));
18312 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18317 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18318 (define_insn_and_split "frndintxf2_mask_pm"
18319 [(set (match_operand:XF 0 "register_operand" "")
18320 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18321 UNSPEC_FRNDINT_MASK_PM))
18322 (clobber (reg:CC FLAGS_REG))]
18323 "TARGET_USE_FANCY_MATH_387
18324 && flag_unsafe_math_optimizations
18325 && !(reload_completed || reload_in_progress)"
18330 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18332 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18333 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18335 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18336 operands[2], operands[3]));
18339 [(set_attr "type" "frndint")
18340 (set_attr "i387_cw" "mask_pm")
18341 (set_attr "mode" "XF")])
18343 (define_insn "frndintxf2_mask_pm_i387"
18344 [(set (match_operand:XF 0 "register_operand" "=f")
18345 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18346 UNSPEC_FRNDINT_MASK_PM))
18347 (use (match_operand:HI 2 "memory_operand" "m"))
18348 (use (match_operand:HI 3 "memory_operand" "m"))]
18349 "TARGET_USE_FANCY_MATH_387
18350 && flag_unsafe_math_optimizations"
18351 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18352 [(set_attr "type" "frndint")
18353 (set_attr "i387_cw" "mask_pm")
18354 (set_attr "mode" "XF")])
18356 (define_expand "nearbyintxf2"
18357 [(use (match_operand:XF 0 "register_operand" ""))
18358 (use (match_operand:XF 1 "register_operand" ""))]
18359 "TARGET_USE_FANCY_MATH_387
18360 && flag_unsafe_math_optimizations"
18362 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18367 (define_expand "nearbyint<mode>2"
18368 [(use (match_operand:MODEF 0 "register_operand" ""))
18369 (use (match_operand:MODEF 1 "register_operand" ""))]
18370 "TARGET_USE_FANCY_MATH_387
18371 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18372 || TARGET_MIX_SSE_I387)
18373 && flag_unsafe_math_optimizations"
18375 rtx op0 = gen_reg_rtx (XFmode);
18376 rtx op1 = gen_reg_rtx (XFmode);
18378 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18379 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18381 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18385 (define_insn "fxam<mode>2_i387"
18386 [(set (match_operand:HI 0 "register_operand" "=a")
18388 [(match_operand:X87MODEF 1 "register_operand" "f")]
18390 "TARGET_USE_FANCY_MATH_387"
18391 "fxam\n\tfnstsw\t%0"
18392 [(set_attr "type" "multi")
18393 (set_attr "unit" "i387")
18394 (set_attr "mode" "<MODE>")])
18396 (define_expand "isinf<mode>2"
18397 [(use (match_operand:SI 0 "register_operand" ""))
18398 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18399 "TARGET_USE_FANCY_MATH_387
18400 && TARGET_C99_FUNCTIONS
18401 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18403 rtx mask = GEN_INT (0x45);
18404 rtx val = GEN_INT (0x05);
18408 rtx scratch = gen_reg_rtx (HImode);
18409 rtx res = gen_reg_rtx (QImode);
18411 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18412 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18413 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18414 cond = gen_rtx_fmt_ee (EQ, QImode,
18415 gen_rtx_REG (CCmode, FLAGS_REG),
18417 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18418 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18422 (define_expand "signbit<mode>2"
18423 [(use (match_operand:SI 0 "register_operand" ""))
18424 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18425 "TARGET_USE_FANCY_MATH_387
18426 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18428 rtx mask = GEN_INT (0x0200);
18430 rtx scratch = gen_reg_rtx (HImode);
18432 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18433 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18437 ;; Block operation instructions
18439 (define_expand "movmemsi"
18440 [(use (match_operand:BLK 0 "memory_operand" ""))
18441 (use (match_operand:BLK 1 "memory_operand" ""))
18442 (use (match_operand:SI 2 "nonmemory_operand" ""))
18443 (use (match_operand:SI 3 "const_int_operand" ""))
18444 (use (match_operand:SI 4 "const_int_operand" ""))
18445 (use (match_operand:SI 5 "const_int_operand" ""))]
18448 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18449 operands[4], operands[5]))
18455 (define_expand "movmemdi"
18456 [(use (match_operand:BLK 0 "memory_operand" ""))
18457 (use (match_operand:BLK 1 "memory_operand" ""))
18458 (use (match_operand:DI 2 "nonmemory_operand" ""))
18459 (use (match_operand:DI 3 "const_int_operand" ""))
18460 (use (match_operand:SI 4 "const_int_operand" ""))
18461 (use (match_operand:SI 5 "const_int_operand" ""))]
18464 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18465 operands[4], operands[5]))
18471 ;; Most CPUs don't like single string operations
18472 ;; Handle this case here to simplify previous expander.
18474 (define_expand "strmov"
18475 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18476 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18477 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18478 (clobber (reg:CC FLAGS_REG))])
18479 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18480 (clobber (reg:CC FLAGS_REG))])]
18483 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18485 /* If .md ever supports :P for Pmode, these can be directly
18486 in the pattern above. */
18487 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18488 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18490 /* Can't use this if the user has appropriated esi or edi. */
18491 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18492 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18494 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18495 operands[2], operands[3],
18496 operands[5], operands[6]));
18500 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18503 (define_expand "strmov_singleop"
18504 [(parallel [(set (match_operand 1 "memory_operand" "")
18505 (match_operand 3 "memory_operand" ""))
18506 (set (match_operand 0 "register_operand" "")
18507 (match_operand 4 "" ""))
18508 (set (match_operand 2 "register_operand" "")
18509 (match_operand 5 "" ""))])]
18510 "TARGET_SINGLE_STRINGOP || optimize_size"
18513 (define_insn "*strmovdi_rex_1"
18514 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18515 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18516 (set (match_operand:DI 0 "register_operand" "=D")
18517 (plus:DI (match_dup 2)
18519 (set (match_operand:DI 1 "register_operand" "=S")
18520 (plus:DI (match_dup 3)
18522 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18524 [(set_attr "type" "str")
18525 (set_attr "mode" "DI")
18526 (set_attr "memory" "both")])
18528 (define_insn "*strmovsi_1"
18529 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18530 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18531 (set (match_operand:SI 0 "register_operand" "=D")
18532 (plus:SI (match_dup 2)
18534 (set (match_operand:SI 1 "register_operand" "=S")
18535 (plus:SI (match_dup 3)
18537 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18539 [(set_attr "type" "str")
18540 (set_attr "mode" "SI")
18541 (set_attr "memory" "both")])
18543 (define_insn "*strmovsi_rex_1"
18544 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18545 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18546 (set (match_operand:DI 0 "register_operand" "=D")
18547 (plus:DI (match_dup 2)
18549 (set (match_operand:DI 1 "register_operand" "=S")
18550 (plus:DI (match_dup 3)
18552 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18554 [(set_attr "type" "str")
18555 (set_attr "mode" "SI")
18556 (set_attr "memory" "both")])
18558 (define_insn "*strmovhi_1"
18559 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18560 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18561 (set (match_operand:SI 0 "register_operand" "=D")
18562 (plus:SI (match_dup 2)
18564 (set (match_operand:SI 1 "register_operand" "=S")
18565 (plus:SI (match_dup 3)
18567 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18569 [(set_attr "type" "str")
18570 (set_attr "memory" "both")
18571 (set_attr "mode" "HI")])
18573 (define_insn "*strmovhi_rex_1"
18574 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18575 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18576 (set (match_operand:DI 0 "register_operand" "=D")
18577 (plus:DI (match_dup 2)
18579 (set (match_operand:DI 1 "register_operand" "=S")
18580 (plus:DI (match_dup 3)
18582 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18584 [(set_attr "type" "str")
18585 (set_attr "memory" "both")
18586 (set_attr "mode" "HI")])
18588 (define_insn "*strmovqi_1"
18589 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18590 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18591 (set (match_operand:SI 0 "register_operand" "=D")
18592 (plus:SI (match_dup 2)
18594 (set (match_operand:SI 1 "register_operand" "=S")
18595 (plus:SI (match_dup 3)
18597 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18599 [(set_attr "type" "str")
18600 (set_attr "memory" "both")
18601 (set_attr "mode" "QI")])
18603 (define_insn "*strmovqi_rex_1"
18604 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18605 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18606 (set (match_operand:DI 0 "register_operand" "=D")
18607 (plus:DI (match_dup 2)
18609 (set (match_operand:DI 1 "register_operand" "=S")
18610 (plus:DI (match_dup 3)
18612 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18614 [(set_attr "type" "str")
18615 (set_attr "memory" "both")
18616 (set_attr "mode" "QI")])
18618 (define_expand "rep_mov"
18619 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18620 (set (match_operand 0 "register_operand" "")
18621 (match_operand 5 "" ""))
18622 (set (match_operand 2 "register_operand" "")
18623 (match_operand 6 "" ""))
18624 (set (match_operand 1 "memory_operand" "")
18625 (match_operand 3 "memory_operand" ""))
18626 (use (match_dup 4))])]
18630 (define_insn "*rep_movdi_rex64"
18631 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18632 (set (match_operand:DI 0 "register_operand" "=D")
18633 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18635 (match_operand:DI 3 "register_operand" "0")))
18636 (set (match_operand:DI 1 "register_operand" "=S")
18637 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18638 (match_operand:DI 4 "register_operand" "1")))
18639 (set (mem:BLK (match_dup 3))
18640 (mem:BLK (match_dup 4)))
18641 (use (match_dup 5))]
18644 [(set_attr "type" "str")
18645 (set_attr "prefix_rep" "1")
18646 (set_attr "memory" "both")
18647 (set_attr "mode" "DI")])
18649 (define_insn "*rep_movsi"
18650 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18651 (set (match_operand:SI 0 "register_operand" "=D")
18652 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18654 (match_operand:SI 3 "register_operand" "0")))
18655 (set (match_operand:SI 1 "register_operand" "=S")
18656 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18657 (match_operand:SI 4 "register_operand" "1")))
18658 (set (mem:BLK (match_dup 3))
18659 (mem:BLK (match_dup 4)))
18660 (use (match_dup 5))]
18663 [(set_attr "type" "str")
18664 (set_attr "prefix_rep" "1")
18665 (set_attr "memory" "both")
18666 (set_attr "mode" "SI")])
18668 (define_insn "*rep_movsi_rex64"
18669 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18670 (set (match_operand:DI 0 "register_operand" "=D")
18671 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18673 (match_operand:DI 3 "register_operand" "0")))
18674 (set (match_operand:DI 1 "register_operand" "=S")
18675 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18676 (match_operand:DI 4 "register_operand" "1")))
18677 (set (mem:BLK (match_dup 3))
18678 (mem:BLK (match_dup 4)))
18679 (use (match_dup 5))]
18682 [(set_attr "type" "str")
18683 (set_attr "prefix_rep" "1")
18684 (set_attr "memory" "both")
18685 (set_attr "mode" "SI")])
18687 (define_insn "*rep_movqi"
18688 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18689 (set (match_operand:SI 0 "register_operand" "=D")
18690 (plus:SI (match_operand:SI 3 "register_operand" "0")
18691 (match_operand:SI 5 "register_operand" "2")))
18692 (set (match_operand:SI 1 "register_operand" "=S")
18693 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18694 (set (mem:BLK (match_dup 3))
18695 (mem:BLK (match_dup 4)))
18696 (use (match_dup 5))]
18699 [(set_attr "type" "str")
18700 (set_attr "prefix_rep" "1")
18701 (set_attr "memory" "both")
18702 (set_attr "mode" "SI")])
18704 (define_insn "*rep_movqi_rex64"
18705 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18706 (set (match_operand:DI 0 "register_operand" "=D")
18707 (plus:DI (match_operand:DI 3 "register_operand" "0")
18708 (match_operand:DI 5 "register_operand" "2")))
18709 (set (match_operand:DI 1 "register_operand" "=S")
18710 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18711 (set (mem:BLK (match_dup 3))
18712 (mem:BLK (match_dup 4)))
18713 (use (match_dup 5))]
18716 [(set_attr "type" "str")
18717 (set_attr "prefix_rep" "1")
18718 (set_attr "memory" "both")
18719 (set_attr "mode" "SI")])
18721 (define_expand "setmemsi"
18722 [(use (match_operand:BLK 0 "memory_operand" ""))
18723 (use (match_operand:SI 1 "nonmemory_operand" ""))
18724 (use (match_operand 2 "const_int_operand" ""))
18725 (use (match_operand 3 "const_int_operand" ""))
18726 (use (match_operand:SI 4 "const_int_operand" ""))
18727 (use (match_operand:SI 5 "const_int_operand" ""))]
18730 if (ix86_expand_setmem (operands[0], operands[1],
18731 operands[2], operands[3],
18732 operands[4], operands[5]))
18738 (define_expand "setmemdi"
18739 [(use (match_operand:BLK 0 "memory_operand" ""))
18740 (use (match_operand:DI 1 "nonmemory_operand" ""))
18741 (use (match_operand 2 "const_int_operand" ""))
18742 (use (match_operand 3 "const_int_operand" ""))
18743 (use (match_operand 4 "const_int_operand" ""))
18744 (use (match_operand 5 "const_int_operand" ""))]
18747 if (ix86_expand_setmem (operands[0], operands[1],
18748 operands[2], operands[3],
18749 operands[4], operands[5]))
18755 ;; Most CPUs don't like single string operations
18756 ;; Handle this case here to simplify previous expander.
18758 (define_expand "strset"
18759 [(set (match_operand 1 "memory_operand" "")
18760 (match_operand 2 "register_operand" ""))
18761 (parallel [(set (match_operand 0 "register_operand" "")
18763 (clobber (reg:CC FLAGS_REG))])]
18766 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18767 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18769 /* If .md ever supports :P for Pmode, this can be directly
18770 in the pattern above. */
18771 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18772 GEN_INT (GET_MODE_SIZE (GET_MODE
18774 if (TARGET_SINGLE_STRINGOP || optimize_size)
18776 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18782 (define_expand "strset_singleop"
18783 [(parallel [(set (match_operand 1 "memory_operand" "")
18784 (match_operand 2 "register_operand" ""))
18785 (set (match_operand 0 "register_operand" "")
18786 (match_operand 3 "" ""))])]
18787 "TARGET_SINGLE_STRINGOP || optimize_size"
18790 (define_insn "*strsetdi_rex_1"
18791 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18792 (match_operand:DI 2 "register_operand" "a"))
18793 (set (match_operand:DI 0 "register_operand" "=D")
18794 (plus:DI (match_dup 1)
18796 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18798 [(set_attr "type" "str")
18799 (set_attr "memory" "store")
18800 (set_attr "mode" "DI")])
18802 (define_insn "*strsetsi_1"
18803 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18804 (match_operand:SI 2 "register_operand" "a"))
18805 (set (match_operand:SI 0 "register_operand" "=D")
18806 (plus:SI (match_dup 1)
18808 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18810 [(set_attr "type" "str")
18811 (set_attr "memory" "store")
18812 (set_attr "mode" "SI")])
18814 (define_insn "*strsetsi_rex_1"
18815 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18816 (match_operand:SI 2 "register_operand" "a"))
18817 (set (match_operand:DI 0 "register_operand" "=D")
18818 (plus:DI (match_dup 1)
18820 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18822 [(set_attr "type" "str")
18823 (set_attr "memory" "store")
18824 (set_attr "mode" "SI")])
18826 (define_insn "*strsethi_1"
18827 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18828 (match_operand:HI 2 "register_operand" "a"))
18829 (set (match_operand:SI 0 "register_operand" "=D")
18830 (plus:SI (match_dup 1)
18832 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18834 [(set_attr "type" "str")
18835 (set_attr "memory" "store")
18836 (set_attr "mode" "HI")])
18838 (define_insn "*strsethi_rex_1"
18839 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18840 (match_operand:HI 2 "register_operand" "a"))
18841 (set (match_operand:DI 0 "register_operand" "=D")
18842 (plus:DI (match_dup 1)
18844 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18846 [(set_attr "type" "str")
18847 (set_attr "memory" "store")
18848 (set_attr "mode" "HI")])
18850 (define_insn "*strsetqi_1"
18851 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18852 (match_operand:QI 2 "register_operand" "a"))
18853 (set (match_operand:SI 0 "register_operand" "=D")
18854 (plus:SI (match_dup 1)
18856 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18858 [(set_attr "type" "str")
18859 (set_attr "memory" "store")
18860 (set_attr "mode" "QI")])
18862 (define_insn "*strsetqi_rex_1"
18863 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18864 (match_operand:QI 2 "register_operand" "a"))
18865 (set (match_operand:DI 0 "register_operand" "=D")
18866 (plus:DI (match_dup 1)
18868 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18870 [(set_attr "type" "str")
18871 (set_attr "memory" "store")
18872 (set_attr "mode" "QI")])
18874 (define_expand "rep_stos"
18875 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18876 (set (match_operand 0 "register_operand" "")
18877 (match_operand 4 "" ""))
18878 (set (match_operand 2 "memory_operand" "") (const_int 0))
18879 (use (match_operand 3 "register_operand" ""))
18880 (use (match_dup 1))])]
18884 (define_insn "*rep_stosdi_rex64"
18885 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18886 (set (match_operand:DI 0 "register_operand" "=D")
18887 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18889 (match_operand:DI 3 "register_operand" "0")))
18890 (set (mem:BLK (match_dup 3))
18892 (use (match_operand:DI 2 "register_operand" "a"))
18893 (use (match_dup 4))]
18896 [(set_attr "type" "str")
18897 (set_attr "prefix_rep" "1")
18898 (set_attr "memory" "store")
18899 (set_attr "mode" "DI")])
18901 (define_insn "*rep_stossi"
18902 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18903 (set (match_operand:SI 0 "register_operand" "=D")
18904 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18906 (match_operand:SI 3 "register_operand" "0")))
18907 (set (mem:BLK (match_dup 3))
18909 (use (match_operand:SI 2 "register_operand" "a"))
18910 (use (match_dup 4))]
18913 [(set_attr "type" "str")
18914 (set_attr "prefix_rep" "1")
18915 (set_attr "memory" "store")
18916 (set_attr "mode" "SI")])
18918 (define_insn "*rep_stossi_rex64"
18919 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18920 (set (match_operand:DI 0 "register_operand" "=D")
18921 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18923 (match_operand:DI 3 "register_operand" "0")))
18924 (set (mem:BLK (match_dup 3))
18926 (use (match_operand:SI 2 "register_operand" "a"))
18927 (use (match_dup 4))]
18930 [(set_attr "type" "str")
18931 (set_attr "prefix_rep" "1")
18932 (set_attr "memory" "store")
18933 (set_attr "mode" "SI")])
18935 (define_insn "*rep_stosqi"
18936 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18937 (set (match_operand:SI 0 "register_operand" "=D")
18938 (plus:SI (match_operand:SI 3 "register_operand" "0")
18939 (match_operand:SI 4 "register_operand" "1")))
18940 (set (mem:BLK (match_dup 3))
18942 (use (match_operand:QI 2 "register_operand" "a"))
18943 (use (match_dup 4))]
18946 [(set_attr "type" "str")
18947 (set_attr "prefix_rep" "1")
18948 (set_attr "memory" "store")
18949 (set_attr "mode" "QI")])
18951 (define_insn "*rep_stosqi_rex64"
18952 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18953 (set (match_operand:DI 0 "register_operand" "=D")
18954 (plus:DI (match_operand:DI 3 "register_operand" "0")
18955 (match_operand:DI 4 "register_operand" "1")))
18956 (set (mem:BLK (match_dup 3))
18958 (use (match_operand:QI 2 "register_operand" "a"))
18959 (use (match_dup 4))]
18962 [(set_attr "type" "str")
18963 (set_attr "prefix_rep" "1")
18964 (set_attr "memory" "store")
18965 (set_attr "mode" "QI")])
18967 (define_expand "cmpstrnsi"
18968 [(set (match_operand:SI 0 "register_operand" "")
18969 (compare:SI (match_operand:BLK 1 "general_operand" "")
18970 (match_operand:BLK 2 "general_operand" "")))
18971 (use (match_operand 3 "general_operand" ""))
18972 (use (match_operand 4 "immediate_operand" ""))]
18973 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18975 rtx addr1, addr2, out, outlow, count, countreg, align;
18977 /* Can't use this if the user has appropriated esi or edi. */
18978 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18983 out = gen_reg_rtx (SImode);
18985 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18986 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18987 if (addr1 != XEXP (operands[1], 0))
18988 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18989 if (addr2 != XEXP (operands[2], 0))
18990 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18992 count = operands[3];
18993 countreg = ix86_zero_extend_to_Pmode (count);
18995 /* %%% Iff we are testing strict equality, we can use known alignment
18996 to good advantage. This may be possible with combine, particularly
18997 once cc0 is dead. */
18998 align = operands[4];
19000 if (CONST_INT_P (count))
19002 if (INTVAL (count) == 0)
19004 emit_move_insn (operands[0], const0_rtx);
19007 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19008 operands[1], operands[2]));
19013 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19015 emit_insn (gen_cmpsi_1 (countreg, countreg));
19016 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19017 operands[1], operands[2]));
19020 outlow = gen_lowpart (QImode, out);
19021 emit_insn (gen_cmpintqi (outlow));
19022 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19024 if (operands[0] != out)
19025 emit_move_insn (operands[0], out);
19030 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19032 (define_expand "cmpintqi"
19033 [(set (match_dup 1)
19034 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19036 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19037 (parallel [(set (match_operand:QI 0 "register_operand" "")
19038 (minus:QI (match_dup 1)
19040 (clobber (reg:CC FLAGS_REG))])]
19042 "operands[1] = gen_reg_rtx (QImode);
19043 operands[2] = gen_reg_rtx (QImode);")
19045 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19046 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19048 (define_expand "cmpstrnqi_nz_1"
19049 [(parallel [(set (reg:CC FLAGS_REG)
19050 (compare:CC (match_operand 4 "memory_operand" "")
19051 (match_operand 5 "memory_operand" "")))
19052 (use (match_operand 2 "register_operand" ""))
19053 (use (match_operand:SI 3 "immediate_operand" ""))
19054 (clobber (match_operand 0 "register_operand" ""))
19055 (clobber (match_operand 1 "register_operand" ""))
19056 (clobber (match_dup 2))])]
19060 (define_insn "*cmpstrnqi_nz_1"
19061 [(set (reg:CC FLAGS_REG)
19062 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19063 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19064 (use (match_operand:SI 6 "register_operand" "2"))
19065 (use (match_operand:SI 3 "immediate_operand" "i"))
19066 (clobber (match_operand:SI 0 "register_operand" "=S"))
19067 (clobber (match_operand:SI 1 "register_operand" "=D"))
19068 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19071 [(set_attr "type" "str")
19072 (set_attr "mode" "QI")
19073 (set_attr "prefix_rep" "1")])
19075 (define_insn "*cmpstrnqi_nz_rex_1"
19076 [(set (reg:CC FLAGS_REG)
19077 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19078 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19079 (use (match_operand:DI 6 "register_operand" "2"))
19080 (use (match_operand:SI 3 "immediate_operand" "i"))
19081 (clobber (match_operand:DI 0 "register_operand" "=S"))
19082 (clobber (match_operand:DI 1 "register_operand" "=D"))
19083 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19086 [(set_attr "type" "str")
19087 (set_attr "mode" "QI")
19088 (set_attr "prefix_rep" "1")])
19090 ;; The same, but the count is not known to not be zero.
19092 (define_expand "cmpstrnqi_1"
19093 [(parallel [(set (reg:CC FLAGS_REG)
19094 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19096 (compare:CC (match_operand 4 "memory_operand" "")
19097 (match_operand 5 "memory_operand" ""))
19099 (use (match_operand:SI 3 "immediate_operand" ""))
19100 (use (reg:CC FLAGS_REG))
19101 (clobber (match_operand 0 "register_operand" ""))
19102 (clobber (match_operand 1 "register_operand" ""))
19103 (clobber (match_dup 2))])]
19107 (define_insn "*cmpstrnqi_1"
19108 [(set (reg:CC FLAGS_REG)
19109 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19111 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19112 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19114 (use (match_operand:SI 3 "immediate_operand" "i"))
19115 (use (reg:CC FLAGS_REG))
19116 (clobber (match_operand:SI 0 "register_operand" "=S"))
19117 (clobber (match_operand:SI 1 "register_operand" "=D"))
19118 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19121 [(set_attr "type" "str")
19122 (set_attr "mode" "QI")
19123 (set_attr "prefix_rep" "1")])
19125 (define_insn "*cmpstrnqi_rex_1"
19126 [(set (reg:CC FLAGS_REG)
19127 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19129 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19130 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19132 (use (match_operand:SI 3 "immediate_operand" "i"))
19133 (use (reg:CC FLAGS_REG))
19134 (clobber (match_operand:DI 0 "register_operand" "=S"))
19135 (clobber (match_operand:DI 1 "register_operand" "=D"))
19136 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19139 [(set_attr "type" "str")
19140 (set_attr "mode" "QI")
19141 (set_attr "prefix_rep" "1")])
19143 (define_expand "strlensi"
19144 [(set (match_operand:SI 0 "register_operand" "")
19145 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19146 (match_operand:QI 2 "immediate_operand" "")
19147 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19150 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19156 (define_expand "strlendi"
19157 [(set (match_operand:DI 0 "register_operand" "")
19158 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19159 (match_operand:QI 2 "immediate_operand" "")
19160 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19163 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19169 (define_expand "strlenqi_1"
19170 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19171 (clobber (match_operand 1 "register_operand" ""))
19172 (clobber (reg:CC FLAGS_REG))])]
19176 (define_insn "*strlenqi_1"
19177 [(set (match_operand:SI 0 "register_operand" "=&c")
19178 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19179 (match_operand:QI 2 "register_operand" "a")
19180 (match_operand:SI 3 "immediate_operand" "i")
19181 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19182 (clobber (match_operand:SI 1 "register_operand" "=D"))
19183 (clobber (reg:CC FLAGS_REG))]
19186 [(set_attr "type" "str")
19187 (set_attr "mode" "QI")
19188 (set_attr "prefix_rep" "1")])
19190 (define_insn "*strlenqi_rex_1"
19191 [(set (match_operand:DI 0 "register_operand" "=&c")
19192 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19193 (match_operand:QI 2 "register_operand" "a")
19194 (match_operand:DI 3 "immediate_operand" "i")
19195 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19196 (clobber (match_operand:DI 1 "register_operand" "=D"))
19197 (clobber (reg:CC FLAGS_REG))]
19200 [(set_attr "type" "str")
19201 (set_attr "mode" "QI")
19202 (set_attr "prefix_rep" "1")])
19204 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19205 ;; handled in combine, but it is not currently up to the task.
19206 ;; When used for their truth value, the cmpstrn* expanders generate
19215 ;; The intermediate three instructions are unnecessary.
19217 ;; This one handles cmpstrn*_nz_1...
19220 (set (reg:CC FLAGS_REG)
19221 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19222 (mem:BLK (match_operand 5 "register_operand" ""))))
19223 (use (match_operand 6 "register_operand" ""))
19224 (use (match_operand:SI 3 "immediate_operand" ""))
19225 (clobber (match_operand 0 "register_operand" ""))
19226 (clobber (match_operand 1 "register_operand" ""))
19227 (clobber (match_operand 2 "register_operand" ""))])
19228 (set (match_operand:QI 7 "register_operand" "")
19229 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19230 (set (match_operand:QI 8 "register_operand" "")
19231 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19232 (set (reg FLAGS_REG)
19233 (compare (match_dup 7) (match_dup 8)))
19235 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19237 (set (reg:CC FLAGS_REG)
19238 (compare:CC (mem:BLK (match_dup 4))
19239 (mem:BLK (match_dup 5))))
19240 (use (match_dup 6))
19241 (use (match_dup 3))
19242 (clobber (match_dup 0))
19243 (clobber (match_dup 1))
19244 (clobber (match_dup 2))])]
19247 ;; ...and this one handles cmpstrn*_1.
19250 (set (reg:CC FLAGS_REG)
19251 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19253 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19254 (mem:BLK (match_operand 5 "register_operand" "")))
19256 (use (match_operand:SI 3 "immediate_operand" ""))
19257 (use (reg:CC FLAGS_REG))
19258 (clobber (match_operand 0 "register_operand" ""))
19259 (clobber (match_operand 1 "register_operand" ""))
19260 (clobber (match_operand 2 "register_operand" ""))])
19261 (set (match_operand:QI 7 "register_operand" "")
19262 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19263 (set (match_operand:QI 8 "register_operand" "")
19264 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19265 (set (reg FLAGS_REG)
19266 (compare (match_dup 7) (match_dup 8)))
19268 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19270 (set (reg:CC FLAGS_REG)
19271 (if_then_else:CC (ne (match_dup 6)
19273 (compare:CC (mem:BLK (match_dup 4))
19274 (mem:BLK (match_dup 5)))
19276 (use (match_dup 3))
19277 (use (reg:CC FLAGS_REG))
19278 (clobber (match_dup 0))
19279 (clobber (match_dup 1))
19280 (clobber (match_dup 2))])]
19285 ;; Conditional move instructions.
19287 (define_expand "movdicc"
19288 [(set (match_operand:DI 0 "register_operand" "")
19289 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19290 (match_operand:DI 2 "general_operand" "")
19291 (match_operand:DI 3 "general_operand" "")))]
19293 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19295 (define_insn "x86_movdicc_0_m1_rex64"
19296 [(set (match_operand:DI 0 "register_operand" "=r")
19297 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19300 (clobber (reg:CC FLAGS_REG))]
19303 ; Since we don't have the proper number of operands for an alu insn,
19304 ; fill in all the blanks.
19305 [(set_attr "type" "alu")
19306 (set_attr "pent_pair" "pu")
19307 (set_attr "memory" "none")
19308 (set_attr "imm_disp" "false")
19309 (set_attr "mode" "DI")
19310 (set_attr "length_immediate" "0")])
19312 (define_insn "*x86_movdicc_0_m1_se"
19313 [(set (match_operand:DI 0 "register_operand" "=r")
19314 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19317 (clobber (reg:CC FLAGS_REG))]
19320 [(set_attr "type" "alu")
19321 (set_attr "pent_pair" "pu")
19322 (set_attr "memory" "none")
19323 (set_attr "imm_disp" "false")
19324 (set_attr "mode" "DI")
19325 (set_attr "length_immediate" "0")])
19327 (define_insn "*movdicc_c_rex64"
19328 [(set (match_operand:DI 0 "register_operand" "=r,r")
19329 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19330 [(reg FLAGS_REG) (const_int 0)])
19331 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19332 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19333 "TARGET_64BIT && TARGET_CMOVE
19334 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19336 cmov%O2%C1\t{%2, %0|%0, %2}
19337 cmov%O2%c1\t{%3, %0|%0, %3}"
19338 [(set_attr "type" "icmov")
19339 (set_attr "mode" "DI")])
19341 (define_expand "movsicc"
19342 [(set (match_operand:SI 0 "register_operand" "")
19343 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19344 (match_operand:SI 2 "general_operand" "")
19345 (match_operand:SI 3 "general_operand" "")))]
19347 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19349 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19350 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19351 ;; So just document what we're doing explicitly.
19353 (define_insn "x86_movsicc_0_m1"
19354 [(set (match_operand:SI 0 "register_operand" "=r")
19355 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19358 (clobber (reg:CC FLAGS_REG))]
19361 ; Since we don't have the proper number of operands for an alu insn,
19362 ; fill in all the blanks.
19363 [(set_attr "type" "alu")
19364 (set_attr "pent_pair" "pu")
19365 (set_attr "memory" "none")
19366 (set_attr "imm_disp" "false")
19367 (set_attr "mode" "SI")
19368 (set_attr "length_immediate" "0")])
19370 (define_insn "*x86_movsicc_0_m1_se"
19371 [(set (match_operand:SI 0 "register_operand" "=r")
19372 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19375 (clobber (reg:CC FLAGS_REG))]
19378 [(set_attr "type" "alu")
19379 (set_attr "pent_pair" "pu")
19380 (set_attr "memory" "none")
19381 (set_attr "imm_disp" "false")
19382 (set_attr "mode" "SI")
19383 (set_attr "length_immediate" "0")])
19385 (define_insn "*movsicc_noc"
19386 [(set (match_operand:SI 0 "register_operand" "=r,r")
19387 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19388 [(reg FLAGS_REG) (const_int 0)])
19389 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19390 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19392 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19394 cmov%O2%C1\t{%2, %0|%0, %2}
19395 cmov%O2%c1\t{%3, %0|%0, %3}"
19396 [(set_attr "type" "icmov")
19397 (set_attr "mode" "SI")])
19399 (define_expand "movhicc"
19400 [(set (match_operand:HI 0 "register_operand" "")
19401 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19402 (match_operand:HI 2 "general_operand" "")
19403 (match_operand:HI 3 "general_operand" "")))]
19404 "TARGET_HIMODE_MATH"
19405 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19407 (define_insn "*movhicc_noc"
19408 [(set (match_operand:HI 0 "register_operand" "=r,r")
19409 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19410 [(reg FLAGS_REG) (const_int 0)])
19411 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19412 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19414 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19416 cmov%O2%C1\t{%2, %0|%0, %2}
19417 cmov%O2%c1\t{%3, %0|%0, %3}"
19418 [(set_attr "type" "icmov")
19419 (set_attr "mode" "HI")])
19421 (define_expand "movqicc"
19422 [(set (match_operand:QI 0 "register_operand" "")
19423 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19424 (match_operand:QI 2 "general_operand" "")
19425 (match_operand:QI 3 "general_operand" "")))]
19426 "TARGET_QIMODE_MATH"
19427 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19429 (define_insn_and_split "*movqicc_noc"
19430 [(set (match_operand:QI 0 "register_operand" "=r,r")
19431 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19432 [(match_operand 4 "flags_reg_operand" "")
19434 (match_operand:QI 2 "register_operand" "r,0")
19435 (match_operand:QI 3 "register_operand" "0,r")))]
19436 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19438 "&& reload_completed"
19439 [(set (match_dup 0)
19440 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19443 "operands[0] = gen_lowpart (SImode, operands[0]);
19444 operands[2] = gen_lowpart (SImode, operands[2]);
19445 operands[3] = gen_lowpart (SImode, operands[3]);"
19446 [(set_attr "type" "icmov")
19447 (set_attr "mode" "SI")])
19449 (define_expand "mov<mode>cc"
19450 [(set (match_operand:X87MODEF 0 "register_operand" "")
19451 (if_then_else:X87MODEF
19452 (match_operand 1 "comparison_operator" "")
19453 (match_operand:X87MODEF 2 "register_operand" "")
19454 (match_operand:X87MODEF 3 "register_operand" "")))]
19455 "(TARGET_80387 && TARGET_CMOVE)
19456 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19457 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19459 (define_insn "*movsfcc_1_387"
19460 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19461 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19462 [(reg FLAGS_REG) (const_int 0)])
19463 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19464 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19465 "TARGET_80387 && TARGET_CMOVE
19466 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19468 fcmov%F1\t{%2, %0|%0, %2}
19469 fcmov%f1\t{%3, %0|%0, %3}
19470 cmov%O2%C1\t{%2, %0|%0, %2}
19471 cmov%O2%c1\t{%3, %0|%0, %3}"
19472 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19473 (set_attr "mode" "SF,SF,SI,SI")])
19475 (define_insn "*movdfcc_1"
19476 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19477 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19478 [(reg FLAGS_REG) (const_int 0)])
19479 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19480 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19481 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19482 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19484 fcmov%F1\t{%2, %0|%0, %2}
19485 fcmov%f1\t{%3, %0|%0, %3}
19488 [(set_attr "type" "fcmov,fcmov,multi,multi")
19489 (set_attr "mode" "DF")])
19491 (define_insn "*movdfcc_1_rex64"
19492 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19493 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19494 [(reg FLAGS_REG) (const_int 0)])
19495 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19496 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19497 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19498 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19500 fcmov%F1\t{%2, %0|%0, %2}
19501 fcmov%f1\t{%3, %0|%0, %3}
19502 cmov%O2%C1\t{%2, %0|%0, %2}
19503 cmov%O2%c1\t{%3, %0|%0, %3}"
19504 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19505 (set_attr "mode" "DF")])
19508 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19509 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19510 [(match_operand 4 "flags_reg_operand" "")
19512 (match_operand:DF 2 "nonimmediate_operand" "")
19513 (match_operand:DF 3 "nonimmediate_operand" "")))]
19514 "!TARGET_64BIT && reload_completed"
19515 [(set (match_dup 2)
19516 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19520 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19523 "split_di (operands+2, 1, operands+5, operands+6);
19524 split_di (operands+3, 1, operands+7, operands+8);
19525 split_di (operands, 1, operands+2, operands+3);")
19527 (define_insn "*movxfcc_1"
19528 [(set (match_operand:XF 0 "register_operand" "=f,f")
19529 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19530 [(reg FLAGS_REG) (const_int 0)])
19531 (match_operand:XF 2 "register_operand" "f,0")
19532 (match_operand:XF 3 "register_operand" "0,f")))]
19533 "TARGET_80387 && TARGET_CMOVE"
19535 fcmov%F1\t{%2, %0|%0, %2}
19536 fcmov%f1\t{%3, %0|%0, %3}"
19537 [(set_attr "type" "fcmov")
19538 (set_attr "mode" "XF")])
19540 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19541 ;; the scalar versions to have only XMM registers as operands.
19543 ;; SSE5 conditional move
19544 (define_insn "*sse5_pcmov_<mode>"
19545 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19546 (if_then_else:MODEF
19547 (match_operand:MODEF 1 "register_operand" "x,0")
19548 (match_operand:MODEF 2 "register_operand" "0,x")
19549 (match_operand:MODEF 3 "register_operand" "x,x")))]
19550 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19551 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19552 [(set_attr "type" "sse4arg")])
19554 ;; These versions of the min/max patterns are intentionally ignorant of
19555 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19556 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19557 ;; are undefined in this condition, we're certain this is correct.
19559 (define_insn "<code><mode>3"
19560 [(set (match_operand:MODEF 0 "register_operand" "=x")
19562 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19563 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19564 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19565 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19566 [(set_attr "type" "sseadd")
19567 (set_attr "mode" "<MODE>")])
19569 ;; These versions of the min/max patterns implement exactly the operations
19570 ;; min = (op1 < op2 ? op1 : op2)
19571 ;; max = (!(op1 < op2) ? op1 : op2)
19572 ;; Their operands are not commutative, and thus they may be used in the
19573 ;; presence of -0.0 and NaN.
19575 (define_insn "*ieee_smin<mode>3"
19576 [(set (match_operand:MODEF 0 "register_operand" "=x")
19578 [(match_operand:MODEF 1 "register_operand" "0")
19579 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19581 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19582 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19583 [(set_attr "type" "sseadd")
19584 (set_attr "mode" "<MODE>")])
19586 (define_insn "*ieee_smax<mode>3"
19587 [(set (match_operand:MODEF 0 "register_operand" "=x")
19589 [(match_operand:MODEF 1 "register_operand" "0")
19590 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19592 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19593 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19594 [(set_attr "type" "sseadd")
19595 (set_attr "mode" "<MODE>")])
19597 ;; Make two stack loads independent:
19599 ;; fld %st(0) -> fld bb
19600 ;; fmul bb fmul %st(1), %st
19602 ;; Actually we only match the last two instructions for simplicity.
19604 [(set (match_operand 0 "fp_register_operand" "")
19605 (match_operand 1 "fp_register_operand" ""))
19607 (match_operator 2 "binary_fp_operator"
19609 (match_operand 3 "memory_operand" "")]))]
19610 "REGNO (operands[0]) != REGNO (operands[1])"
19611 [(set (match_dup 0) (match_dup 3))
19612 (set (match_dup 0) (match_dup 4))]
19614 ;; The % modifier is not operational anymore in peephole2's, so we have to
19615 ;; swap the operands manually in the case of addition and multiplication.
19616 "if (COMMUTATIVE_ARITH_P (operands[2]))
19617 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19618 operands[0], operands[1]);
19620 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19621 operands[1], operands[0]);")
19623 ;; Conditional addition patterns
19624 (define_expand "addqicc"
19625 [(match_operand:QI 0 "register_operand" "")
19626 (match_operand 1 "comparison_operator" "")
19627 (match_operand:QI 2 "register_operand" "")
19628 (match_operand:QI 3 "const_int_operand" "")]
19630 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19632 (define_expand "addhicc"
19633 [(match_operand:HI 0 "register_operand" "")
19634 (match_operand 1 "comparison_operator" "")
19635 (match_operand:HI 2 "register_operand" "")
19636 (match_operand:HI 3 "const_int_operand" "")]
19638 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19640 (define_expand "addsicc"
19641 [(match_operand:SI 0 "register_operand" "")
19642 (match_operand 1 "comparison_operator" "")
19643 (match_operand:SI 2 "register_operand" "")
19644 (match_operand:SI 3 "const_int_operand" "")]
19646 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19648 (define_expand "adddicc"
19649 [(match_operand:DI 0 "register_operand" "")
19650 (match_operand 1 "comparison_operator" "")
19651 (match_operand:DI 2 "register_operand" "")
19652 (match_operand:DI 3 "const_int_operand" "")]
19654 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19657 ;; Misc patterns (?)
19659 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19660 ;; Otherwise there will be nothing to keep
19662 ;; [(set (reg ebp) (reg esp))]
19663 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19664 ;; (clobber (eflags)]
19665 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19667 ;; in proper program order.
19668 (define_insn "pro_epilogue_adjust_stack_1"
19669 [(set (match_operand:SI 0 "register_operand" "=r,r")
19670 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19671 (match_operand:SI 2 "immediate_operand" "i,i")))
19672 (clobber (reg:CC FLAGS_REG))
19673 (clobber (mem:BLK (scratch)))]
19676 switch (get_attr_type (insn))
19679 return "mov{l}\t{%1, %0|%0, %1}";
19682 if (CONST_INT_P (operands[2])
19683 && (INTVAL (operands[2]) == 128
19684 || (INTVAL (operands[2]) < 0
19685 && INTVAL (operands[2]) != -128)))
19687 operands[2] = GEN_INT (-INTVAL (operands[2]));
19688 return "sub{l}\t{%2, %0|%0, %2}";
19690 return "add{l}\t{%2, %0|%0, %2}";
19693 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19694 return "lea{l}\t{%a2, %0|%0, %a2}";
19697 gcc_unreachable ();
19700 [(set (attr "type")
19701 (cond [(eq_attr "alternative" "0")
19702 (const_string "alu")
19703 (match_operand:SI 2 "const0_operand" "")
19704 (const_string "imov")
19706 (const_string "lea")))
19707 (set_attr "mode" "SI")])
19709 (define_insn "pro_epilogue_adjust_stack_rex64"
19710 [(set (match_operand:DI 0 "register_operand" "=r,r")
19711 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19712 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19713 (clobber (reg:CC FLAGS_REG))
19714 (clobber (mem:BLK (scratch)))]
19717 switch (get_attr_type (insn))
19720 return "mov{q}\t{%1, %0|%0, %1}";
19723 if (CONST_INT_P (operands[2])
19724 /* Avoid overflows. */
19725 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19726 && (INTVAL (operands[2]) == 128
19727 || (INTVAL (operands[2]) < 0
19728 && INTVAL (operands[2]) != -128)))
19730 operands[2] = GEN_INT (-INTVAL (operands[2]));
19731 return "sub{q}\t{%2, %0|%0, %2}";
19733 return "add{q}\t{%2, %0|%0, %2}";
19736 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19737 return "lea{q}\t{%a2, %0|%0, %a2}";
19740 gcc_unreachable ();
19743 [(set (attr "type")
19744 (cond [(eq_attr "alternative" "0")
19745 (const_string "alu")
19746 (match_operand:DI 2 "const0_operand" "")
19747 (const_string "imov")
19749 (const_string "lea")))
19750 (set_attr "mode" "DI")])
19752 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19753 [(set (match_operand:DI 0 "register_operand" "=r,r")
19754 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19755 (match_operand:DI 3 "immediate_operand" "i,i")))
19756 (use (match_operand:DI 2 "register_operand" "r,r"))
19757 (clobber (reg:CC FLAGS_REG))
19758 (clobber (mem:BLK (scratch)))]
19761 switch (get_attr_type (insn))
19764 return "add{q}\t{%2, %0|%0, %2}";
19767 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19768 return "lea{q}\t{%a2, %0|%0, %a2}";
19771 gcc_unreachable ();
19774 [(set_attr "type" "alu,lea")
19775 (set_attr "mode" "DI")])
19777 (define_insn "allocate_stack_worker_32"
19778 [(set (match_operand:SI 0 "register_operand" "+a")
19779 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19780 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19781 (clobber (reg:CC FLAGS_REG))]
19782 "!TARGET_64BIT && TARGET_STACK_PROBE"
19784 [(set_attr "type" "multi")
19785 (set_attr "length" "5")])
19787 (define_insn "allocate_stack_worker_64"
19788 [(set (match_operand:DI 0 "register_operand" "=a")
19789 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19790 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19791 (clobber (reg:DI R10_REG))
19792 (clobber (reg:DI R11_REG))
19793 (clobber (reg:CC FLAGS_REG))]
19794 "TARGET_64BIT && TARGET_STACK_PROBE"
19796 [(set_attr "type" "multi")
19797 (set_attr "length" "5")])
19799 (define_expand "allocate_stack"
19800 [(match_operand 0 "register_operand" "")
19801 (match_operand 1 "general_operand" "")]
19802 "TARGET_STACK_PROBE"
19806 #ifndef CHECK_STACK_LIMIT
19807 #define CHECK_STACK_LIMIT 0
19810 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19811 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19813 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19814 stack_pointer_rtx, 0, OPTAB_DIRECT);
19815 if (x != stack_pointer_rtx)
19816 emit_move_insn (stack_pointer_rtx, x);
19820 x = copy_to_mode_reg (Pmode, operands[1]);
19822 x = gen_allocate_stack_worker_64 (x);
19824 x = gen_allocate_stack_worker_32 (x);
19828 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19832 (define_expand "builtin_setjmp_receiver"
19833 [(label_ref (match_operand 0 "" ""))]
19834 "!TARGET_64BIT && flag_pic"
19839 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19840 rtx label_rtx = gen_label_rtx ();
19841 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19842 xops[0] = xops[1] = picreg;
19843 xops[2] = gen_rtx_CONST (SImode,
19844 gen_rtx_MINUS (SImode,
19845 gen_rtx_LABEL_REF (SImode, label_rtx),
19846 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19847 ix86_expand_binary_operator (MINUS, SImode, xops);
19850 emit_insn (gen_set_got (pic_offset_table_rtx));
19854 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19857 [(set (match_operand 0 "register_operand" "")
19858 (match_operator 3 "promotable_binary_operator"
19859 [(match_operand 1 "register_operand" "")
19860 (match_operand 2 "aligned_operand" "")]))
19861 (clobber (reg:CC FLAGS_REG))]
19862 "! TARGET_PARTIAL_REG_STALL && reload_completed
19863 && ((GET_MODE (operands[0]) == HImode
19864 && ((!optimize_size && !TARGET_FAST_PREFIX)
19865 /* ??? next two lines just !satisfies_constraint_K (...) */
19866 || !CONST_INT_P (operands[2])
19867 || satisfies_constraint_K (operands[2])))
19868 || (GET_MODE (operands[0]) == QImode
19869 && (TARGET_PROMOTE_QImode || optimize_size)))"
19870 [(parallel [(set (match_dup 0)
19871 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19872 (clobber (reg:CC FLAGS_REG))])]
19873 "operands[0] = gen_lowpart (SImode, operands[0]);
19874 operands[1] = gen_lowpart (SImode, operands[1]);
19875 if (GET_CODE (operands[3]) != ASHIFT)
19876 operands[2] = gen_lowpart (SImode, operands[2]);
19877 PUT_MODE (operands[3], SImode);")
19879 ; Promote the QImode tests, as i386 has encoding of the AND
19880 ; instruction with 32-bit sign-extended immediate and thus the
19881 ; instruction size is unchanged, except in the %eax case for
19882 ; which it is increased by one byte, hence the ! optimize_size.
19884 [(set (match_operand 0 "flags_reg_operand" "")
19885 (match_operator 2 "compare_operator"
19886 [(and (match_operand 3 "aligned_operand" "")
19887 (match_operand 4 "const_int_operand" ""))
19889 (set (match_operand 1 "register_operand" "")
19890 (and (match_dup 3) (match_dup 4)))]
19891 "! TARGET_PARTIAL_REG_STALL && reload_completed
19893 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19894 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19895 /* Ensure that the operand will remain sign-extended immediate. */
19896 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19897 [(parallel [(set (match_dup 0)
19898 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19901 (and:SI (match_dup 3) (match_dup 4)))])]
19904 = gen_int_mode (INTVAL (operands[4])
19905 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19906 operands[1] = gen_lowpart (SImode, operands[1]);
19907 operands[3] = gen_lowpart (SImode, operands[3]);
19910 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19911 ; the TEST instruction with 32-bit sign-extended immediate and thus
19912 ; the instruction size would at least double, which is not what we
19913 ; want even with ! optimize_size.
19915 [(set (match_operand 0 "flags_reg_operand" "")
19916 (match_operator 1 "compare_operator"
19917 [(and (match_operand:HI 2 "aligned_operand" "")
19918 (match_operand:HI 3 "const_int_operand" ""))
19920 "! TARGET_PARTIAL_REG_STALL && reload_completed
19921 && ! TARGET_FAST_PREFIX
19923 /* Ensure that the operand will remain sign-extended immediate. */
19924 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19925 [(set (match_dup 0)
19926 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19930 = gen_int_mode (INTVAL (operands[3])
19931 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19932 operands[2] = gen_lowpart (SImode, operands[2]);
19936 [(set (match_operand 0 "register_operand" "")
19937 (neg (match_operand 1 "register_operand" "")))
19938 (clobber (reg:CC FLAGS_REG))]
19939 "! TARGET_PARTIAL_REG_STALL && reload_completed
19940 && (GET_MODE (operands[0]) == HImode
19941 || (GET_MODE (operands[0]) == QImode
19942 && (TARGET_PROMOTE_QImode || optimize_size)))"
19943 [(parallel [(set (match_dup 0)
19944 (neg:SI (match_dup 1)))
19945 (clobber (reg:CC FLAGS_REG))])]
19946 "operands[0] = gen_lowpart (SImode, operands[0]);
19947 operands[1] = gen_lowpart (SImode, operands[1]);")
19950 [(set (match_operand 0 "register_operand" "")
19951 (not (match_operand 1 "register_operand" "")))]
19952 "! TARGET_PARTIAL_REG_STALL && reload_completed
19953 && (GET_MODE (operands[0]) == HImode
19954 || (GET_MODE (operands[0]) == QImode
19955 && (TARGET_PROMOTE_QImode || optimize_size)))"
19956 [(set (match_dup 0)
19957 (not:SI (match_dup 1)))]
19958 "operands[0] = gen_lowpart (SImode, operands[0]);
19959 operands[1] = gen_lowpart (SImode, operands[1]);")
19962 [(set (match_operand 0 "register_operand" "")
19963 (if_then_else (match_operator 1 "comparison_operator"
19964 [(reg FLAGS_REG) (const_int 0)])
19965 (match_operand 2 "register_operand" "")
19966 (match_operand 3 "register_operand" "")))]
19967 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19968 && (GET_MODE (operands[0]) == HImode
19969 || (GET_MODE (operands[0]) == QImode
19970 && (TARGET_PROMOTE_QImode || optimize_size)))"
19971 [(set (match_dup 0)
19972 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19973 "operands[0] = gen_lowpart (SImode, operands[0]);
19974 operands[2] = gen_lowpart (SImode, operands[2]);
19975 operands[3] = gen_lowpart (SImode, operands[3]);")
19978 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19979 ;; transform a complex memory operation into two memory to register operations.
19981 ;; Don't push memory operands
19983 [(set (match_operand:SI 0 "push_operand" "")
19984 (match_operand:SI 1 "memory_operand" ""))
19985 (match_scratch:SI 2 "r")]
19986 "!optimize_size && !TARGET_PUSH_MEMORY
19987 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19988 [(set (match_dup 2) (match_dup 1))
19989 (set (match_dup 0) (match_dup 2))]
19993 [(set (match_operand:DI 0 "push_operand" "")
19994 (match_operand:DI 1 "memory_operand" ""))
19995 (match_scratch:DI 2 "r")]
19996 "!optimize_size && !TARGET_PUSH_MEMORY
19997 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19998 [(set (match_dup 2) (match_dup 1))
19999 (set (match_dup 0) (match_dup 2))]
20002 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20005 [(set (match_operand:SF 0 "push_operand" "")
20006 (match_operand:SF 1 "memory_operand" ""))
20007 (match_scratch:SF 2 "r")]
20008 "!optimize_size && !TARGET_PUSH_MEMORY
20009 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20010 [(set (match_dup 2) (match_dup 1))
20011 (set (match_dup 0) (match_dup 2))]
20015 [(set (match_operand:HI 0 "push_operand" "")
20016 (match_operand:HI 1 "memory_operand" ""))
20017 (match_scratch:HI 2 "r")]
20018 "!optimize_size && !TARGET_PUSH_MEMORY
20019 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20020 [(set (match_dup 2) (match_dup 1))
20021 (set (match_dup 0) (match_dup 2))]
20025 [(set (match_operand:QI 0 "push_operand" "")
20026 (match_operand:QI 1 "memory_operand" ""))
20027 (match_scratch:QI 2 "q")]
20028 "!optimize_size && !TARGET_PUSH_MEMORY
20029 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20030 [(set (match_dup 2) (match_dup 1))
20031 (set (match_dup 0) (match_dup 2))]
20034 ;; Don't move an immediate directly to memory when the instruction
20037 [(match_scratch:SI 1 "r")
20038 (set (match_operand:SI 0 "memory_operand" "")
20041 && ! TARGET_USE_MOV0
20042 && TARGET_SPLIT_LONG_MOVES
20043 && get_attr_length (insn) >= ix86_cost->large_insn
20044 && peep2_regno_dead_p (0, FLAGS_REG)"
20045 [(parallel [(set (match_dup 1) (const_int 0))
20046 (clobber (reg:CC FLAGS_REG))])
20047 (set (match_dup 0) (match_dup 1))]
20051 [(match_scratch:HI 1 "r")
20052 (set (match_operand:HI 0 "memory_operand" "")
20055 && ! TARGET_USE_MOV0
20056 && TARGET_SPLIT_LONG_MOVES
20057 && get_attr_length (insn) >= ix86_cost->large_insn
20058 && peep2_regno_dead_p (0, FLAGS_REG)"
20059 [(parallel [(set (match_dup 2) (const_int 0))
20060 (clobber (reg:CC FLAGS_REG))])
20061 (set (match_dup 0) (match_dup 1))]
20062 "operands[2] = gen_lowpart (SImode, operands[1]);")
20065 [(match_scratch:QI 1 "q")
20066 (set (match_operand:QI 0 "memory_operand" "")
20069 && ! TARGET_USE_MOV0
20070 && TARGET_SPLIT_LONG_MOVES
20071 && get_attr_length (insn) >= ix86_cost->large_insn
20072 && peep2_regno_dead_p (0, FLAGS_REG)"
20073 [(parallel [(set (match_dup 2) (const_int 0))
20074 (clobber (reg:CC FLAGS_REG))])
20075 (set (match_dup 0) (match_dup 1))]
20076 "operands[2] = gen_lowpart (SImode, operands[1]);")
20079 [(match_scratch:SI 2 "r")
20080 (set (match_operand:SI 0 "memory_operand" "")
20081 (match_operand:SI 1 "immediate_operand" ""))]
20083 && TARGET_SPLIT_LONG_MOVES
20084 && get_attr_length (insn) >= ix86_cost->large_insn"
20085 [(set (match_dup 2) (match_dup 1))
20086 (set (match_dup 0) (match_dup 2))]
20090 [(match_scratch:HI 2 "r")
20091 (set (match_operand:HI 0 "memory_operand" "")
20092 (match_operand:HI 1 "immediate_operand" ""))]
20094 && TARGET_SPLIT_LONG_MOVES
20095 && get_attr_length (insn) >= ix86_cost->large_insn"
20096 [(set (match_dup 2) (match_dup 1))
20097 (set (match_dup 0) (match_dup 2))]
20101 [(match_scratch:QI 2 "q")
20102 (set (match_operand:QI 0 "memory_operand" "")
20103 (match_operand:QI 1 "immediate_operand" ""))]
20105 && TARGET_SPLIT_LONG_MOVES
20106 && get_attr_length (insn) >= ix86_cost->large_insn"
20107 [(set (match_dup 2) (match_dup 1))
20108 (set (match_dup 0) (match_dup 2))]
20111 ;; Don't compare memory with zero, load and use a test instead.
20113 [(set (match_operand 0 "flags_reg_operand" "")
20114 (match_operator 1 "compare_operator"
20115 [(match_operand:SI 2 "memory_operand" "")
20117 (match_scratch:SI 3 "r")]
20118 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20119 [(set (match_dup 3) (match_dup 2))
20120 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20123 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20124 ;; Don't split NOTs with a displacement operand, because resulting XOR
20125 ;; will not be pairable anyway.
20127 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20128 ;; represented using a modRM byte. The XOR replacement is long decoded,
20129 ;; so this split helps here as well.
20131 ;; Note: Can't do this as a regular split because we can't get proper
20132 ;; lifetime information then.
20135 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20136 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20138 && ((TARGET_NOT_UNPAIRABLE
20139 && (!MEM_P (operands[0])
20140 || !memory_displacement_operand (operands[0], SImode)))
20141 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20142 && peep2_regno_dead_p (0, FLAGS_REG)"
20143 [(parallel [(set (match_dup 0)
20144 (xor:SI (match_dup 1) (const_int -1)))
20145 (clobber (reg:CC FLAGS_REG))])]
20149 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20150 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20152 && ((TARGET_NOT_UNPAIRABLE
20153 && (!MEM_P (operands[0])
20154 || !memory_displacement_operand (operands[0], HImode)))
20155 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20156 && peep2_regno_dead_p (0, FLAGS_REG)"
20157 [(parallel [(set (match_dup 0)
20158 (xor:HI (match_dup 1) (const_int -1)))
20159 (clobber (reg:CC FLAGS_REG))])]
20163 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20164 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20166 && ((TARGET_NOT_UNPAIRABLE
20167 && (!MEM_P (operands[0])
20168 || !memory_displacement_operand (operands[0], QImode)))
20169 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20170 && peep2_regno_dead_p (0, FLAGS_REG)"
20171 [(parallel [(set (match_dup 0)
20172 (xor:QI (match_dup 1) (const_int -1)))
20173 (clobber (reg:CC FLAGS_REG))])]
20176 ;; Non pairable "test imm, reg" instructions can be translated to
20177 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20178 ;; byte opcode instead of two, have a short form for byte operands),
20179 ;; so do it for other CPUs as well. Given that the value was dead,
20180 ;; this should not create any new dependencies. Pass on the sub-word
20181 ;; versions if we're concerned about partial register stalls.
20184 [(set (match_operand 0 "flags_reg_operand" "")
20185 (match_operator 1 "compare_operator"
20186 [(and:SI (match_operand:SI 2 "register_operand" "")
20187 (match_operand:SI 3 "immediate_operand" ""))
20189 "ix86_match_ccmode (insn, CCNOmode)
20190 && (true_regnum (operands[2]) != AX_REG
20191 || satisfies_constraint_K (operands[3]))
20192 && peep2_reg_dead_p (1, operands[2])"
20194 [(set (match_dup 0)
20195 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20198 (and:SI (match_dup 2) (match_dup 3)))])]
20201 ;; We don't need to handle HImode case, because it will be promoted to SImode
20202 ;; on ! TARGET_PARTIAL_REG_STALL
20205 [(set (match_operand 0 "flags_reg_operand" "")
20206 (match_operator 1 "compare_operator"
20207 [(and:QI (match_operand:QI 2 "register_operand" "")
20208 (match_operand:QI 3 "immediate_operand" ""))
20210 "! TARGET_PARTIAL_REG_STALL
20211 && ix86_match_ccmode (insn, CCNOmode)
20212 && true_regnum (operands[2]) != AX_REG
20213 && peep2_reg_dead_p (1, operands[2])"
20215 [(set (match_dup 0)
20216 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20219 (and:QI (match_dup 2) (match_dup 3)))])]
20223 [(set (match_operand 0 "flags_reg_operand" "")
20224 (match_operator 1 "compare_operator"
20227 (match_operand 2 "ext_register_operand" "")
20230 (match_operand 3 "const_int_operand" ""))
20232 "! TARGET_PARTIAL_REG_STALL
20233 && ix86_match_ccmode (insn, CCNOmode)
20234 && true_regnum (operands[2]) != AX_REG
20235 && peep2_reg_dead_p (1, operands[2])"
20236 [(parallel [(set (match_dup 0)
20245 (set (zero_extract:SI (match_dup 2)
20256 ;; Don't do logical operations with memory inputs.
20258 [(match_scratch:SI 2 "r")
20259 (parallel [(set (match_operand:SI 0 "register_operand" "")
20260 (match_operator:SI 3 "arith_or_logical_operator"
20262 (match_operand:SI 1 "memory_operand" "")]))
20263 (clobber (reg:CC FLAGS_REG))])]
20264 "! optimize_size && ! TARGET_READ_MODIFY"
20265 [(set (match_dup 2) (match_dup 1))
20266 (parallel [(set (match_dup 0)
20267 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20268 (clobber (reg:CC FLAGS_REG))])]
20272 [(match_scratch:SI 2 "r")
20273 (parallel [(set (match_operand:SI 0 "register_operand" "")
20274 (match_operator:SI 3 "arith_or_logical_operator"
20275 [(match_operand:SI 1 "memory_operand" "")
20277 (clobber (reg:CC FLAGS_REG))])]
20278 "! optimize_size && ! TARGET_READ_MODIFY"
20279 [(set (match_dup 2) (match_dup 1))
20280 (parallel [(set (match_dup 0)
20281 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20282 (clobber (reg:CC FLAGS_REG))])]
20285 ; Don't do logical operations with memory outputs
20287 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20288 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20289 ; the same decoder scheduling characteristics as the original.
20292 [(match_scratch:SI 2 "r")
20293 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20294 (match_operator:SI 3 "arith_or_logical_operator"
20296 (match_operand:SI 1 "nonmemory_operand" "")]))
20297 (clobber (reg:CC FLAGS_REG))])]
20298 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20299 [(set (match_dup 2) (match_dup 0))
20300 (parallel [(set (match_dup 2)
20301 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20302 (clobber (reg:CC FLAGS_REG))])
20303 (set (match_dup 0) (match_dup 2))]
20307 [(match_scratch:SI 2 "r")
20308 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20309 (match_operator:SI 3 "arith_or_logical_operator"
20310 [(match_operand:SI 1 "nonmemory_operand" "")
20312 (clobber (reg:CC FLAGS_REG))])]
20313 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20314 [(set (match_dup 2) (match_dup 0))
20315 (parallel [(set (match_dup 2)
20316 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20317 (clobber (reg:CC FLAGS_REG))])
20318 (set (match_dup 0) (match_dup 2))]
20321 ;; Attempt to always use XOR for zeroing registers.
20323 [(set (match_operand 0 "register_operand" "")
20324 (match_operand 1 "const0_operand" ""))]
20325 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20326 && (! TARGET_USE_MOV0 || optimize_size)
20327 && GENERAL_REG_P (operands[0])
20328 && peep2_regno_dead_p (0, FLAGS_REG)"
20329 [(parallel [(set (match_dup 0) (const_int 0))
20330 (clobber (reg:CC FLAGS_REG))])]
20332 operands[0] = gen_lowpart (word_mode, operands[0]);
20336 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20338 "(GET_MODE (operands[0]) == QImode
20339 || GET_MODE (operands[0]) == HImode)
20340 && (! TARGET_USE_MOV0 || optimize_size)
20341 && peep2_regno_dead_p (0, FLAGS_REG)"
20342 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20343 (clobber (reg:CC FLAGS_REG))])])
20345 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20347 [(set (match_operand 0 "register_operand" "")
20349 "(GET_MODE (operands[0]) == HImode
20350 || GET_MODE (operands[0]) == SImode
20351 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20352 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20353 && peep2_regno_dead_p (0, FLAGS_REG)"
20354 [(parallel [(set (match_dup 0) (const_int -1))
20355 (clobber (reg:CC FLAGS_REG))])]
20356 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20359 ;; Attempt to convert simple leas to adds. These can be created by
20362 [(set (match_operand:SI 0 "register_operand" "")
20363 (plus:SI (match_dup 0)
20364 (match_operand:SI 1 "nonmemory_operand" "")))]
20365 "peep2_regno_dead_p (0, FLAGS_REG)"
20366 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20367 (clobber (reg:CC FLAGS_REG))])]
20371 [(set (match_operand:SI 0 "register_operand" "")
20372 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20373 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20374 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20375 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20376 (clobber (reg:CC FLAGS_REG))])]
20377 "operands[2] = gen_lowpart (SImode, operands[2]);")
20380 [(set (match_operand:DI 0 "register_operand" "")
20381 (plus:DI (match_dup 0)
20382 (match_operand:DI 1 "x86_64_general_operand" "")))]
20383 "peep2_regno_dead_p (0, FLAGS_REG)"
20384 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20385 (clobber (reg:CC FLAGS_REG))])]
20389 [(set (match_operand:SI 0 "register_operand" "")
20390 (mult:SI (match_dup 0)
20391 (match_operand:SI 1 "const_int_operand" "")))]
20392 "exact_log2 (INTVAL (operands[1])) >= 0
20393 && peep2_regno_dead_p (0, FLAGS_REG)"
20394 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20395 (clobber (reg:CC FLAGS_REG))])]
20396 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20399 [(set (match_operand:DI 0 "register_operand" "")
20400 (mult:DI (match_dup 0)
20401 (match_operand:DI 1 "const_int_operand" "")))]
20402 "exact_log2 (INTVAL (operands[1])) >= 0
20403 && peep2_regno_dead_p (0, FLAGS_REG)"
20404 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20405 (clobber (reg:CC FLAGS_REG))])]
20406 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20409 [(set (match_operand:SI 0 "register_operand" "")
20410 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20411 (match_operand:DI 2 "const_int_operand" "")) 0))]
20412 "exact_log2 (INTVAL (operands[2])) >= 0
20413 && REGNO (operands[0]) == REGNO (operands[1])
20414 && peep2_regno_dead_p (0, FLAGS_REG)"
20415 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20416 (clobber (reg:CC FLAGS_REG))])]
20417 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20419 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20420 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20421 ;; many CPUs it is also faster, since special hardware to avoid esp
20422 ;; dependencies is present.
20424 ;; While some of these conversions may be done using splitters, we use peepholes
20425 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20427 ;; Convert prologue esp subtractions to push.
20428 ;; We need register to push. In order to keep verify_flow_info happy we have
20430 ;; - use scratch and clobber it in order to avoid dependencies
20431 ;; - use already live register
20432 ;; We can't use the second way right now, since there is no reliable way how to
20433 ;; verify that given register is live. First choice will also most likely in
20434 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20435 ;; call clobbered registers are dead. We may want to use base pointer as an
20436 ;; alternative when no register is available later.
20439 [(match_scratch:SI 0 "r")
20440 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20441 (clobber (reg:CC FLAGS_REG))
20442 (clobber (mem:BLK (scratch)))])]
20443 "optimize_size || !TARGET_SUB_ESP_4"
20444 [(clobber (match_dup 0))
20445 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20446 (clobber (mem:BLK (scratch)))])])
20449 [(match_scratch:SI 0 "r")
20450 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20451 (clobber (reg:CC FLAGS_REG))
20452 (clobber (mem:BLK (scratch)))])]
20453 "optimize_size || !TARGET_SUB_ESP_8"
20454 [(clobber (match_dup 0))
20455 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20456 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20457 (clobber (mem:BLK (scratch)))])])
20459 ;; Convert esp subtractions to push.
20461 [(match_scratch:SI 0 "r")
20462 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20463 (clobber (reg:CC FLAGS_REG))])]
20464 "optimize_size || !TARGET_SUB_ESP_4"
20465 [(clobber (match_dup 0))
20466 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20469 [(match_scratch:SI 0 "r")
20470 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20471 (clobber (reg:CC FLAGS_REG))])]
20472 "optimize_size || !TARGET_SUB_ESP_8"
20473 [(clobber (match_dup 0))
20474 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20475 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20477 ;; Convert epilogue deallocator to pop.
20479 [(match_scratch:SI 0 "r")
20480 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20481 (clobber (reg:CC FLAGS_REG))
20482 (clobber (mem:BLK (scratch)))])]
20483 "optimize_size || !TARGET_ADD_ESP_4"
20484 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20485 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20486 (clobber (mem:BLK (scratch)))])]
20489 ;; Two pops case is tricky, since pop causes dependency on destination register.
20490 ;; We use two registers if available.
20492 [(match_scratch:SI 0 "r")
20493 (match_scratch:SI 1 "r")
20494 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20495 (clobber (reg:CC FLAGS_REG))
20496 (clobber (mem:BLK (scratch)))])]
20497 "optimize_size || !TARGET_ADD_ESP_8"
20498 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20499 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20500 (clobber (mem:BLK (scratch)))])
20501 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20502 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20506 [(match_scratch:SI 0 "r")
20507 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20508 (clobber (reg:CC FLAGS_REG))
20509 (clobber (mem:BLK (scratch)))])]
20511 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20512 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20513 (clobber (mem:BLK (scratch)))])
20514 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20515 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20518 ;; Convert esp additions to pop.
20520 [(match_scratch:SI 0 "r")
20521 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20522 (clobber (reg:CC FLAGS_REG))])]
20524 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20525 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20528 ;; Two pops case is tricky, since pop causes dependency on destination register.
20529 ;; We use two registers if available.
20531 [(match_scratch:SI 0 "r")
20532 (match_scratch:SI 1 "r")
20533 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20534 (clobber (reg:CC FLAGS_REG))])]
20536 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20537 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20538 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20539 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20543 [(match_scratch:SI 0 "r")
20544 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20545 (clobber (reg:CC FLAGS_REG))])]
20547 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20548 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20549 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20550 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20553 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20554 ;; required and register dies. Similarly for 128 to plus -128.
20556 [(set (match_operand 0 "flags_reg_operand" "")
20557 (match_operator 1 "compare_operator"
20558 [(match_operand 2 "register_operand" "")
20559 (match_operand 3 "const_int_operand" "")]))]
20560 "(INTVAL (operands[3]) == -1
20561 || INTVAL (operands[3]) == 1
20562 || INTVAL (operands[3]) == 128)
20563 && ix86_match_ccmode (insn, CCGCmode)
20564 && peep2_reg_dead_p (1, operands[2])"
20565 [(parallel [(set (match_dup 0)
20566 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20567 (clobber (match_dup 2))])]
20571 [(match_scratch:DI 0 "r")
20572 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20573 (clobber (reg:CC FLAGS_REG))
20574 (clobber (mem:BLK (scratch)))])]
20575 "optimize_size || !TARGET_SUB_ESP_4"
20576 [(clobber (match_dup 0))
20577 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20578 (clobber (mem:BLK (scratch)))])])
20581 [(match_scratch:DI 0 "r")
20582 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20583 (clobber (reg:CC FLAGS_REG))
20584 (clobber (mem:BLK (scratch)))])]
20585 "optimize_size || !TARGET_SUB_ESP_8"
20586 [(clobber (match_dup 0))
20587 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20588 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20589 (clobber (mem:BLK (scratch)))])])
20591 ;; Convert esp subtractions to push.
20593 [(match_scratch:DI 0 "r")
20594 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20595 (clobber (reg:CC FLAGS_REG))])]
20596 "optimize_size || !TARGET_SUB_ESP_4"
20597 [(clobber (match_dup 0))
20598 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20601 [(match_scratch:DI 0 "r")
20602 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20603 (clobber (reg:CC FLAGS_REG))])]
20604 "optimize_size || !TARGET_SUB_ESP_8"
20605 [(clobber (match_dup 0))
20606 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20607 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20609 ;; Convert epilogue deallocator to pop.
20611 [(match_scratch:DI 0 "r")
20612 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20613 (clobber (reg:CC FLAGS_REG))
20614 (clobber (mem:BLK (scratch)))])]
20615 "optimize_size || !TARGET_ADD_ESP_4"
20616 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20617 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20618 (clobber (mem:BLK (scratch)))])]
20621 ;; Two pops case is tricky, since pop causes dependency on destination register.
20622 ;; We use two registers if available.
20624 [(match_scratch:DI 0 "r")
20625 (match_scratch:DI 1 "r")
20626 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20627 (clobber (reg:CC FLAGS_REG))
20628 (clobber (mem:BLK (scratch)))])]
20629 "optimize_size || !TARGET_ADD_ESP_8"
20630 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20631 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20632 (clobber (mem:BLK (scratch)))])
20633 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20634 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20638 [(match_scratch:DI 0 "r")
20639 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20640 (clobber (reg:CC FLAGS_REG))
20641 (clobber (mem:BLK (scratch)))])]
20643 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20644 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20645 (clobber (mem:BLK (scratch)))])
20646 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20647 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20650 ;; Convert esp additions to pop.
20652 [(match_scratch:DI 0 "r")
20653 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20654 (clobber (reg:CC FLAGS_REG))])]
20656 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20657 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20660 ;; Two pops case is tricky, since pop causes dependency on destination register.
20661 ;; We use two registers if available.
20663 [(match_scratch:DI 0 "r")
20664 (match_scratch:DI 1 "r")
20665 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20666 (clobber (reg:CC FLAGS_REG))])]
20668 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20669 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20670 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20671 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20675 [(match_scratch:DI 0 "r")
20676 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20677 (clobber (reg:CC FLAGS_REG))])]
20679 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20680 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20681 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20682 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20685 ;; Convert imul by three, five and nine into lea
20688 [(set (match_operand:SI 0 "register_operand" "")
20689 (mult:SI (match_operand:SI 1 "register_operand" "")
20690 (match_operand:SI 2 "const_int_operand" "")))
20691 (clobber (reg:CC FLAGS_REG))])]
20692 "INTVAL (operands[2]) == 3
20693 || INTVAL (operands[2]) == 5
20694 || INTVAL (operands[2]) == 9"
20695 [(set (match_dup 0)
20696 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20698 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20702 [(set (match_operand:SI 0 "register_operand" "")
20703 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20704 (match_operand:SI 2 "const_int_operand" "")))
20705 (clobber (reg:CC FLAGS_REG))])]
20707 && (INTVAL (operands[2]) == 3
20708 || INTVAL (operands[2]) == 5
20709 || INTVAL (operands[2]) == 9)"
20710 [(set (match_dup 0) (match_dup 1))
20712 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20714 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20718 [(set (match_operand:DI 0 "register_operand" "")
20719 (mult:DI (match_operand:DI 1 "register_operand" "")
20720 (match_operand:DI 2 "const_int_operand" "")))
20721 (clobber (reg:CC FLAGS_REG))])]
20723 && (INTVAL (operands[2]) == 3
20724 || INTVAL (operands[2]) == 5
20725 || INTVAL (operands[2]) == 9)"
20726 [(set (match_dup 0)
20727 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20729 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20733 [(set (match_operand:DI 0 "register_operand" "")
20734 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20735 (match_operand:DI 2 "const_int_operand" "")))
20736 (clobber (reg:CC FLAGS_REG))])]
20739 && (INTVAL (operands[2]) == 3
20740 || INTVAL (operands[2]) == 5
20741 || INTVAL (operands[2]) == 9)"
20742 [(set (match_dup 0) (match_dup 1))
20744 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20746 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20748 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20749 ;; imul $32bit_imm, reg, reg is direct decoded.
20751 [(match_scratch:DI 3 "r")
20752 (parallel [(set (match_operand:DI 0 "register_operand" "")
20753 (mult:DI (match_operand:DI 1 "memory_operand" "")
20754 (match_operand:DI 2 "immediate_operand" "")))
20755 (clobber (reg:CC FLAGS_REG))])]
20756 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20757 && !satisfies_constraint_K (operands[2])"
20758 [(set (match_dup 3) (match_dup 1))
20759 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20760 (clobber (reg:CC FLAGS_REG))])]
20764 [(match_scratch:SI 3 "r")
20765 (parallel [(set (match_operand:SI 0 "register_operand" "")
20766 (mult:SI (match_operand:SI 1 "memory_operand" "")
20767 (match_operand:SI 2 "immediate_operand" "")))
20768 (clobber (reg:CC FLAGS_REG))])]
20769 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20770 && !satisfies_constraint_K (operands[2])"
20771 [(set (match_dup 3) (match_dup 1))
20772 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20773 (clobber (reg:CC FLAGS_REG))])]
20777 [(match_scratch:SI 3 "r")
20778 (parallel [(set (match_operand:DI 0 "register_operand" "")
20780 (mult:SI (match_operand:SI 1 "memory_operand" "")
20781 (match_operand:SI 2 "immediate_operand" ""))))
20782 (clobber (reg:CC FLAGS_REG))])]
20783 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20784 && !satisfies_constraint_K (operands[2])"
20785 [(set (match_dup 3) (match_dup 1))
20786 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20787 (clobber (reg:CC FLAGS_REG))])]
20790 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20791 ;; Convert it into imul reg, reg
20792 ;; It would be better to force assembler to encode instruction using long
20793 ;; immediate, but there is apparently no way to do so.
20795 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20796 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20797 (match_operand:DI 2 "const_int_operand" "")))
20798 (clobber (reg:CC FLAGS_REG))])
20799 (match_scratch:DI 3 "r")]
20800 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20801 && satisfies_constraint_K (operands[2])"
20802 [(set (match_dup 3) (match_dup 2))
20803 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20804 (clobber (reg:CC FLAGS_REG))])]
20806 if (!rtx_equal_p (operands[0], operands[1]))
20807 emit_move_insn (operands[0], operands[1]);
20811 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20812 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20813 (match_operand:SI 2 "const_int_operand" "")))
20814 (clobber (reg:CC FLAGS_REG))])
20815 (match_scratch:SI 3 "r")]
20816 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20817 && satisfies_constraint_K (operands[2])"
20818 [(set (match_dup 3) (match_dup 2))
20819 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20820 (clobber (reg:CC FLAGS_REG))])]
20822 if (!rtx_equal_p (operands[0], operands[1]))
20823 emit_move_insn (operands[0], operands[1]);
20827 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20828 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20829 (match_operand:HI 2 "immediate_operand" "")))
20830 (clobber (reg:CC FLAGS_REG))])
20831 (match_scratch:HI 3 "r")]
20832 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20833 [(set (match_dup 3) (match_dup 2))
20834 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20835 (clobber (reg:CC FLAGS_REG))])]
20837 if (!rtx_equal_p (operands[0], operands[1]))
20838 emit_move_insn (operands[0], operands[1]);
20841 ;; After splitting up read-modify operations, array accesses with memory
20842 ;; operands might end up in form:
20844 ;; movl 4(%esp), %edx
20846 ;; instead of pre-splitting:
20848 ;; addl 4(%esp), %eax
20850 ;; movl 4(%esp), %edx
20851 ;; leal (%edx,%eax,4), %eax
20854 [(parallel [(set (match_operand 0 "register_operand" "")
20855 (ashift (match_operand 1 "register_operand" "")
20856 (match_operand 2 "const_int_operand" "")))
20857 (clobber (reg:CC FLAGS_REG))])
20858 (set (match_operand 3 "register_operand")
20859 (match_operand 4 "x86_64_general_operand" ""))
20860 (parallel [(set (match_operand 5 "register_operand" "")
20861 (plus (match_operand 6 "register_operand" "")
20862 (match_operand 7 "register_operand" "")))
20863 (clobber (reg:CC FLAGS_REG))])]
20864 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20865 /* Validate MODE for lea. */
20866 && ((!TARGET_PARTIAL_REG_STALL
20867 && (GET_MODE (operands[0]) == QImode
20868 || GET_MODE (operands[0]) == HImode))
20869 || GET_MODE (operands[0]) == SImode
20870 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20871 /* We reorder load and the shift. */
20872 && !rtx_equal_p (operands[1], operands[3])
20873 && !reg_overlap_mentioned_p (operands[0], operands[4])
20874 /* Last PLUS must consist of operand 0 and 3. */
20875 && !rtx_equal_p (operands[0], operands[3])
20876 && (rtx_equal_p (operands[3], operands[6])
20877 || rtx_equal_p (operands[3], operands[7]))
20878 && (rtx_equal_p (operands[0], operands[6])
20879 || rtx_equal_p (operands[0], operands[7]))
20880 /* The intermediate operand 0 must die or be same as output. */
20881 && (rtx_equal_p (operands[0], operands[5])
20882 || peep2_reg_dead_p (3, operands[0]))"
20883 [(set (match_dup 3) (match_dup 4))
20884 (set (match_dup 0) (match_dup 1))]
20886 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20887 int scale = 1 << INTVAL (operands[2]);
20888 rtx index = gen_lowpart (Pmode, operands[1]);
20889 rtx base = gen_lowpart (Pmode, operands[3]);
20890 rtx dest = gen_lowpart (mode, operands[5]);
20892 operands[1] = gen_rtx_PLUS (Pmode, base,
20893 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20895 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20896 operands[0] = dest;
20899 ;; Call-value patterns last so that the wildcard operand does not
20900 ;; disrupt insn-recog's switch tables.
20902 (define_insn "*call_value_pop_0"
20903 [(set (match_operand 0 "" "")
20904 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20905 (match_operand:SI 2 "" "")))
20906 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20907 (match_operand:SI 3 "immediate_operand" "")))]
20910 if (SIBLING_CALL_P (insn))
20913 return "call\t%P1";
20915 [(set_attr "type" "callv")])
20917 (define_insn "*call_value_pop_1"
20918 [(set (match_operand 0 "" "")
20919 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20920 (match_operand:SI 2 "" "")))
20921 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20922 (match_operand:SI 3 "immediate_operand" "i")))]
20925 if (constant_call_address_operand (operands[1], Pmode))
20927 if (SIBLING_CALL_P (insn))
20930 return "call\t%P1";
20932 if (SIBLING_CALL_P (insn))
20935 return "call\t%A1";
20937 [(set_attr "type" "callv")])
20939 (define_insn "*call_value_0"
20940 [(set (match_operand 0 "" "")
20941 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20942 (match_operand:SI 2 "" "")))]
20945 if (SIBLING_CALL_P (insn))
20948 return "call\t%P1";
20950 [(set_attr "type" "callv")])
20952 (define_insn "*call_value_0_rex64"
20953 [(set (match_operand 0 "" "")
20954 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20955 (match_operand:DI 2 "const_int_operand" "")))]
20958 if (SIBLING_CALL_P (insn))
20961 return "call\t%P1";
20963 [(set_attr "type" "callv")])
20965 (define_insn "*call_value_1"
20966 [(set (match_operand 0 "" "")
20967 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20968 (match_operand:SI 2 "" "")))]
20969 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20971 if (constant_call_address_operand (operands[1], Pmode))
20972 return "call\t%P1";
20973 return "call\t%A1";
20975 [(set_attr "type" "callv")])
20977 (define_insn "*sibcall_value_1"
20978 [(set (match_operand 0 "" "")
20979 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20980 (match_operand:SI 2 "" "")))]
20981 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20983 if (constant_call_address_operand (operands[1], Pmode))
20987 [(set_attr "type" "callv")])
20989 (define_insn "*call_value_1_rex64"
20990 [(set (match_operand 0 "" "")
20991 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20992 (match_operand:DI 2 "" "")))]
20993 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20994 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20996 if (constant_call_address_operand (operands[1], Pmode))
20997 return "call\t%P1";
20998 return "call\t%A1";
21000 [(set_attr "type" "callv")])
21002 (define_insn "*call_value_1_rex64_large"
21003 [(set (match_operand 0 "" "")
21004 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21005 (match_operand:DI 2 "" "")))]
21006 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21008 [(set_attr "type" "callv")])
21010 (define_insn "*sibcall_value_1_rex64"
21011 [(set (match_operand 0 "" "")
21012 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21013 (match_operand:DI 2 "" "")))]
21014 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21016 [(set_attr "type" "callv")])
21018 (define_insn "*sibcall_value_1_rex64_v"
21019 [(set (match_operand 0 "" "")
21020 (call (mem:QI (reg:DI R11_REG))
21021 (match_operand:DI 1 "" "")))]
21022 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21024 [(set_attr "type" "callv")])
21026 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21027 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21028 ;; caught for use by garbage collectors and the like. Using an insn that
21029 ;; maps to SIGILL makes it more likely the program will rightfully die.
21030 ;; Keeping with tradition, "6" is in honor of #UD.
21031 (define_insn "trap"
21032 [(trap_if (const_int 1) (const_int 6))]
21034 { return ASM_SHORT "0x0b0f"; }
21035 [(set_attr "length" "2")])
21037 (define_expand "sse_prologue_save"
21038 [(parallel [(set (match_operand:BLK 0 "" "")
21039 (unspec:BLK [(reg:DI 21)
21046 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21047 (use (match_operand:DI 1 "register_operand" ""))
21048 (use (match_operand:DI 2 "immediate_operand" ""))
21049 (use (label_ref:DI (match_operand 3 "" "")))])]
21053 (define_insn "*sse_prologue_save_insn"
21054 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21055 (match_operand:DI 4 "const_int_operand" "n")))
21056 (unspec:BLK [(reg:DI 21)
21063 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21064 (use (match_operand:DI 1 "register_operand" "r"))
21065 (use (match_operand:DI 2 "const_int_operand" "i"))
21066 (use (label_ref:DI (match_operand 3 "" "X")))]
21068 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21069 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21072 operands[0] = gen_rtx_MEM (Pmode,
21073 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21074 output_asm_insn ("jmp\t%A1", operands);
21075 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21077 operands[4] = adjust_address (operands[0], DImode, i*16);
21078 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21079 PUT_MODE (operands[4], TImode);
21080 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21081 output_asm_insn ("rex", operands);
21082 output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
21084 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21085 CODE_LABEL_NUMBER (operands[3]));
21088 [(set_attr "type" "other")
21089 (set_attr "length_immediate" "0")
21090 (set_attr "length_address" "0")
21091 (set_attr "length" "135")
21092 (set_attr "memory" "store")
21093 (set_attr "modrm" "0")
21094 (set_attr "mode" "DI")])
21096 (define_expand "prefetch"
21097 [(prefetch (match_operand 0 "address_operand" "")
21098 (match_operand:SI 1 "const_int_operand" "")
21099 (match_operand:SI 2 "const_int_operand" ""))]
21100 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21102 int rw = INTVAL (operands[1]);
21103 int locality = INTVAL (operands[2]);
21105 gcc_assert (rw == 0 || rw == 1);
21106 gcc_assert (locality >= 0 && locality <= 3);
21107 gcc_assert (GET_MODE (operands[0]) == Pmode
21108 || GET_MODE (operands[0]) == VOIDmode);
21110 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21111 supported by SSE counterpart or the SSE prefetch is not available
21112 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21114 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21115 operands[2] = GEN_INT (3);
21117 operands[1] = const0_rtx;
21120 (define_insn "*prefetch_sse"
21121 [(prefetch (match_operand:SI 0 "address_operand" "p")
21123 (match_operand:SI 1 "const_int_operand" ""))]
21124 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21126 static const char * const patterns[4] = {
21127 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21130 int locality = INTVAL (operands[1]);
21131 gcc_assert (locality >= 0 && locality <= 3);
21133 return patterns[locality];
21135 [(set_attr "type" "sse")
21136 (set_attr "memory" "none")])
21138 (define_insn "*prefetch_sse_rex"
21139 [(prefetch (match_operand:DI 0 "address_operand" "p")
21141 (match_operand:SI 1 "const_int_operand" ""))]
21142 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21144 static const char * const patterns[4] = {
21145 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21148 int locality = INTVAL (operands[1]);
21149 gcc_assert (locality >= 0 && locality <= 3);
21151 return patterns[locality];
21153 [(set_attr "type" "sse")
21154 (set_attr "memory" "none")])
21156 (define_insn "*prefetch_3dnow"
21157 [(prefetch (match_operand:SI 0 "address_operand" "p")
21158 (match_operand:SI 1 "const_int_operand" "n")
21160 "TARGET_3DNOW && !TARGET_64BIT"
21162 if (INTVAL (operands[1]) == 0)
21163 return "prefetch\t%a0";
21165 return "prefetchw\t%a0";
21167 [(set_attr "type" "mmx")
21168 (set_attr "memory" "none")])
21170 (define_insn "*prefetch_3dnow_rex"
21171 [(prefetch (match_operand:DI 0 "address_operand" "p")
21172 (match_operand:SI 1 "const_int_operand" "n")
21174 "TARGET_3DNOW && TARGET_64BIT"
21176 if (INTVAL (operands[1]) == 0)
21177 return "prefetch\t%a0";
21179 return "prefetchw\t%a0";
21181 [(set_attr "type" "mmx")
21182 (set_attr "memory" "none")])
21184 (define_expand "stack_protect_set"
21185 [(match_operand 0 "memory_operand" "")
21186 (match_operand 1 "memory_operand" "")]
21189 #ifdef TARGET_THREAD_SSP_OFFSET
21191 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21192 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21194 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21195 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21198 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21200 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21205 (define_insn "stack_protect_set_si"
21206 [(set (match_operand:SI 0 "memory_operand" "=m")
21207 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21208 (set (match_scratch:SI 2 "=&r") (const_int 0))
21209 (clobber (reg:CC FLAGS_REG))]
21211 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21212 [(set_attr "type" "multi")])
21214 (define_insn "stack_protect_set_di"
21215 [(set (match_operand:DI 0 "memory_operand" "=m")
21216 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21217 (set (match_scratch:DI 2 "=&r") (const_int 0))
21218 (clobber (reg:CC FLAGS_REG))]
21220 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21221 [(set_attr "type" "multi")])
21223 (define_insn "stack_tls_protect_set_si"
21224 [(set (match_operand:SI 0 "memory_operand" "=m")
21225 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21226 (set (match_scratch:SI 2 "=&r") (const_int 0))
21227 (clobber (reg:CC FLAGS_REG))]
21229 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21230 [(set_attr "type" "multi")])
21232 (define_insn "stack_tls_protect_set_di"
21233 [(set (match_operand:DI 0 "memory_operand" "=m")
21234 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21235 (set (match_scratch:DI 2 "=&r") (const_int 0))
21236 (clobber (reg:CC FLAGS_REG))]
21239 /* The kernel uses a different segment register for performance reasons; a
21240 system call would not have to trash the userspace segment register,
21241 which would be expensive */
21242 if (ix86_cmodel != CM_KERNEL)
21243 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21245 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21247 [(set_attr "type" "multi")])
21249 (define_expand "stack_protect_test"
21250 [(match_operand 0 "memory_operand" "")
21251 (match_operand 1 "memory_operand" "")
21252 (match_operand 2 "" "")]
21255 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21256 ix86_compare_op0 = operands[0];
21257 ix86_compare_op1 = operands[1];
21258 ix86_compare_emitted = flags;
21260 #ifdef TARGET_THREAD_SSP_OFFSET
21262 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21263 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21265 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21266 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21269 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21271 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21273 emit_jump_insn (gen_beq (operands[2]));
21277 (define_insn "stack_protect_test_si"
21278 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21279 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21280 (match_operand:SI 2 "memory_operand" "m")]
21282 (clobber (match_scratch:SI 3 "=&r"))]
21284 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21285 [(set_attr "type" "multi")])
21287 (define_insn "stack_protect_test_di"
21288 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21289 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21290 (match_operand:DI 2 "memory_operand" "m")]
21292 (clobber (match_scratch:DI 3 "=&r"))]
21294 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21295 [(set_attr "type" "multi")])
21297 (define_insn "stack_tls_protect_test_si"
21298 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21299 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21300 (match_operand:SI 2 "const_int_operand" "i")]
21301 UNSPEC_SP_TLS_TEST))
21302 (clobber (match_scratch:SI 3 "=r"))]
21304 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21305 [(set_attr "type" "multi")])
21307 (define_insn "stack_tls_protect_test_di"
21308 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21309 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21310 (match_operand:DI 2 "const_int_operand" "i")]
21311 UNSPEC_SP_TLS_TEST))
21312 (clobber (match_scratch:DI 3 "=r"))]
21315 /* The kernel uses a different segment register for performance reasons; a
21316 system call would not have to trash the userspace segment register,
21317 which would be expensive */
21318 if (ix86_cmodel != CM_KERNEL)
21319 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21321 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21323 [(set_attr "type" "multi")])
21325 (define_mode_iterator CRC32MODE [QI HI SI])
21326 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21327 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21329 (define_insn "sse4_2_crc32<mode>"
21330 [(set (match_operand:SI 0 "register_operand" "=r")
21332 [(match_operand:SI 1 "register_operand" "0")
21333 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21336 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21337 [(set_attr "type" "sselog1")
21338 (set_attr "prefix_rep" "1")
21339 (set_attr "prefix_extra" "1")
21340 (set_attr "mode" "SI")])
21342 (define_insn "sse4_2_crc32di"
21343 [(set (match_operand:DI 0 "register_operand" "=r")
21345 [(match_operand:DI 1 "register_operand" "0")
21346 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21348 "TARGET_SSE4_2 && TARGET_64BIT"
21349 "crc32q\t{%2, %0|%0, %2}"
21350 [(set_attr "type" "sselog1")
21351 (set_attr "prefix_rep" "1")
21352 (set_attr "prefix_extra" "1")
21353 (set_attr "mode" "DI")])
21357 (include "sync.md")